changeset 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 07156f873116
children 5fbc055c15c7
files src/win32/win32dep.c src/win32/win32dep.h
diffstat 2 files changed, 232 insertions(+), 112 deletions(-) [+]
line wrap: on
line diff
--- a/src/win32/win32dep.c	Sun Nov 16 01:50:39 2003 +0000
+++ b/src/win32/win32dep.c	Sun Nov 16 01:52:48 2003 +0000
@@ -44,16 +44,31 @@
 #include "zlib.h"
 #include "untar.h"
 
-#  include <libintl.h>
-#  define _(x) gettext(x)
+#include <libintl.h>
 
 /*
  *  DEFINES & MACROS
  */
+#define _(x) gettext(x)
 
 /*
  * DATA STRUCTS
  */
+
+/* For shfolder.dll */
+typedef HRESULT (CALLBACK* LPFNSHGETFOLDERPATH)(HWND, int, HANDLE, DWORD, LPTSTR);
+
+typedef enum {
+    SHGFP_TYPE_CURRENT  = 0,   // current value for user, verify it exists
+    SHGFP_TYPE_DEFAULT  = 1,   // default value, may not exist
+} SHGFP_TYPE;
+
+#define CSIDL_APPDATA 0x001a
+#define CSIDL_FLAG_CREATE 0x8000
+
+/* flash info */
+typedef BOOL (CALLBACK* LPFNFLASHWINDOWEX)(PFLASHWINFO);
+
 struct _WGAIM_FLASH_INFO {
 	guint t_handle;
 	guint sig_handler;
@@ -63,7 +78,7 @@
 /*
  * LOCALS
  */
-static char app_data_dir[MAX_PATH];
+static char app_data_dir[MAX_PATH] = "C:";
 static char install_dir[MAXPATHLEN];
 static char lib_dir[MAXPATHLEN];
 static char locale_dir[MAXPATHLEN];
@@ -78,11 +93,12 @@
 /*
  *  PROTOS
  */
-BOOL (*MyFlashWindowEx)(PFLASHWINFO pfwi)=NULL;
-HRESULT (*SHGetFolderPath)(HWND, int, HANDLE, DWORD, LPTSTR) = NULL;
+LPFNFLASHWINDOWEX MyFlashWindowEx = NULL;
+LPFNSHGETFOLDERPATH MySHGetFolderPath = NULL;
 
 FARPROC wgaim_find_and_loadproc(char*, char*);
 extern void wgaim_gtkspell_init();
+char* wgaim_data_dir(void);
 
 /*
  *  STATIC CODE
@@ -105,17 +121,159 @@
 
 static void load_winver_specific_procs(void) {
 	/* Used for Win98+ and WinNT5+ */
-	MyFlashWindowEx = (void*)wgaim_find_and_loadproc("user32.dll", "FlashWindowEx" );
+	MyFlashWindowEx = (LPFNFLASHWINDOWEX)wgaim_find_and_loadproc("user32.dll", "FlashWindowEx" );
+}
+
+static char* base_name(char* path) {
+        char *tmp = path;
+        char *prev = NULL;
+
+        while((tmp=strchr(tmp, '\\'))) {
+                prev = tmp;
+                tmp += 1;
+        }
+        if(prev)
+                return ++prev;
+        else
+                return NULL;
+}
+
+BOOL folder_exists(char *folder) {
+        BOOL ret = FALSE;
+        WIN32_FIND_DATA fileinfo;
+        HANDLE fh;
+
+        memset(&fileinfo, 0, sizeof(WIN32_FIND_DATA));
+        if((fh=FindFirstFile(folder, &fileinfo))) {
+                if(fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+                        ret = TRUE;
+                        SetLastError(ERROR_SUCCESS);
+                }
+                else
+                        SetLastError(ERROR_FILE_EXISTS);
+                FindClose(fh);
+        }
+        return ret;
+}
+
+/* Recursively create directories in the dest path */
+static BOOL CreateDirectoryR(char *dest) {
+        static BOOL start = TRUE;
+        BOOL ret = FALSE;
+
+        if(!dest)
+                return ret;
+
+        if(start) {
+                char *str = g_strdup(dest);
+                start = FALSE;
+                ret = CreateDirectoryR(str);
+                g_free(str);
+                start = TRUE;
+        }
+        else {
+                char *tmp1 = dest;
+                char *tmp=NULL;
+
+                while((tmp1=strchr(tmp1, '\\'))) {
+                        tmp = tmp1;
+                        tmp1+=1;
+                }
+                
+                if(tmp) {
+                        tmp[0] = '\0';
+                        CreateDirectoryR(dest);
+                        tmp[0] = '\\';
+                        if(CreateDirectory(dest, NULL) == 0 && GetLastError() != ERROR_ALREADY_EXISTS) {
+                                gaim_debug(GAIM_DEBUG_ERROR, "wgaim",
+                                           "Error creating directory: %s. Errno: %u\n", 
+                                           dest, (UINT)GetLastError());
+                        }
+                        else
+                                ret = TRUE;
+                }
+        }
+        return ret;
+}
+
+static BOOL move_folder(char *src, char* dest, char* copytitle, BOOL overwrite) {
+        char *tsrc, *tdest;
+        SHFILEOPSTRUCT dirmove;
+        BOOL ret = FALSE;
+
+        g_return_val_if_fail(src!=NULL, ret);
+        g_return_val_if_fail(dest!=NULL, ret);
+
+        if(!folder_exists(src)) {
+                gaim_debug(GAIM_DEBUG_WARNING, "wgaim", 
+                           "move_folder: Source folder %s, does not exist\n", src);
+                return ret;
+        }
+        if(!overwrite) {
+                char *dstpath = g_strdup_printf("%s\\%s", dest, base_name(src));
+
+                if(folder_exists(dstpath)) {
+                        gaim_debug(GAIM_DEBUG_WARNING, "wgaim", 
+                                   "move_folder: Destination Folder %s, already exists\n", dstpath);
+                        g_free(dstpath);
+                        return ret;
+                }
+                g_free(dstpath);
+        }
+
+        /* Create dest folder if it doesn't exist */
+        if(!CreateDirectoryR(dest)) {
+                gaim_debug(GAIM_DEBUG_ERROR, "wgaim", "Error creating directory: %s\n", dest);
+                return ret;
+        }
+
+        tsrc = g_strdup_printf("%s%c", src, '\0');
+        tdest = g_strdup_printf("%s%c", dest, '\0');
+
+        memset(&dirmove, 0, sizeof(SHFILEOPSTRUCT));
+        dirmove.wFunc = FO_MOVE;
+        dirmove.pFrom = tsrc;
+        dirmove.pTo = tdest;
+        dirmove.fFlags = FOF_NOCONFIRMATION | FOF_SIMPLEPROGRESS;
+        dirmove.hNameMappings = 0;
+        dirmove.lpszProgressTitle = copytitle;
+
+        if(SHFileOperation(&dirmove)==0)
+                ret = TRUE;
+
+        g_free(tsrc);
+        g_free(tdest);
+        return ret;
+}
+
+static void move_settings_dir() {
+        char *old_home = g_strdup_printf("%s%s", g_get_home_dir() ? g_get_home_dir() : "C:", "\\.gaim");
+        char *new_home = g_strdup_printf("%s%s", wgaim_data_dir(), "\\.gaim");
+
+        if(folder_exists(old_home) && !folder_exists(new_home)) {
+                if(move_folder(old_home, wgaim_data_dir(), _("Moving Gaim Settings.."), FALSE)) {
+                        char *locenc, *locenc1, *str;
+                        gaim_debug(GAIM_DEBUG_INFO, "wgaim", "Success moving '.gaim' directory\n");
+                        str = g_strdup_printf("%s%s", _("Moving Gaim user settings to: "), new_home);
+                        locenc=g_locale_from_utf8(str, -1, NULL, NULL, NULL);
+                        locenc1=g_locale_from_utf8(_("Notification"), -1, NULL, NULL, NULL);
+                        MessageBox(NULL, locenc, locenc1, MB_OK | MB_TOPMOST);
+                        g_free(locenc);
+                        g_free(locenc1);
+                        g_free(str);
+                }
+                else
+                        gaim_debug(GAIM_DEBUG_ERROR, "wgaim", 
+                                   "Failed to move '.gaim' directory to %s.\n", wgaim_data_dir());
+        }
+        g_free(new_home);
+        g_free(old_home);
 }
 
 /*
  *  PUBLIC CODE
  */
 
