diff src/plugins.c @ 2393:a7ecfd3f7714

[gaim-migrate @ 2406] Arkadiusz Miskiewicz\'s Gadu-Gadu plugin. I was able to figure out enough polish to be able to download Gadu-Gadu, create an account, and test the plugin. Imagine my shock when I got my info and it said I was a woman. Whoops. Also splitting plugins.c so that non-gtk stuff is in modules.c. gaim-core is almost ready for protocol implantaion. Also fixing an IRC bug. Also patiently waiting for anoncvs_gaim's lock in /cvsroot/gaim/gaim/pixmaps committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Sat, 29 Sep 2001 23:06:30 +0000
parents 2927c2c26fe6
children 6e637ad18494
line wrap: on
line diff
--- a/src/plugins.c	Sat Sep 29 02:08:00 2001 +0000
+++ b/src/plugins.c	Sat Sep 29 23:06:30 2001 +0000
@@ -34,6 +34,8 @@
 #include <config.h>
 #endif
 
+#ifdef GAIM_PLUGINS
+
 #include <string.h>
 #include <sys/time.h>
 
@@ -46,10 +48,6 @@
 #include <gtk/gtk.h>
 #include "gaim.h"
 
-#ifdef GAIM_PLUGINS
-
-#include <dlfcn.h>
-
 #include "pixmaps/gnome_add.xpm"
 #include "pixmaps/gnome_remove.xpm"
 #include "pixmaps/gnome_preferences.xpm"
@@ -59,11 +57,6 @@
 #define PATHSIZE 1024	/* XXX: stolen from dialogs.c */
 
 
-/* ------------------ Global Variables ----------------------- */
-
-GList *plugins = NULL;
-GList *callbacks = NULL;
-
 /* ------------------ Local Variables ------------------------ */
 
 static GtkWidget *plugin_dialog = NULL;
@@ -84,25 +77,16 @@
 /* --------------- Function Declarations --------------------- */
 
 void show_plugins(GtkWidget *, gpointer);
-void load_plugin(char *);
-
-void gaim_signal_connect(GModule *, enum gaim_event, void *, void *);
-void gaim_signal_disconnect(GModule *, enum gaim_event, void *);
-void gaim_plugin_unload(GModule *);
 
 /* UI button callbacks */
+static void unload_plugin_cb(GtkWidget *, gpointer);
 static void plugin_reload_cb(GtkWidget *, gpointer);
 
 static const gchar *plugin_makelistname(GModule *);
-static void plugin_remove_callbacks(GModule *);
-
-static void plugin_reload(struct gaim_plugin *p);
 
 static void destroy_plugins(GtkWidget *, gpointer);
 static void load_file(GtkWidget *, gpointer);
 static void load_which_plugin(GtkWidget *, gpointer);
-static void unload_plugin(GtkWidget *, gpointer);
-static void unload_immediate(GModule *);
 static void list_clicked(GtkWidget *, struct gaim_plugin *);
 static void update_show_plugins();
 static void hide_plugins(GtkWidget *, gpointer);
@@ -166,80 +150,8 @@
 	if (plugin_dialog)
 		gtk_widget_destroy(plugin_dialog);
 	plugin_dialog = NULL;
