changeset 7350:e28728795a45

[gaim-migrate @ 7941] Fix for bug #808562 - LANG needs to be set before gtk_init, when setting text widgets to RTL or LTR. New dll hell avoidance policies.. hopefully this time as many bases are covered as can be. committer: Tailor Script <tailor@pidgin.im>
author Herman Bloggs <hermanator12002@yahoo.com>
date Mon, 27 Oct 2003 16:11:54 +0000
parents 345f3b22ebd6
children d5ed905a8ccd
files src/win32/win32dep.c src/win_gaim.c
diffstat 2 files changed, 171 insertions(+), 185 deletions(-) [+]
line wrap: on
line diff
--- a/src/win32/win32dep.c	Mon Oct 27 15:24:21 2003 +0000
+++ b/src/win32/win32dep.c	Mon Oct 27 16:11:54 2003 +0000
@@ -337,93 +337,6 @@
 	RestoreWndFromTray(GDK_WINDOW_HWND(window->window));
 }
 
-char* wgaim_lcid_to_posix(LCID lcid) {
-        switch(lcid) {
-        case 1026: return "bg"; /* bulgarian */
-        case 1027: return "ca"; /* catalan */
-        case 1050: return "hr"; /* croation */
-        case 1029: return "cs"; /* czech */
-        case 1030: return "da"; /* danaish */
-        case 1043: return "nl"; /* dutch - netherlands */
-        case 1033: return "en"; /* english - us */
-        case 1035: return "fi"; /* finish */
-        case 1036: return "fr"; /* french - france */
-        case 1031: return "de"; /* german - germany */
-        case 1032: return "el"; /* greek */
-        case 1037: return "he"; /* hebrew */
-        case 1038: return "hu"; /* hungarian */
-        case 1040: return "it"; /* italian - italy */
-        case 1041: return "ja"; /* japanese */
-        case 1042: return "ko"; /* korean */
-        case 1063: return "lt"; /* lithuanian */
-        case 1071: return "mk"; /* macedonian */
-        case 1045: return "pl"; /* polish */
-        case 2070: return "pt"; /* portuguese - portugal */
-        case 1046: return "pt_BR"; /* portuguese - brazil */
-        case 1048: return "ro"; /* romanian - romania */
-        case 1049: return "ru"; /* russian - russia */
-        case 2074: return "sr@Latn"; /* serbian - latin */
-        case 3098: return "sr"; /* serbian - cyrillic */
-        case 2052: return "zh_CN"; /* chinese - china (simple) */
-        case 1051: return "sk"; /* slovak */
-        case 1060: return "sl"; /* slovenian */
-        case 1034: return "es"; /* spanish */
-        case 1053: return "sv"; /* swedish */
-        case 1054: return "th"; /* thai */
-        case 1028: return "zh_TW"; /* chinese - taiwan (traditional) */
-        case 1055: return "tr"; /* turkish */
-        case 1058: return "uk"; /* ukrainian */
-        default:
-                gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "Could not find posix code for LCID: %d\n", lcid);
-                return NULL;
-        }
-}
-
-/* Determine and set Gaim locale as follows (in order of priority):
-   - Check LANG env var
-   - Check NSIS Installer Language reg value
-   - Use default user locale
-*/
-void wgaim_set_locale() {
-        HKEY hkey;
-	char* locale=NULL;
-        char envstr[25];
-        LCID lcid;
-
-        /* Check if user set LANG env var */
-        if((locale = (char*)g_getenv("LANG"))) {
-                gaim_debug(GAIM_DEBUG_INFO, "wgaim", "Using locale set by the LANG env var.\n");
-                goto finish;
-        }
-
-        /* Check reg key set at install time */
-        if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, 
-                                         "SOFTWARE\\gaim", 
-					 0,  KEY_QUERY_VALUE, &hkey)) {
-                BYTE data[10];
-                DWORD ds = 10;
-                if(ERROR_SUCCESS == RegQueryValueEx(hkey, "Installer Language", 0, NULL, (LPBYTE)&data, &ds)) {
-			gaim_debug(GAIM_DEBUG_INFO, "wgaim", "Using locale set by the installer\n");
-                        if((locale = wgaim_lcid_to_posix(atoi(data))))
-                                goto finish;
-		}
-        }
-
-        lcid = GetUserDefaultLCID();
-        if((locale = wgaim_lcid_to_posix(lcid)))
-                goto finish;
-
-        finish:
-        if(!locale)
-                locale = "en";
-
-        sprintf(envstr, "LANG=%s", locale);
-        if(putenv(envstr)<0)
-		gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "putenv failed\n");
-
-	gaim_debug(GAIM_DEBUG_INFO, "wgaim", "Locale set to: %s\n", locale);
-}
-
 /* Windows Initializations */
 typedef enum {
     SHGFP_TYPE_CURRENT  = 0,   // current value for user, verify it exists
@@ -517,10 +430,6 @@
 		WSACleanup( );
 	}
 