-void wgaim_set_hinstance(HINSTANCE hint) {
-	gaimexe_hInstance = hint;
-}
-
 HINSTANCE wgaim_hinstance(void) {
 	return gaimexe_hInstance;
 }
@@ -245,7 +403,7 @@
                 return;
 	if(MyFlashWindowEx) {
 		FLASHWINFO info;
-
+                memset(&info, 0, sizeof(FLASHWINFO));
 		info.cbSize = sizeof(FLASHWINFO);
 		info.hwnd = GDK_WINDOW_HWND(window->window);
 		info.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG;
@@ -337,16 +495,42 @@
 	RestoreWndFromTray(GDK_WINDOW_HWND(window->window));
 }
 
-/* Windows Initializations */
-typedef enum {
-    SHGFP_TYPE_CURRENT  = 0,   // current value for user, verify it exists
-    SHGFP_TYPE_DEFAULT  = 1,   // default value, may not exist
-} SHGFP_TYPE;
+void wgaim_init(HINSTANCE hint) {
+	WORD wVersionRequested;
+	WSADATA wsaData;
+	char *perlenv;
+        char *newenv;
+
+	gaim_debug(GAIM_DEBUG_INFO, "wgaim", "wgaim_init start\n");
+
+	gaimexe_hInstance = hint;
+
+	load_winver_specific_procs();
+
+	/* Winsock init */
+	wVersionRequested = MAKEWORD( 2, 2 );
+	WSAStartup( wVersionRequested, &wsaData );
 
-#define CSIDL_APPDATA 0x001a
+	/* Confirm that the winsock DLL supports 2.2 */
+	/* Note that if the DLL supports versions greater than
+	   2.2 in addition to 2.2, it will still return 2.2 in 
+	   wVersion since that is the version we requested. */
+	if ( LOBYTE( wsaData.wVersion ) != 2 ||
+             HIBYTE( wsaData.wVersion ) != 2 ) {
+		gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "Could not find a usable WinSock DLL.  Oh well.\n");
+		WSACleanup();
+	}
 
