Mercurial > pidgin
annotate src/module.c @ 3572:bdd0bebd2d04
[gaim-migrate @ 3670]
Phase II. No longer do you have to worry about protocol plugins. When
Gaim probes plugins on load, it will detect protocol plugins and add them
to the list of available protocols. When you try to log an account on with
one of them, Gaim will automatically load the plugin--when no more accounts
need the protocol--Gaim will automatically unload it. Protocol plugins are
no longer available in the plugins ui, and no protocols are compiled statically
by default.
committer: Tailor Script <tailor@pidgin.im>
| author | Sean Egan <seanegan@gmail.com> |
|---|---|
| date | Mon, 30 Sep 2002 01:05:18 +0000 |
| parents | 154c4a9d9b6d |
| children | 9682c0e022c6 |
| rev | line source |
|---|---|
| 2393 | 1 /* |
| 2 * gaim | |
| 3 * | |
| 4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
| 5 * | |
| 6 * This program is free software; you can redistribute it and/or modify | |
| 7 * it under the terms of the GNU General Public License as published by | |
| 8 * the Free Software Foundation; either version 2 of the License, or | |
| 9 * (at your option) any later version. | |
| 10 * | |
| 11 * This program is distributed in the hope that it will be useful, | |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 * GNU General Public License for more details. | |
| 15 * | |
| 16 * You should have received a copy of the GNU General Public License | |
| 17 * along with this program; if not, write to the Free Software | |
| 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 19 * | |
| 20 * ---------------- | |
| 21 * The Plug-in plug | |
| 22 * | |
| 23 * Plugin support is currently being maintained by Mike Saraf | |
| 24 * msaraf@dwc.edu | |
| 25 * | |
| 26 * Well, I didn't see any work done on it for a while, so I'm going to try | |
| 27 * my hand at it. - Eric warmenhoven@yahoo.com | |
| 28 * | |
| 29 * Mike is my roomate. I can assure you that he's lazy :-P -- Rob rob@marko.net | |
| 30 * | |
| 31 */ | |
| 32 | |
| 33 #ifdef HAVE_CONFIG_H | |
| 34 #include <config.h> | |
| 35 #endif | |
| 36 | |
|
2414
70cb0ce6991a
[gaim-migrate @ 2427]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2405
diff
changeset
|
37 #include "gaim.h" |
| 3572 | 38 #include "prpl.h" |
|
2414
70cb0ce6991a
[gaim-migrate @ 2427]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2405
diff
changeset
|
39 |
| 2393 | 40 #include <string.h> |
| 41 #include <sys/time.h> | |
| 42 | |
| 43 #include <sys/types.h> | |
| 44 #include <sys/stat.h> | |
| 45 | |
| 46 #include <unistd.h> | |
| 47 #include <stdio.h> | |
| 48 #include <stdlib.h> | |
| 49 | |
| 50 /* ------------------ Global Variables ----------------------- */ | |
| 51 | |
| 52 GList *plugins = NULL; | |
| 3551 | 53 GList *probed_plugins = NULL; |
| 2393 | 54 GList *callbacks = NULL; |
| 55 | |
|
2405
6e637ad18494
[gaim-migrate @ 2418]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
56 char *last_dir = NULL; |
|
6e637ad18494
[gaim-migrate @ 2418]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
57 |
| 2393 | 58 /* --------------- Function Declarations --------------------- */ |
| 59 | |
| 3466 | 60 struct gaim_plugin * load_plugin(const char *); |
| 3551 | 61 #ifdef GAIM_PLUGINS |
| 2393 | 62 void unload_plugin(struct gaim_plugin *p); |
| 63 struct gaim_plugin *reload_plugin(struct gaim_plugin *p); | |
| 64 void gaim_signal_connect(GModule *, enum gaim_event, void *, void *); | |
| 65 void gaim_signal_disconnect(GModule *, enum gaim_event, void *); | |
| 66 void gaim_plugin_unload(GModule *); | |
| 67 | |
| 68 /* --------------- Static Function Declarations ------------- */ | |
| 69 | |
| 70 static void plugin_remove_callbacks(GModule *); | |
| 3551 | 71 #endif |
| 2393 | 72 /* ------------------ Code Below ---------------------------- */ |
| 73 | |
| 3551 | 74 static int is_so_file(char *filename, char *ext) |
| 75 { | |
| 76 int len; | |
| 77 if (!filename) return 0; | |
| 78 if (!filename[0]) return 0; | |
| 79 len = strlen(filename); | |
| 80 len -= strlen(ext); | |
| 81 if (len < 0) return 0; | |
| 82 return (!strncmp(filename + len, ext, strlen(ext))); | |
| 83 } | |
| 84 | |
| 85 void gaim_probe_plugins() { | |
| 86 GDir *dir; | |
| 87 const gchar *file; | |
| 88 gchar *path; | |
| 89 struct gaim_plugin_description *plugdes; | |
| 90 struct gaim_plugin *plug; | |
| 91 char userspace[128]; | |
| 92 char *probedirs[] = {LIBDIR, &userspace, 0}; | |
| 3565 | 93 int l; |
| 3551 | 94 #if GAIM_PLUGINS |
| 95 char *(*gaim_plugin_init)(GModule *); | |
| 3572 | 96 char *(*gaim_prpl_init)(struct prpl *); |
| 3551 | 97 char *(*cfunc)(); |
| 3572 | 98 struct prpl * new_prpl; |
| 3551 | 99 struct gaim_plugin_description *(*desc)(); |
| 100 GModule *handle; | |
| 101 #endif | |
| 102 | |
| 103 g_snprintf(userspace, sizeof(userspace), "%s" G_DIR_SEPARATOR_S ".gaim", g_get_home_dir()); | |
| 104 | |
| 105 for (l=0; probedirs[l]; l++) { | |
| 106 dir = g_dir_open(probedirs[l], 0, NULL); | |
| 107 if (dir) { | |
| 108 while ((file = g_dir_read_name(dir))) { | |
| 109 #ifdef GAIM_PLUGINS | |
| 110 if (is_so_file(file, ".so") && g_module_supported()) { | |
| 111 path = g_build_filename(probedirs[l], file, NULL); | |
| 112 handle = g_module_open(path, 0); | |
| 113 if (!handle) { | |
| 114 debug_printf("%s is unloadable: %s\n", file, g_module_error()); | |
| 115 continue; | |
| 116 } | |
| 3572 | 117 if (g_module_symbol(handle, "gaim_prpl_init", (gpointer *)&gaim_prpl_init)) { |
| 118 plug = g_new0(struct gaim_plugin, 1); | |
| 119 g_snprintf(plug->path, sizeof(plug->path), path); | |
| 120 plug->type = plugin; | |
| 121 | |
| 122 new_prpl = g_new0(struct prpl, 1); | |
| 123 new_prpl->plug = plug; | |
| 124 gaim_prpl_init(new_prpl); | |
| 125 if (new_prpl->protocol == PROTO_ICQ || | |
| 126 find_prpl(new_prpl->protocol)) { | |
| 127 /* Nothing to see here--move along, move along */ | |
| 128 unload_protocol(new_prpl); | |
| 129 continue; | |
| 130 } | |
| 131 protocols = g_slist_insert_sorted(protocols, new_prpl, (GCompareFunc)proto_compare); | |
| 132 g_module_close(handle); | |
| 133 continue; | |
| 134 } | |
| 135 | |
| 3551 | 136 if (!g_module_symbol(handle, "gaim_plugin_init", (gpointer *)&gaim_plugin_init)) { |
| 137 debug_printf("%s is unloadable %s\n", file, g_module_error()); | |
| 138 g_module_close(handle); | |
| 139 continue; | |
| 140 } | |
| 141 plug = g_new0(struct gaim_plugin, 1); | |
| 142 g_snprintf(plug->path, sizeof(plug->path), path); | |
| 143 plug->type = plugin; | |
| 144 g_free(path); | |
| 145 if (g_module_symbol(handle, "gaim_plugin_desc", (gpointer *)&desc)) { | |
| 146 memcpy(&(plug->desc), desc(), sizeof(plug->desc)); | |
| 147 } else { | |
| 148 if (g_module_symbol(handle, "name", (gpointer *)&cfunc)) { | |
| 149 plug->desc.name = g_strdup(cfunc()); | |
| 150 } | |
| 151 if (g_module_symbol(handle, "description", (gpointer *)&cfunc)) { | |
| 152 plug->desc.description = g_strdup(cfunc()); | |
| 153 } | |
| 154 } | |
| 155 probed_plugins = g_list_append(probed_plugins, plug); | |
| 156 g_module_close(handle); | |
| 157 } | |
| 158 #endif | |
| 159 #ifdef USE_PERL | |
| 160 if (is_so_file(file, ".pl")) { | |
| 3563 | 161 path = g_build_filename(probedirs[l], file, NULL); |
| 3551 | 162 plug = probe_perl(path); |
| 163 if (plug) | |
| 164 probed_plugins = g_list_append(probed_plugins, plug); | |
| 165 g_free(path); | |
| 166 } | |
| 167 #endif | |
| 168 } | |
| 169 g_dir_close(dir); | |
| 170 } | |
| 171 } | |
| 172 } | |
| 173 | |
| 174 #ifdef GAIM_PLUGINS | |
| 3466 | 175 struct gaim_plugin *load_plugin(const char *filename) |
| 2393 | 176 { |
| 177 struct gaim_plugin *plug; | |
| 3551 | 178 struct gaim_plugin_description *desc; |
| 179 struct gaim_plugin_description *(*gaim_plugin_desc)(); | |
| 2393 | 180 char *(*cfunc)(); |
| 3551 | 181 GList *c = plugins; |
| 182 GList *p = probed_plugins; | |
| 183 char *(*gaim_plugin_init)(GModule *); | |
| 3563 | 184 char *error, *retval; |
| 3551 | 185 gboolean newplug = FALSE; |
| 2393 | 186 |
| 187 if (!g_module_supported()) | |
| 188 return NULL; | |
| 3551 | 189 if (!filename || !strlen(filename)) |
| 2393 | 190 return NULL; |
| 191 | |
| 3565 | 192 #ifdef USE_PERL |
| 3563 | 193 if (is_so_file(filename, ".pl")) { |
| 194 return perl_load_file(filename); | |
| 195 } | |
| 3565 | 196 #endif |
| 3563 | 197 |
| 3551 | 198 while (filename && p) { |
| 199 plug = (struct gaim_plugin *)p->data; | |
| 200 if (!strcmp(filename, plug->path)) | |
| 201 break; | |
| 202 p = p->next; | |
| 2393 | 203 } |
| 3551 | 204 |
| 205 if (plug && plug->handle) { | |
| 206 reload_plugin(plug); | |
| 207 return NULL; | |
| 208 } | |
| 209 | |
| 210 if (!plug) { | |
| 211 plug = g_new0(struct gaim_plugin, 1); | |
| 212 g_snprintf(plug->path, sizeof(plug->path), filename); | |
| 213 newplug = TRUE; | |
| 214 } | |
| 215 | |
| 2393 | 216 debug_printf("Loading %s\n", filename); |
| 217 plug->handle = g_module_open(filename, 0); | |
| 218 if (!plug->handle) { | |
| 219 error = (char *)g_module_error(); | |
| 3551 | 220 plug->handle = NULL; |
| 3563 | 221 g_snprintf(plug->error, sizeof(plug->error), error); |
| 2393 | 222 return NULL; |
| 223 } | |
| 3551 | 224 |
| 2393 | 225 if (!g_module_symbol(plug->handle, "gaim_plugin_init", (gpointer *)&gaim_plugin_init)) { |
| 226 g_module_close(plug->handle); | |
| 3551 | 227 plug->handle = NULL; |
| 3563 | 228 g_snprintf(plug->error, sizeof(plug->error), error); |
| 2393 | 229 return NULL; |
| 230 } | |
| 231 | |
| 3563 | 232 plug->error[0] = '\0'; |
|
2662
b0c5770156e1
[gaim-migrate @ 2675]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2511
diff
changeset
|
233 retval = gaim_plugin_init(plug->handle); |
| 2393 | 234 debug_printf("loaded plugin returned %s\n", retval ? retval : "NULL"); |
| 235 if (retval) { | |
| 236 plugin_remove_callbacks(plug->handle); | |
| 3427 | 237 do_error_dialog("Gaim was unable to load your plugin.", retval, GAIM_ERROR); |
| 2393 | 238 g_module_close(plug->handle); |
| 3551 | 239 plug->handle = NULL; |
| 2393 | 240 return NULL; |
| 241 } | |
| 242 | |
| 243 plugins = g_list_append(plugins, plug); | |
| 244 | |
| 3551 | 245 if (newplug) { |
| 246 g_snprintf(plug->path, sizeof(plug->path), filename); | |
| 247 if (g_module_symbol(plug->handle, "gaim_plugin_desc", (gpointer *)&gaim_plugin_desc)) { | |
| 248 desc = gaim_plugin_desc(); | |
| 249 plug->desc.name = desc->name; | |
| 250 } else { | |
| 251 if (g_module_symbol(plug->handle, "name", (gpointer *)&cfunc)) { | |
| 252 plug->desc.name = g_strdup(cfunc()); | |
| 253 } | |
| 254 if (g_module_symbol(plug->handle, "description", (gpointer *)&cfunc)) { | |
| 255 plug->desc.description = g_strdup(cfunc()); | |
| 256 } | |
| 257 } | |
| 258 probed_plugins = g_list_append(probed_plugins, plug); | |
| 2393 | 259 } |
| 3551 | 260 |
| 2393 | 261 save_prefs(); |
| 262 return plug; | |
| 3551 | 263 |
| 2393 | 264 } |
| 265 | |
| 266 static void unload_gaim_plugin(struct gaim_plugin *p) | |
| 267 { | |
| 268 void (*gaim_plugin_remove)(); | |
| 269 | |
| 270 debug_printf("Unloading %s\n", g_module_name(p->handle)); | |
| 271 | |
| 272 /* Attempt to call the plugin's remove function (if there) */ | |
| 273 if (g_module_symbol(p->handle, "gaim_plugin_remove", (gpointer *)&gaim_plugin_remove)) | |
|
2662
b0c5770156e1
[gaim-migrate @ 2675]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2511
diff
changeset
|
274 gaim_plugin_remove(); |
| 2393 | 275 |
| 276 plugin_remove_callbacks(p->handle); | |
| 277 | |
| 278 plugins = g_list_remove(plugins, p); | |
| 3551 | 279 p->handle = NULL; |
| 2393 | 280 save_prefs(); |
| 281 } | |
| 282 | |
| 283 void unload_plugin(struct gaim_plugin *p) | |
| 284 { | |
| 285 GModule *handle = p->handle; | |
| 286 unload_gaim_plugin(p); | |
| 287 g_module_close(handle); | |
| 288 } | |
| 289 | |
| 290 static gboolean unload_timeout(gpointer handle) | |
| 291 { | |
| 292 g_module_close(handle); | |
| 293 return FALSE; | |
| 294 } | |
| 295 | |
| 296 void gaim_plugin_unload(GModule *handle) | |
| 297 { | |
|
2494
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
298 GList *pl = plugins; |
|
2511
a83b4a5ffcd6
[gaim-migrate @ 2524]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2494
diff
changeset
|
299 struct gaim_plugin *p = NULL; |
|
2494
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
300 void (*gaim_plugin_remove)(); |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
301 |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
302 while (pl) { |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
303 p = pl->data; |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
304 if (p->handle == handle) |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
305 break; |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
306 pl = pl->next; |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
307 } |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
308 if (!pl) |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
309 return; |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
310 |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
311 debug_printf("Unloading %s\n", g_module_name(p->handle)); |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
312 |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
313 if (g_module_symbol(p->handle, "gaim_plugin_remove", (gpointer *)&gaim_plugin_remove)) |
|
2662
b0c5770156e1
[gaim-migrate @ 2675]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2511
diff
changeset
|
314 gaim_plugin_remove(); |
|
2494
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
315 plugin_remove_callbacks(p->handle); |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
316 plugins = g_list_remove(plugins, p); |
|
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
317 g_free(p); |
| 3551 | 318 /* XXX CUI need to tell UI what happened, but not like this |
| 319 update_show_plugins(); */ | |
|
2494
2c1950c5544a
[gaim-migrate @ 2507]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2465
diff
changeset
|
320 |
| 2393 | 321 g_timeout_add(5000, unload_timeout, handle); |
| 322 } | |
| 323 | |
| 324 /* Do unload/load cycle of plugin. */ | |
| 325 struct gaim_plugin *reload_plugin(struct gaim_plugin *p) | |
| 326 { | |
| 327 char file[1024]; | |
| 328 GModule *handle = p->handle; | |
| 329 | |
| 330 strncpy(file, g_module_name(handle), sizeof(file)); | |
| 331 file[sizeof(file) - 1] = '\0'; | |
| 332 | |
| 333 debug_printf("Reloading %s\n", file); | |
| 334 | |
| 335 /* Unload */ | |
| 336 unload_plugin(p); | |
| 337 | |
| 338 /* Load */ | |
| 339 return load_plugin(file); | |
| 340 } | |
| 341 | |
| 342 /* Remove all callbacks associated with plugin handle */ | |
| 343 static void plugin_remove_callbacks(GModule *handle) | |
| 344 { | |
| 345 GList *c = callbacks; | |
| 346 struct gaim_callback *g; | |
| 347 | |
| 348 debug_printf("%d callbacks to search\n", g_list_length(callbacks)); | |
| 349 | |
| 350 while (c) { | |
| 351 g = (struct gaim_callback *)c->data; | |
| 352 if (g->handle == handle) { | |
| 353 c = g_list_next(c); | |
| 354 callbacks = g_list_remove(callbacks, (gpointer)g); | |
| 355 debug_printf("Removing callback, %d remain\n", g_list_length(callbacks)); | |
| 356 } else | |
| 357 c = g_list_next(c); | |
| 358 } | |
| 359 } | |
| 360 | |
| 361 void gaim_signal_connect(GModule *handle, enum gaim_event which, void *func, void *data) | |
| 362 { | |
| 363 struct gaim_callback *call = g_new0(struct gaim_callback, 1); | |
| 364 call->handle = handle; | |
| 365 call->event = which; | |
| 366 call->function = func; | |
| 367 call->data = data; | |
| 368 | |
| 369 callbacks = g_list_append(callbacks, call); | |
| 370 debug_printf("Adding callback %d\n", g_list_length(callbacks)); | |
| 371 } | |
| 372 | |
| 373 void gaim_signal_disconnect(GModule *handle, enum gaim_event which, void *func) | |
| 374 { | |
| 375 GList *c = callbacks; | |
| 376 struct gaim_callback *g = NULL; | |
| 377 | |
| 378 while (c) { | |
| 379 g = (struct gaim_callback *)c->data; | |
| 380 if (handle == g->handle && func == g->function) { | |
| 381 callbacks = g_list_remove(callbacks, c->data); | |
| 382 g_free(g); | |
| 383 c = callbacks; | |
| 384 if (c == NULL) | |
| 385 break; | |
| 386 } | |
| 387 c = g_list_next(c); | |
| 388 } | |
| 389 } | |
| 390 | |
| 391 #endif /* GAIM_PLUGINS */ | |
| 392 | |
|
2511
a83b4a5ffcd6
[gaim-migrate @ 2524]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2494
diff
changeset
|
393 char *event_name(enum gaim_event event) |
| 2393 | 394 { |
| 395 static char buf[128]; | |
| 396 switch (event) { | |
| 397 case event_signon: | |
| 398 sprintf(buf, "event_signon"); | |
| 399 break; | |
| 400 case event_signoff: | |
| 401 sprintf(buf, "event_signoff"); | |
| 402 break; | |
| 403 case event_away: | |
| 404 sprintf(buf, "event_away"); | |
| 405 break; | |
| 406 case event_back: | |
| 407 sprintf(buf, "event_back"); | |
| 408 break; | |
| 409 case event_im_recv: | |
| 410 sprintf(buf, "event_im_recv"); | |
| 411 break; | |
| 412 case event_im_send: | |
| 413 sprintf(buf, "event_im_send"); | |
| 414 break; | |
| 415 case event_buddy_signon: | |
| 416 sprintf(buf, "event_buddy_signon"); | |
| 417 break; | |
| 418 case event_buddy_signoff: | |
| 419 sprintf(buf, "event_buddy_signoff"); | |
| 420 break; | |
| 421 case event_buddy_away: | |
| 422 sprintf(buf, "event_buddy_away"); | |
| 423 break; | |
| 424 case event_buddy_back: | |
| 425 sprintf(buf, "event_buddy_back"); | |
| 426 break; | |
| 427 case event_buddy_idle: | |
| 428 sprintf(buf, "event_buddy_idle"); | |
| 429 break; | |
| 430 case event_buddy_unidle: | |
| 431 sprintf(buf, "event_buddy_unidle"); | |
| 432 break; | |
| 433 case event_blist_update: | |
| 434 sprintf(buf, "event_blist_update"); | |
| 435 break; | |
| 436 case event_chat_invited: | |
| 437 sprintf(buf, "event_chat_invited"); | |
| 438 break; | |
| 439 case event_chat_join: | |
| 440 sprintf(buf, "event_chat_join"); | |
| 441 break; | |
| 442 case event_chat_leave: | |
| 443 sprintf(buf, "event_chat_leave"); | |
| 444 break; | |
| 445 case event_chat_buddy_join: | |
| 446 sprintf(buf, "event_chat_buddy_join"); | |
| 447 break; | |
| 448 case event_chat_buddy_leave: | |
| 449 sprintf(buf, "event_chat_buddy_leave"); | |
| 450 break; | |
| 451 case event_chat_recv: | |
| 452 sprintf(buf, "event_chat_recv"); | |
| 453 break; | |
| 454 case event_chat_send: | |
| 455 sprintf(buf, "event_chat_send"); | |
| 456 break; | |
| 457 case event_warned: | |
| 458 sprintf(buf, "event_warned"); | |
| 459 break; | |
| 460 case event_error: | |
| 461 sprintf(buf, "event_error"); | |
| 462 break; | |
| 463 case event_quit: | |
| 464 sprintf(buf, "event_quit"); | |
| 465 break; | |
| 466 case event_new_conversation: | |
| 467 sprintf(buf, "event_new_conversation"); | |
| 468 break; | |
| 469 case event_set_info: | |
| 470 sprintf(buf, "event_set_info"); | |
| 471 break; | |
| 472 case event_draw_menu: | |
| 473 sprintf(buf, "event_draw_menu"); | |
| 474 break; | |
| 475 case event_im_displayed_sent: | |
| 476 sprintf(buf, "event_im_displayed_sent"); | |
| 477 break; | |
| 478 case event_im_displayed_rcvd: | |
| 479 sprintf(buf, "event_im_displayed_rcvd"); | |
| 480 break; | |
| 481 case event_chat_send_invite: | |
| 482 sprintf(buf, "event_chat_send_invite"); | |
| 483 break; | |
| 2993 | 484 case event_got_typing: |
| 485 sprintf(buf, "event_got_typing"); | |
| 486 break; | |
| 3510 | 487 case event_del_conversation: |
| 488 sprintf(buf, "event_del_conversation"); | |
| 489 break; | |
| 490 case event_connecting: | |
| 491 sprintf(buf, "event_connecting"); | |
| 492 break; | |
| 2393 | 493 default: |
| 494 sprintf(buf, "event_unknown"); | |
| 495 break; | |
| 496 } | |
| 497 return buf; | |
| 498 } | |
| 499 | |
| 3517 | 500 int plugin_event(enum gaim_event event, ...) |
| 2393 | 501 { |
| 502 #ifdef GAIM_PLUGINS | |
| 503 GList *c = callbacks; | |
| 504 struct gaim_callback *g; | |
| 3551 | 505 #endif |
| 3517 | 506 va_list arrg; |
| 507 void *arg1 = NULL, | |
| 508 *arg2 = NULL, | |
| 509 *arg3 = NULL, | |
| 510 *arg4 = NULL, | |
| 511 *arg5 = NULL; | |
| 3551 | 512 |
| 2393 | 513 |
| 3517 | 514 debug_printf("%s\n", event_name(event)); |
|
2463
0be6fadaa64f
[gaim-migrate @ 2476]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2443
diff
changeset
|
515 |
|
0be6fadaa64f
[gaim-migrate @ 2476]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2443
diff
changeset
|
516 #ifdef GAIM_PLUGINS |
| 2393 | 517 while (c) { |
| 3517 | 518 void (*cbfunc)(void *, ...); |
| 519 | |
| 2393 | 520 g = (struct gaim_callback *)c->data; |
|
2511
a83b4a5ffcd6
[gaim-migrate @ 2524]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2494
diff
changeset
|
521 if (g->event == event && g->function != NULL) { |
| 3517 | 522 cbfunc=g->function; |
| 523 va_start(arrg, event); | |
| 2393 | 524 switch (event) { |
| 525 | |
| 526 /* no args */ | |
| 527 case event_blist_update: | |
| 528 case event_quit: | |
| 3517 | 529 cbfunc(g->data); |
| 2393 | 530 break; |
| 531 | |
| 532 /* one arg */ | |
| 533 case event_signon: | |
| 534 case event_signoff: | |
| 535 case event_new_conversation: | |
| 3461 | 536 case event_del_conversation: |
| 2393 | 537 case event_error: |
| 3510 | 538 case event_connecting: |
| 3517 | 539 arg1 = va_arg(arrg, void *); |
| 540 cbfunc(arg1, g->data); | |
| 2393 | 541 break; |
| 542 | |
| 543 /* two args */ | |
| 544 case event_buddy_signon: | |
| 545 case event_buddy_signoff: | |
| 546 case event_buddy_away: | |
| 547 case event_buddy_back: | |
| 548 case event_buddy_idle: | |
| 549 case event_buddy_unidle: | |
| 550 case event_set_info: | |
| 551 case event_draw_menu: | |
| 2993 | 552 case event_got_typing: |
| 3517 | 553 arg1 = va_arg(arrg, void *); |
| 554 arg2 = va_arg(arrg, void *); | |
| 555 cbfunc(arg1, arg2, g->data); | |
| 2393 | 556 break; |
| 3517 | 557 case event_chat_leave: |
| 558 { | |
| 559 int id; | |
| 560 arg1 = va_arg(arrg, void*); | |
| 561 id = va_arg(arrg, int); | |
| 562 cbfunc(arg1, id, g->data); | |
| 563 } | |
| 564 break; | |
| 2393 | 565 /* three args */ |
| 566 case event_im_send: | |
| 567 case event_im_displayed_sent: | |
| 3517 | 568 case event_away: |
| 569 arg1 = va_arg(arrg, void *); | |
| 570 arg2 = va_arg(arrg, void *); | |
| 571 arg3 = va_arg(arrg, void *); | |
| 572 cbfunc(arg1, arg2, arg3, g->data); | |
| 573 break; | |
| 2393 | 574 case event_chat_buddy_join: |
| 575 case event_chat_buddy_leave: | |
| 576 case event_chat_send: | |
| 3517 | 577 case event_chat_join: |
| 578 { | |
| 579 int id; | |
| 580 arg1 = va_arg(arrg, void*); | |
| 581 id = va_arg(arrg, int); | |
| 582 arg3 = va_arg(arrg, void*); | |
| 583 cbfunc(arg1, id, arg3, g->data); | |
| 584 } | |
| 585 break; | |
| 2393 | 586 case event_warned: |
| 3517 | 587 { |
| 588 int id; | |
| 589 arg1 = va_arg(arrg, void*); | |
| 590 arg2 = va_arg(arrg, void*); | |
| 591 id = va_arg(arrg, int); | |
| 592 cbfunc(arg1, arg2, id, g->data); | |
| 593 } | |
| 2393 | 594 break; |
| 595 /* four args */ | |
| 596 case event_im_recv: | |
| 3517 | 597 case event_chat_invited: |
| 598 arg1 = va_arg(arrg, void *); | |
| 599 arg2 = va_arg(arrg, void *); | |
| 600 arg3 = va_arg(arrg, void *); | |
| 601 arg4 = va_arg(arrg, void *); | |
| 602 cbfunc(arg1, arg2, arg3, arg4, g->data); | |
| 603 break; | |
| 2393 | 604 case event_chat_recv: |
| 605 case event_chat_send_invite: | |
| 3517 | 606 { |
| 607 int id; | |
| 608 arg1 = va_arg(arrg, void *); | |
| 609 id = va_arg(arrg, int); | |
| 610 | |
| 611 arg3 = va_arg(arrg, void *); | |
| 612 arg4 = va_arg(arrg, void *); | |
| 613 cbfunc(arg1, id, arg3, arg4, g->data); | |
| 614 } | |
| 2393 | 615 break; |
| 3517 | 616 /* five args */ |
| 617 case event_im_displayed_rcvd: | |
| 618 { | |
| 619 time_t time; | |
| 620 arg1 = va_arg(arrg, void *); | |
| 621 arg2 = va_arg(arrg, void *); | |
| 622 arg3 = va_arg(arrg, void *); | |
| 623 arg4 = va_arg(arrg, void *); | |
| 624 time = va_arg(arrg, time_t); | |
| 625 cbfunc(arg1, arg2, arg3, arg4, time, g->data); | |
| 626 } | |
| 627 break; | |
| 628 default: | |
| 2393 | 629 debug_printf("unknown event %d\n", event); |
| 630 break; | |
| 631 } | |
| 3517 | 632 va_end(arrg); |
| 2393 | 633 } |
| 634 c = c->next; | |
| 635 } | |
| 636 #endif /* GAIM_PLUGINS */ | |
| 637 #ifdef USE_PERL | |
| 3517 | 638 va_start(arrg, event); |
| 639 arg1 = va_arg(arrg, void *); | |
| 640 arg2 = va_arg(arrg, void *); | |
| 641 arg3 = va_arg(arrg, void *); | |
| 642 arg4 = va_arg(arrg, void *); | |
| 643 arg5 = va_arg(arrg, void *); | |
| 644 return perl_event(event, arg1, arg2, arg3, arg4, arg5); | |
| 2393 | 645 #else |
| 646 return 0; | |
| 647 #endif | |
| 648 } | |
| 649 | |
| 650 /* Calls the gaim_plugin_remove function in any loaded plugin that has one */ | |
| 651 #ifdef GAIM_PLUGINS | |
| 652 void remove_all_plugins() | |
| 653 { | |
| 654 GList *c = plugins; | |
| 655 struct gaim_plugin *p; | |
| 656 void (*gaim_plugin_remove)(); | |
| 657 | |
| 658 while (c) { | |
| 659 p = (struct gaim_plugin *)c->data; | |
| 3563 | 660 if (p->type == plugin) { |
| 661 if (g_module_symbol(p->handle, "gaim_plugin_remove", (gpointer *)&gaim_plugin_remove)) | |
| 662 gaim_plugin_remove(); | |
| 663 } | |
| 2393 | 664 g_free(p); |
| 665 c = c->next; | |
| 666 } | |
| 667 } | |
| 668 #endif |