-        /* Set locale - determines which translations to user, and which
-           aspell dictionary to use */
-        wgaim_set_locale();
-
 	/* 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 
--- a/src/win_gaim.c	Mon Oct 27 15:24:21 2003 +0000
+++ b/src/win_gaim.c	Mon Oct 27 16:11:54 2003 +0000
@@ -1,10 +1,26 @@
 /*
- *  win_aim.c
+ *  win_gaim.c
  *
- *  Author: Herman Bloggs <hermanator12002@yahoo.com>
  *  Date: June, 2002
  *  Description: Entry point for win32 gaim, and various win32 dependant
  *  routines.
+ *
+ *  Copyright (C) 2002-2003, Herman Bloggs <hermanator12002@yahoo.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
  */
 #include <windows.h>
 #include <stdlib.h>
@@ -12,81 +28,13 @@
 #include <stdio.h>
 
 /*
- *  GLOBALS
- */
-__declspec(dllimport) HINSTANCE gaimexe_hInstance;
-
-/*
- *  LOCALS
- */
-static char msg1[] = "The following duplicate of ";
-static char msg2[] = " has been found in your dll search path and will likely\x0d\x0a"
-              "cause Gaim to malfunction:\x0d\x0a\x0d\x0a";
-
-static char msg3[] = "\x0d\x0a\x0d\x0aWould you like to rename this dll to ";
-static char msg4[] = ".prob in order to avoid any possible conflicts?\x0d\x0a"
-                     "\x0d\x0a"
-                     "Note: Doing so will likely cause the application that installed this dll to stop functioning.\x0d\x0a"
-                     "You may wish to inform the author of the responsible application so that future versions\x0d\x0a"
-                     "do not cause 'Dll Hell'.";
-
-/*
  *  PROTOTYPES
  */
-int (*gaim_main)( HINSTANCE, int, char** ) = NULL;
-
-static void check_dll(char* dll, char* orig) {
-        char tmp[MAX_PATH];
-        char *last;
+static int (*gaim_main)( HINSTANCE, int, char** ) = NULL;
+static void (*MySetDllDirectory)(LPCTSTR lpPathName) = NULL;
 
-        if(SearchPath(NULL, dll, NULL, MAX_PATH, tmp, &last)) {
-                char* patha = (char*)malloc(strlen(orig) + strlen(dll) + 4);
-                strcpy(patha, orig);
-                strcat(patha, "\\");
-                strcat(patha, dll);
-                /* Make sure that 2 paths are not the same */
-                if(strcasecmp(patha, tmp) != 0) {
-                        char *warning = (char*)malloc(strlen(msg1)+
-                                                      strlen(msg2)+
-                                                      strlen(msg3)+
-                                                      strlen(msg4)+
-                                                      strlen(tmp)+
-                                                      (strlen(dll)*2)+4);
-                        sprintf(warning, "%s%s%s%s%s%s%s", msg1, dll, msg2, tmp, msg3, dll, msg4);
-                        if(MessageBox(NULL, warning, "Gaim Warning", MB_YESNO | MB_TOPMOST)==IDYES) {
-                                char *newname = (char*)malloc(strlen(tmp)+6);
-                                /* Rename offending dll */
-                                sprintf(newname, "%s%s", tmp, ".prob");
-                                if(rename(tmp, newname) != 0) {
-                                        MessageBox(NULL, "Error renaming file.", NULL, MB_OK | MB_TOPMOST);
-                                }
-                                else
-                                        check_dll(dll, orig);
-                                free(newname);
-                        }
-                        free(warning);
-                }
-                free(patha);
-        }
-}
 
