comparison src/win32/win32dep.c @ 7523:7c3db2b2a790

[gaim-migrate @ 8136] Window flashing is back. Fixed kernel32 crash bug when gaim settings dir was being moved. Consolidated init functions. committer: Tailor Script <tailor@pidgin.im>
author Herman Bloggs <hermanator12002@yahoo.com>
date Sun, 16 Nov 2003 01:52:48 +0000
parents e28728795a45
children 77727178a1df
comparison
equal deleted inserted replaced
7522:07156f873116 7523:7c3db2b2a790
42 #include "winuser_extra.h" 42 #include "winuser_extra.h"
43 #include "idletrack.h" 43 #include "idletrack.h"
44 #include "zlib.h" 44 #include "zlib.h"
45 #include "untar.h" 45 #include "untar.h"
46 46
47 # include <libintl.h> 47 #include <libintl.h>
48 # define _(x) gettext(x)
49 48
50 /* 49 /*
51 * DEFINES & MACROS 50 * DEFINES & MACROS
52 */ 51 */
52 #define _(x) gettext(x)
53 53
54 /* 54 /*
55 * DATA STRUCTS 55 * DATA STRUCTS
56 */ 56 */
57
58 /* For shfolder.dll */
59 typedef HRESULT (CALLBACK* LPFNSHGETFOLDERPATH)(HWND, int, HANDLE, DWORD, LPTSTR);
60
61 typedef enum {
62 SHGFP_TYPE_CURRENT = 0, // current value for user, verify it exists
63 SHGFP_TYPE_DEFAULT = 1, // default value, may not exist
64 } SHGFP_TYPE;
65
66 #define CSIDL_APPDATA 0x001a
67 #define CSIDL_FLAG_CREATE 0x8000
68
69 /* flash info */
70 typedef BOOL (CALLBACK* LPFNFLASHWINDOWEX)(PFLASHWINFO);
71
57 struct _WGAIM_FLASH_INFO { 72 struct _WGAIM_FLASH_INFO {
58 guint t_handle; 73 guint t_handle;
59 guint sig_handler; 74 guint sig_handler;
60 }; 75 };
61 typedef struct _WGAIM_FLASH_INFO WGAIM_FLASH_INFO; 76 typedef struct _WGAIM_FLASH_INFO WGAIM_FLASH_INFO;
62 77
63 /* 78 /*
64 * LOCALS 79 * LOCALS
65 */ 80 */
66 static char app_data_dir[MAX_PATH]; 81 static char app_data_dir[MAX_PATH] = "C:";
67 static char install_dir[MAXPATHLEN]; 82 static char install_dir[MAXPATHLEN];
68 static char lib_dir[MAXPATHLEN]; 83 static char lib_dir[MAXPATHLEN];
69 static char locale_dir[MAXPATHLEN]; 84 static char locale_dir[MAXPATHLEN];
70 static gboolean blink_turned_on = TRUE; 85 static gboolean blink_turned_on = TRUE;
71 86
76 HINSTANCE gaimdll_hInstance = 0; 91 HINSTANCE gaimdll_hInstance = 0;
77 92
78 /* 93 /*
79 * PROTOS 94 * PROTOS
80 */ 95 */
81 BOOL (*MyFlashWindowEx)(PFLASHWINFO pfwi)=NULL; 96 LPFNFLASHWINDOWEX MyFlashWindowEx = NULL;
82 HRESULT (*SHGetFolderPath)(HWND, int, HANDLE, DWORD, LPTSTR) = NULL; 97 LPFNSHGETFOLDERPATH MySHGetFolderPath = NULL;
83 98
84 FARPROC wgaim_find_and_loadproc(char*, char*); 99 FARPROC wgaim_find_and_loadproc(char*, char*);
85 extern void wgaim_gtkspell_init(); 100 extern void wgaim_gtkspell_init();
101 char* wgaim_data_dir(void);
86 102
87 /* 103 /*
88 * STATIC CODE 104 * STATIC CODE
89 */ 105 */
90 106
103 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "done\n"); 119 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "done\n");
104 } 120 }
105 121
106 static void load_winver_specific_procs(void) { 122 static void load_winver_specific_procs(void) {
107 /* Used for Win98+ and WinNT5+ */ 123 /* Used for Win98+ and WinNT5+ */
108 MyFlashWindowEx = (void*)wgaim_find_and_loadproc("user32.dll", "FlashWindowEx" ); 124 MyFlashWindowEx = (LPFNFLASHWINDOWEX)wgaim_find_and_loadproc("user32.dll", "FlashWindowEx" );
125 }
126
127 static char* base_name(char* path) {
128 char *tmp = path;
129 char *prev = NULL;
130
131 while((tmp=strchr(tmp, '\\'))) {
132 prev = tmp;
133 tmp += 1;
134 }
135 if(prev)
136 return ++prev;
137 else
138 return NULL;
139 }
140
141 BOOL folder_exists(char *folder) {
142 BOOL ret = FALSE;
143 WIN32_FIND_DATA fileinfo;
144 HANDLE fh;
145
146 memset(&fileinfo, 0, sizeof(WIN32_FIND_DATA));
147 if((fh=FindFirstFile(folder, &fileinfo))) {
148 if(fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
149 ret = TRUE;
150 SetLastError(ERROR_SUCCESS);
151 }
152 else
153 SetLastError(ERROR_FILE_EXISTS);
154 FindClose(fh);
155 }
156 return ret;
157 }
158
159 /* Recursively create directories in the dest path */
160 static BOOL CreateDirectoryR(char *dest) {
161 static BOOL start = TRUE;
162 BOOL ret = FALSE;
163
164 if(!dest)
165 return ret;
166
167 if(start) {
168 char *str = g_strdup(dest);
169 start = FALSE;
170 ret = CreateDirectoryR(str);
171 g_free(str);
172 start = TRUE;
173 }
174 else {
175 char *tmp1 = dest;
176 char *tmp=NULL;
177
178 while((tmp1=strchr(tmp1, '\\'))) {
179 tmp = tmp1;
180 tmp1+=1;
181 }
182
183 if(tmp) {
184 tmp[0] = '\0';
185 CreateDirectoryR(dest);
186 tmp[0] = '\\';
187 if(CreateDirectory(dest, NULL) == 0 && GetLastError() != ERROR_ALREADY_EXISTS) {
188 gaim_debug(GAIM_DEBUG_ERROR, "wgaim",
189 "Error creating directory: %s. Errno: %u\n",
190 dest, (UINT)GetLastError());
191 }
192 else
193 ret = TRUE;
194 }
195 }
196 return ret;
197 }
198
199 static BOOL move_folder(char *src, char* dest, char* copytitle, BOOL overwrite) {
200 char *tsrc, *tdest;
201 SHFILEOPSTRUCT dirmove;
202 BOOL ret = FALSE;
203
204 g_return_val_if_fail(src!=NULL, ret);
205 g_return_val_if_fail(dest!=NULL, ret);
206
207 if(!folder_exists(src)) {
208 gaim_debug(GAIM_DEBUG_WARNING, "wgaim",
209 "move_folder: Source folder %s, does not exist\n", src);
210 return ret;
211 }
212 if(!overwrite) {
213 char *dstpath = g_strdup_printf("%s\\%s", dest, base_name(src));
214
215 if(folder_exists(dstpath)) {
216 gaim_debug(GAIM_DEBUG_WARNING, "wgaim",
217 "move_folder: Destination Folder %s, already exists\n", dstpath);
218 g_free(dstpath);
219 return ret;
220 }
221 g_free(dstpath);
222 }
223
224 /* Create dest folder if it doesn't exist */
225 if(!CreateDirectoryR(dest)) {
226 gaim_debug(GAIM_DEBUG_ERROR, "wgaim", "Error creating directory: %s\n", dest);
227 return ret;
228 }
229
230 tsrc = g_strdup_printf("%s%c", src, '\0');
231 tdest = g_strdup_printf("%s%c", dest, '\0');
232
233 memset(&dirmove, 0, sizeof(SHFILEOPSTRUCT));
234 dirmove.wFunc = FO_MOVE;
235 dirmove.pFrom = tsrc;
236 dirmove.pTo = tdest;
237 dirmove.fFlags = FOF_NOCONFIRMATION | FOF_SIMPLEPROGRESS;
238 dirmove.hNameMappings = 0;
239 dirmove.lpszProgressTitle = copytitle;
240
241 if(SHFileOperation(&dirmove)==0)
242 ret = TRUE;
243
244 g_free(tsrc);
245 g_free(tdest);
246 return ret;
247 }
248
249 static void move_settings_dir() {
250 char *old_home = g_strdup_printf("%s%s", g_get_home_dir() ? g_get_home_dir() : "C:", "\\.gaim");
251 char *new_home = g_strdup_printf("%s%s", wgaim_data_dir(), "\\.gaim");
252
253 if(folder_exists(old_home) && !folder_exists(new_home)) {
254 if(move_folder(old_home, wgaim_data_dir(), _("Moving Gaim Settings.."), FALSE)) {
255 char *locenc, *locenc1, *str;
256 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "Success moving '.gaim' directory\n");
257 str = g_strdup_printf("%s%s", _("Moving Gaim user settings to: "), new_home);
258 locenc=g_locale_from_utf8(str, -1, NULL, NULL, NULL);
259 locenc1=g_locale_from_utf8(_("Notification"), -1, NULL, NULL, NULL);
260 MessageBox(NULL, locenc, locenc1, MB_OK | MB_TOPMOST);
261 g_free(locenc);
262 g_free(locenc1);
263 g_free(str);
264 }
265 else
266 gaim_debug(GAIM_DEBUG_ERROR, "wgaim",
267 "Failed to move '.gaim' directory to %s.\n", wgaim_data_dir());
268 }
269 g_free(new_home);
270 g_free(old_home);
109 } 271 }
110 272
111 /* 273 /*
112 * PUBLIC CODE 274 * PUBLIC CODE
113 */ 275 */
114
115 void wgaim_set_hinstance(HINSTANCE hint) {
116 gaimexe_hInstance = hint;
117 }
118 276
119 HINSTANCE wgaim_hinstance(void) { 277 HINSTANCE wgaim_hinstance(void) {
120 return gaimexe_hInstance; 278 return gaimexe_hInstance;
121 } 279 }
122 280
243 void wgaim_conv_im_blink(GtkWidget *window) { 401 void wgaim_conv_im_blink(GtkWidget *window) {
244 if(!blink_turned_on) 402 if(!blink_turned_on)
245 return; 403 return;
246 if(MyFlashWindowEx) { 404 if(MyFlashWindowEx) {
247 FLASHWINFO info; 405 FLASHWINFO info;
248 406 memset(&info, 0, sizeof(FLASHWINFO));
249 info.cbSize = sizeof(FLASHWINFO); 407 info.cbSize = sizeof(FLASHWINFO);
250 info.hwnd = GDK_WINDOW_HWND(window->window); 408 info.hwnd = GDK_WINDOW_HWND(window->window);
251 info.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG; 409 info.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG;
252 info.dwTimeout = 0; 410 info.dwTimeout = 0;
253 MyFlashWindowEx(&info); 411 MyFlashWindowEx(&info);
335 493
336 void wgaim_systray_maximize( GtkWidget *window ) { 494 void wgaim_systray_maximize( GtkWidget *window ) {
337 RestoreWndFromTray(GDK_WINDOW_HWND(window->window)); 495 RestoreWndFromTray(GDK_WINDOW_HWND(window->window));
338 } 496 }
339 497
340 /* Windows Initializations */ 498 void wgaim_init(HINSTANCE hint) {
341 typedef enum { 499 WORD wVersionRequested;
342 SHGFP_TYPE_CURRENT = 0, // current value for user, verify it exists 500 WSADATA wsaData;
343 SHGFP_TYPE_DEFAULT = 1, // default value, may not exist 501 char *perlenv;
344 } SHGFP_TYPE; 502 char *newenv;
345 503
346 #define CSIDL_APPDATA 0x001a 504 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "wgaim_init start\n");
347 505
348 void wgaim_pre_plugin_init(void) { 506 gaimexe_hInstance = hint;
349 char *perlenv, *newenv; 507
508 load_winver_specific_procs();
509
510 /* Winsock init */
511 wVersionRequested = MAKEWORD( 2, 2 );
512 WSAStartup( wVersionRequested, &wsaData );
513
514 /* Confirm that the winsock DLL supports 2.2 */
515 /* Note that if the DLL supports versions greater than
516 2.2 in addition to 2.2, it will still return 2.2 in
517 wVersion since that is the version we requested. */
518 if ( LOBYTE( wsaData.wVersion ) != 2 ||
519 HIBYTE( wsaData.wVersion ) != 2 ) {
520 gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "Could not find a usable WinSock DLL. Oh well.\n");
521 WSACleanup();
522 }
523
524 /* Set Environmental Variables */
525 /* Disable PANGO UNISCRIBE (for GTK 2.2.0). This may not be necessary in the
526 future because there will most likely be a check to see if we need this.
527 For now we need to set this in order to avoid poor performance for some
528 windows machines.
529 */
530 newenv = g_strdup("PANGO_WIN32_NO_UNISCRIBE=1");
531 if(putenv(newenv)<0)
532 gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "putenv failed\n");
533 g_free(newenv);
350 534
351 /* Tell perl where to find Gaim's perl modules */ 535 /* Tell perl where to find Gaim's perl modules */
352 perlenv = (char*)g_getenv("PERL5LIB"); 536 perlenv = (char*)g_getenv("PERL5LIB");
353 newenv = g_strdup_printf("PERL5LIB=%s%s%s%s", 537 newenv = g_strdup_printf("PERL5LIB=%s%s%s%s",
354 perlenv ? perlenv : "", 538 perlenv ? perlenv : "",
357 "\\perlmod;"); 541 "\\perlmod;");
358 if(putenv(newenv)<0) 542 if(putenv(newenv)<0)
359 gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "putenv failed\n"); 543 gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "putenv failed\n");
360 g_free(newenv); 544 g_free(newenv);
361 545
362 /* Set app data dir, where to save Gaim user settings */ 546 /* Set app data dir, used by gaim_home_dir */
363 newenv = (char*)g_getenv("HOME"); 547 newenv = (char*)g_getenv("HOME");
364 if(!newenv) { 548 if(!newenv) {
365 SHGetFolderPath = (void*)wgaim_find_and_loadproc("shfolder.dll", "SHGetFolderPathA"); 549 if((MySHGetFolderPath = (LPFNSHGETFOLDERPATH)wgaim_find_and_loadproc("shfolder.dll", "SHGetFolderPathA"))) {
366 if(SHGetFolderPath) { 550 MySHGetFolderPath(NULL,
367 HRESULT hrResult = SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, app_data_dir); 551 CSIDL_APPDATA,
368 if(hrResult != S_FALSE && hrResult != E_FAIL && hrResult != E_INVALIDARG) { 552 NULL, SHGFP_TYPE_CURRENT, app_data_dir);
369 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "APP DATA PATH set to: %s\n", app_data_dir);
370 }
371 else
372 strcpy(app_data_dir, "C:");
373 } 553 }
374 554 else
555 strcpy(app_data_dir, "C:");
375 /* As of 0.69, using SHGetFolderPath to determine app settings directory. 556 /* As of 0.69, using SHGetFolderPath to determine app settings directory.
376 Move app settings to new location if need be. */ 557 Move app settings to new location if need be. */
377 { 558 move_settings_dir();
378 char *old_home = g_strdup_printf("%s%s", g_get_home_dir() ? g_get_home_dir() : "C:", "\\.gaim");
379 char *new_home = g_strdup_printf("%s\\.gaim", wgaim_data_dir());
380 GDir *dir_old, *dir_new;
381
382 dir_old = g_dir_open(old_home, 0, NULL);
383 dir_new = g_dir_open(new_home, 0, NULL);
384 if(dir_old && !dir_new) {
385 gaim_notify_message(NULL,
386 GAIM_NOTIFY_MSG_INFO,
387 _("Notification"),
388 _("Moving Gaim user settings directory to:"),
389 new_home,
390 NULL,
391 NULL);
392 if(MoveFile(old_home, new_home) != 0)
393 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "Success moving '.gaim' directory\n");
394 }
395 g_free(new_home);
396 g_free(old_home);
397 if(dir_old) g_dir_close(dir_old);
398 if(dir_new) g_dir_close(dir_new);
399 }
400 } 559 }
401 else { 560 else {
402 strcpy(app_data_dir, newenv); 561 strcpy(app_data_dir, newenv);
403 } 562 }
404 } 563 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "Gaim settings dir: %s\n", app_data_dir);
405 564
406 void wgaim_init(void) { 565 /* IdleTracker Initialization */
407 WORD wVersionRequested;
408 WSADATA wsaData;
409 char newenv[128];
410
411 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "wgaim_init\n");
412
413 load_winver_specific_procs();
414
415 /*
416 * Winsock init
417 */
418 wVersionRequested = MAKEWORD( 2, 2 );
419
420 WSAStartup( wVersionRequested, &wsaData );
421
422 /* Confirm that the winsock DLL supports 2.2 */
423 /* Note that if the DLL supports versions greater than
424 2.2 in addition to 2.2, it will still return 2.2 in
425 wVersion since that is the version we requested. */
426
427 if ( LOBYTE( wsaData.wVersion ) != 2 ||
428 HIBYTE( wsaData.wVersion ) != 2 ) {
429 gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "Could not find a usable WinSock DLL. Oh well.\n");
430 WSACleanup( );
431 }
432
433 /* Disable PANGO UNISCRIBE (for GTK 2.2.0). This may not be necessary in the
434 future because there will most likely be a check to see if we need this,
435 but for now we need to set this in order to avoid poor performance for some
436 windows machines.
437 */
438 sprintf(newenv, "PANGO_WIN32_NO_UNISCRIBE=1");
439 if(putenv(newenv)<0)
440 gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "putenv failed\n");
441
442 /*
443 * IdleTracker Initialization
444 */
445 if(!wgaim_set_idlehooks()) 566 if(!wgaim_set_idlehooks())
446 gaim_debug(GAIM_DEBUG_ERROR, "wgaim", "Failed to initialize idle tracker\n"); 567 gaim_debug(GAIM_DEBUG_ERROR, "wgaim", "Failed to initialize idle tracker\n");
447 568
448 wgaim_gtkspell_init(); 569 wgaim_gtkspell_init();
570 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "wgaim_init end\n");
449 } 571 }
450 572
451 /* Windows Cleanup */ 573 /* Windows Cleanup */
452 574
453 void wgaim_cleanup(void) { 575 void wgaim_cleanup(void) {
454 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "wgaim_cleanup\n"); 576 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "wgaim_cleanup\n");
455 577
456 /* winsock cleanup */ 578 /* winsock cleanup */
457 WSACleanup( ); 579 WSACleanup();
458 580
459 /* Idle tracker cleanup */ 581 /* Idle tracker cleanup */
460 wgaim_remove_idlehooks(); 582 wgaim_remove_idlehooks();
461 } 583 }
462 584