Mercurial > pidgin.yaz
diff plugins/tcl/tcl.c @ 13455:70197e8ac15c
[gaim-migrate @ 15830]
This makes tcl.c a little uglier, but offers some significant benefits on win32. Firstly, we no longer call LoadLibrary() from within a DllMain function (which is fundamentally unsafe). Secondly, this prints a debugging message indicating that if gaim fails to load it is cygwin's fault. Thirdly, we now try to detect the loading of a cygwin tcl runtime and aborts loading the tcl plugin. The subsequent "hanging" is one of the most reported bugs, so this will hopefully reduce these bug reports.
committer: Tailor Script <tailor@pidgin.im>
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Wed, 08 Mar 2006 03:41:58 +0000 |
parents | 068282089843 |
children | a84523152a24 |
line wrap: on
line diff
--- a/plugins/tcl/tcl.c Tue Mar 07 20:11:35 2006 +0000 +++ b/plugins/tcl/tcl.c Wed Mar 08 03:41:58 2006 +0000 @@ -325,8 +325,8 @@ static gboolean tcl_load(GaimPlugin *plugin) { - if(!tcl_loaded) - return FALSE; + if(!tcl_loaded) + return FALSE; tcl_glib_init(); tcl_signal_init(); tcl_plugins = g_hash_table_new(g_direct_hash, g_direct_equal); @@ -382,45 +382,86 @@ }; #ifdef _WIN32 -extern Tcl_Interp* (CALLBACK* wtcl_CreateInterp)(); -extern void (CALLBACK* wtk_Init)(Tcl_Interp*); +typedef Tcl_Interp* (CALLBACK* LPFNTCLCREATEINTERP)(void); +typedef void (CALLBACK* LPFNTKINIT)(Tcl_Interp*); + +LPFNTCLCREATEINTERP wtcl_CreateInterp = NULL; +LPFNTKINIT wtk_Init = NULL; #undef Tcl_CreateInterp #define Tcl_CreateInterp wtcl_CreateInterp #undef Tk_Init #define Tk_Init wtk_Init + +static gboolean tcl_win32_init() { + gaim_debug(GAIM_DEBUG_INFO, "tcl", + "Initializing the Tcl runtime. If Gaim doesn't load, it is " + "most likely because you have cygwin in your PATH and you " + "should remove it. See http://gaim.sf.net/win32 for more " + "information\n"); + + if(!(wtcl_CreateInterp = (LPFNTCLCREATEINTERP) wgaim_find_and_loadproc("tcl84.dll", "Tcl_CreateInterp"))) { + gaim_debug(GAIM_DEBUG_INFO, "tcl", "tcl_win32_init error loading Tcl_CreateInterp\n"); + return FALSE; + } + + if(!(wtk_Init = (LPFNTKINIT) wgaim_find_and_loadproc("tk84.dll", "Tk_Init"))) { + HMODULE mod; + gaim_debug(GAIM_DEBUG_INFO, "tcl", "tcl_win32_init error loading Tk_Init\n"); + if((mod = GetModuleHandle("tcl84.dll"))) + FreeLibrary(mod); + return FALSE; + } + + if (GetModuleHandle("cygwin1.dll")) { + HMODULE mod; + gaim_debug(GAIM_DEBUG_INFO, "tcl", "Cygwin has been loaded by tcl84.dll and/or tk84.dll. Disabling Tcl support to avoid problems.\n"); + if((mod = GetModuleHandle("tcl84.dll"))) + FreeLibrary(mod); + if((mod = GetModuleHandle("tk84.dll"))) + FreeLibrary(mod); + return FALSE; + } + + return TRUE; +} + #endif /* _WIN32 */ static void tcl_init_plugin(GaimPlugin *plugin) { #ifdef USE_TCL_STUBS - Tcl_Interp *interp=NULL; + Tcl_Interp *interp = NULL; #endif _tcl_plugin = plugin; #ifdef USE_TCL_STUBS - if(!(interp=Tcl_CreateInterp())) - return; +#ifdef _WIN32 + if(!tcl_win32_init()) + return; +#endif + if(!(interp = Tcl_CreateInterp())) + return; - if(!Tcl_InitStubs(interp, TCL_VERSION, 0)) { - gaim_debug(GAIM_DEBUG_ERROR, "tcl", "Tcl_InitStubs: %s\n", interp->result); - return; - } + if(!Tcl_InitStubs(interp, TCL_VERSION, 0)) { + gaim_debug(GAIM_DEBUG_ERROR, "tcl", "Tcl_InitStubs: %s\n", interp->result); + return; + } #endif Tcl_FindExecutable("gaim"); #if defined(USE_TK_STUBS) && defined(HAVE_TK) - Tk_Init(interp); + Tk_Init(interp); - if(!Tk_InitStubs(interp, TK_VERSION, 0)) { - gaim_debug(GAIM_DEBUG_ERROR, "tcl", "Error Tk_InitStubs: %s\n", interp->result); - Tcl_DeleteInterp(interp); - return; - } + if(!Tk_InitStubs(interp, TK_VERSION, 0)) { + gaim_debug(GAIM_DEBUG_ERROR, "tcl", "Error Tk_InitStubs: %s\n", interp->result); + Tcl_DeleteInterp(interp); + return; + } #endif - tcl_loaded = TRUE; + tcl_loaded = TRUE; #ifdef USE_TCL_STUBS - Tcl_DeleteInterp(interp); + Tcl_DeleteInterp(interp); #endif tcl_loader_info.exts = g_list_append(tcl_loader_info.exts, "tcl"); }