-static void dll_hell_check(char* gtkpath) {
-        HANDLE myHandle;
-        WIN32_FIND_DATA fd;
-        char* srchstr = (char*)malloc(strlen(gtkpath) + 8);
-        
-        sprintf(srchstr, "%s%s", gtkpath, "\\*.dll");
-        myHandle = FindFirstFile(srchstr, &fd );
-        if(myHandle != INVALID_HANDLE_VALUE) {
-                check_dll(fd.cFileName, gtkpath);
-                while(FindNextFile(myHandle, &fd)) {
-                        check_dll(fd.cFileName, gtkpath);
-                }
-        }
-        free(srchstr);
-}
-
-BOOL read_reg_string(HKEY key, char* sub_key, char* val_name, LPBYTE data, LPDWORD data_len) {
+static BOOL read_reg_string(HKEY key, char* sub_key, char* val_name, LPBYTE data, LPDWORD data_len) {
         HKEY hkey;
         BOOL ret = FALSE;
         int retv;
@@ -96,41 +44,167 @@
 					 0,  KEY_QUERY_VALUE, &hkey)) {
                 if(ERROR_SUCCESS == (retv=RegQueryValueEx(hkey, val_name, 0, NULL, data, data_len)))
                         ret = TRUE;
-                else {
-                        printf("Error reading registry string value: %d\n", retv);
-                }
+                else
+                        ret = FALSE;
                 RegCloseKey(key);
         }
         return ret;
 }
 
-void run_dll_check() {
+static void run_dll_prep() {
+        char gtkpath[MAX_PATH];
         char path[MAX_PATH];
         DWORD plen = MAX_PATH;
         int gotreg=FALSE;
+        HKEY hkey;
+        HMODULE hmod;
 
-        /* Dll Hell Check.. Only run check if we are the same gaim as found in the
-           gaim registry key */
-        if(!(gotreg = read_reg_string(HKEY_LOCAL_MACHINE, "SOFTWARE\\gaim", "", (LPBYTE)&path, &plen)))
-                gotreg = read_reg_string(HKEY_CURRENT_USER, "SOFTWARE\\gaim", "", (LPBYTE)&path, &plen);
+        if(!(gotreg = read_reg_string((hkey=HKEY_LOCAL_MACHINE), "SOFTWARE\\GTK\\2.0", "Path", (LPBYTE)&gtkpath, &plen)))
+                gotreg = read_reg_string((hkey=HKEY_CURRENT_USER), "SOFTWARE\\GTK\\2.0", "Path", (LPBYTE)&gtkpath, &plen);
+
+        if(!gotreg)
+                return;
+
+        /* Determine GTK+ dll path .. */
+        if(!read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "DllPath", (LPBYTE)&path, &plen)) {
+                char version[10];
+                char inst[10];
+                DWORD len = 10;
+
+                strcpy(path, gtkpath);
+                if(read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "Version", (LPBYTE)&version, &len) &&
+                   read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "Installer", (LPBYTE)&inst, &len)) {
+                        if(strcmp(version, "2.2.2") >= 0 &&
+                           strcmp(inst, "NSIS") == 0) {
+                                strcat(path, "\\bin");
+                        }
+                        else
+                                strcat(path, "\\lib");
+                }
+                else
+                        strcat(path, "\\lib");
+        }
 
-        if(gotreg) {
-                char modpath[MAX_PATH];
-                
-                strcat(path, "\\gaim.exe");
-                GetModuleFileName(NULL, modpath, MAX_PATH);
-                if(strcasecmp(path, modpath) == 0) {
-                        plen = MAX_PATH;
-                        if(!(gotreg = read_reg_string(HKEY_LOCAL_MACHINE, "SOFTWARE\\GTK\\2.0", "Path", (LPBYTE)&path, &plen)))
-                                gotreg = read_reg_string(HKEY_CURRENT_USER, "SOFTWARE\\GTK\\2.0", "Path", (LPBYTE)&path, &plen);
-                        if(gotreg) {
-                                strcat(path, "\\bin");
-                                dll_hell_check(path);
+        if((hmod=LoadLibrary("kernel32.dll"))) {
+                MySetDllDirectory = (void*)GetProcAddress(hmod, "SetDllDirectory");
+        }
+
+        /* For Windows XP SP1 / Server 2003 we use SetDllDirectory to avoid dll hell */
+        if(MySetDllDirectory)
+                MySetDllDirectory(path);
+        /* For the rest, we set the current directory */
+        else {
+                OSVERSIONINFO osinfo;
+
+                SetCurrentDirectory(path);
+                /* For Windows 2000 SP3 and higher:
+                 * If SafeDllSearchMode is set to 1, Windows system directories are
+                 * searched for dlls before the current directory. Therefore we set it
+                 * to 0.
+                 */
+                osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+                GetVersionEx(&osinfo);
+                if(osinfo.dwMajorVersion == 5 &&
+                   osinfo.dwMinorVersion == 0 &&
+                   strcmp(osinfo.szCSDVersion, "Service Pack 3") >= 0) {
+                        if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
+                                                         "System\\CurrentControlSet\\Control\\Session Manager", 
+                                                         0,  KEY_SET_VALUE, &hkey)) {
+                                DWORD regval = 0;
+                                RegSetValueEx(hkey, 
+                                              "SafeDllSearchMode",
+                                              0,
+                                              REG_DWORD,
+                                              (LPBYTE) &regval,
+                                              sizeof(regval));
+                                RegCloseKey(hkey);
                         }
                 }
         }
 }
 