-void wgaim_pre_plugin_init(void) {
-        char *perlenv, *newenv;
+        /* Set Environmental Variables */
+	/* Disable PANGO UNISCRIBE (for GTK 2.2.0). This may not be necessary in the
+	   future because there will most likely be a check to see if we need this.
+	   For now we need to set this in order to avoid poor performance for some 
+	   windows machines.
+	*/
+	newenv = g_strdup("PANGO_WIN32_NO_UNISCRIBE=1");
+	if(putenv(newenv)<0)
+		gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "putenv failed\n");
+        g_free(newenv);
 
         /* Tell perl where to find Gaim's perl modules */
         perlenv = (char*)g_getenv("PERL5LIB");
@@ -359,93 +543,31 @@
 		gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "putenv failed\n");
         g_free(newenv);
 
-        /* Set app data dir, where to save Gaim user settings */
+        /* Set app data dir, used by gaim_home_dir */
         newenv = (char*)g_getenv("HOME");
         if(!newenv) {
-                SHGetFolderPath = (void*)wgaim_find_and_loadproc("shfolder.dll", "SHGetFolderPathA");
-                if(SHGetFolderPath) {
-                        HRESULT hrResult = SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, app_data_dir);
-                        if(hrResult != S_FALSE && hrResult != E_FAIL && hrResult != E_INVALIDARG) {
-                                gaim_debug(GAIM_DEBUG_INFO, "wgaim", "APP DATA PATH set to: %s\n", app_data_dir);
-                        }
-                        else
-                                strcpy(app_data_dir, "C:");
+                if((MySHGetFolderPath = (LPFNSHGETFOLDERPATH)wgaim_find_and_loadproc("shfolder.dll", "SHGetFolderPathA"))) {
+                        MySHGetFolderPath(NULL,
+                                          CSIDL_APPDATA, 
+                                          NULL, SHGFP_TYPE_CURRENT, app_data_dir);
                 }
-
+                else
+                        strcpy(app_data_dir, "C:");
                 /* As of 0.69, using SHGetFolderPath to determine app settings directory.
                    Move app settings to new location if need be. */
-                { 
-                        char *old_home = g_strdup_printf("%s%s", g_get_home_dir() ? g_get_home_dir() : "C:", "\\.gaim");
-                        char *new_home = g_strdup_printf("%s\\.gaim", wgaim_data_dir());
-                        GDir *dir_old, *dir_new;
-
-                        dir_old = g_dir_open(old_home, 0, NULL);
-                        dir_new = g_dir_open(new_home, 0, NULL);
-                        if(dir_old && !dir_new) {
-                                gaim_notify_message(NULL, 
-                                                    GAIM_NOTIFY_MSG_INFO,
-                                                    _("Notification"), 
-                                                    _("Moving Gaim user settings directory to:"),
-                                                    new_home,
-                                                    NULL,
-                                                    NULL);
-                                if(MoveFile(old_home, new_home) != 0)
-                                        gaim_debug(GAIM_DEBUG_INFO, "wgaim", "Success moving '.gaim' directory\n");
-                        }
-                        g_free(new_home);
-                        g_free(old_home);
-                        if(dir_old) g_dir_close(dir_old);
-                        if(dir_new) g_dir_close(dir_new);
-                }
+                move_settings_dir();
         }
         else {
                 strcpy(app_data_dir, newenv);
         }