-}
-
-void load_plugin(char *filename)
-{
-	struct gaim_plugin *plug;
-	GList *c = plugins;
-	char *(*gaim_plugin_init)(GModule *);
-	char *(*cfunc)();
-	char *error;
-	char *retval;
-
-	if (!g_module_supported())
-		return;
-	if (filename && !strlen(filename))
-		return;
-
-	while (filename && c) {
-		plug = (struct gaim_plugin *)c->data;
-		if (!strcmp(filename, g_module_name(plug->handle))) {
-			/* just need to reload plugin */
-			plugin_reload(plug);
-			return;
-		} else
-			c = g_list_next(c);
-	}
-	plug = g_malloc(sizeof *plug);
-
-	if (filename) {
-		if (last_dir)
-			g_free(last_dir);
-		last_dir = g_dirname(filename);
-	}
-
-	debug_printf("Loading %s\n", filename);
-	plug->handle = g_module_open(filename, 0);
-	if (!plug->handle) {
-		error = (char *)g_module_error();
-		do_error_dialog(error, _("Plugin Error"));
-		g_free(plug);
-		return;
-	}
-
-	if (!g_module_symbol(plug->handle, "gaim_plugin_init", (gpointer *)&gaim_plugin_init)) {
-		do_error_dialog(g_module_error(), _("Plugin Error"));
-		g_module_close(plug->handle);
-		g_free(plug);
-		return;
-	}
-
-	retval = (*gaim_plugin_init)(plug->handle);
-	debug_printf("loaded plugin returned %s\n", retval ? retval : "NULL");
-	if (retval) {
-		plugin_remove_callbacks(plug->handle);
-		do_error_dialog(retval, _("Plugin Error"));
-		g_module_close(plug->handle);
-		g_free(plug);
-		return;
-	}
-
-	plugins = g_list_append(plugins, plug);
-
-	if (g_module_symbol(plug->handle, "name", (gpointer *)&cfunc)) {
-		plug->name = (*cfunc)();
-	} else {
-		plug->name = NULL;
-	}
-
-	if (g_module_symbol(plug->handle, "description", (gpointer *)&cfunc))
-		plug->description = (*cfunc)();
-	else
-		plug->description = NULL;
 
 	update_show_plugins();
-	save_prefs();
 }
 
 void show_plugins(GtkWidget *w, gpointer data)
@@ -358,7 +270,7 @@
 	gtk_tooltips_set_tip(tooltips, reload, _("Reload the selected plugin"), "");
 
 	unload = picture_button(plugwindow, _("Unload"), gnome_remove_xpm);
-	gtk_signal_connect(GTK_OBJECT(unload), "clicked", GTK_SIGNAL_FUNC(unload_plugin), pluglist);
+	gtk_signal_connect(GTK_OBJECT(unload), "clicked", GTK_SIGNAL_FUNC(unload_plugin_cb), pluglist);
 	gtk_box_pack_start(GTK_BOX(bothbox), unload, TRUE, TRUE, 0);
 	gtk_tooltips_set_tip(tooltips, unload, _("Unload the selected plugin"), "");
 
@@ -415,11 +327,10 @@
 	}
 }
 
-static void unload_plugin(GtkWidget *w, gpointer data)
+static void unload_plugin_cb(GtkWidget *w, gpointer data)
 {
 	GList *i;
 	struct gaim_plugin *p;
-	void (*gaim_plugin_remove)();
 
 	i = GTK_LIST(pluglist)->selection;
 
@@ -428,105 +339,28 @@
 
 	p = gtk_object_get_user_data(GTK_OBJECT(i->data));
 
-	/* Attempt to call the plugin's remove function (if there) */
-	if (g_module_symbol(p->handle, "gaim_plugin_remove", (gpointer *)&gaim_plugin_remove))
-		(*gaim_plugin_remove)();
-
-	unload_immediate(p->handle);
+	unload_plugin(p);
 	update_show_plugins();
 }
 
