# HG changeset patch # User Herman Bloggs # Date 1067271114 0 # Node ID e28728795a45ee3e15a7b5b78d2d2edac22983d9 # Parent 345f3b22ebd67ea7300e72e41cdf853acbceff7d [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 diff -r 345f3b22ebd6 -r e28728795a45 src/win32/win32dep.c --- 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 diff -r 345f3b22ebd6 -r e28728795a45 src/win_gaim.c --- 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 * Date: June, 2002 * Description: Entry point for win32 gaim, and various win32 dependant * routines. + * + * Copyright (C) 2002-2003, Herman Bloggs + * + * 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 #include @@ -12,81 +28,13 @@ #include /* - * 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)>kpath, &plen))) + gotreg = read_reg_string((hkey=HKEY_CURRENT_USER), "SOFTWARE\\GTK\\2.0", "Path", (LPBYTE)>kpath, &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) ®val, + 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"))) {