-}
-
-void wgaim_init(void) {
-	WORD wVersionRequested;
-	WSADATA wsaData;
-	char newenv[128];
-
-	gaim_debug(GAIM_DEBUG_INFO, "wgaim", "wgaim_init\n");
-
-	load_winver_specific_procs();
-
-	/*
-	 *  Winsock init
-	 */
-	wVersionRequested = MAKEWORD( 2, 2 );
-
-	WSAStartup( wVersionRequested, &wsaData );
+        gaim_debug(GAIM_DEBUG_INFO, "wgaim", "Gaim settings dir: %s\n", app_data_dir);
 
-	/* Confirm that the winsock DLL supports 2.2 */
-	/* Note that if the DLL supports versions greater than
-	   2.2 in addition to 2.2, it will still return 2.2 in 
-	   wVersion since that is the version we requested. */
-
-	if ( LOBYTE( wsaData.wVersion ) != 2 ||
-			HIBYTE( wsaData.wVersion ) != 2 ) {
-		gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "Could not find a usable WinSock DLL.  Oh well.\n");
-		WSACleanup( );
-	}
-
-	/* Disable PANGO UNISCRIBE (for GTK 2.2.0). This may not be necessary in the
-	   future because there will most likely be a check to see if we need this,
-	   but for now we need to set this in order to avoid poor performance for some 
-	   windows machines.
-	*/
-	sprintf(newenv, "PANGO_WIN32_NO_UNISCRIBE=1");
-	if(putenv(newenv)<0)
-		gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "putenv failed\n");
-
-	/*
-	 *  IdleTracker Initialization
-	 */
+	/* IdleTracker Initialization */
 	if(!wgaim_set_idlehooks())
 		gaim_debug(GAIM_DEBUG_ERROR, "wgaim", "Failed to initialize idle tracker\n");
 
 	wgaim_gtkspell_init();
+        gaim_debug(GAIM_DEBUG_INFO, "wgaim", "wgaim_init end\n");
 }
 
 /* Windows Cleanup */
@@ -454,7 +576,7 @@
 	gaim_debug(GAIM_DEBUG_INFO, "wgaim", "wgaim_cleanup\n");
 
 	/* winsock cleanup */
-	WSACleanup( );
+	WSACleanup();
 
 	/* Idle tracker cleanup */
 	wgaim_remove_idlehooks();
--- a/src/win32/win32dep.h	Sun Nov 16 01:50:39 2003 +0000
+++ b/src/win32/win32dep.h	Sun Nov 16 01:52:48 2003 +0000
@@ -37,30 +37,28 @@
  ** win32dep.c
  **/
 /* Windows helper functions */
-void wgaim_set_hinstance(HINSTANCE);
-HINSTANCE wgaim_hinstance(void);
-FARPROC wgaim_find_and_loadproc(char*, char*);
-gboolean wgaim_read_reg_string(HKEY key, char* sub_key, char* val_name, LPBYTE data, LPDWORD data_len);
+extern HINSTANCE wgaim_hinstance(void);
+extern FARPROC   wgaim_find_and_loadproc(char*, char*);
+extern gboolean  wgaim_read_reg_string(HKEY key, char* sub_key, char* val_name, LPBYTE data, LPDWORD data_len);
+extern char*     wgaim_escape_dirsep(char*);
 /* Determine Gaim paths */
-extern char* wgaim_install_dir(void);
-extern char* wgaim_lib_dir(void);
-extern char* wgaim_locale_dir(void);
-extern char* wgaim_data_dir(void);
-extern char* wgaim_escape_dirsep(char*);
+extern char*     wgaim_install_dir(void);
+extern char*     wgaim_lib_dir(void);
+extern char*     wgaim_locale_dir(void);
+extern char*     wgaim_data_dir(void);
 /* UI related */
-extern void wgaim_conv_im_blink(GtkWidget*);
-extern void wgaim_conv_im_blink_state(gboolean val);
-extern void wgaim_gtk_window_move(GtkWindow *window, gint x, gint y);
+extern void      wgaim_conv_im_blink(GtkWidget*);
+extern void      wgaim_conv_im_blink_state(gboolean val);
+extern void      wgaim_gtk_window_move(GtkWindow *window, gint x, gint y);
 /* Utility */
-extern int wgaim_gz_decompress(const char* in, const char* out);
-extern int wgaim_gz_untar(const char* filename, const char* destdir);
+extern int       wgaim_gz_decompress(const char* in, const char* out);
+extern int       wgaim_gz_untar(const char* filename, const char* destdir);
 /* Docklet */
-extern void wgaim_systray_minimize( GtkWidget* );
-extern void wgaim_systray_maximize( GtkWidget* );
+extern void      wgaim_systray_minimize( GtkWidget* );
+extern void      wgaim_systray_maximize( GtkWidget* );
 /* init / cleanup */
-extern void wgaim_pre_plugin_init(void);
-extern void wgaim_init(void);
-extern void wgaim_cleanup(void);
+extern void      wgaim_init(HINSTANCE);
+extern void      wgaim_cleanup(void);
 
 /*
  *  MACROS