+static char* wgaim_lcid_to_posix(LCID lcid) {
+        switch(lcid) {
+        case 1026: return "bg"; /* bulgarian */
+        case 1027: return "ca"; /* catalan */
+        case 1050: return "hr"; /* croation */
+        case 1029: return "cs"; /* czech */
+        case 1030: return "da"; /* danaish */
+        case 1043: return "nl"; /* dutch - netherlands */
+        case 1033: return "en"; /* english - us */
+        case 1035: return "fi"; /* finish */
+        case 1036: return "fr"; /* french - france */
+        case 1031: return "de"; /* german - germany */
+        case 1032: return "el"; /* greek */
+        case 1037: return "he"; /* hebrew */
+        case 1038: return "hu"; /* hungarian */
+        case 1040: return "it"; /* italian - italy */
+        case 1041: return "ja"; /* japanese */
+        case 1042: return "ko"; /* korean */
+        case 1063: return "lt"; /* lithuanian */
+        case 1071: return "mk"; /* macedonian */
+        case 1045: return "pl"; /* polish */
+        case 2070: return "pt"; /* portuguese - portugal */
+        case 1046: return "pt_BR"; /* portuguese - brazil */
+        case 1048: return "ro"; /* romanian - romania */
+        case 1049: return "ru"; /* russian - russia */
+        case 2074: return "sr@Latn"; /* serbian - latin */
+        case 3098: return "sr"; /* serbian - cyrillic */
+        case 2052: return "zh_CN"; /* chinese - china (simple) */
+        case 1051: return "sk"; /* slovak */
+        case 1060: return "sl"; /* slovenian */
+        case 1034: return "es"; /* spanish */
+        case 1053: return "sv"; /* swedish */
+        case 1054: return "th"; /* thai */
+        case 1028: return "zh_TW"; /* chinese - taiwan (traditional) */
+        case 1055: return "tr"; /* turkish */
+        case 1058: return "uk"; /* ukrainian */
+        default:
+                return NULL;
+        }
+}
+
+/* Determine and set Gaim locale as follows (in order of priority):
+   - Check LANG env var
+   - Check NSIS Installer Language reg value
+   - Use default user locale
+*/
+static void wgaim_set_locale() {
+        HKEY hkey;
+	char* locale=NULL;
+        char envstr[25];
+        LCID lcid;
+
+        /* Check if user set LANG env var */
+        if((locale = (char*)getenv("LANG"))) {
+                goto finish;
+        }
+
+        /* Check reg key set at install time */
+        if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, 
+                                         "SOFTWARE\\gaim", 
+					 0,  KEY_QUERY_VALUE, &hkey)) {
+                BYTE data[10];
+                DWORD ds = 10;
+                if(ERROR_SUCCESS == RegQueryValueEx(hkey, "Installer Language", 0, NULL, (LPBYTE)&data, &ds)) {
+                        if((locale = wgaim_lcid_to_posix(atoi(data))))
+                                goto finish;
+		}
+        }
+
+        lcid = GetUserDefaultLCID();
+        if((locale = wgaim_lcid_to_posix(lcid)))
+                goto finish;
+
+        finish:
+        if(!locale)
+                locale = "en";
+
+        sprintf(envstr, "LANG=%s", locale);
+        putenv(envstr);
+}
+
+
 #ifdef __GNUC__
 #  ifndef _stdcall
 #    define _stdcall  __attribute__((stdcall))
@@ -149,7 +223,7 @@
 
         /* If GAIM_NO_DLL_CHECK is set, don't run the dll check */
         if(!getenv("GAIM_NO_DLL_CHECK"))
-                run_dll_check();
+                run_dll_prep();
 
         /* Load exception handler if we have it */
         GetModuleFileName(NULL, gaimdir, MAX_PATH);
@@ -158,6 +232,9 @@
                 strcat(gaimdir, "exchndl.dll");
                 LoadLibrary(gaimdir);
         }
+        
+        /* Set Gaim locale */
+        wgaim_set_locale();
 
         /* Now we are ready for Gaim .. */
         if((hmod=LoadLibrary("gaim.dll"))) {