Wed, 03 Jul 2019 20:09:04 -0400
Convert UI ops to PurpleBuddyListClass methods.
| finch/gntblist.c | file | annotate | diff | comparison | revisions | |
| finch/gntblist.h | file | annotate | diff | comparison | revisions | |
| finch/gntui.c | file | annotate | diff | comparison | revisions | |
| libpurple/buddylist.c | file | annotate | diff | comparison | revisions | |
| libpurple/buddylist.h | file | annotate | diff | comparison | revisions | |
| pidgin/gtkblist.c | file | annotate | diff | comparison | revisions | |
| pidgin/gtkblist.h | file | annotate | diff | comparison | revisions | |
| pidgin/libpidgin.c | file | annotate | diff | comparison | revisions |
--- a/finch/gntblist.c Wed Jul 03 04:02:46 2019 -0400 +++ b/finch/gntblist.c Wed Jul 03 20:09:04 2019 -0400 @@ -65,8 +65,9 @@ #define SHOW_EMPTY_GROUP_TIMEOUT 60 -typedef struct -{ +struct _FinchBuddyList { + PurpleBuddyList parent; + GntWidget *window; GntWidget *tree; @@ -96,7 +97,7 @@ guint new_group_timeout; FinchBlistManager *manager; -} FinchBlist; +}; typedef struct { @@ -122,23 +123,24 @@ } u; } StatusBoxItem; -static FinchBlist *ggblist; - -static void add_buddy(PurpleBuddy *buddy, FinchBlist *ggblist); -static void add_contact(PurpleContact *contact, FinchBlist *ggblist); -static void add_group(PurpleGroup *group, FinchBlist *ggblist); -static void add_chat(PurpleChat *chat, FinchBlist *ggblist); -static void add_node(PurpleBlistNode *node, FinchBlist *ggblist); +static FinchBuddyList *ggblist; + +static void add_buddy(PurpleBuddy *buddy, FinchBuddyList *ggblist); +static void add_contact(PurpleContact *contact, FinchBuddyList *ggblist); +static void add_group(PurpleGroup *group, FinchBuddyList *ggblist); +static void add_chat(PurpleChat *chat, FinchBuddyList *ggblist); +static void add_node(PurpleBlistNode *node, FinchBuddyList *ggblist); static void node_update(PurpleBuddyList *list, PurpleBlistNode *node); -static void draw_tooltip(FinchBlist *ggblist); +static void draw_tooltip(FinchBuddyList *ggblist); static void tooltip_for_buddy(PurpleBuddy *buddy, GString *str, gboolean full); static gboolean remove_typing_cb(gpointer null); -static void remove_peripherals(FinchBlist *ggblist); +static void remove_peripherals(FinchBuddyList *ggblist); static const char * get_display_name(PurpleBlistNode *node); static void savedstatus_changed(PurpleSavedStatus *now, PurpleSavedStatus *old); static void blist_show(PurpleBuddyList *list); -static void update_node_display(PurpleBlistNode *buddy, FinchBlist *ggblist); -static void update_buddy_display(PurpleBuddy *buddy, FinchBlist *ggblist); +static void update_node_display(PurpleBlistNode *buddy, + FinchBuddyList *ggblist); +static void update_buddy_display(PurpleBuddy *buddy, FinchBuddyList *ggblist); static gboolean account_autojoin_cb(PurpleConnection *pc, gpointer null); static void finch_request_add_buddy(PurpleBuddyList *list, PurpleAccount *account, @@ -405,7 +407,7 @@ } static void -add_node(PurpleBlistNode *node, FinchBlist *ggblist) +add_node(PurpleBlistNode *node, FinchBuddyList *ggblist) { if (purple_blist_node_get_ui_data(node)) return; @@ -431,7 +433,7 @@ } static void -remove_tooltip(FinchBlist *ggblist) +remove_tooltip(FinchBuddyList *ggblist) { gnt_widget_destroy(ggblist->tooltip); ggblist->tooltip = NULL; @@ -441,7 +443,7 @@ static void node_remove(PurpleBuddyList *list, PurpleBlistNode *node) { - FinchBlist *ggblist = purple_blist_get_ui_data(); + FinchBuddyList *ggblist = purple_blist_get_ui_data(); PurpleBlistNode *parent; if (ggblist == NULL || purple_blist_node_get_ui_data(node) == NULL) @@ -525,7 +527,7 @@ if (ggblist) return; - ggblist = g_new0(FinchBlist, 1); + ggblist = FINCH_BUDDY_LIST(list); purple_blist_set_ui_data(ggblist); ggblist->manager = finch_blist_manager_find(purple_prefs_get_string(PREF_ROOT "/grouping")); if (!ggblist->manager) @@ -538,7 +540,6 @@ return; gnt_widget_destroy(ggblist->window); - g_free(ggblist); ggblist = NULL; } @@ -793,24 +794,6 @@ NULL, NULL); } -static PurpleBlistUiOps blist_ui_ops = -{ - new_list, - new_node, - blist_show, - node_update, - node_remove, - destroy_list, - NULL, - finch_request_add_buddy, - finch_request_add_chat, - finch_request_add_group, - NULL, - NULL, - NULL, - NULL, NULL, NULL, NULL -}; - static gpointer finch_blist_get_handle(void) { @@ -820,7 +803,7 @@ } static void -add_group(PurpleGroup *group, FinchBlist *ggblist) +add_group(PurpleGroup *group, FinchBuddyList *ggblist) { gpointer parent; PurpleBlistNode *node = (PurpleBlistNode *)group; @@ -893,7 +876,7 @@ } static void -add_chat(PurpleChat *chat, FinchBlist *ggblist) +add_chat(PurpleChat *chat, FinchBuddyList *ggblist) { gpointer parent; PurpleBlistNode *node = (PurpleBlistNode *)chat; @@ -910,7 +893,7 @@ } static void -add_contact(PurpleContact *contact, FinchBlist *ggblist) +add_contact(PurpleContact *contact, FinchBuddyList *ggblist) { gpointer parent; PurpleBlistNode *node = (PurpleBlistNode*)contact; @@ -933,7 +916,7 @@ } static void -add_buddy(PurpleBuddy *buddy, FinchBlist *ggblist) +add_buddy(PurpleBuddy *buddy, FinchBuddyList *ggblist) { gpointer parent; PurpleBlistNode *node = (PurpleBlistNode *)buddy; @@ -954,13 +937,8 @@ blist_update_row_flags((PurpleBlistNode*)contact); } -PurpleBlistUiOps *finch_blist_get_ui_ops() -{ - return &blist_ui_ops; -} - static void -selection_activate(GntWidget *widget, FinchBlist *ggblist) +selection_activate(GntWidget *widget, FinchBuddyList *ggblist) { GntTree *tree = GNT_TREE(ggblist->tree); PurpleBlistNode *node = gnt_tree_get_selection_data(tree); @@ -1560,13 +1538,13 @@ } static void -context_menu_destroyed(GntWidget *widget, FinchBlist *ggblist) +context_menu_destroyed(GntWidget *widget, FinchBuddyList *ggblist) { ggblist->context = NULL; } static void -draw_context_menu(FinchBlist *ggblist) +draw_context_menu(FinchBuddyList *ggblist) { PurpleBlistNode *node = NULL; GntWidget *context = NULL; @@ -1721,7 +1699,7 @@ } static gboolean -draw_tooltip_real(FinchBlist *ggblist) +draw_tooltip_real(FinchBuddyList *ggblist) { PurpleBlistNode *node; int x, y, top, width, w, h; @@ -1791,7 +1769,7 @@ } static void -draw_tooltip(FinchBlist *ggblist) +draw_tooltip(FinchBuddyList *ggblist) { /* When an account has signed off, it removes one buddy at a time. * Drawing the tooltip after removing each buddy is expensive. On @@ -1804,21 +1782,22 @@ } static void -selection_changed(GntWidget *widget, gpointer old, gpointer current, FinchBlist *ggblist) +selection_changed(GntWidget *widget, gpointer old, gpointer current, + FinchBuddyList *ggblist) { remove_peripherals(ggblist); draw_tooltip(ggblist); } static gboolean -context_menu(GntWidget *widget, FinchBlist *ggblist) +context_menu(GntWidget *widget, FinchBuddyList *ggblist) { draw_context_menu(ggblist); return TRUE; } static gboolean -key_pressed(GntWidget *widget, const char *text, FinchBlist *ggblist) +key_pressed(GntWidget *widget, const char *text, FinchBuddyList *ggblist) { if (text[0] == 27 && text[1] == 0) { /* Escape was pressed */ @@ -1845,14 +1824,14 @@ } static void -update_node_display(PurpleBlistNode *node, FinchBlist *ggblist) +update_node_display(PurpleBlistNode *node, FinchBuddyList *ggblist) { GntTextFormatFlags flag = get_blist_node_flag(node); gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), node, flag); } static void -update_buddy_display(PurpleBuddy *buddy, FinchBlist *ggblist) +update_buddy_display(PurpleBuddy *buddy, FinchBuddyList *ggblist) { PurpleContact *contact; @@ -1870,19 +1849,21 @@ } static void -buddy_status_changed(PurpleBuddy *buddy, PurpleStatus *old, PurpleStatus *now, FinchBlist *ggblist) +buddy_status_changed(PurpleBuddy *buddy, PurpleStatus *old, PurpleStatus *now, + FinchBuddyList *ggblist) { update_buddy_display(buddy, ggblist); } static void -buddy_idle_changed(PurpleBuddy *buddy, int old, int new, FinchBlist *ggblist) +buddy_idle_changed(PurpleBuddy *buddy, int old, int new, + FinchBuddyList *ggblist) { update_buddy_display(buddy, ggblist); } static void -remove_peripherals(FinchBlist *ggblist) +remove_peripherals(FinchBuddyList *ggblist) { if (ggblist->tooltip) remove_tooltip(ggblist); @@ -1930,7 +1911,6 @@ if (ggblist->new_group) g_list_free(ggblist->new_group); - g_free(ggblist); ggblist = NULL; } @@ -3165,6 +3145,33 @@ } /************************************************************************** + * GObject code + **************************************************************************/ +G_DEFINE_TYPE(FinchBuddyList, finch_buddy_list, PURPLE_TYPE_BUDDY_LIST) + +static void +finch_buddy_list_init(FinchBuddyList *self) +{ +} + +static void +finch_buddy_list_class_init(FinchBuddyListClass *klass) +{ + PurpleBuddyListClass *purple_blist_class; + + purple_blist_class = PURPLE_BUDDY_LIST_CLASS(klass); + purple_blist_class->new_list = new_list; + purple_blist_class->new_node = new_node; + purple_blist_class->show = blist_show; + purple_blist_class->update = node_update; + purple_blist_class->remove = node_remove; + purple_blist_class->destroy = destroy_list; + purple_blist_class->request_add_buddy = finch_request_add_buddy; + purple_blist_class->request_add_chat = finch_request_add_chat; + purple_blist_class->request_add_group = finch_request_add_group; +} + +/************************************************************************** * GBoxed code **************************************************************************/ static FinchBlistManager *
--- a/finch/gntblist.h Wed Jul 03 04:02:46 2019 -0400 +++ b/finch/gntblist.h Wed Jul 03 20:09:04 2019 -0400 @@ -32,6 +32,7 @@ #include "gnt.h" #include "gnttree.h" +#define FINCH_TYPE_BUDDY_LIST (finch_buddy_list_get_type()) #define FINCH_TYPE_BLIST_MANAGER (finch_blist_manager_get_type()) /********************************************************************** @@ -74,14 +75,8 @@ */ GType finch_blist_manager_get_type(void); -/** - * finch_blist_get_ui_ops: - * - * Get the ui-functions. - * - * Returns: The PurpleBlistUiOps structure populated with the appropriate functions. - */ -PurpleBlistUiOps * finch_blist_get_ui_ops(void); +G_DECLARE_FINAL_TYPE(FinchBuddyList, finch_buddy_list, FINCH, BUDDY_LIST, + PurpleBuddyList) /** * finch_blist_init:
--- a/finch/gntui.c Wed Jul 03 04:02:46 2019 -0400 +++ b/finch/gntui.c Wed Jul 03 20:09:04 2019 -0400 @@ -65,7 +65,7 @@ /* Initialize the buddy list */ finch_blist_init(); - purple_blist_set_ui_ops(finch_blist_get_ui_ops()); + purple_blist_set_ui(FINCH_TYPE_BUDDY_LIST); /* Initialize sound */ purple_sound_set_ui_ops(finch_sound_get_ui_ops()); @@ -122,7 +122,7 @@ purple_connections_set_ui_ops(NULL); finch_connections_uninit(); - purple_blist_set_ui_ops(NULL); + purple_blist_set_ui(G_TYPE_INVALID); finch_blist_uninit(); purple_conversations_set_ui_ops(NULL);
--- a/libpurple/buddylist.c Wed Jul 03 04:02:46 2019 -0400 +++ b/libpurple/buddylist.c Wed Jul 03 20:09:04 2019 -0400 @@ -40,8 +40,7 @@ GHashTable *buddies; /* Every buddy in this list */ } PurpleBuddyListPrivate; -static PurpleBlistUiOps *blist_ui_ops = NULL; - +static GType buddy_list_type = G_TYPE_INVALID; static PurpleBuddyList *purplebuddylist = NULL; G_DEFINE_TYPE_WITH_PRIVATE(PurpleBuddyList, purple_buddy_list, G_TYPE_OBJECT); @@ -456,11 +455,15 @@ void purple_blist_schedule_save() { - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); + PurpleBuddyListClass *klass = NULL; + + g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); + + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); /* Save everything */ - if (ops && ops->save_account) { - ops->save_account(purplebuddylist, NULL); + if (klass && klass->save_account) { + klass->save_account(purplebuddylist, NULL); } } @@ -709,13 +712,19 @@ *****************************************************************************/ void +purple_blist_set_ui(GType type) +{ + g_return_if_fail(g_type_is_a(type, PURPLE_TYPE_BUDDY_LIST) || + type == G_TYPE_INVALID); + buddy_list_type = type; +} + +void purple_blist_boot(void) { - PurpleBlistUiOps *ui_ops; GList *account; - PurpleBuddyList *gbl = g_object_new(PURPLE_TYPE_BUDDY_LIST, NULL); - - ui_ops = purple_blist_get_ui_ops(); + PurpleBuddyList *gbl = g_object_new(buddy_list_type, NULL); + PurpleBuddyListClass *klass = PURPLE_BUDDY_LIST_GET_CLASS(gbl); buddies_cache = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_hash_table_destroy); @@ -729,10 +738,11 @@ purple_blist_buddies_cache_add_account(account->data); } - if (ui_ops != NULL && ui_ops->new_list != NULL) - ui_ops->new_list(gbl); + purplebuddylist = gbl; - purplebuddylist = gbl; + if (klass && klass->new_list) { + klass->new_list(gbl); + } load_blist(); } @@ -812,18 +822,26 @@ void purple_blist_show() { - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); + PurpleBuddyListClass *klass = NULL; - if (ops && ops->show) - ops->show(purplebuddylist); + g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); + + if (klass && klass->show) { + klass->show(purplebuddylist); + } } void purple_blist_set_visible(gboolean show) { - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); + PurpleBuddyListClass *klass = NULL; - if (ops && ops->set_visible) - ops->set_visible(purplebuddylist, show); + g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); + + if (klass && klass->set_visible) { + klass->set_visible(purplebuddylist, show); + } } void purple_blist_update_buddies_cache(PurpleBuddy *buddy, const char *new_name) @@ -875,10 +893,12 @@ void purple_blist_add_chat(PurpleChat *chat, PurpleGroup *group, PurpleBlistNode *node) { PurpleBlistNode *cnode = PURPLE_BLIST_NODE(chat); - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); + PurpleBuddyListClass *klass = NULL; PurpleCountingNode *group_counter; g_return_if_fail(PURPLE_IS_CHAT(chat)); + g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); if (node == NULL) { if (group == NULL) @@ -916,12 +936,13 @@ if (cnode->parent->child == cnode) cnode->parent->child = cnode->next; - if (ops && ops->remove) - ops->remove(purplebuddylist, cnode); + if (klass && klass->remove) { + klass->remove(purplebuddylist, cnode); + } /* ops->remove() cleaned up the cnode's ui_data, so we need to * reinitialize it */ - if (ops && ops->new_node) { - ops->new_node(purplebuddylist, cnode); + if (klass && klass->new_node) { + klass->new_node(purplebuddylist, cnode); } } @@ -953,12 +974,14 @@ } } - if (ops) { - if (ops->save_node) { - ops->save_node(purplebuddylist, cnode); + if (klass) { + if (klass->save_node) { + klass->save_node(purplebuddylist, cnode); } - if (ops->update) - ops->update(purplebuddylist, PURPLE_BLIST_NODE(cnode)); + if (klass->update) { + klass->update(purplebuddylist, + PURPLE_BLIST_NODE(cnode)); + } } purple_signal_emit(purple_blist_get_handle(), "blist-node-added", @@ -967,19 +990,21 @@ void purple_blist_add_buddy(PurpleBuddy *buddy, PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node) { + PurpleBuddyListClass *klass = NULL; + PurpleBuddyListPrivate *priv = NULL; PurpleBlistNode *cnode, *bnode; PurpleCountingNode *contact_counter, *group_counter; PurpleGroup *g; PurpleContact *c; PurpleAccount *account; - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); struct _purple_hbuddy *hb, *hb2; GHashTable *account_buddies; - PurpleBuddyListPrivate *priv = - purple_buddy_list_get_instance_private(purplebuddylist); + g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); g_return_if_fail(PURPLE_IS_BUDDY(buddy)); + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); + priv = purple_buddy_list_get_instance_private(purplebuddylist); bnode = PURPLE_BLIST_NODE(buddy); account = purple_buddy_get_account(buddy); @@ -1040,8 +1065,9 @@ if (bnode->parent->child == bnode) bnode->parent->child = bnode->next; - if (ops && ops->remove) - ops->remove(purplebuddylist, bnode); + if (klass && klass->remove) { + klass->remove(purplebuddylist, bnode); + } if (bnode->parent->parent != (PurpleBlistNode*)g) { struct _purple_hbuddy hb; @@ -1060,8 +1086,9 @@ } else { purple_contact_invalidate_priority_buddy((PurpleContact*)bnode->parent); - if (ops && ops->update) - ops->update(purplebuddylist, bnode->parent); + if (klass && klass->update) { + klass->update(purplebuddylist, bnode->parent); + } } } @@ -1114,13 +1141,15 @@ purple_contact_invalidate_priority_buddy(purple_buddy_get_contact(buddy)); - if (ops) { - if (ops->save_node) { - ops->save_node(purplebuddylist, - (PurpleBlistNode *)buddy); + if (klass) { + if (klass->save_node) { + klass->save_node(purplebuddylist, + (PurpleBlistNode *)buddy); } - if (ops->update) - ops->update(purplebuddylist, PURPLE_BLIST_NODE(buddy)); + if (klass->update) { + klass->update(purplebuddylist, + PURPLE_BLIST_NODE(buddy)); + } } /* Signal that the buddy has been added */ @@ -1130,18 +1159,21 @@ void purple_blist_add_contact(PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node) { - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); + PurpleBuddyListClass *klass = NULL; + PurpleBuddyListPrivate *priv = NULL; PurpleGroup *g; PurpleBlistNode *gnode, *cnode, *bnode; PurpleCountingNode *contact_counter, *group_counter; - PurpleBuddyListPrivate *priv = - purple_buddy_list_get_instance_private(purplebuddylist); g_return_if_fail(PURPLE_IS_CONTACT(contact)); + g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); if (PURPLE_BLIST_NODE(contact) == node) return; + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); + priv = purple_buddy_list_get_instance_private(purplebuddylist); + if (node && (PURPLE_IS_CONTACT(node) || PURPLE_IS_CHAT(node))) g = PURPLE_GROUP(node->parent); @@ -1227,11 +1259,12 @@ purple_counting_node_change_current_size(group_counter, -1); purple_counting_node_change_total_size(group_counter, -1); - if (ops && ops->remove) - ops->remove(purplebuddylist, cnode); + if (klass && klass->remove) { + klass->remove(purplebuddylist, cnode); + } - if (ops && ops->remove_node) { - ops->remove_node(purplebuddylist, cnode); + if (klass && klass->remove_node) { + klass->remove_node(purplebuddylist, cnode); } } @@ -1261,36 +1294,37 @@ purple_counting_node_change_current_size(group_counter, +1); purple_counting_node_change_total_size(group_counter, +1); - if (ops && ops->save_node) - { + if (klass && klass->save_node) { if (cnode->child) { - ops->save_node(purplebuddylist, cnode); + klass->save_node(purplebuddylist, cnode); } for (bnode = cnode->child; bnode; bnode = bnode->next) { - ops->save_node(purplebuddylist, bnode); + klass->save_node(purplebuddylist, bnode); } } - if (ops && ops->update) - { - if (cnode->child) - ops->update(purplebuddylist, cnode); + if (klass && klass->update) { + if (cnode->child) { + klass->update(purplebuddylist, cnode); + } - for (bnode = cnode->child; bnode; bnode = bnode->next) - ops->update(purplebuddylist, bnode); + for (bnode = cnode->child; bnode; bnode = bnode->next) { + klass->update(purplebuddylist, bnode); + } } } void purple_blist_add_group(PurpleGroup *group, PurpleBlistNode *node) { + PurpleBuddyListClass *klass = NULL; PurpleBuddyListPrivate *priv = NULL; - PurpleBlistUiOps *ops; PurpleBlistNode *gnode = (PurpleBlistNode*)group; gchar* key; + g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); g_return_if_fail(PURPLE_IS_GROUP(group)); - ops = purple_blist_get_ui_ops(); + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); priv = purple_buddy_list_get_instance_private(purplebuddylist); /* if we're moving to overtop of ourselves, do nothing */ @@ -1305,8 +1339,10 @@ if (purple_blist_find_group(purple_group_get_name(group))) { /* This is just being moved */ - if (ops && ops->remove) - ops->remove(purplebuddylist, (PurpleBlistNode *)group); + if (klass && klass->remove) { + klass->remove(purplebuddylist, + (PurpleBlistNode *)group); + } if (gnode == priv->root) { priv->root = gnode->next; @@ -1335,17 +1371,18 @@ priv->root = gnode; } - if (ops && ops->save_node) { - ops->save_node(purplebuddylist, gnode); + if (klass && klass->save_node) { + klass->save_node(purplebuddylist, gnode); for (node = gnode->child; node; node = node->next) { - ops->save_node(purplebuddylist, node); + klass->save_node(purplebuddylist, node); } } - if (ops && ops->update) { - ops->update(purplebuddylist, gnode); - for (node = gnode->child; node; node = node->next) - ops->update(purplebuddylist, node); + if (klass && klass->update) { + klass->update(purplebuddylist, gnode); + for (node = gnode->child; node; node = node->next) { + klass->update(purplebuddylist, node); + } } purple_signal_emit(purple_blist_get_handle(), "blist-node-added", @@ -1354,12 +1391,14 @@ void purple_blist_remove_contact(PurpleContact *contact) { - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); + PurpleBuddyListClass *klass = NULL; PurpleBlistNode *node, *gnode; PurpleGroup *group; + g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); g_return_if_fail(PURPLE_IS_CONTACT(contact)); + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); node = (PurpleBlistNode *)contact; gnode = node->parent; group = PURPLE_GROUP(gnode); @@ -1390,11 +1429,12 @@ purple_counting_node_change_total_size(PURPLE_COUNTING_NODE(group), -1); /* Update the UI */ - if (ops && ops->remove) - ops->remove(purplebuddylist, node); + if (klass && klass->remove) { + klass->remove(purplebuddylist, node); + } - if (ops && ops->remove_node) { - ops->remove_node(purplebuddylist, node); + if (klass && klass->remove_node) { + klass->remove_node(purplebuddylist, node); } purple_signal_emit(purple_blist_get_handle(), "blist-node-removed", @@ -1407,9 +1447,8 @@ void purple_blist_remove_buddy(PurpleBuddy *buddy) { - PurpleBuddyListPrivate *priv = - purple_buddy_list_get_instance_private(purplebuddylist); - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); + PurpleBuddyListClass *klass = NULL; + PurpleBuddyListPrivate *priv = NULL; PurpleBlistNode *node, *cnode, *gnode; PurpleCountingNode *contact_counter, *group_counter; PurpleContact *contact; @@ -1418,8 +1457,11 @@ GHashTable *account_buddies; PurpleAccount *account; + g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); g_return_if_fail(PURPLE_IS_BUDDY(buddy)); + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); + priv = purple_buddy_list_get_instance_private(purplebuddylist); account = purple_buddy_get_account(buddy); node = PURPLE_BLIST_NODE(buddy); cnode = node->parent; @@ -1456,8 +1498,9 @@ if (cnode->child && purple_contact_get_priority_buddy(contact) == buddy) { purple_contact_invalidate_priority_buddy(contact); - if (ops && ops->update) - ops->update(purplebuddylist, cnode); + if (klass && klass->update) { + klass->update(purplebuddylist, cnode); + } } } @@ -1471,11 +1514,12 @@ g_hash_table_remove(account_buddies, &hb); /* Update the UI */ - if (ops && ops->remove) - ops->remove(purplebuddylist, node); + if (klass && klass->remove) { + klass->remove(purplebuddylist, node); + } - if (ops && ops->remove_node) { - ops->remove_node(purplebuddylist, node); + if (klass && klass->remove_node) { + klass->remove_node(purplebuddylist, node); } /* Remove this buddy's pounces */ @@ -1494,13 +1538,15 @@ void purple_blist_remove_chat(PurpleChat *chat) { - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); + PurpleBuddyListClass *klass = NULL; PurpleBlistNode *node, *gnode; PurpleGroup *group; PurpleCountingNode *group_counter; + g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); g_return_if_fail(PURPLE_IS_CHAT(chat)); + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); node = (PurpleBlistNode *)chat; gnode = node->parent; group = (PurpleGroup *)gnode; @@ -1525,11 +1571,12 @@ } /* Update the UI */ - if (ops && ops->remove) - ops->remove(purplebuddylist, node); + if (klass && klass->remove) { + klass->remove(purplebuddylist, node); + } - if (ops && ops->remove_node) { - ops->remove_node(purplebuddylist, node); + if (klass && klass->remove_node) { + klass->remove_node(purplebuddylist, node); } purple_signal_emit(purple_blist_get_handle(), "blist-node-removed", @@ -1541,18 +1588,20 @@ void purple_blist_remove_group(PurpleGroup *group) { - PurpleBuddyListPrivate *priv = - purple_buddy_list_get_instance_private(purplebuddylist); - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); + PurpleBuddyListClass *klass = NULL; + PurpleBuddyListPrivate *priv = NULL; PurpleBlistNode *node; GList *l; gchar* key; + g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); g_return_if_fail(PURPLE_IS_GROUP(group)); if (group == purple_blist_get_default_group()) purple_debug_warning("buddylist", "cannot remove default group"); + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); + priv = purple_buddy_list_get_instance_private(purplebuddylist); node = (PurpleBlistNode *)group; /* Make sure the group is empty */ @@ -1573,11 +1622,12 @@ g_free(key); /* Update the UI */ - if (ops && ops->remove) - ops->remove(purplebuddylist, node); + if (klass && klass->remove) { + klass->remove(purplebuddylist, node); + } - if (ops && ops->remove_node) { - ops->remove_node(purplebuddylist, node); + if (klass && klass->remove_node) { + klass->remove_node(purplebuddylist, node); } purple_signal_emit(purple_blist_get_handle(), "blist-node-removed", @@ -1778,14 +1828,16 @@ void purple_blist_add_account(PurpleAccount *account) { - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); + PurpleBuddyListClass *klass = NULL; PurpleBlistNode *gnode, *cnode, *bnode; PurpleCountingNode *contact_counter, *group_counter; g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); - if (!ops || !ops->update) + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); + if (!klass || !klass->update) { return; + } for (gnode = purple_blist_get_default_root(); gnode; gnode = gnode->next) { @@ -1803,29 +1855,34 @@ purple_counting_node_change_current_size(contact_counter, +1); if (purple_counting_node_get_current_size(contact_counter) == 1) purple_counting_node_change_current_size(group_counter, +1); - ops->update(purplebuddylist, bnode); - } - } - if (recompute || - purple_blist_node_get_bool(cnode, "show_offline")) { - purple_contact_invalidate_priority_buddy((PurpleContact*)cnode); - ops->update(purplebuddylist, cnode); - } + klass->update( + purplebuddylist, + bnode); + } + } + if (recompute || + purple_blist_node_get_bool( + cnode, "show_offline")) { + purple_contact_invalidate_priority_buddy( + (PurpleContact *)cnode); + klass->update(purplebuddylist, + cnode); + } } else if (PURPLE_IS_CHAT(cnode) && purple_chat_get_account(PURPLE_CHAT(cnode)) == account) { group_counter = PURPLE_COUNTING_NODE(gnode); purple_counting_node_change_online_count(group_counter, +1); purple_counting_node_change_current_size(group_counter, +1); - ops->update(purplebuddylist, cnode); + klass->update(purplebuddylist, cnode); } } - ops->update(purplebuddylist, gnode); + klass->update(purplebuddylist, gnode); } } void purple_blist_remove_account(PurpleAccount *account) { - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); + PurpleBuddyListClass *klass = NULL; PurpleBlistNode *gnode, *cnode, *bnode; PurpleCountingNode *contact_counter, *group_counter; PurpleBuddy *buddy; @@ -1835,6 +1892,7 @@ GList *list = NULL, *iter = NULL; g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); for (gnode = purple_blist_get_default_root(); gnode; gnode = gnode->next) { @@ -1881,16 +1939,20 @@ else recompute = TRUE; - if (ops && ops->remove) { - ops->remove(purplebuddylist, bnode); + if (klass && klass->remove) { + klass->remove( + purplebuddylist, + bnode); } } } if (recompute) { purple_contact_invalidate_priority_buddy(contact); - if (ops && ops->update) - ops->update(purplebuddylist, cnode); + if (klass && klass->update) { + klass->update(purplebuddylist, + cnode); + } } } else if (PURPLE_IS_CHAT(cnode)) { chat = PURPLE_CHAT(cnode); @@ -1900,8 +1962,10 @@ purple_counting_node_change_current_size(group_counter, -1); purple_counting_node_change_online_count(group_counter, -1); - if (ops && ops->remove) - ops->remove(purplebuddylist, cnode); + if (klass && klass->remove) { + klass->remove(purplebuddylist, + cnode); + } } } } @@ -1954,13 +2018,14 @@ purple_blist_request_add_buddy(PurpleAccount *account, const char *username, const char *group, const char *alias) { - PurpleBlistUiOps *ui_ops; + PurpleBuddyListClass *klass = NULL; - ui_ops = purple_blist_get_ui_ops(); + g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); - if (ui_ops != NULL && ui_ops->request_add_buddy != NULL) { - ui_ops->request_add_buddy(purplebuddylist, account, username, - group, alias); + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); + if (klass != NULL && klass->request_add_buddy != NULL) { + klass->request_add_buddy(purplebuddylist, account, username, + group, alias); } } @@ -1968,98 +2033,80 @@ purple_blist_request_add_chat(PurpleAccount *account, PurpleGroup *group, const char *alias, const char *name) { - PurpleBlistUiOps *ui_ops; + PurpleBuddyListClass *klass = NULL; - ui_ops = purple_blist_get_ui_ops(); + g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); - if (ui_ops != NULL && ui_ops->request_add_chat != NULL) { - ui_ops->request_add_chat(purplebuddylist, account, group, alias, - name); + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); + if (klass != NULL && klass->request_add_chat != NULL) { + klass->request_add_chat(purplebuddylist, account, group, alias, + name); } } void purple_blist_request_add_group(void) { - PurpleBlistUiOps *ui_ops; + PurpleBuddyListClass *klass = NULL; + + g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); - ui_ops = purple_blist_get_ui_ops(); - - if (ui_ops != NULL && ui_ops->request_add_group != NULL) { - ui_ops->request_add_group(purplebuddylist); + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); + if (klass != NULL && klass->request_add_group != NULL) { + klass->request_add_group(purplebuddylist); } } void purple_blist_new_node(PurpleBuddyList *list, PurpleBlistNode *node) { - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); - if (ops && ops->new_node) { - ops->new_node(list, node); + PurpleBuddyListClass *klass = NULL; + + g_return_if_fail(PURPLE_IS_BUDDY_LIST(list)); + + klass = PURPLE_BUDDY_LIST_GET_CLASS(list); + if (klass && klass->new_node) { + klass->new_node(list, node); } } void purple_blist_update_node(PurpleBuddyList *list, PurpleBlistNode *node) { - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); - if (ops && ops->update) { - ops->update(list, node); + PurpleBuddyListClass *klass = NULL; + + g_return_if_fail(PURPLE_IS_BUDDY_LIST(list)); + + klass = PURPLE_BUDDY_LIST_GET_CLASS(list); + if (klass && klass->update) { + klass->update(list, node); } } void purple_blist_save_node(PurpleBuddyList *list, PurpleBlistNode *node) { - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); - if (ops && ops->save_node) { - ops->save_node(list, node); + PurpleBuddyListClass *klass = NULL; + + g_return_if_fail(PURPLE_IS_BUDDY_LIST(list)); + + klass = PURPLE_BUDDY_LIST_GET_CLASS(list); + if (klass && klass->save_node) { + klass->save_node(list, node); } } void purple_blist_save_account(PurpleBuddyList *list, PurpleAccount *account) { - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); - if (ops && ops->save_account) { - ops->save_account(list, account); - } -} + PurpleBuddyListClass *klass = NULL; + + g_return_if_fail(PURPLE_IS_BUDDY_LIST(list)); -void -purple_blist_set_ui_ops(PurpleBlistUiOps *ops) -{ - gboolean overrode = FALSE; - blist_ui_ops = ops; - - if (!ops) - return; - - if (!ops->save_node) { - ops->save_node = purple_blist_real_save_node; - overrode = TRUE; + klass = PURPLE_BUDDY_LIST_GET_CLASS(list); + if (klass && klass->save_account) { + klass->save_account(list, account); } - if (!ops->remove_node) { - ops->remove_node = purple_blist_real_save_node; - overrode = TRUE; - } - if (!ops->save_account) { - ops->save_account = purple_blist_real_save_account; - overrode = TRUE; - } - - if (overrode && (ops->save_node != purple_blist_real_save_node || - ops->remove_node != purple_blist_real_save_node || - ops->save_account != purple_blist_real_save_account)) { - purple_debug_warning("buddylist", "Only some of the blist saving UI ops " - "were overridden. This probably is not what you want!\n"); - } -} - -PurpleBlistUiOps * -purple_blist_get_ui_ops(void) -{ - return blist_ui_ops; } const gchar * @@ -2081,6 +2128,9 @@ { void *handle = purple_blist_get_handle(); + /* Set a default, which can't be done as a static initializer. */ + buddy_list_type = PURPLE_TYPE_BUDDY_LIST; + purple_signal_register(handle, "buddy-status-changed", purple_marshal_VOID__POINTER_POINTER_POINTER, G_TYPE_NONE, 3, PURPLE_TYPE_BUDDY, PURPLE_TYPE_STATUS, @@ -2151,10 +2201,10 @@ static void blist_node_destroy(PurpleBlistNode *node) { - PurpleBlistUiOps *ui_ops; + PurpleBuddyListClass *klass = NULL; PurpleBlistNode *child, *next_child; - ui_ops = purple_blist_get_ui_ops(); + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); child = node->child; while (child) { next_child = child->next; @@ -2167,8 +2217,9 @@ node->child = NULL; node->next = NULL; node->prev = NULL; - if (ui_ops && ui_ops->remove) - ui_ops->remove(purplebuddylist, node); + if (klass && klass->remove) { + klass->remove(purplebuddylist, node); + } g_object_unref(node); } @@ -2176,14 +2227,15 @@ void purple_blist_uninit(void) { + PurpleBuddyListClass *klass = NULL; PurpleBuddyListPrivate *priv = NULL; - PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); PurpleBlistNode *node, *next_node; /* This happens if we quit before purple_set_blist is called. */ if (purplebuddylist == NULL) return; + klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); priv = purple_buddy_list_get_instance_private(purplebuddylist); if (save_timer != 0) { @@ -2194,8 +2246,9 @@ purple_debug(PURPLE_DEBUG_INFO, "buddylist", "Destroying\n"); - if (ops && ops->destroy) - ops->destroy(purplebuddylist); + if (klass && klass->destroy) { + klass->destroy(purplebuddylist); + } node = priv->root; while (node) { @@ -2222,36 +2275,6 @@ } /************************************************************************** - * GBoxed code - **************************************************************************/ -static PurpleBlistUiOps * -purple_blist_ui_ops_copy(PurpleBlistUiOps *ops) -{ - PurpleBlistUiOps *ops_new; - - g_return_val_if_fail(ops != NULL, NULL); - - ops_new = g_new(PurpleBlistUiOps, 1); - *ops_new = *ops; - - return ops_new; -} - -GType -purple_blist_ui_ops_get_type(void) -{ - static GType type = 0; - - if (type == 0) { - type = g_boxed_type_register_static("PurpleBlistUiOps", - (GBoxedCopyFunc)purple_blist_ui_ops_copy, - (GBoxedFreeFunc)g_free); - } - - return type; -} - -/************************************************************************** * GObject code **************************************************************************/ @@ -2285,5 +2308,8 @@ GObjectClass *obj_class = G_OBJECT_CLASS(klass); obj_class->finalize = purple_buddy_list_finalize; + + klass->save_node = purple_blist_real_save_node; + klass->remove_node = purple_blist_real_save_node; + klass->save_account = purple_blist_real_save_account; } -
--- a/libpurple/buddylist.h Wed Jul 03 04:02:46 2019 -0400 +++ b/libpurple/buddylist.h Wed Jul 03 20:09:04 2019 -0400 @@ -33,19 +33,8 @@ #include "buddy.h" -#define PURPLE_TYPE_BUDDY_LIST (purple_buddy_list_get_type()) -#define PURPLE_BUDDY_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_BUDDY_LIST, PurpleBuddyList)) -#define PURPLE_BUDDY_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_BUDDY_LIST, PurpleBuddyListClass)) -#define PURPLE_IS_BUDDY_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_BUDDY_LIST)) -#define PURPLE_IS_BUDDY_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_BUDDY_LIST)) -#define PURPLE_BUDDY_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_BUDDY_LIST, PurpleBuddyListClass)) - -typedef struct _PurpleBuddyList PurpleBuddyList; -typedef struct _PurpleBuddyListClass PurpleBuddyListClass; - -#define PURPLE_TYPE_BLIST_UI_OPS (purple_blist_ui_ops_get_type()) - -typedef struct _PurpleBlistUiOps PurpleBlistUiOps; +#define PURPLE_TYPE_BUDDY_LIST (purple_buddy_list_get_type()) +typedef struct _PurpleBuddyList PurpleBuddyList; #define PURPLE_BLIST_DEFAULT_GROUP_NAME _("Buddies") @@ -70,45 +59,31 @@ * * The Buddy List */ -struct _PurpleBuddyList { - GObject gparent; -}; - -struct _PurpleBuddyListClass { - GObjectClass gparent_class; - - /*< private >*/ - void (*_purple_reserved1)(void); - void (*_purple_reserved2)(void); - void (*_purple_reserved3)(void); - void (*_purple_reserved4)(void); -}; - /** - * PurpleBlistUiOps: + * PurpleBuddyListClass: * @new_list: Sets UI-specific data on a buddy list. * @new_node: Sets UI-specific data on a node. * @show: The core will call this when it's finished doing its core - * stuff + * stuff. * @update: This will update a node in the buddy list. * @remove: This removes a node from the list * @destroy: When the list is destroyed, this is called to destroy the UI. - * @set_visible: Hides or unhides the buddy list + * @set_visible: Hides or unhides the buddy list. * @save_node: This is called when a node has been modified and should be * saved. - * <sbr/>Implementation of this UI op is + * <sbr/>Implementation of this method is * <emphasis>OPTIONAL</emphasis>. If not implemented, it will be * set to a fallback function that saves data to * <filename>blist.xml</filename> like in previous libpurple * versions. * <sbr/>@node: The node which has been modified. * @remove_node: Called when a node is about to be removed from the buddy list. - * The UI op should update the relevant data structures to remove - * this node (for example, removing a buddy from the group this - * node is in). - * <sbr/>Implementation of this UI op is - * <emphasis>OPTIONAL</emphasis>. If not implemented, - * it will be set to a fallback function that saves data to + * The method should update the relevant data structures to + * remove this node (for example, removing a buddy from the + * group this node is in). + * <sbr/>Implementation of this method is + * <emphasis>OPTIONAL</emphasis>. If not implemented, it will be + * set to a fallback function that saves data to * <filename>blist.xml</filename> like in previous libpurple * versions. * <sbr/>@node: The node which has been modified. @@ -116,7 +91,7 @@ * this, the callback must save the privacy and buddy list data * for an account. If the account is %NULL, save the data for all * accounts. - * <sbr/>Implementation of this UI op is + * <sbr/>Implementation of this method is * <emphasis>OPTIONAL</emphasis>. If not implemented, it will be * set to a fallback function that saves data to * <filename>blist.xml</filename> like in previous @@ -124,13 +99,15 @@ * <sbr/>@account: The account whose data to save. If %NULL, * save all data for all accounts. * - * Buddy list UI operations. + * Buddy list operations. * - * Any UI representing a buddy list must assign a filled-out PurpleBlistUiOps - * structure to the buddy list core. + * Any UI representing a buddy list must derive a filled-out + * @PurpleBuddyListClass and set the GType using purple_blist_set_ui() before a + * buddy list is created. */ -struct _PurpleBlistUiOps -{ +struct _PurpleBuddyListClass { + GObjectClass gparent_class; + void (*new_list)(PurpleBuddyList *list); void (*new_node)(PurpleBuddyList *list, PurpleBlistNode *node); void (*show)(PurpleBuddyList *list); @@ -155,10 +132,7 @@ void (*save_account)(PurpleBuddyList *list, PurpleAccount *account); /*< private >*/ - void (*_purple_reserved1)(void); - void (*_purple_reserved2)(void); - void (*_purple_reserved3)(void); - void (*_purple_reserved4)(void); + gpointer reserved[4]; }; G_BEGIN_DECLS @@ -172,7 +146,8 @@ * * Returns: The #GType for the #PurpleBuddyList object. */ -GType purple_buddy_list_get_type(void); +G_DECLARE_DERIVABLE_TYPE(PurpleBuddyList, purple_buddy_list, PURPLE, BUDDY_LIST, + GObject) /** * purple_blist_get_default: @@ -517,10 +492,6 @@ */ void purple_blist_request_add_group(void); -/**************************************************************************/ -/* Buddy list UI Functions */ -/**************************************************************************/ - /** * purple_blist_new_node: * @list: The list that contains the node. @@ -576,36 +547,21 @@ void purple_blist_save_account(PurpleBuddyList *list, PurpleAccount *account); /**************************************************************************/ -/* UI Registration Functions */ +/* Buddy List Subsystem */ /**************************************************************************/ /** - * purple_blist_ui_ops_get_type: + * purple_blist_set_ui: + * @type: The @GType of a derived UI implementation of @PurpleBuddyList. + * + * Set the UI implementation of the buddy list. * - * Returns: The #GType for the #PurpleBlistUiOps boxed structure. - */ -GType purple_blist_ui_ops_get_type(void); - -/** - * purple_blist_set_ui_ops: - * @ops: The ops struct. + * This must be called before the buddy list is created or you will get the + * default libpurple implementation. * - * Sets the UI operations structure to be used for the buddy list. + * Since: 3.0.0 */ -void purple_blist_set_ui_ops(PurpleBlistUiOps *ops); - -/** - * purple_blist_get_ui_ops: - * - * Returns the UI operations structure to be used for the buddy list. - * - * Returns: The UI operations structure. - */ -PurpleBlistUiOps *purple_blist_get_ui_ops(void); - -/**************************************************************************/ -/* Buddy List Subsystem */ -/**************************************************************************/ +void purple_blist_set_ui(GType type); /** * purple_blist_get_handle:
--- a/pidgin/gtkblist.c Wed Jul 03 04:02:46 2019 -0400 +++ b/pidgin/gtkblist.c Wed Jul 03 20:09:04 2019 -0400 @@ -4793,51 +4793,6 @@ } } -/************************************************************************** - * GTK Buddy list GBoxed code - **************************************************************************/ -static PidginBuddyList * -pidgin_buddy_list_ref(PidginBuddyList *gtkblist) -{ - PidginBuddyListPrivate *priv; - - g_return_val_if_fail(gtkblist != NULL, NULL); - - priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); - priv->box_count++; - - return gtkblist; -} - -static void -pidgin_buddy_list_unref(PidginBuddyList *gtkblist) -{ - PidginBuddyListPrivate *priv; - - g_return_if_fail(gtkblist != NULL); - - priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); - - g_return_if_fail(priv->box_count >= 0); - - if (!priv->box_count--) - purple_core_quit(); -} - -GType -pidgin_buddy_list_get_type(void) -{ - static GType type = 0; - - if (type == 0) { - type = g_boxed_type_register_static("PidginBuddyList", - (GBoxedCopyFunc)pidgin_buddy_list_ref, - (GBoxedFreeFunc)pidgin_buddy_list_unref); - } - - return type; -} - /********************************************************************************** * Public API Functions * **********************************************************************************/ @@ -4846,7 +4801,7 @@ { PidginBuddyList *gtkblist; - gtkblist = g_new0(PidginBuddyList, 1); + gtkblist = PIDGIN_BUDDY_LIST(blist); gtkblist->priv = g_new0(PidginBuddyListPrivate, 1); purple_blist_set_ui_data(gtkblist); @@ -6892,7 +6847,6 @@ g_source_remove(priv->select_notebook_page_timeout); g_free(priv); - g_free(gtkblist); accountmenu = NULL; gtkblist = NULL; purple_prefs_disconnect_by_handle(pidgin_blist_get_handle()); @@ -7382,31 +7336,6 @@ pidgin_set_urgent(GTK_WINDOW(gtkblist->window), TRUE); } -static PurpleBlistUiOps blist_ui_ops = -{ - pidgin_blist_new_list, - pidgin_blist_new_node, - pidgin_blist_show, - pidgin_blist_update, - pidgin_blist_remove, - pidgin_blist_destroy, - pidgin_blist_set_visible, - pidgin_blist_request_add_buddy, - pidgin_blist_request_add_chat, - pidgin_blist_request_add_group, - NULL, - NULL, - NULL, - NULL, NULL, NULL, NULL -}; - - -PurpleBlistUiOps * -pidgin_blist_get_ui_ops(void) -{ - return &blist_ui_ops; -} - PidginBuddyList *pidgin_blist_get_default_gtk_blist() { return gtkblist; @@ -7578,6 +7507,34 @@ purple_signals_disconnect_by_handle(pidgin_blist_get_handle()); } +/************************************************************************** + * GTK Buddy list GObject code + **************************************************************************/ +G_DEFINE_TYPE(PidginBuddyList, pidgin_buddy_list, PURPLE_TYPE_BUDDY_LIST) + +static void +pidgin_buddy_list_init(PidginBuddyList *self) +{ +} + +static void +pidgin_buddy_list_class_init(PidginBuddyListClass *klass) +{ + PurpleBuddyListClass *purple_blist_class; + + purple_blist_class = PURPLE_BUDDY_LIST_CLASS(klass); + purple_blist_class->new_list = pidgin_blist_new_list; + purple_blist_class->new_node = pidgin_blist_new_node; + purple_blist_class->show = pidgin_blist_show; + purple_blist_class->update = pidgin_blist_update; + purple_blist_class->remove = pidgin_blist_remove; + purple_blist_class->destroy = pidgin_blist_destroy; + purple_blist_class->set_visible = pidgin_blist_set_visible; + purple_blist_class->request_add_buddy = pidgin_blist_request_add_buddy; + purple_blist_class->request_add_chat = pidgin_blist_request_add_chat; + purple_blist_class->request_add_group = pidgin_blist_request_add_group; +} + /********************************************************************* * Buddy List sorting functions * *********************************************************************/
--- a/pidgin/gtkblist.h Wed Jul 03 04:02:46 2019 -0400 +++ b/pidgin/gtkblist.h Wed Jul 03 20:09:04 2019 -0400 @@ -106,6 +106,8 @@ * Like, everything you need to know about the gtk buddy list */ struct _PidginBuddyList { + PurpleBuddyList parent; + GtkWidget *window; GtkWidget *notebook; GtkWidget *main_vbox; @@ -149,8 +151,6 @@ }; #define PIDGIN_BLIST(list) ((PidginBuddyList *)purple_blist_get_ui_data()) -#define PIDGIN_IS_PIDGIN_BLIST(list) \ - (purple_blist_get_ui_ops() == pidgin_blist_get_ui_ops()) G_BEGIN_DECLS @@ -163,7 +163,8 @@ * * Returns: The #GType for the #PidginBuddyList boxed structure. */ -GType pidgin_buddy_list_get_type(void); +G_DECLARE_FINAL_TYPE(PidginBuddyList, pidgin_buddy_list, PIDGIN, BUDDY_LIST, + PurpleBuddyList) /** * pidgin_blist_get_handle: @@ -189,15 +190,6 @@ void pidgin_blist_uninit(void); /** - * pidgin_blist_get_ui_ops: - * - * Returns the UI operations structure for the buddy list. - * - * Returns: The GTK+ list operations structure. - */ -PurpleBlistUiOps *pidgin_blist_get_ui_ops(void); - -/** * pidgin_blist_get_default_gtk_blist: * * Returns the default gtk buddy list
--- a/pidgin/libpidgin.c Wed Jul 03 04:02:46 2019 -0400 +++ b/pidgin/libpidgin.c Wed Jul 03 20:09:04 2019 -0400 @@ -225,7 +225,7 @@ /* Set the UI operation structures. */ purple_accounts_set_ui_ops(pidgin_accounts_get_ui_ops()); purple_xfers_set_ui_ops(pidgin_xfers_get_ui_ops()); - purple_blist_set_ui_ops(pidgin_blist_get_ui_ops()); + purple_blist_set_ui(PIDGIN_TYPE_BUDDY_LIST); purple_notify_set_ui_ops(pidgin_notify_get_ui_ops()); purple_request_set_ui_ops(pidgin_request_get_ui_ops()); purple_sound_set_ui_ops(pidgin_sound_get_ui_ops());