# HG changeset patch # User Eric Warmenhoven # Date 955129409 0 # Node ID f5b305c0d974ad6afe3dc0c978b084c7cfc3a055 # Parent a382929aeb4f0024ee051b3d498c42debb4fe072 [gaim-migrate @ 100] Added plugin code. I have yet to test it. :P All I know is, I can successfully load a plugin. I don't know what I can do with it yet, and I'm not even sure I can unload it yet. committer: Tailor Script diff -r a382929aeb4f -r f5b305c0d974 plugins/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/Makefile Fri Apr 07 17:43:29 2000 +0000 @@ -0,0 +1,6 @@ +CC = gcc +CFLAGS = -Wall +LDFLAGS = -ggdb + +simple.so: simple.c + $(CC) $(CFLAGS) $(LDFLAGS) -shared -Wl,-soname,$@ -o $@ $< diff -r a382929aeb4f -r f5b305c0d974 plugins/simple.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/simple.c Fri Apr 07 17:43:29 2000 +0000 @@ -0,0 +1,9 @@ +#include + +void gaim_plugin_init() { + printf("works.\n"); +} + +void gaim_plugin_remove() { + printf("works again.\n"); +} diff -r a382929aeb4f -r f5b305c0d974 src/Makefile.am --- a/src/Makefile.am Fri Apr 07 07:51:14 2000 +0000 +++ b/src/Makefile.am Fri Apr 07 17:43:29 2000 +0000 @@ -1,9 +1,9 @@ if GNOMEAPPLET bin_PROGRAMS = gaim_applet -gaim_applet_SOURCES = about.c aim.c away.c buddy.c buddy_chat.c conversation.c \ - dialogs.c html.c prefs.c proxy.c toc.c sound.c gaim.h \ - gnome_applet_mgr.c plugins.c network.c server.c \ - browser.c util.c oscar.c gtkhtml.c idle.c gaimrc.c +gaim_applet_SOURCES = about.c aim.c away.c browser.c buddy.c buddy_chat.c \ + conversation.c dialogs.c gaimrc.c gnome_applet_mgr.c gtkhtml.c \ + html.c idle.c network.c oscar.c plugins.c prefs.c proxy.c server.c \ + sound.c toc.c util.c else bin_PROGRAMS = gaim gaim_SOURCES = about.c aim.c away.c buddy.c buddy_chat.c conversation.c \ diff -r a382929aeb4f -r f5b305c0d974 src/buddy.c --- a/src/buddy.c Fri Apr 07 07:51:14 2000 +0000 +++ b/src/buddy.c Fri Apr 07 17:43:29 2000 +0000 @@ -1632,7 +1632,6 @@ gtk_menu_append(GTK_MENU(findmenu), menuitem); gtk_signal_connect(GTK_OBJECT(menuitem), "activate", GTK_SIGNAL_FUNC(show_find_info), NULL); gtk_widget_show(menuitem); - setmenu = gtk_menu_new(); gtk_widget_show(setmenu); @@ -1648,18 +1647,22 @@ gtk_signal_connect(GTK_OBJECT(menuitem), "activate", GTK_SIGNAL_FUNC(show_set_dir), NULL); gtk_widget_show(menuitem); - /* Ok, this is the menu hookup for the plugin stuff */ -#ifdef GAIM_PLUGINS - gaim_seperator(menu); - - gaim_new_item(menu, "Plugins", GTK_SIGNAL_FUNC(show_plugins)); -#endif - - /*---------------*/ - gaim_seperator(menu); gaim_new_item(menu, "Preferences", GTK_SIGNAL_FUNC(show_prefs)); + +#ifdef GAIM_PLUGINS + menu = gtk_menu_new(); + + menuitem = gaim_new_item(NULL, "Plugins", NULL); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menu); + gtk_menu_bar_append(GTK_MENU_BAR(menubar), menuitem); + + gaim_new_item(menu, "Load Plugin", GTK_SIGNAL_FUNC(load_plugin)); + /* FIXME */ + gaim_new_item(menu, "Remove Plugin", GTK_SIGNAL_FUNC(show_plugins)); + gaim_new_item(menu, "Show Plugins", GTK_SIGNAL_FUNC(show_plugins)); +#endif menu = gtk_menu_new(); diff -r a382929aeb4f -r f5b305c0d974 src/gaim.h --- a/src/gaim.h Fri Apr 07 07:51:14 2000 +0000 +++ b/src/gaim.h Fri Apr 07 17:43:29 2000 +0000 @@ -64,7 +64,7 @@ #define AUTO_RESPONSE " : " -#define PLUGIN_DIR "$HOME/.gaim/plugins/" +#define PLUGIN_DIR ".gaim/plugins/" #define REG_EMAIL_ADDR "gaiminfo@blueridge.net" #define REG_SRVR "blueridge.net" @@ -117,15 +117,14 @@ char page[255]; }; +#ifdef GAIM_PLUGINS struct gaim_plugin { - char name[64]; - char filename[512]; -/* char description[256]; - int major_version; - int minor_version; */ - char *(*init_gaim_plugin)(); - void (*toc_receive)(char *); + char *name; + char *filename; + char *description; + void *handle; }; +#endif struct buddy { char name[80]; @@ -269,7 +268,7 @@ #define TYPE_SIGNOFF 4 #define TYPE_KEEPALIVE 5 -#define REVISION "gaim:$Revision: 92 $" +#define REVISION "gaim:$Revision: 100 $" #define FLAPON "FLAPON\r\n\r\n" #define ROAST "Tic/Toc" @@ -541,7 +540,9 @@ #ifdef GAIM_PLUGINS /* Functions in plugins.c */ -extern void load_plugins(); +extern void load_plugin (GtkWidget *, gpointer); +extern void unload_plugin(GtkWidget *, gpointer); +extern void show_plugins (GtkWidget *, gpointer); #endif /* Functions in prefs.c */ @@ -556,9 +557,6 @@ extern void save_prefs(); -/*Functions in plugins.c */ -extern void show_plugins(); - /* Functions in dialogs.c */ extern void show_warn_dialog(char *); extern void do_error_dialog(char *, char *); diff -r a382929aeb4f -r f5b305c0d974 src/plugins.c --- a/src/plugins.c Fri Apr 07 07:51:14 2000 +0000 +++ b/src/plugins.c Fri Apr 07 17:43:29 2000 +0000 @@ -23,8 +23,13 @@ * Plugin support is currently being maintained by Mike Saraf * msaraf@dwc.edu * + * Well, I didn't see any work done on it for a while, so I'm going to try + * my hand at it. - Eric warmenhoven@yahoo.com + * */ +#ifdef GAIM_PLUGINS + #include #include @@ -37,59 +42,245 @@ #include #include "gaim.h" +#include + /* ------------------ Local Variables -------------------------*/ -static GtkWidget *plugins=NULL; +static GtkWidget *plugin_dialog = NULL; +static GList *plugins = NULL; + +static GtkWidget *pluglist; +static GtkWidget *plugtext; /* --------------- Function Declarations -------------------- */ -static void destroy_plugins(); - void do_plugins(GtkWidget *, void *); + void load_plugin (GtkWidget *, gpointer); + void unload_plugin(GtkWidget *, gpointer); + void show_plugins (GtkWidget *, gpointer); + +static void destroy_plugins (GtkWidget *, gpointer); +static void load_which_plugin(GtkWidget *, gpointer); +static void unload (GtkWidget *, gpointer); +static void list_clicked (GtkWidget *, struct gaim_plugin *); + /* ------------------ Code Below ---------------------------- */ -void show_plugins() +static void destroy_plugins(GtkWidget *w, gpointer data) { + if (plugin_dialog) + gtk_widget_destroy(plugin_dialog); + plugin_dialog = NULL; +} + +void load_plugin(GtkWidget *w, gpointer data) { - char *buf = g_malloc(BUF_LEN); + char *buf = g_malloc(BUF_LEN); - if (!plugins) - { - plugins = gtk_file_selection_new("Gaim - Plugin List"); + if (!plugin_dialog) { + plugin_dialog = gtk_file_selection_new("Gaim - Plugin List"); + + gtk_file_selection_hide_fileop_buttons( + GTK_FILE_SELECTION(plugin_dialog)); + + if(getenv("PLUGIN_DIR") == NULL) { + g_snprintf(buf, BUF_LEN - 1, "%s/%s", getenv("HOME"), PLUGIN_DIR); + } else { + g_snprintf(buf, BUF_LEN - 1, "%s/", getenv("PLUGIN_DIR")); + } - gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(plugins)); + gtk_file_selection_set_filename(GTK_FILE_SELECTION(plugin_dialog), buf); + gtk_signal_connect(GTK_OBJECT(plugin_dialog), "destroy", + GTK_SIGNAL_FUNC(destroy_plugins), plugin_dialog); + + gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(plugin_dialog)->ok_button), + "clicked", GTK_SIGNAL_FUNC(load_which_plugin), NULL); + + gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(plugin_dialog)->cancel_button), + "clicked", GTK_SIGNAL_FUNC(destroy_plugins), NULL); + + } + + g_free(buf); + gtk_widget_show(plugin_dialog); + gdk_window_raise(plugin_dialog->window); +} - if(getenv("PLUGIN_DIR") == NULL) - { - g_snprintf(buf, BUF_LEN - 1, "%s/", getenv("HOME")); - } - else - { - g_snprintf(buf, BUF_LEN - 1, "%s/", getenv("PLUGIN_DIR")); - } +void load_which_plugin(GtkWidget *w, gpointer data) { + struct gaim_plugin *plug; + void (*gaim_plugin_init)(); + char *(*cfunc)(); + int (*nfunc)(); + char *error; + + plug = g_malloc(sizeof *plug); + plug->filename = gtk_file_selection_get_filename( + GTK_FILE_SELECTION(plugin_dialog)); + /* do NOT OR with RTLD_GLOBAL, otherwise plugins may conflict + * (it's really just a way to work around other people's bad + * programming, by not using RTLD_GLOBAL :P ) */ + plug->handle = dlopen(plug->filename, RTLD_LAZY); + if (!plug->handle) { + error = dlerror(); + do_error_dialog(error, "Plugin Error"); + g_free(plug); + return; + } + + if (plugin_dialog) + gtk_widget_destroy(plugin_dialog); + plugin_dialog = NULL; - gtk_file_selection_set_filename(GTK_FILE_SELECTION(plugins), buf); - gtk_signal_connect(GTK_OBJECT(plugins), "destroy", - GTK_SIGNAL_FUNC(destroy_plugins), plugins); + gaim_plugin_init = dlsym(plug->handle, "gaim_plugin_init"); + if ((error = dlerror()) != NULL) { + do_error_dialog(error, "Plugin Error"); + dlclose(plug->handle); + g_free(plug); + return; + } + + plugins = g_list_append(plugins, plug); + (*gaim_plugin_init)(); - gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(plugins)->ok_button), - "clicked", GTK_SIGNAL_FUNC(do_plugins), NULL); - - gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(plugins)->cancel_button), - "clicked", GTK_SIGNAL_FUNC(destroy_plugins),plugins ); + cfunc = dlsym(plug->handle, "name"); + if ((error = dlerror()) == NULL) + plug->name = (*cfunc)(); + else + plug->name = NULL; - } + cfunc = dlsym(plug->handle, "description"); + if ((error = dlerror()) == NULL) + plug->description = (*cfunc)(); + else + plug->description = NULL; +} - gtk_widget_show(plugins); - gdk_window_raise(plugins->window); +void unload_plugin(GtkWidget *w, gpointer data) { + /* FIXME */ } -void do_plugins(GtkWidget *w, void *dummy) -{ +void show_plugins(GtkWidget *w, gpointer data) { + /* most of this code was shamelessly stolen from prefs.c */ + GtkWidget *window; + GtkWidget *page; + GtkWidget *topbox; + GtkWidget *botbox; + GtkWidget *sw; + GtkWidget *label; + GtkWidget *list_item; + GtkWidget *sw2; + GtkWidget *add; + GtkWidget *remove; + GList *plugs = plugins; + struct gaim_plugin *p; + gchar buffer[1024]; + + window = gtk_window_new(GTK_WINDOW_DIALOG); + gtk_widget_realize(window); + aol_icon(window->window); + gtk_container_border_width(GTK_CONTAINER(window), 10); + gtk_window_set_title(GTK_WINDOW(window), "Gaim - Plugins"); + + page = gtk_vbox_new(FALSE, 0); + topbox = gtk_hbox_new(FALSE, 0); + botbox = gtk_hbox_new(FALSE, 0); + + sw2 = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw2), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + pluglist = gtk_list_new(); + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw2), pluglist); + gtk_box_pack_start(GTK_BOX(topbox), sw2, TRUE, TRUE, 0); + + sw = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + plugtext = gtk_text_new(NULL, NULL); + gtk_container_add(GTK_CONTAINER(sw), plugtext); + gtk_box_pack_start(GTK_BOX(topbox), sw, TRUE, TRUE, 0); + gtk_text_set_word_wrap(GTK_TEXT(plugtext), TRUE); + gtk_text_set_editable(GTK_TEXT(plugtext), FALSE); + + add = gtk_button_new_with_label("Load Plugin"); + gtk_signal_connect(GTK_OBJECT(add), "clicked", + GTK_SIGNAL_FUNC(load_plugin), NULL); + gtk_box_pack_start(GTK_BOX(botbox), add, TRUE, FALSE, 5); + + remove = gtk_button_new_with_label("Unload Plugin"); + gtk_signal_connect(GTK_OBJECT(remove), "clicked", + GTK_SIGNAL_FUNC(unload), pluglist); + gtk_box_pack_start(GTK_BOX(botbox), remove, TRUE, FALSE, 5); + + gtk_box_pack_start(GTK_BOX(page), topbox, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(page), botbox, FALSE, FALSE, 0); + + if (plugs != NULL) { + p = (struct gaim_plugin *)plugs->data; + g_snprintf(buffer, sizeof(buffer), "%s", p->filename); + gtk_text_insert(GTK_TEXT(plugtext), NULL, NULL, NULL, buffer, -1); + } + + while (plugs) { + p = (struct gaim_plugin *)plugs->data; + label = gtk_label_new(p->filename); + list_item = gtk_list_item_new(); + gtk_container_add(GTK_CONTAINER(list_item), label); + gtk_signal_connect(GTK_OBJECT(list_item), "select", + GTK_SIGNAL_FUNC(list_clicked), p); + gtk_object_set_user_data(GTK_OBJECT(list_item), p); + + gtk_widget_show(label); + gtk_container_add(GTK_CONTAINER(pluglist), list_item); + gtk_widget_show(list_item); + + plugs = plugs->next; + } + + gtk_widget_show(page); + gtk_widget_show(topbox); + gtk_widget_show(botbox); + gtk_widget_show(sw); + gtk_widget_show(sw2); + gtk_widget_show(pluglist); + gtk_widget_show(plugtext); + gtk_widget_show(add); + gtk_widget_show(remove); + + gtk_container_add(GTK_CONTAINER(window), page); + gtk_widget_show(window); } -static void destroy_plugins() -{ - if (plugins) - gtk_widget_destroy(plugins); +void unload(GtkWidget *w, gpointer data) { + GList *i; + struct gaim_plugin *p; + void (*gaim_plugin_remove)(); + char *error; + + i = GTK_LIST(pluglist)->selection; + + p = gtk_object_get_user_data(GTK_OBJECT(i->data)); + + g_list_remove(plugins, p); - plugins = NULL; -} + gaim_plugin_remove = dlsym(p->handle, "gaim_plugin_remove"); + if ((error = dlerror()) == NULL) + (*gaim_plugin_remove)(); + dlclose(p->handle); + g_free(p); +} + +void list_clicked(GtkWidget *w, struct gaim_plugin *p) { + gchar buffer[2048]; + guint text_len; + + text_len = gtk_text_get_length(GTK_TEXT(plugtext)); + gtk_text_set_point(GTK_TEXT(plugtext), 0); + gtk_text_forward_delete(GTK_TEXT(plugtext), text_len); + + g_snprintf(buffer, sizeof buffer, "%s\n%s", p->name, p->description); + gtk_text_insert(GTK_TEXT(plugtext), NULL, NULL, NULL, buffer, -1); +} + +#endif /* GAIM_PLUGINS */