--- a/pidgin/gtkimhtml.c Sun Jan 09 20:28:58 2011 +0000 +++ b/pidgin/gtkimhtml.c Sun Jan 09 23:32:10 2011 +0000 @@ -422,7 +422,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); } @@ -511,18 +511,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; } @@ -534,12 +536,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; } @@ -563,11 +568,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", @@ -592,8 +596,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(); @@ -633,7 +637,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); @@ -761,6 +765,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) @@ -788,7 +794,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, @@ -894,6 +901,7 @@ return FALSE; } +#endif static void paste_unformatted_cb(GtkMenuItem *menu, GtkIMHtml *imhtml) @@ -1170,11 +1178,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 { @@ -1198,13 +1207,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 @@ -1215,10 +1224,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) { @@ -1579,7 +1588,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; @@ -1641,20 +1651,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) @@ -1881,13 +1891,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; } } @@ -1919,21 +1929,22 @@ { 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); - while((link = links[i]) != NULL){ + 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; @@ -1971,8 +1982,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"); @@ -2001,7 +2012,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); } @@ -2532,8 +2544,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); @@ -2556,9 +2568,10 @@ static gboolean scroll_idle_cb(gpointer data) { GtkIMHtml *imhtml = data; - GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment; - if(adj) { - gtk_adjustment_set_value(adj, adj->upper - adj->page_size); + GtkAdjustment *adj = gtk_text_view_get_vadjustment(GTK_TEXT_VIEW(imhtml)); + if (adj) { + gtk_adjustment_set_value(adj, gtk_adjustment_get_upper(adj) - + gtk_adjustment_get_page_size(adj)); } imhtml->scroll_src = 0; return FALSE; @@ -4216,9 +4229,14 @@ for (l = tags; l; l = l->next) { GtkTextTag *tag = l->data; - - if (tag->name && !strncmp(tag->name, prefix, len)) + gchar *name = NULL; + + 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); @@ -4234,10 +4252,15 @@ for (l = tags; l; l = l->next) { GtkTextTag *tag = l->data; - - if (tag->name && !strncmp(tag->name, prefix, len)) + gchar *name = NULL; + + 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); } @@ -4357,11 +4380,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 = NULL; + + 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); @@ -4583,27 +4611,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 = NULL; + + 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); @@ -4894,6 +4927,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) { @@ -4901,9 +4936,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) { @@ -4998,7 +5034,9 @@ * 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) @@ -5100,22 +5138,29 @@ static const gchar *tag_to_html_start(GtkTextTag *tag) { - const gchar *name; static gchar buf[1024]; - - name = tag->name; + gchar *name = NULL; + g_return_val_if_fail(name != NULL, ""); + g_object_get(G_OBJECT(tag), "name", &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) { + g_free(name); return "<u>"; } else if (strcmp(name, "STRIKE") == 0) { + g_free(name); return "<s>"; } else if (strncmp(name, "LINK ", 5) == 0) { char *tmp = g_object_get_data(G_OBJECT(tag), "link_url"); + + g_free(name); + if (tmp) { g_snprintf(buf, sizeof(buf), "<a href=\"%s\">", tmp); buf[sizeof(buf)-1] = '\0'; @@ -5125,18 +5170,29 @@ } } else if (strncmp(name, "FORECOLOR ", 10) == 0) { g_snprintf(buf, sizeof(buf), "<font color=\"%s\">", &name[10]); + + g_free(name); + return buf; } else if (strncmp(name, "BACKCOLOR ", 10) == 0) { g_snprintf(buf, sizeof(buf), "<font back=\"%s\">", &name[10]); + g_free(name); + return buf; } else if (strncmp(name, "BACKGROUND ", 10) == 0) { g_snprintf(buf, sizeof(buf), "<body bgcolor=\"%s\">", &name[11]); + g_free(name); + return buf; } else if (strncmp(name, "FONT FACE ", 10) == 0) { g_snprintf(buf, sizeof(buf), "<font face=\"%s\">", &name[10]); + g_free(name); + return buf; } else if (strncmp(name, "FONT SIZE ", 10) == 0) { g_snprintf(buf, sizeof(buf), "<font size=\"%s\">", &name[10]); + g_free(name); + return buf; } else { char *str = buf; @@ -5199,6 +5255,7 @@ } g_snprintf(str, sizeof(buf) - (str - buf), "'>"); + g_free(name); return (empty ? "" : buf); } @@ -5206,30 +5263,40 @@ static const gchar *tag_to_html_end(GtkTextTag *tag) { - const gchar *name; - - name = tag->name; + gchar *name; + g_return_val_if_fail(name != NULL, ""); + g_object_get(G_OBJECT(tag), "name", &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) { + g_free(name); return "</u>"; } else if (strcmp(name, "STRIKE") == 0) { + g_free(name); return "</s>"; } else if (strncmp(name, "LINK ", 5) == 0) { + g_free(name); return "</a>"; } else if (strncmp(name, "FORECOLOR ", 10) == 0) { + g_free(name); return "</font>"; } else if (strncmp(name, "BACKCOLOR ", 10) == 0) { + g_free(name); return "</font>"; } else if (strncmp(name, "BACKGROUND ", 10) == 0) { + g_free(name); return "</body>"; } else if (strncmp(name, "FONT FACE ", 10) == 0) { + g_free(name); return "</font>"; } else if (strncmp(name, "FONT SIZE ", 10) == 0) { + g_free(name); return "</font>"; } else { const char *props[] = {"weight-set", "foreground-set", "background-set", @@ -5242,6 +5309,8 @@ return "</span>"; } + g_free(name); + return ""; } }