# HG changeset patch # User Christian Hammond # Date 1047320189 0 # Node ID 4bdd9a5fd026938e268358a370e82c1282934d80 # Parent 8f523dbb970e78d0e7bb7e9a24f8ddabb93c0d7a [gaim-migrate @ 5006] This may very well have issues, but it's a slightly better core/ui split, removing global variables and fixing some GTK+ runtime errors and a couple segfaults. It's some progress. committer: Tailor Script diff -r 8f523dbb970e -r 4bdd9a5fd026 src/buddy.c --- a/src/buddy.c Mon Mar 10 16:39:46 2003 +0000 +++ b/src/buddy.c Mon Mar 10 18:16:29 2003 +0000 @@ -54,6 +54,8 @@ #include "win32dep.h" #endif +static struct gaim_gtk_buddy_list *gtkblist = NULL; + static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node); /*************************************************** @@ -482,6 +484,16 @@ /********************************************************************************** * Public API Functions * **********************************************************************************/ +static void gaim_gtk_blist_new_list(struct gaim_buddy_list *blist) +{ + blist->ui_data = g_new0(struct gaim_gtk_buddy_list, 1); +} + +static void gaim_gtk_blist_new_node(GaimBlistNode *node) +{ + node->ui_data = g_new0(struct gaim_gtk_blist_node, 1); +} + static void gaim_gtk_blist_show(struct gaim_buddy_list *list) { GtkItemFactory *ift; @@ -496,7 +508,8 @@ return; } - gtkblist = g_new0(struct gaim_gtk_buddy_list , 1); + gtkblist = GAIM_GTK_BLIST(list); + gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List")); @@ -608,17 +621,23 @@ static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node) { - GtkTreeIter *iter = node->ui_data; + struct gaim_gtk_blist_node *gtknode; + GtkTreeIter *iter; gboolean expand = FALSE; if (!gtkblist) return; + + gtknode = GAIM_GTK_BLIST_NODE(node); + iter = gtknode->iter; + if (!iter) { /* This is a newly added node */ if (GAIM_BLIST_NODE_IS_BUDDY(node)) { if (((struct buddy*)node)->present) { - if(node->parent && node->parent && !node->parent->ui_data) { - + if(node->parent && node->parent && + !GAIM_GTK_BLIST_NODE(node->parent)->iter) { + /* This buddy's group has not yet been added. We do that here */ char *mark = g_strdup_printf("%s", ((struct group*)node->parent)->name); @@ -627,36 +646,41 @@ GtkTreeIter *insertatiter = NULL; /* We traverse backwards through the buddy list to find the node in the tree to insert it after */ - while (insertat && !insertat->ui_data) + while (insertat && !GAIM_GTK_BLIST_NODE(insertat)->iter) insertat = insertat->prev; + if (insertat) - insertatiter = insertat->ui_data; + insertatiter = GAIM_GTK_BLIST_NODE(insertat)->iter; /* This is where we create the node and add it. */ gtk_tree_store_insert_after(gtkblist->treemodel, iter2, - node->parent->parent ? node->parent->parent->ui_data : NULL, insertatiter); + node->parent->parent ? + GAIM_GTK_BLIST_NODE(node->parent->parent)->iter : NULL, insertatiter); gtk_tree_store_set(gtkblist->treemodel, iter2, STATUS_ICON_COLUMN, gtk_widget_render_icon (gtkblist->treeview,GTK_STOCK_OPEN,GTK_ICON_SIZE_SMALL_TOOLBAR,NULL), NAME_COLUMN, mark, NODE_COLUMN, node->parent, -1); - node->parent->ui_data = iter2; + + GAIM_GTK_BLIST_NODE(node->parent)->iter = iter2; expand = TRUE; } iter = g_new0(GtkTreeIter, 1); - node->ui_data = iter; - - gtk_tree_store_insert_after (gtkblist->treemodel, iter, node->parent ? node->parent->ui_data : NULL, - node->prev ? node->prev->ui_data : NULL); + + GAIM_GTK_BLIST_NODE(node)->iter = iter; + + gtk_tree_store_insert_after (gtkblist->treemodel, iter, node->parent ? GAIM_GTK_BLIST_NODE(node->parent)->iter : NULL, + node->prev ? GAIM_GTK_BLIST_NODE(node->prev)->iter : NULL); if (expand) { /* expand was set to true if this is the first element added to a group. In such case * we expand the group node */ - GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), node->parent->ui_data); + GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), GAIM_GTK_BLIST_NODE(node->parent)->iter); gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), path, TRUE); } - node->ui_data = iter; + + GAIM_GTK_BLIST_NODE(node)->iter = iter; } } } @@ -679,23 +703,36 @@ -1); g_free(mark); - g_object_unref(status); - if (avatar) { - g_object_unref(avatar); - } - } else if (GAIM_BLIST_NODE_IS_BUDDY(node) && node->ui_data){ - gtk_tree_store_remove(GTK_TREE_STORE(gtkblist->treemodel), (GtkTreeIter*)(node->ui_data)); - g_free(node->ui_data); - node->ui_data = NULL; + + if (status != NULL) + g_object_unref(status); + + if (avatar != NULL) + g_object_unref(avatar); + + } else if (GAIM_BLIST_NODE_IS_BUDDY(node) && GAIM_GTK_BLIST_NODE(node)->iter){ + gtk_tree_store_remove(GTK_TREE_STORE(gtkblist->treemodel), GAIM_GTK_BLIST_NODE(node)->iter); + + g_free(GAIM_GTK_BLIST_NODE(node)->iter); + GAIM_GTK_BLIST_NODE(node)->iter = NULL; } } static void gaim_gtk_blist_remove(struct gaim_buddy_list *list, GaimBlistNode *node) { + struct gaim_gtk_blist_node *gtknode; + if (!node->ui_data) return; - gtk_tree_store_remove(gtkblist->treemodel, (GtkTreeIter*)(node->ui_data)); + + gtknode = (struct gaim_gtk_blist_node *)node->ui_data; + + if (gtknode->timer > 0) + g_source_remove(gtknode->timer); + + if (gtknode->iter != NULL) + gtk_tree_store_remove(gtkblist->treemodel, gtknode->iter); } static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list) @@ -713,6 +750,8 @@ static struct gaim_blist_ui_ops blist_ui_ops = { + gaim_gtk_blist_new_list, + gaim_gtk_blist_new_node, gaim_gtk_blist_show, gaim_gtk_blist_update, gaim_gtk_blist_remove, diff -r 8f523dbb970e -r 4bdd9a5fd026 src/dialogs.c --- a/src/dialogs.c Mon Mar 10 16:39:46 2003 +0000 +++ b/src/dialogs.c Mon Mar 10 18:16:29 2003 +0000 @@ -585,10 +585,12 @@ GtkWidget *window; GtkWidget *hbox; GtkWidget *label; - + struct gaim_gtk_buddy_list *gtkblist; char *filename = g_build_filename(DATADIR, "pixmaps", "gaim", "dialogs", "gaim_cool.png", NULL); GtkWidget *img = gtk_image_new_from_file(filename); - + + gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); + label = gtk_label_new(NULL); if (ee == 0) gtk_label_set_markup(GTK_LABEL(label), @@ -658,11 +660,14 @@ GtkWidget *table, *menu, *opt; GSList *g = connections; struct gaim_connection *c; + struct gaim_gtk_buddy_list *gtkblist; char buf[256]; char *filename = g_build_filename(DATADIR, "pixmaps", "gaim", "dialogs", "gaim_question.png", NULL); GtkWidget *img = gtk_image_new_from_file(filename); struct getuserinfo *info = NULL; + gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); + g_free(filename); if (!imdialog) { @@ -764,8 +769,11 @@ GSList *g = connections; struct gaim_connection *c; struct getuserinfo *info = g_new0(struct getuserinfo, 1); + struct gaim_gtk_buddy_list *gtkblist; char buf[256]; + gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); + g_free(filename); info->gc = connections->data; @@ -941,10 +949,13 @@ GtkWidget *hbox, *vbox; GtkWidget *label; + struct gaim_gtk_buddy_list *gtkblist; char *filename = g_build_filename(DATADIR, "pixmaps", "gaim", "dialogs", "gaim_question.png", NULL); GtkWidget *img = gtk_image_new_from_file(filename); struct addbuddy *a = g_new0(struct addbuddy, 1); + gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); + g_free(filename); a->gc = gc; @@ -1051,13 +1062,14 @@ GtkWidget *label; GtkWidget *hbox; GtkWidget *vbox; - + struct gaim_gtk_buddy_list *gtkblist; char *filename = g_build_filename(DATADIR, "pixmaps", "gaim", "dialogs", "gaim_question.png", NULL); GtkWidget *img = gtk_image_new_from_file(filename); - struct addbuddy *a = g_new0(struct addbuddy, 1); a->gc = gc ? gc : connections->data; + gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); + g_free(filename); GAIM_DIALOG(a->window); @@ -3911,12 +3923,15 @@ GtkWidget *hbox, *vbox; GtkWidget *label; + struct gaim_gtk_buddy_list *gtkblist; char *filename = g_build_filename(DATADIR, "pixmaps", "gaim", "dialogs", "gaim_question.png", NULL); GtkWidget *img = gtk_image_new_from_file(filename); GtkWidget *name_entry = NULL; g_free(filename); + gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); + if (!rename_dialog) { rename_dialog = gtk_dialog_new_with_buttons(_("Rename Group"), GTK_WINDOW(gtkblist->window), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); diff -r 8f523dbb970e -r 4bdd9a5fd026 src/gtklist.h --- a/src/gtklist.h Mon Mar 10 16:39:46 2003 +0000 +++ b/src/gtklist.h Mon Mar 10 18:16:29 2003 +0000 @@ -23,7 +23,6 @@ #ifndef _GAIM_GTK_LIST_H_ #define _GAIM_GTK_LIST_H_ -extern GtkWidget *blist; enum { STATUS_ICON_COLUMN, @@ -51,8 +50,18 @@ GtkWidget *bbox; /**< A Button Box. */ }; -struct gaim_gtk_buddy_list *gtkblist; +/** + * A GTK+ buddy list node. + */ +struct gaim_gtk_blist_node +{ + GtkTreeIter *iter; /**< The tree iterator. */ + uint timer; /**< The timer handle. */ +}; + +#define GAIM_GTK_BLIST_NODE(node) ((struct gaim_gtk_blist_node *)(node)->ui_data) +#define GAIM_GTK_BLIST(list) ((struct gaim_gtk_buddy_list *)(list)->ui_data) /************************************************************************** * @name GTK+ Conversation API diff -r 8f523dbb970e -r 4bdd9a5fd026 src/list.c --- a/src/list.c Mon Mar 10 16:39:46 2003 +0000 +++ b/src/list.c Mon Mar 10 18:16:29 2003 +0000 @@ -89,10 +89,27 @@ struct gaim_buddy_list *gaim_blist_new() { struct gaim_buddy_list *gbl = g_new0(struct gaim_buddy_list, 1); - gbl->ui_ops = blist_ui_ops; + + gbl->ui_ops = gaim_get_blist_ui_ops(); + + if (gbl->ui_ops != NULL && gbl->ui_ops->new_list != NULL) + gbl->ui_ops->new_list(gbl); + return gbl; } +void +gaim_set_blist(struct gaim_buddy_list *list) +{ + gaimbuddylist = list; +} + +struct gaim_buddy_list * +gaim_get_blist(void) +{ + return gaimbuddylist; +} + void gaim_blist_show () { struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops; @@ -173,13 +190,21 @@ } struct buddy *gaim_buddy_new(struct gaim_account *account, const char *screenname, const char *alias) { - struct buddy *b = g_new0(struct buddy, 1); + struct buddy *b; + struct gaim_blist_ui_ops *ops; + + b = g_new0(struct buddy, 1); b->account = account; b->name = g_strdup(screenname); b->alias = g_strdup(alias); b->settings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); ((GaimBlistNode*)b)->type = GAIM_BLIST_BUDDY_NODE; + ops = gaim_get_blist_ui_ops(); + + if (ops != NULL && ops->new_node != NULL) + ops->new_node((GaimBlistNode *)b); + return b; } void gaim_blist_add_buddy (struct buddy *buddy, struct group *group, GaimBlistNode *node) @@ -224,11 +249,18 @@ struct group *gaim_group_new(const char *name) { struct group *g = gaim_find_group(name); + if (!g) { + struct gaim_blist_ui_ops *ops; g= g_new0(struct group, 1); g->name = g_strdup(name); ((GaimBlistNode*)g)->type = GAIM_BLIST_GROUP_NODE; + ops = gaim_get_blist_ui_ops(); + + if (ops != NULL && ops->new_node != NULL) + ops->new_node((GaimBlistNode *)g); + } return g; } @@ -1243,5 +1275,11 @@ void gaim_set_blist_ui_ops(struct gaim_blist_ui_ops *ops) { - gaimbuddylist->ui_ops = blist_ui_ops = ops; + blist_ui_ops = ops; } + +struct gaim_blist_ui_ops * +gaim_get_blist_ui_ops(void) +{ + return blist_ui_ops; +} diff -r 8f523dbb970e -r 4bdd9a5fd026 src/list.h --- a/src/list.h Mon Mar 10 16:39:46 2003 +0000 +++ b/src/list.h Mon Mar 10 18:16:29 2003 +0000 @@ -37,8 +37,8 @@ GAIM_BLIST_OTHER_NODE, }; -#define GAIM_BLIST_NODE_IS_BUDDY(n) (n->type == GAIM_BLIST_BUDDY_NODE) -#define GAIM_BLIST_NODE_IS_GROUP(n) (n->type == GAIM_BLIST_GROUP_NODE) +#define GAIM_BLIST_NODE_IS_BUDDY(n) ((n)->type == GAIM_BLIST_BUDDY_NODE) +#define GAIM_BLIST_NODE_IS_GROUP(n) ((n)->type == GAIM_BLIST_GROUP_NODE) /**************************************************************************/ /* Data Structures */ @@ -93,6 +93,8 @@ struct gaim_buddy_list { GaimBlistNode *root; /**< The first node in the buddy list */ struct gaim_blist_ui_ops *ui_ops; /**< The UI operations for the buddy list */ + + void *ui_data; /**< UI-specific data. */ }; /** @@ -103,6 +105,8 @@ */ struct gaim_blist_ui_ops { + void (*new_list)(struct gaim_buddy_list *list); /**< Sets UI-specific data on a buddy list. */ + void (*new_node)(GaimBlistNode *node); /**< Sets UI-specific data on a node. */ void (*show)(struct gaim_buddy_list *list); /**< The core will call this when its finished doing it's core stuff */ void (*update)(struct gaim_buddy_list *list, GaimBlistNode *node); /**< This will update a node in the buddy list. */ @@ -115,12 +119,6 @@ }; /**************************************************************************/ -/* Globals */ -/**************************************************************************/ -extern struct gaim_buddy_list *gaimbuddylist; /**< A global for the core buddy list. */ - - -/**************************************************************************/ /** @name Buddy List API */ /**************************************************************************/ /*@{*/ @@ -130,6 +128,19 @@ */ struct gaim_buddy_list *gaim_blist_new(); +/** + * Sets the main buddy list. + * + * @return The main buddy list. + */ +void gaim_set_blist(struct gaim_buddy_list *blist); + +/** + * Returns the main buddy list. + * + * @return The main buddy list. + */ +struct gaim_buddy_list *gaim_get_blist(void); /** * Shows the buddy list, creating a new one if necessary. @@ -402,6 +413,13 @@ */ void gaim_set_blist_ui_ops(struct gaim_blist_ui_ops *ops); +/** + * Returns the UI operations structure to be used for the buddy list. + * + * @return The UI operations structure. + */ +struct gaim_blist_ui_ops *gaim_get_blist_ui_ops(void); + /*@}*/ #endif /* _LIST_H_ */ diff -r 8f523dbb970e -r 4bdd9a5fd026 src/main.c --- a/src/main.c Mon Mar 10 16:39:46 2003 +0000 +++ b/src/main.c Mon Mar 10 18:16:29 2003 +0000 @@ -526,11 +526,6 @@ } } - /* Set the UI operation structures. */ - gaim_set_win_ui_ops(gaim_get_gtk_window_ui_ops()); - gaim_set_xfer_ui_ops(gaim_get_gtk_xfer_ui_ops()); - gaim_set_blist_ui_ops(gaim_get_gtk_blist_ui_ops()); - setup_stock(); #ifndef _WIN32 @@ -863,6 +858,11 @@ wgaim_init(); #endif + /* Set the UI operation structures. */ + gaim_set_win_ui_ops(gaim_get_gtk_window_ui_ops()); + gaim_set_xfer_ui_ops(gaim_get_gtk_xfer_ui_ops()); + gaim_set_blist_ui_ops(gaim_get_gtk_blist_ui_ops()); + load_prefs(); core_main(); ui_main(); diff -r 8f523dbb970e -r 4bdd9a5fd026 src/multi.c --- a/src/multi.c Mon Mar 10 16:39:46 2003 +0000 +++ b/src/multi.c Mon Mar 10 18:16:29 2003 +0000 @@ -185,9 +185,14 @@ gtk_widget_destroy(acctedit); acctedit = NULL; } + treeview = NULL; - if (!d && !gtkblist->window && !mainwindow && !connections) + + if (!d && !GAIM_GTK_BLIST(gaim_get_blist())->window && + !mainwindow && !connections) { + do_quit(); + } } static void on_delete_acctedit(GtkWidget *w, GdkEvent *ev, gpointer d) diff -r 8f523dbb970e -r 4bdd9a5fd026 src/prefs.c --- a/src/prefs.c Mon Mar 10 16:39:46 2003 +0000 +++ b/src/prefs.c Mon Mar 10 18:16:29 2003 +0000 @@ -1966,12 +1966,16 @@ static void set_blist_option(GtkWidget *w, int option) { + struct gaim_gtk_buddy_list *gtkblist; + + gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); + blist_options ^= option; if (!gtkblist) return; - gaim_gtk_blist_refresh(gaimbuddylist); + gaim_gtk_blist_refresh(gaim_get_blist()); } diff -r 8f523dbb970e -r 4bdd9a5fd026 src/util.c --- a/src/util.c Mon Mar 10 16:39:46 2003 +0000 +++ b/src/util.c Mon Mar 10 18:16:29 2003 +0000 @@ -815,6 +815,9 @@ { GSList *awy = away_messages; struct away_message *a, *message = NULL; + struct gaim_gtk_buddy_list *gtkblist; + + gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); if (!gtkblist->window) { return;