changeset 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 1b5bf4b215f0
children 09faf5b43b8b
files plugins/tcl/Makefile.mingw plugins/tcl/tcl.c plugins/tcl/tcl_win32.c
diffstat 3 files changed, 61 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/tcl/Makefile.mingw	Tue Mar 07 20:11:35 2006 +0000
+++ b/plugins/tcl/Makefile.mingw	Wed Mar 08 03:41:58 2006 +0000
@@ -21,8 +21,6 @@
 
 TARGET = tcl
 
-CC = gcc.exe
-
 # Compiler Options
 
 CFLAGS =
@@ -65,8 +63,7 @@
 C_SRC =			tcl.c \
 			tcl_cmds.c \
 			tcl_glib.c \
-			tcl_signals.c \
-			tcl_win32.c
+			tcl_signals.c
 
 
 OBJECTS = $(C_SRC:%.c=%.o)
--- 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");
 }
--- a/plugins/tcl/tcl_win32.c	Tue Mar 07 20:11:35 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/**
- * @file tcl_win32.c Gaim Tcl Windows Init
- *
- * gaim
- *
- * Copyright (C) 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 "internal.h"
-#include "debug.h"
-#include <tcl.h>
-
-#ifdef HAVE_TK
-#include <tk.h>
-#endif
-
-typedef Tcl_Interp* (CALLBACK* LPFNTCLCREATEINTERP)(void);
-typedef void        (CALLBACK* LPFNTKINIT)(Tcl_Interp*);
-
-LPFNTCLCREATEINTERP wtcl_CreateInterp = NULL;
-LPFNTKINIT wtk_Init = NULL;
-
-static BOOL tcl_win32_init() {
-	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"))) {
-		gaim_debug(GAIM_DEBUG_INFO, "tcl", "tcl_win32_init error loading Tk_Init\n");
-		return FALSE;
-	}
-	return TRUE;
-}
-
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
-	switch (fdwReason) {
-		case DLL_PROCESS_ATTACH:
-			return tcl_win32_init();
-
-		case DLL_THREAD_ATTACH:
-		case DLL_THREAD_DETACH:
-		case DLL_PROCESS_DETACH:
-			break;
-	}
-	return TRUE;
-}
-