tcl.c

来自「Linux下的多协议即时通讯程序源代码」· C语言 代码 · 共 554 行 · 第 1/2 页

C
554
字号
	Tcl_Interp *interp;	Tcl_Obj *result;	plugin->extra = NULL;	if ((interp = tcl_create_interp()) == NULL) {		purple_debug(PURPLE_DEBUG_ERROR, "tcl", "Could not initialize Tcl interpreter\n");		return FALSE;	}	Tcl_SourceRCFile(interp);	if (Tcl_EvalFile(interp, plugin->path) != TCL_OK) {		result = Tcl_GetObjResult(interp);		purple_debug(PURPLE_DEBUG_ERROR, "tcl",		           "Error evaluating %s: %s\n", plugin->path,		           Tcl_GetString(result));		Tcl_DeleteInterp(interp);		return FALSE;	}	Tcl_Preserve((ClientData)interp);	data = g_new0(struct tcl_plugin_data, 1);	data->plugin = plugin;	data->interp = interp;	plugin->extra = data;	g_hash_table_insert(tcl_plugins, (gpointer)interp, (gpointer)data);	return TRUE;}static gboolean tcl_unload_plugin(PurplePlugin *plugin){	struct tcl_plugin_data *data;	if (plugin == NULL)		return TRUE;	data = plugin->extra;	if (data != NULL) {		g_hash_table_remove(tcl_plugins, (gpointer)(data->interp));		purple_signals_disconnect_by_handle(data->interp);		tcl_cmd_cleanup(data->interp);		tcl_signal_cleanup(data->interp);		Tcl_Release((ClientData)data->interp);		Tcl_DeleteInterp(data->interp);		g_free(data);	}	return TRUE;}static void tcl_destroy_plugin(PurplePlugin *plugin){	if (plugin->info != NULL) {		g_free(plugin->info->id);		g_free(plugin->info->name);		g_free(plugin->info->version);		g_free(plugin->info->description);		g_free(plugin->info->author);		g_free(plugin->info->homepage);	}	return;}static gboolean tcl_load(PurplePlugin *plugin){	if(!tcl_loaded)		return FALSE;	tcl_glib_init();	tcl_cmd_init();	tcl_signal_init();	purple_tcl_ref_init();	PurpleTclRefAccount = purple_stringref_new("Account");	PurpleTclRefConnection = purple_stringref_new("Connection");	PurpleTclRefConversation = purple_stringref_new("Conversation");	PurpleTclRefPointer = purple_stringref_new("Pointer");	PurpleTclRefPlugin = purple_stringref_new("Plugin");	PurpleTclRefPresence = purple_stringref_new("Presence");	PurpleTclRefStatus = purple_stringref_new("Status");	PurpleTclRefStatusAttr = purple_stringref_new("StatusAttr");	PurpleTclRefStatusType = purple_stringref_new("StatusType");	PurpleTclRefXfer = purple_stringref_new("Xfer");	tcl_plugins = g_hash_table_new(g_direct_hash, g_direct_equal);#ifdef HAVE_TK	Tcl_StaticPackage(NULL, "Tk", Tk_Init, Tk_SafeInit);#endif /* HAVE_TK */	return TRUE;}static gboolean tcl_unload(PurplePlugin *plugin){	g_hash_table_destroy(tcl_plugins);	tcl_plugins = NULL;	purple_stringref_unref(PurpleTclRefAccount);	purple_stringref_unref(PurpleTclRefConnection);	purple_stringref_unref(PurpleTclRefConversation);	purple_stringref_unref(PurpleTclRefPointer);	purple_stringref_unref(PurpleTclRefPlugin);	purple_stringref_unref(PurpleTclRefPresence);	purple_stringref_unref(PurpleTclRefStatus);	purple_stringref_unref(PurpleTclRefStatusAttr);	purple_stringref_unref(PurpleTclRefStatusType);	purple_stringref_unref(PurpleTclRefXfer);	return TRUE;}static PurplePluginLoaderInfo tcl_loader_info ={	NULL,	tcl_probe_plugin,	tcl_load_plugin,	tcl_unload_plugin,	tcl_destroy_plugin,	/* pidgin */	NULL,	NULL,	NULL,	NULL};static PurplePluginInfo tcl_info ={	PURPLE_PLUGIN_MAGIC,	PURPLE_MAJOR_VERSION,	PURPLE_MINOR_VERSION,	PURPLE_PLUGIN_LOADER,	NULL,	0,	NULL,	PURPLE_PRIORITY_DEFAULT,	"core-tcl",	N_("Tcl Plugin Loader"),	VERSION,	N_("Provides support for loading Tcl plugins"),	N_("Provides support for loading Tcl plugins"),	"Ethan Blanton <eblanton@cs.purdue.edu>",	PURPLE_WEBSITE,	tcl_load,	tcl_unload,	NULL,	NULL,	&tcl_loader_info,	NULL,	NULL,	/* padding */	NULL,	NULL,	NULL,	NULL};#ifdef _WIN32typedef 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_Initstatic gboolean tcl_win32_init() {	const char regkey[] = "SOFTWARE\\ActiveState\\ActiveTcl\\";	char *version = NULL;	gboolean retval = FALSE;	if ((version = wpurple_read_reg_string(HKEY_LOCAL_MACHINE, regkey, "CurrentVersion"))			|| (version = wpurple_read_reg_string(HKEY_CURRENT_USER, regkey, "CurrentVersion"))) {		char *path = NULL;		char *regkey2;		char **tokens;		int major = 0, minor = 0, micro = 0;		tokens = g_strsplit(version, ".", 0);		if (tokens[0] && tokens[1] && tokens[2]) {			major = atoi(tokens[0]);			minor = atoi(tokens[1]);			micro = atoi(tokens[2]);		}		g_strfreev(tokens);		regkey2 = g_strdup_printf("%s%s\\", regkey, version);		if (!(major == 8 && minor == 4 && micro >= 5))			purple_debug(PURPLE_DEBUG_INFO, "tcl", "Unsupported ActiveTCL version %s found.\n", version);		else if ((path = wpurple_read_reg_string(HKEY_LOCAL_MACHINE, regkey2, NULL)) || (path = wpurple_read_reg_string(HKEY_CURRENT_USER, regkey2, NULL))) {			char *tclpath;			char *tkpath;			purple_debug(PURPLE_DEBUG_INFO, "tcl", "Loading ActiveTCL version %s from \"%s\"\n", version, path);			tclpath = g_build_filename(path, "bin", "tcl84.dll", NULL);			tkpath = g_build_filename(path, "bin", "tk84.dll", NULL);			if(!(wtcl_CreateInterp = (LPFNTCLCREATEINTERP) wpurple_find_and_loadproc(tclpath, "Tcl_CreateInterp"))) {				purple_debug(PURPLE_DEBUG_INFO, "tcl", "tcl_win32_init error loading Tcl_CreateInterp\n");			} else {				if(!(wtk_Init = (LPFNTKINIT) wpurple_find_and_loadproc(tkpath, "Tk_Init"))) {					HMODULE mod;					purple_debug(PURPLE_DEBUG_INFO, "tcl", "tcl_win32_init error loading Tk_Init\n");					if((mod = GetModuleHandle("tcl84.dll")))						FreeLibrary(mod);				} else {					retval = TRUE;				}			}			g_free(tclpath);			g_free(tkpath);		}		g_free(path);		g_free(regkey2);	}	g_free(version);	if (!retval)		purple_debug(PURPLE_DEBUG_INFO, "tcl", _("Unable to detect ActiveTCL installation. If you wish to use TCL plugins, install ActiveTCL from http://www.activestate.com\n"));	return retval;}#endif /* _WIN32 */static void tcl_init_plugin(PurplePlugin *plugin){#ifdef USE_TCL_STUBS	Tcl_Interp *interp = NULL;#endif	_tcl_plugin = plugin;#ifdef USE_TCL_STUBS#ifdef _WIN32	if(!tcl_win32_init())		return;#endif	if(!(interp = Tcl_CreateInterp()))		return;	if(!Tcl_InitStubs(interp, TCL_VERSION, 0)) {		purple_debug(PURPLE_DEBUG_ERROR, "tcl", "Tcl_InitStubs: %s\n", interp->result);		return;	}#endif	Tcl_FindExecutable("purple");#if defined(USE_TK_STUBS) && defined(HAVE_TK)	Tk_Init(interp);	if(!Tk_InitStubs(interp, TK_VERSION, 0)) {		purple_debug(PURPLE_DEBUG_ERROR, "tcl", "Error Tk_InitStubs: %s\n", interp->result);		Tcl_DeleteInterp(interp);		return;	}#endif	tcl_loaded = TRUE;#ifdef USE_TCL_STUBS	Tcl_DeleteInterp(interp);#endif	tcl_loader_info.exts = g_list_append(tcl_loader_info.exts, "tcl");}PURPLE_INIT_PLUGIN(tcl, tcl_init_plugin, tcl_info)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?