pidgin/ljfisher-ssl-client-auth

f718420c4932
propagate from branch 'im.pidgin.pidgin' (head 39b9c5ca504e86f304dea353c1f0798298b567a6)
to branch 'im.pidgin.cpw.qulogic.gtk3' (head 21e9527afb95f0d11eb2994c82618c5dfcc6db90)
  • +2 -2
    configure.ac
  • +52 -21
    pidgin/gtkaccount.c
  • +2 -1
    pidgin/gtkblist-theme-loader.c
  • +564 -390
    pidgin/gtkblist.c
  • +1 -1
    pidgin/gtkblist.h
  • +52 -38
    pidgin/gtkcellrendererexpander.c
  • +516 -330
    pidgin/gtkconv.c
  • +4 -0
    pidgin/gtkconv.h
  • +21 -20
    pidgin/gtkconvwin.h
  • +10 -10
    pidgin/gtkdebug.c
  • +8 -5
    pidgin/gtkdialogs.c
  • +1 -1
    pidgin/gtkdialogs.h
  • +31 -17
    pidgin/gtkdnd-hints.c
  • +3 -9
    pidgin/gtkdocklet-gtk.c
  • +5 -21
    pidgin/gtkdocklet.c
  • +4 -2
    pidgin/gtkidle.c
  • +169 -100
    pidgin/gtkimhtml.c
  • +72 -32
    pidgin/gtkimhtmltoolbar.c
  • +4 -0
    pidgin/gtkimhtmltoolbar.h
  • +11 -6
    pidgin/gtklog.c
  • +1 -1
    pidgin/gtkmain.c
  • +2 -2
    pidgin/gtkmedia.c
  • +17 -9
    pidgin/gtkmenutray.c
  • +4 -0
    pidgin/gtkmenutray.h
  • +21 -11
    pidgin/gtknotify.c
  • +14 -9
    pidgin/gtkplugin.c
  • +11 -9
    pidgin/gtkpounce.c
  • +87 -45
    pidgin/gtkprefs.c
  • +4 -4
    pidgin/gtkprivacy.c
  • +43 -20
    pidgin/gtkrequest.c
  • +14 -10
    pidgin/gtkroomlist.c
  • +1 -1
    pidgin/gtksavedstatuses.c
  • +3 -3
    pidgin/gtkscrollbook.c
  • +9 -6
    pidgin/gtksmiley.c
  • +2 -1
    pidgin/gtksourceundomanager.c
  • +76 -64
    pidgin/gtkstatusbox.c
  • +94 -160
    pidgin/gtkutils.c
  • +0 -15
    pidgin/gtkutils.h
  • +61 -42
    pidgin/gtkwhiteboard.c
  • +1 -1
    pidgin/gtkwhiteboard.h
  • +1 -1
    pidgin/minidialog.c
  • +10 -5
    pidgin/pidgintooltip.c
  • +4 -5
    pidgin/plugins/contact_priority.c
  • +2 -2
    pidgin/plugins/convcolors.c
  • +3 -6
    pidgin/plugins/disco/gtkdisco.c
  • +1 -1
    pidgin/plugins/gestures/stroke-draw.c
  • +2 -0
    pidgin/plugins/markerline.c
  • +0 -1
    pidgin/plugins/themeedit.c
  • +17 -20
    pidgin/plugins/ticker/gtkticker.c
  • +1 -1
    pidgin/plugins/timestamp.c
  • +2 -1
    pidgin/plugins/timestamp_format.c
  • +2 -2
    pidgin/plugins/vvconfig.c
  • +46 -40
    pidgin/plugins/xmppconsole.c
  • --- a/configure.ac Sun Dec 05 03:09:52 2010 +0000
    +++ b/configure.ac Sun Dec 05 03:10:05 2010 +0000
    @@ -416,11 +416,11 @@
    fi
    if test "x$enable_gtkui" = "xyes" ; then
    - PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.10.0], , [
    + PKG_CHECK_MODULES(GTK, [gtk+-3.0 >= 2.91.6], , [
    AC_MSG_RESULT(no)
    AC_MSG_ERROR([
    -You must have GTK+ 2.10.0 or newer development headers installed to compile
    +You must have GTK+ 2.91.5 or newer development headers installed to compile
    Pidgin. If you want to build only Finch then specify --disable-gtkui when
    running configure.
    ])])
    --- a/pidgin/gtkaccount.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkaccount.c Sun Dec 05 03:10:05 2010 +0000
    @@ -160,6 +160,37 @@
    static void add_protocol_options(AccountPrefsDialog *dialog);
    static void add_proxy_options(AccountPrefsDialog *dialog, GtkWidget *parent);
    +static const char *
    +google_talk_default_domain_hackery(GtkWidget *protocol_combo, const char *value_if_gtalk)
    +{
    + GtkTreeModel *model;
    + GtkTreeIter iter;
    + const char *value = NULL;
    +
    + model = gtk_combo_box_get_model(GTK_COMBO_BOX(protocol_combo));
    + if (model != NULL && gtk_combo_box_get_active_iter(GTK_COMBO_BOX(protocol_combo), &iter)) {
    + char *protocol = NULL;
    +
    + /* protocol is not stored as G_TYPE_STRING in the model so no g_free necessary */
    + gtk_tree_model_get(model, &iter, 2, &protocol, -1);
    + if (protocol && !strcmp("prpl-jabber", protocol)) {
    + char *item_name = NULL;
    +
    + gtk_tree_model_get(model, &iter, 1, &item_name, -1);
    + if (item_name) {
    + if (!strcmp(item_name, _("Google Talk")))
    + value = value_if_gtalk;
    + g_free(item_name);
    + }
    + /* If it's not GTalk, but still Jabber then the value is not NULL, it's empty */
    + if (NULL == value)
    + value = "";
    + }
    + }
    +
    + return value;
    +}
    +
    static GtkWidget *
    add_pref_box(AccountPrefsDialog *dialog, GtkWidget *parent,
    const char *text, GtkWidget *widget)
    @@ -214,7 +245,7 @@
    }
    static void
    -set_account_protocol_cb(GtkWidget *item, const char *id,
    +set_account_protocol_cb(GtkWidget *widget, const char *id,
    AccountPrefsDialog *dialog)
    {
    PurplePlugin *new_plugin;
    @@ -240,8 +271,7 @@
    gtk_widget_grab_focus(dialog->protocol_menu);
    - if (!dialog->prpl_info || !dialog->prpl_info->register_user ||
    - g_object_get_data(G_OBJECT(item), "fake")) {
    + if (!dialog->prpl_info || !dialog->prpl_info->register_user) {
    gtk_widget_hide(dialog->register_button);
    } else {
    if (dialog->prpl_info != NULL &&
    @@ -348,9 +378,11 @@
    account_dnd_recv(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
    GtkSelectionData *sd, guint info, guint t, AccountPrefsDialog *dialog)
    {
    - gchar *name = (gchar *)sd->data;
    -
    - if ((sd->length >= 0) && (sd->format == 8)) {
    + const gchar *name = (gchar *) gtk_selection_data_get_data(sd);
    + gint length = gtk_selection_data_get_length(sd);
    + gint format = gtk_selection_data_get_format(sd);
    +
    + if (length >= 0 && format == 8) {
    /* Well, it looks like the drag event was cool.
    * Let's do something with it */
    if (!g_ascii_strncasecmp(name, "file://", 7)) {
    @@ -417,8 +449,6 @@
    GtkWidget *hbox;
    GtkWidget *vbox;
    GtkWidget *entry;
    - GtkWidget *menu;
    - GtkWidget *item;
    GList *user_splits;
    GList *l, *l2;
    char *username = NULL;
    @@ -557,11 +587,8 @@
    value = purple_account_user_split_get_default_value(split);
    /* Google Talk default domain hackery! */
    - menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(dialog->protocol_menu));
    - item = gtk_menu_get_active(GTK_MENU(menu));
    - if (value == NULL && g_object_get_data(G_OBJECT(item), "fake") &&
    - !strcmp(purple_account_user_split_get_text(split), _("Domain")))
    - value = "gmail.com";
    + if (!strcmp(_("Domain"), purple_account_user_split_get_text(split)) && !value)
    + value = google_talk_default_domain_hackery(dialog->protocol_menu, "gmail.com");
    if (value != NULL)
    gtk_entry_set_text(GTK_ENTRY(entry), value);
    @@ -1025,7 +1052,7 @@
    dialog->new_proxy_type == PURPLE_PROXY_NONE ||
    dialog->new_proxy_type == PURPLE_PROXY_USE_ENVVAR) {
    - gtk_widget_hide_all(dialog->proxy_vbox);
    + gtk_widget_hide(dialog->proxy_vbox);
    }
    else
    gtk_widget_show_all(dialog->proxy_vbox);
    @@ -1120,7 +1147,7 @@
    if (type == PURPLE_PROXY_USE_GLOBAL || type == PURPLE_PROXY_NONE ||
    type == PURPLE_PROXY_USE_ENVVAR)
    - gtk_widget_hide_all(vbox2);
    + gtk_widget_hide(vbox2);
    if ((value = purple_proxy_info_get_host(proxy_info)) != NULL)
    @@ -1144,7 +1171,7 @@
    dialog->new_proxy_type = PURPLE_PROXY_USE_GLOBAL;
    gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->proxy_dropdown),
    dialog->new_proxy_type + 1);
    - gtk_widget_hide_all(vbox2);
    + gtk_widget_hide(vbox2);
    }
    /* Connect signals. */
    @@ -1684,7 +1711,10 @@
    GtkSelectionData *data, guint info, guint time,
    AccountsWindow *dialog)
    {
    - if (data->target == gdk_atom_intern("PURPLE_ACCOUNT", FALSE)) {
    +
    + GdkAtom target = gtk_selection_data_get_target(data);
    +
    + if (target == gdk_atom_intern("PURPLE_ACCOUNT", FALSE)) {
    GtkTreeRowReference *ref;
    GtkTreePath *source_row;
    GtkTreeIter iter;
    @@ -1755,13 +1785,16 @@
    guint x, guint y, GtkSelectionData *sd,
    guint info, guint t, AccountsWindow *dialog)
    {
    - if (sd->target == gdk_atom_intern("PURPLE_ACCOUNT", FALSE) && sd->data) {
    + GdkAtom target = gtk_selection_data_get_target(sd);
    + const guchar *data = gtk_selection_data_get_data(sd);
    +
    + if (target == gdk_atom_intern("PURPLE_ACCOUNT", FALSE) && data) {
    gint dest_index;
    PurpleAccount *a = NULL;
    GtkTreePath *path = NULL;
    GtkTreeViewDropPosition position;
    - memcpy(&a, sd->data, sizeof(a));
    + memcpy(&a, data, sizeof(a));
    if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y,
    &path, &position)) {
    @@ -2610,5 +2643,3 @@
    purple_signals_disconnect_by_handle(pidgin_account_get_handle());
    purple_signals_unregister_by_instance(pidgin_account_get_handle());
    }
    -
    -
    --- a/pidgin/gtkblist-theme-loader.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkblist-theme-loader.c Sun Dec 05 03:10:05 2010 +0000
    @@ -65,7 +65,8 @@
    GdkColor color;
    if (temp && gdk_color_parse(temp, &color)) {
    - gdk_colormap_alloc_color(gdk_colormap_get_system(), &color, FALSE, TRUE);
    + /* TODO: fix this for gtk+ 3.0 */
    + /*gdk_colormap_alloc_color(gdk_colormap_get_system(), &color, FALSE, TRUE);*/
    return gdk_color_copy(&color);
    } else {
    return NULL;
    --- a/pidgin/gtkblist.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkblist.c Sun Dec 05 03:10:05 2010 +0000
    @@ -123,7 +123,8 @@
    #define PIDGIN_BUDDY_LIST_GET_PRIVATE(list) \
    ((PidginBuddyListPrivate *)((list)->priv))
    -static GtkWidget *accountmenu = NULL;
    +static guint accounts_merge_id;
    +static GtkActionGroup *accounts_action_group = NULL;
    static guint visibility_manager_count = 0;
    static GdkVisibilityState gtk_blist_visibility = GDK_VISIBILITY_UNOBSCURED;
    @@ -137,6 +138,9 @@
    static void sort_method_alphabetical(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
    static void sort_method_status(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
    static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
    +static guint sort_merge_id;
    +static GtkActionGroup *sort_action_group = NULL;
    +
    static PidginBuddyList *gtkblist = NULL;
    static GList *groups_tree(void);
    @@ -147,7 +151,6 @@
    static void pidgin_blist_update_group(PurpleBuddyList *list, PurpleBlistNode *node);
    static void pidgin_blist_update_contact(PurpleBuddyList *list, PurpleBlistNode *node);
    static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full);
    -static const char *item_factory_translate_func (const char *path, gpointer func_data);
    static gboolean get_iter_from_node(PurpleBlistNode *node, GtkTreeIter *iter);
    static gboolean buddy_is_displayable(PurpleBuddy *buddy);
    static void redo_buddy_list(PurpleBuddyList *list, gboolean remove, gboolean rerender);
    @@ -241,7 +244,7 @@
    /* check for visibility because when we aren't visible, this will *
    * give us bogus (0,0) coordinates. - xOr */
    - if (GTK_WIDGET_VISIBLE(w))
    + if (gtk_widget_get_visible(w))
    gtk_window_get_position(GTK_WINDOW(w), &x, &y);
    else
    return FALSE; /* carry on normally */
    @@ -987,20 +990,23 @@
    gtkblist = PIDGIN_BLIST(purple_get_blist());
    blist_window = gtkblist ? GTK_WINDOW(gtkblist->window) : NULL;
    + /* TODO: set no separator in gtk+ 3... */
    data->window = gtk_dialog_new_with_buttons(title,
    - blist_window, GTK_DIALOG_NO_SEPARATOR,
    - NULL);
    + blist_window, 0, NULL);
    gtk_window_set_transient_for(GTK_WINDOW(data->window), blist_window);
    gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK);
    gtk_container_set_border_width(GTK_CONTAINER(data->window), PIDGIN_HIG_BOX_SPACE);
    gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE);
    - gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), PIDGIN_HIG_BORDER);
    - gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), PIDGIN_HIG_BOX_SPACE);
    + gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(data->window))),
    + PIDGIN_HIG_BORDER);
    + gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(data->window))),
    + PIDGIN_HIG_BOX_SPACE);
    gtk_window_set_role(GTK_WINDOW(data->window), window_role);
    hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
    - gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox);
    + gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(data->window))),
    + hbox);
    gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
    gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
    @@ -1063,7 +1069,7 @@
    if (pce->is_int)
    {
    - GtkObject *adjust;
    + GtkAdjustment *adjust;
    adjust = gtk_adjustment_new(pce->min, pce->min, pce->max,
    1, 10, 10);
    input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0);
    @@ -1624,11 +1630,11 @@
    pidgin_retrieve_user_info(buddy->account->gc, buddy->name);
    } else {
    switch (event->keyval) {
    - case GDK_F2:
    + case GDK_KEY_F2:
    gtk_blist_menu_alias_cb(tv, node);
    break;
    - case GDK_Left:
    + case GDK_KEY_Left:
    path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter);
    if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(tv), path)) {
    /* Collapse the Group */
    @@ -1650,7 +1656,7 @@
    gtk_tree_path_free(path);
    break;
    - case GDK_Right:
    + case GDK_KEY_Right:
    path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter);
    if (!gtk_tree_view_row_expanded(GTK_TREE_VIEW(tv), path)) {
    /* Expand the Group */
    @@ -2041,64 +2047,70 @@
    return handled;
    }
    -static void pidgin_blist_buddy_details_cb(gpointer data, guint action, GtkWidget *item)
    +static void gtk_blist_show_xfer_dialog_cb(GtkAction *item, gpointer data)
    +{
    + pidgin_xfer_dialog_show(NULL);
    +}
    +
    +static void pidgin_blist_buddy_details_cb(GtkToggleAction *item, gpointer data)
    {
    pidgin_set_cursor(gtkblist->window, GDK_WATCH);
    purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons",
    - gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
    + gtk_toggle_action_get_active(item));
    pidgin_clear_cursor(gtkblist->window);
    }
    -static void pidgin_blist_show_idle_time_cb(gpointer data, guint action, GtkWidget *item)
    +static void pidgin_blist_show_idle_time_cb(GtkToggleAction *item, gpointer data)
    {
    pidgin_set_cursor(gtkblist->window, GDK_WATCH);
    purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_idle_time",
    - gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
    + gtk_toggle_action_get_active(item));
    pidgin_clear_cursor(gtkblist->window);
    }
    -static void pidgin_blist_show_protocol_icons_cb(gpointer data, guint action, GtkWidget *item)
    +static void pidgin_blist_show_protocol_icons_cb(GtkToggleAction *item, gpointer data)
    {
    purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons",
    - gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
    -}
    -
    -static void pidgin_blist_show_empty_groups_cb(gpointer data, guint action, GtkWidget *item)
    + gtk_toggle_action_get_active(item));
    +}
    +
    +static void pidgin_blist_show_empty_groups_cb(GtkToggleAction *item, gpointer data)
    {
    pidgin_set_cursor(gtkblist->window, GDK_WATCH);
    purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_empty_groups",
    - gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
    + gtk_toggle_action_get_active(item));
    pidgin_clear_cursor(gtkblist->window);
    }
    -static void pidgin_blist_edit_mode_cb(gpointer callback_data, guint callback_action,
    - GtkWidget *checkitem)
    +static void pidgin_blist_edit_mode_cb(GtkToggleAction *checkitem, gpointer data)
    {
    pidgin_set_cursor(gtkblist->window, GDK_WATCH);
    purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies",
    - gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(checkitem)));
    + gtk_toggle_action_get_active(checkitem));
    pidgin_clear_cursor(gtkblist->window);
    }
    -static void pidgin_blist_mute_sounds_cb(gpointer data, guint action, GtkWidget *item)
    -{
    - purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/sound/mute", GTK_CHECK_MENU_ITEM(item)->active);
    -}
    +static void pidgin_blist_mute_sounds_cb(GtkToggleAction *item, gpointer data)
    +{
    + purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/sound/mute",
    + gtk_toggle_action_get_active(item));
    +}
    +
    static void
    pidgin_blist_mute_pref_cb(const char *name, PurplePrefType type,
    gconstpointer value, gpointer data)
    {
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item(gtkblist->ift,
    - N_("/Tools/Mute Sounds"))), (gboolean)GPOINTER_TO_INT(value));
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui,
    + "/BList/ToolsMenu/MuteSounds")), (gboolean)GPOINTER_TO_INT(value));
    }
    static void
    @@ -2110,7 +2122,7 @@
    if(!strcmp(value, "none"))
    sensitive = FALSE;
    - gtk_widget_set_sensitive(gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Mute Sounds")), sensitive);
    + gtk_action_set_sensitive(gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/MuteSounds"), sensitive);
    }
    static void
    @@ -2267,9 +2279,9 @@
    guint time,
    gpointer null)
    {
    -
    - if (data->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
    - {
    + GdkAtom target = gtk_selection_data_get_target(data);
    +
    + if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) {
    GtkTreeRowReference *ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row");
    GtkTreePath *sourcerow = gtk_tree_row_reference_get_path(ref);
    GtkTreeIter iter;
    @@ -2288,9 +2300,7 @@
    sizeof (node));
    gtk_tree_path_free(sourcerow);
    - }
    - else if (data->target == gdk_atom_intern("application/x-im-contact", FALSE))
    - {
    + } else if (target == gdk_atom_intern("application/x-im-contact", FALSE)) {
    GtkTreeRowReference *ref;
    GtkTreePath *sourcerow;
    GtkTreeIter iter;
    @@ -2373,16 +2383,19 @@
    static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
    GtkSelectionData *sd, guint info, guint t)
    {
    + GdkAtom target = gtk_selection_data_get_target(sd);
    + const guchar *data = gtk_selection_data_get_data(sd);
    +
    if (gtkblist->drag_timeout) {
    g_source_remove(gtkblist->drag_timeout);
    gtkblist->drag_timeout = 0;
    }
    - if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE) && sd->data) {
    + if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE) && data) {
    PurpleBlistNode *n = NULL;
    GtkTreePath *path = NULL;
    GtkTreeViewDropPosition position;
    - memcpy(&n, sd->data, sizeof(n));
    + memcpy(&n, data, sizeof(n));
    if(gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y, &path, &position)) {
    /* if we're here, I think it means the drop is ok */
    GtkTreeIter iter;
    @@ -2521,12 +2534,10 @@
    }
    gtk_tree_path_free(path);
    - gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
    - }
    - }
    - else if (sd->target == gdk_atom_intern("application/x-im-contact",
    - FALSE) && sd->data)
    - {
    + gtk_drag_finish(dc, TRUE, (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
    + }
    + } else if (target == gdk_atom_intern("application/x-im-contact",
    + FALSE) && data) {
    PurpleGroup *group = NULL;
    GtkTreePath *path = NULL;
    GtkTreeViewDropPosition position;
    @@ -2564,7 +2575,7 @@
    }
    }
    - if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account,
    + if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account,
    &protocol, &username, &alias))
    {
    if (account == NULL)
    @@ -2588,9 +2599,10 @@
    if (path != NULL)
    gtk_tree_path_free(path);
    - gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
    - }
    - else if (sd->target == gdk_atom_intern("text/x-vcard", FALSE) && sd->data)
    + gtk_drag_finish(dc, TRUE,
    + (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
    + }
    + else if (target == gdk_atom_intern("text/x-vcard", FALSE) && data)
    {
    gboolean result;
    PurpleGroup *group = NULL;
    @@ -2626,10 +2638,11 @@
    }
    }
    - result = parse_vcard((const gchar *)sd->data, group);
    -
    - gtk_drag_finish(dc, result, (dc->action == GDK_ACTION_MOVE), t);
    - } else if (sd->target == gdk_atom_intern("text/uri-list", FALSE) && sd->data) {
    + result = parse_vcard((const gchar *) data, group);
    +
    + gtk_drag_finish(dc, result,
    + (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
    + } else if (target == gdk_atom_intern("text/uri-list", FALSE) && data) {
    GtkTreePath *path = NULL;
    GtkTreeViewDropPosition position;
    @@ -2650,7 +2663,8 @@
    if (PURPLE_BLIST_NODE_IS_BUDDY(node) || PURPLE_BLIST_NODE_IS_CONTACT(node)) {
    PurpleBuddy *b = PURPLE_BLIST_NODE_IS_BUDDY(node) ? PURPLE_BUDDY(node) : purple_contact_get_priority_buddy(PURPLE_CONTACT(node));
    pidgin_dnd_file_manage(sd, b->account, b->name);
    - gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
    + gtk_drag_finish(dc, TRUE,
    + (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
    } else {
    gtk_drag_finish(dc, FALSE, FALSE, t);
    }
    @@ -2988,7 +3002,7 @@
    if(gtkblist->tooltipdata == NULL)
    return FALSE;
    - style = gtkblist->tipwindow->style;
    + style = gtk_widget_get_style(gtkblist->tipwindow);
    max_text_width = 0;
    max_avatar_width = 0;
    @@ -3014,73 +3028,79 @@
    for(l = gtkblist->tooltipdata; l; l = l->next)
    {
    struct tooltip_data *td = l->data;
    -
    + cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(gtkblist->tipwindow));
    +
    if (td->avatar && pidgin_gdk_pixbuf_is_opaque(td->avatar))
    {
    if (dir == GTK_TEXT_DIR_RTL)
    - gtk_paint_flat_box(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
    - NULL, gtkblist->tipwindow, "tooltip",
    - TOOLTIP_BORDER -1, current_height -1, td->avatar_width +2, td->avatar_height + 2);
    + gtk_paint_flat_box(style, cr, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
    + gtkblist->tipwindow, "tooltip",
    + TOOLTIP_BORDER -1, current_height -1, td->avatar_width +2,
    + td->avatar_height + 2);
    else
    - gtk_paint_flat_box(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
    - NULL, gtkblist->tipwindow, "tooltip",
    + gtk_paint_flat_box(style, cr, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
    + gtkblist->tipwindow, "tooltip",
    max_width - (td->avatar_width+ TOOLTIP_BORDER)-1,
    current_height-1,td->avatar_width+2, td->avatar_height+2);
    }
    if (td->status_icon) {
    - if (dir == GTK_TEXT_DIR_RTL)
    - gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon,
    - 0, 0, max_width - TOOLTIP_BORDER - status_size, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
    - else
    - gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon,
    - 0, 0, TOOLTIP_BORDER, current_height, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0);
    - }
    -
    - if(td->avatar) {
    - if (dir == GTK_TEXT_DIR_RTL)
    - gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL,
    - td->avatar, 0, 0, TOOLTIP_BORDER, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
    - else
    - gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL,
    - td->avatar, 0, 0, max_width - (td->avatar_width + TOOLTIP_BORDER),
    - current_height, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0);
    - }
    -
    - if (!td->avatar_is_prpl_icon && td->prpl_icon)
    - gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->prpl_icon,
    - 0, 0,
    - prpl_col,
    - current_height + ((td->name_height / 2) - (PRPL_SIZE / 2)),
    - -1 , -1, GDK_RGB_DITHER_NONE, 0, 0);
    + if (dir == GTK_TEXT_DIR_RTL) {
    + gdk_cairo_set_source_pixbuf(cr, td->status_icon,
    + max_width - TOOLTIP_BORDER - status_size, current_height);
    + cairo_paint(cr);
    + } else {
    + gdk_cairo_set_source_pixbuf(cr, td->status_icon, TOOLTIP_BORDER, current_height);
    + cairo_paint(cr);
    + }
    + }
    +
    + if (td->avatar) {
    + if (dir == GTK_TEXT_DIR_RTL) {
    + gdk_cairo_set_source_pixbuf(cr, td->avatar, TOOLTIP_BORDER,
    + current_height);
    + cairo_paint(cr);
    + } else {
    + gdk_cairo_set_source_pixbuf(cr, td->avatar,
    + max_width - (td->avatar_width + TOOLTIP_BORDER), current_height);
    + cairo_paint(cr);
    + }
    + }
    +
    + if (!td->avatar_is_prpl_icon && td->prpl_icon) {
    + gdk_cairo_set_source_pixbuf(cr, td->prpl_icon, prpl_col,
    + current_height + ((td->name_height / 2) - (PRPL_SIZE / 2)));
    + cairo_paint(cr);
    + }
    if (td->name_layout) {
    if (dir == GTK_TEXT_DIR_RTL) {
    - gtk_paint_layout(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE,
    - NULL, gtkblist->tipwindow, "tooltip",
    + gtk_paint_layout(style, cr, GTK_STATE_NORMAL, FALSE,
    + gtkblist->tipwindow, "tooltip",
    max_width -(TOOLTIP_BORDER + status_size + SMALL_SPACE) - PANGO_PIXELS(300000),
    current_height, td->name_layout);
    } else {
    - gtk_paint_layout (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE,
    - NULL, gtkblist->tipwindow, "tooltip",
    + gtk_paint_layout (style, cr, GTK_STATE_NORMAL, FALSE,
    + gtkblist->tipwindow, "tooltip",
    TOOLTIP_BORDER + status_size + SMALL_SPACE, current_height, td->name_layout);
    }
    }
    if (td->layout) {
    if (dir != GTK_TEXT_DIR_RTL) {
    - gtk_paint_layout (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE,
    - NULL, gtkblist->tipwindow, "tooltip",
    + gtk_paint_layout (style, cr, GTK_STATE_NORMAL, FALSE,
    + gtkblist->tipwindow, "tooltip",
    TOOLTIP_BORDER + status_size + SMALL_SPACE, current_height + td->name_height, td->layout);
    } else {
    - gtk_paint_layout(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE,
    - NULL, gtkblist->tipwindow, "tooltip",
    + gtk_paint_layout(style, cr, GTK_STATE_NORMAL, FALSE,
    + gtkblist->tipwindow, "tooltip",
    max_width - (TOOLTIP_BORDER + status_size + SMALL_SPACE) - PANGO_PIXELS(300000),
    current_height + td->name_height,
    td->layout);
    }
    }
    + cairo_destroy(cr);
    current_height += MAX(td->name_height + td->height, td->avatar_height) + td->padding;
    }
    return FALSE;
    @@ -3234,7 +3254,8 @@
    pidgin_blist_expand_contact_cb(NULL, node);
    gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, &gtkblist->contact_rect);
    - gdk_drawable_get_size(GDK_DRAWABLE(tv->window), &(gtkblist->contact_rect.width), NULL);
    + gtkblist->contact_rect.width =
    + gdk_window_get_width(gtk_widget_get_window(tv));
    gtkblist->mouseover_contact = node;
    gtk_tree_path_down (path);
    while (gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &i, path)) {
    @@ -3651,6 +3672,123 @@
    /***************************************************
    * Crap *
    ***************************************************/
    +#if 1
    +/* TODO: fill out tooltips... */
    +static const GtkActionEntry blist_menu_entries[] = {
    + /* Buddies menu */
    + { "BuddiesMenu", NULL, N_("_Buddies"), NULL, NULL, NULL },
    + { "NewInstantMessage", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("New Instant _Message..."), "<control>M", NULL, pidgin_dialogs_im },
    + { "JoinAChat", PIDGIN_STOCK_CHAT, N_("Join a _Chat..."), "<control>C", NULL, pidgin_blist_joinchat_show },
    + { "GetUserInfo", PIDGIN_STOCK_TOOLBAR_USER_INFO, N_("Get User _Info..."), "<control>I", NULL, pidgin_dialogs_info },
    + { "ViewUserLog", NULL, N_("View User _Log..."), "<control>L", NULL, pidgin_dialogs_log },
    + { "ShowMenu", NULL, N_("Sh_ow"), NULL, NULL, NULL },
    + { "SortMenu", NULL, N_("_Sort Buddies"), NULL, NULL, NULL },
    + { "AddBuddy", GTK_STOCK_ADD, N_("_Add Buddy..."), "<control>B", NULL, pidgin_blist_add_buddy_cb },
    + { "AddChat", GTK_STOCK_ADD, N_("Add C_hat..."), NULL, NULL, pidgin_blist_add_chat_cb },
    + { "AddGroup", GTK_STOCK_ADD, N_("Add _Group..."), NULL, NULL, purple_blist_request_add_group },
    + { "Quit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q", NULL, purple_core_quit },
    +
    + /* Accounts menu */
    + { "AccountsMenu", NULL, N_("_Accounts"), NULL, NULL, NULL },
    + { "ManageAccounts", NULL, N_("Manage Accounts"), "<control>A", NULL, pidgin_accounts_window_show },
    + { "EnableAccountMenu", NULL, N_("Enable Account"), NULL, NULL, NULL },
    +
    + /* Tools */
    + { "ToolsMenu", NULL, N_("_Tools"), NULL, NULL, NULL },
    + { "BuddyPounces", NULL, N_("Buddy _Pounces"), NULL, NULL, pidgin_pounces_manager_show },
    + { "Certificates", NULL, N_("_Certificates"), NULL, NULL, pidgin_certmgr_show },
    + { "CustomSmileys", PIDGIN_STOCK_TOOLBAR_SMILEY, N_("Custom Smile_ys"), "<control>Y", NULL, pidgin_smiley_manager_show },
    + { "Plugins", PIDGIN_STOCK_TOOLBAR_PLUGINS, N_("Plu_gins"), "<control>U", NULL, pidgin_plugin_dialog_show },
    + { "Preferences", GTK_STOCK_PREFERENCES, N_("Pr_eferences"), "<control>P", NULL, pidgin_prefs_show },
    + { "Privacy", NULL, N_("Pr_ivacy"), NULL, NULL, pidgin_privacy_dialog_show },
    + { "SetMood", NULL, N_("Set _Mood"), "<control>O", NULL, set_mood_show },
    + { "FileTransfers", PIDGIN_STOCK_TOOLBAR_TRANSFER, N_("_File Transfers"), "<control>T", NULL, G_CALLBACK(gtk_blist_show_xfer_dialog_cb) },
    + { "RoomList", NULL, N_("R_oom List"), NULL, NULL, pidgin_roomlist_dialog_show },
    + { "SystemLog", NULL, N_("System _Log"), NULL, NULL, gtk_blist_show_systemlog_cb },
    +
    + /* Help */
    + { "HelpMenu", NULL, N_("_Help"), NULL, NULL, NULL },
    + { "OnlineHelp", GTK_STOCK_HELP, N_("Online _Help"), "F1", NULL, gtk_blist_show_onlinehelp_cb },
    + { "BuildInformation", NULL, N_("_Build Information"), NULL, NULL, pidgin_dialogs_buildinfo },
    + { "DebugWindow", NULL, N_("_Debug Window"), NULL, NULL, toggle_debug },
    + { "DeveloperInformation", NULL, N_("De_veloper Information"), NULL, NULL, pidgin_dialogs_developers },
    + { "TranslatorInformation", NULL, N_("_Translator Information"), NULL, NULL, pidgin_dialogs_translators },
    + { "About", GTK_STOCK_ABOUT, N_("_About"), NULL, NULL, pidgin_dialogs_about },
    +};
    +
    +/* Toggle items */
    +static const GtkToggleActionEntry blist_menu_toggle_entries[] = {
    + /* Buddies->Show menu */
    + { "ShowOffline", NULL, N_("_Offline Buddies"), NULL, NULL, G_CALLBACK(pidgin_blist_edit_mode_cb), FALSE },
    + { "ShowEmptyGroups", NULL, N_("_Empty Groups"), NULL, NULL, G_CALLBACK(pidgin_blist_show_empty_groups_cb), FALSE },
    + { "ShowBuddyDetails", NULL, N_("Buddy _Details"), NULL, NULL, G_CALLBACK(pidgin_blist_buddy_details_cb), FALSE },
    + { "ShowIdleTimes", NULL, N_("Idle _Times"), NULL, NULL, G_CALLBACK(pidgin_blist_show_idle_time_cb), FALSE },
    + { "ShowProtocolIcons", NULL, N_("_Protocol Icons"), NULL, NULL, G_CALLBACK(pidgin_blist_show_protocol_icons_cb), FALSE },
    +
    + /* Tools menu */
    + { "MuteSounds", NULL, N_("Mute _Sounds"), NULL, NULL, G_CALLBACK(pidgin_blist_mute_sounds_cb), FALSE },
    +};
    +
    +static const char *blist_menu =
    +"<ui>"
    + "<menubar name='BList'>"
    + "<menu action='BuddiesMenu'>"
    + "<menuitem action='NewInstantMessage'/>"
    + "<menuitem action='JoinAChat'/>"
    + "<menuitem action='GetUserInfo'/>"
    + "<menuitem action='ViewUserLog'/>"
    + "<separator/>"
    + "<menu action='ShowMenu'>"
    + "<menuitem action='ShowOffline'/>"
    + "<menuitem action='ShowEmptyGroups'/>"
    + "<menuitem action='ShowBuddyDetails'/>"
    + "<menuitem action='ShowIdleTimes'/>"
    + "<menuitem action='ShowProtocolIcons'/>"
    + "</menu>"
    + "<menu action='SortMenu'/>"
    + "<separator/>"
    + "<menuitem action='AddBuddy'/>"
    + "<menuitem action='AddChat'/>"
    + "<menuitem action='AddGroup'/>"
    + "<separator/>"
    + "<menuitem action='Quit'/>"
    + "</menu>"
    + "<menu action='AccountsMenu'>"
    + "<menuitem action='ManageAccounts'/>"
    + "<menu action='EnableAccountMenu'/>"
    + "<separator/>"
    + "<placeholder name='Accounts'/>"
    + "</menu>"
    + "<menu action='ToolsMenu'>"
    + "<menuitem action='BuddyPounces'/>"
    + "<menuitem action='Certificates'/>"
    + "<menuitem action='CustomSmileys'/>"
    + "<menuitem action='Plugins'/>"
    + "<menuitem action='Preferences'/>"
    + "<menuitem action='Privacy'/>"
    + "<menuitem action='SetMood'/>"
    + "<separator/>"
    + "<menuitem action='FileTransfers'/>"
    + "<menuitem action='RoomList'/>"
    + "<menuitem action='SystemLog'/>"
    + "<separator/>"
    + "<menuitem action='MuteSounds'/>"
    + "<placeholder name='PluginActions'/>"
    + "</menu>"
    + "<menu action='HelpMenu'>"
    + "<menuitem action='OnlineHelp'/>"
    + "<separator/>"
    + "<menuitem action='BuildInformation'/>"
    + "<menuitem action='DebugWindow'/>"
    + "<menuitem action='DeveloperInformation'/>"
    + "<menuitem action='TranslatorInformation'/>"
    + "<separator/>"
    + "<menuitem action='About'/>"
    + "</menu>"
    + "</menubar>"
    +"</ui>";
    +
    +#else
    static GtkItemFactoryEntry blist_menu[] =
    {
    /* NOTE: Do not set any accelerator to Control+O. It is mapped by
    @@ -3707,6 +3845,7 @@
    { "/Help/sep2", NULL, NULL, 0, "<Separator>", NULL },
    { N_("/Help/_About"), NULL, pidgin_dialogs_about, 4, "<StockItem>", GTK_STOCK_ABOUT },
    };
    +#endif
    /*********************************************************
    * Private Utility functions *
    @@ -4448,7 +4587,7 @@
    /* if the window exists, is hidden, we're saving positions, and the
    * position is sane... */
    if (gtkblist && gtkblist->window &&
    - !GTK_WIDGET_VISIBLE(gtkblist->window) && blist_width != 0) {
    + !gtk_widget_get_visible(gtkblist->window) && blist_width != 0) {
    blist_x = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/x");
    blist_y = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/y");
    @@ -4478,7 +4617,7 @@
    PurpleBlistNode *gnode, *cnode;
    if (gtk_blist_visibility == GDK_VISIBILITY_FULLY_OBSCURED
    - || !GTK_WIDGET_VISIBLE(gtkblist->window))
    + || !gtk_widget_get_visible(gtkblist->window))
    return TRUE;
    for(gnode = list->root; gnode; gnode = gnode->next) {
    @@ -4524,12 +4663,21 @@
    static const char *require_connection[] =
    {
    +#if 1
    + "/BList/BuddiesMenu/NewInstantMessage",
    + "/BList/BuddiesMenu/JoinAChat",
    + "/BList/BuddiesMenu/GetUserInfo",
    + "/BList/BuddiesMenu/AddBuddy",
    + "/BList/BuddiesMenu/AddChat",
    + "/BList/BuddiesMenu/AddGroup",
    +#else
    N_("/Buddies/New Instant Message..."),
    N_("/Buddies/Join a Chat..."),
    N_("/Buddies/Get User Info..."),
    N_("/Buddies/Add Buddy..."),
    N_("/Buddies/Add Chat..."),
    N_("/Buddies/Add Group..."),
    +#endif
    };
    static const int require_connection_size = sizeof(require_connection)
    @@ -4542,7 +4690,7 @@
    static void
    update_menu_bar(PidginBuddyList *gtkblist)
    {
    - GtkWidget *widget;
    + GtkAction *action;
    gboolean sensitive;
    int i;
    @@ -4554,21 +4702,21 @@
    for (i = 0; i < require_connection_size; i++)
    {
    - widget = gtk_item_factory_get_widget(gtkblist->ift, require_connection[i]);
    - gtk_widget_set_sensitive(widget, sensitive);
    - }
    -
    - widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Join a Chat..."));
    - gtk_widget_set_sensitive(widget, pidgin_blist_joinchat_is_showable());
    -
    - widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Add Chat..."));
    - gtk_widget_set_sensitive(widget, pidgin_blist_joinchat_is_showable());
    -
    - widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Privacy"));
    - gtk_widget_set_sensitive(widget, sensitive);
    -
    - widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Room List"));
    - gtk_widget_set_sensitive(widget, pidgin_roomlist_is_showable());
    + action = gtk_ui_manager_get_action(gtkblist->ui, require_connection[i]);
    + gtk_action_set_sensitive(action, sensitive);
    + }
    +
    + action = gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/JoinAChat");
    + gtk_action_set_sensitive(action, pidgin_blist_joinchat_is_showable());
    +
    + action = gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/AddChat");
    + gtk_action_set_sensitive(action, pidgin_blist_joinchat_is_showable());
    +
    + action = gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/Privacy");
    + gtk_action_set_sensitive(action, sensitive);
    +
    + action = gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/RoomList");
    + gtk_action_set_sensitive(action, pidgin_roomlist_is_showable());
    }
    static void
    @@ -4859,12 +5007,6 @@
    NUM_TARGETS
    };
    -static const char *
    -item_factory_translate_func (const char *path, gpointer func_data)
    -{
    - return _((char *)path);
    -}
    -
    void pidgin_blist_setup_sort_methods()
    {
    const char *id;
    @@ -4987,7 +5129,7 @@
    widget = gtk_window_get_focus(GTK_WINDOW(gtkblist->window));
    if (GTK_IS_IMHTML(widget) || GTK_IS_ENTRY(widget)) {
    - if (gtk_bindings_activate(GTK_OBJECT(widget), event->keyval, event->state))
    + if (gtk_bindings_activate(G_OBJECT(widget), event->keyval, event->state))
    return TRUE;
    }
    return FALSE;
    @@ -4996,14 +5138,14 @@
    static gboolean
    headline_box_enter_cb(GtkWidget *widget, GdkEventCrossing *event, PidginBuddyList *gtkblist)
    {
    - gdk_window_set_cursor(widget->window, gtkblist->hand_cursor);
    + gdk_window_set_cursor(gtk_widget_get_window(widget), gtkblist->hand_cursor);
    return FALSE;
    }
    static gboolean
    headline_box_leave_cb(GtkWidget *widget, GdkEventCrossing *event, PidginBuddyList *gtkblist)
    {
    - gdk_window_set_cursor(widget->window, gtkblist->arrow_cursor);
    + gdk_window_set_cursor(gtk_widget_get_window(widget), gtkblist->arrow_cursor);
    return FALSE;
    }
    @@ -5137,7 +5279,7 @@
    }
    static void
    -generic_error_destroy_cb(GtkObject *dialog,
    +generic_error_destroy_cb(GtkWidget *dialog,
    PurpleAccount *account)
    {
    g_hash_table_remove(gtkblist->connection_errors, account);
    @@ -5499,17 +5641,22 @@
    GdkEventExpose *event,
    gpointer user_data)
    {
    - gtk_paint_flat_box (widget->style,
    - widget->window,
    - GTK_STATE_NORMAL,
    - GTK_SHADOW_OUT,
    - NULL,
    - widget,
    - "tooltip",
    - widget->allocation.x + 1,
    - widget->allocation.y + 1,
    - widget->allocation.width - 2,
    - widget->allocation.height - 2);
    + cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget));
    + GtkAllocation allocation;
    +
    + gtk_widget_get_allocation(widget, &allocation);
    + gtk_paint_flat_box (gtk_widget_get_style(widget),
    + cr,
    + GTK_STATE_NORMAL,
    + GTK_SHADOW_OUT,
    + widget,
    + "tooltip",
    + allocation.x + 1,
    + allocation.y + 1,
    + allocation.width - 2,
    + allocation.height - 2);
    + cairo_destroy(cr);
    +
    return FALSE;
    }
    @@ -5533,8 +5680,28 @@
    headline_style_set (GtkWidget *widget,
    GtkStyle *prev_style)
    {
    + GtkStyle *style;
    +#if GTK_CHECK_VERSION(2,12,0)
    + GtkWidget *window;
    +
    + if (gtkblist->changing_style)
    + return;
    +
    + /* This is a hack needed to use the tooltip background colour */
    + window = gtk_window_new(GTK_WINDOW_POPUP);
    + gtk_widget_set_name(window, "gtk-tooltip");
    + gtk_widget_ensure_style(window);
    + style = gtk_widget_get_style(window);
    +
    + gtkblist->changing_style = TRUE;
    + gtk_widget_set_style(gtkblist->headline_hbox, style);
    + gtkblist->changing_style = FALSE;
    +
    + gtk_widget_destroy(window);
    +
    + gtk_widget_queue_draw(gtkblist->headline_hbox);
    +#else
    GtkTooltips *tooltips;
    - GtkStyle *style;
    if (gtkblist->changing_style)
    return;
    @@ -5554,6 +5721,7 @@
    gtkblist->changing_style = FALSE;
    g_object_unref (tooltips);
    +#endif
    }
    /******************************************/
    @@ -5791,6 +5959,8 @@
    GtkWidget *close;
    char *pretty, *tmp;
    const char *theme_name;
    + GtkActionGroup *action_group;
    + GError *error;
    GtkAccelGroup *accel_group;
    GtkTreeSelection *selection;
    GtkTargetEntry dte[] = {{"PURPLE_BLIST_NODE", GTK_TARGET_SAME_APP, DRAG_ROW},
    @@ -5826,7 +5996,9 @@
    G_CALLBACK(blist_focus_cb), gtkblist);
    g_signal_connect(G_OBJECT(gtkblist->window), "focus-out-event",
    G_CALLBACK(blist_focus_cb), gtkblist);
    - GTK_WINDOW(gtkblist->window)->allow_shrink = TRUE;
    +
    + /* TODO: how is this done in gtk+ 3.0? */
    + /*GTK_WINDOW(gtkblist->window)->allow_shrink = TRUE;*/
    gtkblist->main_vbox = gtk_vbox_new(FALSE, 0);
    gtk_widget_show(gtkblist->main_vbox);
    @@ -5840,28 +6012,41 @@
    gtk_widget_add_events(gtkblist->window, GDK_VISIBILITY_NOTIFY_MASK);
    /******************************* Menu bar *************************************/
    - accel_group = gtk_accel_group_new();
    - gtk_window_add_accel_group(GTK_WINDOW (gtkblist->window), accel_group);
    - g_object_unref(accel_group);
    - gtkblist->ift = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<PurpleMain>", accel_group);
    - gtk_item_factory_set_translate_func(gtkblist->ift,
    - (GtkTranslateFunc)item_factory_translate_func,
    - NULL, NULL);
    - gtk_item_factory_create_items(gtkblist->ift, sizeof(blist_menu) / sizeof(*blist_menu),
    - blist_menu, NULL);
    - pidgin_load_accels();
    - g_signal_connect(G_OBJECT(accel_group), "accel-changed", G_CALLBACK(pidgin_save_accels_cb), NULL);
    -
    - menu = gtk_item_factory_get_widget(gtkblist->ift, "<PurpleMain>");
    + action_group = gtk_action_group_new("BListActions");
    + gtk_action_group_add_actions(action_group,
    + blist_menu_entries,
    + G_N_ELEMENTS(blist_menu_entries),
    + GTK_WINDOW(gtkblist->window));
    + gtk_action_group_add_toggle_actions(action_group,
    + blist_menu_toggle_entries,
    + G_N_ELEMENTS(blist_menu_toggle_entries),
    + GTK_WINDOW(gtkblist->window));
    +#ifdef ENABLE_NLS
    + gtk_action_group_set_translation_domain(action_group,
    + PACKAGE);
    +#endif
    +
    + gtkblist->ui = gtk_ui_manager_new();
    + gtk_ui_manager_insert_action_group(gtkblist->ui, action_group, 0);
    +
    + accel_group = gtk_ui_manager_get_accel_group(gtkblist->ui);
    + gtk_window_add_accel_group(GTK_WINDOW(gtkblist->window), accel_group);
    +
    + error = NULL;
    + if (!gtk_ui_manager_add_ui_from_string(gtkblist->ui, blist_menu, -1, &error))
    + {
    + g_message("building menus failed: %s", error->message);
    + g_error_free(error);
    + exit(EXIT_FAILURE);
    + }
    +
    + menu = gtk_ui_manager_get_widget(gtkblist->ui, "/BList");
    gtkblist->menutray = pidgin_menu_tray_new();
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtkblist->menutray);
    gtk_widget_show(gtkblist->menutray);
    gtk_widget_show(menu);
    gtk_box_pack_start(GTK_BOX(gtkblist->main_vbox), menu, FALSE, FALSE, 0);
    - accountmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Accounts"));
    -
    -
    /****************************** Notebook *************************************/
    gtkblist->notebook = gtk_notebook_new();
    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gtkblist->notebook), FALSE);
    @@ -5882,7 +6067,6 @@
    pretty = pidgin_make_pretty_arrows(tmp);
    g_free(tmp);
    label = gtk_label_new(NULL);
    - gtk_widget_set_size_request(label, purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/width") - 12, -1);
    gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
    gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.2);
    gtk_label_set_markup(GTK_LABEL(label), pretty);
    @@ -5912,7 +6096,7 @@
    G_CALLBACK(headline_style_set),
    NULL);
    g_signal_connect (gtkblist->headline_hbox,
    - "expose_event",
    + "draw",
    G_CALLBACK (paint_headline_hbox),
    NULL);
    gtk_widget_set_name(gtkblist->headline_hbox, "gtk-tooltips");
    @@ -5965,7 +6149,7 @@
    gtk_widget_show(gtkblist->treeview);
    gtk_widget_set_name(gtkblist->treeview, "pidgin_blist_treeview");
    -
    +
    g_signal_connect(gtkblist->treeview,
    "style-set",
    G_CALLBACK(treeview_style_set), list);
    @@ -6052,26 +6236,26 @@
    /* set the Show Offline Buddies option. must be done
    * after the treeview or faceprint gets mad. -Robot101
    */
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Offline Buddies"))),
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowOffline")),
    purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies"));
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Empty Groups"))),
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowEmptyGroups")),
    purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_empty_groups"));
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Tools/Mute Sounds"))),
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/MuteSounds")),
    purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/sound/mute"));
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Buddy Details"))),
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowBuddyDetails")),
    purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"));
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Idle Times"))),
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowIdleTimes")),
    purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_idle_time"));
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Protocol Icons"))),
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowProtocolIcons")),
    purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"));
    if(!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), "none"))
    - gtk_widget_set_sensitive(gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Mute Sounds")), FALSE);
    + gtk_action_set_sensitive(gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/MuteSounds"), FALSE);
    /* Update some dynamic things */
    update_menu_bar(gtkblist);
    @@ -6928,7 +7112,7 @@
    purple_signals_disconnect_by_handle(gtkblist);
    if (gtkblist->headline_close)
    - gdk_pixbuf_unref(gtkblist->headline_close);
    + g_object_unref(G_OBJECT(gtkblist->headline_close));
    gtk_widget_destroy(gtkblist->window);
    @@ -6948,7 +7132,7 @@
    gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL;
    g_object_unref(G_OBJECT(gtkblist->treemodel));
    gtkblist->treemodel = NULL;
    - g_object_unref(G_OBJECT(gtkblist->ift));
    + g_object_unref(G_OBJECT(gtkblist->ui));
    g_object_unref(G_OBJECT(gtkblist->empty_avatar));
    gdk_cursor_unref(gtkblist->hand_cursor);
    @@ -6962,7 +7146,6 @@
    g_free(priv);
    g_free(gtkblist);
    - accountmenu = NULL;
    gtkblist = NULL;
    purple_prefs_disconnect_by_handle(pidgin_blist_get_handle());
    }
    @@ -6973,7 +7156,8 @@
    return;
    if (show) {
    - if(!PIDGIN_WINDOW_ICONIFIED(gtkblist->window) && !GTK_WIDGET_VISIBLE(gtkblist->window))
    + if(!PIDGIN_WINDOW_ICONIFIED(gtkblist->window) &&
    + !gtk_widget_get_visible(gtkblist->window))
    purple_signal_emit(pidgin_blist_get_handle(), "gtkblist-unhiding", gtkblist);
    pidgin_blist_restore_position();
    gtk_window_present(GTK_WINDOW(gtkblist->window));
    @@ -6982,7 +7166,7 @@
    purple_signal_emit(pidgin_blist_get_handle(), "gtkblist-hiding", gtkblist);
    gtk_widget_hide(gtkblist->window);
    } else {
    - if (!GTK_WIDGET_VISIBLE(gtkblist->window))
    + if (!gtk_widget_get_visible(gtkblist->window))
    gtk_widget_show(gtkblist->window);
    gtk_window_iconify(GTK_WINDOW(gtkblist->window));
    }
    @@ -7358,7 +7542,7 @@
    pidgin_blist_toggle_visibility()
    {
    if (gtkblist && gtkblist->window) {
    - if (GTK_WIDGET_VISIBLE(gtkblist->window)) {
    + if (gtk_widget_get_visible(gtkblist->window)) {
    /* make the buddy list visible if it is iconified or if it is
    * obscured and not currently focused (the focus part ensures
    * that we do something reasonable if the buddy list is obscured
    @@ -7423,7 +7607,7 @@
    static void
    set_urgent(void)
    {
    - if (gtkblist->window && !GTK_WIDGET_HAS_FOCUS(gtkblist->window))
    + if (gtkblist->window && !gtk_widget_is_focus(gtkblist->window))
    pidgin_set_urgent(GTK_WINDOW(gtkblist->window), TRUE);
    }
    @@ -7966,47 +8150,50 @@
    }
    static void
    -plugin_act(GtkObject *obj, PurplePluginAction *pam)
    +plugin_act(GtkWidget *obj, PurplePluginAction *pam)
    {
    if (pam && pam->callback)
    pam->callback(pam);
    }
    static void
    -build_plugin_actions(GtkWidget *menu, PurplePlugin *plugin,
    - gpointer context)
    -{
    - GtkWidget *menuitem;
    +build_plugin_actions(GtkActionGroup *action_group, GString *ui, char *parent,
    + PurplePlugin *plugin, gpointer context)
    +{
    + GtkAction *menuaction;
    PurplePluginAction *action = NULL;
    GList *actions, *l;
    + char *name;
    + int count = 0;
    actions = PURPLE_PLUGIN_ACTIONS(plugin, context);
    - for (l = actions; l != NULL; l = l->next)
    - {
    - if (l->data)
    - {
    - action = (PurplePluginAction *) l->data;
    + for (l = actions; l != NULL; l = l->next) {
    + if (l->data) {
    + action = (PurplePluginAction *)l->data;
    action->plugin = plugin;
    action->context = context;
    - menuitem = gtk_menu_item_new_with_label(action->label);
    - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
    -
    - g_signal_connect(G_OBJECT(menuitem), "activate",
    + name = g_strdup_printf("%s-action-%d", parent, count++);
    + menuaction = gtk_action_new(name, action->label, NULL, NULL);
    + gtk_action_group_add_action(action_group, menuaction);
    + g_string_append_printf(ui, "<menuitem action='%s'/>", name);
    +
    + g_signal_connect(G_OBJECT(menuaction), "activate",
    G_CALLBACK(plugin_act), action);
    - g_object_set_data_full(G_OBJECT(menuitem), "plugin_action",
    + g_object_set_data_full(G_OBJECT(menuaction), "plugin_action",
    action,
    (GDestroyNotify)purple_plugin_action_free);
    - gtk_widget_show(menuitem);
    + g_free(name);
    }
    else
    - pidgin_separator(menu);
    + g_string_append(ui, "<separator/>");
    }
    g_list_free(actions);
    }
    +
    static void
    modify_account_cb(GtkWidget *widget, gpointer data)
    {
    @@ -8038,183 +8225,146 @@
    void
    pidgin_blist_update_accounts_menu(void)
    {
    - GtkWidget *menuitem = NULL, *submenu = NULL;
    - GtkAccelGroup *accel_group = NULL;
    - GList *l = NULL, *accounts = NULL;
    - gboolean disabled_accounts = FALSE;
    - gboolean enabled_accounts = FALSE;
    -
    - if (accountmenu == NULL)
    + GList *accounts = NULL;
    +
    + GtkAction *action;
    + GString *accounts_ui;
    + GString *enable_ui;
    + gchar *ui_string;
    + int count = 0;
    +
    + if ((gtkblist == NULL) || (gtkblist->ui == NULL))
    return;
    - /* Clear the old Accounts menu */
    - for (l = gtk_container_get_children(GTK_CONTAINER(accountmenu)); l; l = g_list_delete_link(l, l)) {
    - menuitem = l->data;
    -
    - if (menuitem != gtk_item_factory_get_widget(gtkblist->ift, N_("/Accounts/Manage Accounts")))
    - gtk_widget_destroy(menuitem);
    - }
    -
    - for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
    - char *buf = NULL;
    - GtkWidget *image = NULL;
    - PurpleAccount *account = NULL;
    - GdkPixbuf *pixbuf = NULL;
    -
    - account = accounts->data;
    -
    - if(!purple_account_get_enabled(account, PIDGIN_UI)) {
    - if (!disabled_accounts) {
    - menuitem = gtk_menu_item_new_with_label(_("Enable Account"));
    - gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
    -
    - submenu = gtk_menu_new();
    - gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
    - gtk_menu_set_accel_path(GTK_MENU(submenu), N_("<PurpleMain>/Accounts/Enable Account"));
    - gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
    -
    - disabled_accounts = TRUE;
    - }
    -
    - buf = g_strconcat(purple_account_get_username(account), " (",
    - purple_account_get_protocol_name(account), ")", NULL);
    - menuitem = gtk_image_menu_item_new_with_label(buf);
    - g_free(buf);
    - pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
    - if (pixbuf != NULL)
    - {
    - if (!purple_account_is_connected(account))
    - gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
    - image = gtk_image_new_from_pixbuf(pixbuf);
    - g_object_unref(G_OBJECT(pixbuf));
    - gtk_widget_show(image);
    - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
    - }
    - g_signal_connect(G_OBJECT(menuitem), "activate",
    - G_CALLBACK(enable_account_cb), account);
    - gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
    - } else {
    - enabled_accounts = TRUE;
    - }
    - }
    -
    - if (!enabled_accounts) {
    - gtk_widget_show_all(accountmenu);
    - return;
    - }
    -
    - pidgin_separator(accountmenu);
    - accel_group = gtk_menu_get_accel_group(GTK_MENU(accountmenu));
    + /* Clear the old menu */
    + if (accounts_action_group) {
    + gtk_ui_manager_remove_ui(gtkblist->ui, accounts_merge_id);
    + gtk_ui_manager_remove_action_group(gtkblist->ui, accounts_action_group);
    + g_object_unref(G_OBJECT(accounts_action_group));
    + }
    +
    + accounts_action_group = gtk_action_group_new("Accounts");
    +#ifdef ENABLE_NLS
    + gtk_action_group_set_translation_domain(accounts_action_group, PACKAGE);
    +#endif
    + accounts_ui = g_string_new(NULL);
    + enable_ui = g_string_new(NULL);
    +
    + action = gtk_action_new("none-available", N_("No actions available"), NULL, NULL);
    + gtk_action_group_add_action(accounts_action_group, action);
    + gtk_action_set_sensitive(action, FALSE);
    for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
    - char *buf = NULL;
    - char *accel_path_buf = NULL;
    - GtkWidget *image = NULL;
    - PurpleConnection *gc = NULL;
    + char *label;
    + char *base;
    + char *name;
    PurpleAccount *account = NULL;
    - GdkPixbuf *pixbuf = NULL;
    - PurplePlugin *plugin = NULL;
    - PurplePluginProtocolInfo *prpl_info;
    account = accounts->data;
    - if (!purple_account_get_enabled(account, PIDGIN_UI))
    - continue;
    -
    - buf = g_strconcat(purple_account_get_username(account), " (",
    + base = name = g_strdup_printf("account%d", count);
    + label = g_strconcat(purple_account_get_username(account), " (",
    purple_account_get_protocol_name(account), ")", NULL);
    - menuitem = gtk_image_menu_item_new_with_label(buf);
    - accel_path_buf = g_strconcat(N_("<PurpleMain>/Accounts/"), buf, NULL);
    - g_free(buf);
    - pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
    - if (pixbuf != NULL) {
    - if (!purple_account_is_connected(account))
    - gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf,
    - 0.0, FALSE);
    - image = gtk_image_new_from_pixbuf(pixbuf);
    - g_object_unref(G_OBJECT(pixbuf));
    - gtk_widget_show(image);
    - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
    - }
    - gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
    -
    - submenu = gtk_menu_new();
    - gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
    - gtk_menu_set_accel_path(GTK_MENU(submenu), accel_path_buf);
    - g_free(accel_path_buf);
    - gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
    -
    -
    - menuitem = gtk_menu_item_new_with_mnemonic(_("_Edit Account"));
    - g_signal_connect(G_OBJECT(menuitem), "activate",
    - G_CALLBACK(modify_account_cb), account);
    - gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
    -
    - pidgin_separator(submenu);
    -
    - gc = purple_account_get_connection(account);
    - plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
    - prpl_info = plugin ? PURPLE_PLUGIN_PROTOCOL_INFO(plugin) : NULL;
    -
    - if (prpl_info &&
    - (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_moods) ||
    - PURPLE_PLUGIN_HAS_ACTIONS(plugin))) {
    - if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_moods) &&
    - gc->flags & PURPLE_CONNECTION_SUPPORT_MOODS) {
    -
    - if (purple_account_get_status(account, "mood")) {
    - menuitem = gtk_menu_item_new_with_mnemonic(_("Set _Mood..."));
    - g_signal_connect(G_OBJECT(menuitem), "activate",
    - G_CALLBACK(set_mood_cb), account);
    - gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
    - }
    + action = gtk_action_new(name, label, NULL, NULL);
    + g_free(label);
    + gtk_action_group_add_action(accounts_action_group, action);
    +
    + if (!purple_account_get_enabled(account, PIDGIN_UI)) {
    + g_string_append_printf(enable_ui, "<menuitem action='%s'/>", name);
    + g_signal_connect(G_OBJECT(action), "activate",
    + G_CALLBACK(enable_account_cb), account);
    +
    + } else {
    + PurpleConnection *gc = NULL;
    + PurplePlugin *plugin = NULL;
    +
    + g_string_append_printf(accounts_ui, "<menu action='%s'>", name);
    +
    + name = g_strconcat(base, "-edit", NULL);
    + action = gtk_action_new(name, N_("_Edit Account"), NULL, NULL);
    + gtk_action_group_add_action(accounts_action_group, action);
    + g_signal_connect(G_OBJECT(action), "activate",
    + G_CALLBACK(modify_account_cb), account);
    + g_string_append_printf(accounts_ui, "<menuitem action='%s'/>", name);
    + g_free(name);
    +
    + g_string_append(accounts_ui, "<separator/>");
    +
    + gc = purple_account_get_connection(account);
    + plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
    + if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
    + build_plugin_actions(accounts_action_group, accounts_ui, base, plugin, gc);
    + } else {
    + g_string_append(accounts_ui, "<menuitem action='none-available'/>");
    }
    - if (PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
    - build_plugin_actions(submenu, plugin, gc);
    - }
    - } else {
    - menuitem = gtk_menu_item_new_with_label(_("No actions available"));
    - gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
    - gtk_widget_set_sensitive(menuitem, FALSE);
    - }
    -
    - pidgin_separator(submenu);
    -
    - menuitem = gtk_menu_item_new_with_mnemonic(_("_Disable"));
    - g_signal_connect(G_OBJECT(menuitem), "activate",
    - G_CALLBACK(disable_account_cb), account);
    - gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
    - }
    - gtk_widget_show_all(accountmenu);
    -}
    -
    -static GList *plugin_submenus = NULL;
    +
    + g_string_append(accounts_ui, "<separator/>");
    +
    + name = g_strconcat(base, "-disable", NULL);
    + action = gtk_action_new(name, N_("_Disable"), NULL, NULL);
    + gtk_action_group_add_action(accounts_action_group, action);
    + g_signal_connect(G_OBJECT(action), "activate",
    + G_CALLBACK(disable_account_cb), account);
    + g_string_append_printf(accounts_ui, "<menuitem action='%s'/>", name);
    + g_free(name);
    +
    + g_string_append(accounts_ui, "</menu>");
    + }
    +
    + g_free(base);
    + count++;
    + }
    +
    + ui_string = g_strconcat("<ui><menubar action='BList'><menu action='AccountsMenu'><menu action='EnableAccountMenu'>",
    + enable_ui->str,
    + "</menu><placeholder name='Accounts'>",
    + accounts_ui->str,
    + "</placeholder></menu></menubar></ui>",
    + NULL);
    + gtk_ui_manager_insert_action_group(gtkblist->ui, accounts_action_group, 1);
    + accounts_merge_id = gtk_ui_manager_add_ui_from_string(gtkblist->ui, ui_string, -1, NULL);
    +purple_debug_info("blist", "The account menu is {%s}\n", ui_string);
    +
    + g_string_free(enable_ui, TRUE);
    + g_string_free(accounts_ui, TRUE);
    + g_free(ui_string);
    +}
    +
    +static guint plugins_merge_id;
    +static GtkActionGroup *plugins_action_group = NULL;
    void
    pidgin_blist_update_plugin_actions(void)
    {
    - GtkWidget *menuitem, *submenu;
    PurplePlugin *plugin = NULL;
    GList *l;
    - GtkAccelGroup *accel_group;
    -
    - GtkWidget *pluginmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools"));
    -
    - g_return_if_fail(pluginmenu != NULL);
    -
    - /* Remove old plugin action submenus from the Tools menu */
    - for (l = plugin_submenus; l; l = l->next)
    - gtk_widget_destroy(GTK_WIDGET(l->data));
    - g_list_free(plugin_submenus);
    - plugin_submenus = NULL;
    -
    - accel_group = gtk_menu_get_accel_group(GTK_MENU(pluginmenu));
    +
    + GtkAction *action;
    + GString *plugins_ui;
    + gchar *ui_string;
    + int count = 0;
    +
    + if ((gtkblist == NULL) || (gtkblist->ui == NULL))
    + return;
    +
    + /* Clear the old menu */
    + if (plugins_action_group) {
    + gtk_ui_manager_remove_ui(gtkblist->ui, plugins_merge_id);
    + gtk_ui_manager_remove_action_group(gtkblist->ui, plugins_action_group);
    + g_object_unref(G_OBJECT(plugins_action_group));
    + }
    +
    + plugins_action_group = gtk_action_group_new("PluginActions");
    +#ifdef ENABLE_NLS
    + gtk_action_group_set_translation_domain(plugins_action_group, PACKAGE);
    +#endif
    + plugins_ui = g_string_new(NULL);
    /* Add a submenu for each plugin with custom actions */
    for (l = purple_plugins_get_loaded(); l; l = l->next) {
    - char *path;
    -
    - plugin = (PurplePlugin *) l->data;
    + char *name;
    +
    + plugin = (PurplePlugin *)l->data;
    if (PURPLE_IS_PROTOCOL_PLUGIN(plugin))
    continue;
    @@ -8222,28 +8372,35 @@
    if (!PURPLE_PLUGIN_HAS_ACTIONS(plugin))
    continue;
    - menuitem = gtk_image_menu_item_new_with_label(_(plugin->info->name));
    - gtk_menu_shell_append(GTK_MENU_SHELL(pluginmenu), menuitem);
    -
    - plugin_submenus = g_list_append(plugin_submenus, menuitem);
    -
    - submenu = gtk_menu_new();
    - gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
    -
    - gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
    - path = g_strdup_printf("%s/Tools/%s", gtkblist->ift->path, plugin->info->name);
    - gtk_menu_set_accel_path(GTK_MENU(submenu), path);
    - g_free(path);
    -
    - build_plugin_actions(submenu, plugin, NULL);
    - }
    - gtk_widget_show_all(pluginmenu);
    + name = g_strdup_printf("plugin%d", count);
    + action = gtk_action_new(name, plugin->info->name, NULL, NULL);
    + gtk_action_group_add_action(plugins_action_group, action);
    + g_string_append_printf(plugins_ui, "<menu action='%s'>", name);
    +
    + build_plugin_actions(plugins_action_group, plugins_ui, name, plugin, NULL);
    +
    + g_string_append(plugins_ui, "</menu>");
    + count++;
    +
    + g_free(name);
    + }
    +
    + ui_string = g_strconcat("<ui><menubar action='BList'><menu action='ToolsMenu'><placeholder name='PluginActions'>",
    + plugins_ui->str,
    + "</placeholder></menu></menubar></ui>",
    + NULL);
    + gtk_ui_manager_insert_action_group(gtkblist->ui, plugins_action_group, 1);
    + plugins_merge_id = gtk_ui_manager_add_ui_from_string(gtkblist->ui, ui_string, -1, NULL);
    +purple_debug_info("blist", "The plugins menu is {%s}\n", ui_string);
    +
    + g_string_free(plugins_ui, TRUE);
    + g_free(ui_string);
    }
    static void
    -sortmethod_act(GtkCheckMenuItem *checkmenuitem, char *id)
    -{
    - if (gtk_check_menu_item_get_active(checkmenuitem))
    +sortmethod_act(GtkRadioAction *action, GtkRadioAction *current, char *id)
    +{
    + if (action == current)
    {
    pidgin_set_cursor(gtkblist->window, GDK_WATCH);
    /* This is redundant. I think. */
    @@ -8257,40 +8414,57 @@
    void
    pidgin_blist_update_sort_methods(void)
    {
    - GtkWidget *menuitem = NULL, *activeitem = NULL;
    PidginBlistSortMethod *method = NULL;
    GList *l;
    GSList *sl = NULL;
    - GtkWidget *sortmenu;
    const char *m = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/sort_type");
    - if ((gtkblist == NULL) || (gtkblist->ift == NULL))
    - return;
    -
    - g_return_if_fail(m != NULL);
    -
    - sortmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Sort Buddies"));
    -
    - if (sortmenu == NULL)
    + GtkRadioAction *action;
    + GString *ui_string;
    +
    + if ((gtkblist == NULL) || (gtkblist->ui == NULL))
    return;
    /* Clear the old menu */
    - for (l = gtk_container_get_children(GTK_CONTAINER(sortmenu)); l; l = g_list_delete_link(l, l)) {
    - menuitem = l->data;
    - gtk_widget_destroy(GTK_WIDGET(menuitem));
    - }
    + if (sort_action_group) {
    + gtk_ui_manager_remove_ui(gtkblist->ui, sort_merge_id);
    + gtk_ui_manager_remove_action_group(gtkblist->ui, sort_action_group);
    + g_object_unref(G_OBJECT(sort_action_group));
    + }
    +
    + sort_action_group = gtk_action_group_new("SortMethods");
    +#ifdef ENABLE_NLS
    + gtk_action_group_set_translation_domain(sort_action_group, PACKAGE);
    +#endif
    + ui_string = g_string_new("<ui><menubar name='BList'>"
    + "<menu action='BuddiesMenu'><menu action='SortMenu'>");
    for (l = pidgin_blist_sort_methods; l; l = l->next) {
    - method = (PidginBlistSortMethod *) l->data;
    - menuitem = gtk_radio_menu_item_new_with_label(sl, _(method->name));
    - if (g_str_equal(m, method->id))
    - activeitem = menuitem;
    - sl = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem));
    - gtk_menu_shell_append(GTK_MENU_SHELL(sortmenu), menuitem);
    - g_signal_connect(G_OBJECT(menuitem), "toggled",
    - G_CALLBACK(sortmethod_act), method->id);
    - gtk_widget_show(menuitem);
    - }
    - if (activeitem)
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(activeitem), TRUE);
    -}
    + method = (PidginBlistSortMethod *)l->data;
    +
    + g_string_append_printf(ui_string, "<menuitem action='%s'/>", method->id);
    + action = gtk_radio_action_new(method->id,
    + method->name,
    + NULL,
    + NULL,
    + 0);
    + gtk_action_group_add_action_with_accel(sort_action_group, GTK_ACTION(action), NULL);
    +
    + gtk_radio_action_set_group(action, sl);
    + sl = gtk_radio_action_get_group(action);
    +
    + if (!strcmp(m, method->id))
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE);
    + else
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), FALSE);
    +
    + g_signal_connect(G_OBJECT(action), "changed",
    + G_CALLBACK(sortmethod_act), method->id);
    + }
    +
    + g_string_append(ui_string, "</menu></menu></menubar></ui>");
    + gtk_ui_manager_insert_action_group(gtkblist->ui, sort_action_group, 1);
    + sort_merge_id = gtk_ui_manager_add_ui_from_string(gtkblist->ui, ui_string->str, -1, NULL);
    +
    + g_string_free(ui_string, TRUE);
    +}
    --- a/pidgin/gtkblist.h Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkblist.h Sun Dec 05 03:10:05 2010 +0000
    @@ -82,7 +82,7 @@
    GtkCellRenderer *text_rend;
    - GtkItemFactory *ift;
    + GtkUIManager *ui;
    GtkWidget *menutray; /**< The menu tray widget. */
    GtkWidget *menutrayicon; /**< The menu tray icon. */
    --- a/pidgin/gtkcellrendererexpander.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkcellrendererexpander.c Sun Dec 05 03:10:05 2010 +0000
    @@ -44,24 +44,23 @@
    static void pidgin_cell_renderer_expander_class_init (PidginCellRendererExpanderClass *class);
    static void pidgin_cell_renderer_expander_get_size (GtkCellRenderer *cell,
    GtkWidget *widget,
    - GdkRectangle *cell_area,
    + const GdkRectangle *cell_area,
    gint *x_offset,
    gint *y_offset,
    gint *width,
    gint *height);
    static void pidgin_cell_renderer_expander_render (GtkCellRenderer *cell,
    - GdkWindow *window,
    + cairo_t *cr,
    GtkWidget *widget,
    - GdkRectangle *background_area,
    - GdkRectangle *cell_area,
    - GdkRectangle *expose_area,
    - guint flags);
    + const GdkRectangle *background_area,
    + const GdkRectangle *cell_area,
    + GtkCellRendererState flags);
    static gboolean pidgin_cell_renderer_expander_activate (GtkCellRenderer *r,
    GdkEvent *event,
    GtkWidget *widget,
    const gchar *p,
    - GdkRectangle *bg,
    - GdkRectangle *cell,
    + const GdkRectangle *bg,
    + const GdkRectangle *cell,
    GtkCellRendererState flags);
    static void pidgin_cell_renderer_expander_finalize (GObject *gobject);
    @@ -108,9 +107,10 @@
    static void pidgin_cell_renderer_expander_init (PidginCellRendererExpander *cellexpander)
    {
    - GTK_CELL_RENDERER(cellexpander)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
    - GTK_CELL_RENDERER(cellexpander)->xpad = 0;
    - GTK_CELL_RENDERER(cellexpander)->ypad = 2;
    + g_object_set(G_OBJECT(cellexpander), "mode",
    + GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
    + /*GTK_CELL_RENDERER(cellexpander)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;*/
    + gtk_cell_renderer_set_padding(GTK_CELL_RENDERER(cellexpander), 0, 2);
    }
    static void pidgin_cell_renderer_expander_class_init (PidginCellRendererExpanderClass *class)
    @@ -190,7 +190,7 @@
    static void pidgin_cell_renderer_expander_get_size (GtkCellRenderer *cell,
    GtkWidget *widget,
    - GdkRectangle *cell_area,
    + const GdkRectangle *cell_area,
    gint *x_offset,
    gint *y_offset,
    gint *width,
    @@ -199,11 +199,17 @@
    gint calc_width;
    gint calc_height;
    gint expander_size;
    -
    + gint xpad;
    + gint ypad;
    + gfloat xalign;
    + gfloat yalign;
    +
    gtk_widget_style_get(widget, "expander-size", &expander_size, NULL);
    - calc_width = (gint) cell->xpad * 2 + expander_size;
    - calc_height = (gint) cell->ypad * 2 + expander_size;
    + gtk_cell_renderer_get_padding(cell, &xpad, &ypad);
    + gtk_cell_renderer_get_alignment(cell, &xalign, &yalign);
    + calc_width = (gint) xpad * 2 + expander_size;
    + calc_height = (gint) ypad * 2 + expander_size;
    if (width)
    *width = calc_width;
    @@ -215,12 +221,12 @@
    {
    if (x_offset)
    {
    - *x_offset = cell->xalign * (cell_area->width - calc_width);
    + *x_offset = xalign * (cell_area->width - calc_width);
    *x_offset = MAX (*x_offset, 0);
    }
    if (y_offset)
    {
    - *y_offset = cell->yalign * (cell_area->height - calc_height);
    + *y_offset = yalign * (cell_area->height - calc_height);
    *y_offset = MAX (*y_offset, 0);
    }
    }
    @@ -228,56 +234,64 @@
    static void pidgin_cell_renderer_expander_render(GtkCellRenderer *cell,
    - GdkWindow *window,
    + cairo_t *cr,
    GtkWidget *widget,
    - GdkRectangle *background_area,
    - GdkRectangle *cell_area,
    - GdkRectangle *expose_area,
    - guint flags)
    + const GdkRectangle *background_area,
    + const GdkRectangle *cell_area,
    + GtkCellRendererState flags)
    {
    PidginCellRendererExpander *cellexpander = (PidginCellRendererExpander *) cell;
    gboolean set;
    gint width, height;
    GtkStateType state;
    -
    + gint xpad;
    + gint ypad;
    + gboolean is_expanded;
    + GtkAllocation allocation;
    +
    + gtk_cell_renderer_get_padding(cell, &xpad, &ypad);
    + g_object_get(G_OBJECT(cell), "is-expanded", &is_expanded, NULL);
    +
    if (!cellexpander->is_expander)
    return;
    width = cell_area->width;
    height = cell_area->height;
    - if (!cell->sensitive)
    + if (!gtk_widget_get_sensitive(widget))
    state = GTK_STATE_INSENSITIVE;
    else if (flags & GTK_CELL_RENDERER_PRELIT)
    state = GTK_STATE_PRELIGHT;
    - else if (GTK_WIDGET_HAS_FOCUS (widget) && flags & GTK_CELL_RENDERER_SELECTED)
    + else if (gtk_widget_has_focus(widget) && flags & GTK_CELL_RENDERER_SELECTED)
    state = GTK_STATE_ACTIVE;
    else
    state = GTK_STATE_NORMAL;
    - width -= cell->xpad*2;
    - height -= cell->ypad*2;
    + width -= xpad*2;
    + height -= ypad*2;
    - gtk_paint_expander (widget->style,
    - window, state,
    - NULL, widget, "treeview",
    - cell_area->x + cell->xpad + (width / 2),
    - cell_area->y + cell->ypad + (height / 2),
    - cell->is_expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED);
    + gtk_paint_expander (gtk_widget_get_style(widget),
    + cr, state,
    + widget, "treeview",
    + cell_area->x + xpad + (width / 2),
    + cell_area->y + ypad + (height / 2),
    + is_expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED);
    /* only draw the line if the color isn't set - this prevents a bug where the hline appears only under the expander */
    g_object_get(cellexpander, "cell-background-set", &set, NULL);
    - if (cell->is_expanded && !set)
    - gtk_paint_hline (widget->style, window, state, NULL, widget, NULL, 0,
    - widget->allocation.width, cell_area->y + cell_area->height);
    + gtk_widget_get_allocation(widget, &allocation);
    +
    + if (is_expanded && !set)
    + gtk_paint_hline (gtk_widget_get_style(widget), cr, state, widget, NULL, 0,
    + allocation.width, cell_area->y + cell_area->height);
    }
    static gboolean pidgin_cell_renderer_expander_activate(GtkCellRenderer *r,
    GdkEvent *event,
    GtkWidget *widget,
    const gchar *p,
    - GdkRectangle *bg,
    - GdkRectangle *cell,
    + const GdkRectangle *bg,
    + const GdkRectangle *cell,
    GtkCellRendererState flags)
    {
    GtkTreePath *path = gtk_tree_path_new_from_string(p);
    --- a/pidgin/gtkconv.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkconv.c Sun Dec 05 03:10:05 2010 +0000
    @@ -160,7 +160,6 @@
    static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state);
    static void update_typing_icon(PidginConversation *gtkconv);
    static void update_typing_message(PidginConversation *gtkconv, const char *message);
    -static const char *item_factory_translate_func (const char *path, gpointer func_data);
    gboolean pidgin_conv_has_focus(PurpleConversation *conv);
    static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background);
    static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
    @@ -779,15 +778,17 @@
    InviteBuddyInfo *info = (InviteBuddyInfo *)data;
    const char *convprotocol;
    gboolean success = TRUE;
    -
    + GdkAtom target = gtk_selection_data_get_target(sd);
    +
    convprotocol = purple_account_get_protocol_id(purple_conversation_get_account(info->conv));
    - if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
    + if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
    {
    PurpleBlistNode *node = NULL;
    PurpleBuddy *buddy;
    -
    - memcpy(&node, sd->data, sizeof(node));
    + const guchar *data = gtk_selection_data_get_data(sd);
    +
    + memcpy(&node, data, sizeof(node));
    if (PURPLE_BLIST_NODE_IS_CONTACT(node))
    buddy = purple_contact_get_priority_buddy((PurpleContact *)node);
    @@ -806,15 +807,16 @@
    else
    gtk_entry_set_text(GTK_ENTRY(info->entry), purple_buddy_get_name(buddy));
    - gtk_drag_finish(dc, success, (dc->action == GDK_ACTION_MOVE), t);
    - }
    - else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE))
    + gtk_drag_finish(dc, success,
    + gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
    + }
    + else if (target == gdk_atom_intern("application/x-im-contact", FALSE))
    {
    char *protocol = NULL;
    char *username = NULL;
    PurpleAccount *account;
    - if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account,
    + if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account,
    &protocol, &username, NULL))
    {
    if (account == NULL)
    @@ -839,7 +841,8 @@
    g_free(username);
    g_free(protocol);
    - gtk_drag_finish(dc, success, (dc->action == GDK_ACTION_MOVE), t);
    + gtk_drag_finish(dc, success,
    + gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
    }
    }
    @@ -881,12 +884,15 @@
    GTK_RESPONSE_OK);
    gtk_container_set_border_width(GTK_CONTAINER(invite_dialog), PIDGIN_HIG_BOX_SPACE);
    gtk_window_set_resizable(GTK_WINDOW(invite_dialog), FALSE);
    + /* TODO: set no separator using GTK+ 3.0 */
    + /*
    gtk_dialog_set_has_separator(GTK_DIALOG(invite_dialog), FALSE);
    -
    + */
    +
    info->window = GTK_WIDGET(invite_dialog);
    /* Setup the outside spacing. */
    - vbox = GTK_DIALOG(invite_dialog)->vbox;
    + vbox = gtk_dialog_get_content_area(GTK_DIALOG(invite_dialog));
    gtk_box_set_spacing(GTK_BOX(vbox), PIDGIN_HIG_BORDER);
    gtk_container_set_border_width(GTK_CONTAINER(vbox), PIDGIN_HIG_BOX_SPACE);
    @@ -978,7 +984,7 @@
    }
    static void
    -menu_new_conv_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_new_conv_cb(GtkAction *action, gpointer data)
    {
    pidgin_dialogs_im();
    }
    @@ -1025,7 +1031,7 @@
    * plaintext v. HTML file.
    */
    static void
    -menu_save_as_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_save_as_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
    @@ -1055,7 +1061,7 @@
    }
    static void
    -menu_view_log_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_view_log_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PurpleConversation *conv;
    @@ -1079,10 +1085,12 @@
    gtkblist = pidgin_blist_get_default_gtk_blist();
    cursor = gdk_cursor_new(GDK_WATCH);
    - gdk_window_set_cursor(gtkblist->window->window, cursor);
    - gdk_window_set_cursor(win->window->window, cursor);
    + gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), cursor);
    + gdk_window_set_cursor(gtk_widget_get_window(win->window), cursor);
    gdk_cursor_unref(cursor);
    +#if GTK_CHECK_VERSION(2,4,0) && !GTK_CHECK_VERSION(2,6,0) //FIXME: What?
    gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(widget->window)));
    +#endif
    name = purple_conversation_get_name(conv);
    account = purple_conversation_get_account(conv);
    @@ -1095,8 +1103,8 @@
    {
    pidgin_log_show_contact((PurpleContact *)node->parent);
    g_slist_free(buddies);
    - gdk_window_set_cursor(gtkblist->window->window, NULL);
    - gdk_window_set_cursor(win->window->window, NULL);
    + gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), NULL);
    + gdk_window_set_cursor(gtk_widget_get_window(win->window), NULL);
    return;
    }
    }
    @@ -1104,12 +1112,12 @@
    pidgin_log_show(type, name, account);
    - gdk_window_set_cursor(gtkblist->window->window, NULL);
    - gdk_window_set_cursor(win->window->window, NULL);
    -}
    -
    -static void
    -menu_clear_cb(gpointer data, guint action, GtkWidget *widget)
    + gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), NULL);
    + gdk_window_set_cursor(gtk_widget_get_window(win->window), NULL);
    +}
    +
    +static void
    +menu_clear_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PurpleConversation *conv;
    @@ -1119,7 +1127,7 @@
    }
    static void
    -menu_find_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_find_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *gtkwin = data;
    PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(gtkwin);
    @@ -1129,7 +1137,7 @@
    #ifdef USE_VV
    static void
    -menu_initiate_media_call_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_initiate_media_call_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = (PidginWindow *)data;
    PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
    @@ -1137,15 +1145,15 @@
    purple_prpl_initiate_media(account,
    purple_conversation_get_name(conv),
    - action == 0 ? PURPLE_MEDIA_AUDIO :
    - action == 1 ? PURPLE_MEDIA_VIDEO :
    - action == 2 ? PURPLE_MEDIA_AUDIO |
    + action == win->audio_call ? PURPLE_MEDIA_AUDIO :
    + action == win->video_call ? PURPLE_MEDIA_VIDEO :
    + action == win->audio_video_call ? PURPLE_MEDIA_AUDIO |
    PURPLE_MEDIA_VIDEO : PURPLE_MEDIA_NONE);
    }
    #endif
    static void
    -menu_send_file_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_send_file_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
    @@ -1157,7 +1165,7 @@
    }
    static void
    -menu_get_attention_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_get_attention_cb(GtkAction *ation, gpointer data)
    {
    PidginWindow *win = data;
    PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
    @@ -1169,7 +1177,7 @@
    }
    static void
    -menu_add_pounce_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_add_pounce_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PurpleConversation *conv;
    @@ -1181,7 +1189,7 @@
    }
    static void
    -menu_insert_link_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_insert_link_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PidginConversation *gtkconv;
    @@ -1195,7 +1203,7 @@
    }
    static void
    -menu_insert_image_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_insert_image_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PidginConversation *gtkconv;
    @@ -1210,7 +1218,7 @@
    static void
    -menu_alias_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_alias_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PurpleConversation *conv;
    @@ -1237,7 +1245,7 @@
    }
    static void
    -menu_get_info_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_get_info_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PurpleConversation *conv;
    @@ -1248,7 +1256,7 @@
    }
    static void
    -menu_invite_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_invite_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PurpleConversation *conv;
    @@ -1259,7 +1267,7 @@
    }
    static void
    -menu_block_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_block_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PurpleConversation *conv;
    @@ -1270,7 +1278,7 @@
    }
    static void
    -menu_unblock_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_unblock_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PurpleConversation *conv;
    @@ -1281,7 +1289,7 @@
    }
    static void
    -menu_add_remove_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_add_remove_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PurpleConversation *conv;
    @@ -1326,7 +1334,7 @@
    }
    static void
    -menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_close_conv_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    @@ -1334,7 +1342,7 @@
    }
    static void
    -menu_logging_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_logging_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PurpleConversation *conv;
    @@ -1346,7 +1354,7 @@
    if (conv == NULL)
    return;
    - logging = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
    + logging = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
    if (logging == purple_conversation_is_logging(conv))
    return;
    @@ -1399,14 +1407,14 @@
    }
    static void
    -menu_toolbar_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_toolbar_cb(GtkAction *action, gpointer data)
    {
    purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar",
    - gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)));
    -}
    -
    -static void
    -menu_sounds_cb(gpointer data, guint action, GtkWidget *widget)
    + gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)));
    +}
    +
    +static void
    +menu_sounds_cb(GtkAction *action, gpointer data)
    {
    PidginWindow *win = data;
    PurpleConversation *conv;
    @@ -1421,17 +1429,17 @@
    gtkconv = PIDGIN_CONVERSATION(conv);
    gtkconv->make_sound =
    - gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
    + gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
    node = get_conversation_blist_node(conv);
    if (node)
    purple_blist_node_set_bool(node, "gtk-mute-sound", !gtkconv->make_sound);
    }
    static void
    -menu_timestamps_cb(gpointer data, guint action, GtkWidget *widget)
    +menu_timestamps_cb(GtkAction *action, gpointer data)
    {
    purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps",
    - gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)));
    + gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)));
    }
    static void
    @@ -1918,7 +1926,7 @@
    /* If CTRL was held down... */
    if (event->state & GDK_CONTROL_MASK) {
    switch (event->keyval) {
    - case GDK_Page_Down:
    + case GDK_KEY_Page_Down:
    case ']':
    if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv + 1))
    gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0);
    @@ -1927,7 +1935,7 @@
    return TRUE;
    break;
    - case GDK_Page_Up:
    + case GDK_KEY_Page_Up:
    case '[':
    if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv - 1))
    gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), -1);
    @@ -1936,9 +1944,9 @@
    return TRUE;
    break;
    - case GDK_Tab:
    - case GDK_KP_Tab:
    - case GDK_ISO_Left_Tab:
    + case GDK_KEY_Tab:
    + case GDK_KEY_KP_Tab:
    + case GDK_KEY_ISO_Left_Tab:
    if (event->state & GDK_SHIFT_MASK) {
    move_to_next_unread_tab(gtkconv, FALSE);
    } else {
    @@ -1948,20 +1956,20 @@
    return TRUE;
    break;
    - case GDK_comma:
    + case GDK_KEY_comma:
    gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook),
    gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv),
    curconv - 1);
    return TRUE;
    break;
    - case GDK_period:
    + case GDK_KEY_period:
    gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook),
    gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv),
    (curconv + 1) % gtk_notebook_get_n_pages(GTK_NOTEBOOK(win->notebook)));
    return TRUE;
    break;
    - case GDK_F6:
    + case GDK_KEY_F6:
    if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD))
    return TRUE;
    break;
    @@ -1985,13 +1993,13 @@
    else
    {
    switch (event->keyval) {
    - case GDK_F2:
    + case GDK_KEY_F2:
    if (gtk_widget_is_focus(GTK_WIDGET(win->notebook))) {
    infopane_entry_activate(gtkconv);
    return TRUE;
    }
    break;
    - case GDK_F6:
    + case GDK_KEY_F6:
    if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD))
    return TRUE;
    break;
    @@ -2015,7 +2023,7 @@
    /* If CTRL was held down... */
    if (event->state & GDK_CONTROL_MASK) {
    switch (event->keyval) {
    - case GDK_Up:
    + case GDK_KEY_Up:
    if (!gtkconv->send_history)
    break;
    @@ -2066,7 +2074,7 @@
    return TRUE;
    break;
    - case GDK_Down:
    + case GDK_KEY_Down:
    if (!gtkconv->send_history)
    break;
    @@ -2119,20 +2127,20 @@
    /* If neither CTRL nor ALT were held down... */
    else {
    switch (event->keyval) {
    - case GDK_Tab:
    - case GDK_KP_Tab:
    - case GDK_ISO_Left_Tab:
    + case GDK_KEY_Tab:
    + case GDK_KEY_KP_Tab:
    + case GDK_KEY_ISO_Left_Tab:
    if (gtkconv->entry != entry)
    break;
    return tab_complete(conv);
    break;
    - case GDK_Page_Up:
    + case GDK_KEY_Page_Up:
    gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml));
    return TRUE;
    break;
    - case GDK_Page_Down:
    + case GDK_KEY_Page_Down:
    gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml));
    return TRUE;
    break;
    @@ -2176,24 +2184,24 @@
    /* If we have a valid key for the conversation display, then exit */
    if ((event->state & GDK_CONTROL_MASK) ||
    - (event->keyval == GDK_F6) ||
    - (event->keyval == GDK_F10) ||
    - (event->keyval == GDK_Shift_L) ||
    - (event->keyval == GDK_Shift_R) ||
    - (event->keyval == GDK_Control_L) ||
    - (event->keyval == GDK_Control_R) ||
    - (event->keyval == GDK_Escape) ||
    - (event->keyval == GDK_Up) ||
    - (event->keyval == GDK_Down) ||
    - (event->keyval == GDK_Left) ||
    - (event->keyval == GDK_Right) ||
    - (event->keyval == GDK_Page_Up) ||
    - (event->keyval == GDK_Page_Down) ||
    - (event->keyval == GDK_Home) ||
    - (event->keyval == GDK_End) ||
    - (event->keyval == GDK_Tab) ||
    - (event->keyval == GDK_KP_Tab) ||
    - (event->keyval == GDK_ISO_Left_Tab))
    + (event->keyval == GDK_KEY_F6) ||
    + (event->keyval == GDK_KEY_F10) ||
    + (event->keyval == GDK_KEY_Shift_L) ||
    + (event->keyval == GDK_KEY_Shift_R) ||
    + (event->keyval == GDK_KEY_Control_L) ||
    + (event->keyval == GDK_KEY_Control_R) ||
    + (event->keyval == GDK_KEY_Escape) ||
    + (event->keyval == GDK_KEY_Up) ||
    + (event->keyval == GDK_KEY_Down) ||
    + (event->keyval == GDK_KEY_Left) ||
    + (event->keyval == GDK_KEY_Right) ||
    + (event->keyval == GDK_KEY_Page_Up) ||
    + (event->keyval == GDK_KEY_Page_Down) ||
    + (event->keyval == GDK_KEY_Home) ||
    + (event->keyval == GDK_KEY_End) ||
    + (event->keyval == GDK_KEY_Tab) ||
    + (event->keyval == GDK_KEY_KP_Tab) ||
    + (event->keyval == GDK_KEY_ISO_Left_Tab))
    {
    if (event->type == GDK_KEY_PRESS)
    return conv_keypress_common(gtkconv, event);
    @@ -2236,7 +2244,7 @@
    gtkconv->active_conv = conv;
    purple_conversation_set_logging(conv,
    - gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging)));
    + gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging)));
    entry = GTK_IMHTML(gtkconv->entry);
    protocol_name = purple_account_get_protocol_name(conv->account);
    @@ -2661,7 +2669,7 @@
    }
    static void
    -start_anim(GtkObject *obj, PidginConversation *gtkconv)
    +start_anim(GtkWidget *widget, PidginConversation *gtkconv)
    {
    int delay;
    @@ -2834,7 +2842,7 @@
    }
    static void
    -stop_anim(GtkObject *obj, PidginConversation *gtkconv)
    +stop_anim(GtkWidget *widget, PidginConversation *gtkconv)
    {
    if (gtkconv->u.im->icon_timer != 0)
    g_source_remove(gtkconv->u.im->icon_timer);
    @@ -2856,7 +2864,7 @@
    }
    static gboolean
    -icon_menu(GtkObject *obj, GdkEventButton *e, PidginConversation *gtkconv)
    +icon_menu(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv)
    {
    static GtkWidget *menu = NULL;
    PurpleConversation *conv;
    @@ -3050,6 +3058,101 @@
    return gtkconv->win;
    }
    +#if 1
    +
    +static GtkActionEntry menu_entries[] =
    +/* TODO: fill out tooltips... */
    +{
    + /* Conversation menu */
    + { "ConversationMenu", NULL, N_("_Conversation"), NULL, NULL, NULL },
    + { "NewInstantMessage", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("New Instant _Message..."), "<control>M", NULL, G_CALLBACK(menu_new_conv_cb) },
    + { "Find", GTK_STOCK_FIND, N_("_Find..."), NULL, NULL, G_CALLBACK(menu_find_cb) },
    + { "ViewLog", NULL, N_("View _Log"), NULL, NULL, G_CALLBACK(menu_view_log_cb) },
    + { "SaveAs", GTK_STOCK_SAVE_AS, N_("_Save As..."), NULL, NULL, G_CALLBACK(menu_save_as_cb) },
    + { "ClearScrollback", GTK_STOCK_CLEAR, N_("Clea_r Scrollback"), "<control>L", NULL, G_CALLBACK(menu_clear_cb) },
    +
    +#ifdef USE_VV
    + { "MediaMenu", NULL, N_("M_edia"), NULL, NULL, NULL },
    + { "AudioCall", PIDGIN_STOCK_TOOLBAR_AUDIO_CALL, N_("_Audio Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
    + { "VideoCall", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL, N_("_Video Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
    + { "AudioVideoCall", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL, N_("Audio\\/Video _Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
    +#endif
    +
    + { "SendFile", PIDGIN_STOCK_TOOLBAR_SEND_FILE, N_("Se_nd File..."), NULL, NULL, G_CALLBACK(menu_send_file_cb) },
    + { "GetAttention", PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION, N_("Get _Attention"), NULL, NULL, G_CALLBACK(menu_get_attention_cb) },
    + { "AddBuddyPounce", NULL, N_("Add Buddy _Pounce..."), NULL, NULL, G_CALLBACK(menu_add_pounce_cb) },
    + { "GetInfo", PIDGIN_STOCK_TOOLBAR_USER_INFO, N_("_Get Info"), "<control>O", NULL, G_CALLBACK(menu_get_info_cb) },
    + { "Invite", NULL, N_("In_vite..."), NULL, NULL, G_CALLBACK(menu_invite_cb) },
    + { "MoreMenu", NULL, N_("M_ore"), NULL, NULL, NULL },
    + { "Alias", NULL, N_("Al_ias..."), NULL, NULL, G_CALLBACK(menu_alias_cb) },
    + { "Block", PIDGIN_STOCK_TOOLBAR_BLOCK, N_("_Block..."), NULL, NULL, G_CALLBACK(menu_block_cb) },
    + { "Unblock", PIDGIN_STOCK_TOOLBAR_UNBLOCK, N_("_Unblock..."), NULL, NULL, G_CALLBACK(menu_unblock_cb) },
    + { "Add", GTK_STOCK_ADD, N_("_Add..."), NULL, NULL, G_CALLBACK(menu_add_remove_cb) },
    + { "Remove", GTK_STOCK_REMOVE, N_("_Remove..."), NULL, NULL, G_CALLBACK(menu_add_remove_cb) },
    + { "InsertLink", PIDGIN_STOCK_TOOLBAR_INSERT_LINK, N_("Insert Lin_k..."), NULL, NULL, G_CALLBACK(menu_insert_link_cb) },
    + { "InsertImage", PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, N_("Insert Imag_e..."), NULL, NULL, G_CALLBACK(menu_insert_image_cb) },
    + { "Close", GTK_STOCK_CLOSE, N_("_Close"), NULL, NULL, G_CALLBACK(menu_close_conv_cb) },
    +
    + /* Options */
    + { "OptionsMenu", NULL, N_("_Options"), NULL, NULL, NULL },
    +};
    +
    +/* Toggle items */
    +static const GtkToggleActionEntry menu_toggle_entries[] = {
    + { "EnableLogging", NULL, N_("Enable _Logging"), NULL, NULL, G_CALLBACK(menu_logging_cb), FALSE },
    + { "EnableSounds", NULL, N_("Enable _Sounds"), NULL, NULL, G_CALLBACK(menu_sounds_cb), FALSE },
    + { "ShowFormattingToolbars", NULL, N_("Show Formatting _Toolbars"), NULL, NULL, G_CALLBACK(menu_toolbar_cb), FALSE },
    + { "ShowTimestamps", NULL, N_("Show Ti_mestamps"), NULL, NULL, G_CALLBACK(menu_timestamps_cb), FALSE },
    +};
    +
    +static const char *conversation_menu =
    +"<ui>"
    + "<menubar name='Conversation'>"
    + "<menu action='ConversationMenu'>"
    + "<menuitem action='NewInstantMessage'/>"
    + "<separator/>"
    + "<menuitem action='Find'/>"
    + "<menuitem action='ViewLog'/>"
    + "<menuitem action='SaveAs'/>"
    + "<menuitem action='ClearScrollback'/>"
    + "<separator/>"
    +#ifdef USE_VV
    + "<menu action='MediaMenu'>"
    + "<menuitem action='AudioCall'/>"
    + "<menuitem action='VideoCall'/>"
    + "<menuitem action='AudioVideoCall'/>"
    + "</menu>"
    +#endif
    + "<menuitem action='SendFile'/>"
    + "<menuitem action='GetAttention'/>"
    + "<menuitem action='AddBuddyPounce'/>"
    + "<menuitem action='GetInfo'/>"
    + "<menuitem action='Invite'/>"
    + "<menu action='MoreMenu'/>"
    + "<separator/>"
    + "<menuitem action='Alias'/>"
    + "<menuitem action='Block'/>"
    + "<menuitem action='Unblock'/>"
    + "<menuitem action='Add'/>"
    + "<menuitem action='Remove'/>"
    + "<separator/>"
    + "<menuitem action='InsertLink'/>"
    + "<menuitem action='InsertImage'/>"
    + "<separator/>"
    + "<menuitem action='Close'/>"
    + "</menu>"
    + "<menu action='OptionsMenu'>"
    + "<menuitem action='EnableLogging'/>"
    + "<menuitem action='EnableSounds'/>"
    + "<separator/>"
    + "<menuitem action='ShowFormattingToolbars'/>"
    + "<menuitem action='ShowTimestamps'/>"
    + "</menu>"
    + "</menubar>"
    +"</ui>";
    +
    +#else
    +
    static GtkItemFactoryEntry menu_items[] =
    {
    /* Conversation menu */
    @@ -3126,15 +3229,7 @@
    { N_("/Options/Show Formatting _Toolbars"), NULL, menu_toolbar_cb, 0, "<CheckItem>", NULL },
    { N_("/Options/Show Ti_mestamps"), NULL, menu_timestamps_cb, 0, "<CheckItem>", NULL },
    };
    -
    -static const int menu_item_count =
    -sizeof(menu_items) / sizeof(*menu_items);
    -
    -static const char *
    -item_factory_translate_func (const char *path, gpointer func_data)
    -{
    - return _(path);
    -}
    +#endif
    static void
    sound_method_pref_changed_cb(const char *name, PurplePrefType type,
    @@ -3145,19 +3240,18 @@
    if (!strcmp(method, "none"))
    {
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds),
    - FALSE);
    - gtk_widget_set_sensitive(win->menu.sounds, FALSE);
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
    + FALSE);
    + gtk_action_set_sensitive(win->menu.sounds, FALSE);
    }
    else
    {
    PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win);
    if (gtkconv != NULL)
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds),
    - gtkconv->make_sound);
    - gtk_widget_set_sensitive(win->menu.sounds, TRUE);
    -
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
    + gtkconv->make_sound);
    + gtk_action_set_sensitive(win->menu.sounds, TRUE);
    }
    }
    @@ -3285,25 +3379,25 @@
    purple_prpl_get_media_caps(account,
    purple_conversation_get_name(conv));
    - gtk_widget_set_sensitive(win->audio_call,
    + gtk_action_set_sensitive(win->audio_call,
    caps & PURPLE_MEDIA_CAPS_AUDIO
    ? TRUE : FALSE);
    - gtk_widget_set_sensitive(win->video_call,
    + gtk_action_set_sensitive(win->video_call,
    caps & PURPLE_MEDIA_CAPS_VIDEO
    ? TRUE : FALSE);
    - gtk_widget_set_sensitive(win->audio_video_call,
    + gtk_action_set_sensitive(win->audio_video_call,
    caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO
    ? TRUE : FALSE);
    } else if (purple_conversation_get_type(conv)
    == PURPLE_CONV_TYPE_CHAT) {
    /* for now, don't care about chats... */
    - gtk_widget_set_sensitive(win->audio_call, FALSE);
    - gtk_widget_set_sensitive(win->video_call, FALSE);
    - gtk_widget_set_sensitive(win->audio_video_call, FALSE);
    + gtk_action_set_sensitive(win->audio_call, FALSE);
    + gtk_action_set_sensitive(win->video_call, FALSE);
    + gtk_action_set_sensitive(win->audio_video_call, FALSE);
    } else {
    - gtk_widget_set_sensitive(win->audio_call, FALSE);
    - gtk_widget_set_sensitive(win->video_call, FALSE);
    - gtk_widget_set_sensitive(win->audio_video_call, FALSE);
    + gtk_action_set_sensitive(win->audio_call, FALSE);
    + gtk_action_set_sensitive(win->video_call, FALSE);
    + gtk_action_set_sensitive(win->audio_video_call, FALSE);
    }
    #endif
    }
    @@ -3311,6 +3405,8 @@
    static void
    regenerate_options_items(PidginWindow *win)
    {
    +#if GTK_CHECK_VERSION(2,6,0)
    +#else
    GtkWidget *menu;
    PidginConversation *gtkconv;
    GList *list;
    @@ -3334,6 +3430,7 @@
    }
    gtk_widget_show_all(menu);
    +#endif
    }
    static void
    @@ -3347,6 +3444,8 @@
    static void
    regenerate_plugins_items(PidginWindow *win)
    {
    +#if GTK_CHECK_VERSION(2,6,0)
    +#else
    GList *action_items;
    GtkWidget *menu;
    GList *list;
    @@ -3388,8 +3487,10 @@
    g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win);
    }
    g_object_set_data(G_OBJECT(win->window), "plugin-actions", action_items);
    -}
    -
    +#endif
    +}
    +
    +#if 0
    static void menubar_activated(GtkWidget *item, gpointer data)
    {
    PidginWindow *win = data;
    @@ -3413,134 +3514,145 @@
    g_signal_handlers_disconnect_by_func(G_OBJECT(win->menu.menubar),
    G_CALLBACK(focus_out_from_menubar), win);
    }
    +#endif
    static GtkWidget *
    setup_menubar(PidginWindow *win)
    {
    GtkAccelGroup *accel_group;
    const char *method;
    - GtkWidget *menuitem;
    -
    - accel_group = gtk_accel_group_new ();
    + GtkActionGroup *action_group;
    + GError *error;
    +
    + action_group = gtk_action_group_new("ConversationActions");
    + gtk_action_group_add_actions(action_group,
    + menu_entries,
    + G_N_ELEMENTS(menu_entries),
    + win);
    + gtk_action_group_add_toggle_actions(action_group,
    + menu_toggle_entries,
    + G_N_ELEMENTS(menu_toggle_entries),
    + win);
    +#ifdef ENABLE_NLS
    + gtk_action_group_set_translation_domain(action_group,
    + PACKAGE);
    +#endif
    +
    + win->menu.ui = gtk_ui_manager_new();
    + gtk_ui_manager_insert_action_group(win->menu.ui, action_group, 0);
    +
    + accel_group = gtk_ui_manager_get_accel_group(win->menu.ui);
    gtk_window_add_accel_group(GTK_WINDOW(win->window), accel_group);
    - g_object_unref(accel_group);
    -
    - win->menu.item_factory =
    - gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
    -
    - gtk_item_factory_set_translate_func(win->menu.item_factory,
    - (GtkTranslateFunc)item_factory_translate_func,
    - NULL, NULL);
    -
    - gtk_item_factory_create_items(win->menu.item_factory, menu_item_count,
    - menu_items, win);
    g_signal_connect(G_OBJECT(accel_group), "accel-changed",
    G_CALLBACK(pidgin_save_accels_cb), NULL);
    - /* Make sure the 'Conversation -> More' menuitems are regenerated whenever
    - * the 'Conversation' menu pops up because the entries can change after the
    - * conversation is created. */
    - menuitem = gtk_item_factory_get_item(win->menu.item_factory, N_("/Conversation"));
    - g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menubar_activated), win);
    + error = NULL;
    + if (!gtk_ui_manager_add_ui_from_string(win->menu.ui, conversation_menu, -1, &error))
    + {
    + g_message("building menus failed: %s", error->message);
    + g_error_free(error);
    + exit(EXIT_FAILURE);
    + }
    win->menu.menubar =
    - gtk_item_factory_get_widget(win->menu.item_factory, "<main>");
    + gtk_ui_manager_get_widget(win->menu.ui, "/Conversation");
    win->menu.view_log =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/View Log"));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/ViewLog");
    #ifdef USE_VV
    win->audio_call =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Media/Audio Call"));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/MediaMenu/AudioCall");
    win->video_call =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Media/Video Call"));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/MediaMenu/VideoCall");
    win->audio_video_call =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Media/Audio\\/Video Call"));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/MediaMenu/AudioVideoCall");
    #endif
    /* --- */
    win->menu.send_file =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Send File..."));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/SendFile");
    g_object_set_data(G_OBJECT(win->window), "get_attention",
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Get Attention")));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/GetAttention"));
    +
    win->menu.add_pounce =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Add Buddy Pounce..."));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/AddBuddyPounce");
    /* --- */
    win->menu.get_info =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Get Info"));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/GetInfo");
    win->menu.invite =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Invite..."));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/Invite");
    /* --- */
    win->menu.alias =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Alias..."));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/Alias");
    win->menu.block =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Block..."));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/Block");
    win->menu.unblock =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Unblock..."));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/Unblock");
    win->menu.add =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Add..."));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/Add");
    win->menu.remove =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Remove..."));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/Remove");
    /* --- */
    win->menu.insert_link =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Insert Link..."));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/InsertLink");
    win->menu.insert_image =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Conversation/Insert Image..."));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/ConversationMenu/InsertImage");
    /* --- */
    win->menu.logging =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Options/Enable Logging"));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/OptionsMenu/EnableLogging");
    win->menu.sounds =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Options/Enable Sounds"));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/OptionsMenu/EnableSounds");
    method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
    if (method != NULL && !strcmp(method, "none"))
    {
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds),
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
    FALSE);
    - gtk_widget_set_sensitive(win->menu.sounds, FALSE);
    + gtk_action_set_sensitive(win->menu.sounds, FALSE);
    }
    purple_prefs_connect_callback(win, PIDGIN_PREFS_ROOT "/sound/method",
    sound_method_pref_changed_cb, win);
    win->menu.show_formatting_toolbar =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Options/Show Formatting Toolbars"));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/OptionsMenu/ShowFormattingToolbars");
    win->menu.show_timestamps =
    - gtk_item_factory_get_widget(win->menu.item_factory,
    - N_("/Options/Show Timestamps"));
    + gtk_ui_manager_get_action(win->menu.ui,
    + "/Conversation/OptionsMenu/ShowTimestamps");
    win->menu.show_icon = NULL;
    win->menu.tray = pidgin_menu_tray_new();
    @@ -3721,7 +3833,7 @@
    if (!(b = purple_find_buddy(account, conv->name)))
    return FALSE;
    -
    +#if 0 /* TODO */
    gtk_widget_show(win->menu.send_to);
    menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(win->menu.send_to));
    @@ -3743,6 +3855,7 @@
    break;
    }
    }
    +#endif
    return FALSE;
    }
    @@ -3852,6 +3965,7 @@
    static void
    generate_send_to_items(PidginWindow *win)
    {
    +#if 0 /* TODO */
    GtkWidget *menu;
    GSList *group = NULL;
    GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
    @@ -3936,6 +4050,7 @@
    if (!group)
    gtk_widget_set_sensitive(win->menu.send_to, FALSE);
    update_send_to_selection(win);
    +#endif
    }
    static const char *
    @@ -4554,13 +4669,22 @@
    GdkRectangle oneline;
    int height, diff;
    int pad_top, pad_inside, pad_bottom;
    - int total_height = (gtkconv->imhtml->allocation.height + gtkconv->entry->allocation.height);
    - int max_height = total_height / 2;
    + int total_height;
    + int max_height;
    int min_lines = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines");
    int min_height;
    gboolean interior_focus;
    int focus_width;
    -
    + GtkAllocation imhtml_allocation;
    + GtkAllocation entry_allocation;
    + GtkAllocation lower_hbox_allocation;
    +
    + gtk_widget_get_allocation(gtkconv->imhtml, &imhtml_allocation);
    + gtk_widget_get_allocation(gtkconv->entry, &entry_allocation);
    + gtk_widget_get_allocation(gtkconv->lower_hbox, &lower_hbox_allocation);
    + total_height = imhtml_allocation.height + entry_allocation.height;
    + max_height = total_height / 2;
    +
    pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry));
    pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry));
    pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(gtkconv->entry));
    @@ -4593,12 +4717,15 @@
    if (!interior_focus)
    height += 2 * focus_width;
    - diff = height - gtkconv->entry->allocation.height;
    + diff = height - entry_allocation.height;
    if (ABS(diff) < oneline.height / 2)
    return FALSE;
    + purple_debug_info("pidgin", "resizing to %d, %d lines, diff %d\n",
    + diff + lower_hbox_allocation.height, min_lines, diff);
    +
    gtk_widget_set_size_request(gtkconv->lower_hbox, -1,
    - diff + gtkconv->lower_hbox->allocation.height);
    + diff + lower_hbox_allocation.height);
    return FALSE;
    }
    @@ -4645,7 +4772,7 @@
    if(prpl_info->set_chat_topic == NULL) {
    gtk_editable_set_editable(GTK_EDITABLE(gtkchat->topic_text), FALSE);
    } else {
    - g_signal_connect(GTK_OBJECT(gtkchat->topic_text), "activate",
    + g_signal_connect(GTK_WIDGET(gtkchat->topic_text), "activate",
    G_CALLBACK(topic_callback), gtkconv);
    }
    @@ -4820,7 +4947,7 @@
    gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL);
    gtk_imhtml_search_clear(GTK_IMHTML(gtkconv->imhtml));
    - gtk_widget_hide_all(gtkconv->quickfind.container);
    + gtk_widget_hide(gtkconv->quickfind.container);
    gtk_widget_grab_focus(gtkconv->entry);
    return TRUE;
    @@ -4830,8 +4957,8 @@
    quickfind_process_input(GtkWidget *entry, GdkEventKey *event, PidginConversation *gtkconv)
    {
    switch (event->keyval) {
    - case GDK_Return:
    - case GDK_KP_Enter:
    + case GDK_KEY_Return:
    + case GDK_KEY_KP_Enter:
    if (gtk_imhtml_search_find(GTK_IMHTML(gtkconv->imhtml), gtk_entry_get_text(GTK_ENTRY(entry)))) {
    gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL);
    } else {
    @@ -4842,7 +4969,7 @@
    gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, &col);
    }
    break;
    - case GDK_Escape:
    + case GDK_KEY_Escape:
    pidgin_conv_end_quickfind(gtkconv);
    break;
    default:
    @@ -4861,8 +4988,12 @@
    close = pidgin_create_small_button(gtk_label_new("×"));
    gtk_box_pack_start(GTK_BOX(widget), close, FALSE, FALSE, 0);
    +#if GTK_CHECK_VERSION(2,12,0)
    + gtk_widget_set_tooltip_text(close, _("Close Find bar"));
    +#else
    gtk_tooltips_set_tip(gtkconv->tooltips, close,
    _("Close Find bar"), NULL);
    +#endif
    label = gtk_label_new(_("Find:"));
    gtk_box_pack_start(GTK_BOX(widget), label, FALSE, FALSE, 10);
    @@ -5081,8 +5212,10 @@
    PurpleAccount *convaccount = purple_conversation_get_account(conv);
    PurpleConnection *gc = purple_account_get_connection(convaccount);
    PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl) : NULL;
    -
    - if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
    + GdkAtom target = gtk_selection_data_get_target(sd);
    + const guchar *data = gtk_selection_data_get_data(sd);
    +
    + if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
    {
    PurpleBlistNode *n = NULL;
    PurpleBuddy *b;
    @@ -5090,7 +5223,7 @@
    PurpleAccount *buddyaccount;
    const char *buddyname;
    - n = *(PurpleBlistNode **)sd->data;
    + n = *(PurpleBlistNode **) data;
    if (PURPLE_BLIST_NODE_IS_CONTACT(n))
    b = purple_contact_get_priority_buddy((PurpleContact*)n);
    @@ -5138,16 +5271,17 @@
    pidgin_conv_window_switch_gtkconv(win, gtkconv);
    }
    - gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
    - }
    - else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE))
    + gtk_drag_finish(dc, TRUE,
    + gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
    + }
    + else if (target == gdk_atom_intern("application/x-im-contact", FALSE))
    {
    char *protocol = NULL;
    char *username = NULL;
    PurpleAccount *account;
    PidginConversation *gtkconv;
    - if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account,
    + if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account,
    &protocol, &username, NULL))
    {
    if (account == NULL)
    @@ -5178,12 +5312,14 @@
    g_free(username);
    g_free(protocol);
    - gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
    - }
    - else if (sd->target == gdk_atom_intern("text/uri-list", FALSE)) {
    + gtk_drag_finish(dc, TRUE,
    + gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
    + }
    + else if (target == gdk_atom_intern("text/uri-list", FALSE)) {
    if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
    pidgin_dnd_file_manage(sd, convaccount, purple_conversation_get_name(conv));
    - gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
    + gtk_drag_finish(dc, TRUE,
    + gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
    }
    else
    gtk_drag_finish(dc, FALSE, FALSE, t);
    @@ -5318,7 +5454,9 @@
    gtkconv->send_history = g_list_append(NULL, NULL);
    /* Setup some initial variables. */
    +#if !GTK_CHECK_VERSION(2,12,0)
    gtkconv->tooltips = gtk_tooltips_new();
    +#endif
    gtkconv->unseen_state = PIDGIN_UNSEEN_NONE;
    gtkconv->unseen_count = 0;
    @@ -5521,7 +5659,9 @@
    g_free(gtkconv->u.chat);
    }
    +#if !GTK_CHECK_VERSION(2,12,0)
    gtk_object_sink(GTK_OBJECT(gtkconv->tooltips));
    +#endif
    gtkconv->send_history = g_list_first(gtkconv->send_history);
    g_list_foreach(gtkconv->send_history, (GFunc)g_free, NULL);
    @@ -5585,21 +5725,28 @@
    GdkEventButton *btn_event = (GdkEventButton*) event;
    PurpleConversation *conv = data;
    char *buddyname;
    -
    + gchar *name;
    +
    + g_object_get(G_OBJECT(tag), "name", &name, NULL);
    +
    /* strlen("BUDDY " or "HILIT ") == 6 */
    - g_return_val_if_fail((tag->name != NULL)
    - && (strlen(tag->name) > 6), FALSE);
    -
    - buddyname = (tag->name) + 6;
    -
    + g_return_val_if_fail((name != NULL) && (strlen(name) > 6), FALSE);
    +
    + buddyname = name + 6;
    +
    +
    if (btn_event->button == 1 &&
    event->type == GDK_2BUTTON_PRESS) {
    chat_do_im(PIDGIN_CONVERSATION(conv), buddyname);
    + g_free(name);
    +
    return TRUE;
    } else if (btn_event->button == 2
    && event->type == GDK_2BUTTON_PRESS) {
    chat_do_info(PIDGIN_CONVERSATION(conv), buddyname);
    + g_free(name);
    +
    return TRUE;
    } else if (btn_event->button == 3
    && event->type == GDK_BUTTON_PRESS) {
    @@ -5621,10 +5768,14 @@
    btn_event->button,
    btn_event->time);
    + g_free(name);
    +
    /* Don't propagate the event any further */
    return TRUE;
    }
    }
    +
    + g_free(name);
    }
    return FALSE;
    @@ -6466,57 +6617,57 @@
    /* Show stuff that applies to IMs, hide stuff that applies to chats */
    /* Deal with menu items */
    - gtk_widget_show(win->menu.view_log);
    - gtk_widget_show(win->menu.send_file);
    - gtk_widget_show(g_object_get_data(G_OBJECT(win->window), "get_attention"));
    - gtk_widget_show(win->menu.add_pounce);
    - gtk_widget_show(win->menu.get_info);
    - gtk_widget_hide(win->menu.invite);
    - gtk_widget_show(win->menu.alias);
    + gtk_action_set_visible(win->menu.view_log, TRUE);
    + gtk_action_set_visible(win->menu.send_file, TRUE);
    + gtk_action_set_visible(GTK_ACTION(g_object_get_data(G_OBJECT(win->window), "get_attention")), TRUE);
    + gtk_action_set_visible(win->menu.add_pounce, TRUE);
    + gtk_action_set_visible(win->menu.get_info, TRUE);
    + gtk_action_set_visible(win->menu.invite, FALSE);
    + gtk_action_set_visible(win->menu.alias, TRUE);
    if (purple_privacy_check(account, purple_conversation_get_name(conv))) {
    - gtk_widget_hide(win->menu.unblock);
    - gtk_widget_show(win->menu.block);
    + gtk_action_set_visible(win->menu.unblock, FALSE);
    + gtk_action_set_visible(win->menu.block, TRUE);
    } else {
    - gtk_widget_hide(win->menu.block);
    - gtk_widget_show(win->menu.unblock);
    + gtk_action_set_visible(win->menu.block, FALSE);
    + gtk_action_set_visible(win->menu.unblock, TRUE);
    }
    if ((account == NULL) || purple_find_buddy(account, purple_conversation_get_name(conv)) == NULL) {
    - gtk_widget_show(win->menu.add);
    - gtk_widget_hide(win->menu.remove);
    + gtk_action_set_visible(win->menu.add, TRUE);
    + gtk_action_set_visible(win->menu.remove, FALSE);
    } else {
    - gtk_widget_show(win->menu.remove);
    - gtk_widget_hide(win->menu.add);
    - }
    -
    - gtk_widget_show(win->menu.insert_link);
    - gtk_widget_show(win->menu.insert_image);
    + gtk_action_set_visible(win->menu.remove, TRUE);
    + gtk_action_set_visible(win->menu.add, FALSE);
    + }
    +
    + gtk_action_set_visible(win->menu.insert_link, TRUE);
    + gtk_action_set_visible(win->menu.insert_image, TRUE);
    } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
    /* Show stuff that applies to Chats, hide stuff that applies to IMs */
    /* Deal with menu items */
    - gtk_widget_show(win->menu.view_log);
    - gtk_widget_hide(win->menu.send_file);
    - gtk_widget_hide(g_object_get_data(G_OBJECT(win->window), "get_attention"));
    - gtk_widget_hide(win->menu.add_pounce);
    - gtk_widget_hide(win->menu.get_info);
    - gtk_widget_show(win->menu.invite);
    - gtk_widget_show(win->menu.alias);
    - gtk_widget_hide(win->menu.block);
    - gtk_widget_hide(win->menu.unblock);
    + gtk_action_set_visible(win->menu.view_log, TRUE);
    + gtk_action_set_visible(win->menu.send_file, FALSE);
    + gtk_action_set_visible(g_object_get_data(G_OBJECT(win->window), "get_attention"), FALSE);
    + gtk_action_set_visible(win->menu.add_pounce, FALSE);
    + gtk_action_set_visible(win->menu.get_info, FALSE);
    + gtk_action_set_visible(win->menu.invite, TRUE);
    + gtk_action_set_visible(win->menu.alias, TRUE);
    + gtk_action_set_visible(win->menu.block, FALSE);
    + gtk_action_set_visible(win->menu.unblock, FALSE);
    if ((account == NULL) || purple_blist_find_chat(account, purple_conversation_get_name(conv)) == NULL) {
    /* If the chat is NOT in the buddy list */
    - gtk_widget_show(win->menu.add);
    - gtk_widget_hide(win->menu.remove);
    + gtk_action_set_visible(win->menu.add, TRUE);
    + gtk_action_set_visible(win->menu.remove, FALSE);
    } else {
    /* If the chat IS in the buddy list */
    - gtk_widget_hide(win->menu.add);
    - gtk_widget_show(win->menu.remove);
    - }
    -
    - gtk_widget_show(win->menu.insert_link);
    - gtk_widget_show(win->menu.insert_image);
    + gtk_action_set_visible(win->menu.add, FALSE);
    + gtk_action_set_visible(win->menu.remove, TRUE);
    + }
    +
    + gtk_action_set_visible(win->menu.insert_link, TRUE);
    + gtk_action_set_visible(win->menu.insert_image, TRUE);
    }
    /*
    @@ -6561,30 +6712,30 @@
    gtk_imhtmltoolbar_associate_smileys(GTK_IMHTMLTOOLBAR(gtkconv->toolbar), purple_account_get_protocol_id(account));
    /* Deal with menu items */
    - gtk_widget_set_sensitive(win->menu.view_log, TRUE);
    - gtk_widget_set_sensitive(win->menu.add_pounce, TRUE);
    - gtk_widget_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL));
    - gtk_widget_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL));
    - gtk_widget_set_sensitive(win->menu.insert_link, (conv->features & PURPLE_CONNECTION_HTML));
    - gtk_widget_set_sensitive(win->menu.insert_image, !(conv->features & PURPLE_CONNECTION_NO_IMAGES));
    + gtk_action_set_sensitive(win->menu.view_log, TRUE);
    + gtk_action_set_sensitive(win->menu.add_pounce, TRUE);
    + gtk_action_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL));
    + gtk_action_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL));
    + gtk_action_set_sensitive(win->menu.insert_link, (conv->features & PURPLE_CONNECTION_HTML));
    + gtk_action_set_sensitive(win->menu.insert_image, !(conv->features & PURPLE_CONNECTION_NO_IMAGES));
    if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
    {
    - gtk_widget_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL));
    - gtk_widget_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL));
    - gtk_widget_set_sensitive(win->menu.send_file,
    + gtk_action_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL));
    + gtk_action_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL));
    + gtk_action_set_sensitive(win->menu.send_file,
    (prpl_info->send_file != NULL && (!prpl_info->can_receive_file ||
    prpl_info->can_receive_file(gc, purple_conversation_get_name(conv)))));
    - gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(win->window), "get_attention"), (prpl_info->send_attention != NULL));
    - gtk_widget_set_sensitive(win->menu.alias,
    + gtk_action_set_sensitive(g_object_get_data(G_OBJECT(win->window), "get_attention"), (prpl_info->send_attention != NULL));
    + gtk_action_set_sensitive(win->menu.alias,
    (account != NULL) &&
    (purple_find_buddy(account, purple_conversation_get_name(conv)) != NULL));
    }
    else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
    {
    - gtk_widget_set_sensitive(win->menu.add, (prpl_info->join_chat != NULL));
    - gtk_widget_set_sensitive(win->menu.remove, (prpl_info->join_chat != NULL));
    - gtk_widget_set_sensitive(win->menu.alias,
    + gtk_action_set_sensitive(win->menu.add, (prpl_info->join_chat != NULL));
    + gtk_action_set_sensitive(win->menu.remove, (prpl_info->join_chat != NULL));
    + gtk_action_set_sensitive(win->menu.alias,
    (account != NULL) &&
    (purple_blist_find_chat(account, purple_conversation_get_name(conv)) != NULL));
    }
    @@ -6594,18 +6745,18 @@
    /* Or it's a chat that we've left. */
    /* Then deal with menu items */
    - gtk_widget_set_sensitive(win->menu.view_log, TRUE);
    - gtk_widget_set_sensitive(win->menu.send_file, FALSE);
    - gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(win->window),
    + gtk_action_set_sensitive(win->menu.view_log, TRUE);
    + gtk_action_set_sensitive(win->menu.send_file, FALSE);
    + gtk_action_set_sensitive(g_object_get_data(G_OBJECT(win->window),
    "get_attention"), FALSE);
    - gtk_widget_set_sensitive(win->menu.add_pounce, TRUE);
    - gtk_widget_set_sensitive(win->menu.get_info, FALSE);
    - gtk_widget_set_sensitive(win->menu.invite, FALSE);
    - gtk_widget_set_sensitive(win->menu.alias, FALSE);
    - gtk_widget_set_sensitive(win->menu.add, FALSE);
    - gtk_widget_set_sensitive(win->menu.remove, FALSE);
    - gtk_widget_set_sensitive(win->menu.insert_link, TRUE);
    - gtk_widget_set_sensitive(win->menu.insert_image, FALSE);
    + gtk_action_set_sensitive(win->menu.add_pounce, TRUE);
    + gtk_action_set_sensitive(win->menu.get_info, FALSE);
    + gtk_action_set_sensitive(win->menu.invite, FALSE);
    + gtk_action_set_sensitive(win->menu.alias, FALSE);
    + gtk_action_set_sensitive(win->menu.add, FALSE);
    + gtk_action_set_sensitive(win->menu.remove, FALSE);
    + gtk_action_set_sensitive(win->menu.insert_link, TRUE);
    + gtk_action_set_sensitive(win->menu.insert_image, FALSE);
    }
    /*
    @@ -6685,8 +6836,13 @@
    topic = purple_conv_chat_get_topic(chat);
    gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : "");
    +#if GTK_CHECK_VERSION(2,12,0)
    + gtk_widget_set_tooltip_text(gtkchat->topic_text,
    + topic ? topic : "");
    +#else
    gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text,
    topic ? topic : "", NULL);
    +#endif
    }
    }
    @@ -6746,7 +6902,7 @@
    if (title != markup)
    g_free(markup);
    - if (!GTK_WIDGET_REALIZED(gtkconv->tab_label))
    + if (!gtk_widget_get_realized(gtkconv->tab_label))
    gtk_widget_realize(gtkconv->tab_label);
    accessibility_obj = gtk_widget_get_accessible(gtkconv->tab_cont);
    @@ -7121,11 +7277,14 @@
    {
    gint pane_x, pane_y, x_rel;
    PidginConversation *gtkconv;
    -
    - gdk_window_get_origin(win->notebook->window, &pane_x, &pane_y);
    + GtkAllocation allocation;
    +
    + gtk_widget_get_allocation(gtkconv->infopane, &allocation);
    + gdk_window_get_origin(gtk_widget_get_window(win->notebook),
    + &pane_x, &pane_y);
    x_rel = x - pane_x;
    gtkconv = pidgin_conv_window_get_active_gtkconv(win);
    - return (x_rel > gtkconv->infopane->allocation.x + gtkconv->infopane->allocation.width / 2);
    + return (x_rel > allocation.x + allocation.width / 2);
    }
    int
    @@ -7143,7 +7302,7 @@
    notebook = GTK_NOTEBOOK(win->notebook);
    - gdk_window_get_origin(win->notebook->window, &nb_x, &nb_y);
    + gdk_window_get_origin(gtk_widget_get_window(win->notebook), &nb_x, &nb_y);
    x_rel = x - nb_x;
    y_rel = y - nb_y;
    @@ -7153,30 +7312,32 @@
    count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook));
    for (i = 0; i < count; i++) {
    + GtkAllocation allocation;
    page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i);
    tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
    + gtk_widget_get_allocation(tab, &allocation);
    /* Make sure the tab is not hidden beyond an arrow */
    - if (!GTK_WIDGET_DRAWABLE(tab) && gtk_notebook_get_show_tabs(notebook))
    + if (!gtk_widget_is_drawable(tab) && gtk_notebook_get_show_tabs(notebook))
    continue;
    if (horiz) {
    - if (x_rel >= tab->allocation.x - PIDGIN_HIG_BOX_SPACE &&
    - x_rel <= tab->allocation.x + tab->allocation.width + PIDGIN_HIG_BOX_SPACE) {
    + if (x_rel >= allocation.x - PIDGIN_HIG_BOX_SPACE &&
    + x_rel <= allocation.x + allocation.width + PIDGIN_HIG_BOX_SPACE) {
    page_num = i;
    - if (to_right && x_rel >= tab->allocation.x + tab->allocation.width/2)
    + if (to_right && x_rel >= allocation.x + allocation.width/2)
    *to_right = TRUE;
    break;
    }
    } else {
    - if (y_rel >= tab->allocation.y - PIDGIN_HIG_BOX_SPACE &&
    - y_rel <= tab->allocation.y + tab->allocation.height + PIDGIN_HIG_BOX_SPACE) {
    + if (y_rel >= allocation.y - PIDGIN_HIG_BOX_SPACE &&
    + y_rel <= allocation.y + allocation.height + PIDGIN_HIG_BOX_SPACE) {
    page_num = i;
    - if (to_right && y_rel >= tab->allocation.y + tab->allocation.height/2)
    + if (to_right && y_rel >= allocation.y + allocation.height/2)
    *to_right = TRUE;
    break;
    @@ -7283,8 +7444,8 @@
    gtkconv = PIDGIN_CONVERSATION(conv);
    win = gtkconv->win;
    - gtk_check_menu_item_set_active(
    - GTK_CHECK_MENU_ITEM(win->menu.show_timestamps),
    + gtk_toggle_action_set_active(
    + GTK_TOGGLE_ACTION(win->menu.show_timestamps),
    (gboolean)GPOINTER_TO_INT(value));
    gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
    @@ -7311,8 +7472,8 @@
    gtkconv = PIDGIN_CONVERSATION(conv);
    win = gtkconv->win;
    - gtk_check_menu_item_set_active(
    - GTK_CHECK_MENU_ITEM(win->menu.show_formatting_toolbar),
    + gtk_toggle_action_set_active(
    + GTK_TOGGLE_ACTION(win->menu.show_formatting_toolbar),
    (gboolean)GPOINTER_TO_INT(value));
    if ((gboolean)GPOINTER_TO_INT(value))
    @@ -8266,11 +8427,15 @@
    gtk_container_set_border_width(GTK_CONTAINER(warn_close_dialog),
    6);
    gtk_window_set_resizable(GTK_WINDOW(warn_close_dialog), FALSE);
    - gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog),
    +
    + /* TODO: figure out how to set no separator in GTK+ 3.0 */
    + /*
    + gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog),
    FALSE);
    -
    + */
    +
    /* Setup the outside spacing. */
    - vbox = GTK_DIALOG(warn_close_dialog)->vbox;
    + vbox = gtk_dialog_get_content_area(GTK_DIALOG(warn_close_dialog));
    gtk_box_set_spacing(GTK_BOX(vbox), 12);
    gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
    @@ -8424,7 +8589,7 @@
    always be true after a button press. */
    if (!gdk_pointer_is_grabbed())
    #endif
    - gdk_pointer_grab(gtkwin->notebook->window, FALSE,
    + gdk_pointer_grab(gtk_widget_get_window(gtkwin->notebook), FALSE,
    GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
    NULL, cursor, GDK_CURRENT_TIME);
    }
    @@ -8544,19 +8709,22 @@
    if (e->button == 1) {
    int nb_x, nb_y;
    -
    + GtkAllocation allocation;
    +
    + gtk_widget_get_allocation(gtkconv->infopane_hbox, &allocation);
    +
    if (gtkconv->win->in_drag)
    return TRUE;
    gtkconv->win->in_predrag = TRUE;
    gtkconv->win->drag_tab = gtk_notebook_page_num(GTK_NOTEBOOK(gtkconv->win->notebook), gtkconv->tab_cont);
    - gdk_window_get_origin(gtkconv->infopane_hbox->window, &nb_x, &nb_y);
    -
    - gtkconv->win->drag_min_x = gtkconv->infopane_hbox->allocation.x + nb_x;
    - gtkconv->win->drag_min_y = gtkconv->infopane_hbox->allocation.y + nb_y;
    - gtkconv->win->drag_max_x = gtkconv->infopane_hbox->allocation.width + gtkconv->win->drag_min_x;
    - gtkconv->win->drag_max_y = gtkconv->infopane_hbox->allocation.height + gtkconv->win->drag_min_y;
    + gdk_window_get_origin(gtk_widget_get_window(gtkconv->infopane_hbox), &nb_x, &nb_y);
    +
    + gtkconv->win->drag_min_x = allocation.x + nb_x;
    + gtkconv->win->drag_min_y = allocation.y + nb_y;
    + gtkconv->win->drag_max_x = allocation.width + gtkconv->win->drag_min_x;
    + gtkconv->win->drag_max_y = allocation.height + gtkconv->win->drag_min_y;
    gtkconv->win->drag_motion_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "motion_notify_event",
    G_CALLBACK(notebook_motion_cb), gtkconv->win);
    @@ -8569,6 +8737,7 @@
    /* Right click was pressed. Popup the context menu. */
    GtkWidget *menu = gtk_menu_new(), *sub;
    gboolean populated = populate_menu_with_options(menu, gtkconv, TRUE);
    +#if 0 /* TODO */
    sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to));
    if (sub && GTK_WIDGET_IS_SENSITIVE(gtkconv->win->menu.send_to)) {
    @@ -8583,7 +8752,7 @@
    gtk_widget_destroy(menu);
    return FALSE;
    }
    -
    +#endif
    gtk_widget_show_all(menu);
    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, e->button, e->time);
    return TRUE;
    @@ -8598,6 +8767,7 @@
    int tab_clicked;
    GtkWidget *page;
    GtkWidget *tab;
    + GtkAllocation allocation;
    if (e->button == 2 && e->type == GDK_BUTTON_PRESS) {
    PidginConversation *gtkconv;
    @@ -8635,7 +8805,7 @@
    * Get the relative position of the press event, with regards to
    * the position of the notebook.
    */
    - gdk_window_get_origin(win->notebook->window, &nb_x, &nb_y);
    + gdk_window_get_origin(gtk_widget_get_window(win->notebook), &nb_x, &nb_y);
    /* Reset the min/max x/y */
    win->drag_min_x = 0;
    @@ -8647,10 +8817,12 @@
    page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), tab_clicked);
    tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(win->notebook), page);
    - win->drag_min_x = tab->allocation.x + nb_x;
    - win->drag_min_y = tab->allocation.y + nb_y;
    - win->drag_max_x = tab->allocation.width + win->drag_min_x;
    - win->drag_max_y = tab->allocation.height + win->drag_min_y;
    + gtk_widget_get_allocation(tab, &allocation);
    +
    + win->drag_min_x = allocation.x + nb_x;
    + win->drag_min_y = allocation.y + nb_y;
    + win->drag_max_x = allocation.width + win->drag_min_x;
    + win->drag_max_y = allocation.height + win->drag_min_y;
    /* Make sure the click occurred in the tab. */
    if (e->x_root < win->drag_min_x ||
    @@ -8887,12 +9059,15 @@
    close_conv_cb(NULL, gtkconv);
    }
    +/* TODO: I don't know if this doable in GTK+ 3.0 */
    +#if 0
    static gboolean
    right_click_menu_cb(GtkNotebook *notebook, GdkEventButton *event, PidginWindow *win)
    {
    - GtkWidget *item, *menu;
    + GtkWidget *item;
    PidginConversation *gtkconv;
    -
    + GtkWidget *menu = gtk_notebook_get_menu
    +
    if (event->type != GDK_BUTTON_PRESS || event->button != 3)
    return FALSE;
    @@ -8938,6 +9113,7 @@
    return FALSE;
    }
    +#endif
    static void
    remove_edit_entry(PidginConversation *gtkconv, GtkWidget *entry)
    @@ -8959,7 +9135,7 @@
    static gboolean
    alias_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
    {
    - if (event->keyval == GDK_Escape) {
    + if (event->keyval == GDK_KEY_Escape) {
    remove_edit_entry(user_data, widget);
    return TRUE;
    }
    @@ -9004,7 +9180,7 @@
    PurpleConversation *conv = gtkconv->active_conv;
    const char *text = NULL;
    - if (!GTK_WIDGET_VISIBLE(gtkconv->infopane)) {
    + if (!gtk_widget_get_visible(gtkconv->infopane)) {
    /* There's already an entry for alias. Let's not create another one. */
    return FALSE;
    }
    @@ -9088,8 +9264,8 @@
    /* Update the menubar */
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging),
    - purple_conversation_is_logging(conv));
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging),
    + purple_conversation_is_logging(conv));
    generate_send_to_items(win);
    regenerate_options_items(win);
    @@ -9099,14 +9275,14 @@
    sound_method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
    if (strcmp(sound_method, "none") != 0)
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds),
    - gtkconv->make_sound);
    -
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_formatting_toolbar),
    - purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar"));
    -
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_timestamps),
    - purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps"));
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
    + gtkconv->make_sound);
    +
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.show_formatting_toolbar),
    + purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar"));
    +
    + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.show_timestamps),
    + purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps"));
    /*
    * We pause icons when they are not visible. If this icon should
    @@ -9166,14 +9342,14 @@
    static gboolean gtk_conv_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) {
    int x, y;
    - if (GTK_WIDGET_VISIBLE(w))
    + if (gtk_widget_get_visible(w))
    gtk_window_get_position(GTK_WINDOW(w), &x, &y);
    else
    return FALSE; /* carry on normally */
    /* Workaround for GTK+ bug # 169811 - "configure_event" is fired
    * when the window is being maximized */
    - if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED)
    + if (gdk_window_get_state(gtk_widget_get_window(w)) & GDK_WINDOW_STATE_MAXIMIZED)
    return FALSE;
    /* don't save off-screen positioning */
    @@ -9201,7 +9377,7 @@
    /* if the window exists, is hidden, we're saving positions, and the
    * position is sane... */
    if (win && win->window &&
    - !GTK_WIDGET_VISIBLE(win->window) && conv_width != 0) {
    + !gtk_widget_get_visible(win->window) && conv_width != 0) {
    #ifdef _WIN32 /* only override window manager placement on Windows */
    /* ...check position is on screen... */
    @@ -9286,9 +9462,13 @@
    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE);
    gtk_notebook_set_show_border(GTK_NOTEBOOK(win->notebook), TRUE);
    + /* TODO: figure out how to add custom stuff to the right-click menu in
    + GtkNotebook in GTK+ 3.0 */
    + /*
    g_signal_connect(G_OBJECT(win->notebook), "button-press-event",
    G_CALLBACK(right_click_menu_cb), win);
    -
    + */
    +
    gtk_widget_show(win->notebook);
    g_signal_connect(G_OBJECT(win->notebook), "switch_page",
    @@ -9356,7 +9536,7 @@
    }
    gtk_widget_destroy(win->window);
    - g_object_unref(G_OBJECT(win->menu.item_factory));
    + g_object_unref(G_OBJECT(win->menu.ui));
    purple_notify_close_with_handle(win);
    purple_signals_disconnect_by_handle(win);
    @@ -9379,7 +9559,7 @@
    void
    pidgin_conv_window_raise(PidginWindow *win)
    {
    - gdk_window_raise(GDK_WINDOW(win->window->window));
    + gdk_window_raise(GDK_WINDOW(gtk_widget_get_window(win->window)));
    }
    void
    @@ -9434,8 +9614,12 @@
    /* Close button. */
    gtkconv->close = pidgin_create_small_button(gtk_label_new("×"));
    +#if GTK_CHECK_VERSION(2,12,0)
    + gtk_widget_set_tooltip_text(gtkconv->close, _("Close conversation"));
    +#else
    gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close,
    _("Close conversation"), NULL);
    +#endif
    g_signal_connect(gtkconv->close, "clicked", G_CALLBACK (close_conv_cb), gtkconv);
    @@ -9550,7 +9734,7 @@
    g_signal_connect(G_OBJECT(ebox), "enter-notify-event",
    G_CALLBACK(gtkconv_tab_set_tip), gtkconv);
    - if (gtkconv->tab_label->parent == NULL) {
    + if (gtk_widget_get_parent(gtkconv->tab_label) == NULL) {
    /* Pack if it's a new widget */
    gtk_box_pack_start(GTK_BOX(gtkconv->tabby), first, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(gtkconv->tabby), gtkconv->tab_label, TRUE, TRUE, 0);
    @@ -9571,9 +9755,7 @@
    gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox);
    }
    - gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont,
    - !tabs_side && !angle,
    - TRUE, GTK_PACK_START);
    + g_object_set(G_OBJECT(win->notebook), "expand", !tabs_side && !angle, NULL);
    if (pidgin_conv_window_get_gtkconv_count(win) == 1)
    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook),
    @@ -9597,8 +9779,12 @@
    index = gtk_notebook_page_num(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont);
    +#if GTK_CHECK_VERSION(2,10,0)
    + g_object_ref_sink(G_OBJECT(gtkconv->tab_cont));
    +#else
    g_object_ref(gtkconv->tab_cont);
    gtk_object_sink(GTK_OBJECT(gtkconv->tab_cont));
    +#endif
    gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook), index);
    @@ -9681,7 +9867,7 @@
    for (l = pidgin_conv_windows_get_list(); l != NULL; l = l->next) {
    win = l->data;
    - if (gdkwin == win->window->window)
    + if (gdkwin == gtk_widget_get_window(win->window))
    return win;
    }
    @@ -9803,14 +9989,14 @@
    PurpleConversationType type = purple_conversation_get_type(conv->active_conv);
    GList *all;
    - if (GTK_WIDGET_VISIBLE(w))
    + if (gtk_widget_get_visible(w))
    gtk_window_get_position(GTK_WINDOW(w), &x, &y);
    else
    return FALSE; /* carry on normally */
    /* Workaround for GTK+ bug # 169811 - "configure_event" is fired
    * when the window is being maximized */
    - if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED)
    + if (gdk_window_get_state(gtk_widget_get_window(w)) & GDK_WINDOW_STATE_MAXIMIZED)
    return FALSE;
    /* don't save off-screen positioning */
    --- a/pidgin/gtkconv.h Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkconv.h Sun Dec 05 03:10:05 2010 +0000
    @@ -122,7 +122,11 @@
    gboolean make_sound;
    +#if GTK_CHECK_VERSION(2,12,0)
    + gpointer depr2;
    +#else
    GtkTooltips *tooltips;
    +#endif
    GtkWidget *tab_cont;
    GtkWidget *tabby;
    --- a/pidgin/gtkconvwin.h Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkconvwin.h Sun Dec 05 03:10:05 2010 +0000
    @@ -48,26 +48,27 @@
    {
    GtkWidget *menubar;
    - GtkWidget *view_log;
    + GtkAction *view_log;
    - GtkWidget *send_file;
    - GtkWidget *add_pounce;
    - GtkWidget *get_info;
    - GtkWidget *invite;
    + GtkAction *send_file;
    + GtkAction *add_pounce;
    + GtkAction *get_info;
    + GtkAction *invite;
    - GtkWidget *alias;
    - GtkWidget *block;
    - GtkWidget *unblock;
    - GtkWidget *add;
    - GtkWidget *remove;
    + GtkAction *alias;
    + GtkAction *block;
    + GtkAction *unblock;
    + GtkAction *add;
    + GtkAction *remove;
    - GtkWidget *insert_link;
    - GtkWidget *insert_image;
    + GtkAction *insert_link;
    + GtkAction *insert_image;
    - GtkWidget *logging;
    - GtkWidget *sounds;
    - GtkWidget *show_formatting_toolbar;
    - GtkWidget *show_timestamps;
    + GtkAction *logging;
    + GtkAction *sounds;
    + GtkAction *show_formatting_toolbar;
    + GtkAction *show_timestamps;
    +
    GtkWidget *show_icon;
    GtkWidget *send_to;
    @@ -76,7 +77,7 @@
    GtkWidget *typing_icon;
    - GtkItemFactory *item_factory;
    + GtkUIManager *ui;
    } menu;
    @@ -98,9 +99,9 @@
    gint drag_leave_signal;
    /* Media menu options. */
    - GtkWidget *audio_call;
    - GtkWidget *video_call;
    - GtkWidget *audio_video_call;
    + GtkAction *audio_call;
    + GtkAction *video_call;
    + GtkAction *audio_video_call;
    };
    /*@}*/
    --- a/pidgin/gtkdebug.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkdebug.c Sun Dec 05 03:10:05 2010 +0000
    @@ -128,7 +128,7 @@
    static gboolean
    configure_cb(GtkWidget *w, GdkEventConfigure *event, DebugWindow *win)
    {
    - if (GTK_WIDGET_VISIBLE(w)) {
    + if (gtk_widget_get_visible(w)) {
    purple_prefs_set_int(PIDGIN_PREFS_ROOT "/debug/width", event->width);
    purple_prefs_set_int(PIDGIN_PREFS_ROOT "/debug/height", event->height);
    }
    @@ -622,8 +622,8 @@
    static void
    regex_key_release_cb(GtkWidget *w, GdkEventKey *e, DebugWindow *win) {
    - if(e->keyval == GDK_Return &&
    - GTK_WIDGET_IS_SENSITIVE(win->filter) &&
    + if(e->keyval == GDK_KEY_Return &&
    + gtk_widget_is_sensitive(win->filter) &&
    !gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter)))
    {
    gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(win->filter), TRUE);
    @@ -925,7 +925,7 @@
    gtk_container_add(GTK_CONTAINER(item), gtk_label_new(_("Level ")));
    gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
    - win->filterlevel = gtk_combo_box_new_text();
    + win->filterlevel = gtk_combo_box_text_new();
    item = gtk_tool_item_new();
    #if GTK_CHECK_VERSION(2,12,0)
    gtk_widget_set_tooltip_text(win->filterlevel, _("Select the debug filter level."));
    @@ -935,12 +935,12 @@
    gtk_container_add(GTK_CONTAINER(item), win->filterlevel);
    gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
    - gtk_combo_box_append_text(GTK_COMBO_BOX(win->filterlevel), _("All"));
    - gtk_combo_box_append_text(GTK_COMBO_BOX(win->filterlevel), _("Misc"));
    - gtk_combo_box_append_text(GTK_COMBO_BOX(win->filterlevel), _("Info"));
    - gtk_combo_box_append_text(GTK_COMBO_BOX(win->filterlevel), _("Warning"));
    - gtk_combo_box_append_text(GTK_COMBO_BOX(win->filterlevel), _("Error "));
    - gtk_combo_box_append_text(GTK_COMBO_BOX(win->filterlevel), _("Fatal Error"));
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(win->filterlevel), _("All"));
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(win->filterlevel), _("Misc"));
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(win->filterlevel), _("Info"));
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(win->filterlevel), _("Warning"));
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(win->filterlevel), _("Error "));
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(win->filterlevel), _("Fatal Error"));
    gtk_combo_box_set_active(GTK_COMBO_BOX(win->filterlevel),
    purple_prefs_get_int(PIDGIN_PREFS_ROOT "/debug/filterlevel"));
    #ifdef USE_REGEX
    --- a/pidgin/gtkdialogs.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkdialogs.c Sun Dec 05 03:10:05 2010 +0000
    @@ -452,7 +452,7 @@
    button = pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_CLOSE,
    G_CALLBACK(destroy_win), win);
    - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
    + gtk_widget_set_can_default(button, TRUE);
    gtk_widget_grab_default(button);
    gtk_widget_show_all(win);
    @@ -899,12 +899,15 @@
    gtk_container_set_border_width (GTK_CONTAINER(window), PIDGIN_HIG_BOX_SPACE);
    gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
    - gtk_dialog_set_has_separator(GTK_DIALOG(window), FALSE);
    - gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(window)->vbox), PIDGIN_HIG_BORDER);
    - gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(window)->vbox), PIDGIN_HIG_BOX_SPACE);
    + /* TODO: figure out how to set no separator in a dialog in GTK+ 3.0 */
    + /*gtk_dialog_set_has_separator(GTK_DIALOG(window), FALSE);*/
    + gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(window))),
    + PIDGIN_HIG_BORDER);
    + gtk_container_set_border_width (GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(window))),
    + PIDGIN_HIG_BOX_SPACE);
    hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
    - gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->vbox), hbox);
    + gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(window))), hbox);
    img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_COOL, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE));
    gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
    --- a/pidgin/gtkdialogs.h Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkdialogs.h Sun Dec 05 03:10:05 2010 +0000
    @@ -66,6 +66,6 @@
    gtk_window_set_type_hint(GTK_WINDOW(x), GDK_WINDOW_TYPE_HINT_DIALOG)
    #endif
    -#define PIDGIN_WINDOW_ICONIFIED(x) (gdk_window_get_state(GTK_WIDGET(x)->window) & GDK_WINDOW_STATE_ICONIFIED)
    +#define PIDGIN_WINDOW_ICONIFIED(x) (gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(x))) & GDK_WINDOW_STATE_ICONIFIED)
    #endif /* _PIDGINDIALOGS_H_ */
    --- a/pidgin/gtkdnd-hints.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkdnd-hints.c Sun Dec 05 03:10:05 2010 +0000
    @@ -57,28 +57,34 @@
    static GtkWidget *
    dnd_hints_init_window(const gchar *fname)
    {
    + /* TODO: this is likely very broken right now, I think this needs to be
    + Cairo-ified */
    GdkPixbuf *pixbuf;
    - GdkPixmap *pixmap;
    - GdkBitmap *bitmap;
    + /*GdkPixmap *pixmap;*/
    + /*GdkBitmap *bitmap;*/
    GtkWidget *pix;
    GtkWidget *win;
    pixbuf = gdk_pixbuf_new_from_file(fname, NULL);
    g_return_val_if_fail(pixbuf, NULL);
    + /*
    gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, &bitmap, 128);
    g_object_unref(G_OBJECT(pixbuf));
    -
    - gtk_widget_push_colormap(gdk_rgb_get_colormap());
    + */
    +
    + /*gtk_widget_push_colormap(gdk_rgb_get_colormap());*/
    win = gtk_window_new(GTK_WINDOW_POPUP);
    - pix = gtk_image_new_from_pixmap(pixmap, bitmap);
    + pix = gtk_image_new_from_pixbuf(pixbuf);
    gtk_container_add(GTK_CONTAINER(win), pix);
    - gtk_widget_shape_combine_mask(win, bitmap, 0, 0);
    - gtk_widget_pop_colormap();
    + /*gtk_widget_shape_combine_mask(win, bitmap, 0, 0);
    + gtk_widget_pop_colormap();*/
    + /*
    g_object_unref(G_OBJECT(pixmap));
    g_object_unref(G_OBJECT(bitmap));
    -
    + */
    +
    gtk_widget_show_all(pix);
    return win;
    @@ -88,17 +94,22 @@
    get_widget_coords(GtkWidget *w, gint *x1, gint *y1, gint *x2, gint *y2)
    {
    gint ox, oy, width, height;
    -
    - if (w->parent && w->parent->window == w->window)
    + GtkWidget *parent = gtk_widget_get_parent(w);
    +
    + if (parent && gtk_widget_get_window(parent) == gtk_widget_get_window(w))
    {
    - get_widget_coords(w->parent, &ox, &oy, NULL, NULL);
    - height = w->allocation.height;
    - width = w->allocation.width;
    + GtkAllocation allocation;
    +
    + gtk_widget_get_allocation(w, &allocation);
    + get_widget_coords(parent, &ox, &oy, NULL, NULL);
    + height = allocation.height;
    + width = allocation.width;
    }
    else
    {
    - gdk_window_get_origin(w->window, &ox, &oy);
    - gdk_drawable_get_size(w->window, &width, &height);
    + gdk_window_get_origin(gtk_widget_get_window(w), &ox, &oy);
    + width = gdk_window_get_width(gtk_widget_get_window(w));
    + height = gdk_window_get_height(gtk_widget_get_window(w));
    }
    if (x1) *x1 = ox;
    @@ -171,10 +182,13 @@
    {
    gint x1, x2, y1, y2;
    gint x = 0, y = 0;
    + GtkAllocation allocation;
    +
    + gtk_widget_get_allocation(widget, &allocation);
    get_widget_coords(widget, &x1, &y1, &x2, &y2);
    - x1 += widget->allocation.x; x2 += widget->allocation.x;
    - y1 += widget->allocation.y; y2 += widget->allocation.y;
    + x1 += allocation.x; x2 += allocation.x;
    + y1 += allocation.y; y2 += allocation.y;
    switch (horiz)
    {
    --- a/pidgin/gtkdocklet-gtk.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkdocklet-gtk.c Sun Dec 05 03:10:05 2010 +0000
    @@ -51,7 +51,7 @@
    docklet_gtk_status_update_icon(PurpleStatusPrimitive status, gboolean connecting, gboolean pending)
    {
    const gchar *icon_name = NULL;
    -
    +
    switch (status) {
    case PURPLE_STATUS_OFFLINE:
    icon_name = PIDGIN_STOCK_TRAY_OFFLINE;
    @@ -81,21 +81,15 @@
    if (icon_name) {
    gtk_status_icon_set_from_icon_name(docklet, icon_name);
    }
    -
    - if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink")) {
    - gtk_status_icon_set_blinking(docklet, (pending && !connecting));
    - } else if (gtk_status_icon_get_blinking(docklet)) {
    - gtk_status_icon_set_blinking(docklet, FALSE);
    - }
    }
    static void
    docklet_gtk_status_set_tooltip(gchar *tooltip)
    {
    if (tooltip) {
    - gtk_status_icon_set_tooltip(docklet, tooltip);
    + gtk_status_icon_set_tooltip_text(docklet, tooltip);
    } else {
    - gtk_status_icon_set_tooltip(docklet, NULL);
    + gtk_status_icon_set_tooltip_text(docklet, NULL);
    }
    }
    --- a/pidgin/gtkdocklet.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkdocklet.c Sun Dec 05 03:10:05 2010 +0000
    @@ -210,12 +210,6 @@
    connecting = newconnecting;
    pidgin_docklet_update_icon();
    -
    - /* and schedule the blinker function if messages are pending */
    - if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink")
    - && pending && !connecting && docklet_blinking_timer == 0) {
    - docklet_blinking_timer = g_timeout_add(500, docklet_blink_icon, NULL);
    - }
    }
    return FALSE; /* for when we're called by the glib idle handler */
    @@ -315,19 +309,14 @@
    static void
    docklet_toggle_mute(GtkWidget *toggle, void *data)
    {
    - purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/sound/mute", GTK_CHECK_MENU_ITEM(toggle)->active);
    -}
    -
    -static void
    -docklet_toggle_blink(GtkWidget *toggle, void *data)
    -{
    - purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/blink", GTK_CHECK_MENU_ITEM(toggle)->active);
    + purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/sound/mute",
    + gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(toggle)));
    }
    static void
    docklet_toggle_blist(GtkWidget *toggle, void *data)
    {
    - purple_blist_set_visible(GTK_CHECK_MENU_ITEM(toggle)->active);
    + purple_blist_set_visible(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(toggle)));
    }
    #ifdef _WIN32
    @@ -523,7 +512,7 @@
    new_menu_item_with_status_icon(menu,
    purple_status_type_get_name(status_type),
    prim, G_CALLBACK(activate_status_account_cb),
    - status_type, 0, 0, NULL);
    + GINT_TO_POINTER(status_type), 0, 0, NULL);
    }
    }
    @@ -593,7 +582,7 @@
    static void
    -plugin_act(GtkObject *obj, PurplePluginAction *pam)
    +plugin_act(GtkWidget *widget, PurplePluginAction *pam)
    {
    if (pam && pam->callback)
    pam->callback(pam);
    @@ -734,11 +723,6 @@
    g_signal_connect(G_OBJECT(menuitem), "toggled", G_CALLBACK(docklet_toggle_mute), NULL);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
    - menuitem = gtk_check_menu_item_new_with_mnemonic(_("_Blink on New Message"));
    - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink"));
    - g_signal_connect(G_OBJECT(menuitem), "toggled", G_CALLBACK(docklet_toggle_blink), NULL);
    - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
    -
    pidgin_separator(menu);
    /* add plugin actions */
    --- a/pidgin/gtkidle.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkidle.c Sun Dec 05 03:10:05 2010 +0000
    @@ -107,14 +107,16 @@
    int event_base, error_base;
    if (has_extension == -1)
    - has_extension = XScreenSaverQueryExtension(GDK_DISPLAY(), &event_base, &error_base);
    + has_extension = XScreenSaverQueryExtension(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
    + &event_base, &error_base);
    if (has_extension)
    {
    if (mit_info == NULL)
    mit_info = XScreenSaverAllocInfo();
    - XScreenSaverQueryInfo(GDK_DISPLAY(), GDK_ROOT_WINDOW(), mit_info);
    + XScreenSaverQueryInfo(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
    + GDK_ROOT_WINDOW(), mit_info);
    return (mit_info->idle) / 1000;
    }
    else
    --- a/pidgin/gtkimhtml.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkimhtml.c Sun Dec 05 03:10:05 2010 +0000
    @@ -410,7 +410,7 @@
    /* Don't scroll here if we're in the middle of a smooth scroll */
    if (scroll && imhtml->scroll_time == NULL &&
    - GTK_WIDGET_REALIZED(imhtml))
    + gtk_widget_get_realized(GTK_WIDGET(imhtml)))
    gtk_imhtml_scroll_to_end(imhtml, FALSE);
    }
    @@ -499,18 +499,20 @@
    gtk_imhtml_tip_paint (GtkIMHtml *imhtml)
    {
    PangoLayout *layout;
    + cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(imhtml->tip_window));
    g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE);
    layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip);
    - gtk_paint_flat_box (imhtml->tip_window->style, imhtml->tip_window->window,
    - GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, imhtml->tip_window,
    - "tooltip", 0, 0, -1, -1);
    -
    - gtk_paint_layout (imhtml->tip_window->style, imhtml->tip_window->window, GTK_STATE_NORMAL,
    - FALSE, NULL, imhtml->tip_window, NULL, 4, 4, layout);
    -
    + gtk_paint_flat_box (gtk_widget_get_style(imhtml->tip_window), cr,
    + GTK_STATE_NORMAL, GTK_SHADOW_OUT, imhtml->tip_window, "tooltip",
    + 0, 0, -1, -1);
    +
    + gtk_paint_layout (gtk_widget_get_style(imhtml->tip_window), cr,
    + GTK_STATE_NORMAL, TRUE, imhtml->tip_window, NULL, 4, 4, layout);
    +
    + cairo_destroy(cr);
    g_object_unref(layout);
    return FALSE;
    }
    @@ -522,12 +524,15 @@
    PangoFontMetrics *font_metrics;
    PangoLayout *layout;
    PangoFont *font;
    -
    + GtkStyle *style = gtk_widget_get_style(imhtml->tip_window);
    + GtkAllocation allocation;
    gint gap, x, y, h, w, scr_w, baseline_skip;
    g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE);
    - if (!imhtml->tip || !GTK_WIDGET_DRAWABLE (GTK_WIDGET(imhtml))) {
    + gtk_widget_get_allocation(GTK_WIDGET(imhtml), &allocation);
    +
    + if (!imhtml->tip || !gtk_widget_is_drawable(GTK_WIDGET(imhtml))) {
    imhtml->tip_timer = 0;
    return FALSE;
    }
    @@ -551,11 +556,10 @@
    gtk_widget_ensure_style (imhtml->tip_window);
    layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip);
    font = pango_context_load_font(pango_layout_get_context(layout),
    - imhtml->tip_window->style->font_desc);
    + style->font_desc);
    if (font == NULL) {
    - char *tmp = pango_font_description_to_string(
    - imhtml->tip_window->style->font_desc);
    + char *tmp = pango_font_description_to_string(style->font_desc);
    purple_debug(PURPLE_DEBUG_ERROR, "gtk_imhtml_tip",
    "pango_context_load_font() couldn't load font: '%s'\n",
    @@ -580,8 +584,8 @@
    h = 8 + baseline_skip;
    gdk_window_get_pointer (NULL, &x, &y, NULL);
    - if (GTK_WIDGET_NO_WINDOW (GTK_WIDGET(imhtml)))
    - y += GTK_WIDGET(imhtml)->allocation.y;
    + if ((!gtk_widget_get_has_window(GTK_WIDGET(imhtml))))
    + y += allocation.y;
    scr_w = gdk_screen_width();
    @@ -621,7 +625,7 @@
    oldprelit_tag = GTK_IMHTML(imhtml)->prelit_tag;
    - gdk_window_get_pointer(GTK_WIDGET(imhtml)->window, NULL, NULL, NULL);
    + gdk_window_get_pointer(gtk_widget_get_window(GTK_WIDGET(imhtml)), NULL, NULL, NULL);
    gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(imhtml), GTK_TEXT_WINDOW_WIDGET,
    event->x, event->y, &x, &y);
    gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, x, y);
    @@ -749,6 +753,8 @@
    return FALSE;
    }
    +/* TODO: I think this can be removed for GTK+ 3.0... */
    +#if 0
    static gint
    gtk_imhtml_expose_event (GtkWidget *widget,
    GdkEventExpose *event)
    @@ -776,7 +782,8 @@
    gdk_color_parse(GTK_IMHTML(widget)->edit.background, &gcolor);
    gdk_cairo_set_source_color(cr, &gcolor);
    } else {
    - gdk_cairo_set_source_color(cr, &(widget->style->base[GTK_WIDGET_STATE(widget)]));
    + gdk_cairo_set_source_color(cr,
    + &(gtk_widget_get_style(widget)->base[gtk_widget_get_state(widget)]));
    }
    cairo_rectangle(cr,
    @@ -882,6 +889,7 @@
    return FALSE;
    }
    +#endif
    static void paste_unformatted_cb(GtkMenuItem *menu, GtkIMHtml *imhtml)
    @@ -1158,11 +1166,12 @@
    {
    char *text;
    GtkIMHtml *imhtml = data;
    -
    + gint length = gtk_selection_data_get_length(selection_data);
    +
    if (!gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml)))
    return;
    - if (imhtml->wbfo || selection_data->length <= 0) {
    + if (imhtml->wbfo || length <= 0) {
    gtk_clipboard_request_text(clipboard, paste_plaintext_received_cb, imhtml);
    return;
    } else {
    @@ -1186,13 +1195,13 @@
    }
    #endif
    - text = g_malloc(selection_data->length + 1);
    - memcpy(text, selection_data->data, selection_data->length);
    + text = g_malloc(length + 1);
    + memcpy(text, gtk_selection_data_get_data(selection_data), length);
    /* Make sure the paste data is null-terminated. Given that
    * we're passed length (but assume later that it is
    * null-terminated), this seems sensible to me.
    */
    - text[selection_data->length] = '\0';
    + text[length] = '\0';
    }
    #ifdef _WIN32
    @@ -1203,10 +1212,10 @@
    }
    #endif
    - if (selection_data->length >= 2 &&
    + if (length >= 2 &&
    (*(guint16 *)text == 0xfeff || *(guint16 *)text == 0xfffe)) {
    /* This is UTF-16 */
    - char *utf8 = utf16_to_utf8_with_bom_check(text, selection_data->length);
    + char *utf8 = utf16_to_utf8_with_bom_check(text, length);
    g_free(text);
    text = utf8;
    if (!text) {
    @@ -1567,7 +1576,8 @@
    gobject_class->finalize = gtk_imhtml_finalize;
    widget_class->drag_motion = gtk_text_view_drag_motion;
    - widget_class->expose_event = gtk_imhtml_expose_event;
    + /* TODO: I _think_ this should be removed for GTK+ 3.0 */
    + /*widget_class->expose_event = gtk_imhtml_expose_event;*/
    parent_size_allocate = widget_class->size_allocate;
    widget_class->size_allocate = gtk_imhtml_size_allocate;
    parent_style_set = widget_class->style_set;
    @@ -1629,20 +1639,20 @@
    TRUE, G_PARAM_READABLE));
    binding_set = gtk_binding_set_by_class (parent_class);
    - gtk_binding_entry_add_signal (binding_set, GDK_b, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_BOLD);
    - gtk_binding_entry_add_signal (binding_set, GDK_i, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_ITALIC);
    - gtk_binding_entry_add_signal (binding_set, GDK_u, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_UNDERLINE);
    - gtk_binding_entry_add_signal (binding_set, GDK_plus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
    - gtk_binding_entry_add_signal (binding_set, GDK_equal, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
    - gtk_binding_entry_add_signal (binding_set, GDK_minus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_SHRINK);
    + gtk_binding_entry_add_signal (binding_set, GDK_KEY_b, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_BOLD);
    + gtk_binding_entry_add_signal (binding_set, GDK_KEY_i, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_ITALIC);
    + gtk_binding_entry_add_signal (binding_set, GDK_KEY_u, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_UNDERLINE);
    + gtk_binding_entry_add_signal (binding_set, GDK_KEY_plus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
    + gtk_binding_entry_add_signal (binding_set, GDK_KEY_equal, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
    + gtk_binding_entry_add_signal (binding_set, GDK_KEY_minus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_SHRINK);
    binding_set = gtk_binding_set_by_class(klass);
    - gtk_binding_entry_add_signal (binding_set, GDK_r, GDK_CONTROL_MASK, "format_function_clear", 0);
    - gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, "message_send", 0);
    - gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, "message_send", 0);
    - gtk_binding_entry_add_signal (binding_set, GDK_z, GDK_CONTROL_MASK, "undo", 0);
    - gtk_binding_entry_add_signal (binding_set, GDK_z, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "redo", 0);
    - gtk_binding_entry_add_signal (binding_set, GDK_F14, 0, "undo", 0);
    - gtk_binding_entry_add_signal(binding_set, GDK_v, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "paste", 1, G_TYPE_STRING, "text");
    + gtk_binding_entry_add_signal (binding_set, GDK_KEY_r, GDK_CONTROL_MASK, "format_function_clear", 0);
    + gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0, "message_send", 0);
    + gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0, "message_send", 0);
    + gtk_binding_entry_add_signal (binding_set, GDK_KEY_z, GDK_CONTROL_MASK, "undo", 0);
    + gtk_binding_entry_add_signal (binding_set, GDK_KEY_z, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "redo", 0);
    + gtk_binding_entry_add_signal (binding_set, GDK_KEY_F14, 0, "undo", 0);
    + gtk_binding_entry_add_signal(binding_set, GDK_KEY_v, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "paste", 1, G_TYPE_STRING, "text");
    }
    static void gtk_imhtml_init (GtkIMHtml *imhtml)
    @@ -1869,13 +1879,13 @@
    /* can't accept any of the offered targets */
    } else {
    GtkWidget *source_widget;
    - suggested_action = context->suggested_action;
    + suggested_action = gdk_drag_context_get_suggested_action(context);
    source_widget = gtk_drag_get_source_widget (context);
    if (source_widget == widget) {
    /* Default to MOVE, unless the user has
    * pressed ctrl or alt to affect available actions
    */
    - if ((context->actions & GDK_ACTION_MOVE) != 0)
    + if ((gdk_drag_context_get_actions(context) & GDK_ACTION_MOVE) != 0)
    suggested_action = GDK_ACTION_MOVE;
    }
    }
    @@ -1907,20 +1917,21 @@
    {
    gchar **links;
    gchar *link;
    - char *text = (char *)sd->data;
    + char *text = (char *) gtk_selection_data_get_data(sd);
    GtkTextMark *mark = gtk_text_buffer_get_insert(imhtml->text_buffer);
    GtkTextIter iter;
    gint i = 0;
    + gint length = gtk_selection_data_get_length(sd);
    gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, mark);
    - if(gtk_imhtml_get_editable(imhtml) && sd->data){
    + if(gtk_imhtml_get_editable(imhtml) && text){
    switch (info) {
    case GTK_IMHTML_DRAG_URL:
    /* TODO: Is it really ok to change sd->data...? */
    - purple_str_strip_char((char *)sd->data, '\r');
    -
    - links = g_strsplit((char *)sd->data, "\n", 0);
    + purple_str_strip_char(text, '\r');
    +
    + links = g_strsplit(text, "\n", 0);
    while((link = links[i]) != NULL){
    if (gtk_imhtml_is_protocol(link)) {
    gchar *label;
    @@ -1959,8 +1970,8 @@
    * See also the comment on text/html here:
    * http://mail.gnome.org/archives/gtk-devel-list/2001-September/msg00114.html
    */
    - if (sd->length >= 2 && !g_utf8_validate(text, sd->length - 1, NULL)) {
    - utf8 = utf16_to_utf8_with_bom_check(text, sd->length);
    + if (length >= 2 && !g_utf8_validate(text, length - 1, NULL)) {
    + utf8 = utf16_to_utf8_with_bom_check(text, length);
    if (!utf8) {
    purple_debug_warning("gtkimhtml", "g_convert from UTF-16 failed in drag_rcv_cb\n");
    @@ -1989,7 +2000,8 @@
    gtk_drag_finish(dc, FALSE, FALSE, t);
    return;
    }
    - gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
    + gtk_drag_finish(dc, TRUE,
    + (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
    } else {
    gtk_drag_finish(dc, FALSE, FALSE, t);
    }
    @@ -2520,8 +2532,8 @@
    static gboolean smooth_scroll_cb(gpointer data)
    {
    GtkIMHtml *imhtml = data;
    - GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment;
    - gdouble max_val = adj->upper - adj->page_size;
    + GtkAdjustment *adj = gtk_text_view_get_vadjustment(GTK_TEXT_VIEW(imhtml));
    + gdouble max_val = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
    gdouble scroll_val = gtk_adjustment_get_value(adj) + ((max_val - gtk_adjustment_get_value(adj)) / 3);
    g_return_val_if_fail(imhtml->scroll_time != NULL, FALSE);
    @@ -2544,9 +2556,10 @@
    static gboolean scroll_idle_cb(gpointer data)
    {
    GtkIMHtml *imhtml = data;
    - GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment;
    + GtkAdjustment *adj = gtk_text_view_get_vadjustment(GTK_TEXT_VIEW(imhtml));
    if(adj) {
    - gtk_adjustment_set_value(adj, adj->upper - adj->page_size);
    + gtk_adjustment_set_value(adj, gtk_adjustment_get_upper(adj) -
    + gtk_adjustment_get_page_size(adj));
    }
    imhtml->scroll_src = 0;
    return FALSE;
    @@ -4186,9 +4199,14 @@
    for (l = tags; l; l = l->next) {
    GtkTextTag *tag = l->data;
    -
    - if (tag->name && !strncmp(tag->name, prefix, len))
    + gchar *name;
    +
    + g_object_get(G_OBJECT(tag), "name", &name, NULL);
    +
    + if (name && !strncmp(name, prefix, len))
    gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, i, e);
    +
    + g_free(name);
    }
    g_slist_free(tags);
    @@ -4204,10 +4222,15 @@
    for (l = tags; l; l = l->next) {
    GtkTextTag *tag = l->data;
    -
    - if (tag->name && !strncmp(tag->name, prefix, len))
    + gchar *name;
    +
    + g_object_get(G_OBJECT(tag), "name", &name, NULL);
    +
    + if (name && !strncmp(name, prefix, len))
    gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, &iter, e);
    - }
    +
    + g_free(name);
    + }
    g_slist_free(tags);
    }
    @@ -4327,11 +4350,16 @@
    gtk_text_iter_begins_tag(start, tag) && /* the tag starts with the selection */
    (!gtk_text_iter_has_tag(end, tag) || /* the tag ends within the selection */
    gtk_text_iter_ends_tag(end, tag))) {
    + gchar *name;
    +
    + g_object_get(G_OBJECT(tag), "name", &name, NULL);
    gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, start, end);
    - if (tag->name &&
    - strncmp(tag->name, "LINK ", 5) == 0 && imhtml->edit.link) {
    +
    + if (name && strncmp(name, "LINK ", 5) == 0 && imhtml->edit.link) {
    gtk_imhtml_toggle_link(imhtml, NULL);
    }
    +
    + g_free(name);
    }
    }
    g_slist_free(tags);
    @@ -4553,27 +4581,32 @@
    for (l = tags; l != NULL; l = l->next) {
    GtkTextTag *tag = GTK_TEXT_TAG(l->data);
    -
    - if (tag->name) {
    - if (strcmp(tag->name, "BOLD") == 0)
    + gchar *name;
    +
    + g_object_get(G_OBJECT(tag), "name", &name, NULL);
    +
    + if (name) {
    + if (strcmp(name, "BOLD") == 0)
    imhtml->edit.bold = TRUE;
    - else if (strcmp(tag->name, "ITALICS") == 0)
    + else if (strcmp(name, "ITALICS") == 0)
    imhtml->edit.italic = TRUE;
    - else if (strcmp(tag->name, "UNDERLINE") == 0)
    + else if (strcmp(name, "UNDERLINE") == 0)
    imhtml->edit.underline = TRUE;
    - else if (strcmp(tag->name, "STRIKE") == 0)
    + else if (strcmp(name, "STRIKE") == 0)
    imhtml->edit.strike = TRUE;
    - else if (strncmp(tag->name, "FORECOLOR ", 10) == 0)
    - imhtml->edit.forecolor = g_strdup(&(tag->name)[10]);
    - else if (strncmp(tag->name, "BACKCOLOR ", 10) == 0)
    - imhtml->edit.backcolor = g_strdup(&(tag->name)[10]);
    - else if (strncmp(tag->name, "FONT FACE ", 10) == 0)
    - imhtml->edit.fontface = g_strdup(&(tag->name)[10]);
    - else if (strncmp(tag->name, "FONT SIZE ", 10) == 0)
    - imhtml->edit.fontsize = strtol(&(tag->name)[10], NULL, 10);
    - else if ((strncmp(tag->name, "LINK ", 5) == 0) && !gtk_text_iter_is_end(&iter))
    + else if (strncmp(name, "FORECOLOR ", 10) == 0)
    + imhtml->edit.forecolor = g_strdup(&(name)[10]);
    + else if (strncmp(name, "BACKCOLOR ", 10) == 0)
    + imhtml->edit.backcolor = g_strdup(&(name)[10]);
    + else if (strncmp(name, "FONT FACE ", 10) == 0)
    + imhtml->edit.fontface = g_strdup(&(name)[10]);
    + else if (strncmp(name, "FONT SIZE ", 10) == 0)
    + imhtml->edit.fontsize = strtol(&(name)[10], NULL, 10);
    + else if ((strncmp(name, "LINK ", 5) == 0) && !gtk_text_iter_is_end(&iter))
    imhtml->edit.link = tag;
    }
    +
    + g_free(name);
    }
    g_slist_free(tags);
    @@ -4864,6 +4897,8 @@
    gtk_text_buffer_end_user_action(imhtml->text_buffer);
    }
    +/* TODO: I think this can be removed for GTK+ 3.0... */
    +#if 0
    static gboolean
    image_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
    {
    @@ -4871,9 +4906,10 @@
    return TRUE;
    }
    +#endif
    /* In case the smiley gets removed from the imhtml before it gets removed from the queue */
    -static void animated_smiley_destroy_cb(GtkObject *widget, GtkIMHtml *imhtml)
    +static void animated_smiley_destroy_cb(GtkWidget *widget, GtkIMHtml *imhtml)
    {
    GList *l = imhtml->animations->head;
    while (l) {
    @@ -4968,8 +5004,10 @@
    * images, and ensures that they are handled by the image
    * itself, without propagating to the textview and causing
    * a complete refresh */
    + /* TODO: I think this should be removed for GTK+ 3.0?
    g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL);
    -
    + */
    +
    gtk_widget_show(icon);
    if (ebox)
    gtk_container_add(GTK_CONTAINER(ebox), icon);
    @@ -5070,23 +5108,30 @@
    static const gchar *tag_to_html_start(GtkTextTag *tag)
    {
    - const gchar *name;
    static gchar buf[1024];
    -
    - name = tag->name;
    + gchar *name;
    +
    + g_object_get(G_OBJECT(tag), "name", &name, NULL);
    g_return_val_if_fail(name != NULL, "");
    if (strcmp(name, "BOLD") == 0) {
    + g_free(name);
    return "<b>";
    } else if (strcmp(name, "ITALICS") == 0) {
    + g_free(name);
    return "<i>";
    } else if (strcmp(name, "UNDERLINE") == 0) {
    - return "<u>";
    + g_free(name);
    + return "<u>";
    } else if (strcmp(name, "STRIKE") == 0) {
    - return "<s>";
    + g_free(name);
    + return "<s>";
    } else if (strncmp(name, "LINK ", 5) == 0) {
    char *tmp = g_object_get_data(G_OBJECT(tag), "link_url");
    - if (tmp) {
    +
    + g_free(name);
    +
    + if (tmp) {
    g_snprintf(buf, sizeof(buf), "<a href=\"%s\">", tmp);
    buf[sizeof(buf)-1] = '\0';
    return buf;
    @@ -5095,19 +5140,30 @@
    }
    } else if (strncmp(name, "FORECOLOR ", 10) == 0) {
    g_snprintf(buf, sizeof(buf), "<font color=\"%s\">", &name[10]);
    - return buf;
    +
    + g_free(name);
    +
    + return buf;
    } else if (strncmp(name, "BACKCOLOR ", 10) == 0) {
    g_snprintf(buf, sizeof(buf), "<font back=\"%s\">", &name[10]);
    - return buf;
    + g_free(name);
    +
    + return buf;
    } else if (strncmp(name, "BACKGROUND ", 10) == 0) {
    g_snprintf(buf, sizeof(buf), "<body bgcolor=\"%s\">", &name[11]);
    - return buf;
    + g_free(name);
    +
    + return buf;
    } else if (strncmp(name, "FONT FACE ", 10) == 0) {
    g_snprintf(buf, sizeof(buf), "<font face=\"%s\">", &name[10]);
    - return buf;
    + g_free(name);
    +
    + return buf;
    } else if (strncmp(name, "FONT SIZE ", 10) == 0) {
    g_snprintf(buf, sizeof(buf), "<font size=\"%s\">", &name[10]);
    - return buf;
    + g_free(name);
    +
    + return buf;
    } else {
    char *str = buf;
    gboolean isset;
    @@ -5169,38 +5225,49 @@
    }
    g_snprintf(str, sizeof(buf) - (str - buf), "'>");
    -
    + g_free(name);
    +
    return (empty ? "" : buf);
    }
    }
    static const gchar *tag_to_html_end(GtkTextTag *tag)
    {
    - const gchar *name;
    -
    - name = tag->name;
    + gchar *name;
    +
    + g_object_get(G_OBJECT(tag), "name", &name, NULL);
    g_return_val_if_fail(name != NULL, "");
    if (strcmp(name, "BOLD") == 0) {
    + g_free(name);
    return "</b>";
    } else if (strcmp(name, "ITALICS") == 0) {
    - return "</i>";
    + g_free(name);
    + return "</i>";
    } else if (strcmp(name, "UNDERLINE") == 0) {
    - return "</u>";
    + g_free(name);
    + return "</u>";
    } else if (strcmp(name, "STRIKE") == 0) {
    - return "</s>";
    + g_free(name);
    + return "</s>";
    } else if (strncmp(name, "LINK ", 5) == 0) {
    - return "</a>";
    + g_free(name);
    + return "</a>";
    } else if (strncmp(name, "FORECOLOR ", 10) == 0) {
    - return "</font>";
    + g_free(name);
    + return "</font>";
    } else if (strncmp(name, "BACKCOLOR ", 10) == 0) {
    - return "</font>";
    + g_free(name);
    + return "</font>";
    } else if (strncmp(name, "BACKGROUND ", 10) == 0) {
    - return "</body>";
    + g_free(name);
    + return "</body>";
    } else if (strncmp(name, "FONT FACE ", 10) == 0) {
    - return "</font>";
    + g_free(name);
    + return "</font>";
    } else if (strncmp(name, "FONT SIZE ", 10) == 0) {
    - return "</font>";
    + g_free(name);
    + return "</font>";
    } else {
    const char *props[] = {"weight-set", "foreground-set", "background-set",
    "size-set", "underline-set", NULL};
    @@ -5212,6 +5279,8 @@
    return "</span>";
    }
    + g_free(name);
    +
    return "";
    }
    }
    --- a/pidgin/gtkimhtmltoolbar.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkimhtmltoolbar.c Sun Dec 05 03:10:05 2010 +0000
    @@ -124,11 +124,15 @@
    {
    GtkFontSelection *sel;
    - sel = GTK_FONT_SELECTION(GTK_FONT_SELECTION_DIALOG(toolbar->font_dialog)->fontsel);
    - gtk_widget_hide_all(gtk_widget_get_parent(sel->size_entry));
    - gtk_widget_show_all(sel->family_list);
    - gtk_widget_show(gtk_widget_get_parent(sel->family_list));
    - gtk_widget_show(gtk_widget_get_parent(gtk_widget_get_parent(sel->family_list)));
    + sel = GTK_FONT_SELECTION(
    + gtk_font_selection_dialog_get_font_selection(GTK_FONT_SELECTION_DIALOG(toolbar->font_dialog)));
    + gtk_widget_hide(gtk_widget_get_parent(
    + gtk_font_selection_get_size_entry(sel)));
    + gtk_widget_show_all(gtk_font_selection_get_family_list(sel));
    + gtk_widget_show(gtk_widget_get_parent(
    + gtk_font_selection_get_family_list(sel)));
    + gtk_widget_show(gtk_widget_get_parent(gtk_widget_get_parent(
    + gtk_font_selection_get_family_list(sel))));
    }
    static void
    @@ -191,10 +195,12 @@
    g_signal_connect(G_OBJECT(toolbar->font_dialog), "delete_event",
    G_CALLBACK(destroy_toolbar_font), toolbar);
    - g_signal_connect(G_OBJECT(GTK_FONT_SELECTION_DIALOG(toolbar->font_dialog)->ok_button), "clicked",
    - G_CALLBACK(apply_font), toolbar->font_dialog);
    - g_signal_connect(G_OBJECT(GTK_FONT_SELECTION_DIALOG(toolbar->font_dialog)->cancel_button), "clicked",
    - G_CALLBACK(cancel_toolbar_font), toolbar);
    + g_signal_connect(G_OBJECT(
    + gtk_font_selection_dialog_get_ok_button(GTK_FONT_SELECTION_DIALOG(toolbar->font_dialog))),
    + "clicked", G_CALLBACK(apply_font), toolbar->font_dialog);
    + g_signal_connect(G_OBJECT(
    + gtk_font_selection_dialog_get_cancel_button(GTK_FONT_SELECTION_DIALOG(toolbar->font_dialog))),
    + "clicked", G_CALLBACK(cancel_toolbar_font), toolbar);
    g_signal_connect_after(G_OBJECT(toolbar->font_dialog), "realize",
    G_CALLBACK(realize_toolbar_font), toolbar);
    }
    @@ -253,9 +259,12 @@
    char *color = gtk_imhtml_get_current_forecolor(GTK_IMHTML(toolbar->imhtml));
    if (!toolbar->fgcolor_dialog) {
    -
    + GtkWidget *ok_button;
    + GtkWidget *cancel_button;
    +
    toolbar->fgcolor_dialog = gtk_color_selection_dialog_new(_("Select Text Color"));
    - colorsel = GTK_COLOR_SELECTION_DIALOG(toolbar->fgcolor_dialog)->colorsel;
    + colorsel =
    + gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(toolbar->fgcolor_dialog));
    if (color) {
    gdk_color_parse(color, &fgcolor);
    gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(colorsel), &fgcolor);
    @@ -264,12 +273,14 @@
    g_object_set_data(G_OBJECT(colorsel), "purple_toolbar", toolbar);
    + g_object_get(G_OBJECT(toolbar->fgcolor_dialog), "ok-button", &ok_button, NULL);
    + g_object_get(G_OBJECT(toolbar->fgcolor_dialog), "cancel-button",
    + &cancel_button, NULL);
    g_signal_connect(G_OBJECT(toolbar->fgcolor_dialog), "delete_event",
    G_CALLBACK(destroy_toolbar_fgcolor), toolbar);
    - g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(toolbar->fgcolor_dialog)->ok_button), "clicked",
    - G_CALLBACK(do_fgcolor), colorsel);
    - g_signal_connect(G_OBJECT (GTK_COLOR_SELECTION_DIALOG(toolbar->fgcolor_dialog)->cancel_button), "clicked",
    - G_CALLBACK(cancel_toolbar_fgcolor), toolbar);
    + g_signal_connect(G_OBJECT(ok_button), "clicked", G_CALLBACK(do_fgcolor), colorsel);
    + g_signal_connect(G_OBJECT(cancel_button), "clicked",
    + G_CALLBACK(cancel_toolbar_fgcolor), toolbar);
    }
    gtk_window_present(GTK_WINDOW(toolbar->fgcolor_dialog));
    } else {
    @@ -333,10 +344,14 @@
    char *color = gtk_imhtml_get_current_backcolor(GTK_IMHTML(toolbar->imhtml));
    if (!toolbar->bgcolor_dialog) {
    -
    + GtkWidget *ok_button;
    + GtkWidget *cancel_button;
    +
    toolbar->bgcolor_dialog = gtk_color_selection_dialog_new(_("Select Background Color"));
    - colorsel = GTK_COLOR_SELECTION_DIALOG(toolbar->bgcolor_dialog)->colorsel;
    - if (color) {
    + colorsel =
    + gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(toolbar->fgcolor_dialog));
    +
    + if (color) {
    gdk_color_parse(color, &bgcolor);
    gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(colorsel), &bgcolor);
    g_free(color);
    @@ -344,11 +359,14 @@
    g_object_set_data(G_OBJECT(colorsel), "purple_toolbar", toolbar);
    + g_object_get(G_OBJECT(toolbar->bgcolor_dialog), "ok-button", &ok_button, NULL);
    + g_object_get(G_OBJECT(toolbar->bgcolor_dialog), "cancel-button",
    + &cancel_button, NULL);
    g_signal_connect(G_OBJECT(toolbar->bgcolor_dialog), "delete_event",
    G_CALLBACK(destroy_toolbar_bgcolor), toolbar);
    - g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(toolbar->bgcolor_dialog)->ok_button), "clicked",
    - G_CALLBACK(do_bgcolor), colorsel);
    - g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(toolbar->bgcolor_dialog)->cancel_button), "clicked",
    + g_signal_connect(G_OBJECT(ok_button), "clicked",
    + G_CALLBACK(do_bgcolor), colorsel);
    + g_signal_connect(G_OBJECT(cancel_button), "clicked",
    G_CALLBACK(cancel_toolbar_bgcolor), toolbar);
    }
    @@ -658,7 +676,11 @@
    g_object_set_data(G_OBJECT(button), "smiley_text", face);
    g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(insert_smiley_text), toolbar);
    +#if GTK_CHECK_VERSION(2,12,0)
    + gtk_widget_set_tooltip_text(button, face);
    +#else
    gtk_tooltips_set_tip(toolbar->tooltips, button, face, NULL);
    +#endif
    /* these look really weird with borders */
    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
    @@ -672,7 +694,11 @@
    g_snprintf(tip, sizeof(tip),
    _("This smiley is disabled because a custom smiley exists for this shortcut:\n %s"),
    face);
    +#if GTK_CHECK_VERSION(2,12,0)
    + gtk_widget_set_tooltip_text(button, tip);
    +#else
    gtk_tooltips_set_tip(toolbar->tooltips, button, tip, NULL);
    +#endif
    gtk_widget_set_sensitive(button, FALSE);
    } else if (psmiley) {
    /* Remove the button if the smiley is destroyed */
    @@ -714,7 +740,7 @@
    static gboolean
    smiley_dialog_input_cb(GtkWidget *dialog, GdkEvent *event, GtkIMHtmlToolbar *toolbar)
    {
    - if ((event->type == GDK_KEY_PRESS && event->key.keyval == GDK_Escape) ||
    + if ((event->type == GDK_KEY_PRESS && event->key.keyval == GDK_KEY_Escape) ||
    (event->type == GDK_BUTTON_PRESS && event->button.button == 1))
    {
    close_smiley_dialog(toolbar);
    @@ -1087,19 +1113,21 @@
    {
    GtkWidget *widget = GTK_WIDGET(data);
    GtkRequisition menu_req;
    - gint ythickness = widget->style->ythickness;
    + GtkAllocation allocation;
    + gint ythickness = gtk_widget_get_style(widget)->ythickness;
    int savy;
    + gtk_widget_get_allocation(widget, &allocation);
    gtk_widget_size_request(GTK_WIDGET (menu), &menu_req);
    - gdk_window_get_origin(widget->window, x, y);
    - *x += widget->allocation.x;
    - *y += widget->allocation.y + widget->allocation.height;
    + gdk_window_get_origin(gtk_widget_get_window(widget), x, y);
    + *x += allocation.x;
    + *y += allocation.y + allocation.height;
    savy = *y;
    pidgin_menu_position_func_helper(menu, x, y, push_in, data);
    if (savy > *y + ythickness + 1)
    - *y -= widget->allocation.height;
    + *y -= allocation.height;
    }
    static gboolean
    @@ -1158,7 +1186,9 @@
    }
    g_free(toolbar->sml);
    +#if !GTK_CHECK_VERSION(2,12,0)
    gtk_object_sink(GTK_OBJECT(toolbar->tooltips));
    +#endif
    menu = g_object_get_data(object, "font_menu");
    if (menu)
    @@ -1189,7 +1219,7 @@
    if (event->button != 3)
    return FALSE;
    - wide = GTK_WIDGET_VISIBLE(toolbar->bold);
    + wide = gtk_widget_get_visible(toolbar->bold);
    menu = gtk_menu_new();
    item = gtk_menu_item_new_with_mnemonic(wide ? _("Group Items") : _("Ungroup Items"));
    @@ -1255,7 +1285,11 @@
    g_signal_connect(G_OBJECT(button), "clicked",
    G_CALLBACK(buttons[iter].callback), toolbar);
    *(buttons[iter].button) = button;
    +#if GTK_CHECK_VERSION(2,12,0)
    + gtk_widget_set_tooltip_text(button, buttons[iter].tooltip);
    +#else
    gtk_tooltips_set_tip(toolbar->tooltips, button, buttons[iter].tooltip, NULL);
    +#endif
    } else
    button = gtk_vseparator_new();
    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
    @@ -1266,7 +1300,11 @@
    g_signal_connect(G_OBJECT(button), "clicked",
    G_CALLBACK(send_attention_cb), toolbar);
    g_object_set_data(G_OBJECT(toolbar), "attention", button);
    +#if GTK_CHECK_VERSION(2,12,0)
    + gtk_widget_set_tooltip_text(button, _("Send Attention"));
    +#else
    gtk_tooltips_set_tip(toolbar->tooltips, button, _("Send Attention"), NULL);
    +#endif
    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(toolbar), hbox, FALSE, FALSE, 0);
    @@ -1276,7 +1314,7 @@
    static void
    button_visibility_changed(GtkWidget *button, gpointer dontcare, GtkWidget *item)
    {
    - if (GTK_WIDGET_VISIBLE(button))
    + if (gtk_widget_get_visible(button))
    gtk_widget_hide(item);
    else
    gtk_widget_show(item);
    @@ -1285,7 +1323,7 @@
    static void
    button_sensitiveness_changed(GtkWidget *button, gpointer dontcare, GtkWidget *item)
    {
    - gtk_widget_set_sensitive(item, GTK_WIDGET_IS_SENSITIVE(button));
    + gtk_widget_set_sensitive(item, gtk_widget_get_sensitive(button));
    }
    static void
    @@ -1308,10 +1346,10 @@
    gconstpointer value, gpointer toolbar)
    {
    if (value) {
    - gtk_widget_hide_all(g_object_get_data(G_OBJECT(toolbar), "lean-view"));
    + gtk_widget_hide(g_object_get_data(G_OBJECT(toolbar), "lean-view"));
    gtk_widget_show_all(g_object_get_data(G_OBJECT(toolbar), "wide-view"));
    } else {
    - gtk_widget_hide_all(g_object_get_data(G_OBJECT(toolbar), "wide-view"));
    + gtk_widget_hide(g_object_get_data(G_OBJECT(toolbar), "wide-view"));
    gtk_widget_show_all(g_object_get_data(G_OBJECT(toolbar), "lean-view"));
    }
    }
    @@ -1364,7 +1402,9 @@
    toolbar->smiley_dialog = NULL;
    toolbar->image_dialog = NULL;
    +#if !GTK_CHECK_VERSION(2,12,0)
    toolbar->tooltips = gtk_tooltips_new();
    +#endif
    gtk_box_set_spacing(GTK_BOX(toolbar), 3);
    --- a/pidgin/gtkimhtmltoolbar.h Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkimhtmltoolbar.h Sun Dec 05 03:10:05 2010 +0000
    @@ -46,7 +46,11 @@
    GtkWidget *imhtml;
    +#if GTK_CHECK_VERSION(2,12,0)
    + gpointer depr1;
    +#else
    GtkTooltips *tooltips;
    +#endif
    GtkWidget *bold;
    GtkWidget *italic;
    --- a/pidgin/gtklog.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtklog.c Sun Dec 05 03:10:05 2010 +0000
    @@ -582,8 +582,10 @@
    gtk_dialog_add_button(GTK_DIALOG(lv->window), _("_Browse logs folder"), GTK_RESPONSE_HELP);
    #endif
    gtk_container_set_border_width (GTK_CONTAINER(lv->window), PIDGIN_HIG_BOX_SPACE);
    - gtk_dialog_set_has_separator(GTK_DIALOG(lv->window), FALSE);
    - gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(lv->window)->vbox), 0);
    + /* TODO: is it possible to set this in GTK+ 3.0?
    + gtk_dialog_set_has_separator(GTK_DIALOG(lv->window), FALSE);
    + */
    + gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(lv->window))), 0);
    g_signal_connect(G_OBJECT(lv->window), "response",
    G_CALLBACK(destroy_cb), ht);
    gtk_window_set_role(GTK_WINDOW(lv->window), "log_viewer");
    @@ -592,11 +594,12 @@
    if (icon != NULL) {
    title_box = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
    gtk_container_set_border_width(GTK_CONTAINER(title_box), PIDGIN_HIG_BOX_SPACE);
    - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lv->window)->vbox), title_box, FALSE, FALSE, 0);
    + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(lv->window))),
    + title_box, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(title_box), icon, FALSE, FALSE, 0);
    } else
    - title_box = GTK_DIALOG(lv->window)->vbox;
    + title_box = gtk_dialog_get_content_area(GTK_DIALOG(lv->window));
    /* Label ************/
    lv->label = gtk_label_new(NULL);
    @@ -611,7 +614,8 @@
    /* Pane *************/
    pane = gtk_hpaned_new();
    gtk_container_set_border_width(GTK_CONTAINER(pane), PIDGIN_HIG_BOX_SPACE);
    - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lv->window)->vbox), pane, TRUE, TRUE, 0);
    + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(lv->window))),
    + pane, TRUE, TRUE, 0);
    /* List *************/
    sw = gtk_scrolled_window_new (NULL, NULL);
    @@ -649,7 +653,8 @@
    gtk_label_set_markup(GTK_LABEL(size_label), text);
    /* gtk_paned_add1(GTK_PANED(pane), size_label); */
    gtk_misc_set_alignment(GTK_MISC(size_label), 0, 0);
    - gtk_box_pack_end(GTK_BOX(GTK_DIALOG(lv->window)->vbox), size_label, FALSE, FALSE, 0);
    + gtk_box_pack_end(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(lv->window))),
    + size_label, FALSE, FALSE, 0);
    g_free(sz_txt);
    g_free(text);
    }
    --- a/pidgin/gtkmain.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkmain.c Sun Dec 05 03:10:05 2010 +0000
    @@ -490,7 +490,7 @@
    {
    Display *xdisplay;
    - xdisplay = GDK_DISPLAY();
    + xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
    sn_display = sn_display_new(xdisplay,
    sn_error_trap_push,
    sn_error_trap_pop);
    --- a/pidgin/gtkmedia.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkmedia.c Sun Dec 05 03:10:05 2010 +0000
    @@ -445,9 +445,9 @@
    window_id = GDK_WINDOW_HWND(priv->remote_video->window);
    #elif defined(HAVE_X11)
    if (data->participant == NULL)
    - window_id = GDK_WINDOW_XWINDOW(priv->local_video->window);
    + window_id = gdk_x11_window_get_xid(gtk_widget_get_window(priv->local_video));
    else
    - window_id = GDK_WINDOW_XWINDOW(priv->remote_video->window);
    + window_id = gdk_x11_window_get_xid(gtk_widget_get_window(priv->remote_video));
    #else
    # error "Unsupported windowing system"
    #endif
    --- a/pidgin/gtkmenutray.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkmenutray.c Sun Dec 05 03:10:05 2010 +0000
    @@ -44,7 +44,7 @@
    * Item Stuff
    *****************************************************************************/
    static void
    -pidgin_menu_tray_select(GtkItem *item) {
    +pidgin_menu_tray_select(GtkMenuItem *widget) {
    /* this may look like nothing, but it's really overriding the
    * GtkMenuItem's select function so that it doesn't get highlighted like
    * a normal menu item would.
    @@ -52,7 +52,7 @@
    }
    static void
    -pidgin_menu_tray_deselect(GtkItem *item) {
    +pidgin_menu_tray_deselect(GtkMenuItem *widget) {
    /* Probably not necessary, but I'd rather be safe than sorry. We're
    * overridding the select, so it makes sense to override deselect as well.
    */
    @@ -104,9 +104,11 @@
    gtk_widget_destroy(GTK_WIDGET(tray->tray));
    #endif
    +#if !GTK_CHECK_VERSION(2,12,0)
    if (tray->tooltips) {
    gtk_object_sink(GTK_OBJECT(tray->tooltips));
    }
    +#endif
    G_OBJECT_CLASS(parent_class)->finalize(obj);
    }
    @@ -114,7 +116,7 @@
    static void
    pidgin_menu_tray_class_init(PidginMenuTrayClass *klass) {
    GObjectClass *object_class = G_OBJECT_CLASS(klass);
    - GtkItemClass *item_class = GTK_ITEM_CLASS(klass);
    + GtkMenuItemClass *menu_item_class = GTK_MENU_ITEM_CLASS(klass);
    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
    GParamSpec *pspec;
    @@ -123,8 +125,8 @@
    object_class->finalize = pidgin_menu_tray_finalize;
    object_class->get_property = pidgin_menu_tray_get_property;
    - item_class->select = pidgin_menu_tray_select;
    - item_class->deselect = pidgin_menu_tray_deselect;
    + menu_item_class->select = pidgin_menu_tray_select;
    + menu_item_class->deselect = pidgin_menu_tray_deselect;
    widget_class->map = pidgin_menu_tray_map;
    @@ -205,7 +207,7 @@
    g_return_if_fail(PIDGIN_IS_MENU_TRAY(menu_tray));
    g_return_if_fail(GTK_IS_WIDGET(widget));
    - if (GTK_WIDGET_NO_WINDOW(widget))
    + if (!gtk_widget_get_has_window(widget))
    {
    GtkWidget *event;
    @@ -238,21 +240,27 @@
    void
    pidgin_menu_tray_set_tooltip(PidginMenuTray *menu_tray, GtkWidget *widget, const char *tooltip)
    {
    +#if !GTK_CHECK_VERSION(2,12,0)
    if (!menu_tray->tooltips)
    menu_tray->tooltips = gtk_tooltips_new();
    +#endif
    /* Should we check whether widget is a child of menu_tray? */
    /*
    - * If the widget does not have it's own window, then it
    + * If the widget does not have its own window, then it
    * must have automatically been added to an event box
    * when it was added to the menu tray. If this is the
    * case, we want to set the tooltip on the widget's parent,
    * not on the widget itself.
    */
    - if (GTK_WIDGET_NO_WINDOW(widget))
    - widget = widget->parent;
    + if (!gtk_widget_get_has_window(widget))
    + widget = gtk_widget_get_parent(widget);
    +#if GTK_CHECK_VERSION(2,12,0)
    + gtk_widget_set_tooltip_text(widget, tooltip);
    +#else
    gtk_tooltips_set_tip(menu_tray->tooltips, widget, tooltip, NULL);
    +#endif
    }
    --- a/pidgin/gtkmenutray.h Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkmenutray.h Sun Dec 05 03:10:05 2010 +0000
    @@ -40,7 +40,11 @@
    struct _PidginMenuTray {
    GtkMenuItem gparent; /**< The parent instance */
    GtkWidget *tray; /**< The tray */
    +#if GTK_CHECK_VERSION(2,12,0)
    + gpointer depr1;
    +#else
    GtkTooltips *tooltips; /**< Tooltips */
    +#endif
    };
    /** A PidginMenuTrayClass */
    --- a/pidgin/gtknotify.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtknotify.c Sun Dec 05 03:10:05 2010 +0000
    @@ -534,12 +534,18 @@
    gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BORDER);
    gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
    + /* TODO: not sure if there is a way to do this in gtk+ 3, or
    + if we want to...
    gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
    - gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
    - gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BOX_SPACE);
    + */
    + gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
    + PIDGIN_HIG_BORDER);
    + gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
    + PIDGIN_HIG_BOX_SPACE);
    hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
    - gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
    + gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
    + hbox);
    if (img != NULL)
    gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
    @@ -775,7 +781,7 @@
    }
    }
    - if (!GTK_WIDGET_VISIBLE(mail_dialog->dialog)) {
    + if (!gtk_widget_get_visible(mail_dialog->dialog)) {
    GdkPixbuf *pixbuf = gtk_widget_render_icon(mail_dialog->dialog, PIDGIN_STOCK_DIALOG_MAIL,
    gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), NULL);
    char *label_text = g_strdup_printf(ngettext("<b>%d new email.</b>",
    @@ -791,7 +797,7 @@
    g_free(label_text);
    if (pixbuf)
    g_object_unref(pixbuf);
    - } else if (!GTK_WIDGET_HAS_FOCUS(mail_dialog->dialog))
    + } else if (!gtk_widget_has_focus(mail_dialog->dialog))
    pidgin_set_urgent(GTK_WINDOW(mail_dialog->dialog), TRUE);
    return data;
    @@ -800,7 +806,7 @@
    static gboolean
    formatted_input_cb(GtkWidget *win, GdkEventKey *event, gpointer data)
    {
    - if (event->keyval == GDK_Escape)
    + if (event->keyval == GDK_KEY_Escape)
    {
    purple_notify_close(PURPLE_NOTIFY_FORMATTED, win);
    @@ -847,7 +853,7 @@
    G_CALLBACK(formatted_close_cb), NULL);
    /* Setup the main vbox */
    - vbox = GTK_DIALOG(window)->vbox;
    + vbox = gtk_dialog_get_content_area(GTK_DIALOG(window));
    /* Setup the descriptive label */
    primary_esc = g_markup_escape_text(primary, -1);
    @@ -978,7 +984,7 @@
    G_CALLBACK(searchresults_close_cb), data);
    /* Setup the main vbox */
    - vbox = GTK_DIALOG(window)->vbox;
    + vbox = gtk_dialog_get_content_area(GTK_DIALOG(window));
    /* Setup the descriptive label */
    primary_esc = (primary != NULL) ? g_markup_escape_text(primary, -1) : NULL;
    @@ -1516,12 +1522,16 @@
    /* Setup the dialog */
    gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BOX_SPACE);
    - gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BOX_SPACE);
    + gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
    + PIDGIN_HIG_BOX_SPACE);
    + /* TODO: not sure if this is possible (or nessesary) in gtk+ 3
    gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
    - gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
    + */
    + gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
    + PIDGIN_HIG_BORDER);
    /* Vertical box */
    - vbox = GTK_DIALOG(dialog)->vbox;
    + vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
    /* Golden ratio it up! */
    gtk_widget_set_size_request(dialog, 550, 400);
    --- a/pidgin/gtkplugin.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkplugin.c Sun Dec 05 03:10:05 2010 +0000
    @@ -518,7 +518,7 @@
    break;
    dialog = gtk_dialog_new_with_buttons(PIDGIN_ALERT_TITLE, GTK_WINDOW(d),
    - GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
    + GTK_DIALOG_DESTROY_WITH_PARENT,
    GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
    NULL);
    if (plugin_pref_dialogs == NULL)
    @@ -527,7 +527,7 @@
    g_hash_table_insert(plugin_pref_dialogs, plug, dialog);
    g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(pref_dialog_response_cb), plug);
    - gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), box);
    + gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), box);
    gtk_window_set_role(GTK_WINDOW(dialog), "plugin_config");
    gtk_window_set_title(GTK_WINDOW(dialog), _(purple_plugin_get_name(plug)));
    gtk_widget_show_all(dialog);
    @@ -562,10 +562,13 @@
    pidgin_plugins_paint_tooltip(GtkWidget *tipwindow, gpointer data)
    {
    PangoLayout *layout = g_object_get_data(G_OBJECT(tipwindow), "tooltip-plugin");
    - gtk_paint_layout(tipwindow->style, tipwindow->window, GTK_STATE_NORMAL, FALSE,
    - NULL, tipwindow, "tooltip",
    + cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(tipwindow));
    + gtk_paint_layout(gtk_widget_get_style(tipwindow), cr, GTK_STATE_NORMAL, FALSE,
    + tipwindow, "tooltip",
    6, 6, layout);
    - return TRUE;
    + cairo_destroy(cr);
    +
    + return TRUE;
    }
    static gboolean
    @@ -720,8 +723,9 @@
    plugin_dialog = gtk_dialog_new_with_buttons(_("Plugins"),
    NULL,
    - GTK_DIALOG_NO_SEPARATOR,
    + 0,
    NULL);
    +
    pref_button = gtk_dialog_add_button(GTK_DIALOG(plugin_dialog),
    _("Configure Pl_ugin"), PIDGIN_RESPONSE_CONFIGURE);
    gtk_dialog_add_button(GTK_DIALOG(plugin_dialog),
    @@ -733,7 +737,8 @@
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN);
    - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(plugin_dialog)->vbox), sw, TRUE, TRUE, 0);
    + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(plugin_dialog))),
    + sw, TRUE, TRUE, 0);
    ls = gtk_list_store_new(4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN);
    gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(ls),
    @@ -793,8 +798,8 @@
    gtk_expander_set_use_markup(GTK_EXPANDER(expander), TRUE);
    gtk_widget_set_sensitive(expander, FALSE);
    gtk_container_add(GTK_CONTAINER(expander), create_details());
    - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(plugin_dialog)->vbox), expander,
    - FALSE, FALSE, 0);
    + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(plugin_dialog))),
    + expander, FALSE, FALSE, 0);
    g_signal_connect (G_OBJECT (sel), "changed", G_CALLBACK (prefs_plugin_sel), NULL);
    --- a/pidgin/gtkpounce.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkpounce.c Sun Dec 05 03:10:05 2010 +0000
    @@ -410,13 +410,15 @@
    GtkSelectionData *sd, guint info, guint t, gpointer data)
    {
    PidginPounceDialog *dialog;
    -
    - if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
    + GdkAtom target = gtk_selection_data_get_target(sd);
    + const guchar *sd_data = gtk_selection_data_get_data(sd);
    +
    + if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
    {
    PurpleBlistNode *node = NULL;
    PurpleBuddy *buddy;
    - memcpy(&node, sd->data, sizeof(node));
    + memcpy(&node, sd_data, sizeof(node));
    if (PURPLE_BLIST_NODE_IS_CONTACT(node))
    buddy = purple_contact_get_priority_buddy((PurpleContact *)node);
    @@ -431,15 +433,15 @@
    dialog->account = buddy->account;
    pidgin_account_option_menu_set_selected(dialog->account_menu, buddy->account);
    - gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
    + gtk_drag_finish(dc, TRUE, (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
    }
    - else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE))
    + else if (target == gdk_atom_intern("application/x-im-contact", FALSE))
    {
    char *protocol = NULL;
    char *username = NULL;
    PurpleAccount *account;
    - if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account,
    + if (pidgin_parse_x_im_contact((const char *) sd_data, FALSE, &account,
    &protocol, &username, NULL))
    {
    if (account == NULL)
    @@ -461,7 +463,7 @@
    g_free(username);
    g_free(protocol);
    - gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
    + gtk_drag_finish(dc, TRUE, (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
    }
    }
    @@ -540,7 +542,7 @@
    G_CALLBACK(delete_win_cb), dialog);
    /* Create the parent vbox for everything. */
    - vbox1 = GTK_DIALOG(window)->vbox;
    + vbox1 = gtk_dialog_get_content_area(GTK_DIALOG(window));
    /* Create the vbox that will contain all the prefs stuff. */
    vbox2 = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
    @@ -1018,7 +1020,7 @@
    static gboolean
    pounces_manager_configure_cb(GtkWidget *widget, GdkEventConfigure *event, PouncesManager *dialog)
    {
    - if (GTK_WIDGET_VISIBLE(widget)) {
    + if (gtk_widget_get_visible(widget)) {
    purple_prefs_set_int(PIDGIN_PREFS_ROOT "/pounces/dialog/width", event->width);
    purple_prefs_set_int(PIDGIN_PREFS_ROOT "/pounces/dialog/height", event->height);
    }
    --- a/pidgin/gtkprefs.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkprefs.c Sun Dec 05 03:10:05 2010 +0000
    @@ -118,7 +118,7 @@
    const char *key, int min, int max, GtkSizeGroup *sg)
    {
    GtkWidget *spin;
    - GtkObject *adjust;
    + GtkAdjustment *adjust;
    int val;
    val = purple_prefs_get_int(key);
    @@ -182,29 +182,49 @@
    return pidgin_add_widget_to_vbox(GTK_BOX(page), title, sg, entry, TRUE, NULL);
    }
    +/* TODO: Maybe move this up somewheres... */
    +enum {
    + PREF_DROPDOWN_TEXT,
    + PREF_DROPDOWN_VALUE,
    + PREF_DROPDOWN_COUNT
    +};
    static void
    dropdown_set(GObject *w, const char *key)
    {
    const char *str_value;
    int int_value;
    + gboolean bool_value;
    PurplePrefType type;
    + GtkTreeIter iter;
    + GtkTreeModel *tree_model;
    +
    + tree_model = gtk_combo_box_get_model(GTK_COMBO_BOX(w));
    + if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(w), &iter))
    + return;
    type = GPOINTER_TO_INT(g_object_get_data(w, "type"));
    if (type == PURPLE_PREF_INT) {
    - int_value = GPOINTER_TO_INT(g_object_get_data(w, "value"));
    + gtk_tree_model_get(tree_model, &iter,
    + PREF_DROPDOWN_VALUE, &int_value,
    + -1);
    purple_prefs_set_int(key, int_value);
    }
    else if (type == PURPLE_PREF_STRING) {
    - str_value = (const char *)g_object_get_data(w, "value");
    + gtk_tree_model_get(tree_model, &iter,
    + PREF_DROPDOWN_VALUE, &str_value,
    + -1);
    purple_prefs_set_string(key, str_value);
    }
    else if (type == PURPLE_PREF_BOOLEAN) {
    - purple_prefs_set_bool(key,
    - GPOINTER_TO_INT(g_object_get_data(w, "value")));
    + gtk_tree_model_get(tree_model, &iter,
    + PREF_DROPDOWN_VALUE, &bool_value,
    + -1);
    +
    + purple_prefs_set_bool(key, bool_value);
    }
    }
    @@ -212,69 +232,86 @@
    pidgin_prefs_dropdown_from_list(GtkWidget *box, const gchar *title,
    PurplePrefType type, const char *key, GList *menuitems)
    {
    - GtkWidget *dropdown, *opt, *menu;
    + GtkWidget *dropdown;
    GtkWidget *label = NULL;
    gchar *text;
    const char *stored_str = NULL;
    int stored_int = 0;
    + gboolean stored_bool = FALSE;
    int int_value = 0;
    const char *str_value = NULL;
    - int o = 0;
    + gboolean bool_value = FALSE;
    + GtkListStore *store;
    + GtkTreeIter iter;
    + GtkTreeIter active;
    + GtkCellRenderer *renderer;
    g_return_val_if_fail(menuitems != NULL, NULL);
    - dropdown = gtk_option_menu_new();
    - menu = gtk_menu_new();
    -
    - if (type == PURPLE_PREF_INT)
    + if (type == PURPLE_PREF_INT) {
    + store = gtk_list_store_new(PREF_DROPDOWN_COUNT, G_TYPE_STRING, G_TYPE_INT);
    stored_int = purple_prefs_get_int(key);
    - else if (type == PURPLE_PREF_STRING)
    + } else if (type == PURPLE_PREF_STRING) {
    + store = gtk_list_store_new(PREF_DROPDOWN_COUNT, G_TYPE_STRING, G_TYPE_STRING);
    stored_str = purple_prefs_get_string(key);
    -
    - while (menuitems != NULL && (text = (char *) menuitems->data) != NULL) {
    + } else if (type == PURPLE_PREF_BOOLEAN) {
    + store = gtk_list_store_new(PREF_DROPDOWN_COUNT, G_TYPE_STRING, G_TYPE_BOOLEAN);
    + stored_bool = purple_prefs_get_bool(key);
    + }
    +
    + dropdown = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
    + g_object_set_data(G_OBJECT(dropdown), "type", GINT_TO_POINTER(type));
    +
    + while (menuitems != NULL && (text = (char *)menuitems->data) != NULL) {
    menuitems = g_list_next(menuitems);
    g_return_val_if_fail(menuitems != NULL, NULL);
    - opt = gtk_menu_item_new_with_label(text);
    -
    - g_object_set_data(G_OBJECT(opt), "type", GINT_TO_POINTER(type));
    + gtk_list_store_append(store, &iter);
    + gtk_list_store_set(store, &iter,
    + PREF_DROPDOWN_TEXT, text,
    + -1);
    if (type == PURPLE_PREF_INT) {
    int_value = GPOINTER_TO_INT(menuitems->data);
    - g_object_set_data(G_OBJECT(opt), "value",
    - GINT_TO_POINTER(int_value));
    + gtk_list_store_set(store, &iter,
    + PREF_DROPDOWN_VALUE, int_value,
    + -1);
    }
    else if (type == PURPLE_PREF_STRING) {
    str_value = (const char *)menuitems->data;
    -
    - g_object_set_data(G_OBJECT(opt), "value", (char *)str_value);
    + gtk_list_store_set(store, &iter,
    + PREF_DROPDOWN_VALUE, str_value,
    + -1);
    }
    else if (type == PURPLE_PREF_BOOLEAN) {
    - g_object_set_data(G_OBJECT(opt), "value",
    - menuitems->data);
    + bool_value = (gboolean)GPOINTER_TO_INT(menuitems->data);
    + gtk_list_store_set(store, &iter,
    + PREF_DROPDOWN_VALUE, bool_value,
    + -1);
    }
    - g_signal_connect(G_OBJECT(opt), "activate",
    - G_CALLBACK(dropdown_set), (char *)key);
    -
    - gtk_widget_show(opt);
    - gtk_menu_shell_append(GTK_MENU_SHELL(menu), opt);
    -
    if ((type == PURPLE_PREF_INT && stored_int == int_value) ||
    (type == PURPLE_PREF_STRING && stored_str != NULL &&
    !strcmp(stored_str, str_value)) ||
    (type == PURPLE_PREF_BOOLEAN &&
    - (purple_prefs_get_bool(key) == GPOINTER_TO_INT(menuitems->data)))) {
    -
    - gtk_menu_set_active(GTK_MENU(menu), o);
    + (stored_bool == bool_value))) {
    +
    + active = iter;
    }
    menuitems = g_list_next(menuitems);
    -
    - o++;
    }
    - gtk_option_menu_set_menu(GTK_OPTION_MENU(dropdown), menu);
    + renderer = gtk_cell_renderer_text_new();
    + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dropdown), renderer, TRUE);
    + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(dropdown), renderer,
    + "text", 0,
    + NULL);
    +
    + gtk_combo_box_set_active_iter(GTK_COMBO_BOX(dropdown), &active);
    +
    + g_signal_connect(G_OBJECT(dropdown), "changed",
    + G_CALLBACK(dropdown_set), (char *)key);
    pidgin_add_widget_to_vbox(GTK_BOX(box), title, NULL, dropdown, FALSE, &label);
    @@ -827,9 +864,10 @@
    theme_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
    GtkSelectionData *sd, guint info, guint t, gpointer user_data)
    {
    - gchar *name = g_strchomp((gchar *)sd->data);
    -
    - if ((sd->length >= 0) && (sd->format == 8)) {
    + gchar *name = g_strchomp((gchar *)gtk_selection_data_get_data(sd));
    +
    + if ((gtk_selection_data_get_length(sd) >= 0)
    + && (gtk_selection_data_get_format(sd) == 8)) {
    /* Well, it looks like the drag event was cool.
    * Let's do something with it */
    gchar *temp;
    @@ -2405,7 +2443,7 @@
    sound_page(void)
    {
    GtkWidget *ret;
    - GtkWidget *vbox, *vbox2, *sw, *button;
    + GtkWidget *vbox, *vbox2, *sw, *button, *parent, *parent_parent, *parent_parent_parent;
    GtkSizeGroup *sg;
    GtkTreeIter iter;
    GtkWidget *event_view;
    @@ -2502,15 +2540,19 @@
    sound_changed2_cb, vbox);
    #endif
    vbox = pidgin_make_frame(ret, _("Sound Events"));
    -
    + parent = gtk_widget_get_parent(vbox);
    + parent_parent = gtk_widget_get_parent(parent);
    + parent_parent_parent = gtk_widget_get_parent(parent_parent);
    +
    /* The following is an ugly hack to make the frame expand so the
    * sound events list is big enough to be usable */
    - gtk_box_set_child_packing(GTK_BOX(vbox->parent), vbox, TRUE, TRUE, 0,
    + gtk_box_set_child_packing(GTK_BOX(parent), vbox, TRUE, TRUE, 0,
    GTK_PACK_START);
    - gtk_box_set_child_packing(GTK_BOX(vbox->parent->parent), vbox->parent, TRUE,
    - TRUE, 0, GTK_PACK_START);
    - gtk_box_set_child_packing(GTK_BOX(vbox->parent->parent->parent),
    - vbox->parent->parent, TRUE, TRUE, 0, GTK_PACK_START);
    + gtk_box_set_child_packing(GTK_BOX(parent_parent),
    + parent, TRUE, TRUE, 0, GTK_PACK_START);
    + gtk_box_set_child_packing(
    + GTK_BOX(parent_parent_parent),
    + parent_parent, TRUE, TRUE, 0, GTK_PACK_START);
    /* SOUND SELECTION */
    sw = gtk_scrolled_window_new(NULL,NULL);
    --- a/pidgin/gtkprivacy.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkprivacy.c Sun Dec 05 03:10:05 2010 +0000
    @@ -243,7 +243,7 @@
    gtk_widget_hide(dialog->allow_widget);
    gtk_widget_hide(dialog->block_widget);
    - gtk_widget_hide_all(dialog->button_box);
    + gtk_widget_hide(dialog->button_box);
    if (new_type == PURPLE_PRIVACY_ALLOW_USERS) {
    gtk_widget_show(dialog->allow_widget);
    @@ -371,12 +371,12 @@
    dialog->account = pidgin_account_option_menu_get_selected(dropdown);
    /* Add the drop-down list with the allow/block types. */
    - dialog->type_menu = gtk_combo_box_new_text();
    + dialog->type_menu = gtk_combo_box_text_new();
    gtk_box_pack_start(GTK_BOX(vbox), dialog->type_menu, FALSE, FALSE, 0);
    gtk_widget_show(dialog->type_menu);
    for (i = 0; i < menu_entry_count; i++) {
    - gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->type_menu),
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(dialog->type_menu),
    _(menu_entries[i].text));
    if (menu_entries[i].num == dialog->account->perm_deny)
    @@ -442,7 +442,7 @@
    privacy_dialog = privacy_dialog_new();
    gtk_widget_show(privacy_dialog->win);
    - gdk_window_raise(privacy_dialog->win->window);
    + gdk_window_raise(gtk_widget_get_window(privacy_dialog->win));
    }
    void
    --- a/pidgin/gtkrequest.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkrequest.c Sun Dec 05 03:10:05 2010 +0000
    @@ -86,7 +86,9 @@
    {
    GtkWidget *image;
    GdkPixbuf *pixbuf;
    +#if !GTK_CHECK_VERSION(2,12,0)
    GtkTooltips *tips;
    +#endif
    if (!account)
    return;
    @@ -95,12 +97,18 @@
    image = gtk_image_new_from_pixbuf(pixbuf);
    g_object_unref(G_OBJECT(pixbuf));
    +#if GTK_CHECK_VERSION(2,12,0)
    + gtk_widget_set_tooltip_text(image, purple_account_get_username(account));
    +#else
    tips = gtk_tooltips_new();
    gtk_tooltips_set_tip(tips, image, purple_account_get_username(account), NULL);
    +#endif
    if (GTK_IS_DIALOG(cont)) {
    - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(cont)->action_area), image, FALSE, TRUE, 0);
    - gtk_box_reorder_child(GTK_BOX(GTK_DIALOG(cont)->action_area), image, 0);
    + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_action_area(GTK_DIALOG(cont))),
    + image, FALSE, TRUE, 0);
    + gtk_box_reorder_child(GTK_BOX(gtk_dialog_get_action_area(GTK_DIALOG(cont))),
    + image, 0);
    } else if (GTK_IS_HBOX(cont)) {
    gtk_misc_set_alignment(GTK_MISC(image), 0, 0);
    gtk_box_pack_end(GTK_BOX(cont), image, FALSE, TRUE, 0);
    @@ -257,7 +265,7 @@
    {
    generic_response_start(data);
    - if (!GTK_WIDGET_HAS_FOCUS(button))
    + if (!gtk_widget_has_focus(button))
    gtk_widget_grab_focus(button);
    if (data->cbs[0] != NULL)
    @@ -353,16 +361,21 @@
    /* Setup the dialog */
    gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BORDER/2);
    - gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER/2);
    + gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
    + PIDGIN_HIG_BORDER / 2);
    if (!multiline)
    gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
    + /* TODO: not sure how to do this with GTK+ 3
    gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
    + */
    gtk_dialog_set_default_response(GTK_DIALOG(dialog), 0);
    - gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
    + gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
    + PIDGIN_HIG_BORDER);
    /* Setup the main horizontal box */
    hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
    - gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
    + gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
    + hbox);
    /* Dialog icon. */
    img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION,
    @@ -530,14 +543,19 @@
    /* Setup the dialog */
    gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BORDER/2);
    - gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER/2);
    + gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
    + PIDGIN_HIG_BORDER / 2);
    gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
    - gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
    - gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
    + /* TODO: don't know if this is possible with GTK+ 3
    + gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
    + */
    + gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
    + PIDGIN_HIG_BORDER);
    /* Setup the main horizontal box */
    hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
    - gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
    + gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
    + hbox);
    /* Dialog icon. */
    img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION,
    @@ -652,14 +670,19 @@
    /* Setup the dialog */
    gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BORDER/2);
    - gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER/2);
    + gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
    + PIDGIN_HIG_BORDER / 2);
    gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
    - gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
    - gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
    + /* TODO: this is probably not supported by GTK+ 3
    + gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
    + */
    + gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
    + PIDGIN_HIG_BORDER);
    /* Setup the main horizontal box */
    hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
    - gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
    + gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
    + hbox);
    /* Dialog icon. */
    if (icon_data) {
    @@ -730,8 +753,8 @@
    if (default_action == PURPLE_DEFAULT_ACTION_NONE) {
    - GTK_WIDGET_SET_FLAGS(img, GTK_CAN_DEFAULT);
    - GTK_WIDGET_SET_FLAGS(img, GTK_CAN_FOCUS);
    + gtk_widget_set_can_default(img, TRUE);
    + gtk_widget_set_can_focus(img, TRUE);
    gtk_widget_grab_focus(img);
    gtk_widget_grab_default(img);
    } else
    @@ -976,12 +999,12 @@
    if (num_labels > 5)
    {
    - widget = gtk_combo_box_new_text();
    + widget = gtk_combo_box_text_new();
    for (l = labels; l != NULL; l = l->next)
    {
    const char *text = l->data;
    - gtk_combo_box_append_text(GTK_COMBO_BOX(widget), text);
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), text);
    }
    gtk_combo_box_set_active(GTK_COMBO_BOX(widget),
    @@ -1258,12 +1281,12 @@
    /* Cancel button */
    button = pidgin_dialog_add_button(GTK_DIALOG(win), text_to_stock(cancel_text), G_CALLBACK(multifield_cancel_cb), data);
    - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
    + gtk_widget_set_can_default(button, TRUE);
    /* OK button */
    button = pidgin_dialog_add_button(GTK_DIALOG(win), text_to_stock(ok_text), G_CALLBACK(multifield_ok_cb), data);
    data->ok_button = button;
    - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
    + gtk_widget_set_can_default(button, TRUE);
    gtk_window_set_default(GTK_WINDOW(win), button);
    pidgin_widget_decorate_account(hbox, account);
    --- a/pidgin/gtkroomlist.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkroomlist.c Sun Dec 05 03:10:05 2010 +0000
    @@ -359,8 +359,10 @@
    int current_height, max_width;
    int max_text_width;
    GtkTextDirection dir = gtk_widget_get_direction(GTK_WIDGET(grl->tree));
    -
    - style = grl->tipwindow->style;
    + cairo_t *cr =
    + gdk_cairo_create(gtk_widget_get_window(grl->tipwindow));
    +
    + style = gtk_widget_get_style(grl->tipwindow);
    max_text_width = MAX(grl->tip_width, grl->tip_name_width);
    max_width = TOOLTIP_BORDER + SMALL_SPACE + max_text_width + TOOLTIP_BORDER;
    @@ -368,26 +370,28 @@
    current_height = 12;
    if (dir == GTK_TEXT_DIR_RTL) {
    - gtk_paint_layout(style, grl->tipwindow->window, GTK_STATE_NORMAL, FALSE,
    - NULL, grl->tipwindow, "tooltip",
    + gtk_paint_layout(style, cr, GTK_STATE_NORMAL, FALSE,
    + grl->tipwindow, "tooltip",
    max_width - (TOOLTIP_BORDER + SMALL_SPACE) - PANGO_PIXELS(600000),
    current_height, grl->tip_name_layout);
    } else {
    - gtk_paint_layout (style, grl->tipwindow->window, GTK_STATE_NORMAL, FALSE,
    - NULL, grl->tipwindow, "tooltip",
    + gtk_paint_layout (style, cr, GTK_STATE_NORMAL, FALSE,
    + grl->tipwindow, "tooltip",
    TOOLTIP_BORDER + SMALL_SPACE, current_height, grl->tip_name_layout);
    }
    if (dir != GTK_TEXT_DIR_RTL) {
    - gtk_paint_layout (style, grl->tipwindow->window, GTK_STATE_NORMAL, FALSE,
    - NULL, grl->tipwindow, "tooltip",
    + gtk_paint_layout (style, cr, GTK_STATE_NORMAL, FALSE,
    + grl->tipwindow, "tooltip",
    TOOLTIP_BORDER + SMALL_SPACE, current_height + grl->tip_name_height, grl->tip_layout);
    } else {
    - gtk_paint_layout(style, grl->tipwindow->window, GTK_STATE_NORMAL, FALSE,
    - NULL, grl->tipwindow, "tooltip",
    + gtk_paint_layout(style, cr, GTK_STATE_NORMAL, FALSE,
    + grl->tipwindow, "tooltip",
    max_width - (TOOLTIP_BORDER + SMALL_SPACE) - PANGO_PIXELS(600000),
    current_height + grl->tip_name_height,
    grl->tip_layout);
    }
    + cairo_destroy(cr);
    +
    return FALSE;
    }
    --- a/pidgin/gtksavedstatuses.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtksavedstatuses.c Sun Dec 05 03:10:05 2010 +0000
    @@ -535,7 +535,7 @@
    static gboolean
    configure_cb(GtkWidget *widget, GdkEventConfigure *event, StatusWindow *dialog)
    {
    - if (GTK_WIDGET_VISIBLE(widget))
    + if (gtk_widget_get_visible(widget))
    {
    purple_prefs_set_int(PIDGIN_PREFS_ROOT "/status/dialog/width", event->width);
    purple_prefs_set_int(PIDGIN_PREFS_ROOT "/status/dialog/height", event->height);
    --- a/pidgin/gtkscrollbook.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkscrollbook.c Sun Dec 05 03:10:05 2010 +0000
    @@ -102,7 +102,7 @@
    gtk_widget_show_all(GTK_WIDGET(scroll_book));
    if (count < 1)
    - gtk_widget_hide_all(scroll_book->hbox);
    + gtk_widget_hide(scroll_book->hbox);
    else {
    gtk_widget_show_all(scroll_book->hbox);
    if (count == 1) {
    @@ -147,7 +147,7 @@
    }
    static void
    -switch_page_cb(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, PidginScrollBook *scroll_book)
    +switch_page_cb(GtkNotebook *notebook, GtkWidget *page, guint page_num, PidginScrollBook *scroll_book)
    {
    int count;
    count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book->notebook));
    @@ -160,7 +160,7 @@
    PidginScrollBook *scroll_book;
    g_return_if_fail(GTK_IS_WIDGET (widget));
    - g_return_if_fail (widget->parent == NULL);
    + g_return_if_fail (gtk_widget_get_parent(widget) == NULL);
    scroll_book = PIDGIN_SCROLL_BOOK(container);
    scroll_book->children = g_list_append(scroll_book->children, widget);
    --- a/pidgin/gtksmiley.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtksmiley.c Sun Dec 05 03:10:05 2010 +0000
    @@ -399,7 +399,7 @@
    window = gtk_dialog_new_with_buttons(smiley ? _("Edit Smiley") : _("Add Smiley"),
    widget ? GTK_WINDOW(widget) : NULL,
    - GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
    + GTK_DIALOG_DESTROY_WITH_PARENT,
    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
    smiley ? GTK_STOCK_SAVE : GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT,
    NULL);
    @@ -414,7 +414,8 @@
    /* The vbox */
    vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER);
    - gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->vbox), vbox);
    + gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(window))),
    + vbox);
    gtk_widget_show(vbox);
    /* The hbox */
    @@ -727,9 +728,10 @@
    GtkSelectionData *sd, guint info, guint t, gpointer user_data)
    {
    SmileyManager *dialog = user_data;
    - gchar *name = g_strchomp((gchar *)sd->data);
    -
    - if ((sd->length >= 0) && (sd->format == 8)) {
    + gchar *name = g_strchomp((gchar *) gtk_selection_data_get_data(sd));
    +
    + if ((gtk_selection_data_get_length(sd) >= 0)
    + && (gtk_selection_data_get_format(sd) == 8)) {
    /* Well, it looks like the drag event was cool.
    * Let's do something with it */
    @@ -895,7 +897,8 @@
    /* The vbox */
    vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER);
    - gtk_container_add(GTK_CONTAINER(GTK_DIALOG(win)->vbox), vbox);
    + gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(win))),
    + vbox);
    gtk_widget_show(vbox);
    /* get the scrolled window with all stuff */
    --- a/pidgin/gtksourceundomanager.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtksourceundomanager.c Sun Dec 05 03:10:05 2010 +0000
    @@ -532,7 +532,8 @@
    um->priv->document,
    undo_action->action.insert_anchor.pos,
    undo_action->action.insert_anchor.pos + 1);
    - undo_action->action.insert_anchor.anchor->segment = NULL; /* XXX: This may be a bug in GTK+ */
    + /* TODO: is this needed in GTK+ 3? */
    + /*gtk_text_child_anchor_set_segment(undo_action->action.insert_anchor.anchor, NULL); XXX: This may be a bug in GTK+ */
    break;
    default:
    /* Unknown action type. */
    --- a/pidgin/gtkstatusbox.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkstatusbox.c Sun Dec 05 03:10:05 2010 +0000
    @@ -82,9 +82,10 @@
    static void status_menu_refresh_iter(PidginStatusBox *status_box, gboolean status_changed);
    static void pidgin_status_box_regenerate(PidginStatusBox *status_box, gboolean status_changed);
    static void pidgin_status_box_changed(PidginStatusBox *box);
    -static void pidgin_status_box_size_request (GtkWidget *widget, GtkRequisition *requisition);
    +static void pidgin_status_box_get_preferred_height (GtkWidget *widget,
    + gint *minimum_height, gint *natural_height);
    static void pidgin_status_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
    -static gboolean pidgin_status_box_expose_event (GtkWidget *widget, GdkEventExpose *event);
    +static gboolean pidgin_status_box_draw (GtkWidget *widget, cairo_t *cr);
    static void pidgin_status_box_redisplay_buddy_icon(PidginStatusBox *status_box);
    static void pidgin_status_box_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data);
    static void pidgin_status_box_popup(PidginStatusBox *box);
    @@ -282,7 +283,7 @@
    if (!message || !*message)
    {
    - gtk_widget_hide_all(status_box->vbox);
    + gtk_widget_hide(status_box->vbox);
    status_box->imhtml_visible = FALSE;
    }
    else
    @@ -343,9 +344,10 @@
    icon_box_dnd_cb(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
    GtkSelectionData *sd, guint info, guint t, PidginStatusBox *box)
    {
    - gchar *name = (gchar *)sd->data;
    -
    - if ((sd->length >= 0) && (sd->format == 8)) {
    + gchar *name = (gchar *) gtk_selection_data_get_data(sd);
    +
    + if ((gtk_selection_data_get_length(sd) >= 0)
    + && (gtk_selection_data_get_format(sd) == 8)) {
    /* Well, it looks like the drag event was cool.
    * Let's do something with it */
    if (!g_ascii_strncasecmp(name, "file://", 7)) {
    @@ -419,7 +421,7 @@
    static gboolean
    icon_box_enter_cb(GtkWidget *widget, GdkEventCrossing *event, PidginStatusBox *box)
    {
    - gdk_window_set_cursor(widget->window, box->hand_cursor);
    + gdk_window_set_cursor(gtk_widget_get_window(widget), box->hand_cursor);
    gtk_image_set_from_pixbuf(GTK_IMAGE(box->icon), box->buddy_icon_hover);
    return FALSE;
    }
    @@ -427,7 +429,7 @@
    static gboolean
    icon_box_leave_cb(GtkWidget *widget, GdkEventCrossing *event, PidginStatusBox *box)
    {
    - gdk_window_set_cursor(widget->window, box->arrow_cursor);
    + gdk_window_set_cursor(gtk_widget_get_window(widget), box->arrow_cursor);
    gtk_image_set_from_pixbuf(GTK_IMAGE(box->icon), box->buddy_icon) ;
    return FALSE;
    }
    @@ -615,9 +617,9 @@
    parent_class = g_type_class_peek_parent(klass);
    widget_class = (GtkWidgetClass*)klass;
    - widget_class->size_request = pidgin_status_box_size_request;
    + widget_class->get_preferred_height = pidgin_status_box_get_preferred_height;
    widget_class->size_allocate = pidgin_status_box_size_allocate;
    - widget_class->expose_event = pidgin_status_box_expose_event;
    + widget_class->draw = pidgin_status_box_draw;
    container_class->child_type = pidgin_status_box_child_type;
    container_class->forall = pidgin_status_box_forall;
    @@ -931,7 +933,7 @@
    if (!purple_savedstatus_is_transient(saved_status) || !message || !*message)
    {
    status_box->imhtml_visible = FALSE;
    - gtk_widget_hide_all(status_box->vbox);
    + gtk_widget_hide(status_box->vbox);
    }
    else
    {
    @@ -1135,7 +1137,7 @@
    static gboolean imhtml_remove_focus(GtkWidget *w, GdkEventKey *event, PidginStatusBox *status_box)
    {
    - if (event->keyval == GDK_Tab || event->keyval == GDK_KP_Tab || event->keyval == GDK_ISO_Left_Tab)
    + if (event->keyval == GDK_KEY_Tab || event->keyval == GDK_KEY_KP_Tab || event->keyval == GDK_KEY_ISO_Left_Tab)
    {
    /* If last inserted character is a tab, then remove the focus from here */
    GtkWidget *top = gtk_widget_get_toplevel(w);
    @@ -1148,7 +1150,7 @@
    return FALSE;
    /* Reset the status if Escape was pressed */
    - if (event->keyval == GDK_Escape)
    + if (event->keyval == GDK_KEY_Escape)
    {
    purple_timeout_remove(status_box->typing);
    status_box->typing = 0;
    @@ -1299,13 +1301,15 @@
    GdkRectangle monitor;
    GtkRequisition popup_req;
    GtkPolicyType hpolicy, vpolicy;
    -
    - gdk_window_get_origin (GTK_WIDGET(status_box)->window, x, y);
    -
    - *x += GTK_WIDGET(status_box)->allocation.x;
    - *y += GTK_WIDGET(status_box)->allocation.y;
    -
    - *width = GTK_WIDGET(status_box)->allocation.width;
    + GtkAllocation allocation;
    +
    + gtk_widget_get_allocation(GTK_WIDGET(status_box), &allocation);
    + gdk_window_get_origin (gtk_widget_get_window(GTK_WIDGET(status_box)), x, y);
    +
    + *x += allocation.x;
    + *y += allocation.y;
    +
    + *width = allocation.width;
    hpolicy = vpolicy = GTK_POLICY_NEVER;
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (status_box->scrolled_window),
    @@ -1324,7 +1328,7 @@
    screen = gtk_widget_get_screen (GTK_WIDGET (status_box));
    monitor_num = gdk_screen_get_monitor_at_window (screen,
    - GTK_WIDGET (status_box)->window);
    + gtk_widget_get_window(GTK_WIDGET (status_box)));
    gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
    if (*x < monitor.x)
    @@ -1332,13 +1336,13 @@
    else if (*x + *width > monitor.x + monitor.width)
    *x = monitor.x + monitor.width - *width;
    - if (*y + GTK_WIDGET(status_box)->allocation.height + *height <= monitor.y + monitor.height)
    - *y += GTK_WIDGET(status_box)->allocation.height;
    + if (*y + allocation.height + *height <= monitor.y + monitor.height)
    + *y += allocation.height;
    else if (*y - *height >= monitor.y)
    *y -= *height;
    - else if (monitor.y + monitor.height - (*y + GTK_WIDGET(status_box)->allocation.height) > *y - monitor.y)
    + else if (monitor.y + monitor.height - (*y + allocation.height) > *y - monitor.y)
    {
    - *y += GTK_WIDGET(status_box)->allocation.height;
    + *y += allocation.height;
    *height = monitor.y + monitor.height - *y;
    }
    else
    @@ -1369,7 +1373,7 @@
    if (!grab_keyboard || gdk_keyboard_grab (window, TRUE, activate_time) == 0)
    return TRUE;
    else {
    - gdk_display_pointer_ungrab (gdk_drawable_get_display (window), activate_time);
    + gdk_display_pointer_ungrab (gdk_window_get_display (window), activate_time);
    return FALSE;
    }
    }
    @@ -1388,7 +1392,7 @@
    gtk_window_move (GTK_WINDOW (box->popup_window), x, y);
    gtk_widget_show(box->popup_window);
    gtk_widget_grab_focus (box->tree_view);
    - if (!popup_grab_on_window (box->popup_window->window,
    + if (!popup_grab_on_window (gtk_widget_get_window(box->popup_window),
    GDK_CURRENT_TIME, TRUE)) {
    gtk_widget_hide (box->popup_window);
    return;
    @@ -1419,10 +1423,10 @@
    toggle_key_press_cb(GtkWidget *widget, GdkEventKey *event, PidginStatusBox *box)
    {
    switch (event->keyval) {
    - case GDK_Return:
    - case GDK_KP_Enter:
    - case GDK_KP_Space:
    - case GDK_space:
    + case GDK_KEY_Return:
    + case GDK_KEY_KP_Enter:
    + case GDK_KEY_KP_Space:
    + case GDK_KEY_space:
    if (!box->popup_in_progress) {
    pidgin_status_box_popup (box);
    box->popup_in_progress = TRUE;
    @@ -1654,7 +1658,7 @@
    GdkEventKey *event, PidginStatusBox *box)
    {
    if (box->popup_in_progress) {
    - if (event->keyval == GDK_Escape) {
    + if (event->keyval == GDK_KEY_Escape) {
    pidgin_status_box_popdown(box);
    return TRUE;
    } else {
    @@ -1665,9 +1669,9 @@
    if (gtk_tree_selection_get_selected(sel, NULL, &iter)) {
    gboolean ret = TRUE;
    path = gtk_tree_model_get_path(GTK_TREE_MODEL(box->dropdown_store), &iter);
    - if (event->keyval == GDK_Return) {
    + if (event->keyval == GDK_KEY_Return) {
    treeview_activate_current_selection(box, path);
    - } else if (event->keyval == GDK_Delete) {
    + } else if (event->keyval == GDK_KEY_Delete) {
    tree_view_delete_current_selection(box, path);
    } else
    ret = FALSE;
    @@ -1743,7 +1747,7 @@
    GtkWidget *toplevel;
    GtkTreeSelection *sel;
    - GTK_WIDGET_SET_FLAGS (status_box, GTK_NO_WINDOW);
    + gtk_widget_set_has_window(GTK_WIDGET(status_box), FALSE);
    status_box->imhtml_visible = FALSE;
    status_box->network_available = purple_network_is_available();
    status_box->connecting = FALSE;
    @@ -1928,24 +1932,27 @@
    }
    static void
    -pidgin_status_box_size_request(GtkWidget *widget,
    - GtkRequisition *requisition)
    +pidgin_status_box_get_preferred_height(GtkWidget *widget, gint *minimum_height,
    + gint *natural_height)
    {
    - GtkRequisition box_req;
    - gint border_width = GTK_CONTAINER (widget)->border_width;
    -
    - gtk_widget_size_request(PIDGIN_STATUS_BOX(widget)->toggle_button, requisition);
    -
    - /* Make this icon the same size as other buddy icons in the list; unless it already wants to be bigger */
    - requisition->height = MAX(requisition->height, 34);
    - requisition->height += border_width * 2;
    + gint box_min_height, box_nat_height;
    + gint border_width = gtk_container_get_border_width(GTK_CONTAINER (widget));
    +
    + gtk_widget_get_preferred_height(PIDGIN_STATUS_BOX(widget)->toggle_button,
    + minimum_height, natural_height);
    +
    + *minimum_height = MAX(*minimum_height, 34) + border_width * 2;
    + *natural_height = MAX(*natural_height, 34) + border_width * 2;
    /* If the gtkimhtml is visible, then add some additional padding */
    - gtk_widget_size_request(PIDGIN_STATUS_BOX(widget)->vbox, &box_req);
    - if (box_req.height > 1)
    - requisition->height += box_req.height + border_width * 2;
    -
    - requisition->width = 1;
    + gtk_widget_get_preferred_height(PIDGIN_STATUS_BOX(widget)->vbox,
    + &box_min_height, &box_nat_height);
    +
    + if (box_min_height > 1)
    + *minimum_height += box_min_height + border_width * 2;
    +
    + if (box_nat_height > 1)
    + *natural_height += box_nat_height + border_width * 2;
    }
    /* From gnome-panel */
    @@ -1993,9 +2000,9 @@
    GtkAllocation *allocation)
    {
    PidginStatusBox *status_box = PIDGIN_STATUS_BOX(widget);
    - GtkRequisition req = {0,0};
    + GtkRequisition req = {0,40};
    GtkAllocation parent_alc, box_alc, icon_alc;
    - gint border_width = GTK_CONTAINER (widget)->border_width;
    + gint border_width = gtk_container_get_border_width(GTK_CONTAINER (widget));
    gtk_widget_size_request(status_box->toggle_button, &req);
    /* Make this icon the same size as other buddy icons in the list; unless it already wants to be bigger */
    @@ -2034,19 +2041,24 @@
    gtk_widget_size_allocate(status_box->icon_box, &icon_alc);
    }
    gtk_widget_size_allocate(status_box->toggle_button, &parent_alc);
    - widget->allocation = *allocation;
    + gtk_widget_set_allocation(GTK_WIDGET(status_box), allocation);
    + purple_debug_info("pidgin", "statusbox allocation: width = %d, height = %d\n",
    + allocation->width, allocation->height);
    }
    static gboolean
    -pidgin_status_box_expose_event(GtkWidget *widget,
    - GdkEventExpose *event)
    +pidgin_status_box_draw(GtkWidget *widget, cairo_t *cr)
    {
    PidginStatusBox *status_box = PIDGIN_STATUS_BOX(widget);
    - gtk_container_propagate_expose(GTK_CONTAINER(widget), status_box->vbox, event);
    - gtk_container_propagate_expose(GTK_CONTAINER(widget), status_box->toggle_button, event);
    + gtk_widget_draw(status_box->vbox, cr);
    + gtk_widget_draw(status_box->toggle_button, cr);
    +
    if (status_box->icon_box && status_box->icon_opaque) {
    - gtk_paint_box(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL,
    - status_box->icon_box, "button", status_box->icon_box->allocation.x-1, status_box->icon_box->allocation.y-1,
    + GtkAllocation allocation;
    +
    + gtk_widget_get_allocation(status_box->icon_box, &allocation);
    + gtk_paint_box(gtk_widget_get_style(widget), cr, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
    + status_box->icon_box, "button", allocation.x-1, allocation.y-1,
    34, 34);
    }
    return FALSE;
    @@ -2333,7 +2345,7 @@
    message = pidgin_status_box_get_message(status_box);
    if (!message || !*message)
    {
    - gtk_widget_hide_all(status_box->vbox);
    + gtk_widget_hide(status_box->vbox);
    status_box->imhtml_visible = FALSE;
    if (message != NULL)
    {
    @@ -2605,7 +2617,7 @@
    purple_timeout_remove(status_box->typing);
    status_box->typing = 0;
    - if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(status_box)))
    + if (gtk_widget_get_sensitive(GTK_WIDGET(status_box)))
    {
    if (type == PIDGIN_STATUS_BOX_TYPE_POPULAR || type == PIDGIN_STATUS_BOX_TYPE_SAVED_POPULAR)
    {
    @@ -2667,7 +2679,7 @@
    }
    g_list_free(accounts);
    - if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(status_box)))
    + if (gtk_widget_get_sensitive(GTK_WIDGET(status_box)))
    {
    if (status_box->imhtml_visible)
    {
    @@ -2687,7 +2699,7 @@
    }
    else
    {
    - gtk_widget_hide_all(status_box->vbox);
    + gtk_widget_hide(status_box->vbox);
    activate_currently_selected_status(status_box); /* This is where we actually set the status */
    }
    }
    @@ -2723,7 +2735,7 @@
    static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data)
    {
    PidginStatusBox *status_box = (PidginStatusBox*)data;
    - if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(status_box)))
    + if (gtk_widget_get_sensitive(GTK_WIDGET(status_box)))
    {
    if (status_box->typing != 0) {
    pidgin_status_box_pulse_typing(status_box);
    --- a/pidgin/gtkutils.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkutils.c Sun Dec 05 03:10:05 2010 +0000
    @@ -70,7 +70,7 @@
    #include "pidgin/minidialog.h"
    typedef struct {
    - GtkWidget *menu;
    + GtkTreeModel *model;
    gint default_item;
    } AopMenu;
    @@ -180,7 +180,6 @@
    wnd = GTK_WINDOW(gtk_dialog_new());
    pidgin_window_init(wnd, title, border_width, role, resizable);
    - g_object_set(G_OBJECT(wnd), "has-separator", FALSE, NULL);
    return GTK_WIDGET(wnd);
    }
    @@ -188,7 +187,7 @@
    GtkWidget *
    pidgin_dialog_get_vbox_with_properties(GtkDialog *dialog, gboolean homogeneous, gint spacing)
    {
    - GtkBox *vbox = GTK_BOX(GTK_DIALOG(dialog)->vbox);
    + GtkBox *vbox = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog)));
    gtk_box_set_homogeneous(vbox, homogeneous);
    gtk_box_set_spacing(vbox, spacing);
    return GTK_WIDGET(vbox);
    @@ -196,12 +195,12 @@
    GtkWidget *pidgin_dialog_get_vbox(GtkDialog *dialog)
    {
    - return GTK_DIALOG(dialog)->vbox;
    + return gtk_dialog_get_content_area(GTK_DIALOG(dialog));
    }
    GtkWidget *pidgin_dialog_get_action_area(GtkDialog *dialog)
    {
    - return GTK_DIALOG(dialog)->action_area;
    + return gtk_dialog_get_action_area(GTK_DIALOG(dialog));
    }
    GtkWidget *pidgin_dialog_add_button(GtkDialog *dialog, const char *label,
    @@ -297,7 +296,7 @@
    if (to_toggle == NULL)
    return;
    - sensitivity = GTK_WIDGET_IS_SENSITIVE(to_toggle);
    + sensitivity = gtk_widget_get_sensitive(to_toggle);
    gtk_widget_set_sensitive(to_toggle, !sensitivity);
    }
    @@ -314,7 +313,7 @@
    if (element == NULL)
    continue;
    - sensitivity = GTK_WIDGET_IS_SENSITIVE(element);
    + sensitivity = gtk_widget_get_sensitive(element);
    gtk_widget_set_sensitive(element, !sensitivity);
    }
    @@ -326,7 +325,7 @@
    if (to_toggle == NULL)
    return;
    - if (GTK_WIDGET_VISIBLE(to_toggle))
    + if (gtk_widget_get_visible(to_toggle))
    gtk_widget_hide(to_toggle);
    else
    gtk_widget_show(to_toggle);
    @@ -527,68 +526,35 @@
    }
    static gpointer
    -aop_option_menu_get_selected(GtkWidget *optmenu, GtkWidget **p_item)
    +aop_option_menu_get_selected(GtkWidget *optmenu)
    {
    - GtkWidget *menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu));
    - GtkWidget *item = gtk_menu_get_active(GTK_MENU(menu));
    - if (p_item)
    - (*p_item) = item;
    - return item ? g_object_get_data(G_OBJECT(item), "aop_per_item_data") : NULL;
    + gpointer data = NULL;
    + GtkTreeIter iter;
    +
    + g_return_val_if_fail(optmenu != NULL, NULL);
    +
    + if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(optmenu), &iter))
    + gtk_tree_model_get(gtk_combo_box_get_model(GTK_COMBO_BOX(optmenu)), &iter, 2, &data, -1);
    +
    + return data;
    }
    static void
    aop_menu_cb(GtkWidget *optmenu, GCallback cb)
    {
    - GtkWidget *item;
    - gpointer per_item_data;
    -
    - per_item_data = aop_option_menu_get_selected(optmenu, &item);
    -
    if (cb != NULL) {
    - ((void (*)(GtkWidget *, gpointer, gpointer))cb)(item, per_item_data, g_object_get_data(G_OBJECT(optmenu), "user_data"));
    + ((void (*)(GtkWidget *, gpointer, gpointer))cb)(optmenu,
    + aop_option_menu_get_selected(optmenu),
    + g_object_get_data(G_OBJECT(optmenu), "user_data"));
    }
    }
    -static GtkWidget *
    -aop_menu_item_new(GtkSizeGroup *sg, GdkPixbuf *pixbuf, const char *lbl, gpointer per_item_data, const char *data)
    +static void
    +aop_option_menu_replace_menu(GtkWidget *optmenu, AopMenu *new_aop_menu)
    {
    - GtkWidget *item;
    - GtkWidget *hbox;
    - GtkWidget *image;
    - GtkWidget *label;
    -
    - item = gtk_menu_item_new();
    - gtk_widget_show(item);
    -
    - hbox = gtk_hbox_new(FALSE, 4);
    - gtk_widget_show(hbox);
    -
    - /* Create the image */
    - if (pixbuf == NULL)
    - image = gtk_image_new();
    - else
    - image = gtk_image_new_from_pixbuf(pixbuf);
    - gtk_widget_show(image);
    -
    - if (sg)
    - gtk_size_group_add_widget(sg, image);
    -
    - /* Create the label */
    - label = gtk_label_new (lbl);
    - gtk_widget_show (label);
    - gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
    - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    -
    - gtk_container_add(GTK_CONTAINER(item), hbox);
    - gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
    - gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
    -
    - g_object_set_data(G_OBJECT (item), data, per_item_data);
    - g_object_set_data(G_OBJECT (item), "aop_per_item_data", per_item_data);
    -
    - pidgin_set_accessible_label(item, label);
    -
    - return item;
    + gtk_combo_box_set_model(GTK_COMBO_BOX(optmenu), new_aop_menu->model);
    + gtk_combo_box_set_active(GTK_COMBO_BOX(optmenu), new_aop_menu->default_item);
    + g_object_set_data_full(G_OBJECT(optmenu), "aop_menu", new_aop_menu, (GDestroyNotify)g_free);
    }
    static GdkPixbuf *
    @@ -629,16 +595,19 @@
    static GtkWidget *
    aop_option_menu_new(AopMenu *aop_menu, GCallback cb, gpointer user_data)
    {
    - GtkWidget *optmenu;
    -
    - optmenu = gtk_option_menu_new();
    + GtkWidget *optmenu = NULL;
    + GtkCellRenderer *cr = NULL;
    +
    + optmenu = gtk_combo_box_new();
    gtk_widget_show(optmenu);
    - gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), aop_menu->menu);
    -
    - if (aop_menu->default_item != -1)
    - gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), aop_menu->default_item);
    -
    - g_object_set_data_full(G_OBJECT(optmenu), "aop_menu", aop_menu, (GDestroyNotify)g_free);
    + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(optmenu), cr = gtk_cell_renderer_pixbuf_new(), FALSE);
    + gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(optmenu), cr, "pixbuf", 0);
    + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(optmenu), cr = gtk_cell_renderer_text_new(), TRUE);
    + gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(optmenu), cr, "text", 1);
    +
    + aop_option_menu_replace_menu(optmenu, aop_menu);
    + if (aop_menu->default_item == -1)
    + gtk_combo_box_set_active(GTK_COMBO_BOX(optmenu), 0);
    g_object_set_data(G_OBJECT(optmenu), "user_data", user_data);
    g_signal_connect(G_OBJECT(optmenu), "changed", G_CALLBACK(aop_menu_cb), cb);
    @@ -647,32 +616,20 @@
    }
    static void
    -aop_option_menu_replace_menu(GtkWidget *optmenu, AopMenu *new_aop_menu)
    -{
    - if (gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)))
    - gtk_option_menu_remove_menu(GTK_OPTION_MENU(optmenu));
    -
    - gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), new_aop_menu->menu);
    -
    - if (new_aop_menu->default_item != -1)
    - gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), new_aop_menu->default_item);
    -
    - g_object_set_data_full(G_OBJECT(optmenu), "aop_menu", new_aop_menu, (GDestroyNotify)g_free);
    -}
    -
    -static void
    aop_option_menu_select_by_data(GtkWidget *optmenu, gpointer data)
    {
    - guint idx;
    - GList *llItr = NULL;
    -
    - for (idx = 0, llItr = GTK_MENU_SHELL(gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)))->children;
    - llItr != NULL;
    - llItr = llItr->next, idx++) {
    - if (data == g_object_get_data(G_OBJECT(llItr->data), "aop_per_item_data")) {
    - gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), idx);
    - break;
    - }
    + GtkTreeModel *model;
    + GtkTreeIter iter;
    + gpointer iter_data;
    + model = gtk_combo_box_get_model(GTK_COMBO_BOX(optmenu));
    + if (gtk_tree_model_get_iter_first(model, &iter)) {
    + do {
    + gtk_tree_model_get(model, &iter, 2, &iter_data, -1);
    + if (iter_data == data) {
    + gtk_combo_box_set_active_iter(GTK_COMBO_BOX(optmenu), &iter);
    + return;
    + }
    + } while (gtk_tree_model_iter_next(model, &iter));
    }
    }
    @@ -682,16 +639,17 @@
    AopMenu *aop_menu = NULL;
    PurplePlugin *plugin;
    GdkPixbuf *pixbuf = NULL;
    - GtkSizeGroup *sg;
    + GtkTreeIter iter;
    + GtkListStore *ls;
    GList *p;
    const char *gtalk_name = NULL;
    int i;
    + ls = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
    +
    aop_menu = g_malloc0(sizeof(AopMenu));
    aop_menu->default_item = -1;
    - aop_menu->menu = gtk_menu_new();
    - gtk_widget_show(aop_menu->menu);
    - sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
    + aop_menu->model = GTK_TREE_MODEL(ls);
    if (purple_find_prpl("prpl-jabber"))
    gtalk_name = _("Google Talk");
    @@ -705,14 +663,11 @@
    if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) {
    char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols",
    "16", "google-talk.png", NULL);
    - GtkWidget *item;
    -
    pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
    g_free(filename);
    - gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu),
    - item = aop_menu_item_new(sg, pixbuf, gtalk_name, "prpl-jabber", "protocol"));
    - g_object_set_data(G_OBJECT(item), "fake", GINT_TO_POINTER(1));
    + gtk_list_store_append(ls, &iter);
    + gtk_list_store_set(ls, &iter, 0, pixbuf, 1, gtalk_name, 2, "prpl-jabber", -1);
    if (pixbuf)
    g_object_unref(pixbuf);
    @@ -723,8 +678,8 @@
    pixbuf = pidgin_create_prpl_icon_from_prpl(plugin, PIDGIN_PRPL_ICON_SMALL, NULL);
    - gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu),
    - aop_menu_item_new(sg, pixbuf, plugin->info->name, plugin->info->id, "protocol"));
    + gtk_list_store_append(ls, &iter);
    + gtk_list_store_set(ls, &iter, 0, pixbuf, 1, plugin->info->name, 2, plugin->info->id, -1);
    if (pixbuf)
    g_object_unref(pixbuf);
    @@ -732,9 +687,6 @@
    if (default_proto_id != NULL && !strcmp(plugin->info->id, default_proto_id))
    aop_menu->default_item = i;
    }
    -
    - g_object_unref(sg);
    -
    return aop_menu;
    }
    @@ -748,13 +700,13 @@
    const char *
    pidgin_protocol_option_menu_get_selected(GtkWidget *optmenu)
    {
    - return (const char *)aop_option_menu_get_selected(optmenu, NULL);
    + return (const char *)aop_option_menu_get_selected(optmenu);
    }
    PurpleAccount *
    pidgin_account_option_menu_get_selected(GtkWidget *optmenu)
    {
    - return (PurpleAccount *)aop_option_menu_get_selected(optmenu, NULL);
    + return (PurpleAccount *)aop_option_menu_get_selected(optmenu);
    }
    static AopMenu *
    @@ -766,7 +718,8 @@
    GdkPixbuf *pixbuf = NULL;
    GList *list;
    GList *p;
    - GtkSizeGroup *sg;
    + GtkListStore *ls;
    + GtkTreeIter iter;
    int i;
    char buf[256];
    @@ -775,11 +728,11 @@
    else
    list = purple_connections_get_all();
    + ls = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
    +
    aop_menu = g_malloc0(sizeof(AopMenu));
    aop_menu->default_item = -1;
    - aop_menu->menu = gtk_menu_new();
    - gtk_widget_show(aop_menu->menu);
    - sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
    + aop_menu->model = GTK_TREE_MODEL(ls);
    for (p = list, i = 0; p != NULL; p = p->next, i++) {
    if (show_all)
    @@ -814,8 +767,8 @@
    purple_account_get_protocol_name(account));
    }
    - gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu),
    - aop_menu_item_new(sg, pixbuf, buf, account, "account"));
    + gtk_list_store_append(ls, &iter);
    + gtk_list_store_set(ls, &iter, 0, pixbuf, 1, buf, 2, account, -1);
    if (pixbuf)
    g_object_unref(pixbuf);
    @@ -823,9 +776,6 @@
    if (default_account && account == default_account)
    aop_menu->default_item = i;
    }
    -
    - g_object_unref(sg);
    -
    return aop_menu;
    }
    @@ -836,7 +786,7 @@
    PurpleAccount *account;
    PurpleFilterAccountFunc filter_func;
    - account = (PurpleAccount *)aop_option_menu_get_selected(optmenu, NULL);
    + account = (PurpleAccount *)aop_option_menu_get_selected(optmenu);
    show_all = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(optmenu), "show_all"));
    filter_func = g_object_get_data(G_OBJECT(optmenu), "filter_func");
    @@ -906,24 +856,6 @@
    return optmenu;
    }
    -gboolean
    -pidgin_check_if_dir(const char *path, GtkFileSelection *filesel)
    -{
    - char *dirname = NULL;
    -
    - if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
    - /* append a / if needed */
    - if (path[strlen(path) - 1] != G_DIR_SEPARATOR) {
    - dirname = g_strconcat(path, G_DIR_SEPARATOR_S, NULL);
    - }
    - gtk_file_selection_set_filename(filesel, (dirname != NULL) ? dirname : path);
    - g_free(dirname);
    - return TRUE;
    - }
    -
    - return FALSE;
    -}
    -
    void
    pidgin_setup_gtkspell(GtkTextView *textview)
    {
    @@ -1278,8 +1210,8 @@
    widget = GTK_WIDGET(menu);
    screen = gtk_widget_get_screen(widget);
    - xthickness = widget->style->xthickness;
    - ythickness = widget->style->ythickness;
    + xthickness = gtk_widget_get_style(widget)->xthickness;
    + ythickness = gtk_widget_get_style(widget)->ythickness;
    rtl = (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL);
    /*
    @@ -1417,9 +1349,9 @@
    GtkTreePath *path;
    GtkTreeViewColumn *col;
    GdkRectangle rect;
    - gint ythickness = GTK_WIDGET(menu)->style->ythickness;
    -
    - gdk_window_get_origin (widget->window, x, y);
    + gint ythickness = gtk_widget_get_style(GTK_WIDGET(menu))->ythickness;
    +
    + gdk_window_get_origin (gtk_widget_get_window(widget), x, y);
    gtk_tree_view_get_cursor (tv, &path, &col);
    gtk_tree_view_get_cell_area (tv, path, col, &rect);
    @@ -1533,7 +1465,7 @@
    pidgin_dnd_file_manage(GtkSelectionData *sd, PurpleAccount *account, const char *who)
    {
    GdkPixbuf *pb;
    - GList *files = purple_uri_list_extract_filenames((const gchar *)sd->data);
    + GList *files = purple_uri_list_extract_filenames((const gchar *) gtk_selection_data_get_data(sd));
    PurpleConnection *gc = purple_account_get_connection(account);
    PurplePluginProtocolInfo *prpl_info = NULL;
    #ifndef _WIN32
    @@ -1851,7 +1783,9 @@
    group = gtk_menu_get_accel_group(GTK_MENU(menu));
    if (group) {
    - char *path = g_strdup_printf("%s/%s", GTK_MENU_ITEM(menuitem)->accel_path, act->label);
    + char *path = g_strdup_printf("%s/%s",
    + gtk_menu_item_get_accel_path(GTK_MENU_ITEM(menuitem)),
    + act->label);
    gtk_menu_set_accel_path(GTK_MENU(submenu), path);
    g_free(path);
    gtk_menu_set_accel_group(GTK_MENU(submenu), group);
    @@ -2174,23 +2108,23 @@
    GdkCursor *cursor;
    g_return_if_fail(widget != NULL);
    - if (widget->window == NULL)
    + if (gtk_widget_get_window(widget) == NULL)
    return;
    cursor = gdk_cursor_new(cursor_type);
    - gdk_window_set_cursor(widget->window, cursor);
    + gdk_window_set_cursor(gtk_widget_get_window(widget), cursor);
    gdk_cursor_unref(cursor);
    - gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(widget->window)));
    + gdk_display_flush(gdk_window_get_display(gtk_widget_get_window(widget)));
    }
    void pidgin_clear_cursor(GtkWidget *widget)
    {
    g_return_if_fail(widget != NULL);
    - if (widget->window == NULL)
    + if (gtk_widget_get_window(widget) == NULL)
    return;
    - gdk_window_set_cursor(widget->window, NULL);
    + gdk_window_set_cursor(gtk_widget_get_window(widget), NULL);
    }
    struct _icon_chooser {
    @@ -2877,18 +2811,18 @@
    }
    static void
    -combo_box_changed_cb(GtkComboBox *combo_box, GtkEntry *entry)
    +combo_box_changed_cb(GtkComboBoxText *combo_box, GtkEntry *entry)
    {
    - char *text = gtk_combo_box_get_active_text(combo_box);
    + char *text = gtk_combo_box_text_get_active_text(combo_box);
    gtk_entry_set_text(entry, text ? text : "");
    g_free(text);
    }
    static gboolean
    -entry_key_pressed_cb(GtkWidget *entry, GdkEventKey *key, GtkComboBox *combo)
    +entry_key_pressed_cb(GtkWidget *entry, GdkEventKey *key, GtkComboBoxText *combo)
    {
    - if (key->keyval == GDK_Down || key->keyval == GDK_Up) {
    - gtk_combo_box_popup(combo);
    + if (key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_Up) {
    + gtk_combo_box_popup(GTK_COMBO_BOX(combo));
    return TRUE;
    }
    return FALSE;
    @@ -2897,10 +2831,10 @@
    GtkWidget *
    pidgin_text_combo_box_entry_new(const char *default_item, GList *items)
    {
    - GtkComboBox *ret = NULL;
    + GtkComboBoxText *ret = NULL;
    GtkWidget *the_entry = NULL;
    - ret = GTK_COMBO_BOX(gtk_combo_box_new_text());
    + ret = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
    the_entry = gtk_entry_new();
    gtk_container_add(GTK_CONTAINER(ret), the_entry);
    @@ -2910,7 +2844,7 @@
    for (; items != NULL ; items = items->next) {
    char *text = items->data;
    if (text && *text)
    - gtk_combo_box_append_text(ret, text);
    + gtk_combo_box_text_append_text(ret, text);
    }
    g_signal_connect(G_OBJECT(ret), "changed", (GCallback)combo_box_changed_cb, the_entry);
    @@ -2921,12 +2855,12 @@
    const char *pidgin_text_combo_box_entry_get_text(GtkWidget *widget)
    {
    - return gtk_entry_get_text(GTK_ENTRY(GTK_BIN((widget))->child));
    + return gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((widget)))));
    }
    void pidgin_text_combo_box_entry_set_text(GtkWidget *widget, const char *text)
    {
    - gtk_entry_set_text(GTK_ENTRY(GTK_BIN((widget))->child), (text));
    + gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((widget)))), (text));
    }
    GtkWidget *
    @@ -3047,12 +2981,12 @@
    windows = g_list_delete_link(windows, windows);
    if (window == widget ||
    - !GTK_WIDGET_VISIBLE(window)) {
    + !gtk_widget_get_visible(window)) {
    continue;
    }
    if (gtk_window_has_toplevel_focus(GTK_WINDOW(window)) ||
    - (menu && menu == window->window)) {
    + (menu && menu == gtk_widget_get_window(window))) {
    parent = window;
    break;
    }
    --- a/pidgin/gtkutils.h Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkutils.h Sun Dec 05 03:10:05 2010 +0000
    @@ -402,21 +402,6 @@
    void pidgin_setup_screenname_autocomplete(GtkWidget *entry, GtkWidget *optmenu, gboolean all);
    /**
    - * Check if the given path is a directory or not. If it is, then modify
    - * the given GtkFileSelection dialog so that it displays the given path.
    - * If the given path is not a directory, then do nothing.
    - *
    - * @param path The path entered in the file selection window by the user.
    - * @param filesel The file selection window.
    - *
    - * @return TRUE if given path is a directory, FALSE otherwise.
    - * @deprecated Pidgin no longer uses GtkFileSelection internally. It has also
    - * been deprecated by GTK+. Use GtkFileChooser instead and ignore
    - * this function.
    - */
    -gboolean pidgin_check_if_dir(const char *path, GtkFileSelection *filesel);
    -
    -/**
    * Sets up GtkSpell for the given GtkTextView, reporting errors
    * if encountered.
    *
    --- a/pidgin/gtkwhiteboard.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkwhiteboard.c Sun Dec 05 03:10:05 2010 +0000
    @@ -280,13 +280,13 @@
    /* TODO Ask if user wants to save picture before the session is closed */
    /* Clear graphical memory */
    - if(gtkwb->pixmap)
    + if(gtkwb->pixbuf)
    {
    - cairo_t *cr = g_object_get_data(G_OBJECT(gtkwb->pixmap), "cairo-context");
    + cairo_t *cr = g_object_get_data(G_OBJECT(gtkwb->pixbuf), "cairo-context");
    if (cr)
    cairo_destroy(cr);
    - g_object_unref(gtkwb->pixmap);
    - gtkwb->pixmap = NULL;
    + g_object_unref(gtkwb->pixbuf);
    + gtkwb->pixbuf = NULL;
    }
    colour_dialog = g_object_get_data(G_OBJECT(gtkwb->window), "colour-dialog");
    @@ -356,28 +356,32 @@
    static gboolean pidgin_whiteboard_configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
    {
    PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
    - GdkPixmap *pixmap = gtkwb->pixmap;
    + GdkPixbuf *pixbuf = gtkwb->pixbuf;
    cairo_t *cr;
    -
    - if (pixmap) {
    - cr = g_object_get_data(G_OBJECT(pixmap), "cairo-context");
    + GdkWindow *window = gtk_widget_get_window(widget);
    + GtkAllocation allocation;
    +
    + if (pixbuf) {
    + cr = g_object_get_data(G_OBJECT(pixbuf), "cairo-context");
    if (cr)
    cairo_destroy(cr);
    - g_object_unref(pixmap);
    + g_object_unref(pixbuf);
    }
    - pixmap = gdk_pixmap_new(widget->window,
    - widget->allocation.width,
    - widget->allocation.height,
    - -1);
    - gtkwb->pixmap = pixmap;
    + gtk_widget_get_allocation(widget, &allocation);
    +
    + pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
    + FALSE, gdk_visual_get_depth(GDK_VISUAL(window)),
    + allocation.width, allocation.height);
    +
    + gtkwb->pixbuf = pixbuf;
    - cr = gdk_cairo_create(GDK_DRAWABLE(pixmap));
    - g_object_set_data(G_OBJECT(pixmap), "cairo-context", cr);
    - gdk_cairo_set_source_color(cr, &widget->style->white);
    + cr = gdk_cairo_create(gtk_widget_get_window(widget));
    + g_object_set_data(G_OBJECT(pixbuf), "cairo-context", cr);
    + gdk_cairo_set_source_color(cr, &gtk_widget_get_style(widget)->white);
    cairo_rectangle(cr,
    0, 0,
    - widget->allocation.width, widget->allocation.height);
    + allocation.width, allocation.height);
    cairo_fill(cr);
    return TRUE;
    @@ -386,11 +390,11 @@
    static gboolean pidgin_whiteboard_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
    {
    PidginWhiteboard *gtkwb = (PidginWhiteboard*)(data);
    - GdkPixmap *pixmap = gtkwb->pixmap;
    + GdkPixbuf *pixbuf = gtkwb->pixbuf;
    cairo_t *cr;
    - cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
    - gdk_cairo_set_source_pixmap(cr, pixmap, 0, 0);
    + cr = gdk_cairo_create(gtk_widget_get_window(widget));
    + gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
    cairo_rectangle(cr,
    event->area.x, event->area.y,
    event->area.width, event->area.height);
    @@ -403,7 +407,7 @@
    static gboolean pidgin_whiteboard_brush_down(GtkWidget *widget, GdkEventButton *event, gpointer data)
    {
    PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
    - GdkPixmap *pixmap = gtkwb->pixmap;
    + GdkPixbuf *pixbuf = gtkwb->pixbuf;
    PurpleWhiteboard *wb = gtkwb->wb;
    GList *draw_list = wb->draw_list;
    @@ -418,7 +422,7 @@
    BrushState = BRUSH_STATE_DOWN;
    - if(event->button == 1 && pixmap != NULL)
    + if(event->button == 1 && pixbuf != NULL)
    {
    /* Check if draw_list has contents; if so, clear it */
    if(draw_list)
    @@ -456,7 +460,7 @@
    GdkModifierType state;
    PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
    - GdkPixmap *pixmap = gtkwb->pixmap;
    + GdkPixbuf *pixbuf = gtkwb->pixbuf;
    PurpleWhiteboard *wb = gtkwb->wb;
    GList *draw_list = wb->draw_list;
    @@ -470,7 +474,7 @@
    state = event->state;
    }
    - if(state & GDK_BUTTON1_MASK && pixmap != NULL)
    + if(state & GDK_BUTTON1_MASK && pixbuf != NULL)
    {
    if((BrushState != BRUSH_STATE_DOWN) && (BrushState != BRUSH_STATE_MOTION))
    {
    @@ -536,7 +540,7 @@
    static gboolean pidgin_whiteboard_brush_up(GtkWidget *widget, GdkEventButton *event, gpointer data)
    {
    PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
    - GdkPixmap *pixmap = gtkwb->pixmap;
    + GdkPixbuf *pixbuf = gtkwb->pixbuf;
    PurpleWhiteboard *wb = gtkwb->wb;
    GList *draw_list = wb->draw_list;
    @@ -551,7 +555,7 @@
    }
    BrushState = BRUSH_STATE_UP;
    - if(event->button == 1 && pixmap != NULL)
    + if(event->button == 1 && pixbuf != NULL)
    {
    /* If the brush was never moved, express two sets of two deltas That's a
    * 'point,' but not for Yahoo!
    @@ -593,9 +597,9 @@
    {
    PidginWhiteboard *gtkwb = wb->ui_data;
    GtkWidget *widget = gtkwb->drawing_area;
    - GdkPixmap *pixmap = gtkwb->pixmap;
    + GdkPixbuf *pixbuf = gtkwb->pixbuf;
    - cairo_t *gfx_con = g_object_get_data(G_OBJECT(pixmap), "cairo-context");
    + cairo_t *gfx_con = g_object_get_data(G_OBJECT(pixbuf), "cairo-context");
    GdkColor col;
    /* Interpret and convert color */
    @@ -701,21 +705,24 @@
    static void pidgin_whiteboard_clear(PurpleWhiteboard *wb)
    {
    PidginWhiteboard *gtkwb = wb->ui_data;
    - GdkPixmap *pixmap = gtkwb->pixmap;
    + GdkPixbuf *pixbuf = gtkwb->pixbuf;
    GtkWidget *drawing_area = gtkwb->drawing_area;
    - cairo_t *cr = g_object_get_data(G_OBJECT(pixmap), "cairo-context");
    + cairo_t *cr = g_object_get_data(G_OBJECT(pixbuf), "cairo-context");
    + GtkAllocation allocation;
    - gdk_cairo_set_source_color(cr, &drawing_area->style->white);
    + gtk_widget_get_allocation(drawing_area, &allocation);
    +
    + gdk_cairo_set_source_color(cr, &gtk_widget_get_style(drawing_area)->white);
    cairo_rectangle(cr,
    0, 0,
    - drawing_area->allocation.width,
    - drawing_area->allocation.height);
    + allocation.width,
    + allocation.height);
    cairo_fill(cr);
    gtk_widget_queue_draw_area(drawing_area,
    0, 0,
    - drawing_area->allocation.width,
    - drawing_area->allocation.height);
    + allocation.width,
    + allocation.height);
    }
    static void pidgin_whiteboard_button_clear_press(GtkWidget *widget, gpointer data)
    @@ -781,12 +788,15 @@
    gtk_widget_destroy(dialog);
    /* Makes an icon from the whiteboard's canvas 'image' */
    + pixbuf = gtkwb->pixbuf;
    + /*
    pixbuf = gdk_pixbuf_get_from_drawable(NULL,
    (GdkDrawable*)(gtkwb->pixmap),
    gdk_drawable_get_colormap(gtkwb->pixmap),
    0, 0,
    0, 0,
    gtkwb->width, gtkwb->height);
    + */
    if(gdk_pixbuf_save(pixbuf, filename, "jpeg", NULL, "quality", "100", NULL))
    purple_debug_info("gtkwhiteboard", "File Saved...\n");
    @@ -807,12 +817,15 @@
    GdkPixbuf *pixbuf;
    /* Makes an icon from the whiteboard's canvas 'image' */
    + pixbuf = gtkwb->pixbuf;
    + /*
    pixbuf = gdk_pixbuf_get_from_drawable(NULL,
    (GdkDrawable*)(gtkwb->pixmap),
    gdk_drawable_get_colormap(gtkwb->pixmap),
    0, 0,
    0, 0,
    gtkwb->width, gtkwb->height);
    + */
    gtk_window_set_icon((GtkWindow*)(gtkwb->window), pixbuf);
    }
    @@ -853,23 +866,29 @@
    {
    GdkColor color;
    GtkColorSelectionDialog *dialog;
    -
    + GtkWidget *ok_button;
    +
    dialog = (GtkColorSelectionDialog *)gtk_color_selection_dialog_new(_("Select color"));
    g_object_set_data(G_OBJECT(gtkwb->window), "colour-dialog", dialog);
    - g_signal_connect(G_OBJECT(dialog->colorsel), "color-changed",
    + g_signal_connect(G_OBJECT(gtk_color_selection_dialog_get_color_selection(dialog)),
    + "color-changed",
    G_CALLBACK(change_color_cb), gtkwb);
    + /*
    gtk_widget_destroy(dialog->cancel_button);
    gtk_widget_destroy(dialog->help_button);
    -
    - g_signal_connect(G_OBJECT(dialog->ok_button), "clicked",
    + */
    + g_object_get(G_OBJECT(dialog), "ok-button", &ok_button, NULL);
    +
    + g_signal_connect(G_OBJECT(ok_button), "clicked",
    G_CALLBACK(color_selection_dialog_destroy), gtkwb);
    - gtk_color_selection_set_has_palette(GTK_COLOR_SELECTION(dialog->colorsel), TRUE);
    + gtk_color_selection_set_has_palette(GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(dialog)), TRUE);
    pidgin_whiteboard_rgb24_to_rgb48(gtkwb->brush_color, &color);
    - gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(dialog->colorsel), &color);
    + gtk_color_selection_set_current_color(
    + GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(dialog)), &color);
    gtk_widget_show_all(GTK_WIDGET(dialog));
    }
    --- a/pidgin/gtkwhiteboard.h Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/gtkwhiteboard.h Sun Dec 05 03:10:05 2010 +0000
    @@ -51,7 +51,7 @@
    GtkWidget *window; /**< Window for the Doodle session */
    GtkWidget *drawing_area; /**< Drawing area */
    - GdkPixmap *pixmap; /**< Memory for drawing area */
    + GdkPixbuf *pixbuf; /**< Memory for drawing area */
    int width; /**< Canvas width */
    int height; /**< Canvas height */
    --- a/pidgin/minidialog.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/minidialog.c Sun Dec 05 03:10:05 2010 +0000
    @@ -160,7 +160,7 @@
    guint
    pidgin_mini_dialog_get_num_children(PidginMiniDialog *mini_dialog)
    {
    - return g_list_length(mini_dialog->contents->children);
    + return g_list_length(gtk_container_get_children(GTK_CONTAINER(mini_dialog->contents)));
    }
    static gboolean
    --- a/pidgin/pidgintooltip.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/pidgintooltip.c Sun Dec 05 03:10:05 2010 +0000
    @@ -101,11 +101,16 @@
    }
    static gboolean
    -pidgin_tooltip_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
    +pidgin_tooltip_draw_cb(GtkWidget *widget, cairo_t *cr, gpointer data)
    {
    + GtkAllocation allocation;
    +
    + gtk_widget_get_allocation(widget, &allocation);
    +
    if (pidgin_tooltip.paint_tooltip) {
    - gtk_paint_flat_box(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
    - NULL, widget, "tooltip", 0, 0, -1, -1);
    + gtk_paint_flat_box(gtk_widget_get_style(widget), cr,
    + GTK_STATE_NORMAL, GTK_SHADOW_OUT,
    + widget, "tooltip", 0, 0, allocation.width, allocation.height);
    pidgin_tooltip.paint_tooltip(widget, data);
    }
    return FALSE;
    @@ -179,8 +184,8 @@
    gtk_window_move(GTK_WINDOW(tipwindow), x, y);
    gtk_widget_show(tipwindow);
    - g_signal_connect(G_OBJECT(tipwindow), "expose_event",
    - G_CALLBACK(pidgin_tooltip_expose_event), data);
    + g_signal_connect(G_OBJECT(tipwindow), "draw",
    + G_CALLBACK(pidgin_tooltip_draw_cb), data);
    /* Hide the tooltip when the widget is destroyed */
    sig = g_signal_connect(G_OBJECT(pidgin_tooltip.widget), "destroy", G_CALLBACK(pidgin_tooltip_destroy), NULL);
    --- a/pidgin/plugins/contact_priority.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/plugins/contact_priority.c Sun Dec 05 03:10:05 2010 +0000
    @@ -35,11 +35,11 @@
    }
    static void
    -account_update(GtkWidget *widget, GtkOptionMenu *optmenu)
    +account_update(GtkWidget *widget, GtkWidget *optmenu)
    {
    PurpleAccount *account = NULL;
    - account = g_object_get_data(G_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(optmenu)))), "account");
    + account = pidgin_account_option_menu_get_selected(optmenu);
    purple_account_set_int(account, "score", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)));
    }
    @@ -75,7 +75,7 @@
    GtkWidget *ret = NULL, *hbox = NULL, *frame = NULL, *vbox = NULL;
    GtkWidget *label = NULL, *spin = NULL, *check = NULL;
    GtkWidget *optmenu = NULL;
    - GtkObject *adj = NULL;
    + GtkAdjustment *adj = NULL;
    GtkSizeGroup *sg = NULL;
    PurpleAccount *account = NULL;
    int i;
    @@ -147,8 +147,7 @@
    gtk_box_pack_start(GTK_BOX(hbox), optmenu, FALSE, FALSE, 0);
    /* this is where we set up the spin button we made above */
    - account = g_object_get_data(G_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu))))),
    - "account");
    + account = pidgin_account_option_menu_get_selected(optmenu);
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin),
    (gdouble)purple_account_get_int(account, "score", 0));
    gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(spin), GTK_ADJUSTMENT(adj));
    --- a/pidgin/plugins/convcolors.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/plugins/convcolors.c Sun Dec 05 03:10:05 2010 +0000
    @@ -302,7 +302,7 @@
    }
    static void
    -disconnect_prefs_callbacks(GtkObject *object, gpointer data)
    +disconnect_prefs_callbacks(GtkWidget *widget, gpointer data)
    {
    PurplePlugin *plugin = (PurplePlugin *)data;
    @@ -383,7 +383,7 @@
    purple_prefs_connect_callback(plugin, tmp2, enable_toggled, button);
    }
    - g_signal_connect(GTK_OBJECT(ret), "destroy", G_CALLBACK(disconnect_prefs_callbacks), plugin);
    + g_signal_connect(ret, "destroy", G_CALLBACK(disconnect_prefs_callbacks), plugin);
    frame = pidgin_make_frame(ret, _("General"));
    pidgin_prefs_checkbox(_("Ignore incoming format"), PREF_IGNORE, frame);
    pidgin_prefs_checkbox(_("Apply in Chats"), PREF_CHATS, frame);
    --- a/pidgin/plugins/disco/gtkdisco.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/plugins/disco/gtkdisco.c Sun Dec 05 03:10:05 2010 +0000
    @@ -429,15 +429,12 @@
    static gboolean
    disco_paint_tooltip(GtkWidget *tipwindow, gpointer data)
    {
    + cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(tipwindow));
    PangoLayout *layout = g_object_get_data(G_OBJECT(tipwindow), "tooltip-plugin");
    -#if GTK_CHECK_VERSION(2,14,0)
    gtk_paint_layout(gtk_widget_get_style(tipwindow),
    - gtk_widget_get_window(tipwindow),
    + cr,
    GTK_STATE_NORMAL, FALSE,
    -#else
    - gtk_paint_layout(tipwindow->style, tipwindow->window, GTK_STATE_NORMAL, FALSE,
    -#endif
    - NULL, tipwindow, "tooltip",
    + tipwindow, "tooltip",
    6, 6, layout);
    return TRUE;
    }
    --- a/pidgin/plugins/gestures/stroke-draw.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/plugins/gestures/stroke-draw.c Sun Dec 05 03:10:05 2010 +0000
    @@ -339,7 +339,7 @@
    unsigned int border_width;
    XSizeHints hints;
    Display *disp = GDK_WINDOW_XDISPLAY(gtk_widget_get_window(widget));
    - Window wind = GDK_WINDOW_XWINDOW (gtk_widget_get_window(widget));
    + Window wind = gdk_x11_window_get_xid(gtk_widget_get_window(widget));
    int screen = DefaultScreen (disp);
    if (!gstroke_draw_strokes())
    --- a/pidgin/plugins/markerline.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/plugins/markerline.c Sun Dec 05 03:10:05 2010 +0000
    @@ -76,6 +76,7 @@
    gtk_text_view_buffer_to_window_coords(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_TEXT,
    0, last_y, 0, &y);
    + /* TODO: port this to using Cairo
    if (y >= event->area.y)
    {
    GdkColor red = {0, 0xffff, 0, 0};
    @@ -88,6 +89,7 @@
    cairo_stroke(cr);
    cairo_destroy(cr);
    }
    + */
    return FALSE;
    }
    --- a/pidgin/plugins/themeedit.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/plugins/themeedit.c Sun Dec 05 03:10:05 2010 +0000
    @@ -306,7 +306,6 @@
    }
    }
    - gtk_dialog_set_has_separator(GTK_DIALOG(dialog), TRUE);
    #ifdef NOT_SADRUL
    pidgin_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_SAVE, G_CALLBACK(save_blist_theme), dialog);
    #endif
    --- a/pidgin/plugins/ticker/gtkticker.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/plugins/ticker/gtkticker.c Sun Dec 05 03:10:05 2010 +0000
    @@ -21,28 +21,24 @@
    * GtkTicker Copyright 2000 Syd Logan
    */
    -/* FIXME: GTK+ deprecated GTK_WIDGET_MAPPED/REALIZED, but don't provide
    - accessor functions yet. */
    -#undef GSEAL_ENABLE
    -
    #include "gtkticker.h"
    #include <gtk/gtk.h>
    -/* These don't seem to be in a release yet. See BZ #69872 */
    -#define gtk_widget_is_mapped(x) GTK_WIDGET_MAPPED(x)
    -#define gtk_widget_is_realized(x) GTK_WIDGET_REALIZED(x)
    +#if !GTK_CHECK_VERSION(2,20,0)
    +#define gtk_widget_get_mapped(x) GTK_WIDGET_MAPPED(x)
    +#define gtk_widget_set_mapped(x,y) do {\
    + if (y) \
    + GTK_WIDGET_SET_FLAGS(x, GTK_MAPPED); \
    + else \
    + GTK_WIDGET_UNSET_FLAGS(x, GTK_MAPPED); \
    +} while(0)
    +#define gtk_widget_get_realized(x) GTK_WIDGET_REALIZED(x)
    #define gtk_widget_set_realized(x,y) do {\
    if (y) \
    GTK_WIDGET_SET_FLAGS(x, GTK_REALIZED); \
    else \
    GTK_WIDGET_UNSET_FLAGS(x, GTK_REALIZED); \
    } while(0)
    -#define gtk_widget_set_mapped(x,y) do {\
    - if (y) \
    - GTK_WIDGET_SET_FLAGS(x, GTK_MAPPED); \
    - else \
    - GTK_WIDGET_UNSET_FLAGS(x, GTK_MAPPED); \
    -} while(0)
    #if !GTK_CHECK_VERSION(2,18,0)
    #define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x)
    @@ -51,6 +47,7 @@
    #define gtk_widget_get_window(x) x->window
    #endif
    #endif
    +#endif
    static void gtk_ticker_compute_offsets (GtkTicker *ticker);
    static void gtk_ticker_class_init (GtkTickerClass *klass);
    @@ -131,7 +128,7 @@
    widget_class->map = gtk_ticker_map;
    widget_class->realize = gtk_ticker_realize;
    - widget_class->size_request = gtk_ticker_size_request;
    + /*widget_class->size_request = gtk_ticker_size_request;*/
    widget_class->size_allocate = gtk_ticker_size_allocate;
    container_class->add = gtk_ticker_add_real;
    @@ -181,13 +178,13 @@
    ticker->children = g_list_append (ticker->children, child_info);
    - if (gtk_widget_is_realized (ticker))
    + if (gtk_widget_get_realized (GTK_WIDGET(ticker)))
    gtk_widget_realize (widget);
    if (gtk_widget_get_visible (GTK_WIDGET (ticker)) &&
    gtk_widget_get_visible (widget))
    {
    - if (gtk_widget_is_mapped (GTK_WIDGET (ticker)))
    + if (gtk_widget_get_mapped (GTK_WIDGET (ticker)))
    gtk_widget_map (widget);
    gtk_widget_queue_resize (GTK_WIDGET (ticker));
    @@ -298,7 +295,7 @@
    children = children->next;
    if (gtk_widget_get_visible (child->widget) &&
    - !gtk_widget_is_mapped (child->widget))
    + !gtk_widget_get_mapped (child->widget))
    gtk_widget_map (child->widget);
    }
    @@ -335,11 +332,11 @@
    #endif
    attributes.wclass = GDK_INPUT_OUTPUT;
    attributes.visual = gtk_widget_get_visual (widget);
    - attributes.colormap = gtk_widget_get_colormap (widget);
    + /*attributes.colormap = gtk_widget_get_colormap (widget);*/
    attributes.event_mask = gtk_widget_get_events (widget);
    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
    - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
    + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL /*| GDK_WA_COLORMAP*/;
    window = gdk_window_new (gtk_widget_get_parent_window (widget),
    &attributes, attributes_mask);
    @@ -474,7 +471,7 @@
    #else
    widget->allocation = *allocation;
    #endif
    - if (gtk_widget_is_realized (widget))
    + if (gtk_widget_get_realized (widget))
    gdk_window_move_resize (gtk_widget_get_window (widget),
    allocation->x,
    allocation->y,
    --- a/pidgin/plugins/timestamp.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/plugins/timestamp.c Sun Dec 05 03:10:05 2010 +0000
    @@ -134,7 +134,7 @@
    GtkWidget *ret;
    GtkWidget *frame, *label;
    GtkWidget *vbox, *hbox;
    - GtkObject *adj;
    + GtkAdjustment *adj;
    GtkWidget *spinner;
    ret = gtk_vbox_new(FALSE, 18);
    --- a/pidgin/plugins/timestamp_format.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/plugins/timestamp_format.c Sun Dec 05 03:10:05 2010 +0000
    @@ -155,8 +155,9 @@
    if (!frame)
    return;
    + /* GTK_DIALOG_NO_SEPARATOR seems to be gone in gtk+ 3.0... */
    dialog = gtk_dialog_new_with_buttons(PIDGIN_ALERT_TITLE, NULL,
    - GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
    + GTK_DIALOG_DESTROY_WITH_PARENT,
    GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
    NULL);
    g_signal_connect_after(G_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), dialog);
    --- a/pidgin/plugins/vvconfig.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/plugins/vvconfig.c Sun Dec 05 03:10:05 2010 +0000
    @@ -506,14 +506,14 @@
    }
    static void
    -config_destroy(GtkObject *w, gpointer nul)
    +config_destroy(GtkWidget *w, gpointer nul)
    {
    purple_debug_info("vvconfig", "closing vv configuration window\n");
    window = NULL;
    }
    static void
    -config_close(GtkObject *w, gpointer nul)
    +config_close(GtkWidget *w, gpointer nul)
    {
    gtk_widget_destroy(GTK_WIDGET(window));
    }
    --- a/pidgin/plugins/xmppconsole.c Sun Dec 05 03:09:52 2010 +0000
    +++ b/pidgin/plugins/xmppconsole.c Sun Dec 05 03:10:05 2010 +0000
    @@ -274,7 +274,7 @@
    GTK_STOCK_OK,
    GTK_RESPONSE_ACCEPT,
    NULL);
    - gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
    + /* TODO: how to set no separator for GtkDialog in gtk+ 3.0... */
    gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
    gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
    #if GTK_CHECK_VERSION(2,14,0)
    @@ -302,11 +302,11 @@
    gtk_size_group_add_widget(sg, label);
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
    - type_combo = gtk_combo_box_new_text();
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "get");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "set");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "result");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "error");
    + type_combo = gtk_combo_box_text_new();
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "get");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "set");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "result");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "error");
    gtk_combo_box_set_active(GTK_COMBO_BOX(type_combo), 0);
    gtk_box_pack_start(GTK_BOX(hbox), type_combo, FALSE, FALSE, 0);
    @@ -325,7 +325,7 @@
    to && *to ? to : "",
    to && *to ? "'" : "",
    g_random_int(),
    - gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_combo)));
    + gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(type_combo)));
    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(console->entry));
    gtk_text_buffer_set_text(buffer, stanza, -1);
    @@ -362,7 +362,9 @@
    GTK_STOCK_OK,
    GTK_RESPONSE_ACCEPT,
    NULL);
    - gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
    +
    + /* TODO: find a way to specify no separator for a dialog in gtk+ 3 */
    + /*gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);*/
    gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
    gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
    #if GTK_CHECK_VERSION(2,14,0)
    @@ -389,15 +391,15 @@
    gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
    gtk_size_group_add_widget(sg, label);
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
    - type_combo = gtk_combo_box_new_text();
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "default");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "unavailable");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "subscribe");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "unsubscribe");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "subscribed");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "unsubscribed");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "probe");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "error");
    + type_combo = gtk_combo_box_text_new();
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "default");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "unavailable");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "subscribe");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "unsubscribe");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "subscribed");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "unsubscribed");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "probe");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "error");
    gtk_combo_box_set_active(GTK_COMBO_BOX(type_combo), 0);
    gtk_box_pack_start(GTK_BOX(hbox), type_combo, FALSE, FALSE, 0);
    @@ -407,12 +409,12 @@
    gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
    gtk_size_group_add_widget(sg, label);
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
    - show_combo = gtk_combo_box_new_text();
    - gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "default");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "away");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "dnd");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "xa");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "chat");
    + show_combo = gtk_combo_box_text_new();
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(show_combo), "default");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(show_combo), "away");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(show_combo), "dnd");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(show_combo), "xa");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(show_combo), "chat");
    gtk_combo_box_set_active(GTK_COMBO_BOX(show_combo), 0);
    gtk_box_pack_start(GTK_BOX(hbox), show_combo, FALSE, FALSE, 0);
    @@ -450,10 +452,10 @@
    }
    to = gtk_entry_get_text(GTK_ENTRY(to_entry));
    - type = gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_combo));
    + type = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(type_combo));
    if (!strcmp(type, "default"))
    type = "";
    - show = gtk_combo_box_get_active_text(GTK_COMBO_BOX(show_combo));
    + show = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(show_combo));
    if (!strcmp(show, "default"))
    show = "";
    status = gtk_entry_get_text(GTK_ENTRY(status_entry));
    @@ -520,7 +522,8 @@
    GTK_STOCK_OK,
    GTK_RESPONSE_ACCEPT,
    NULL);
    - gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
    + /* TODO: find a way to create a dialog without separtor in gtk+ 3 */
    + /*gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);*/
    gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
    gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
    #if GTK_CHECK_VERSION(2,14,0)
    @@ -547,12 +550,12 @@
    gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
    gtk_size_group_add_widget(sg, label);
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
    - type_combo = gtk_combo_box_new_text();
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "chat");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "headline");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "groupchat");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "normal");
    - gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "error");
    + type_combo = gtk_combo_box_text_new();
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "chat");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "headline");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "groupchat");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "normal");
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "error");
    gtk_combo_box_set_active(GTK_COMBO_BOX(type_combo), 0);
    gtk_box_pack_start(GTK_BOX(hbox), type_combo, FALSE, FALSE, 0);
    @@ -613,7 +616,8 @@
    *to ? to : "",
    *to ? "'" : "",
    g_random_int(),
    - gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_combo)),
    + gtk_combo_box_text_get_active_text(
    + GTK_COMBO_BOX_TEXT(type_combo)),
    *body ? "<body>" : "",
    *body ? body : "",
    @@ -643,7 +647,8 @@
    if (!console)
    return;
    - gtk_combo_box_append_text(GTK_COMBO_BOX(console->dropdown), purple_account_get_username(gc->account));
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(console->dropdown),
    + purple_account_get_username(gc->account));
    console->accounts = g_list_append(console->accounts, gc);
    console->count++;
    @@ -674,7 +679,7 @@
    if (l == NULL)
    return;
    - gtk_combo_box_remove_text(GTK_COMBO_BOX(console->dropdown), i);
    + gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(console->dropdown), i);
    console->accounts = g_list_remove(console->accounts, gc);
    console->count--;
    @@ -716,7 +721,7 @@
    }
    static void
    -console_destroy(GtkObject *window, gpointer nul)
    +console_destroy(GtkWidget *window, gpointer nul)
    {
    g_list_free(console->accounts);
    g_free(console);
    @@ -731,8 +736,9 @@
    if (!console)
    return;
    - account = purple_accounts_find(gtk_combo_box_get_active_text(GTK_COMBO_BOX(console->dropdown)),
    - "prpl-jabber");
    + account =
    + purple_accounts_find(gtk_combo_box_text_get_active_text(
    + GTK_COMBO_BOX_TEXT(console->dropdown)), "prpl-jabber");
    if (!account || !account->gc)
    return;
    @@ -768,13 +774,13 @@
    label = gtk_label_new(_("Account: "));
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_box_pack_start(GTK_BOX(console->hbox), label, FALSE, FALSE, 0);
    - console->dropdown = gtk_combo_box_new_text();
    + console->dropdown = gtk_combo_box_text_new();
    for (connections = purple_connections_get_all(); connections; connections = connections->next) {
    PurpleConnection *gc = connections->data;
    if (!strcmp(purple_account_get_protocol_id(purple_connection_get_account(gc)), "prpl-jabber")) {
    console->count++;
    console->accounts = g_list_append(console->accounts, gc);
    - gtk_combo_box_append_text(GTK_COMBO_BOX(console->dropdown),
    + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(console->dropdown),
    purple_account_get_username(purple_connection_get_account(gc)));
    if (!console->gc)
    console->gc = gc;