=================================================================== RCS file: /cvsroot/gaim/gaim/src/gtkimhtml.c,v
retrieving revision 1.120
diff -u -r1.120 gtkimhtml.c --- src/gtkimhtml.c 14 Sep 2002 03:17:04 -0000 1.120 +++ src/gtkimhtml.c 10 Oct 2002 19:40:55 -0000 -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <gdk-pixbuf/gdk-pixbuf-loader.h> -#include "pixmaps/angel.xpm" -#include "pixmaps/bigsmile.xpm" -#include "pixmaps/burp.xpm" -#include "pixmaps/crossedlips.xpm" -#include "pixmaps/cry.xpm" -#include "pixmaps/embarrassed.xpm" -#include "pixmaps/kiss.xpm" -#include "pixmaps/moneymouth.xpm" -#include "pixmaps/sad.xpm" -#include "pixmaps/scream.xpm" -#include "pixmaps/smile.xpm" -#include "pixmaps/smile8.xpm" -#include "pixmaps/think.xpm" -#include "pixmaps/tongue.xpm" -#include "pixmaps/wink.xpm" -#include "pixmaps/yell.xpm" -#define POINT_SIZE(x) (_point_sizes [MIN ((x), MAX_FONT_SIZE) - 1]) -static gint _point_sizes [] = { 80, 100, 120, 140, 200, 300, 400 }; -#define DEFAULT_PRE_FACE "courier" -#define TOOLTIP_TIMEOUT 500 -#define DIFF(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a))) -#define COLOR_MOD 0x8000 -#define COLOR_DIFF 0x800 -#define GTK_IMHTML_GET_STYLE_FONT(style) gtk_style_get_font (style) -#define DRAW_IMG(x) (((x)->type == TYPE_IMG) || (imhtml->smileys && ((x)->type == TYPE_SMILEY))) -typedef struct _GtkIMHtmlBit GtkIMHtmlBit; -typedef struct _FontDetail FontDetail; - GtkSmileyTree **children; - return g_new0 (GtkSmileyTree, 1); -gtk_smiley_tree_insert (GtkSmileyTree *tree, - GtkSmileyTree *t = tree; - t->values = g_string_new (""); - pos = strchr (t->values->str, *x); - t->values = g_string_append_c (t->values, *x); - index = t->values->len - 1; - t->children = g_realloc (t->children, t->values->len * sizeof (GtkSmileyTree *)); - t->children [index] = g_new0 (GtkSmileyTree, 1); - index = (int) pos - (int) t->values->str; - t = t->children [index]; -gtk_smiley_tree_remove (GtkSmileyTree *tree, - GtkSmileyTree *t = tree; - pos = strchr (t->values->str, *x); - t = t->children [(int) pos - (int) t->values->str]; -gtk_smiley_tree_lookup (GtkSmileyTree *tree, - GtkSmileyTree *t = tree; - pos = strchr (t->values->str, *x); - t = t->children [(int) pos - (int) t->values->str]; -gtk_smiley_tree_image (GtkSmileyTree *tree, - GtkSmileyTree *t = tree; - pos = strchr (t->values->str, *x); - t = t->children [(int) pos - (int) t->values->str]; -gtk_smiley_tree_destroy (GtkSmileyTree *tree) - GSList *list = g_slist_append (NULL, tree); - GtkSmileyTree *t = list->data; - list = g_slist_remove(list, t); - for (i = 0; i < t->values->len; i++) - list = g_slist_append (list, t->children [i]); - g_string_free (t->values, TRUE); -gtk_imhtml_remove_smileys (GtkIMHtml *imhtml) - g_return_if_fail (imhtml != NULL); - g_return_if_fail (GTK_IS_IMHTML (imhtml)); - gtk_smiley_tree_destroy (imhtml->smiley_data); - imhtml->smiley_data = gtk_smiley_tree_new (); -gtk_imhtml_reset_smileys (GtkIMHtml *imhtml) - gtk_imhtml_remove_smileys(imhtml); - gtk_imhtml_init_smileys (imhtml); -static GtkLayoutClass *parent_class = NULL; -static guint signals [LAST_SIGNAL] = { 0 }; -static void gtk_imhtml_draw_bit (GtkIMHtml *, GtkIMHtmlBit *); -static GdkColor *gtk_imhtml_get_color (const gchar *); -static gint gtk_imhtml_motion_notify_event (GtkWidget *, GdkEventMotion *); -gtk_imhtml_finalize (GObject *object) - imhtml = GTK_IMHTML (object); - gtk_imhtml_clear (imhtml); - if (imhtml->selected_text) - g_string_free (imhtml->selected_text, TRUE); - if (imhtml->default_font) - gdk_font_unref (imhtml->default_font); - if (imhtml->default_fg_color) - gdk_color_free (imhtml->default_fg_color); - if (imhtml->default_bg_color) - gdk_color_free (imhtml->default_bg_color); - if (imhtml->default_hl_color) - gdk_color_free (imhtml->default_hl_color); - if (imhtml->default_hlfg_color) - gdk_color_free (imhtml->default_hlfg_color); - gdk_cursor_destroy (imhtml->hand_cursor); - gdk_cursor_destroy (imhtml->arrow_cursor); - gtk_smiley_tree_destroy (imhtml->smiley_data); - G_OBJECT_CLASS (parent_class)->finalize (object); -gtk_imhtml_realize (GtkWidget *widget) - GdkWindowAttr attributes; - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_IMHTML (widget)); - imhtml = GTK_IMHTML (widget); - GTK_WIDGET_SET_FLAGS (imhtml, GTK_REALIZED); - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x; - attributes.y = widget->allocation.y; - attributes.width = widget->allocation.width; - attributes.height = widget->allocation.height; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK; - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gdk_window_set_user_data (widget->window, widget); - attributes.x = widget->style->xthickness + BORDER_SIZE; - attributes.y = widget->style->xthickness + BORDER_SIZE; - attributes.width = MAX (1, (gint) widget->allocation.width - (gint) attributes.x * 2); - attributes.height = MAX (1, (gint) widget->allocation.height - (gint) attributes.y * 2); - attributes.event_mask = gtk_widget_get_events (widget) - | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - | GDK_POINTER_MOTION_MASK | GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK; - GTK_LAYOUT (imhtml)->bin_window = gdk_window_new (widget->window, - &attributes, attributes_mask); - gdk_window_set_user_data (GTK_LAYOUT (imhtml)->bin_window, widget); - widget->style = gtk_style_attach (widget->style, widget->window); - gdk_window_set_cursor (widget->window, imhtml->arrow_cursor); - imhtml->default_font = gdk_font_ref (gtk_style_get_font (widget->style)); - gdk_window_set_background (widget->window, &widget->style->base [GTK_STATE_NORMAL]); - gdk_window_set_background (GTK_LAYOUT (imhtml)->bin_window, - &widget->style->base [GTK_STATE_NORMAL]); - imhtml->default_fg_color = gdk_color_copy (>K_WIDGET (imhtml)->style->fg [GTK_STATE_NORMAL]); - imhtml->default_bg_color = gdk_color_copy (>K_WIDGET (imhtml)->style->base [GTK_STATE_NORMAL]); - imhtml->default_hl_color = gdk_color_copy (>K_WIDGET (imhtml)->style->bg [GTK_STATE_SELECTED]); - imhtml->default_hlfg_color=gdk_color_copy (>K_WIDGET (imhtml)->style->fg [GTK_STATE_SELECTED]); - gdk_window_show (GTK_LAYOUT (imhtml)->bin_window); -similar_colors (GdkColor *bg, - if ((DIFF (bg->red, fg->red) < COLOR_DIFF) && - (DIFF (bg->green, fg->green) < COLOR_DIFF) && - (DIFF (bg->blue, fg->blue) < COLOR_DIFF)) { - fg->red = (0xff00 - COLOR_MOD > bg->red) ? - bg->red + COLOR_MOD : bg->red - COLOR_MOD; - fg->green = (0xff00 - COLOR_MOD > bg->green) ? - bg->green + COLOR_MOD : bg->green - COLOR_MOD; - fg->blue = (0xff00 - COLOR_MOD > bg->blue) ? - bg->blue + COLOR_MOD : bg->blue - COLOR_MOD; -draw_text (GtkIMHtml *imhtml, - struct line_info *line) - GdkWindow *window = GTK_LAYOUT (imhtml)->bin_window; - gchar *start = NULL, *end = NULL; - if (GTK_LAYOUT (imhtml)->freeze_count) - gc = gdk_gc_new (window); - cmap = gtk_widget_get_colormap (GTK_WIDGET (imhtml)); - xoff = GTK_LAYOUT (imhtml)->hadjustment->value; - yoff = GTK_LAYOUT (imhtml)->vadjustment->value; - gdk_color_alloc (cmap, bit->bg); - gdk_gc_set_foreground (gc, bit->bg); - gdk_color_alloc (cmap, imhtml->default_bg_color); - gdk_gc_set_foreground (gc, imhtml->default_bg_color); - bg = imhtml->default_bg_color; - gdk_draw_rectangle (window, gc, TRUE, line->x - xoff, line->y - yoff, - line->width ? line->width : imhtml->xsize, line->height); - if (bit->back != NULL) { - gdk_color_alloc (cmap, bit->back); - gdk_gc_set_foreground (gc, bit->back); - gdk_draw_rectangle (window, gc, TRUE, line->x - xoff, line->y - yoff, - gdk_string_width (bit->font, line->text), line->height); - bg = gdk_color_copy (bg); - if ((line->sel_start > line->sel_end) && (line->sel_end != NULL)) { - start = line->sel_start; - x = gdk_text_width (bit->font, line->text, start - line->text); - end = strchr(line->text, '\0'); - width = gdk_text_width (bit->font, line->text, end - line->text) - x; - gdk_gc_set_foreground (gc, imhtml->default_hl_color); - gdk_draw_rectangle (window, gc, TRUE, x + line->x - xoff, line->y - yoff, - gdk_gc_set_foreground (gc, imhtml->default_hlfg_color); - fg = gdk_color_copy(imhtml->default_hlfg_color); - GdkColor *tc = gtk_imhtml_get_color ("#0000a0"); - gdk_color_alloc (cmap, tc); - gdk_gc_set_foreground (gc, tc); - fg = gdk_color_copy (tc); - } else if (bit->fore) { - gdk_color_alloc (cmap, bit->fore); - gdk_gc_set_foreground (gc, bit->fore); - fg = gdk_color_copy (bit->fore); - gdk_color_alloc (cmap, imhtml->default_fg_color); - gdk_gc_set_foreground (gc, imhtml->default_fg_color); - fg = gdk_color_copy (imhtml->default_fg_color); - if (similar_colors (bg, fg)) { - gdk_color_alloc (cmap, fg); - gdk_gc_set_foreground (gc, fg); - gdk_draw_text (window, bit->font, gc, line->x - xoff, - line->y - yoff + line->ascent, line->text, start - line->text); - offset = gdk_text_width(bit->font, line->text, start - line->text); - if (bit->underline || bit->url) - gdk_draw_rectangle (window, gc, TRUE, line->x - xoff, - line->y - yoff + line->ascent + 1, - gdk_draw_rectangle (window, gc, TRUE, line->x - xoff, - line->y - yoff + line->ascent - (bit->font->ascent / 2), - gdk_gc_set_foreground (gc, imhtml->default_hlfg_color); - gdk_draw_text (window, bit->font, gc, line->x - xoff + offset, - line->y - yoff + line->ascent, start, end - start); - if (bit->underline || bit->url) - gdk_draw_rectangle (window, gc, TRUE, line->x - xoff + offset, - line->y - yoff + line->ascent + 1, - gdk_text_width(bit->font, line->text, end - start), 1); - gdk_draw_rectangle (window, gc, TRUE, line->x - xoff + offset, - line->y - yoff + line->ascent - (bit->font->ascent / 2), - gdk_text_width(bit->font, line->text, end - start), 1); - offset = gdk_text_width(bit->font, line->text, end - line->text); - gdk_gc_set_foreground (gc, fg); - gdk_draw_string (window, bit->font, gc, line->x - xoff + offset, - line->y - yoff + line->ascent, end); - if (bit->underline || bit->url) - gdk_draw_rectangle (window, gc, TRUE, line->x - xoff + offset, - line->y - yoff + line->ascent + 1, - gdk_string_width(bit->font, end), 1); - gdk_draw_rectangle (window, gc, TRUE, line->x - xoff + offset, - line->y - yoff + line->ascent - (bit->font->ascent / 2), - gdk_string_width(bit->font, end), 1); - gdk_draw_string (window, bit->font, gc, line->x - xoff, - line->y - yoff + line->ascent, line->text); - if (bit->underline || bit->url) - gdk_draw_rectangle (window, gc, TRUE, line->x - xoff, line->y - yoff + line->ascent + 1, - gdk_string_width (bit->font, line->text), 1); - gdk_draw_rectangle (window, gc, TRUE, line->x - xoff, - line->y - yoff + line->ascent - (bit->font->ascent / 2), - gdk_string_width (bit->font, line->text), 1); -draw_img (GtkIMHtml *imhtml, - struct line_info *line) - gint width, height, hoff; - GdkWindow *window = GTK_LAYOUT (imhtml)->bin_window; - if (GTK_LAYOUT (imhtml)->freeze_count) - gdk_window_get_size (bit->pm, &width, &height); - hoff = (line->height - height) / 2; - xoff = GTK_LAYOUT (imhtml)->hadjustment->value; - yoff = GTK_LAYOUT (imhtml)->vadjustment->value; - gc = gdk_gc_new (window); - cmap = gtk_widget_get_colormap (GTK_WIDGET (imhtml)); - gdk_color_alloc (cmap, bit->bg); - gdk_gc_set_foreground (gc, bit->bg); - gdk_color_alloc (cmap, imhtml->default_bg_color); - gdk_gc_set_foreground (gc, imhtml->default_bg_color); - gdk_draw_rectangle (window, gc, TRUE, line->x - xoff, line->y - yoff, line->width, line->height); - gdk_color_alloc (cmap, imhtml->default_hl_color); - gdk_gc_set_foreground(gc, imhtml->default_hl_color); - gdk_draw_rectangle (window, gc, TRUE, line->x - xoff, line->y - yoff, - } else if (bit->back != NULL) { - gdk_color_alloc (cmap, bit->back); - gdk_gc_set_foreground (gc, bit->back); - gdk_gc_set_clip_mask(gc, bit->bm); - gdk_gc_set_clip_origin(gc, line->x - xoff, line->y - yoff + hoff); - gdk_draw_pixmap (window, gc, bit->pm, 0, 0, line->x - xoff, line->y - yoff + hoff, -1, -1); -draw_line (GtkIMHtml *imhtml, - struct line_info *line) - if (GTK_LAYOUT (imhtml)->freeze_count) - xoff = GTK_LAYOUT (imhtml)->hadjustment->value; - yoff = GTK_LAYOUT (imhtml)->vadjustment->value; - drawable = GTK_LAYOUT (imhtml)->bin_window; - cmap = gtk_widget_get_colormap (GTK_WIDGET (imhtml)); - gc = gdk_gc_new (drawable); - gdk_color_alloc (cmap, imhtml->default_hl_color); - gdk_gc_set_foreground (gc, imhtml->default_hl_color); - } else if (bit->bg != NULL) { - gdk_color_alloc (cmap, bit->bg); - gdk_gc_set_foreground (gc, bit->bg); - gdk_color_alloc (cmap, imhtml->default_bg_color); - gdk_gc_set_foreground (gc, imhtml->default_bg_color); - gdk_draw_rectangle (drawable, gc, TRUE, line->x - xoff, line->y - yoff, - line->width, line->height); - gdk_color_alloc (cmap, imhtml->default_hlfg_color); - gdk_gc_set_foreground (gc, imhtml->default_hlfg_color); - gdk_color_alloc (cmap, imhtml->default_fg_color); - gdk_gc_set_foreground (gc, imhtml->default_fg_color); - line_height = line->height / 2; - gdk_draw_rectangle (drawable, gc, TRUE, line->x - xoff, line->y - yoff + line_height / 2, - line->width, line_height); -gtk_imhtml_draw_focus (GtkWidget *widget) - imhtml = GTK_IMHTML (widget); - if (!GTK_WIDGET_DRAWABLE (widget)) - if (GTK_WIDGET_HAS_FOCUS (widget)) { - gtk_paint_focus (widget->style, widget->window, GTK_STATE_NORMAL, NULL, widget, "text", - 0, 0, widget->allocation.width - 1, widget->allocation.height - 1); - x = 1; y = 1; w = 2; h = 2; - gtk_paint_shadow (widget->style, widget->window, GTK_STATE_NORMAL, - GTK_SHADOW_IN, NULL, widget, "text", x, y, - widget->allocation.width - w, widget->allocation.height - h); -gtk_imhtml_draw_exposed (GtkIMHtml *imhtml) - struct line_info *line; - x = GTK_LAYOUT (imhtml)->hadjustment->value; - y = GTK_LAYOUT (imhtml)->vadjustment->value; - gdk_window_get_size (GTK_LAYOUT (imhtml)->bin_window, &width, &height); - if ((line->x <= x + width) && - (line->y <= y + height) && - (x <= line->x + line->width) && - (y <= line->y + line->height)) - draw_img (imhtml, line); - } else if (bit->type == TYPE_SEP) { - if ((line->x <= x + width) && - (line->y <= y + height) && - (x <= line->x + line->width) && - (y <= line->y + line->height)) - draw_line (imhtml, line); - line = chunks->next->data; - if ((line->x <= x + width) && - (line->y <= y + height) && - (x <= line->x + line->width) && - (y <= line->y + line->height)) - draw_text (imhtml, line); - if ((line->x <= x + width) && - (line->y <= y + height) && - (x <= line->x + line->width) && - (y <= line->y + line->height)) - draw_text (imhtml, line); - chunks = g_list_next (chunks); - bits = g_list_next (bits); - gtk_imhtml_draw_focus (GTK_WIDGET (imhtml)); -gtk_imhtml_style_set (GtkWidget *widget, - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_IMHTML (widget)); - if (GTK_WIDGET_CLASS (parent_class)->style_set) - (* GTK_WIDGET_CLASS (parent_class)->style_set) (widget, style); - if (!GTK_WIDGET_REALIZED (widget)) - imhtml = GTK_IMHTML (widget); - if (imhtml->default_fg_color) - gdk_color_free(imhtml->default_fg_color); - if (imhtml->default_bg_color) - gdk_color_free(imhtml->default_bg_color); - if (imhtml->default_hl_color) - gdk_color_free(imhtml->default_hl_color); - if (imhtml->default_hlfg_color) - gdk_color_free(imhtml->default_hlfg_color); - imhtml->default_fg_color = gdk_color_copy (>K_WIDGET (imhtml)->style->fg [GTK_STATE_NORMAL]); - imhtml->default_bg_color = gdk_color_copy (>K_WIDGET (imhtml)->style->base [GTK_STATE_NORMAL]); - imhtml->default_hl_color = gdk_color_copy (>K_WIDGET (imhtml)->style->bg [GTK_STATE_SELECTED]); - imhtml->default_hlfg_color=gdk_color_copy (>K_WIDGET (imhtml)->style->fg [GTK_STATE_SELECTED]); - if (imhtml->default_font) - gdk_font_unref (imhtml->default_font); - imhtml->default_font = gdk_font_ref (gtk_style_get_font (widget->style)); - gdk_window_set_background (widget->window, &widget->style->base [GTK_STATE_NORMAL]); - gdk_window_set_background (GTK_LAYOUT (imhtml)->bin_window, - &widget->style->base [GTK_STATE_NORMAL]); - gtk_imhtml_draw_exposed (imhtml); -gtk_imhtml_expose_event (GtkWidget *widget, - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_IMHTML (widget), FALSE); - imhtml = GTK_IMHTML (widget); - gtk_imhtml_draw_exposed (imhtml); -gtk_imhtml_redraw_all (GtkIMHtml *imhtml) - vadj = GTK_LAYOUT (imhtml)->vadjustment; - oldvalue = vadj->value / vadj->upper; - gtk_layout_freeze (GTK_LAYOUT (imhtml)); - g_list_free (imhtml->line); - while (imhtml->click) { - g_free (imhtml->click->data); - imhtml->click = g_list_remove (imhtml->click, imhtml->click->data); - imhtml->y = TOP_BORDER; - if (GTK_LAYOUT (imhtml)->vadjustment->value < TOP_BORDER) - gdk_window_clear_area (GTK_LAYOUT (imhtml)->bin_window, 0, 0, - TOP_BORDER - GTK_LAYOUT (imhtml)->vadjustment->value); - struct line_info *li = bit->chunks->data; - bit->chunks = g_list_remove (bit->chunks, li); - gtk_imhtml_draw_bit (imhtml, bit); - GTK_LAYOUT (imhtml)->height = imhtml->y; - GTK_LAYOUT (imhtml)->vadjustment->upper = imhtml->y; - gtk_signal_emit_by_name (GTK_OBJECT (GTK_LAYOUT (imhtml)->vadjustment), "changed"); - gtk_widget_set_usize (GTK_WIDGET (imhtml), -1, imhtml->y); - gtk_adjustment_set_value (vadj, vadj->upper * oldvalue); - if (GTK_LAYOUT (imhtml)->bin_window && (imhtml->y < oldy)) { - gc = gdk_gc_new (GTK_LAYOUT (imhtml)->bin_window); - cmap = gtk_widget_get_colormap (GTK_WIDGET (imhtml)); - gdk_color_alloc (cmap, imhtml->default_bg_color); - gdk_gc_set_foreground (gc, imhtml->default_bg_color); - gdk_draw_rectangle (GTK_LAYOUT (imhtml)->bin_window, gc, TRUE, - 0, imhtml->y - GTK_LAYOUT (imhtml)->vadjustment->value, - GTK_WIDGET (imhtml)->allocation.width, - gtk_layout_thaw (GTK_LAYOUT (imhtml)); - gtk_imhtml_draw_focus (GTK_WIDGET (imhtml)); -gtk_imhtml_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) - gint new_xsize, new_ysize; - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_IMHTML (widget)); - g_return_if_fail (allocation != NULL); - imhtml = GTK_IMHTML (widget); - layout = GTK_LAYOUT (widget); - widget->allocation = *allocation; - new_xsize = MAX (1, (gint) allocation->width - - (gint) (widget->style->xthickness + BORDER_SIZE) * 2); - new_ysize = MAX (1, (gint) allocation->height - - (gint) (widget->style->ythickness + BORDER_SIZE) * 2); - if (GTK_WIDGET_REALIZED (widget)) { - gint x = widget->style->xthickness + BORDER_SIZE; - gint y = widget->style->ythickness + BORDER_SIZE; - gdk_window_move_resize (widget->window, - allocation->x, allocation->y, - allocation->width, allocation->height); - gdk_window_move_resize (layout->bin_window, - x, y, new_xsize, new_ysize); - layout->hadjustment->page_size = new_xsize; - layout->hadjustment->page_increment = new_xsize / 2; - layout->hadjustment->lower = 0; - layout->hadjustment->upper = imhtml->x; - layout->vadjustment->page_size = new_ysize; - layout->vadjustment->page_increment = new_ysize / 2; - layout->vadjustment->lower = 0; - layout->vadjustment->upper = imhtml->y; - gtk_signal_emit_by_name (GTK_OBJECT (layout->hadjustment), "changed"); - gtk_signal_emit_by_name (GTK_OBJECT (layout->vadjustment), "changed"); - if (new_xsize == imhtml->xsize) { - if ((GTK_LAYOUT (imhtml)->vadjustment->value > imhtml->y - new_ysize)) { - if (imhtml->y > new_ysize) - gtk_adjustment_set_value (GTK_LAYOUT (imhtml)->vadjustment, - imhtml->y - new_ysize); - gtk_adjustment_set_value (GTK_LAYOUT (imhtml)->vadjustment, 0); - imhtml->xsize = new_xsize; - if (GTK_WIDGET_REALIZED (widget)) - gtk_imhtml_redraw_all (imhtml); -gtk_imhtml_select_none (GtkIMHtml *imhtml) - struct line_info *chunk; - g_return_if_fail (GTK_IS_IMHTML (imhtml)); - chunk->selected = FALSE; - chunk->sel_start = chunk->text; - draw_img (imhtml, chunk); - else if ((bit->type == TYPE_SEP) && (bit->chunks->data == chunk)) - draw_line (imhtml, chunk); - draw_text (imhtml, chunk); - chunks = g_list_next (chunks); - bits = g_list_next (bits); - imhtml->sel_endchunk = NULL; -get_position (struct line_info *chunk, - gint width = x - chunk->x; - switch (chunk->bit->type) { - for (pos = text; *pos != '\0'; pos++) { - gint char_width = gdk_text_width (chunk->bit->font, pos, 1); - if ((width > total) && (width <= total + char_width)) { - if (width < total + (char_width / 2)) -append_to_sel (GString *string, - struct line_info *chunk, - switch (chunk->bit->type) { - start = (chunk->sel_start == NULL) ? chunk->text : chunk->sel_start; - length = (chunk->sel_end == NULL) ? strlen (start) : chunk->sel_end - start; - buf = g_strndup (start, length); - start = (chunk->sel_start == NULL) ? chunk->bit->text : chunk->sel_start; - length = (chunk->sel_end == NULL) ? strlen (start) : chunk->sel_end - start; - buf = g_strndup (start, length); - start = (chunk->sel_start == NULL) ? chunk->text : chunk->sel_start; - length = (chunk->sel_end == NULL) ? strlen (start) : chunk->sel_end - start; - buf = g_strndup (start, length); - new_string = g_string_append (string, buf); -chunk_select_words (struct line_info *chunk) - start = chunk->sel_start; - if (start != chunk->text) { - if (isalnum(*start) || *start == '\'') - while (start > chunk->text && - (isalnum(*(start-1)) || *(start-1) == '\'')) - else if (isspace(*start)) - while (start > chunk->text && isspace(*(start-1))) - else if (ispunct(*start)) - while (start > chunk->text && ispunct(*(start-1))) - chunk->sel_start = start; - if (isalnum(*end) || *end == '\'') - (isalnum(*end) || *end == '\'')) - else if (isspace(*end)) - while (*end != '\0' && isspace(*end)) - else if (ispunct(*end)) - while (*end != '\0' && ispunct(*end)) -#define COORDS_IN_CHUNK(xx, yy) (((xx) < chunk->x + chunk->width) && \ - ((yy) < chunk->y + chunk->height)) -gtk_imhtml_select_bits (GtkIMHtml *imhtml) - struct line_info *chunk; - guint startx = imhtml->sel_startx, - starty = imhtml->sel_starty, - endx = imhtml->sel_endx, - endy = imhtml->sel_endy; - guint mode = imhtml->sel_mode; - gboolean smileys = imhtml->smileys; - gboolean redraw = FALSE; - gboolean got_start = FALSE; - gboolean got_end = FALSE; - g_return_if_fail (GTK_IS_IMHTML (imhtml)); - if (!imhtml->selection) - if (imhtml->selected_text) { - g_string_free (imhtml->selected_text, TRUE); - imhtml->selected_text = g_string_new (""); - if (COORDS_IN_CHUNK (startx, starty)) { - new_pos = get_position (chunk, startx, smileys); - if (!chunk->selected || - (chunk->sel_start != new_pos) || - (chunk->sel_end != NULL)) - chunk->selected = TRUE; - chunk->sel_start = new_pos; - chunk_select_words (chunk); - if (COORDS_IN_CHUNK (endx, endy)) { - new_pos = get_position (chunk, endx, smileys); - if (chunk->sel_end != new_pos) - if (chunk->sel_start > new_pos) { - chunk->sel_end = chunk->sel_start; - chunk->sel_start = new_pos; - chunk->sel_end = new_pos; - imhtml->sel_endchunk = chunk; - chunk_select_words (chunk); - new_pos = get_position (chunk, endx, smileys); - if ( !chunk->selected || - (chunk->sel_start != new_pos) || - (chunk->sel_end != NULL)) - chunk->selected = TRUE; - chunk->sel_start = new_pos; - imhtml->sel_endchunk = chunk; - starty += chunk->height; - chunk_select_words (chunk); - } else if (!COORDS_IN_CHUNK (startx, starty) && !got_start) { - chunk->selected = FALSE; - chunk->sel_start = chunk->text; - if (!got_start && COORDS_IN_CHUNK (startx, starty)) { - new_pos = get_position (chunk, startx, smileys); - if ( !chunk->selected || - (chunk->sel_end != new_pos) || - (chunk->sel_start != chunk->text)) - chunk->selected = TRUE; - chunk->sel_start = chunk->text; - chunk->sel_end = new_pos; - chunk_select_words (chunk); - } else if (!got_end && COORDS_IN_CHUNK (endx, endy)) { - new_pos = get_position (chunk, endx, smileys); - if ( !chunk->selected || - (chunk->sel_end != new_pos) || - (chunk->sel_start != chunk->text)) - chunk->selected = TRUE; - chunk->sel_start = chunk->text; - chunk->sel_end = new_pos; - imhtml->sel_endchunk = chunk; - chunk_select_words (chunk); - if ( !chunk->selected || - (chunk->sel_end != NULL) || - (chunk->sel_start != chunk->text)) - chunk->selected = TRUE; - chunk->sel_start = chunk->text; - chunk->selected = FALSE; - chunk->sel_start = chunk->text; - if (chunk->selected == TRUE) - imhtml->selected_text = append_to_sel (imhtml->selected_text, - draw_img (imhtml, chunk); - else if ((bit->type == TYPE_SEP) && (bit->chunks->data == chunk)) - draw_line (imhtml, chunk); - draw_text (imhtml, chunk); - chunks = g_list_next (chunks); - bits = g_list_next (bits); -gtk_imhtml_select_in_chunk (GtkIMHtml *imhtml, - struct line_info *chunk) - GtkIMHtmlBit *bit = chunk->bit; - guint endx = imhtml->sel_endx; - guint startx = imhtml->sel_startx; - guint starty = imhtml->sel_starty; - gboolean smileys = imhtml->smileys; - gboolean redraw = FALSE; - new_pos = get_position (chunk, endx, smileys); - if ((starty < chunk->y) || - ((starty < chunk->y + chunk->height) && (startx < endx))) { - if (chunk->sel_end != new_pos) - chunk->sel_end = new_pos; - if (chunk->sel_start != new_pos) - chunk->sel_start = new_pos; - draw_img (imhtml, chunk); - else if ((bit->type == TYPE_SEP) && - (bit->chunks->data == chunk)) - draw_line (imhtml, chunk); - draw_text (imhtml, chunk); -scroll_timeout (GtkIMHtml *imhtml) - imhtml->scroll_timer = 0; - gdk_window_get_pointer (GTK_LAYOUT (imhtml)->bin_window, &x, &y, &mask); - if (mask & GDK_BUTTON1_MASK) { - gtk_imhtml_motion_notify_event (GTK_WIDGET (imhtml), &event); -gtk_imhtml_tip_paint (GtkIMHtml *imhtml) - if (imhtml->tip_bit->url) - layout = gtk_widget_create_pango_layout (imhtml->tip_window, imhtml->tip_bit->url); - else if (imhtml->tip_bit->img) - layout = gtk_widget_create_pango_layout (imhtml->tip_window, imhtml->tip_bit->img->filename); - style = imhtml->tip_window->style; - pango_layout_get_size (layout, &x, &y); - gtk_paint_flat_box (style, imhtml->tip_window->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, - NULL, imhtml->tip_window, "tooltip", 0, 0, -1, -1); - gtk_paint_layout (style, imhtml->tip_window->window, GTK_STATE_NORMAL, TRUE, - NULL, imhtml->tip_window, "tooltip", 4, 4, layout); - g_object_unref (layout); -gtk_imhtml_tip (gpointer data) - GtkIMHtml *imhtml = data; - GtkWidget *widget = GTK_WIDGET (imhtml); - gint x, y, w, h, scr_w, scr_h; - if (!imhtml->tip_bit || !GTK_WIDGET_DRAWABLE (widget)) { - if (imhtml->tip_window) - gtk_widget_destroy (imhtml->tip_window); - imhtml->tip_window = gtk_window_new (GTK_WINDOW_POPUP); - gtk_widget_set_app_paintable (imhtml->tip_window, TRUE); - gtk_window_set_policy (GTK_WINDOW (imhtml->tip_window), FALSE, FALSE, TRUE); - gtk_widget_set_name (imhtml->tip_window, "gtk-tooltips"); - gtk_signal_connect_object (GTK_OBJECT (imhtml->tip_window), "expose_event", - GTK_SIGNAL_FUNC (gtk_imhtml_tip_paint), GTK_OBJECT (imhtml)); - gtk_widget_ensure_style (imhtml->tip_window); - style = imhtml->tip_window->style; - layout = gtk_widget_create_pango_layout(imhtml->tip_window, - imhtml->tip_bit->url ? imhtml->tip_bit->url : imhtml->tip_bit->img->filename); - scr_w = gdk_screen_width (); - scr_h = gdk_screen_height (); - pango_layout_get_size(layout, &w, &h); - w = PANGO_PIXELS(w) + 8; - h = PANGO_PIXELS(h) + 8; - gdk_window_get_pointer (NULL, &x, &y, NULL); - if (GTK_WIDGET_NO_WINDOW (widget)) - y += widget->allocation.y; - if ((y + h + + 4) > scr_h) - gtk_widget_set_usize (imhtml->tip_window, w, h); - gtk_widget_set_uposition (imhtml->tip_window, x, y); - gtk_widget_show (imhtml->tip_window); - g_object_unref(layout); -gtk_imhtml_motion_notify_event (GtkWidget *widget, - GtkIMHtml *imhtml = GTK_IMHTML (widget); - GtkAdjustment *vadj = GTK_LAYOUT (widget)->vadjustment; - GtkAdjustment *hadj = GTK_LAYOUT (widget)->hadjustment; - gdk_window_get_pointer (event->window, &x, &y, &state); - x = event->x + hadj->value; - y = event->y + vadj->value; - if (state & GDK_BUTTON1_MASK) { - gint height = vadj->page_size; - gint yy = y - vadj->value; - if (((yy < 0) || (yy > height)) && - (imhtml->scroll_timer == 0) && - (vadj->upper > vadj->page_size)) { - imhtml->scroll_timer = gtk_timeout_add (100, - (GtkFunction) scroll_timeout, - diff = (yy < 0) ? (yy / 2) : ((yy - height) / 2); - gtk_adjustment_set_value (vadj, - MIN (vadj->value + diff, vadj->upper - height)); - if (imhtml->selection) { - struct line_info *chunk = imhtml->sel_endchunk; - imhtml->sel_endx = MAX (x, 0); - imhtml->sel_endy = MAX (y, 0); - (x > chunk->x + chunk->width) || - (y > chunk->y + chunk->height) || - (imhtml->sel_mode > 0)) - gtk_imhtml_select_bits (imhtml); - gtk_imhtml_select_in_chunk (imhtml, chunk); - GList *click = imhtml->click; - uw = (struct clickable *) click->data; - if ((uw->bit->url) && (x > uw->x) && (x < uw->x + uw->width) && - (y > uw->y) && (y < uw->y + uw->height) && - (uw->bit->url || uw->bit->img)) { - if (imhtml->tip_bit != uw->bit) { - imhtml->tip_bit = uw->bit; - if (imhtml->tip_timer != 0) - gtk_timeout_remove (imhtml->tip_timer); - if (imhtml->tip_window) { - gtk_widget_destroy (imhtml->tip_window); - imhtml->tip_window = NULL; - imhtml->tip_timer = gtk_timeout_add (TOOLTIP_TIMEOUT, - gdk_window_set_cursor (GTK_LAYOUT (imhtml)->bin_window, - click = g_list_next (click); - if (imhtml->tip_timer) { - gtk_timeout_remove (imhtml->tip_timer); - if (imhtml->tip_window) { - gtk_widget_destroy (imhtml->tip_window); - imhtml->tip_window = NULL; - imhtml->tip_bit = NULL; - gdk_window_set_cursor (GTK_LAYOUT (imhtml)->bin_window, imhtml->arrow_cursor); -gtk_imhtml_leave_notify_event (GtkWidget *widget, - GdkEventCrossing *event) - GtkIMHtml *imhtml = GTK_IMHTML (widget); - if (imhtml->tip_timer) { - gtk_timeout_remove (imhtml->tip_timer); - if (imhtml->tip_window) { - gtk_widget_destroy (imhtml->tip_window); - imhtml->tip_window = NULL; - imhtml->tip_bit = NULL; -save_img (GtkObject *object, - struct imgsv *is = data; - struct im_image *img = is->img; - filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(is->savedialog)); - g_print("Saving %s\n", filename); - if (! (f=fopen(filename, "w"))) { - /* There should be some sort of dialog */ - g_print("Could not open file for writing.\n"); - gtk_widget_destroy(is->savedialog); - fwrite(img->data, 1, img->len, f); - gtk_widget_destroy(is->savedialog); -save_img_dialog (GtkObject *object, - struct imgsv *is = g_malloc(sizeof(struct imgsv)); - struct im_image *img = data; - GtkWidget *savedialog = gtk_file_selection_new ("Gaim - Save Image"); - gtk_file_selection_set_filename (GTK_FILE_SELECTION(savedialog), img->filename); - gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(savedialog)->cancel_button), - "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), - (gpointer) savedialog); - is->savedialog = savedialog; - gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(savedialog)->ok_button), - "clicked", GTK_SIGNAL_FUNC (save_img), is); - gtk_widget_show (savedialog); -menu_open_url (GtkObject *object, - struct clickable *uw = data; - gtk_signal_emit (GTK_OBJECT (uw->imhtml), signals [URL_CLICKED], uw->bit->url); -menu_copy_link (GtkObject *object, - struct clickable *uw = data; - GtkIMHtml *imhtml = uw->imhtml; - if (imhtml->selected_text) - g_string_free (imhtml->selected_text, TRUE); - gtk_imhtml_select_none (uw->imhtml); - imhtml->selection = TRUE; - imhtml->selected_text = g_string_new (uw->bit->url); - gtk_selection_owner_set (GTK_WIDGET (imhtml), GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); -gtk_imhtml_button_press_event (GtkWidget *widget, - GtkIMHtml *imhtml = GTK_IMHTML (widget); - GtkAdjustment *vadj = GTK_LAYOUT (widget)->vadjustment; - GtkAdjustment *hadj = GTK_LAYOUT (widget)->hadjustment; - x = event->x + hadj->value; - y = event->y + vadj->value; - if (event->button == 1) { - imhtml->sel_startx = imhtml->sel_endx = x; - imhtml->sel_starty = imhtml->sel_endy = y; - imhtml->selection = TRUE; - if (event->type == GDK_BUTTON_PRESS) { - imhtml->sel_mode = 0; /* select by letter */ - gtk_imhtml_select_none (imhtml); - } else if (event->type == GDK_2BUTTON_PRESS) { - imhtml->sel_mode = 1; /* select by word */ - gtk_imhtml_select_none (imhtml); - } else if (event->type == GDK_3BUTTON_PRESS) { - imhtml->sel_mode = 2; /* select by line */ - gtk_imhtml_select_bits (imhtml); - if (event->button == 3) { - GList *click = imhtml->click; - if ((x > uw->x) && (x < uw->x + uw->width) && - (y > uw->y) && (y < uw->y + uw->height)) { - static GtkWidget *menu = NULL; - * If a menu already exists, destroy it before creating a new one, - * thus freeing-up the memory it occupied. - gtk_widget_destroy(menu); - button = gtk_menu_item_new_with_label ("Open URL"); - gtk_signal_connect (GTK_OBJECT (button), "activate", - GTK_SIGNAL_FUNC (menu_open_url), uw); - gtk_menu_append (GTK_MENU (menu), button); - gtk_widget_show (button); - button = gtk_menu_item_new_with_label ("Copy Link Location"); - gtk_signal_connect (GTK_OBJECT (button), "activate", - GTK_SIGNAL_FUNC (menu_copy_link), uw); - gtk_menu_append (GTK_MENU (menu), button); - gtk_widget_show (button); - button = gtk_menu_item_new_with_label ("Save Image"); - gtk_signal_connect (GTK_OBJECT (button), "activate", - GTK_SIGNAL_FUNC (save_img_dialog), uw->bit->img); - gtk_menu_append (GTK_MENU (menu), button); - gtk_widget_show (button); - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 3, event->time); - if (imhtml->tip_timer) { - gtk_timeout_remove (imhtml->tip_timer); - if (imhtml->tip_window) { - gtk_widget_destroy (imhtml->tip_window); - imhtml->tip_window = NULL; - imhtml->tip_bit = NULL; - click = g_list_next (click); -gtk_imhtml_button_release_event (GtkWidget *widget, - GtkIMHtml *imhtml = GTK_IMHTML (widget); - GtkAdjustment *vadj = GTK_LAYOUT (widget)->vadjustment; - GtkAdjustment *hadj = GTK_LAYOUT (widget)->hadjustment; - x = event->x + hadj->value; - y = event->y + vadj->value; - if ((event->button == 1) && imhtml->selection) { - if ((x == imhtml->sel_startx) && (y == imhtml->sel_starty) && - (imhtml->sel_mode == 0)) { - imhtml->sel_startx = imhtml->sel_starty = 0; - imhtml->selection = FALSE; - gtk_imhtml_select_none (imhtml); - imhtml->sel_endx = MAX (x, 0); - imhtml->sel_endy = MAX (y, 0); - gtk_imhtml_select_bits (imhtml); - gtk_selection_owner_set (widget, GDK_SELECTION_PRIMARY, event->time); - if ((event->button == 1) && (imhtml->sel_startx == 0)) { - GList *click = imhtml->click; - uw = (struct clickable *) click->data; - if ((x > uw->x) && (x < uw->x + uw->width) && - (y > uw->y) && (y < uw->y + uw->height)) { - gtk_signal_emit (GTK_OBJECT (imhtml), signals [URL_CLICKED], - click = g_list_next (click); -gtk_imhtml_selection_get (GtkWidget *widget, - GtkSelectionData *sel_data, - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_IMHTML (widget)); - g_return_if_fail (sel_data->selection == GDK_SELECTION_PRIMARY); - imhtml = GTK_IMHTML (widget); - g_return_if_fail (imhtml->selected_text != NULL); - g_return_if_fail (imhtml->selected_text->str != NULL); - if (imhtml->selected_text->len <= 0) - string = g_strdup (imhtml->selected_text->str); - length = strlen (string); - if (sel_info == TARGET_STRING) { - gtk_selection_data_set (sel_data, - GDK_SELECTION_TYPE_STRING, - } else if ((sel_info == TARGET_TEXT) || (sel_info == TARGET_COMPOUND_TEXT)) { - gdk_string_to_compound_text (string, &encoding, &format, &text, &new_length); - gtk_selection_data_set (sel_data, encoding, format, text, new_length); - gdk_free_compound_text (text); -gtk_imhtml_selection_clear_event (GtkWidget *widget, - GdkEventSelection *event) - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_IMHTML (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - g_return_val_if_fail (event->selection == GDK_SELECTION_PRIMARY, TRUE); - if (!gtk_selection_clear (widget, event)) - imhtml = GTK_IMHTML (widget); - gtk_imhtml_select_none (imhtml); -gtk_imhtml_adjustment_changed (GtkAdjustment *adjustment, - GtkLayout *layout = GTK_LAYOUT (imhtml); - if (!GTK_WIDGET_MAPPED (imhtml) || !GTK_WIDGET_REALIZED (imhtml)) - if (layout->freeze_count) - if (layout->vadjustment->value < TOP_BORDER) - gdk_window_clear_area (layout->bin_window, 0, 0, - imhtml->xsize, TOP_BORDER - layout->vadjustment->value); - gtk_imhtml_draw_exposed (imhtml); -gtk_imhtml_set_scroll_adjustments (GtkLayout *layout, - gboolean need_adjust = FALSE; - g_return_if_fail (layout != NULL); - g_return_if_fail (GTK_IS_IMHTML (layout)); - g_return_if_fail (GTK_IS_ADJUSTMENT (hadj)); - hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); - g_return_if_fail (GTK_IS_ADJUSTMENT (vadj)); - vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); - if (layout->hadjustment && (layout->hadjustment != hadj)) { - gtk_signal_disconnect_by_data (GTK_OBJECT (layout->hadjustment), layout); - gtk_object_unref (GTK_OBJECT (layout->hadjustment)); - if (layout->vadjustment && (layout->vadjustment != vadj)) { - gtk_signal_disconnect_by_data (GTK_OBJECT (layout->vadjustment), layout); - gtk_object_unref (GTK_OBJECT (layout->vadjustment)); - if (layout->hadjustment != hadj) { - layout->hadjustment = hadj; - gtk_object_ref (GTK_OBJECT (layout->hadjustment)); - gtk_object_sink (GTK_OBJECT (layout->hadjustment)); - gtk_signal_connect (GTK_OBJECT (layout->hadjustment), "value_changed", - (GtkSignalFunc) gtk_imhtml_adjustment_changed, layout); - if (layout->vadjustment != vadj) { - layout->vadjustment = vadj; - gtk_object_ref (GTK_OBJECT (layout->vadjustment)); - gtk_object_sink (GTK_OBJECT (layout->vadjustment)); - gtk_signal_connect (GTK_OBJECT (layout->vadjustment), "value_changed", - (GtkSignalFunc) gtk_imhtml_adjustment_changed, layout); - gtk_imhtml_adjustment_changed (NULL, GTK_IMHTML (layout)); -gtk_imhtml_class_init (GtkIMHtmlClass *class) - GObjectClass *gobject_class; - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkLayoutClass *layout_class; - gobject_class = (GObjectClass*) class; - object_class = (GtkObjectClass*) class; - widget_class = (GtkWidgetClass*) class; - layout_class = (GtkLayoutClass*) class; - parent_class = gtk_type_class (GTK_TYPE_LAYOUT); - signals [URL_CLICKED] = - gtk_signal_new ("url_clicked", - GTK_CLASS_TYPE (object_class), - GTK_SIGNAL_OFFSET (GtkIMHtmlClass, url_clicked), - gtk_marshal_NONE__POINTER, - gobject_class->finalize = gtk_imhtml_finalize; - widget_class->realize = gtk_imhtml_realize; - widget_class->style_set = gtk_imhtml_style_set; - widget_class->expose_event = gtk_imhtml_expose_event; - widget_class->size_allocate = gtk_imhtml_size_allocate; - widget_class->motion_notify_event = gtk_imhtml_motion_notify_event; - widget_class->leave_notify_event = gtk_imhtml_leave_notify_event; - widget_class->button_press_event = gtk_imhtml_button_press_event; - widget_class->button_release_event = gtk_imhtml_button_release_event; - widget_class->selection_get = gtk_imhtml_selection_get; - widget_class->selection_clear_event = gtk_imhtml_selection_clear_event; - layout_class->set_scroll_adjustments = gtk_imhtml_set_scroll_adjustments; -/* the font stuff is the most insane stuff. i don't understand it half - * the time. so we're going to comment it. isn't that wonderful. */ -/* when you g_strsplit a valid font name, these are the positions of all the various parts of it. */ -gtk_imhtml_get_font_name (GdkFont *font) - return gdk_x11_font_get_name(font); -gtk_imhtml_font_load (GtkIMHtml *imhtml, - GdkFont *default_font = imhtml->default_font; - const gchar *default_name; - char *italicstrings[] = {"i","o","*"}; - int italicsind = 0, nameind = 0; - gboolean usebold = TRUE, usesize = TRUE, useregenc = TRUE; - /* if we're not changing anything, use the default. this is the common case */ - if (!name && !bold && !italics && !fontsize) - return gdk_font_ref (default_font); - /* base things off of the default font name */ - default_name = gtk_imhtml_get_font_name (default_font); - /* the default font name can actually be several names separated by ','. - * This is a fontset... used in foreign encodings. */ - xnames = g_strsplit (default_name, ",", -1); - for (pos = xnames; pos && *pos; pos++) { - xname = g_strchomp (xname); - xname = g_strchug (xname); - xflds = g_strsplit (xname, "-", -1); - /* figure out if we have a valid name. i wish there were an - * easier way for determining how many values g_strplit gave */ - for (i = 0; xflds [i]; i++); - newvals = g_malloc0 (16 * sizeof (gchar *)); - for (tmp = 1; tmp < 15; tmp++) - newvals = g_memdup (xflds, 16 * sizeof (xflds)); - /* we force foundry as "*" because i hate them. i should give a better reason. */ - /* if it's "*" then it defaults to (nil) anyway. some fonts don't want (nil) */ - if ((i > ADSTYL) && !xflds [ADSTYL][0]) - newvals [ADSTYL] = "*"; - /* If the font doesn't work the first time, we try it with - * registry and encoding as "*" */ - newvals [RGSTRY] = "*"; - newvals [ENCDNG] = "*"; - newvals [WGHT] = "bold"; - /* We'll try "i" "o" to get italics and then just use "*" */ - newvals [SLANT] = italicstrings[italicsind]; - if (usesize && fontsize) { - g_snprintf (fs, sizeof (fs), "%d", POINT_SIZE (fontsize)); - /* we got passed a name. it might be a list of names. */ - gchar **tmp_nms = g_strsplit (name, ",", -1); - for (j = 0; tmp_nms [j]; j++); - names = g_new0 (char *, j + 2); - for (j = 0; tmp_nms [j]; j++) - names [j] = tmp_nms [j]; - /* Put the default font on the array. */ - names [j] = g_strdup (xflds [FMLY]); - newvals [FMLY] = names[nameind]; - /* we didn't get a name. we come here if the gtk font name is valid */ - names = g_new0 (gchar *, 2); - names [0] = g_strdup (xflds [FMLY]); - names = g_new0 (gchar *, 2); - names [0] = g_strdup ("*"); - tmp = g_strjoinv("-", newvals); - /* We have to concat the xlfds in the fontset */ - tmp = g_strconcat(garbage, ",", - g_strjoinv ("-", newvals), NULL); - if (default_font->type == GDK_FONT_FONT) - ret_font = gdk_font_load (tmp); - /* For some reason, fontsets must end with a single * as an xlfd */ - ret_font = gdk_fontset_load (tmp); - /* If the font didn't load, we change some of the xlfds one by one - * to get the closest we can. */ - } else if (italics && italicsind != 2) { - } else if (bold && usebold) { - } else if (names && names[nameind++]) { - ret_font = gdk_font_ref(default_font); - } while (!ret_font); /* Loop with the new options */ -gtk_imhtml_init (GtkIMHtml *imhtml) - static const GtkTargetEntry targets [] = { - { "STRING", 0, TARGET_STRING }, - { "TEXT", 0, TARGET_TEXT }, - { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT } - imhtml->hand_cursor = gdk_cursor_new (GDK_HAND2); - imhtml->arrow_cursor = gdk_cursor_new (GDK_LEFT_PTR); - GTK_WIDGET_SET_FLAGS (GTK_WIDGET (imhtml), GTK_CAN_FOCUS); - gtk_selection_add_targets (GTK_WIDGET (imhtml), GDK_SELECTION_PRIMARY, targets, 3); -gtk_imhtml_get_type (void) - static GtkType imhtml_type = 0; - static const GtkTypeInfo imhtml_info = { - sizeof (GtkIMHtmlClass), - (GtkClassInitFunc) gtk_imhtml_class_init, - (GtkObjectInitFunc) gtk_imhtml_init, - imhtml_type = gtk_type_unique (GTK_TYPE_LAYOUT, &imhtml_info); -gtk_imhtml_init_smileys (GtkIMHtml *imhtml) - g_return_if_fail (imhtml != NULL); - g_return_if_fail (GTK_IS_IMHTML (imhtml)); - imhtml->smiley_data = gtk_smiley_tree_new (); - gtk_imhtml_associate_smiley (imhtml, ":)", smile_xpm); - gtk_imhtml_associate_smiley (imhtml, ":-)", smile_xpm); - gtk_imhtml_associate_smiley (imhtml, ":(", sad_xpm); - gtk_imhtml_associate_smiley (imhtml, ":-(", sad_xpm); - gtk_imhtml_associate_smiley (imhtml, ";)", wink_xpm); - gtk_imhtml_associate_smiley (imhtml, ";-)", wink_xpm); - gtk_imhtml_associate_smiley (imhtml, ":-p", tongue_xpm); - gtk_imhtml_associate_smiley (imhtml, ":-P", tongue_xpm); - gtk_imhtml_associate_smiley (imhtml, "=-O", scream_xpm); - gtk_imhtml_associate_smiley (imhtml, "=-o", scream_xpm); - gtk_imhtml_associate_smiley (imhtml, ":-*", kiss_xpm); - gtk_imhtml_associate_smiley (imhtml, ">:O", yell_xpm); - gtk_imhtml_associate_smiley (imhtml, ">:o", yell_xpm); - gtk_imhtml_associate_smiley (imhtml, "8-)", smile8_xpm); - gtk_imhtml_associate_smiley (imhtml, ":-$", moneymouth_xpm); - gtk_imhtml_associate_smiley (imhtml, ":-!", burp_xpm); - gtk_imhtml_associate_smiley (imhtml, ":-[", embarrassed_xpm); - gtk_imhtml_associate_smiley (imhtml, ":'(", cry_xpm); - gtk_imhtml_associate_smiley (imhtml, ":-/", think_xpm); - gtk_imhtml_associate_smiley (imhtml, ":-\\", think_xpm); - gtk_imhtml_associate_smiley (imhtml, ":-X", crossedlips_xpm); - gtk_imhtml_associate_smiley (imhtml, ":-x", crossedlips_xpm); - gtk_imhtml_associate_smiley (imhtml, ":-D", bigsmile_xpm); - gtk_imhtml_associate_smiley (imhtml, ":-d", bigsmile_xpm); - gtk_imhtml_associate_smiley (imhtml, "O:-)", angel_xpm); -gtk_imhtml_new (GtkAdjustment *hadj, - GtkIMHtml *imhtml = gtk_type_new (GTK_TYPE_IMHTML); - gtk_imhtml_set_adjustments (imhtml, hadj, vadj); - imhtml->im_images = NULL; - imhtml->y = TOP_BORDER; - imhtml->selected_text = g_string_new (""); - imhtml->scroll_timer = 0; - imhtml->smileys = TRUE; - imhtml->comments = FALSE; - gtk_imhtml_init_smileys (imhtml); - return GTK_WIDGET (imhtml); -gtk_imhtml_set_adjustments (GtkIMHtml *imhtml, - gtk_layout_set_hadjustment (GTK_LAYOUT (imhtml), hadj); - gtk_layout_set_vadjustment (GTK_LAYOUT (imhtml), vadj); -gtk_imhtml_set_defaults (GtkIMHtml *imhtml, +static void gtk_imhtml_class_init (GtkIMHtmlClass *class) - g_return_if_fail (imhtml != NULL); - g_return_if_fail (GTK_IS_IMHTML (imhtml)); - if (imhtml->default_font) - gdk_font_unref (imhtml->default_font); - imhtml->default_font = gdk_font_ref (font); - if (imhtml->default_fg_color) - gdk_color_free (imhtml->default_fg_color); - imhtml->default_fg_color = gdk_color_copy (fg_color); - if (imhtml->default_bg_color) - gdk_color_free (imhtml->default_bg_color); - imhtml->default_bg_color = gdk_color_copy (bg_color); - gdk_window_set_background (GTK_LAYOUT (imhtml)->bin_window, imhtml->default_bg_color); -gtk_imhtml_set_img_handler (GtkIMHtml *imhtml, - GtkIMHtmlImage handler) - g_return_if_fail (imhtml != NULL); - g_return_if_fail (GTK_IS_IMHTML (imhtml)); -gtk_imhtml_associate_smiley (GtkIMHtml *imhtml, - g_return_if_fail (imhtml != NULL); - g_return_if_fail (GTK_IS_IMHTML (imhtml)); - g_return_if_fail (text != NULL); - gtk_smiley_tree_remove (imhtml->smiley_data, text); - gtk_smiley_tree_insert (imhtml->smiley_data, text, xpm); -new_line (GtkIMHtml *imhtml) - GList *last = g_list_last (imhtml->line); - if (li->x + li->width != imhtml->xsize) - li->width = imhtml->xsize - li->x; - if (li->height < MIN_HEIGHT) { - diff = MIN_HEIGHT - li->height; - li->height = MIN_HEIGHT; - li->ascent += diff / 2; - last = g_list_next (last); - imhtml->llheight = MIN_HEIGHT; - g_list_free (imhtml->line); - imhtml->y += imhtml->llheight; -backwards_update (GtkIMHtml *imhtml, - if (height > imhtml->llheight) { - diff = height - imhtml->llheight; - li->ascent += diff / 2; - if (uw->y + diff > imhtml->y) - ls = imhtml->im_images; - if (img->y + diff > imhtml->y) - imhtml->llheight = height; - imhtml->llascent = ascent; - imhtml->llascent += diff / 2; + GtkObjectClass *object_class; + object_class = (GtkObjectClass*) class; -add_text_renderer (GtkIMHtml *imhtml, +static void gtk_imhtml_init (GtkIMHtml *imhtml) - width = gdk_string_width (bit->font, text); - li = g_new0 (struct line_info, 1); - li->height = imhtml->llheight; - li->ascent = MAX (imhtml->llascent, bit->font->ascent); - uw = g_new0 (struct clickable, 1); - uw->height = imhtml->llheight; - imhtml->click = g_list_append (imhtml->click, uw); - bit->chunks = g_list_append (bit->chunks, li); - imhtml->line = g_list_append (imhtml->line, li); + imhtml->text_buffer = gtk_text_buffer_new(NULL); + gtk_text_view_set_buffer (GTK_TEXT_VIEW(imhtml), imhtml->text_buffer); -add_img_renderer (GtkIMHtml *imhtml, +GtkWidget *gtk_imhtml_new(void *a, void *b) - gdk_window_get_size (bit->pm, &width, NULL); - li = g_new0 (struct line_info, 1); - li->height = imhtml->llheight; - if (bit->url || bit->img) { - uw = g_new0 (struct clickable, 1); - uw->height = imhtml->llheight; - imhtml->click = g_list_append (imhtml->click, uw); - bit->chunks = g_list_append (bit->chunks, li); - imhtml->line = g_list_append (imhtml->line, li); + return GTK_WIDGET(gtk_type_new(gtk_imhtml_get_type())); -gtk_imhtml_draw_bit (GtkIMHtml *imhtml, +GtkType gtk_imhtml_get_type() - g_return_if_fail (imhtml != NULL); - g_return_if_fail (GTK_IS_IMHTML (imhtml)); - g_return_if_fail (bit != NULL); - if ( ((bit->type == TYPE_TEXT) || - ((bit->type == TYPE_SMILEY) && !imhtml->smileys) || - ((bit->type == TYPE_COMMENT) && imhtml->comments)) && - gchar *copy = g_strdup (bit->text); - gboolean seenspace = FALSE; - height = bit->font->ascent + bit->font->descent; - width = gdk_string_width (bit->font, bit->text); - if ((imhtml->x != 0) && ((imhtml->x + width) > imhtml->xsize)) { - gint remain = imhtml->xsize - imhtml->x; - while (gdk_text_width (bit->font, copy, pos) < remain) { - while (copy [pos - 1] != ' ') pos--; - tmp = g_strndup (copy, pos); - backwards_update (imhtml, bit, height, bit->font->ascent); - add_text_renderer (imhtml, bit, tmp); - backwards_update (imhtml, bit, height, bit->font->ascent); - while (pos < strlen (bit->text)) { - width = gdk_string_width (bit->font, copy + pos); - if (imhtml->x + width > imhtml->xsize) { - gint remain = imhtml->xsize - imhtml->x; - while (gdk_text_width (bit->font, copy + pos, newpos) < remain) { - if (copy [pos + newpos] == ' ') - while (copy [pos + newpos - 1] != ' ') newpos--; - tmp = g_strndup (copy + pos, newpos); - backwards_update (imhtml, bit, height, bit->font->ascent); - add_text_renderer (imhtml, bit, tmp); - tmp = g_strdup (copy + pos); - backwards_update (imhtml, bit, height, bit->font->ascent); - add_text_renderer (imhtml, bit, tmp); + static guint imhtml_type = 0; - pos = strlen (bit->text); - } else if ((bit->type == TYPE_SMILEY) || (bit->type == TYPE_IMG)) { - GdkPixbuf *imagepb = bit->img->pb; - if (gdk_pixbuf_get_width(imagepb) > imhtml->xsize - imhtml->x) - if (gdk_pixbuf_get_width(imagepb) > imhtml->xsize) { - tmp = gdk_pixbuf_scale_simple(imagepb, imhtml->xsize, - gdk_pixbuf_get_height(imagepb) * - gdk_pixbuf_get_width(imagepb), - gdk_pixmap_unref (bit->pm); - gdk_bitmap_unref (bit->bm); - gdk_pixbuf_render_pixmap_and_mask(tmp, &(bit->pm), &(bit->bm), 100); - gdk_pixmap_unref (bit->pm); - gdk_bitmap_unref (bit->bm); - gdk_pixbuf_render_pixmap_and_mask(imagepb, &(bit->pm), &(bit->bm), 100); + GtkTypeInfo imhtml_info = { + sizeof (GtkIMHtmlClass), + (GtkClassInitFunc) gtk_imhtml_class_init, + (GtkObjectInitFunc) gtk_imhtml_init, - gdk_window_get_size (bit->pm, &width, &height); - if ((imhtml->x != 0) && ((imhtml->x + width) > imhtml->xsize)) - backwards_update (imhtml, bit, height, 0); - add_img_renderer (imhtml, bit); - } else if (bit->type == TYPE_BR) { - add_text_renderer (imhtml, bit, NULL); - } else if (bit->type == TYPE_SEP) { - li = g_new0 (struct line_info, 1); - li->width = imhtml->xsize; - li->height = HR_HEIGHT * 2; - bit->chunks = g_list_append (bit->chunks, li); - imhtml->llheight = HR_HEIGHT * 2; - add_text_renderer (imhtml, bit, NULL); -gtk_imhtml_show_smileys (GtkIMHtml *imhtml, - g_return_if_fail (imhtml != NULL); - g_return_if_fail (GTK_IS_IMHTML (imhtml)); - imhtml->smileys = show; - if (GTK_WIDGET_VISIBLE (GTK_WIDGET (imhtml))) - gtk_imhtml_redraw_all (imhtml); -gtk_imhtml_show_comments (GtkIMHtml *imhtml, - g_return_if_fail (imhtml != NULL); - g_return_if_fail (GTK_IS_IMHTML (imhtml)); - imhtml->comments = show; - if (GTK_WIDGET_VISIBLE (GTK_WIDGET (imhtml))) - gtk_imhtml_redraw_all (imhtml); -gtk_imhtml_get_color (const gchar *color) - if (!gdk_color_parse (color, &c)) - return gdk_color_copy (&c); -gtk_imhtml_is_smiley (GtkIMHtml *imhtml, - *len = gtk_smiley_tree_lookup (imhtml->smiley_data, text); -gtk_imhtml_new_bit (GtkIMHtml *imhtml, - GtkIMHtmlBit *bit = NULL; - g_return_val_if_fail (imhtml != NULL, NULL); - g_return_val_if_fail (GTK_IS_IMHTML (imhtml), NULL); - if ((type == TYPE_TEXT) && ((text == NULL) || (strlen (text) == 0))) - bit = g_new0 (GtkIMHtmlBit, 1); - if ((text != NULL) && (strlen (text) != 0)) - bit->text = g_strdup (text); - if ((font != NULL) || bold || italics || pre) { - if (font && (bold || italics || font->size || font->face || pre)) { - bit->font = gtk_imhtml_font_load (imhtml, DEFAULT_PRE_FACE, bold, italics, font->size); - bit->font = gtk_imhtml_font_load (imhtml, font->face, bold, italics, font->size); - } else if (bold || italics || pre) { - bit->font = gtk_imhtml_font_load (imhtml, DEFAULT_PRE_FACE, bold, italics, 0); - bit->font = gtk_imhtml_font_load (imhtml, NULL, bold, italics, 0); - if (font && (type != TYPE_BR)) { - if (font->fore != NULL) - bit->fore = gdk_color_copy (font->fore); - if (font->back != NULL) - bit->back = gdk_color_copy (font->back); - if (((bit->type == TYPE_TEXT) || (bit->type == TYPE_SMILEY) || (bit->type == TYPE_COMMENT)) && - bit->font = gdk_font_ref (imhtml->default_font); - bit->bg = gdk_color_copy (bg); - bit->underline = underline; - bit->url = g_strdup (url); - if (type == TYPE_SMILEY) { - if ((font != NULL) && (font->back != NULL)) - clr = (bg != NULL) ? bg : imhtml->default_bg_color; - bit->pm = gdk_pixmap_create_from_xpm_d (GTK_WIDGET (imhtml)->window, - gtk_smiley_tree_image (imhtml->smiley_data, text)); -#define NEW_TEXT_BIT gtk_imhtml_new_bit (imhtml, TYPE_TEXT, ws, bold, italics, underline, strike, \ - fonts ? fonts->data : NULL, bg, url, pre, sub, sup) -#define NEW_SMILEY_BIT gtk_imhtml_new_bit (imhtml, TYPE_SMILEY, ws, bold, italics, underline, strike, \ - fonts ? fonts->data : NULL, bg, url, pre, sub, sup) -#define NEW_SEP_BIT gtk_imhtml_new_bit (imhtml, TYPE_SEP, NULL, 0, 0, 0, 0, NULL, bg, NULL, 0, 0, 0) -#define NEW_BR_BIT gtk_imhtml_new_bit (imhtml, TYPE_BR, NULL, 0, 0, 0, 0, \ - fonts ? fonts->data : NULL, bg, NULL, 0, 0, 0) -#define NEW_COMMENT_BIT gtk_imhtml_new_bit (imhtml, TYPE_COMMENT, ws, bold, italics, underline, strike, \ - fonts ? fonts->data : NULL, bg, url, pre, sub, sup) -#define NEW_BIT(bit) ws [wpos] = '\0'; \ - { GtkIMHtmlBit *tmp = bit; if (tmp != NULL) \ - newbits = g_list_append (newbits, tmp); } \ - wpos = 0; ws [wpos] = '\0' -#define UPDATE_BG_COLORS \ - cmap = gtk_widget_get_colormap (GTK_WIDGET (imhtml)); \ - rev = g_list_last (newbits); \ - GtkIMHtmlBit *bit = rev->data; \ - gdk_color_free (bit->bg); \ - bit->bg = gdk_color_copy (bg); \ - if (bit->type == TYPE_BR) \ - rev = g_list_previous (rev); \ - rev = g_list_last (imhtml->bits); \ - GtkIMHtmlBit *bit = rev->data; \ - gdk_color_free (bit->bg); \ - bit->bg = gdk_color_copy (bg); \ - gdk_color_alloc (cmap, bit->bg); \ - if (bit->type == TYPE_BR) \ - rev = g_list_previous (rev); \ -gtk_imhtml_is_amp_escape (const gchar *string, - g_return_val_if_fail (string != NULL, FALSE); - g_return_val_if_fail (replace != NULL, FALSE); - g_return_val_if_fail (length != NULL, FALSE); - if (!g_strncasecmp (string, "&", 5)) { - } else if (!g_strncasecmp (string, "<", 4)) { - } else if (!g_strncasecmp (string, ">", 4)) { - } else if (!g_strncasecmp (string, " ", 6)) { - } else if (!g_strncasecmp (string, "©", 6)) { - } else if (!g_strncasecmp (string, """, 6)) { - } else if (!g_strncasecmp (string, "®", 5)) { - } else if (*(string + 1) == '#') { - if ((sscanf (string, "&#%u;", £) == 1) && pound != 0) { - if (*(string + 3 + (gint)log10 (pound)) != ';') - *replace = (gchar)pound; - while (isdigit ((gint) string [*length])) (*length)++; - if (string [*length] == ';') (*length)++; -#define VALID_TAG(x) if (!g_strncasecmp (string, x ">", strlen (x ">"))) { \ - *tag = g_strndup (string, strlen (x)); \ - *len = strlen (x) + 1; \ -#define VALID_OPT_TAG(x) if (!g_strncasecmp (string, x " ", strlen (x " "))) { \ - const gchar *c = string + strlen (x " "); \ - gboolean quote = FALSE; \ - if (*c == '"' || *c == '\'') { \ - if (quote && (*c == e)) \ - } else if (!quote && (*c == '>')) \ - *tag = g_strndup (string, c - string); \ - *len = c - string + 1; \ -gtk_imhtml_is_tag (const gchar *string, - if (!strchr (string, '>')) - VALID_TAG ("UNDERLINE"); - VALID_TAG ("/UNDERLINE"); - VALID_OPT_TAG ("FONT"); - VALID_OPT_TAG ("BODY"); - if (!g_strncasecmp(string, "!--", strlen ("!--"))) { - gchar *e = strstr (string + strlen("!--"), "-->"); - *len = e - string + strlen ("-->"); - *tag = g_strndup (string + strlen ("!--"), *len - strlen ("!---->")); -gtk_imhtml_get_html_opt (gchar *tag, - while (g_strncasecmp (t, opt, strlen (opt))) { - gboolean quote = FALSE; - while (*t && !((*t == ' ') && !quote)) { - while (*t && (*t == ' ')) t++; - if (!g_strncasecmp (t, opt, strlen (opt))) { + imhtml_type = gtk_type_unique (gtk_text_view_get_type (), &imhtml_info); - if ((*t == '\"') || (*t == '\'')) { - while (*e && (*e != *(t - 1))) e++; - return g_strndup (a, e - a); - while (*e && !isspace ((gint) *e)) e++; - return g_strndup (a, e - a); -gtk_imhtml_append_text (GtkIMHtml *imhtml, - GtkIMHtmlOptions options) +gchar *imhtml_strip_html(gchar *text) - gboolean binary = TRUE; - gboolean scrolldown = TRUE; - GString *retval = NULL; - g_return_val_if_fail (imhtml != NULL, NULL); - g_return_val_if_fail (GTK_IS_IMHTML (imhtml), NULL); - g_return_val_if_fail (text != NULL, NULL); - if (options & GTK_IMHTML_RETURN_LOG) - retval = g_string_new (""); - vadj = GTK_LAYOUT (imhtml)->vadjustment; - if ((vadj->value < imhtml->y - GTK_WIDGET (imhtml)->allocation.height) && - (vadj->upper >= GTK_WIDGET (imhtml)->allocation.height)) - ws = g_malloc (len + 1); - if (*c == '<' && gtk_imhtml_is_tag (c + 1, &tag, &tlen, &type)) { - NEW_BIT (NEW_TEXT_BIT); - NEW_BIT (NEW_TEXT_BIT); - NEW_BIT (NEW_TEXT_BIT); - NEW_BIT (NEW_TEXT_BIT); - case 10: /* UNDERLINE */ - NEW_BIT (NEW_TEXT_BIT); - case 12: /* /UNDERLINE */ - NEW_BIT (NEW_TEXT_BIT); - NEW_BIT (NEW_TEXT_BIT); - NEW_BIT (NEW_TEXT_BIT); - NEW_BIT (NEW_TEXT_BIT); - NEW_BIT (NEW_TEXT_BIT); - NEW_BIT (NEW_TEXT_BIT); - NEW_BIT (NEW_TEXT_BIT); - NEW_BIT (NEW_TEXT_BIT); - NEW_BIT (NEW_TEXT_BIT); - NEW_BIT (NEW_TEXT_BIT); - if (options & GTK_IMHTML_NO_TITLE) { - NEW_BIT (NEW_TEXT_BIT); - NEW_BIT (NEW_TEXT_BIT); - FontDetail *font = fonts->data; - NEW_BIT (NEW_TEXT_BIT); - fonts = g_slist_remove (fonts, font); - gdk_color_free (font->fore); - gdk_color_free (font->back); - NEW_BIT (NEW_TEXT_BIT); - NEW_BIT (NEW_TEXT_BIT); - if (!g_strncasecmp("</BINARY>", c, strlen("</BINARY>"))) - c = c - tlen; /* Because it will add this later */ - case 42: /* HR (opt) */ - NEW_BIT (NEW_TEXT_BIT); - case 43: /* FONT (opt) */ - gchar *color, *back, *face, *size; - color = gtk_imhtml_get_html_opt (tag, "COLOR="); - back = gtk_imhtml_get_html_opt (tag, "BACK="); - face = gtk_imhtml_get_html_opt (tag, "FACE="); - size = gtk_imhtml_get_html_opt (tag, "SIZE="); - if (!(color || back || face || size)) - NEW_BIT (NEW_TEXT_BIT); - font = g_new0 (FontDetail, 1); - if (color && !(options & GTK_IMHTML_NO_COLOURS)) - font->fore = gtk_imhtml_get_color (color); - if (back && !(options & GTK_IMHTML_NO_COLOURS)) - font->back = gtk_imhtml_get_color (back); - if (face && !(options & GTK_IMHTML_NO_FONTS)) - font->face = g_strdup (face); - if (size && !(options & GTK_IMHTML_NO_SIZES)) { - sscanf (size + 1, "%hd", &font->size); - } else if (*size == '-') { - sscanf (size + 1, "%hd", &font->size); - font->size = MAX (0, 3 - font->size); - } else if (isdigit (*size)) { - sscanf (size, "%hd", &font->size); - FontDetail *oldfont = fonts->data; - font->size = oldfont->size; - if (!font->face && oldfont->face) - font->face = g_strdup (oldfont->face); - if (!font->fore && oldfont->fore) - font->fore = gdk_color_copy (oldfont->fore); - if (!font->back && oldfont->back) - font->back = gdk_color_copy (oldfont->back); - fonts = g_slist_prepend (fonts, font); - case 44: /* BODY (opt) */ - if (!(options & GTK_IMHTML_NO_COLOURS)) { - gchar *bgcolor = gtk_imhtml_get_html_opt (tag, "BGCOLOR="); - GdkColor *tmp = gtk_imhtml_get_color (bgcolor); - NEW_BIT (NEW_TEXT_BIT); - gchar *href = gtk_imhtml_get_html_opt (tag, "HREF="); - NEW_BIT (NEW_TEXT_BIT); - case 46: /* IMG (opt) */ - gchar *src = gtk_imhtml_get_html_opt (tag, "SRC="); - gchar *id = gtk_imhtml_get_html_opt (tag, "ID="); - gchar *datasize = gtk_imhtml_get_html_opt (tag, "DATASIZE="); - if (!imhtml->img && id && datasize) { /* This is an embedded IM image */ - char *tmp, *imagedata, *e; - GdkPixbuf *imagepb = NULL; - NEW_BIT (NEW_TEXT_BIT); - tmp = g_malloc(strlen("<DATA ID=\"\" SIZE=\"\">") + - strlen(id) + strlen(datasize)); - g_snprintf(tmp, strlen("<DATA ID=\"\" SIZE=\"\">") + - strlen(id) + strlen(datasize) + 1, - "<DATA ID=\"%s\" SIZE=\"%s\">", id, datasize); - while (g_strncasecmp(alltext, tmp, strlen(tmp)) && alltext < (c + len)) - alltext = alltext + strlen("<DATA ID=\"\" SIZE=\"\">") + strlen(id) + strlen(datasize); - if (atoi(datasize) > len - pos) - imagedata = g_malloc(atoi(datasize)); - memcpy(imagedata, alltext, atoi(datasize)); - if (!GTK_WIDGET_REALIZED (imhtml)) - gtk_widget_realize (GTK_WIDGET (imhtml)); - img = g_new0 (struct im_image, 1); - if (*tmp == '/' || *tmp == '\\') { - img->filename = g_strdup(src); - img->len = atoi(datasize); - img->data = g_malloc(img->len); - memcpy(img->data, imagedata, img->len); - load = gdk_pixbuf_loader_new(); - if (!gdk_pixbuf_loader_write(load, imagedata, - g_print("IM Image corrupt or unreadable.\n"); - imagepb = gdk_pixbuf_loader_get_pixbuf(load); - bit = g_new0 (GtkIMHtmlBit, 1); - bit->url = g_strdup (url); + gchar *text2 = g_strdup(text); + for (i = 0, j = 0; text2[i]; i++) { - if (!imhtml->img || ((xpm = imhtml->img (src)) == NULL)) { - if (!fonts || ((clr = ((FontDetail *) fonts->data)->back) == NULL)) - clr = (bg != NULL) ? bg : imhtml->default_bg_color; - if (!GTK_WIDGET_REALIZED (imhtml)) - gtk_widget_realize (GTK_WIDGET (imhtml)); - bit = g_new0 (GtkIMHtmlBit, 1); - bit->pm = gdk_pixmap_create_from_xpm_d (GTK_WIDGET (imhtml)->window, - bit->url = g_strdup (url); - case 48: /* H3 (opt) */ - NEW_BIT (NEW_TEXT_BIT); - wpos = g_snprintf (ws, len, "%s", tag); - NEW_BIT (NEW_COMMENT_BIT); - } else if (*c == '&' && gtk_imhtml_is_amp_escape (c, &, &tlen)) { - } else if (*c == '\n') { - if (!(options & GTK_IMHTML_NO_NEWLINE)) { - NEW_BIT (NEW_TEXT_BIT); - } else if (gtk_imhtml_is_smiley (imhtml, c, &smilelen)) { - NEW_BIT (NEW_TEXT_BIT); - wpos = g_snprintf (ws, smilelen + 1, "%s", c); - NEW_BIT (NEW_SMILEY_BIT); - NEW_BIT (NEW_TEXT_BIT); - GtkIMHtmlBit *bit = newbits->data; - imhtml->bits = g_list_append (imhtml->bits, bit); - newbits = g_list_remove (newbits, bit); - gtk_imhtml_draw_bit (imhtml, bit); - GTK_LAYOUT (imhtml)->height = imhtml->y; - GTK_LAYOUT (imhtml)->vadjustment->upper = imhtml->y; - gtk_signal_emit_by_name (GTK_OBJECT (GTK_LAYOUT (imhtml)->vadjustment), "changed"); - gtk_widget_set_usize (GTK_WIDGET (imhtml), -1, imhtml->y); - if (!(options & GTK_IMHTML_NO_SCROLL) && - (GTK_WIDGET (imhtml)->allocation.height - - (GTK_WIDGET (imhtml)->style->ythickness + BORDER_SIZE) * 2)))) - gtk_adjustment_set_value (vadj, imhtml->y - - MAX (1, (GTK_WIDGET (imhtml)->allocation.height - - (GTK_WIDGET (imhtml)->style->ythickness + - retval = g_string_append (retval, "</A>"); - FontDetail *font = fonts->data; - fonts = g_slist_remove (fonts, font); - gdk_color_free (font->fore); - gdk_color_free (font->back); - retval = g_string_append (retval, "</FONT>"); - retval = g_string_append (retval, "</B>"); - retval = g_string_append (retval, "</I>"); - retval = g_string_append (retval, "</U>"); - retval = g_string_append (retval, "</S>"); + } else if (text2[i] == '>' && !visible) { - retval = g_string_append (retval, "</SUB>"); - retval = g_string_append (retval, "</SUP>"); - retval = g_string_append (retval, "</TITLE>"); - retval = g_string_append (retval, "</PRE>"); -gtk_imhtml_clear (GtkIMHtml *imhtml) +GString* gtk_imhtml_append_text (GtkIMHtml *imhtml, + GtkIMHtmlOptions options) - g_return_if_fail (imhtml != NULL); - g_return_if_fail (GTK_IS_IMHTML (imhtml)); - layout = GTK_LAYOUT (imhtml); - GtkIMHtmlBit *bit = imhtml->bits->data; - imhtml->bits = g_list_remove (imhtml->bits, bit); - gdk_font_unref (bit->font); - gdk_color_free (bit->fore); - gdk_color_free (bit->back); - gdk_color_free (bit->bg); - gdk_pixmap_unref (bit->pm); - gdk_bitmap_unref (bit->bm); - g_free(bit->img->filename); - g_free(bit->img->data); - gdk_pixbuf_unref(bit->img->pb); - struct line_info *li = bit->chunks->data; - bit->chunks = g_list_remove (bit->chunks, li); - while (imhtml->click) { - g_free (imhtml->click->data); - imhtml->click = g_list_remove (imhtml->click, imhtml->click->data); + char *o = text + (strlen(text) - 4); - while (imhtml->im_images) { - imhtml->im_images = g_list_remove(imhtml->im_images, imhtml->im_images->data); + if (!strcmp(text, "<BR>")) + stripped = g_strdup("\n"); + stripped = imhtml_strip_html(text); - if (imhtml->selected_text) { - g_string_free (imhtml->selected_text, TRUE); - imhtml->selected_text = g_string_new (""); - imhtml->sel_startx = 0; - imhtml->sel_starty = 0; - imhtml->sel_endchunk = NULL; + str = g_string_new(stripped); - if (imhtml->tip_timer) { - gtk_timeout_remove (imhtml->tip_timer); - if (imhtml->tip_window) { - gtk_widget_destroy (imhtml->tip_window); - imhtml->tip_window = NULL; - imhtml->tip_bit = NULL; - if (imhtml->scroll_timer) { - gtk_timeout_remove (imhtml->scroll_timer); - imhtml->scroll_timer = 0; - g_list_free(imhtml->im_images); - imhtml->im_images = NULL; - imhtml->y = TOP_BORDER; - g_list_free (imhtml->line); - layout->hadjustment->page_size = 0; - layout->hadjustment->page_increment = 0; - layout->hadjustment->lower = 0; - layout->hadjustment->upper = imhtml->x; - gtk_adjustment_set_value (layout->hadjustment, 0); - layout->vadjustment->page_size = 0; - layout->vadjustment->page_increment = 0; - layout->vadjustment->lower = 0; - layout->vadjustment->upper = imhtml->y; - gtk_adjustment_set_value (layout->vadjustment, 0); - if (GTK_WIDGET_REALIZED (GTK_WIDGET (imhtml))) { - gdk_window_set_cursor (GTK_LAYOUT (imhtml)->bin_window, imhtml->arrow_cursor); - gdk_window_clear (GTK_LAYOUT (imhtml)->bin_window); - gtk_signal_emit_by_name (GTK_OBJECT (layout->hadjustment), "changed"); - gtk_signal_emit_by_name (GTK_OBJECT (layout->vadjustment), "changed"); + gtk_text_buffer_get_end_iter(imhtml->text_buffer, &iter); + gtk_text_buffer_insert(imhtml->text_buffer, &iter, stripped, -1); -gtk_imhtml_page_up (GtkIMHtml *imhtml) - g_return_if_fail (imhtml != NULL); - g_return_if_fail (GTK_IS_IMHTML (imhtml)); +void gtk_imhtml_set_adjustments (GtkIMHtml *imhtml, - vadj = GTK_LAYOUT (imhtml)->vadjustment; - gtk_adjustment_set_value (vadj, MAX (vadj->value - vadj->page_increment, - gtk_signal_emit_by_name (GTK_OBJECT (vadj), "changed"); +void gtk_imhtml_set_defaults (GtkIMHtml *imhtml, + PangoFontDescription *font, -gtk_imhtml_page_down (GtkIMHtml *imhtml) +void gtk_imhtml_set_img_handler (GtkIMHtml *imhtml, + GtkIMHtmlImage handler){} - g_return_if_fail (imhtml != NULL); - g_return_if_fail (GTK_IS_IMHTML (imhtml)); +void gtk_imhtml_associate_smiley (GtkIMHtml *imhtml, +void gtk_imhtml_init_smileys (GtkIMHtml *imhtml){} +void gtk_imhtml_remove_smileys (GtkIMHtml *imhtml){} +void gtk_imhtml_reset_smileys (GtkIMHtml *imhtml){} +void gtk_imhtml_show_smileys (GtkIMHtml *imhtml, - vadj = GTK_LAYOUT (imhtml)->vadjustment; - gtk_adjustment_set_value (vadj, MIN (vadj->value + vadj->page_increment, - vadj->upper - vadj->page_size)); - gtk_signal_emit_by_name (GTK_OBJECT (vadj), "changed"); +void gtk_imhtml_show_comments (GtkIMHtml *imhtml, +void gtk_imhtml_clear (GtkIMHtml *imhtml){} +void gtk_imhtml_page_up (GtkIMHtml *imhtml){} +void gtk_imhtml_page_down (GtkIMHtml *imhtml){} =================================================================== RCS file: /cvsroot/gaim/gaim/src/gtkimhtml.h,v
diff -u -r1.17 gtkimhtml.h --- src/gtkimhtml.h 29 Aug 2002 01:47:14 -0000 1.17 +++ src/gtkimhtml.h 10 Oct 2002 19:40:58 -0000 -#include <gtk/gtklayout.h> +#include <gtk/gtktextview.h> typedef struct _GtkIMHtmlClass GtkIMHtmlClass;
- // PangoFontDescription *default_font; - GdkColor *default_fg_color; - GdkColor *default_bg_color; - GdkColor *default_hl_color; - GdkColor *default_hlfg_color; - GdkCursor *hand_cursor; - GdkCursor *arrow_cursor; - struct _GtkIMHtmlBit *tip_bit; - guint sel_startx, sel_starty; - guint sel_endx, sel_endy; - GString *selected_text; - struct line_info *sel_endchunk; + GtkTextBuffer *text_buffer; - GtkSmileyTree *smiley_data; - GtkLayoutClass parent_class; + GtkTextViewClass parent_class; void (*url_clicked) (GtkIMHtml *, const gchar *);
GtkType gtk_imhtml_get_type (void);
-GtkWidget* gtk_imhtml_new (GtkAdjustment *hadj, +GtkWidget* gtk_imhtml_new (void *, void *); void gtk_imhtml_set_adjustments (GtkIMHtml *imhtml,
void gtk_imhtml_set_defaults (GtkIMHtml *imhtml,
- //PangoFontDescription *font, + PangoFontDescription *font,