# HG changeset patch # User Christian Hammond # Date 1055642603 0 # Node ID 448f2f4ca3ec4e0a98f4e5e8cbde1ca22784e05d # Parent 964e4f94fc5651593a8827b6722d99edadd6b789 [gaim-migrate @ 6307] Rewrote the pounce framework.. yes, again. But now it saves! OOhh!! Neato. Things are cleaner too. AND I CHANGED THE OK BUTTON TO SAVE! committer: Tailor Script diff -r 964e4f94fc56 -r 448f2f4ca3ec src/account.c --- a/src/account.c Sat Jun 14 23:50:24 2003 +0000 +++ b/src/account.c Sun Jun 15 02:03:23 2003 +0000 @@ -705,7 +705,7 @@ AccountParserData *data = user_data; if (data->buffer != NULL) - g_free(data->buffer); + g_string_free(data->buffer, TRUE); if (data->setting_name != NULL) g_free(data->setting_name); diff -r 964e4f94fc56 -r 448f2f4ca3ec src/gaimrc.c --- a/src/gaimrc.c Sat Jun 14 23:50:24 2003 +0000 +++ b/src/gaimrc.c Sun Jun 15 02:03:23 2003 +0000 @@ -1647,7 +1647,7 @@ old_pounce_opts_to_new(ph->options, &events, &actions); - pounce = gaim_gtkpounce_new(account, ph->name, events); + pounce = gaim_pounce_new(GAIM_GTK_UI, account, ph->name, events); gaim_pounce_action_set_enabled(pounce, "open-window", (actions & GAIM_GTKPOUNCE_OPEN_WIN)); diff -r 964e4f94fc56 -r 448f2f4ca3ec src/gtkpounce.c --- a/src/gtkpounce.c Sat Jun 14 23:50:24 2003 +0000 +++ b/src/gtkpounce.c Sun Jun 15 02:03:23 2003 +0000 @@ -219,7 +219,8 @@ if (*sound == '\0') sound = NULL; if (dialog->pounce == NULL) { - dialog->pounce = gaim_gtkpounce_new(dialog->account, name, events); + dialog->pounce = gaim_pounce_new(GAIM_GTK_UI, dialog->account, + name, events); } else { gaim_pounce_set_events(dialog->pounce, events); @@ -251,6 +252,8 @@ delete_win_cb(NULL, NULL, dialog); + gaim_pounces_sync(); + /* Rebuild the pounce menu */ blist = gaim_get_blist(); @@ -316,134 +319,6 @@ return opt_menu; } -static void -pounce_cb(GaimPounce *pounce, GaimPounceEvent events, void *data) -{ - GaimConversation *conv; - GaimAccount *account; - const char *pouncee; - - pouncee = gaim_pounce_get_pouncee(pounce); - account = gaim_pounce_get_pouncer(pounce); - - if (gaim_pounce_action_is_enabled(pounce, "open-window")) { - conv = gaim_find_conversation(pouncee); - - if (conv == NULL) - conv = gaim_conversation_new(GAIM_CONV_IM, account, pouncee); - } - - if (gaim_pounce_action_is_enabled(pounce, "popup-notify")) { - char tmp[1024]; - - g_snprintf(tmp, sizeof(tmp), - (events & GAIM_POUNCE_TYPING) ? _("%s has started typing to you") : - (events & GAIM_POUNCE_SIGNON) ? _("%s has signed on") : - (events & GAIM_POUNCE_IDLE_RETURN) ? _("%s has returned from being idle") : - (events & GAIM_POUNCE_AWAY_RETURN) ? _("%s has returned from being away") : - (events & GAIM_POUNCE_TYPING_STOPPED) ? _("%s has stopped typing to you") : - (events & GAIM_POUNCE_SIGNOFF) ? _("%s has signed off") : - (events & GAIM_POUNCE_IDLE) ? _("%s has become idle") : - (events & GAIM_POUNCE_AWAY) ? _("%s has gone away.") : - _("Unknown pounce event. Please report this!"), - pouncee); - - gaim_notify_info(NULL, NULL, tmp, NULL); - } - - if (gaim_pounce_action_is_enabled(pounce, "send-message")) { - const char *message; - - message = gaim_pounce_action_get_attribute(pounce, "send-message", - "message"); - - if (message != NULL) { - conv = gaim_find_conversation(pouncee); - - if (conv == NULL) - conv = gaim_conversation_new(GAIM_CONV_IM, account, pouncee); - - gaim_conversation_write(conv, NULL, message, -1, - WFLAG_SEND, time(NULL)); - - serv_send_im(account->gc, (char *)pouncee, (char *)message, -1, 0); - } - } - -#ifndef _WIN32 - if (gaim_pounce_action_is_enabled(pounce, "execute-command")) { - const char *command; - - command = gaim_pounce_action_get_attribute(pounce, "execute-command", - "command"); - - if (command != NULL) { - int pid = fork(); - - if (pid == 0) { - char *args[4]; - - args[0] = "sh"; - args[1] = "-c"; - args[2] = (char *)command; - args[3] = NULL; - - execvp(args[0], args); - - _exit(0); - } - } - } -#endif /* _WIN32 */ - - if (gaim_pounce_action_is_enabled(pounce, "play-sound")) { - const char *sound; - - sound = gaim_pounce_action_get_attribute(pounce, "play-sound", - "sound"); - - if (sound != NULL) - gaim_sound_play_file(sound); - else - gaim_sound_play_event(GAIM_SOUND_POUNCE_DEFAULT); - } -} - -static void -free_pounce(void *data) -{ - struct gaim_buddy_list *blist; - struct gaim_gtk_buddy_list *gtkblist; - - /* Rebuild the pounce menu */ - blist = gaim_get_blist(); - - if (GAIM_IS_GTK_BLIST(blist)) - { - gtkblist = GAIM_GTK_BLIST(blist); - - gaim_gtkpounce_menu_build(gtkblist->bpmenu); - } -} - -GaimPounce * -gaim_gtkpounce_new(GaimAccount *pouncer, const char *pouncee, - GaimPounceEvent events) -{ - GaimPounce *pounce; - - pounce = gaim_pounce_new(GAIM_GTK_UI, pouncer, pouncee, events, - pounce_cb, NULL, free_pounce); - - gaim_pounce_action_register(pounce, "open-window"); - gaim_pounce_action_register(pounce, "popup-notify"); - gaim_pounce_action_register(pounce, "send-message"); - gaim_pounce_action_register(pounce, "execute-command"); - gaim_pounce_action_register(pounce, "play-sound"); - - return pounce; -} - void gaim_gtkpounce_dialog_show(struct buddy *buddy, GaimPounce *cur_pounce) @@ -729,8 +604,8 @@ g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cancel_cb), dialog); - /* OK button */ - button = gtk_button_new_from_stock(GTK_STOCK_OK); + /* Save button */ + button = gtk_button_new_from_stock(GTK_STOCK_SAVE); gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); gtk_widget_show(button); @@ -910,3 +785,129 @@ fill_menu(menu, G_CALLBACK(edit_pounce_cb)); } +static void +pounce_cb(GaimPounce *pounce, GaimPounceEvent events, void *data) +{ + GaimConversation *conv; + GaimAccount *account; + const char *pouncee; + + pouncee = gaim_pounce_get_pouncee(pounce); + account = gaim_pounce_get_pouncer(pounce); + + if (gaim_pounce_action_is_enabled(pounce, "open-window")) { + conv = gaim_find_conversation(pouncee); + + if (conv == NULL) + conv = gaim_conversation_new(GAIM_CONV_IM, account, pouncee); + } + + if (gaim_pounce_action_is_enabled(pounce, "popup-notify")) { + char tmp[1024]; + + g_snprintf(tmp, sizeof(tmp), + (events & GAIM_POUNCE_TYPING) ? _("%s has started typing to you") : + (events & GAIM_POUNCE_SIGNON) ? _("%s has signed on") : + (events & GAIM_POUNCE_IDLE_RETURN) ? _("%s has returned from being idle") : + (events & GAIM_POUNCE_AWAY_RETURN) ? _("%s has returned from being away") : + (events & GAIM_POUNCE_TYPING_STOPPED) ? _("%s has stopped typing to you") : + (events & GAIM_POUNCE_SIGNOFF) ? _("%s has signed off") : + (events & GAIM_POUNCE_IDLE) ? _("%s has become idle") : + (events & GAIM_POUNCE_AWAY) ? _("%s has gone away.") : + _("Unknown pounce event. Please report this!"), + pouncee); + + gaim_notify_info(NULL, NULL, tmp, NULL); + } + + if (gaim_pounce_action_is_enabled(pounce, "send-message")) { + const char *message; + + message = gaim_pounce_action_get_attribute(pounce, "send-message", + "message"); + + if (message != NULL) { + conv = gaim_find_conversation(pouncee); + + if (conv == NULL) + conv = gaim_conversation_new(GAIM_CONV_IM, account, pouncee); + + gaim_conversation_write(conv, NULL, message, -1, + WFLAG_SEND, time(NULL)); + + serv_send_im(account->gc, (char *)pouncee, (char *)message, -1, 0); + } + } + +#ifndef _WIN32 + if (gaim_pounce_action_is_enabled(pounce, "execute-command")) { + const char *command; + + command = gaim_pounce_action_get_attribute(pounce, "execute-command", + "command"); + + if (command != NULL) { + int pid = fork(); + + if (pid == 0) { + char *args[4]; + + args[0] = "sh"; + args[1] = "-c"; + args[2] = (char *)command; + args[3] = NULL; + + execvp(args[0], args); + + _exit(0); + } + } + } +#endif /* _WIN32 */ + + if (gaim_pounce_action_is_enabled(pounce, "play-sound")) { + const char *sound; + + sound = gaim_pounce_action_get_attribute(pounce, "play-sound", + "sound"); + + if (sound != NULL) + gaim_sound_play_file(sound); + else + gaim_sound_play_event(GAIM_SOUND_POUNCE_DEFAULT); + } +} + +static void +free_pounce(GaimPounce *pounce) +{ + struct gaim_buddy_list *blist; + struct gaim_gtk_buddy_list *gtkblist; + + /* Rebuild the pounce menu */ + blist = gaim_get_blist(); + + if (GAIM_IS_GTK_BLIST(blist)) + { + gtkblist = GAIM_GTK_BLIST(blist); + + gaim_gtkpounce_menu_build(gtkblist->bpmenu); + } +} + +static void +new_pounce(GaimPounce *pounce) +{ + gaim_pounce_action_register(pounce, "open-window"); + gaim_pounce_action_register(pounce, "popup-notify"); + gaim_pounce_action_register(pounce, "send-message"); + gaim_pounce_action_register(pounce, "execute-command"); + gaim_pounce_action_register(pounce, "play-sound"); +} + +void +gaim_gtk_pounces_init(void) +{ + gaim_pounces_register_handler(GAIM_GTK_UI, pounce_cb, new_pounce, + free_pounce); +} diff -r 964e4f94fc56 -r 448f2f4ca3ec src/gtkpounce.h --- a/src/gtkpounce.h Sat Jun 14 23:50:24 2003 +0000 +++ b/src/gtkpounce.h Sun Jun 15 02:03:23 2003 +0000 @@ -26,18 +26,6 @@ #include "pounce.h" /** - * Creates a GTK-specific pounce. - * - * @param pouncer The account that will pounce. - * @param pouncee The buddy to pounce on. - * @param events The event(s) to pounce on. - * - * @return The new buddy pounce. - */ -GaimPounce *gaim_gtkpounce_new(GaimAccount *pouncer, const char *pouncee, - GaimPounceEvent events); - -/** * Displays a New Buddy Pounce or Edit Buddy Pounce dialog. * * @param buddy The optional buddy to pounce on. @@ -52,4 +40,9 @@ */ void gaim_gtkpounce_menu_build(GtkWidget *menu); +/** + * Initializes the GTK+ pounces subsystem. + */ +void gaim_gtk_pounces_init(void); + #endif /* _GAIM_GTK_POUNCE_H_ */ diff -r 964e4f94fc56 -r 448f2f4ca3ec src/main.c --- a/src/main.c Sat Jun 14 23:50:24 2003 +0000 +++ b/src/main.c Sun Jun 15 02:03:23 2003 +0000 @@ -42,6 +42,7 @@ #include "gtkdebug.h" #include "gtkft.h" #include "gtknotify.h" +#include "gtkpounce.h" #include "gtkprefs.h" #include "gtkrequest.h" #include "gtksound.h" @@ -855,8 +856,10 @@ gaim_conversation_init(); gaim_proxy_init(); gaim_sound_init(); + gaim_pounces_init(); gaim_gtk_conversation_init(); + gaim_gtk_pounces_init(); plugin_search_paths[0] = LIBDIR; plugin_search_paths[1] = gaim_user_dir(); diff -r 964e4f94fc56 -r 448f2f4ca3ec src/pounce.c --- a/src/pounce.c Sat Jun 14 23:50:24 2003 +0000 +++ b/src/pounce.c Sun Jun 15 02:03:23 2003 +0000 @@ -30,6 +30,23 @@ typedef struct { + GString *buffer; + + GaimPounce *pounce; + GaimPounceEvent events; + + char *ui_name; + char *pouncee; + char *protocol_id; + char *event_type; + char *action_name; + char *param_name; + char *account_name; + +} PounceParserData; + +typedef struct +{ char *name; gboolean enabled; @@ -38,10 +55,21 @@ } GaimPounceActionData; +typedef struct +{ + char *ui; + GaimPounceCb cb; + void (*new_pounce)(GaimPounce *); + void (*free_pounce)(GaimPounce *); -static GList *pounces = NULL; -static guint pounces_save_timer = 0; -static gboolean pounces_loaded = FALSE; +} GaimPounceHandler; + + +static GHashTable *pounce_handlers = NULL; +static GList *pounces = NULL; +static guint pounces_save_timer = 0; +static gboolean pounces_loaded = FALSE; + static GaimPounceActionData * find_action_data(const GaimPounce *pounce, const char *name) @@ -86,16 +114,15 @@ GaimPounce * gaim_pounce_new(const char *ui_type, GaimAccount *pouncer, - const char *pouncee, GaimPounceEvent event, - GaimPounceCb cb, void *data, void (*free)(void *)) + const char *pouncee, GaimPounceEvent event) { GaimPounce *pounce; + GaimPounceHandler *handler; g_return_val_if_fail(ui_type != NULL, NULL); g_return_val_if_fail(pouncer != NULL, NULL); g_return_val_if_fail(pouncee != NULL, NULL); g_return_val_if_fail(event != 0, NULL); - g_return_val_if_fail(cb != NULL, NULL); pounce = g_new0(GaimPounce, 1); @@ -103,13 +130,15 @@ pounce->pouncer = pouncer; pounce->pouncee = g_strdup(pouncee); pounce->events = event; - pounce->callback = cb; - pounce->data = data; - pounce->free = free; pounce->actions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_action_data); + handler = g_hash_table_lookup(pounce_handlers, pounce->ui_type); + + if (handler != NULL && handler->new_pounce != NULL) + handler->new_pounce(pounce); + pounces = g_list_append(pounces, pounce); return pounce; @@ -118,8 +147,12 @@ void gaim_pounce_destroy(GaimPounce *pounce) { + GaimPounceHandler *handler; + g_return_if_fail(pounce != NULL); + handler = g_hash_table_lookup(pounce_handlers, pounce->ui_type); + pounces = g_list_remove(pounces, pounce); if (pounce->ui_type != NULL) g_free(pounce->ui_type); @@ -127,8 +160,8 @@ g_hash_table_destroy(pounce->actions); - if (pounce->free != NULL && pounce->data != NULL) - pounce->free(pounce->data); + if (handler != NULL && handler->free_pounce != NULL) + handler->free_pounce(pounce); g_free(pounce); @@ -327,6 +360,7 @@ GaimPounceEvent events) { GaimPounce *pounce; + GaimPounceHandler *handler; GList *l, *l_next; g_return_if_fail(pouncer != NULL); @@ -341,8 +375,10 @@ (gaim_pounce_get_pouncer(pounce) == pouncer) && !strcmp(gaim_pounce_get_pouncee(pounce), pouncee)) { - if (pounce->callback != NULL) { - pounce->callback(pounce, events, gaim_pounce_get_data(pounce)); + handler = g_hash_table_lookup(pounce_handlers, pounce->ui_type); + + if (handler != NULL && handler->cb != NULL) { + handler->cb(pounce, events, gaim_pounce_get_data(pounce)); if (!gaim_pounce_get_save(pounce)) gaim_pounce_destroy(pounce); @@ -376,9 +412,299 @@ return NULL; } +/* XML Stuff */ +static void +free_parser_data(gpointer user_data) +{ + PounceParserData *data = user_data; + + if (data->buffer != NULL) + g_string_free(data->buffer, TRUE); + + if (data->ui_name != NULL) g_free(data->ui_name); + if (data->pouncee != NULL) g_free(data->pouncee); + if (data->protocol_id != NULL) g_free(data->protocol_id); + if (data->event_type != NULL) g_free(data->event_type); + if (data->action_name != NULL) g_free(data->action_name); + if (data->param_name != NULL) g_free(data->param_name); + if (data->account_name != NULL) g_free(data->account_name); + + g_free(data); +} + +static void +start_element_handler(GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, GError **error) +{ + PounceParserData *data = user_data; + GHashTable *atts; + int i; + + atts = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + + for (i = 0; attribute_names[i] != NULL; i++) { + g_hash_table_insert(atts, g_strdup(attribute_names[i]), + g_strdup(attribute_values[i])); + } + + if (data->buffer != NULL) { + g_string_free(data->buffer, TRUE); + data->buffer = NULL; + } + + if (!strcmp(element_name, "pounce")) { + const char *ui = g_hash_table_lookup(atts, "ui"); + + if (ui == NULL) { + gaim_debug(GAIM_DEBUG_ERROR, "pounce", + "Unset 'ui' parameter for pounce!\n"); + } + else + data->ui_name = g_strdup(ui); + + data->events = 0; + } + else if (!strcmp(element_name, "account")) { + const char *protocol_id = g_hash_table_lookup(atts, "protocol"); + + if (protocol_id == NULL) { + gaim_debug(GAIM_DEBUG_ERROR, "pounce", + "Unset 'protocol' parameter for account!\n"); + } + else + data->protocol_id = g_strdup(protocol_id); + } + else if (!strcmp(element_name, "event")) { + const char *type = g_hash_table_lookup(atts, "type"); + + if (type == NULL) { + gaim_debug(GAIM_DEBUG_ERROR, "pounce", + "Unset 'type' parameter for event!\n"); + } + else + data->event_type = g_strdup(type); + } + else if (!strcmp(element_name, "action")) { + const char *type = g_hash_table_lookup(atts, "type"); + + if (type == NULL) { + gaim_debug(GAIM_DEBUG_ERROR, "pounce", + "Unset 'type' parameter for action!\n"); + } + else + data->action_name = g_strdup(type); + } + else if (!strcmp(element_name, "param")) { + const char *param_name = g_hash_table_lookup(atts, "name"); + + if (param_name == NULL) { + gaim_debug(GAIM_DEBUG_ERROR, "pounce", + "Unset 'name' parameter for param!\n"); + } + else + data->param_name = g_strdup(param_name); + } + + g_hash_table_destroy(atts); +} + +static void +end_element_handler(GMarkupParseContext *context, const gchar *element_name, + gpointer user_data, GError **error) +{ + PounceParserData *data = user_data; + gchar *buffer = NULL; + + if (data->buffer != NULL) { + buffer = g_string_free(data->buffer, FALSE); + data->buffer = NULL; + } + + if (!strcmp(element_name, "account")) { + data->account_name = g_strdup(buffer); + } + else if (!strcmp(element_name, "pouncee")) { + data->pouncee = g_strdup(buffer); + } + else if (!strcmp(element_name, "event")) { + if (!strcmp(data->event_type, "sign-on")) + data->events |= GAIM_POUNCE_SIGNON; + else if (!strcmp(data->event_type, "sign-off")) + data->events |= GAIM_POUNCE_SIGNOFF; + else if (!strcmp(data->event_type, "away")) + data->events |= GAIM_POUNCE_AWAY; + else if (!strcmp(data->event_type, "return-from-away")) + data->events |= GAIM_POUNCE_AWAY_RETURN; + else if (!strcmp(data->event_type, "idle")) + data->events |= GAIM_POUNCE_IDLE; + else if (!strcmp(data->event_type, "return-from-idle")) + data->events |= GAIM_POUNCE_IDLE_RETURN; + else if (!strcmp(data->event_type, "typing")) + data->events |= GAIM_POUNCE_TYPING; + else if (!strcmp(data->event_type, "stop-typing")) + data->events |= GAIM_POUNCE_TYPING_STOPPED; + + g_free(data->event_type); + data->event_type = NULL; + } + else if (!strcmp(element_name, "action")) { + gaim_pounce_action_set_enabled(data->pounce, data->action_name, TRUE); + + g_free(data->action_name); + data->action_name = NULL; + } + else if (!strcmp(element_name, "param")) { + gaim_pounce_action_set_attribute(data->pounce, data->action_name, + data->param_name, buffer); + + g_free(data->param_name); + data->param_name = NULL; + } + else if (!strcmp(element_name, "events")) { + GList *l; + GaimAccount *account; + GaimProtocol protocol = -1; + + for (l = gaim_plugins_get_protocols(); l != NULL; l = l->next) { + GaimPlugin *plugin = (GaimPlugin *)l->data; + + if (GAIM_IS_PROTOCOL_PLUGIN(plugin)) { + if (!strcmp(plugin->info->id, data->protocol_id)) { + protocol = GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol; + + break; + } + } + } + + account = gaim_accounts_find(data->account_name, protocol); + + g_free(data->account_name); + g_free(data->protocol_id); + + data->account_name = NULL; + data->protocol_id = NULL; + + if (account == NULL) { + gaim_debug(GAIM_DEBUG_ERROR, "pounce", + "Account for pounce not found!\n"); + } + else { + gaim_debug(GAIM_DEBUG_INFO, "pounce", + "Creating pounce: %s, %s\n", data->ui_name, + data->pouncee); + + data->pounce = gaim_pounce_new(data->ui_name, account, + data->pouncee, data->events); + } + + g_free(data->pouncee); + data->pouncee = NULL; + } + else if (!strcmp(element_name, "pounce")) { + data->pounce = NULL; + data->events = 0; + + if (data->ui_name != NULL) g_free(data->ui_name); + if (data->pouncee != NULL) g_free(data->pouncee); + if (data->protocol_id != NULL) g_free(data->protocol_id); + if (data->event_type != NULL) g_free(data->event_type); + if (data->action_name != NULL) g_free(data->action_name); + if (data->param_name != NULL) g_free(data->param_name); + if (data->account_name != NULL) g_free(data->account_name); + + data->ui_name = NULL; + data->pounce = NULL; + data->protocol_id = NULL; + data->event_type = NULL; + data->action_name = NULL; + data->param_name = NULL; + data->account_name = NULL; + } + + if (buffer != NULL) + g_free(buffer); +} + +static void +text_handler(GMarkupParseContext *context, const gchar *text, + gsize text_len, gpointer user_data, GError **error) +{ + PounceParserData *data = user_data; + + if (data->buffer == NULL) + data->buffer = g_string_new_len(text, text_len); + else + g_string_append_len(data->buffer, text, text_len); +} + +static GMarkupParser pounces_parser = +{ + start_element_handler, + end_element_handler, + text_handler, + NULL, + NULL +}; + gboolean gaim_pounces_load(void) { + gchar *filename = g_build_filename(gaim_user_dir(), "pounces.xml", NULL); + gchar *contents = NULL; + gsize length; + GMarkupParseContext *context; + GError *error = NULL; + PounceParserData *parser_data; + + if (filename == NULL) { + pounces_loaded = TRUE; + return FALSE; + } + + if (!g_file_get_contents(filename, &contents, &length, &error)) { + gaim_debug(GAIM_DEBUG_ERROR, "pounces", + "Error reading pounces: %s\n", error->message); + + g_error_free(error); + + pounces_loaded = TRUE; + return FALSE; + } + + parser_data = g_new0(PounceParserData, 1); + + context = g_markup_parse_context_new(&pounces_parser, 0, + parser_data, free_parser_data); + + if (!g_markup_parse_context_parse(context, contents, length, NULL)) { + g_markup_parse_context_free(context); + g_free(contents); + + pounces_loaded = TRUE; + + return FALSE; + } + + if (!g_markup_parse_context_end_parse(context, NULL)) { + gaim_debug(GAIM_DEBUG_ERROR, "pounces", "Error parsing %s\n", + filename); + + g_markup_parse_context_free(context); + g_free(contents); + pounces_loaded = TRUE; + + return FALSE; + } + + g_markup_parse_context_free(context); + g_free(contents); + + g_free(filename); + pounces_loaded = TRUE; return TRUE; @@ -444,21 +770,21 @@ fprintf(fp, " \n"); if (events & GAIM_POUNCE_SIGNON) - fprintf(fp, " \n"); + fprintf(fp, " \n"); if (events & GAIM_POUNCE_SIGNOFF) - fprintf(fp, " \n"); + fprintf(fp, " \n"); if (events & GAIM_POUNCE_AWAY) - fprintf(fp, " \n"); + fprintf(fp, " \n"); if (events & GAIM_POUNCE_AWAY_RETURN) - fprintf(fp, " \n"); + fprintf(fp, " \n"); if (events & GAIM_POUNCE_IDLE) - fprintf(fp, " \n"); + fprintf(fp, " \n"); if (events & GAIM_POUNCE_IDLE_RETURN) - fprintf(fp, " \n"); + fprintf(fp, " \n"); if (events & GAIM_POUNCE_TYPING) - fprintf(fp, " \n"); + fprintf(fp, " \n"); if (events & GAIM_POUNCE_TYPING_STOPPED) - fprintf(fp, " \n"); + fprintf(fp, " \n"); fprintf(fp, " \n"); fprintf(fp, " \n"); @@ -530,8 +856,52 @@ g_free(filename_real); } +void +gaim_pounces_register_handler(const char *ui, GaimPounceCb cb, + void (*new_pounce)(GaimPounce *pounce), + void (*free_pounce)(GaimPounce *pounce)) +{ + GaimPounceHandler *handler; + + g_return_if_fail(ui != NULL); + g_return_if_fail(cb != NULL); + + handler = g_new0(GaimPounceHandler, 1); + + handler->ui = g_strdup(ui); + handler->cb = cb; + handler->new_pounce = new_pounce; + handler->free_pounce = free_pounce; + + g_hash_table_insert(pounce_handlers, g_strdup(ui), handler); +} + +void +gaim_pounces_unregister_handler(const char *ui) +{ + g_return_if_fail(ui != NULL); + + g_hash_table_remove(pounce_handlers, ui); +} + GList * gaim_pounces_get_all(void) { return pounces; } + +static void +free_pounce_handler(gpointer user_data) +{ + GaimPounceHandler *handler = (GaimPounceHandler *)user_data; + + g_free(handler->ui); + g_free(handler); +} + +void +gaim_pounces_init(void) +{ + pounce_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, free_pounce_handler); +} diff -r 964e4f94fc56 -r 448f2f4ca3ec src/pounce.h --- a/src/pounce.h Sat Jun 14 23:50:24 2003 +0000 +++ b/src/pounce.h Sun Jun 15 02:03:23 2003 +0000 @@ -69,9 +69,6 @@ gboolean save; /**< Whether or not the pounce should be saved after activation. */ - GaimPounceCb callback; /**< The callback function to call when the - event is triggered. */ - void (*free)(void *data); /**< The data free function. */ void *data; /**< Pounce-specific data. */ }; @@ -82,16 +79,11 @@ * @param pouncer The account that will pounce. * @param pouncee The buddy to pounce on. * @param event The event(s) to pounce on. - * @param cb The callback function to call when the pounce is triggered. - * @param data Pounce-specific data. - * @param free The function to free the pounce-specific data. * * @return The new buddy pounce structure. */ -GaimPounce *gaim_pounce_new(const char *ui_type, - GaimAccount *pouncer, const char *pouncee, - GaimPounceEvent event, GaimPounceCb cb, - void *data, void (*free)(void *)); +GaimPounce *gaim_pounce_new(const char *ui_type, GaimAccount *pouncer, + const char *pouncee, GaimPounceEvent event); /** * Destroys a buddy pounce. @@ -263,6 +255,12 @@ GaimPounce *gaim_find_pounce(const GaimAccount *pouncer, const char *pouncee, GaimPounceEvent events); + +/** + * Initializes the pounces subsystem. + */ +void gaim_pounces_init(void); + /** * Loads the pounces. */ @@ -274,6 +272,25 @@ void gaim_pounces_sync(void); /** + * Registers a pounce handler for a UI. + * + * @param ui The UI name. + * @param cb The callback function. + * @param new_pounce The function called when a pounce is created. + * @param free_pounce The function called when a pounce is freed. + */ +void gaim_pounces_register_handler(const char *ui, GaimPounceCb cb, + void (*new_pounce)(GaimPounce *pounce), + void (*free_pounce)(GaimPounce *pounce)); + +/** + * Unregisters a pounce handle for a UI. + * + * @param ui The UI name. + */ +void gaim_pounces_unregister_handler(const char *ui); + +/** * Returns a list of all registered buddy pounces. * * @return The list of buddy pounces.