-static void unload_for_real(void *handle)
-{
-	GList *i;
-	struct gaim_plugin *p = NULL;
-
-	i = plugins;
-	while (i) {
-		p = (struct gaim_plugin *)i->data;
-		if (handle == p->handle)
-			break;
-		p = NULL;
-		i = g_list_next(i);
-	}
-
-	if (!p)
-		return;
-
-	debug_printf("Unloading %s\n", g_module_name(p->handle));
-
-	plugin_remove_callbacks(p->handle);
-
-	plugins = g_list_remove(plugins, p);
-	g_free(p);
-	update_show_plugins();
-	save_prefs();
-}
-
-static void unload_immediate(GModule *handle)
-{
-	unload_for_real(handle);
-	g_module_close(handle);
-}
-
-static gboolean unload_timeout(gpointer handle)
-{
-	g_module_close(handle);
-	return FALSE;
-}
-
-void gaim_plugin_unload(GModule *handle)
-{
-	unload_for_real(handle);
-	g_timeout_add(5000, unload_timeout, handle);
-}
-
 static void plugin_reload_cb(GtkWidget *w, gpointer data)
 {
 	GList *i;
+	struct gaim_plugin *p;
 
 	i = GTK_LIST(pluglist)->selection;
 	if (i == NULL)
 		return;
 
 	/* Just pass off plugin to the actual function */
-	plugin_reload(gtk_object_get_user_data(GTK_OBJECT(i->data)));
-}
-
-/* Do unload/load cycle of plugin. */
-static void plugin_reload(struct gaim_plugin *p)
-{
-	char file[PATHSIZE];
-	void (*gaim_plugin_remove)();
-	GModule *handle = p->handle;
-	struct gaim_plugin *plug;
-	GList *plugs;
+	p = reload_plugin(gtk_object_get_user_data(GTK_OBJECT(i->data)));
 
-	strncpy(file, g_module_name(handle), sizeof(file));
-	file[sizeof(file) - 1] = '\0';
-
-	debug_printf("Reloading %s\n", file);
-
-	/* Unload */
-	if (g_module_symbol(handle, "gaim_plugin_remove", (gpointer *)&gaim_plugin_remove))
-		(*gaim_plugin_remove)();
-	unload_immediate(handle);
-
-	/* Load */
-	load_plugin(file);
+	update_show_plugins();
 
 	/* Try and reselect the plugin in list */
 	if (!pluglist)
 		return;
-	plugs = plugins;
-	while (plugs) {
-		plug = plugs->data;
-		if (!strcmp(file, g_module_name(plug->handle))) {
-			gtk_list_select_item(GTK_LIST(pluglist), g_list_index(plugins, plug));
-			return;
-		}
-		plugs = plugs->next;
-	}
+	gtk_list_select_item(GTK_LIST(pluglist), g_list_index(plugins, p));
 }
 
 static void list_clicked(GtkWidget *w, struct gaim_plugin *p)
@@ -594,330 +428,5 @@
 
 	return filename;
 }		
