Mercurial > pidgin.yaz
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 |