Sat, 29 Sep 2001 23:06:30 +0000
[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
--- a/ChangeLog Sat Sep 29 02:08:00 2001 +0000 +++ b/ChangeLog Sat Sep 29 23:06:30 2001 +0000 @@ -11,6 +11,7 @@ * Nick Highlighting in chat * Tab-completion for nicks in chat (thanks to Sean Egan) * Large internal reworkings + * New Protocol: Gadu-Gadu, written by Arkadiusz Miskiewicz version 0.44 (09/20/2001): * More sane scaling of buddy icons (intelligently scale to
--- a/acconfig.h Sat Sep 29 02:08:00 2001 +0000 +++ b/acconfig.h Sat Sep 29 23:06:30 2001 +0000 @@ -17,7 +17,6 @@ #undef ARTSC_SOUND #undef _REENTRANT #undef NEED_GNOMESUPPORT_H -#undef NEED_SOCKLEN_T #undef ZEPHYR_INT32 #undef ZEPHYR_USES_KERBEROS #ifndef STATIC_PROTO_INIT
--- a/configure.ac Sat Sep 29 02:08:00 2001 +0000 +++ b/configure.ac Sat Sep 29 23:06:30 2001 +0000 @@ -32,8 +32,6 @@ AC_TYPE_SIGNAL AC_FUNC_STRFTIME AC_CHECK_FUNCS(socket strdup strstr atexit getaddrinfo) -AC_TRY_COMPILE([#include <sys/types.h> -#include <sys/socket.h>], [socklen_t slen;],,[AC_DEFINE(NEED_SOCKLEN_T)]) dnl Checks for getopt in standard library AC_CHECK_FUNCS(getopt_long , , [LIBOBJS="$LIBOBJS getopt.o getopt1.o"] ) @@ -48,7 +46,7 @@ AC_ARG_ENABLE(prpls, [ --disable-prpls don't build dynamic protocol plugins],,enable_prpls=yes) AC_ARG_WITH(static-prpls, [ --with-static-prpls link in certain protocols statically],[STATIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`],STATIC_PRPLS="oscar toc") if test "x$STATIC_PRPLS" = "xall" ; then - STATIC_PRPLS="icq irc jabber msn napster oscar toc yahoo zephyr" + STATIC_PRPLS="gg icq irc jabber msn napster oscar toc yahoo zephyr" fi AC_SUBST(STATIC_PRPLS) STATIC_LINK_LIBS= @@ -59,6 +57,7 @@ extern_init="$extern_init extern void ${i}_init(struct prpl *);" load_proto="$load_proto load_protocol(${i}_init, sizeof(struct prpl));" case $i in + gg) static_gg=yes ;; icq) static_icq=yes ;; irc) static_irc=yes ;; jabber) static_jabber=yes ;; @@ -71,6 +70,7 @@ *) echo "Invalid static protocol $i!!" ; exit ;; esac done +AM_CONDITIONAL(STATIC_GG, test "x$static_gg" = "xyes") AM_CONDITIONAL(STATIC_ICQ, test "x$static_icq" = "xyes") AM_CONDITIONAL(STATIC_IRC, test "x$static_irc" = "xyes") AM_CONDITIONAL(STATIC_JABBER, test "x$static_jabber" = "xyes") @@ -358,6 +358,7 @@ sounds/Makefile src/Makefile src/protocols/Makefile + src/protocols/gg/Makefile src/protocols/icq/Makefile src/protocols/irc/Makefile src/protocols/jabber/Makefile
--- a/doc/CREDITS Sat Sep 29 02:08:00 2001 +0000 +++ b/doc/CREDITS Sat Sep 29 23:06:30 2001 +0000 @@ -36,6 +36,8 @@ A healthy amount of patches for the Jabber plugin Neil Sanchala Wrote most of the Zephyr plugin +Arkadiusz Miskiewicz + Wrote the Gadu-Gadu plugin David Prater <IM: dRaven43> draven@tcsx.net Log and Colour Button Images
--- a/pixmaps/Makefile.am Sat Sep 29 02:08:00 2001 +0000 +++ b/pixmaps/Makefile.am Sat Sep 29 23:06:30 2001 +0000 @@ -34,6 +34,10 @@ fontface2.xpm \ free_icon.xpm \ gaim.xpm \ + gg_suncloud.xpm \ + gg_sunred.xpm \ + gg_sunwhitered.xpm \ + gg_sunyellow.xpm \ gnome_add.xpm \ gnome_preferences.xpm \ gnome_remove.xpm \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pixmaps/gg_suncloud.xpm Sat Sep 29 23:06:30 2001 +0000 @@ -0,0 +1,28 @@ +/* XPM */ +static char * gg_suncloud_xpm[] = { +"18 18 7 1", +" c None", +". c #FF0000", +"+ c #7F7F7F", +"@ c #FFFF00", +"# c #000000", +"$ c #00007F", +"% c #00FFFF", +" ", +" . ", +" .+ ", +" . .+ . ", +" . ..@.. .+ ", +" .@@@@@.+ ", +" .@@#@#@@.+ ", +" .@@@@@@@.+ ", +" ...@$@@@@@@@... ", +" $$%$@@@#@$$$++ ", +" $%%%%$##@$%%%$ ", +" $%%%%%%$$$%%%%$ ", +" $%%%%%%%%%%%%%%$ ", +" $%%%%%%%%%%%%%$ ", +" $%%%%%%%%%%%%$ ", +" $%%%$$$%%%$$$ ", +" $$$ $$$ ", +" "};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pixmaps/gg_sunred.xpm Sat Sep 29 23:06:30 2001 +0000 @@ -0,0 +1,25 @@ +/* XPM */ +static char * gg_sunred_xpm[] = { +"19 18 4 1", +" c None", +". c #FF0000", +"+ c #7F7F7F", +"@ c #000000", +" ", +" . ", +" .+ ", +" . .+ . ", +" . ..... .+ ", +" .......+ ", +" ...@.@...+ ", +" .........+ ", +" ............... ", +" ..@...@..++++ ", +" ...@@@...+ ", +" .......+ ", +" .+..... .+ ", +" .+ .++ .+ ", +" + .+ ", +" .+ ", +" + ", +" "};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pixmaps/gg_sunwhitered.xpm Sat Sep 29 23:06:30 2001 +0000 @@ -0,0 +1,27 @@ +/* XPM */ +static char * gg_sunwhitered_xpm[] = { +"19 18 6 1", +" c None", +". c #7F0000", +"+ c #FF0000", +"@ c #7F7F7F", +"# c #FFFFFF", +"$ c #000000", +" ", +" . ", +" +@ ", +" + .@ + ", +" . .+#+. .@ ", +" +#####+@ ", +" .##$#$##.@ ", +" +#######+@ ", +" .+.#########.+. ", +" +#$###$#+@@@@ ", +" .##$$$##.@ ", +" +#####+@ ", +" .@.+#+. .@ ", +" +@ .@@ +@ ", +" @ +@ ", +" .@ ", +" @ ", +" "};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pixmaps/gg_sunyellow.xpm Sat Sep 29 23:06:30 2001 +0000 @@ -0,0 +1,26 @@ +/* XPM */ +static char * gg_sunyellow_xpm[] = { +"18 18 5 1", +" c None", +". c #FF0000", +"+ c #7F7F7F", +"@ c #FFFF00", +"# c #000000", +" ", +" . ", +" .+ ", +" . .+ . ", +" . ..@.. .+ ", +" .@@@@@.+ ", +" .@@#@#@@.+ ", +" .@@@@@@@.+ ", +" ...@@@@@@@@@... ", +" .@#@@@#@.++++ ", +" .@@###@@.+ ", +" .@@@@@.+ ", +" .+..@.. .+ ", +" .+ .++ .+ ", +" + .+ ", +" .+ ", +" + ", +" "};
--- a/po/POTFILES.in Sat Sep 29 02:08:00 2001 +0000 +++ b/po/POTFILES.in Sat Sep 29 23:06:30 2001 +0000 @@ -1,3 +1,4 @@ +src/protocols/gg/gg.c src/protocols/icq/gaim_icq.c src/protocols/irc/irc.c src/protocols/jabber/jabber.c
--- a/src/Makefile.am Sat Sep 29 02:08:00 2001 +0000 +++ b/src/Makefile.am Sat Sep 29 23:06:30 2001 +0000 @@ -18,6 +18,7 @@ html.c \ idle.c \ list.c \ + module.c \ multi.c \ perl.c \ plugins.c \ @@ -49,6 +50,7 @@ html.c \ idle.c \ list.c \ + module.c \ multi.c \ perl.c \ plugins.c \
--- a/src/buddy.c Sat Sep 29 02:08:00 2001 +0000 +++ b/src/buddy.c Sat Sep 29 23:06:30 2001 +0000 @@ -2389,7 +2389,8 @@ gtk_widget_show(menuitem); menuitem = gtk_menu_item_new_with_label(_("by Dir Info")); gtk_menu_append(GTK_MENU(findmenu), menuitem); - gtk_signal_connect(GTK_OBJECT(menuitem), "activate", GTK_SIGNAL_FUNC(show_find_info), NULL); + gtk_signal_connect(GTK_OBJECT(menuitem), "activate", GTK_SIGNAL_FUNC(show_find_info), + connections->data); gtk_widget_show(menuitem); setmenu = gtk_menu_new();
--- a/src/dialogs.c Sat Sep 29 02:08:00 2001 +0000 +++ b/src/dialogs.c Sat Sep 29 23:06:30 2001 +0000 @@ -150,6 +150,7 @@ }; struct findbyinfo { + struct gaim_connection *gc; GtkWidget *window; GtkWidget *firstentry; GtkWidget *middleentry; @@ -2058,10 +2059,7 @@ state = gtk_entry_get_text(GTK_ENTRY(b->stateentry)); country = gtk_entry_get_text(GTK_ENTRY(b->countryentry)); - /* FIXME : dir search. not sure if even works; not important */ - if (connections) - serv_dir_search(connections->data, first, middle, last, maiden, city, state, country, - ""); + serv_dir_search(b->gc, first, middle, last, maiden, city, state, country, ""); destroy_dialog(NULL, b->window); } @@ -2079,7 +2077,7 @@ destroy_dialog(NULL, b->window); } -void show_find_info() +void show_find_info(struct gaim_connection *gc) { GtkWidget *cancel; GtkWidget *ok; @@ -2091,6 +2089,7 @@ GtkWidget *frame; struct findbyinfo *b = g_new0(struct findbyinfo, 1); + b->gc = gc; b->window = gtk_window_new(GTK_WINDOW_DIALOG); gtk_window_set_policy(GTK_WINDOW(b->window), FALSE, TRUE, TRUE); gtk_window_set_wmclass(GTK_WINDOW(b->window), "find_info", "Gaim");
--- a/src/gaim.h Sat Sep 29 02:08:00 2001 +0000 +++ b/src/gaim.h Sat Sep 29 23:06:30 2001 +0000 @@ -807,7 +807,9 @@ /* Functions in plugins.c */ #ifdef GAIM_PLUGINS extern void show_plugins(GtkWidget *, gpointer); -extern void load_plugin (char *); +extern struct gaim_plugin *load_plugin(char *); +extern void unload_plugin(struct gaim_plugin *); +extern struct gaim_plugin *reload_plugin(struct gaim_plugin *); extern void gaim_signal_connect(GModule *, enum gaim_event, void *, void *); extern void gaim_signal_disconnect(GModule *, enum gaim_event, void *); extern void gaim_plugin_unload(GModule *); @@ -857,8 +859,8 @@ extern void show_new_bp(); extern void show_log(char *); extern void show_log_dialog(struct conversation *); -extern void show_find_email(struct gaim_connection *gc); -extern void show_find_info(); +extern void show_find_email(struct gaim_connection *); +extern void show_find_info(struct gaim_connection *); extern void g_show_info_text(char *, ...); extern void show_set_info(struct gaim_connection *); extern void show_set_dir();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/module.c Sat Sep 29 23:06:30 2001 +0000 @@ -0,0 +1,516 @@ +/* + * gaim + * + * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> + * + * 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 + * + * ---------------- + * The Plug-in plug + * + * 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 + * + * Mike is my roomate. I can assure you that he's lazy :-P -- Rob rob@marko.net + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef GAIM_PLUGINS + +#include <string.h> +#include <sys/time.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include "gaim.h" + +/* ------------------ Global Variables ----------------------- */ + +GList *plugins = NULL; +GList *callbacks = NULL; + +/* --------------- Function Declarations --------------------- */ + +struct gaim_plugin * load_plugin(char *); + void unload_plugin(struct gaim_plugin *p); +struct gaim_plugin *reload_plugin(struct gaim_plugin *p); + +void gaim_signal_connect(GModule *, enum gaim_event, void *, void *); +void gaim_signal_disconnect(GModule *, enum gaim_event, void *); +void gaim_plugin_unload(GModule *); + +/* --------------- Static Function Declarations ------------- */ + +static void plugin_remove_callbacks(GModule *); + +/* ------------------ Code Below ---------------------------- */ + +struct gaim_plugin *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 NULL; + if (filename && !strlen(filename)) + return NULL; + + while (filename && c) { + plug = (struct gaim_plugin *)c->data; + if (!strcmp(filename, g_module_name(plug->handle))) { + /* just need to reload plugin */ + return reload_plugin(plug); + } else + c = g_list_next(c); + } + plug = g_malloc(sizeof *plug); + + 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 NULL; + } + + 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 NULL; + } + + 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 NULL; + } + + 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; + + save_prefs(); + return plug; +} + +static void unload_gaim_plugin(struct gaim_plugin *p) +{ + void (*gaim_plugin_remove)(); + + debug_printf("Unloading %s\n", g_module_name(p->handle)); + + /* 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)(); + + plugin_remove_callbacks(p->handle); + + plugins = g_list_remove(plugins, p); + g_free(p); + save_prefs(); +} + +void unload_plugin(struct gaim_plugin *p) +{ + GModule *handle = p->handle; + unload_gaim_plugin(p); + g_module_close(handle); +} + +static gboolean unload_timeout(gpointer handle) +{ + g_module_close(handle); + return FALSE; +} + +void gaim_plugin_unload(GModule *handle) +{ + g_timeout_add(5000, unload_timeout, handle); +} + +/* Do unload/load cycle of plugin. */ +struct gaim_plugin *reload_plugin(struct gaim_plugin *p) +{ + char file[1024]; + GModule *handle = p->handle; + + strncpy(file, g_module_name(handle), sizeof(file)); + file[sizeof(file) - 1] = '\0'; + + debug_printf("Reloading %s\n", file); + + /* Unload */ + unload_plugin(p); + + /* Load */ + return load_plugin(file); +} + +/* 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
--- 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");