-		
-/* Remove all callbacks associated with plugin handle */
-static void plugin_remove_callbacks(GModule *handle)
-{
-	GList *c = callbacks;
-	struct gaim_callback *g;
 
-	debug_printf("%d callbacks to search\n", g_list_length(callbacks));
-
-	while (c) {
-		g = (struct gaim_callback *)c->data;
-		if (g->handle == handle) {
-			c = g_list_next(c);
-			callbacks = g_list_remove(callbacks, (gpointer)g);
-			debug_printf("Removing callback, %d remain\n", g_list_length(callbacks));
-		} else
-			c = g_list_next(c);
-	}
-}
-
-void gaim_signal_connect(GModule *handle, enum gaim_event which, void *func, void *data)
-{
-	struct gaim_callback *call = g_new0(struct gaim_callback, 1);
-	call->handle = handle;
-	call->event = which;
-	call->function = func;
-	call->data = data;
-
-	callbacks = g_list_append(callbacks, call);
-	debug_printf("Adding callback %d\n", g_list_length(callbacks));
-}
-
-void gaim_signal_disconnect(GModule *handle, enum gaim_event which, void *func)
-{
-	GList *c = callbacks;
-	struct gaim_callback *g = NULL;
-
-	while (c) {
-		g = (struct gaim_callback *)c->data;
-		if (handle == g->handle && func == g->function) {
-			callbacks = g_list_remove(callbacks, c->data);
-			g_free(g);
-			c = callbacks;
-			if (c == NULL)
-				break;
-		}
-		c = g_list_next(c);
-	}
-}
-
-#endif /* GAIM_PLUGINS */
-
-static char *event_name(enum gaim_event event)
-{
-	static char buf[128];
-	switch (event) {
-	case event_signon:
-		sprintf(buf, "event_signon");
-		break;
-	case event_signoff:
-		sprintf(buf, "event_signoff");
-		break;
-	case event_away:
-		sprintf(buf, "event_away");
-		break;
-	case event_back:
-		sprintf(buf, "event_back");
-		break;
-	case event_im_recv:
-		sprintf(buf, "event_im_recv");
-		break;
-	case event_im_send:
-		sprintf(buf, "event_im_send");
-		break;
-	case event_buddy_signon:
-		sprintf(buf, "event_buddy_signon");
-		break;
-	case event_buddy_signoff:
-		sprintf(buf, "event_buddy_signoff");
-		break;
-	case event_buddy_away:
-		sprintf(buf, "event_buddy_away");
-		break;
-	case event_buddy_back:
-		sprintf(buf, "event_buddy_back");
-		break;
-	case event_buddy_idle:
-		sprintf(buf, "event_buddy_idle");
-		break;
-	case event_buddy_unidle:
-		sprintf(buf, "event_buddy_unidle");
-		break;
-	case event_blist_update:
-		sprintf(buf, "event_blist_update");
-		break;
-	case event_chat_invited:
-		sprintf(buf, "event_chat_invited");
-		break;
-	case event_chat_join:
-		sprintf(buf, "event_chat_join");
-		break;
-	case event_chat_leave:
-		sprintf(buf, "event_chat_leave");
-		break;
-	case event_chat_buddy_join:
-		sprintf(buf, "event_chat_buddy_join");
-		break;
-	case event_chat_buddy_leave:
-		sprintf(buf, "event_chat_buddy_leave");
-		break;
-	case event_chat_recv:
-		sprintf(buf, "event_chat_recv");
-		break;
-	case event_chat_send:
-		sprintf(buf, "event_chat_send");
-		break;
-	case event_warned:
-		sprintf(buf, "event_warned");
-		break;
-	case event_error:
-		sprintf(buf, "event_error");
-		break;
-	case event_quit:
-		sprintf(buf, "event_quit");
-		break;
-	case event_new_conversation:
-		sprintf(buf, "event_new_conversation");
-		break;
-	case event_set_info:
-		sprintf(buf, "event_set_info");
-		break;
-	case event_draw_menu:
-		sprintf(buf, "event_draw_menu");
-		break;
-	case event_im_displayed_sent:
-		sprintf(buf, "event_im_displayed_sent");
-		break;
-	case event_im_displayed_rcvd:
-		sprintf(buf, "event_im_displayed_rcvd");
-		break;
-	case event_chat_send_invite:
-		sprintf(buf, "event_chat_send_invite");
-		break;
-	default:
-		sprintf(buf, "event_unknown");
-		break;
-	}
-	return buf;
-}
-
-int plugin_event(enum gaim_event event, void *arg1, void *arg2, void *arg3, void *arg4)
-{
-#ifdef USE_PERL
-	char buf[BUF_LONG];
 #endif
-#ifdef GAIM_PLUGINS
-	GList *c = callbacks;
-	struct gaim_callback *g;
-
-	while (c) {
-		void (*zero)(void *);
-		void (*one)(void *, void *);
-		void (*two)(void *, void *, void *);
-		void (*three)(void *, void *, void *, void *);
-		void (*four)(void *, void *, void *, void *, void *);
-
-		g = (struct gaim_callback *)c->data;
-		if (g->event == event && g->function !=NULL) {
-			switch (event) {
-
-				/* no args */
-			case event_blist_update:
-			case event_quit:
-				zero = g->function;
-				(*zero)(g->data);
-				break;
-
-				/* one arg */
-			case event_signon:
-			case event_signoff:
-			case event_new_conversation:
-			case event_error:
-				one = g->function;
-				(*one)(arg1, g->data);
-				break;
-
-				/* two args */
-			case event_buddy_signon:
-			case event_buddy_signoff:
-			case event_buddy_away:
-			case event_buddy_back:
-			case event_buddy_idle:
-			case event_buddy_unidle:
-			case event_chat_leave:
-			case event_set_info:
-			case event_draw_menu:
-				two = g->function;
-				(*two)(arg1, arg2, g->data);
-				break;
-
-				/* three args */
-			case event_im_send:
-			case event_im_displayed_sent:
-			case event_chat_join:
-			case event_chat_buddy_join:
-			case event_chat_buddy_leave:
-			case event_chat_send:
-			case event_away:
-			case event_back:
-			case event_warned:
-				three = g->function;
-				(*three)(arg1, arg2, arg3, g->data);
-				break;
-
-				/* four args */
-			case event_im_recv:
-			case event_chat_recv:
-			case event_im_displayed_rcvd:
-			case event_chat_send_invite:
-			case event_chat_invited:
-				four = g->function;
-				(*four)(arg1, arg2, arg3, arg4, g->data);
-				break;
-
-			default:
-				debug_printf("unknown event %d\n", event);
-				break;
-			}
-		}
-		c = c->next;
-	}
-#endif /* GAIM_PLUGINS */
-#ifdef USE_PERL
-	switch (event) {
-	case event_signon:
-	case event_signoff:
-	case event_away:
-	case event_back:
-		g_snprintf(buf, sizeof buf, "%lu", (unsigned long)arg1);
-		break;
-	case event_im_recv:
-		g_snprintf(buf, sizeof buf, "%lu \"%s\" %s", (unsigned long)arg1,
-			   *(char **)arg2 ? *(char **)arg2 : "(null)",
-			   *(char **)arg3 ? *(char **)arg3 : "(null)");
-		break;
-	case event_im_send:
-		g_snprintf(buf, sizeof buf, "%lu \"%s\" %s", (unsigned long)arg1,
-			   (char *)arg2, *(char **)arg3 ? *(char **)arg3 : "(null)");
-		break;
-	case event_buddy_signon:
-	case event_buddy_signoff:
-	case event_set_info:
-	case event_buddy_away:
-	case event_buddy_back:
-	case event_buddy_idle:
-	case event_buddy_unidle:
-		g_snprintf(buf, sizeof buf, "%lu \"%s\"", (unsigned long)arg1, (char *)arg2);
-		break;
-	case event_chat_invited:
-		g_snprintf(buf, sizeof buf, "%lu \"%s\" \"%s\" %s", (unsigned long)arg1,
-				(char *)arg2, (char *)arg3, arg4 ? (char *)arg4 : "");
-		break;
-	case event_chat_join:
-	case event_chat_buddy_join:
-	case event_chat_buddy_leave:
-		g_snprintf(buf, sizeof buf, "%lu %d \"%s\"", (unsigned long)arg1,
-				(int)arg2, (char *)arg3);
-		break;
-	case event_chat_leave:
-		g_snprintf(buf, sizeof buf, "%lu %d", (unsigned long)arg1, (int)arg2);
-		break;
-	case event_chat_recv:
-		g_snprintf(buf, sizeof buf, "%lu %d \"%s\" %s", (unsigned long)arg1,
-				(int)arg2, (char *)arg3, (char *)arg4 ? (char *)arg4 : "(null)");
-		break;
-	case event_chat_send_invite:
-		g_snprintf(buf, sizeof buf, "%lu %d \"%s\" %s", (unsigned long)arg1,
-				(int)arg2, (char *)arg3, *(char **)arg4 ? *(char **)arg4 : "(null)");
-		break;
-	case event_chat_send:
-		g_snprintf(buf, sizeof buf, "%lu %d %s", (unsigned long)arg1, (int)arg2,
-				*(char **)arg3 ? *(char **)arg3 : "(null)");
-		break;
-	case event_warned:
-		g_snprintf(buf, sizeof buf, "%lu \"%s\" %d", (unsigned long)arg1,
-				arg2 ? (char *)arg2 : "", (int)arg3);
-		break;
-	case event_quit:
-		buf[0] = 0;
-		break;
-	case event_new_conversation:
-		g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg1);
-		break;
-	case event_im_displayed_sent:
-		g_snprintf(buf, sizeof buf, "%lu \"%s\" %s", (unsigned long)arg1,
-				(char *)arg2, *(char **)arg3 ? *(char **)arg3 : "(null)");
-		break;
-	case event_im_displayed_rcvd:
-		g_snprintf(buf, sizeof buf, "%lu \"%s\" %s", (unsigned long)arg1,
-				(char *)arg2, (char *)arg3 ? (char *)arg3 : "(null)");
-		break;
-	default:
-		return 0;
-	}
-	return perl_event(event_name(event), buf);
-#else
-	return 0;
-#endif
-}
-
-/* Calls the gaim_plugin_remove function in any loaded plugin that has one */
-#ifdef GAIM_PLUGINS
-void remove_all_plugins()
-{
-	GList *c = plugins;
-	struct gaim_plugin *p;
-	void (*gaim_plugin_remove)();
-
-	while (c) {
-		p = (struct gaim_plugin *)c->data;
-		if (g_module_symbol(p->handle, "gaim_plugin_remove", (gpointer *)&gaim_plugin_remove))
-			(*gaim_plugin_remove)();
-		g_free(p);
-		c = c->next;
-	}
-}
-#endif