Mercurial > pidgin
annotate src/gtkhtml.c @ 1106:5bc8fdacd2cb
[gaim-migrate @ 1116]
lots of changes.
buddy.c: just in general tried to get things to work better. moving things in the edit list window and signing off should be handled better in the main buddy list window (watch out for flashes).
gaim.h: removed toc-specific things and moved them to toc.c and rvous.c as needed.
gtkhtml.c: possible fix for AOL 6.0 problems (I wasn't able to reproduce the problem before or after the fix, but i fixed what i think might have been causing the problem).
multi.c: moved LOGIN_STEPS from gaim.h here and actually use it now
oscar.c: moved an oscar-specific struct definition from gaim.h here and also handle problems better
perl.c: fix for stupid problem
rvous.c: first pass at attempt to be able to remove toc.c and rvous.c (though this will never happen; gaim will support toc as long as aol does) without cruft. gaim is now only dependent on toc.c and rvous.c for toc_build_config and parse_toc_buddy_list, which gaim needs to save and read its buddy list.
toc.c: rewrote the signin process so that the read()'s won't block. it's not actually a non-blocking read; it's just that it won't ever get to the read until there's data to be read (thanks to the gdk_input watcher). this means the cancel button should work after it's connected, but it's still not a non-blocking connect.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Mon, 20 Nov 2000 07:24:18 +0000 |
parents | a4635c7c2128 |
children | f3e0f41beddb |
rev | line source |
---|---|
12 | 1 |
1 | 2 /* |
3 * gaim | |
4 * | |
5 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 * | |
21 */ | |
22 | |
349
b402a23f35df
[gaim-migrate @ 359]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
337
diff
changeset
|
23 #ifdef HAVE_CONFIG_H |
b402a23f35df
[gaim-migrate @ 359]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
337
diff
changeset
|
24 #include "../config.h" |
b402a23f35df
[gaim-migrate @ 359]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
337
diff
changeset
|
25 #endif |
1 | 26 #include <stdio.h> |
27 #include <stdlib.h> | |
28 #include <string.h> | |
29 #include <gtk/gtk.h> | |
30 #include <gdk/gdkprivate.h> | |
31 #include <gdk/gdkx.h> | |
32 #include <gdk/gdkkeysyms.h> | |
604
0b1a132e0f75
[gaim-migrate @ 614]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
574
diff
changeset
|
33 #include <ctype.h> |
12 | 34 |
35 #ifndef _WIN32 | |
1 | 36 #include <X11/Xlib.h> |
37 #include <X11/Xatom.h> | |
12 | 38 #endif |
39 | |
69 | 40 #include "gaim.h" |
1 | 41 #include "gtkhtml.h" |
42 | |
549 | 43 #include "pixmaps/aol_icon.xpm" |
44 #include "pixmaps/admin_icon.xpm" | |
45 #include "pixmaps/free_icon.xpm" | |
46 #include "pixmaps/dt_icon.xpm" | |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
47 #define MAX_SIZE 7 |
1 | 48 #define MIN_HTML_WIDTH_LINES 20 |
49 #define MIN_HTML_HEIGHT_LINES 10 | |
50 #define BORDER_WIDTH 2 | |
51 #define SCROLL_TIME 100 | |
52 #define SCROLL_PIXELS 5 | |
53 #define KEY_SCROLL_PIXELS 10 | |
54 | |
55 int font_sizes[] = { 80, 100, 120, 140, 200, 300, 400 }; | |
56 | |
12 | 57 /* |
1 | 58 GdkFont *fixed_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; |
59 GdkFont *fixed_bold_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | |
60 GdkFont *fixed_italic_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | |
12 | 61 GdkFont *fixed_bold_italic_font[] = |
62 { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | |
1 | 63 GdkFont *prop_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; |
64 GdkFont *prop_bold_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | |
65 GdkFont *prop_italic_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | |
66 GdkFont *prop_bold_italic_font[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | |
12 | 67 */ |
68 | |
69 GData * font_cache; | |
70 static gboolean cache_init = FALSE; | |
71 | |
72 struct font_state | |
73 { | |
74 int size; | |
75 int owncolor; | |
76 int ownbg; | |
77 gchar font[1024]; | |
78 GdkColor *color; | |
79 GdkColor *bgcol; | |
80 struct font_state *next; | |
1 | 81 }; |
82 | |
83 struct font_state *push_state(struct font_state *current) | |
84 { | |
12 | 85 struct font_state *tmp; |
86 tmp = (struct font_state *) g_new0(struct font_state, 1); | |
1 | 87 tmp->next = current; |
88 tmp->color = current->color; | |
89 tmp->bgcol = current->bgcol; | |
90 tmp->size = current->size; | |
91 tmp->owncolor = 0; | |
92 tmp->ownbg = 0; | |
12 | 93 strcpy( tmp->font, current->font ); |
1 | 94 return tmp; |
95 } | |
96 | |
12 | 97 enum |
98 { | |
99 ARG_0, | |
100 ARG_HADJUSTMENT, | |
101 ARG_VADJUSTMENT, | |
1 | 102 }; |
103 | |
104 | |
12 | 105 enum |
106 { | |
107 TARGET_STRING, | |
108 TARGET_TEXT, | |
109 TARGET_COMPOUND_TEXT | |
1 | 110 }; |
111 | |
112 | |
12 | 113 static void gtk_html_class_init(GtkHtmlClass * klass); |
114 static void gtk_html_set_arg(GtkObject * object, GtkArg * arg, guint arg_id); | |
115 static void gtk_html_get_arg(GtkObject * object, GtkArg * arg, guint arg_id); | |
116 static void gtk_html_init(GtkHtml * html); | |
117 static void gtk_html_destroy(GtkObject * object); | |
118 static void gtk_html_finalize(GtkObject * object); | |
119 static void gtk_html_realize(GtkWidget * widget); | |
120 static void gtk_html_unrealize(GtkWidget * widget); | |
121 static void gtk_html_style_set(GtkWidget * widget, GtkStyle * previous_style); | |
122 static void gtk_html_draw_focus(GtkWidget * widget); | |
123 static void gtk_html_size_request(GtkWidget * widget, | |
124 GtkRequisition * requisition); | |
125 static void gtk_html_size_allocate(GtkWidget * widget, | |
126 GtkAllocation * allocation); | |
127 static void gtk_html_adjustment(GtkAdjustment * adjustment, GtkHtml * html); | |
128 static void gtk_html_disconnect(GtkAdjustment * adjustment, GtkHtml * html); | |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
129 static void gtk_html_add_seperator(GtkHtml *, GdkFont *, GdkColor *, GdkColor *); |
12 | 130 static void gtk_html_add_text(GtkHtml * html, |
131 GdkFont * font, | |
132 GdkColor * fore, | |
133 GdkColor * back, | |
134 gchar * chars, | |
135 gint length, | |
136 gint uline, gint strike, gchar * url); | |
137 static void gtk_html_draw_bit(GtkHtml * html, | |
138 GtkHtmlBit * htmlbit, gint redraw); | |
139 static void gtk_html_selection_get(GtkWidget * widget, | |
140 GtkSelectionData * selection_data, | |
141 guint sel_info, guint32 time); | |
142 static gint gtk_html_selection_clear(GtkWidget * widget, | |
143 GdkEventSelection * event); | |
144 static gint gtk_html_visibility_notify(GtkWidget * widget, | |
145 GdkEventVisibility * event); | |
1 | 146 |
147 | |
148 /* Event handlers */ | |
12 | 149 static void gtk_html_draw(GtkWidget * widget, GdkRectangle * area); |
150 static gint gtk_html_expose(GtkWidget * widget, GdkEventExpose * event); | |
151 static gint gtk_html_button_press(GtkWidget * widget, GdkEventButton * event); | |
152 static gint gtk_html_button_release(GtkWidget * widget, GdkEventButton * event); | |
153 static gint gtk_html_motion_notify(GtkWidget * widget, GdkEventMotion * event); | |
154 static gint gtk_html_key_press(GtkWidget * widget, GdkEventKey * event); | |
155 static gint gtk_html_leave_notify(GtkWidget * widget, GdkEventCrossing * event); | |
1 | 156 |
157 static gint gtk_html_tooltip_timeout(gpointer data); | |
158 | |
159 | |
12 | 160 static void clear_area(GtkHtml * html, GdkRectangle * area); |
161 static void expose_html(GtkHtml * html, GdkRectangle * area, gboolean cursor); | |
162 static void scroll_down(GtkHtml * html, gint diff0); | |
163 static void scroll_up(GtkHtml * html, gint diff0); | |
164 | |
165 static void adjust_adj(GtkHtml * html, GtkAdjustment * adj); | |
166 static void resize_html(GtkHtml * html); | |
167 static gint html_bit_is_onscreen(GtkHtml * html, GtkHtmlBit * hb); | |
168 static void draw_cursor(GtkHtml * html); | |
169 static void undraw_cursor(GtkHtml * html); | |
1 | 170 |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
171 static int get_line_height(GtkHtml *, GtkHtmlBit *); |
895 | 172 |
1 | 173 static GtkWidgetClass *parent_class = NULL; |
174 | |
175 GtkType gtk_html_get_type(void) | |
176 { | |
12 | 177 static GtkType html_type = 0; |
178 | |
179 if (!html_type) | |
180 { | |
181 static const GtkTypeInfo html_info = { | |
182 "GtkHtml", | |
183 sizeof(GtkHtml), | |
184 sizeof(GtkHtmlClass), | |
185 (GtkClassInitFunc) gtk_html_class_init, | |
186 (GtkObjectInitFunc) gtk_html_init, | |
187 NULL, | |
188 NULL, | |
189 NULL, | |
190 }; | |
191 html_type = gtk_type_unique(GTK_TYPE_WIDGET, &html_info); | |
192 } | |
193 return html_type; | |
1 | 194 } |
195 | |
196 | |
12 | 197 static void gtk_html_class_init(GtkHtmlClass * class) |
1 | 198 { |
12 | 199 GtkObjectClass *object_class; |
200 GtkWidgetClass *widget_class; | |
201 | |
202 object_class = (GtkObjectClass *) class; | |
203 widget_class = (GtkWidgetClass *) class; | |
204 parent_class = gtk_type_class(GTK_TYPE_WIDGET); | |
205 | |
206 | |
207 gtk_object_add_arg_type("GtkHtml::hadjustment", | |
208 GTK_TYPE_ADJUSTMENT, | |
209 GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT, | |
210 ARG_HADJUSTMENT); | |
211 | |
212 gtk_object_add_arg_type("GtkHtml::vadjustment", | |
213 GTK_TYPE_ADJUSTMENT, | |
214 GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT, | |
215 ARG_VADJUSTMENT); | |
216 | |
217 object_class->set_arg = gtk_html_set_arg; | |
218 object_class->get_arg = gtk_html_get_arg; | |
219 object_class->destroy = gtk_html_destroy; | |
220 object_class->finalize = gtk_html_finalize; | |
221 | |
222 widget_class->realize = gtk_html_realize; | |
223 widget_class->unrealize = gtk_html_unrealize; | |
224 widget_class->style_set = gtk_html_style_set; | |
225 widget_class->draw_focus = gtk_html_draw_focus; | |
226 widget_class->size_request = gtk_html_size_request; | |
227 widget_class->size_allocate = gtk_html_size_allocate; | |
228 widget_class->draw = gtk_html_draw; | |
229 widget_class->expose_event = gtk_html_expose; | |
230 widget_class->button_press_event = gtk_html_button_press; | |
231 widget_class->button_release_event = gtk_html_button_release; | |
1 | 232 widget_class->motion_notify_event = gtk_html_motion_notify; |
233 widget_class->leave_notify_event = gtk_html_leave_notify; | |
12 | 234 widget_class->selection_get = gtk_html_selection_get; |
1 | 235 widget_class->selection_clear_event = gtk_html_selection_clear; |
236 widget_class->key_press_event = gtk_html_key_press; | |
237 widget_class->visibility_notify_event = gtk_html_visibility_notify; | |
12 | 238 |
239 | |
240 widget_class->set_scroll_adjustments_signal = | |
241 gtk_signal_new("set_scroll_adjustments", | |
242 GTK_RUN_LAST, | |
243 object_class->type, | |
244 GTK_SIGNAL_OFFSET(GtkHtmlClass, set_scroll_adjustments), | |
245 gtk_marshal_NONE__POINTER_POINTER, | |
246 GTK_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, | |
247 GTK_TYPE_ADJUSTMENT); | |
248 | |
249 | |
250 class->set_scroll_adjustments = gtk_html_set_adjustments; | |
1 | 251 |
252 } | |
253 | |
12 | 254 static void gtk_html_set_arg(GtkObject * object, GtkArg * arg, guint arg_id) |
1 | 255 { |
12 | 256 GtkHtml *html; |
257 | |
258 html = GTK_HTML(object); | |
259 | |
260 switch (arg_id) | |
261 { | |
262 case ARG_HADJUSTMENT: | |
263 gtk_html_set_adjustments(html, GTK_VALUE_POINTER(*arg), html->vadj); | |
264 break; | |
265 case ARG_VADJUSTMENT: | |
266 gtk_html_set_adjustments(html, html->hadj, GTK_VALUE_POINTER(*arg)); | |
267 break; | |
268 default: | |
269 break; | |
270 } | |
1 | 271 } |
272 | |
12 | 273 static void gtk_html_get_arg(GtkObject * object, GtkArg * arg, guint arg_id) |
1 | 274 { |
12 | 275 GtkHtml *html; |
276 | |
277 html = GTK_HTML(object); | |
278 | |
279 switch (arg_id) | |
280 { | |
281 case ARG_HADJUSTMENT: | |
282 GTK_VALUE_POINTER(*arg) = html->hadj; | |
283 break; | |
284 case ARG_VADJUSTMENT: | |
285 GTK_VALUE_POINTER(*arg) = html->vadj; | |
286 break; | |
287 default: | |
288 arg->type = GTK_TYPE_INVALID; | |
289 break; | |
290 } | |
1 | 291 } |
292 | |
12 | 293 static void gtk_html_init(GtkHtml * html) |
1 | 294 { |
12 | 295 static const GtkTargetEntry targets[] = { |
296 {"STRING", 0, TARGET_STRING}, | |
297 {"TEXT", 0, TARGET_TEXT}, | |
298 {"COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT} | |
299 }; | |
300 | |
301 static const gint n_targets = sizeof(targets) / sizeof(targets[0]); | |
302 | |
303 GTK_WIDGET_SET_FLAGS(html, GTK_CAN_FOCUS); | |
304 | |
305 html->html_area = NULL; | |
306 html->hadj = NULL; | |
307 html->vadj = NULL; | |
1 | 308 html->current_x = 0; |
309 html->current_y = 0; | |
12 | 310 html->start_sel = html->end_sel = NULL; |
311 html->start_sel_x = html->start_sel_y = -1; | |
312 html->num_end = html->num_start = -1; | |
313 | |
1 | 314 html->html_bits = NULL; |
315 html->urls = NULL; | |
316 html->selected_text = NULL; | |
317 html->tooltip_hb = NULL; | |
318 html->tooltip_timer = -1; | |
319 html->tooltip_window = NULL; | |
12 | 320 html->cursor_hb = NULL; |
1 | 321 html->cursor_pos = 0; |
322 | |
323 html->pm = NULL; | |
324 | |
325 html->editable = 0; | |
326 html->transparent = 0; | |
327 | |
12 | 328 html->frozen = 0; |
329 | |
330 gtk_selection_add_targets(GTK_WIDGET(html), GDK_SELECTION_PRIMARY, | |
331 targets, n_targets); | |
332 | |
333 | |
334 | |
1 | 335 } |
336 | |
337 | |
12 | 338 GtkWidget *gtk_html_new(GtkAdjustment * hadj, GtkAdjustment * vadj) |
1 | 339 { |
12 | 340 GtkWidget *html; |
341 if(!cache_init) | |
342 { | |
343 g_datalist_init(&font_cache); | |
344 cache_init = TRUE; | |
345 } | |
346 | |
347 if (hadj) | |
348 g_return_val_if_fail(GTK_IS_ADJUSTMENT(hadj), NULL); | |
349 if (vadj) | |
350 g_return_val_if_fail(GTK_IS_ADJUSTMENT(vadj), NULL); | |
351 | |
352 html = gtk_widget_new(GTK_TYPE_HTML, | |
353 "hadjustment", hadj, "vadjustment", vadj, NULL); | |
354 | |
355 return html; | |
1 | 356 } |
357 | |
358 | |
12 | 359 void gtk_html_set_editable(GtkHtml * html, gboolean is_editable) |
1 | 360 { |
12 | 361 g_return_if_fail(html != NULL); |
362 g_return_if_fail(GTK_IS_HTML(html)); | |
363 | |
364 | |
365 html->editable = (is_editable != FALSE); | |
366 | |
367 if (is_editable) | |
368 draw_cursor(html); | |
369 else | |
370 undraw_cursor(html); | |
1 | 371 |
372 } | |
373 | |
12 | 374 void gtk_html_set_transparent(GtkHtml * html, gboolean is_transparent) |
1 | 375 { |
12 | 376 GdkRectangle rect; |
377 gint width, | |
378 height; | |
379 GtkWidget *widget; | |
380 | |
381 g_return_if_fail(html != NULL); | |
382 g_return_if_fail(GTK_IS_HTML(html)); | |
383 | |
384 | |
385 widget = GTK_WIDGET(html); | |
386 html->transparent = (is_transparent != FALSE); | |
387 | |
388 if (!GTK_WIDGET_REALIZED(widget)) | |
389 return; | |
390 | |
391 html->bg_gc = NULL; | |
392 gdk_window_get_size(widget->window, &width, &height); | |
393 rect.x = 0; | |
394 rect.y = 0; | |
395 rect.width = width; | |
396 rect.height = height; | |
397 gdk_window_clear_area(widget->window, rect.x, rect.y, rect.width, | |
398 rect.height); | |
399 | |
400 expose_html(html, &rect, FALSE); | |
401 gtk_html_draw_focus((GtkWidget *) html); | |
1 | 402 } |
403 | |
404 | |
12 | 405 void gtk_html_set_adjustments(GtkHtml * html, |
406 GtkAdjustment * hadj, GtkAdjustment * vadj) | |
1 | 407 { |
12 | 408 g_return_if_fail(html != NULL); |
409 g_return_if_fail(GTK_IS_HTML(html)); | |
410 if (hadj) | |
411 g_return_if_fail(GTK_IS_ADJUSTMENT(hadj)); | |
412 else | |
413 hadj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); | |
414 if (vadj) | |
415 g_return_if_fail(GTK_IS_ADJUSTMENT(vadj)); | |
416 else | |
417 vadj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); | |
418 | |
419 if (html->hadj && (html->hadj != hadj)) | |
420 { | |
421 gtk_signal_disconnect_by_data(GTK_OBJECT(html->hadj), html); | |
422 gtk_object_unref(GTK_OBJECT(html->hadj)); | |
423 } | |
424 | |
425 if (html->vadj && (html->vadj != vadj)) | |
426 { | |
427 gtk_signal_disconnect_by_data(GTK_OBJECT(html->vadj), html); | |
428 gtk_object_unref(GTK_OBJECT(html->vadj)); | |
429 } | |
430 | |
431 if (html->hadj != hadj) | |
432 { | |
433 html->hadj = hadj; | |
434 gtk_object_ref(GTK_OBJECT(html->hadj)); | |
435 gtk_object_sink(GTK_OBJECT(html->hadj)); | |
436 | |
437 gtk_signal_connect(GTK_OBJECT(html->hadj), "changed", | |
438 (GtkSignalFunc) gtk_html_adjustment, html); | |
439 gtk_signal_connect(GTK_OBJECT(html->hadj), "value_changed", | |
440 (GtkSignalFunc) gtk_html_adjustment, html); | |
441 gtk_signal_connect(GTK_OBJECT(html->hadj), "disconnect", | |
442 (GtkSignalFunc) gtk_html_disconnect, html); | |
443 gtk_html_adjustment(hadj, html); | |
444 } | |
445 | |
446 if (html->vadj != vadj) | |
447 { | |
448 html->vadj = vadj; | |
449 gtk_object_ref(GTK_OBJECT(html->vadj)); | |
450 gtk_object_sink(GTK_OBJECT(html->vadj)); | |
451 | |
452 gtk_signal_connect(GTK_OBJECT(html->vadj), "changed", | |
453 (GtkSignalFunc) gtk_html_adjustment, html); | |
454 gtk_signal_connect(GTK_OBJECT(html->vadj), "value_changed", | |
455 (GtkSignalFunc) gtk_html_adjustment, html); | |
456 gtk_signal_connect(GTK_OBJECT(html->vadj), "disconnect", | |
457 (GtkSignalFunc) gtk_html_disconnect, html); | |
458 gtk_html_adjustment(vadj, html); | |
459 } | |
1 | 460 } |
461 | |
462 | |
463 | |
12 | 464 GdkColor *get_color(int colorv, GdkColormap * map) |
1 | 465 { |
466 GdkColor *color; | |
12 | 467 #if 0 |
468 fprintf(stdout, "color is %x\n", colorv); | |
469 #endif | |
470 color = (GdkColor *) g_new0(GdkColor, 1); | |
1 | 471 color->red = ((colorv & 0xff0000) >> 16) * 256; |
472 color->green = ((colorv & 0xff00) >> 8) * 256; | |
473 color->blue = ((colorv & 0xff)) * 256; | |
474 #if 0 | |
12 | 475 fprintf(stdout, "Colors are %d, %d, %d\n", color->red, color->green, |
476 color->blue); | |
1 | 477 #endif |
478 gdk_color_alloc(map, color); | |
479 return color; | |
480 } | |
481 | |
482 | |
286 | 483 int load_font_with_cache(const char *name, const char *weight, char slant, |
484 int size, GdkFont **font_return) | |
1 | 485 { |
286 | 486 gchar font_spec[1024]; |
487 | |
306
a8f964718837
[gaim-migrate @ 316]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
305
diff
changeset
|
488 if (size > 0) |
a8f964718837
[gaim-migrate @ 316]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
305
diff
changeset
|
489 g_snprintf(font_spec, sizeof font_spec, |
a8f964718837
[gaim-migrate @ 316]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
305
diff
changeset
|
490 "-*-%s-%s-%c-*-*-*-%d-*-*-*-*-*-*", |
a8f964718837
[gaim-migrate @ 316]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
305
diff
changeset
|
491 name, weight, slant, size); |
852
836d5a02a35c
[gaim-migrate @ 862]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
851
diff
changeset
|
492 else |
791
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
493 g_snprintf(font_spec, sizeof font_spec, |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
494 "-*-%s-%s-%c-*-*-*-*-*-*-*-*-*-*", |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
495 name, weight, slant); |
286 | 496 |
497 if((*font_return = g_datalist_id_get_data(&font_cache, | |
498 g_quark_from_string(font_spec)))) { | |
499 return TRUE; | |
500 } else if ((*font_return = gdk_font_load(font_spec))) { | |
501 g_datalist_id_set_data(&font_cache, | |
502 g_quark_from_string(font_spec), *font_return); | |
503 return TRUE; | |
504 } else { | |
505 return FALSE; | |
12 | 506 } |
286 | 507 } |
508 | |
509 | |
510 GdkFont *getfont(const char *font, int bold, int italic, int fixed, int size) | |
511 { | |
512 GdkFont *my_font = NULL; | |
513 gchar *weight, slant; | |
514 | |
515 if (!font || !strlen(font)) font = fixed ? "courier" : "helvetica"; | |
516 weight = bold ? "bold" : "medium"; | |
517 slant = italic ? 'i' : 'r'; | |
518 | |
519 if (size > MAX_SIZE) size = MAX_SIZE; | |
520 if (size < 1) size = 1; | |
521 size = font_sizes[size-1]; | |
522 | |
852
836d5a02a35c
[gaim-migrate @ 862]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
851
diff
changeset
|
523 /* try both 'i'talic and 'o'blique for italic fonts */ |
286 | 524 |
791
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
525 if (load_font_with_cache(font, weight, slant, size, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
526 return my_font; |
852
836d5a02a35c
[gaim-migrate @ 862]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
851
diff
changeset
|
527 if (load_font_with_cache(font, weight, 'o', size, &my_font)) |
836d5a02a35c
[gaim-migrate @ 862]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
851
diff
changeset
|
528 return my_font; |
836d5a02a35c
[gaim-migrate @ 862]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
851
diff
changeset
|
529 if (italic && load_font_with_cache(font, weight, slant, 0, &my_font)) |
836d5a02a35c
[gaim-migrate @ 862]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
851
diff
changeset
|
530 return my_font; |
791
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
531 if (italic && load_font_with_cache(font, weight, 'o', 0, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
532 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
533 |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
534 /* since we couldn't get the right font, fall back to the default fonts. */ |
286 | 535 |
536 font = fixed ? "courier" : "helvetica"; | |
791
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
537 if (load_font_with_cache(font, weight, slant, size, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
538 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
539 if (load_font_with_cache(font, weight, slant, 0, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
540 return my_font; |
305
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
541 |
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
542 font = fixed ? "helvetica" : "courier"; |
791
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
543 if (load_font_with_cache(font, weight, slant, size, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
544 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
545 if (load_font_with_cache(font, weight, slant, 0, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
546 return my_font; |
305
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
547 |
721
8e7ad10b5f26
[gaim-migrate @ 731]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
720
diff
changeset
|
548 /* whoops, couldn't do any of those. maybe they have a default outgoing |
8e7ad10b5f26
[gaim-migrate @ 731]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
720
diff
changeset
|
549 * font? maybe we can use that. */ |
8e7ad10b5f26
[gaim-migrate @ 731]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
720
diff
changeset
|
550 if (fontface[0]) { |
8e7ad10b5f26
[gaim-migrate @ 731]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
720
diff
changeset
|
551 /* woohoo! */ |
791
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
552 if (load_font_with_cache(fontface, "medium", 'r', size, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
553 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
554 if (load_font_with_cache(fontface, "medium", 'r', 0, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
555 return my_font; |
721
8e7ad10b5f26
[gaim-migrate @ 731]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
720
diff
changeset
|
556 } |
8e7ad10b5f26
[gaim-migrate @ 731]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
720
diff
changeset
|
557 |
305
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
558 /* ok, now we're in a pickle. if we can't do any of the above, let's |
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
559 * try doing the most boring font we can find. */ |
791
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
560 if (load_font_with_cache("helvetica", "medium", 'r', size, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
561 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
562 if (load_font_with_cache("helvetica", "medium", 'r', 0, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
563 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
564 |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
565 if (load_font_with_cache("courier", "medium", 'r', size, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
566 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
567 if (load_font_with_cache("courier", "medium", 'r', 0, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
568 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
569 |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
570 if (load_font_with_cache("times", "medium", 'r', size, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
571 return my_font; |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
572 if (load_font_with_cache("times", "medium", 'r', 0, &my_font)) |
678bdc430df7
[gaim-migrate @ 801]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
740
diff
changeset
|
573 return my_font; |
305
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
574 |
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
575 /* my god, how did we end up here. is there a 'generic font' function |
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
576 * in gdk? that would be incredibly useful here. there's gotta be a |
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
577 * better way to do this. */ |
77404a4692b1
[gaim-migrate @ 315]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
286
diff
changeset
|
578 |
306
a8f964718837
[gaim-migrate @ 316]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
305
diff
changeset
|
579 /* well, if they can't do any of the fonts above, they'll take whatever |
a8f964718837
[gaim-migrate @ 316]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
305
diff
changeset
|
580 * they can get, and be happy about it, damn it. :) */ |
852
836d5a02a35c
[gaim-migrate @ 862]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
851
diff
changeset
|
581 load_font_with_cache("*", "*", '*', 0, &my_font); |
306
a8f964718837
[gaim-migrate @ 316]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
305
diff
changeset
|
582 return my_font; |
1 | 583 } |
584 | |
585 | |
586 /* 'Borrowed' from ETerm */ | |
12 | 587 GdkWindow *get_desktop_window(GtkWidget * widget) |
1 | 588 { |
12 | 589 #ifndef _WIN32 |
590 GdkAtom prop, | |
591 type, | |
592 prop2; | |
593 int format; | |
594 gint length; | |
595 guchar *data; | |
1 | 596 GtkWidget *w; |
597 | |
12 | 598 prop = gdk_atom_intern("_XROOTPMAP_ID", 1); |
599 prop2 = gdk_atom_intern("_XROOTCOLOR_PIXEL", 1); | |
600 | |
601 if (prop == None && prop2 == None) | |
602 { | |
603 return NULL; | |
604 } | |
605 | |
606 | |
607 | |
608 for (w = widget; w; w = w->parent) | |
609 { | |
610 | |
611 if (prop != None) | |
612 { | |
1 | 613 gdk_property_get(w->window, prop, AnyPropertyType, 0L, 1L, 0, |
12 | 614 &type, &format, &length, &data); |
615 } | |
616 else if (prop2 != None) | |
617 { | |
1 | 618 gdk_property_get(w->window, prop2, AnyPropertyType, 0L, 1L, 0, |
12 | 619 &type, &format, &length, &data); |
620 } | |
621 else | |
622 { | |
1 | 623 continue; |
624 } | |
12 | 625 if (type != None) |
626 { | |
1 | 627 return (w->window); |
628 } | |
629 } | |
12 | 630 #endif |
1 | 631 return NULL; |
632 | |
633 } | |
634 | |
635 | |
636 | |
12 | 637 GdkPixmap *get_desktop_pixmap(GtkWidget * widget) |
1 | 638 { |
12 | 639 #ifndef _WIN32 |
640 GdkPixmap *p; | |
641 GdkAtom prop, | |
642 type, | |
643 prop2; | |
644 int format; | |
645 gint length; | |
646 guint32 id; | |
647 guchar *data; | |
648 | |
649 prop = gdk_atom_intern("_XROOTPMAP_ID", 1); | |
650 prop2 = gdk_atom_intern("_XROOTCOLOR_PIXEL", 1); | |
651 | |
652 | |
653 if (prop == None && prop2 == None) | |
654 { | |
655 return NULL; | |
656 } | |
657 | |
658 if (prop != None) | |
659 { | |
660 gdk_property_get(get_desktop_window(widget), prop, AnyPropertyType, 0L, | |
661 1L, 0, &type, &format, &length, &data); | |
662 if (type == XA_PIXMAP) | |
663 { | |
1 | 664 id = data[0]; |
665 id += data[1] << 8; | |
666 id += data[2] << 16; | |
667 id += data[3] << 24; | |
12 | 668 p = gdk_pixmap_foreign_new(id); |
669 return p; | |
670 } | |
671 } | |
672 if (prop2 != None) | |
673 { | |
674 | |
1 | 675 /* XGetWindowProperty(Xdisplay, desktop_window, prop2, 0L, 1L, False, AnyPropertyType, |
676 &type, &format, &length, &after, &data);*/ | |
12 | 677 |
1 | 678 /* if (type == XA_CARDINAL) {*/ |
12 | 679 /* |
680 * D_PIXMAP((" Solid color not yet supported.\n")); | |
681 */ | |
682 | |
1 | 683 /* return NULL; |
684 }*/ | |
12 | 685 } |
686 /* | |
687 * D_PIXMAP(("No suitable attribute found.\n")); | |
688 */ | |
689 #endif | |
690 return NULL; | |
1 | 691 } |
692 | |
693 | |
12 | 694 static void clear_focus_area(GtkHtml * html, |
695 gint area_x, | |
696 gint area_y, gint area_width, gint area_height) | |
1 | 697 { |
12 | 698 GtkWidget *widget = GTK_WIDGET(html); |
699 gint x, | |
700 y; | |
701 | |
702 gint ythick = BORDER_WIDTH + widget->style->klass->ythickness; | |
703 gint xthick = BORDER_WIDTH + widget->style->klass->xthickness; | |
704 | |
705 gint width, | |
706 height; | |
707 | |
708 if (html->frozen > 0) | |
709 return; | |
710 | |
711 if (html->transparent) | |
712 { | |
1 | 713 if (html->pm == NULL) |
714 html->pm = get_desktop_pixmap(widget); | |
715 | |
12 | 716 if (html->pm == NULL) |
717 return; | |
718 | |
719 if (html->bg_gc == NULL) | |
720 { | |
1 | 721 GdkGCValues values; |
722 | |
12 | 723 values.tile = html->pm; |
724 values.fill = GDK_TILED; | |
725 | |
726 html->bg_gc = gdk_gc_new_with_values(html->html_area, &values, | |
727 GDK_GC_FILL | GDK_GC_TILE); | |
728 | |
729 } | |
730 | |
731 gdk_window_get_deskrelative_origin(widget->window, &x, &y); | |
1 | 732 |
733 gdk_draw_pixmap(widget->window, html->bg_gc, html->pm, | |
12 | 734 x + area_x, y + area_y, area_x, area_y, area_width, |
735 area_height); | |
736 | |
737 | |
738 } | |
739 else | |
740 { | |
741 gdk_window_get_size(widget->style->bg_pixmap[GTK_STATE_NORMAL], &width, | |
742 &height); | |
743 | |
744 gdk_gc_set_ts_origin(html->bg_gc, | |
745 (-html->xoffset + xthick) % width, | |
746 (-html->yoffset + ythick) % height); | |
747 | |
748 gdk_draw_rectangle(widget->window, html->bg_gc, TRUE, | |
749 area_x, area_y, area_width, area_height); | |
750 } | |
1 | 751 } |
752 | |
12 | 753 static void gtk_html_draw_focus(GtkWidget * widget) |
1 | 754 { |
12 | 755 GtkHtml *html; |
756 gint width, | |
757 height; | |
758 gint x, | |
759 y; | |
760 | |
761 g_return_if_fail(widget != NULL); | |
762 g_return_if_fail(GTK_IS_HTML(widget)); | |
1 | 763 |
764 html = GTK_HTML(widget); | |
765 | |
12 | 766 if (GTK_WIDGET_DRAWABLE(widget)) |
767 { | |
768 gint ythick = widget->style->klass->ythickness; | |
769 gint xthick = widget->style->klass->xthickness; | |
770 gint xextra = BORDER_WIDTH; | |
771 gint yextra = BORDER_WIDTH; | |
772 | |
773 x = 0; | |
774 y = 0; | |
775 width = widget->allocation.width; | |
776 height = widget->allocation.height; | |
777 | |
778 if (GTK_WIDGET_HAS_FOCUS(widget)) | |
779 { | |
780 x += 1; | |
781 y += 1; | |
782 width -= 2; | |
783 height -= 2; | |
784 xextra -= 1; | |
785 yextra -= 1; | |
786 | |
787 gtk_paint_focus(widget->style, widget->window, | |
788 NULL, widget, "text", | |
789 0, 0, | |
790 widget->allocation.width - 1, | |
791 widget->allocation.height - 1); | |
792 } | |
793 | |
794 gtk_paint_shadow(widget->style, widget->window, | |
795 GTK_STATE_NORMAL, GTK_SHADOW_IN, | |
796 NULL, widget, "text", x, y, width, height); | |
797 | |
798 x += xthick; | |
799 y += ythick; | |
800 width -= 2 * xthick; | |
801 height -= 2 * ythick; | |
802 | |
803 | |
804 if (widget->style->bg_pixmap[GTK_STATE_NORMAL] || html->transparent) | |
805 { | |
806 /* | |
807 * top rect | |
808 */ | |
809 clear_focus_area(html, x, y, width, yextra); | |
810 /* | |
811 * left rect | |
812 */ | |
813 clear_focus_area(html, x, y + yextra, | |
814 xextra, y + height - 2 * yextra); | |
815 /* | |
816 * right rect | |
817 */ | |
818 clear_focus_area(html, x + width - xextra, y + yextra, | |
819 xextra, height - 2 * ythick); | |
820 /* | |
821 * bottom rect | |
822 */ | |
823 clear_focus_area(html, x, x + height - yextra, width, yextra); | |
824 } | |
825 } | |
1 | 826 } |
827 | |
12 | 828 static void gtk_html_size_request(GtkWidget * widget, |
829 GtkRequisition * requisition) | |
1 | 830 { |
12 | 831 gint xthickness; |
832 gint ythickness; | |
833 gint char_height; | |
834 gint char_width; | |
835 | |
836 g_return_if_fail(widget != NULL); | |
837 g_return_if_fail(GTK_IS_HTML(widget)); | |
838 g_return_if_fail(requisition != NULL); | |
839 | |
840 xthickness = widget->style->klass->xthickness + BORDER_WIDTH; | |
841 ythickness = widget->style->klass->ythickness + BORDER_WIDTH; | |
842 | |
843 char_height = MIN_HTML_HEIGHT_LINES * (widget->style->font->ascent + | |
844 widget->style->font->descent); | |
845 | |
846 char_width = MIN_HTML_WIDTH_LINES * (gdk_text_width(widget->style->font, | |
847 "ABCDEFGHIJKLMNOPQRSTUVWXYZ", | |
848 26) / 26); | |
849 | |
850 requisition->width = char_width + xthickness * 2; | |
851 requisition->height = char_height + ythickness * 2; | |
1 | 852 } |
853 | |
12 | 854 static void gtk_html_size_allocate(GtkWidget * widget, |
855 GtkAllocation * allocation) | |
1 | 856 { |
12 | 857 GtkHtml *html; |
858 | |
859 g_return_if_fail(widget != NULL); | |
860 g_return_if_fail(GTK_IS_HTML(widget)); | |
861 g_return_if_fail(allocation != NULL); | |
862 | |
863 html = GTK_HTML(widget); | |
864 | |
865 widget->allocation = *allocation; | |
866 if (GTK_WIDGET_REALIZED(widget)) | |
867 { | |
868 gdk_window_move_resize(widget->window, | |
869 allocation->x, allocation->y, | |
870 allocation->width, allocation->height); | |
871 | |
872 gdk_window_move_resize(html->html_area, | |
873 widget->style->klass->xthickness + BORDER_WIDTH, | |
874 widget->style->klass->ythickness + BORDER_WIDTH, | |
875 MAX(1, (gint) widget->allocation.width - | |
876 (gint) (widget->style->klass->xthickness + | |
877 (gint) BORDER_WIDTH) * 2), | |
878 MAX(1, (gint) widget->allocation.height - | |
879 (gint) (widget->style->klass->ythickness + | |
880 (gint) BORDER_WIDTH) * 2)); | |
881 | |
882 resize_html(html); | |
883 } | |
884 } | |
885 | |
886 static void gtk_html_draw(GtkWidget * widget, GdkRectangle * area) | |
887 { | |
888 g_return_if_fail(widget != NULL); | |
889 g_return_if_fail(GTK_IS_HTML(widget)); | |
890 g_return_if_fail(area != NULL); | |
891 | |
892 if (GTK_WIDGET_DRAWABLE(widget)) | |
893 { | |
894 expose_html(GTK_HTML(widget), area, TRUE); | |
895 gtk_widget_draw_focus(widget); | |
896 } | |
897 } | |
898 | |
899 | |
900 static gint gtk_html_expose(GtkWidget * widget, GdkEventExpose * event) | |
901 { | |
902 GtkHtml *html; | |
903 | |
904 g_return_val_if_fail(widget != NULL, FALSE); | |
905 g_return_val_if_fail(GTK_IS_HTML(widget), FALSE); | |
906 g_return_val_if_fail(event != NULL, FALSE); | |
907 | |
908 html = GTK_HTML(widget); | |
909 | |
910 if (event->window == html->html_area) | |
911 { | |
912 expose_html(html, &event->area, TRUE); | |
913 } | |
914 else if (event->count == 0) | |
915 { | |
916 gtk_widget_draw_focus(widget); | |
917 } | |
918 | |
919 return FALSE; | |
1 | 920 |
921 } | |
922 | |
923 | |
12 | 924 static gint gtk_html_selection_clear(GtkWidget * widget, |
925 GdkEventSelection * event) | |
1 | 926 { |
12 | 927 GtkHtml *html; |
928 | |
929 g_return_val_if_fail(widget != NULL, FALSE); | |
930 g_return_val_if_fail(GTK_IS_HTML(widget), FALSE); | |
931 g_return_val_if_fail(event != NULL, FALSE); | |
932 | |
933 /* | |
934 * Let the selection handling code know that the selection | |
935 * * has been changed, since we've overriden the default handler | |
936 */ | |
937 if (!gtk_selection_clear(widget, event)) | |
938 return FALSE; | |
939 | |
940 html = GTK_HTML(widget); | |
941 | |
942 if (event->selection == GDK_SELECTION_PRIMARY) | |
943 { | |
944 if (html->selected_text) | |
945 { | |
946 GList *hbits = html->html_bits; | |
947 GtkHtmlBit *hb; | |
948 | |
1 | 949 g_free(html->selected_text); |
950 html->selected_text = NULL; | |
951 html->start_sel = NULL; | |
952 html->end_sel = NULL; | |
953 html->num_start = 0; | |
954 html->num_end = 0; | |
12 | 955 while (hbits) |
956 { | |
957 hb = (GtkHtmlBit *) hbits->data; | |
1 | 958 if (hb->was_selected) |
959 gtk_html_draw_bit(html, hb, 1); | |
960 hbits = hbits->prev; | |
961 } | |
962 hbits = g_list_last(html->html_bits); | |
963 } | |
12 | 964 } |
965 | |
966 return TRUE; | |
1 | 967 } |
968 | |
969 | |
970 | |
12 | 971 static void gtk_html_selection_get(GtkWidget * widget, |
972 GtkSelectionData * selection_data, | |
973 guint sel_info, guint32 time) | |
1 | 974 { |
975 gchar *str; | |
12 | 976 gint len; |
977 GtkHtml *html; | |
978 | |
979 g_return_if_fail(widget != NULL); | |
980 g_return_if_fail(GTK_IS_HTML(widget)); | |
981 | |
982 html = GTK_HTML(widget); | |
983 | |
984 | |
1 | 985 if (selection_data->selection != GDK_SELECTION_PRIMARY) |
986 return; | |
987 | |
988 str = html->selected_text; | |
989 | |
990 if (!str) | |
991 return; | |
12 | 992 |
1 | 993 len = strlen(str); |
994 | |
12 | 995 if (sel_info == TARGET_STRING) |
996 { | |
1 | 997 gtk_selection_data_set(selection_data, |
12 | 998 GDK_SELECTION_TYPE_STRING, |
999 8 * sizeof(gchar), (guchar *) str, len); | |
1000 } | |
1001 else if ((sel_info == TARGET_TEXT) || (sel_info == TARGET_COMPOUND_TEXT)) | |
1002 { | |
1 | 1003 guchar *text; |
1004 GdkAtom encoding; | |
1005 gint format; | |
1006 gint new_length; | |
1007 | |
12 | 1008 gdk_string_to_compound_text(str, &encoding, &format, &text, |
1009 &new_length); | |
1010 gtk_selection_data_set(selection_data, encoding, format, text, | |
1011 new_length); | |
1012 gdk_free_compound_text(text); | |
1 | 1013 } |
1014 | |
1015 | |
1016 | |
1017 } | |
1018 | |
12 | 1019 static void do_select(GtkHtml * html, int x, int y) |
1 | 1020 { |
1021 GList *hbits = g_list_last(html->html_bits); | |
12 | 1022 int epos, |
1023 spos; | |
1 | 1024 GtkHtmlBit *hb; |
12 | 1025 |
1 | 1026 if (!hbits) |
1027 return; | |
12 | 1028 |
1029 hb = (GtkHtmlBit *) hbits->data; | |
1030 | |
1031 while (hbits) | |
1032 { | |
1033 hb = (GtkHtmlBit *) hbits->data; | |
1034 if (hb->type == HTML_BIT_TEXT) | |
1 | 1035 break; |
1036 hbits = hbits->prev; | |
12 | 1037 } |
1038 | |
1 | 1039 if (!hb) |
12 | 1040 return; |
1041 | |
1042 | |
1043 if (y > hb->y) | |
1044 { | |
1 | 1045 html->num_end = strlen(hb->text) - 1; |
1046 html->end_sel = hb; | |
12 | 1047 } |
1048 else if (y < 0) | |
1049 { | |
1 | 1050 html->num_end = 0; |
12 | 1051 html->end_sel = (GtkHtmlBit *) html->html_bits->data; |
1052 } | |
1053 else | |
1054 while (hbits) | |
1055 { | |
1056 hb = (GtkHtmlBit *) hbits->data; | |
1057 if ((y < hb->y && y > (hb->y - hb->height)) && | |
1058 (x > hb->x + hb->width)) | |
1059 { | |
1060 if (hb->type != HTML_BIT_TEXT) | |
1061 { | |
1062 html->num_end = 0; | |
1063 html->end_sel = hb; | |
1064 break; | |
1065 } | |
1066 | |
1067 html->num_end = strlen(hb->text) - 1; | |
1 | 1068 html->end_sel = hb; |
1069 break; | |
1070 } | |
12 | 1071 else if ((x > hb->x && x < (hb->x + hb->width)) && |
1072 (y < hb->y && y > (hb->y - hb->height))) | |
1073 { | |
1074 int i, | |
1075 len; | |
1076 int w = x - hb->x; | |
1077 | |
1078 if (hb->type != HTML_BIT_TEXT) | |
1079 { | |
1080 html->num_end = 0; | |
1 | 1081 html->end_sel = hb; |
1082 break; | |
1083 } | |
12 | 1084 |
1085 len = strlen(hb->text); | |
1086 | |
1087 for (i = 1; i <= len; i++) | |
1088 { | |
1089 if (gdk_text_measure(hb->font, hb->text, i) > w) | |
1090 { | |
1091 html->num_end = i - 1; | |
1092 html->end_sel = hb; | |
1093 break; | |
1094 } | |
1095 } | |
1096 break; | |
1 | 1097 } |
12 | 1098 hbits = hbits->prev; |
1 | 1099 } |
1100 | |
1101 if (html->end_sel == NULL) | |
1102 return; | |
12 | 1103 if (html->start_sel == NULL) |
1104 { | |
1 | 1105 html->start_sel = html->end_sel; |
1106 html->num_start = html->num_end; | |
1107 } | |
12 | 1108 |
1 | 1109 epos = g_list_index(html->html_bits, html->end_sel); |
1110 spos = g_list_index(html->html_bits, html->start_sel); | |
1111 g_free(html->selected_text); | |
1112 html->selected_text = NULL; | |
1113 | |
12 | 1114 if (epos == spos) |
1115 { | |
1 | 1116 char *str; |
12 | 1117 if (html->start_sel->type != HTML_BIT_TEXT) |
1118 { | |
1 | 1119 html->selected_text = NULL; |
1120 return; | |
1121 } | |
12 | 1122 if (html->num_end == html->num_start) |
1123 { | |
1 | 1124 str = g_malloc(2); |
12 | 1125 if (strlen(html->start_sel->text)) |
1 | 1126 str[0] = html->start_sel->text[html->num_end]; |
1127 else | |
12 | 1128 str[0] = 0; |
1 | 1129 str[1] = 0; |
1130 gtk_html_draw_bit(html, html->start_sel, 0); | |
1131 html->selected_text = str; | |
12 | 1132 } |
1133 else | |
1134 { | |
79 | 1135 size_t st, |
12 | 1136 en; |
1 | 1137 char *str; |
12 | 1138 if (html->num_end > html->num_start) |
1139 { | |
1 | 1140 en = html->num_end; |
1141 st = html->num_start; | |
12 | 1142 } |
1143 else | |
1144 { | |
1 | 1145 en = html->num_start; |
1146 st = html->num_end; | |
1147 } | |
1148 | |
1149 str = g_malloc(en - st + 2); | |
1150 strncpy(str, html->start_sel->text + st, (en - st + 1)); | |
1151 str[en - st + 1] = 0; | |
12 | 1152 gtk_html_draw_bit(html, html->start_sel, 0); |
1 | 1153 html->selected_text = str; |
12 | 1154 |
1 | 1155 } |
12 | 1156 } |
1157 else | |
1158 { | |
1159 GtkHtmlBit *shb, | |
1160 *ehb; | |
79 | 1161 size_t en, |
12 | 1162 st; |
1163 int len, | |
1164 nlen; | |
1 | 1165 char *str; |
12 | 1166 if (epos > spos) |
1167 { | |
1 | 1168 shb = html->start_sel; |
1169 ehb = html->end_sel; | |
1170 en = html->num_end; | |
1171 st = html->num_start; | |
12 | 1172 } |
1173 else | |
1174 { | |
1 | 1175 shb = html->end_sel; |
1176 ehb = html->start_sel; | |
1177 en = html->num_start; | |
1178 st = html->num_end; | |
1179 } | |
12 | 1180 |
1 | 1181 hbits = g_list_find(html->html_bits, shb); |
1182 | |
1183 if (!hbits) | |
1184 return; | |
12 | 1185 |
1186 if (shb->type == HTML_BIT_TEXT) | |
1187 { | |
1 | 1188 len = strlen(shb->text) - st + 1; |
1189 str = g_malloc(len); | |
1190 strcpy(str, shb->text + st); | |
1191 str[len - 1] = 0; | |
1192 gtk_html_draw_bit(html, shb, 0); | |
12 | 1193 if (shb->newline) |
1194 { | |
1195 len += 1; | |
1 | 1196 str = g_realloc(str, len); |
1197 str[len - 2] = '\n'; | |
1198 str[len - 1] = 0; | |
1199 } | |
12 | 1200 } |
1201 else | |
1202 { | |
1 | 1203 len = 1; |
1204 str = g_malloc(1); | |
1205 str[0] = 0; | |
1206 } | |
12 | 1207 if (hbits->next == NULL) |
1208 { | |
1 | 1209 html->selected_text = str; |
1210 return; | |
1211 } | |
1212 | |
12 | 1213 |
1214 hbits = hbits->next; | |
1215 while (1) | |
1216 { /* | |
1217 * Yah I know is dangerous :P | |
1218 */ | |
1219 hb = (GtkHtmlBit *) hbits->data; | |
1220 if (hb->type != HTML_BIT_TEXT) | |
1221 { | |
1 | 1222 if (hb == ehb) |
1223 break; | |
1224 hbits = hbits->next; | |
1225 continue; | |
1226 } | |
12 | 1227 if (hb != ehb) |
1228 { | |
1 | 1229 nlen = len + strlen(hb->text); |
1230 str = g_realloc(str, nlen); | |
1231 strcpy(str + (len - 1), hb->text); | |
1232 len = nlen; | |
1233 str[len - 1] = 0; | |
1234 gtk_html_draw_bit(html, hb, 0); | |
12 | 1235 if (hb->newline) |
1236 { | |
1237 len += 1; | |
1 | 1238 str = g_realloc(str, len); |
1239 str[len - 2] = '\n'; | |
1240 str[len - 1] = 0; | |
1241 } | |
12 | 1242 } |
1243 else | |
1244 { | |
1 | 1245 nlen = len + en + 1; |
1246 str = g_realloc(str, nlen); | |
1247 strncpy(str + (len - 1), hb->text, en + 1); | |
1248 len = nlen; | |
1249 str[len - 1] = 0; | |
12 | 1250 |
1 | 1251 gtk_html_draw_bit(html, hb, 0); |
12 | 1252 if (hb->newline && en == strlen(hb->text)) |
1253 { | |
1254 len += 1; | |
1 | 1255 str = g_realloc(str, len); |
1256 str[len - 2] = '\n'; | |
1257 str[len - 1] = 0; | |
1258 } | |
1259 break; | |
1260 } | |
1261 hbits = hbits->next; | |
1262 } | |
1263 html->selected_text = str; | |
1264 } | |
1265 | |
1266 } | |
1267 | |
12 | 1268 static gint scroll_timeout(GtkHtml * html) |
1 | 1269 { |
12 | 1270 GdkEventMotion event; |
1271 gint x, | |
1272 y; | |
1273 GdkModifierType mask; | |
1 | 1274 |
1275 html->timer = 0; | |
12 | 1276 gdk_window_get_pointer(html->html_area, &x, &y, &mask); |
1277 | |
1 | 1278 if (mask & GDK_BUTTON1_MASK) |
1279 { | |
1280 event.is_hint = 0; | |
1281 event.x = x; | |
1282 event.y = y; | |
1283 event.state = mask; | |
1284 | |
12 | 1285 gtk_html_motion_notify(GTK_WIDGET(html), &event); |
1 | 1286 } |
1287 | |
1288 return FALSE; | |
1289 | |
1290 } | |
1291 | |
1292 | |
12 | 1293 static gint gtk_html_tooltip_paint_window(GtkHtml * html) |
1 | 1294 { |
1295 GtkStyle *style; | |
12 | 1296 gint y, |
1297 baseline_skip, | |
1298 gap; | |
1 | 1299 |
1300 style = html->tooltip_window->style; | |
1301 | |
1302 gap = (style->font->ascent + style->font->descent) / 4; | |
1303 if (gap < 2) | |
1304 gap = 2; | |
1305 baseline_skip = style->font->ascent + style->font->descent + gap; | |
1306 | |
1307 if (!html->tooltip_hb) | |
1308 return FALSE; | |
1309 | |
1310 gtk_paint_flat_box(style, html->tooltip_window->window, | |
12 | 1311 GTK_STATE_NORMAL, GTK_SHADOW_OUT, |
1312 NULL, GTK_WIDGET(html->tooltip_window), "tooltip", | |
1313 0, 0, -1, -1); | |
1 | 1314 |
1315 y = style->font->ascent + 4; | |
1316 | |
12 | 1317 gtk_paint_string(style, html->tooltip_window->window, |
1318 GTK_STATE_NORMAL, | |
1319 NULL, GTK_WIDGET(html->tooltip_window), "tooltip", | |
1320 4, y, "HTML Link:"); | |
1 | 1321 y += baseline_skip; |
12 | 1322 gtk_paint_string(style, html->tooltip_window->window, |
1323 GTK_STATE_NORMAL, | |
1324 NULL, GTK_WIDGET(html->tooltip_window), "tooltip", | |
1325 4, y, html->tooltip_hb->url); | |
1326 | |
1 | 1327 return FALSE; |
1328 | |
1329 | |
1330 } | |
1331 | |
1332 static gint gtk_html_tooltip_timeout(gpointer data) | |
1333 { | |
12 | 1334 GtkHtml *html = (GtkHtml *) data; |
1335 | |
1336 | |
1 | 1337 GDK_THREADS_ENTER(); |
1338 | |
12 | 1339 if (html->tooltip_hb && GTK_WIDGET_DRAWABLE(GTK_WIDGET(html))) |
1340 { | |
1 | 1341 GtkWidget *widget; |
1342 GtkStyle *style; | |
12 | 1343 gint gap, |
1344 x, | |
1345 y, | |
1346 w, | |
1347 h, | |
1348 scr_w, | |
1349 scr_h, | |
1350 baseline_skip; | |
1 | 1351 |
1352 if (html->tooltip_window) | |
1353 gtk_widget_destroy(html->tooltip_window); | |
12 | 1354 |
1355 html->tooltip_window = gtk_window_new(GTK_WINDOW_POPUP); | |
1356 gtk_widget_set_app_paintable(html->tooltip_window, TRUE); | |
1357 gtk_window_set_policy(GTK_WINDOW(html->tooltip_window), FALSE, FALSE, | |
1358 TRUE); | |
1359 gtk_widget_set_name(html->tooltip_window, "gtk-tooltips"); | |
1360 gtk_signal_connect_object(GTK_OBJECT(html->tooltip_window), | |
1361 "expose_event", | |
1362 GTK_SIGNAL_FUNC | |
1363 (gtk_html_tooltip_paint_window), | |
1364 GTK_OBJECT(html)); | |
1365 gtk_signal_connect_object(GTK_OBJECT(html->tooltip_window), "draw", | |
1366 GTK_SIGNAL_FUNC | |
1367 (gtk_html_tooltip_paint_window), | |
1368 GTK_OBJECT(html)); | |
1369 | |
1370 gtk_widget_ensure_style(html->tooltip_window); | |
1 | 1371 style = html->tooltip_window->style; |
12 | 1372 |
1 | 1373 widget = GTK_WIDGET(html); |
1374 | |
12 | 1375 scr_w = gdk_screen_width(); |
1376 scr_h = gdk_screen_height(); | |
1 | 1377 |
1378 gap = (style->font->ascent + style->font->descent) / 4; | |
1379 if (gap < 2) | |
1380 gap = 2; | |
1381 baseline_skip = style->font->ascent + style->font->descent + gap; | |
1382 | |
353
a4df8f1cc61a
[gaim-migrate @ 363]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
349
diff
changeset
|
1383 w = 8 + MAX(gdk_string_width(style->font, _("HTML Link:")), |
12 | 1384 gdk_string_width(style->font, html->tooltip_hb->url)); |
1385 ; | |
1 | 1386 h = 8 - gap; |
12 | 1387 h += (baseline_skip * 2); |
1388 | |
1389 gdk_window_get_pointer(NULL, &x, &y, NULL); | |
1390 /* | |
1391 * gdk_window_get_origin (widget->window, NULL, &y); | |
1392 */ | |
1393 if (GTK_WIDGET_NO_WINDOW(widget)) | |
1 | 1394 y += widget->allocation.y; |
1395 | |
1396 x -= ((w >> 1) + 4); | |
1397 | |
1398 if ((x + w) > scr_w) | |
1399 x -= (x + w) - scr_w; | |
1400 else if (x < 0) | |
1401 x = 0; | |
1402 | |
1403 if ((y + h + 4) > scr_h) | |
12 | 1404 y = |
1405 y - html->tooltip_hb->font->ascent + | |
1406 html->tooltip_hb->font->descent; | |
1 | 1407 else |
12 | 1408 y = |
1409 y + html->tooltip_hb->font->ascent + | |
1410 html->tooltip_hb->font->descent; | |
1411 | |
1412 gtk_widget_set_usize(html->tooltip_window, w, h); | |
1413 gtk_widget_popup(html->tooltip_window, x, y); | |
1414 | |
1 | 1415 } |
1416 | |
1417 html->tooltip_timer = -1; | |
12 | 1418 |
1 | 1419 GDK_THREADS_LEAVE(); |
1420 | |
1421 return FALSE; | |
1422 } | |
1423 | |
1424 | |
12 | 1425 static gint gtk_html_leave_notify(GtkWidget * widget, GdkEventCrossing * event) |
1 | 1426 { |
12 | 1427 GtkHtml *html; |
1428 | |
1429 html = GTK_HTML(widget); | |
1430 | |
1431 if (html->tooltip_timer != -1) | |
1432 gtk_timeout_remove(html->tooltip_timer); | |
1433 if (html->tooltip_window) | |
1434 { | |
1435 gtk_widget_destroy(html->tooltip_window); | |
1436 html->tooltip_window = NULL; | |
1437 } | |
1438 | |
1439 | |
1440 html->tooltip_hb = NULL; | |
1441 return TRUE; | |
1 | 1442 } |
1443 | |
1444 | |
12 | 1445 static gint gtk_html_motion_notify(GtkWidget * widget, GdkEventMotion * event) |
1 | 1446 { |
12 | 1447 int x, |
1448 y; | |
1449 gint width, | |
1450 height; | |
1451 GdkModifierType state; | |
1452 int realx, | |
1453 realy; | |
1454 GtkHtml *html = GTK_HTML(widget); | |
1455 | |
1456 if (event->is_hint) | |
1457 gdk_window_get_pointer(event->window, &x, &y, &state); | |
1458 else | |
1459 { | |
1460 x = event->x; | |
1461 y = event->y; | |
1462 state = event->state; | |
1463 } | |
1464 | |
1465 gdk_window_get_size(html->html_area, &width, &height); | |
1466 | |
1 | 1467 realx = x; |
1468 realy = y + html->yoffset; | |
1469 | |
1470 | |
12 | 1471 if (state & GDK_BUTTON1_MASK) |
1472 { | |
1473 if (realx != html->start_sel_x || realy != html->start_sel_y) | |
1474 { | |
1 | 1475 char *tmp = NULL; |
1476 | |
12 | 1477 if (y < 0 || y > height) |
1478 { | |
1 | 1479 int diff; |
12 | 1480 if (html->timer == 0) |
1481 { | |
1 | 1482 html->timer = gtk_timeout_add(100, |
12 | 1483 (GtkFunction) scroll_timeout, |
1484 html); | |
1 | 1485 if (y < 0) |
1486 diff = y / 2; | |
1487 else | |
1488 diff = (y - height) / 2; | |
1489 | |
1490 if (html->vadj->value + diff > | |
12 | 1491 html->vadj->upper - height + 20) |
1 | 1492 gtk_adjustment_set_value(html->vadj, |
12 | 1493 html->vadj->upper - height + |
1494 20); | |
1 | 1495 else |
1496 gtk_adjustment_set_value(html->vadj, | |
12 | 1497 html->vadj->value + diff); |
1 | 1498 |
1499 } | |
1500 } | |
12 | 1501 |
1 | 1502 if (html->selected_text != NULL) |
1503 tmp = g_strdup(html->selected_text); | |
1504 do_select(html, realx, realy); | |
12 | 1505 if (tmp) |
1506 { | |
1507 if (!html->selected_text || strcmp(tmp, html->selected_text)) | |
1508 { | |
1 | 1509 GtkHtmlBit *hb; |
1510 GList *hbits = html->html_bits; | |
12 | 1511 while (hbits) |
1512 { | |
1513 hb = (GtkHtmlBit *) hbits->data; | |
1 | 1514 if (hb->was_selected) |
1515 gtk_html_draw_bit(html, hb, 0); | |
1516 hbits = hbits->next; | |
1517 } | |
1518 } | |
1519 g_free(tmp); | |
1520 } | |
1521 } | |
12 | 1522 } |
1523 else | |
1524 { | |
1 | 1525 GtkHtmlBit *hb; |
1526 GList *urls; | |
1527 | |
1528 urls = html->urls; | |
12 | 1529 while (urls) |
1530 { | |
1531 hb = (GtkHtmlBit *) urls->data; | |
1 | 1532 if ((realx > hb->x && realx < (hb->x + hb->width)) && |
12 | 1533 (realy < hb->y && realy > (hb->y - hb->height))) |
1534 { | |
26 | 1535 GdkCursor *cursor = NULL; |
1536 | |
12 | 1537 if (html->tooltip_hb != hb) |
1538 { | |
1 | 1539 html->tooltip_hb = hb; |
1540 if (html->tooltip_timer != -1) | |
1541 gtk_timeout_remove(html->tooltip_timer); | |
12 | 1542 if (html->tooltip_window) |
1543 { | |
1 | 1544 gtk_widget_destroy(html->tooltip_window); |
1545 html->tooltip_window = NULL; | |
1546 } | |
12 | 1547 html->tooltip_timer = |
1548 gtk_timeout_add(HTML_TOOLTIP_DELAY, | |
1549 gtk_html_tooltip_timeout, html); | |
1 | 1550 } |
26 | 1551 |
1552 cursor = gdk_cursor_new(GDK_HAND2); | |
1553 gdk_window_set_cursor(html->html_area, cursor); | |
1554 gdk_cursor_destroy(cursor); | |
1555 | |
1 | 1556 return TRUE; |
1557 } | |
12 | 1558 urls = urls->next; |
1 | 1559 } |
1560 if (html->tooltip_timer != -1) | |
1561 gtk_timeout_remove(html->tooltip_timer); | |
12 | 1562 if (html->tooltip_window) |
1563 { | |
1 | 1564 gtk_widget_destroy(html->tooltip_window); |
1565 html->tooltip_window = NULL; | |
1566 } | |
12 | 1567 |
1568 | |
1569 html->tooltip_hb = NULL; | |
1 | 1570 gdk_window_set_cursor(html->html_area, NULL); |
1571 | |
1572 | |
1573 } | |
1574 | |
1575 return TRUE; | |
1576 } | |
1577 | |
12 | 1578 static gint gtk_html_button_release(GtkWidget * widget, GdkEventButton * event) |
1 | 1579 { |
12 | 1580 GtkHtml *html; |
1581 | |
1582 html = GTK_HTML(widget); | |
1583 | |
1584 if (html->frozen > 0) | |
1585 return TRUE; | |
1586 | |
1587 if (event->button == 1) | |
1588 { | |
1589 int realx, | |
1590 realy; | |
1591 GtkHtmlBit *hb; | |
1592 GList *urls = html->urls; | |
1593 | |
1594 realx = event->x; | |
1595 realy = event->y + html->yoffset; | |
1596 if (realx != html->start_sel_x || realy != html->start_sel_y) | |
1597 { | |
1598 if (gtk_selection_owner_set(widget, | |
1599 GDK_SELECTION_PRIMARY, event->time)) | |
1600 { | |
1601 } | |
1602 else | |
1603 { | |
1604 } | |
1605 } | |
1606 else | |
1607 { | |
1608 if (gdk_selection_owner_get(GDK_SELECTION_PRIMARY) == | |
1609 widget->window) | |
1 | 1610 gtk_selection_owner_set(NULL, GDK_SELECTION_PRIMARY, |
12 | 1611 event->time); |
1612 | |
1613 | |
1614 while (urls) | |
1615 { | |
1616 void open_url_nw(GtkWidget * w, char *url); | |
1617 hb = (GtkHtmlBit *) urls->data; | |
1 | 1618 if ((realx > hb->x && realx < (hb->x + hb->width)) && |
12 | 1619 (realy < hb->y && realy > (hb->y - hb->height))) |
1620 { | |
1621 open_url_nw(NULL, hb->url); | |
1622 // else | |
1623 // open_url(NULL, hb->url); | |
1 | 1624 break; |
1625 } | |
1626 urls = urls->next; | |
1627 } | |
1628 } | |
1629 } | |
1630 return TRUE; | |
1631 } | |
1632 | |
1633 | |
1634 | |
12 | 1635 static gint gtk_html_button_press(GtkWidget * widget, GdkEventButton * event) |
1 | 1636 { |
12 | 1637 GtkHtml *html; |
1638 gfloat value; | |
1639 | |
1640 | |
1641 html = GTK_HTML(widget); | |
1642 value = html->vadj->value; | |
1643 | |
1644 if (html->frozen > 0) | |
1645 return TRUE; | |
1646 | |
1647 if (event->button == 4) | |
1648 { | |
1 | 1649 value -= html->vadj->step_increment; |
1650 if (value < html->vadj->lower) | |
1651 value = html->vadj->lower; | |
12 | 1652 gtk_adjustment_set_value(html->vadj, value); |
1653 } | |
1654 else if (event->button == 5) | |
1655 { | |
1 | 1656 value += html->vadj->step_increment; |
1657 if (value > html->vadj->upper) | |
1658 value = html->vadj->upper; | |
12 | 1659 gtk_adjustment_set_value(html->vadj, value); |
1660 | |
1661 } | |
1662 else if (event->button == 1) | |
1663 { | |
1664 GList *hbits = g_list_last(html->html_bits); | |
1665 int realx, | |
1666 realy; | |
1 | 1667 GtkHtmlBit *hb; |
1668 | |
1669 realx = event->x; | |
1670 realy = event->y + html->yoffset; | |
1671 | |
1672 html->start_sel_x = realx; | |
1673 html->start_sel_y = realy; | |
1674 | |
1675 if (!hbits) | |
1676 return TRUE; | |
1677 | |
12 | 1678 if (html->selected_text) |
1679 { | |
894
b5b3aa06111d
[gaim-migrate @ 904]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
871
diff
changeset
|
1680 gboolean forcedraw = FALSE; |
b5b3aa06111d
[gaim-migrate @ 904]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
871
diff
changeset
|
1681 hbits = html->html_bits; |
1 | 1682 g_free(html->selected_text); |
1683 html->selected_text = NULL; | |
1684 html->start_sel = NULL; | |
1685 html->end_sel = NULL; | |
1686 html->num_start = 0; | |
1687 html->num_end = 0; | |
12 | 1688 while (hbits) |
1689 { | |
1690 hb = (GtkHtmlBit *) hbits->data; | |
894
b5b3aa06111d
[gaim-migrate @ 904]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
871
diff
changeset
|
1691 if (hb->was_selected || forcedraw) { |
1 | 1692 gtk_html_draw_bit(html, hb, 1); |
894
b5b3aa06111d
[gaim-migrate @ 904]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
871
diff
changeset
|
1693 forcedraw = TRUE; |
b5b3aa06111d
[gaim-migrate @ 904]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
871
diff
changeset
|
1694 } |
b5b3aa06111d
[gaim-migrate @ 904]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
871
diff
changeset
|
1695 hbits = hbits->next; |
1 | 1696 } |
1697 hbits = g_list_last(html->html_bits); | |
1698 } | |
1699 | |
12 | 1700 hb = (GtkHtmlBit *) hbits->data; |
1701 if (realy > hb->y) | |
1702 { | |
1 | 1703 if (hb->text) |
1704 html->num_start = strlen(hb->text) - 1; | |
1705 else | |
12 | 1706 html->num_start = 0; |
1 | 1707 html->start_sel = hb; |
12 | 1708 } |
1709 else | |
1710 while (hbits) | |
1711 { | |
1712 hb = (GtkHtmlBit *) hbits->data; | |
1713 if ((realy < hb->y && realy > (hb->y - hb->height)) && | |
1714 (realx > hb->x + hb->width)) | |
1715 { | |
1716 if (hb->type != HTML_BIT_TEXT) | |
1717 { | |
1718 html->num_end = 0; | |
1719 html->end_sel = hb; | |
1720 break; | |
1721 } | |
1722 | |
1723 if (hb->text) | |
1724 html->num_start = strlen(hb->text) - 1; | |
1725 else | |
1726 html->num_start = 0; | |
1727 | |
1728 html->start_sel = hb; | |
1 | 1729 break; |
1730 } | |
12 | 1731 else if ((realx > hb->x && realx < (hb->x + hb->width)) && |
1732 (realy < hb->y && realy > (hb->y - hb->height))) | |
1733 { | |
1734 int i, | |
1735 len; | |
1736 int w = realx - hb->x; | |
1737 | |
1738 if (hb->type != HTML_BIT_TEXT) | |
1739 { | |
1740 html->num_end = 0; | |
1741 html->end_sel = hb; | |
1742 break; | |
1743 } | |
1744 | |
1745 if (hb->text) | |
1746 len = strlen(hb->text); | |
1747 else | |
1748 len = 0; | |
1749 | |
1750 for (i = 1; i <= len; i++) | |
1751 { | |
1752 if (gdk_text_measure(hb->font, hb->text, i) > w) | |
1753 { | |
1754 html->num_start = i - 1; | |
1755 html->start_sel = hb; | |
1756 break; | |
1757 } | |
1758 } | |
1 | 1759 break; |
1760 } | |
12 | 1761 hbits = hbits->prev; |
1 | 1762 } |
12 | 1763 } |
1764 else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) | |
1765 { | |
1 | 1766 GtkHtmlBit *hb = NULL; |
12 | 1767 int realx, |
1768 realy; | |
1769 GList *urls; | |
1770 | |
1 | 1771 realx = event->x; |
1772 realy = event->y + html->yoffset; | |
12 | 1773 |
1 | 1774 urls = html->urls; |
12 | 1775 while (urls) |
1776 { | |
1777 hb = (GtkHtmlBit *) urls->data; | |
1 | 1778 if ((realx > hb->x && realx < (hb->x + hb->width)) && |
12 | 1779 (realy < hb->y && realy > (hb->y - hb->height))) |
1780 { | |
1 | 1781 break; |
1782 } | |
12 | 1783 urls = urls->next; |
1 | 1784 hb = NULL; |
1785 } | |
12 | 1786 |
1787 if (hb != NULL) | |
1788 { | |
69 | 1789 |
1790 GtkWidget *menu, *button; | |
1791 | |
1792 menu = gtk_menu_new(); | |
1793 | |
1794 if (web_browser == BROWSER_NETSCAPE) { | |
1795 | |
353
a4df8f1cc61a
[gaim-migrate @ 363]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
349
diff
changeset
|
1796 button = gtk_menu_item_new_with_label(_("Open URL in existing window")); |
69 | 1797 gtk_signal_connect(GTK_OBJECT(button), "activate", |
1798 GTK_SIGNAL_FUNC(open_url), hb->url); | |
1799 gtk_menu_append(GTK_MENU(menu), button); | |
1800 gtk_widget_show(button); | |
1801 | |
1802 } | |
1803 | |
1804 | |
353
a4df8f1cc61a
[gaim-migrate @ 363]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
349
diff
changeset
|
1805 button = gtk_menu_item_new_with_label(_("Open URL in new window")); |
69 | 1806 gtk_signal_connect(GTK_OBJECT(button), "activate", |
1807 GTK_SIGNAL_FUNC(open_url_nw), hb->url); | |
1808 gtk_menu_append(GTK_MENU(menu), button); | |
1809 gtk_widget_show(button); | |
1810 | |
1811 if (web_browser == BROWSER_NETSCAPE) { | |
1812 | |
353
a4df8f1cc61a
[gaim-migrate @ 363]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
349
diff
changeset
|
1813 button = gtk_menu_item_new_with_label(_("Add URL as bookmark")); |
69 | 1814 gtk_signal_connect(GTK_OBJECT(button), "activate", |
1815 GTK_SIGNAL_FUNC(add_bookmark), hb->url); | |
1816 gtk_menu_append(GTK_MENU(menu), button); | |
1817 gtk_widget_show(button); | |
1818 | |
1819 } | |
1820 | |
1821 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, | |
1822 event->button, event->time); | |
1823 | |
12 | 1824 } |
1 | 1825 } |
12 | 1826 |
1 | 1827 return TRUE; |
1828 } | |
1829 | |
871
75b05911234a
[gaim-migrate @ 881]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
869
diff
changeset
|
1830 |
12 | 1831 static void gtk_html_draw_bit(GtkHtml * html, GtkHtmlBit * hb, int redraw) |
1 | 1832 { |
12 | 1833 int mypos, |
1834 epos, | |
871
75b05911234a
[gaim-migrate @ 881]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
869
diff
changeset
|
1835 spos; |
12 | 1836 GdkGC *gc = html->gc; |
1 | 1837 int shift; |
12 | 1838 GtkStateType selected_state; |
1839 GtkWidget *widget = GTK_WIDGET(html); | |
1 | 1840 GdkRectangle area; |
895 | 1841 GList *hbits; |
1842 | |
1 | 1843 if (html->frozen > 0) |
1844 return; | |
1845 | |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
1846 hbits = g_list_find(html->html_bits, hb); |
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
1847 |
12 | 1848 if (hb->type == HTML_BIT_TEXT) |
1849 { | |
1 | 1850 |
716 | 1851 if (!(hb->text)) |
1 | 1852 return; |
720
8b3412f3ac2a
[gaim-migrate @ 730]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
716
diff
changeset
|
1853 /* this is possible, don't comment it out >:P */ |
8b3412f3ac2a
[gaim-migrate @ 730]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
716
diff
changeset
|
1854 if (!strlen(hb->text)) |
8b3412f3ac2a
[gaim-migrate @ 730]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
716
diff
changeset
|
1855 return; |
12 | 1856 |
1 | 1857 mypos = g_list_index(html->html_bits, hb); |
1858 epos = g_list_index(html->html_bits, html->end_sel); | |
1859 spos = g_list_index(html->html_bits, html->start_sel); | |
1860 | |
12 | 1861 if (((html->end_sel == NULL) || (html->start_sel == NULL)) || |
1862 ((epos < mypos) && (spos < mypos)) || | |
1863 ((epos > mypos) && (spos > mypos))) | |
1864 { | |
1865 selected_state = GTK_STATE_NORMAL; | |
1866 } | |
1867 else | |
1868 { | |
1 | 1869 selected_state = GTK_STATE_SELECTED; |
1870 } | |
1871 | |
1872 gdk_text_extents(hb->font, hb->text, 1, &shift, NULL, NULL, NULL, NULL); | |
1873 | |
12 | 1874 if (selected_state == GTK_STATE_SELECTED) |
1875 { | |
1876 int schar = 0, | |
1877 echar = 0; | |
1878 int startx = 0, | |
1879 xwidth = 0; | |
1880 | |
1881 if (epos > spos || | |
1882 (epos == spos && html->num_end >= html->num_start)) | |
1883 { | |
1884 if (mypos == epos) | |
1885 { | |
1 | 1886 echar = html->num_end; |
12 | 1887 xwidth = |
1888 gdk_text_width(hb->font, hb->text, html->num_end + 1); | |
1889 } | |
1890 else | |
1891 { | |
1 | 1892 echar = strlen(hb->text); |
1893 xwidth = hb->width; | |
1894 } | |
12 | 1895 if (mypos == spos) |
1896 { | |
1 | 1897 schar = html->num_start; |
12 | 1898 startx = |
1899 gdk_text_width(hb->font, hb->text, html->num_start); | |
1 | 1900 xwidth -= startx; |
1901 } | |
12 | 1902 } |
1903 else | |
1904 { | |
1905 if (mypos == spos) | |
1906 { | |
1 | 1907 echar = html->num_start; |
12 | 1908 xwidth = |
1909 gdk_text_width(hb->font, hb->text, | |
1910 html->num_start + 1); | |
1911 } | |
1912 else | |
1913 { | |
1 | 1914 echar = strlen(hb->text); |
1915 xwidth = hb->width; | |
1916 } | |
12 | 1917 if (mypos == epos) |
1918 { | |
1 | 1919 schar = html->num_end; |
12 | 1920 startx = |
1921 gdk_text_width(hb->font, hb->text, html->num_end); | |
1 | 1922 xwidth -= startx; |
1923 } | |
1924 } | |
1925 | |
1926 if (!redraw && echar == hb->sel_e && schar == hb->sel_s) | |
1927 return; | |
12 | 1928 |
1 | 1929 hb->sel_e = echar; |
1930 hb->sel_s = schar; | |
12 | 1931 |
1 | 1932 startx += hb->x; |
1933 | |
12 | 1934 area.x = hb->x - html->xoffset; |
1935 area.y = hb->y - hb->height + 3 - html->yoffset; | |
1936 area.width = hb->width + 2; | |
1937 area.height = hb->height; | |
1938 clear_area(html, &area); | |
1939 | |
1940 gtk_paint_flat_box(widget->style, html->html_area, | |
1941 selected_state, GTK_SHADOW_NONE, | |
1942 NULL, widget, "text", | |
1943 startx, | |
1944 hb->y - hb->height + 3 - html->yoffset, | |
1945 xwidth + 2, hb->height); | |
1946 hb->was_selected = 1; | |
1947 } | |
1948 else if (hb->was_selected) | |
1949 { | |
1950 area.x = hb->x - html->xoffset; | |
1951 area.y = hb->y - hb->height + 3 - html->yoffset; | |
1952 area.width = hb->width + 2; | |
1953 area.height = hb->height; | |
1954 clear_area(html, &area); | |
1955 | |
1956 hb->sel_e = -1; | |
1957 hb->sel_s = -1; | |
1958 | |
1 | 1959 hb->was_selected = 0; |
1960 } | |
12 | 1961 |
1962 if (selected_state == GTK_STATE_SELECTED && (mypos == epos | |
1963 || mypos == spos)) | |
1964 { | |
1 | 1965 char *s = hb->text; |
12 | 1966 int num = 0, |
1967 width = 0, | |
1968 fsel = 0, | |
1969 esel = strlen(hb->text); | |
1970 int lbearing, | |
1971 rbearing, | |
1972 w; | |
1973 | |
1974 if (epos > spos || | |
1975 (epos == spos && html->num_end >= html->num_start)) | |
1976 { | |
1 | 1977 if (mypos == epos) |
1978 esel = html->num_end; | |
1979 if (mypos == spos) | |
1980 fsel = html->num_start; | |
12 | 1981 } |
1982 else | |
1983 { | |
1 | 1984 if (mypos == spos) |
1985 esel = html->num_start; | |
12 | 1986 if (mypos == epos) |
1987 fsel = html->num_end; | |
1 | 1988 } |
1989 | |
12 | 1990 while (*s) |
1991 { | |
1 | 1992 |
1993 if (num < fsel || num > esel) | |
1994 selected_state = GTK_STATE_NORMAL; | |
1995 else | |
1996 selected_state = GTK_STATE_SELECTED; | |
1997 if (hb->fore != NULL) | |
1998 gdk_gc_set_foreground(gc, hb->fore); | |
1999 else | |
12 | 2000 gdk_gc_set_foreground(gc, |
2001 &widget->style->fg[selected_state]); | |
1 | 2002 |
2003 gdk_gc_set_font(gc, hb->font); | |
2004 | |
12 | 2005 gdk_text_extents(hb->font, s, 1, &lbearing, &rbearing, &w, NULL, |
2006 NULL); | |
2007 | |
2008 gdk_draw_text(html->html_area, hb->font, gc, | |
2009 shift + hb->x + width, hb->y - html->yoffset, s, | |
2010 1); | |
2011 | |
2012 if (hb->uline) | |
2013 gdk_draw_line(html->html_area, gc, shift + hb->x + width, | |
2014 hb->y - html->yoffset, | |
2015 shift + hb->x + width + w, | |
2016 hb->y - html->yoffset); | |
1 | 2017 |
2018 if (hb->strike) | |
12 | 2019 gdk_draw_line(html->html_area, gc, shift + hb->x + width, |
2020 hb->y - html->yoffset - (hb->height / 3), | |
2021 shift + hb->x + width + w, | |
2022 hb->y - html->yoffset - (hb->height / 3)); | |
1 | 2023 |
2024 width += w; | |
12 | 2025 |
1 | 2026 s++; |
2027 num++; | |
2028 } | |
2029 | |
2030 | |
12 | 2031 } |
2032 else | |
2033 { | |
2034 /*my stuff here*/ | |
2035 | |
2036 if(!hb->was_selected) | |
2037 { | |
2038 area.x = hb->x - html->xoffset; | |
2039 area.y = hb->y - hb->height + 3 - html->yoffset; | |
2040 area.width = hb->width + 2; | |
2041 area.height = hb->height; | |
2042 clear_area(html, &area); | |
2043 } | |
2044 | |
2045 /*end my stuff*/ | |
2046 | |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2047 if (hb->text && hb->back != NULL) { |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
2048 int hwidth, hheight, hei, tmpcnt; |
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
2049 hei = get_line_height(html, hb); |
860
a8633715fb5b
[gaim-migrate @ 870]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
853
diff
changeset
|
2050 gdk_window_get_size(html->html_area, &hwidth, &hheight); |
629
ce8d8608d05b
[gaim-migrate @ 639]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
627
diff
changeset
|
2051 gdk_gc_set_foreground(gc, hb->back); |
938 | 2052 /* we use a 2-pixel window border */ |
2053 if (hb->x < 2) | |
2054 hb->x = 2; | |
635
2ad1a8234ef1
[gaim-migrate @ 645]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
632
diff
changeset
|
2055 gdk_draw_rectangle(html->html_area, gc, TRUE /* filled */, |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
2056 hb->x, hb->y - html->yoffset - hei - 6, |
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
2057 hwidth - shift - hb->x + 1, hei + hei + 2); |
897
b2ce6a6a8633
[gaim-migrate @ 907]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
896
diff
changeset
|
2058 for (tmpcnt = 1; tmpcnt < hb->newline; tmpcnt++) { |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
2059 int eoff = hei + hei + 2; |
897
b2ce6a6a8633
[gaim-migrate @ 907]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
896
diff
changeset
|
2060 eoff *= tmpcnt; |
b2ce6a6a8633
[gaim-migrate @ 907]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
896
diff
changeset
|
2061 gdk_draw_rectangle(html->html_area, gc, TRUE, |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
2062 2, hb->y - html->yoffset - hei - 6 + eoff, |
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
2063 hwidth, hei + hei + 2); |
897
b2ce6a6a8633
[gaim-migrate @ 907]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
896
diff
changeset
|
2064 } |
629
ce8d8608d05b
[gaim-migrate @ 639]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
627
diff
changeset
|
2065 } |
ce8d8608d05b
[gaim-migrate @ 639]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
627
diff
changeset
|
2066 |
1 | 2067 if (hb->fore != NULL) |
2068 gdk_gc_set_foreground(gc, hb->fore); | |
2069 else | |
12 | 2070 gdk_gc_set_foreground(gc, &widget->style->fg[selected_state]); |
1 | 2071 |
2072 gdk_gc_set_font(gc, hb->font); | |
2073 | |
12 | 2074 gdk_draw_string(html->html_area, hb->font, gc, shift + hb->x, |
2075 hb->y - html->yoffset, hb->text); | |
1 | 2076 if (hb->uline) |
12 | 2077 gdk_draw_line(html->html_area, gc, shift + hb->x, |
2078 hb->y - html->yoffset, | |
2079 hb->x + gdk_string_measure(hb->font, hb->text), | |
2080 hb->y - html->yoffset); | |
1 | 2081 |
2082 if (hb->strike) | |
12 | 2083 gdk_draw_line(html->html_area, gc, shift + hb->x, |
2084 hb->y - html->yoffset - (hb->height / 3), | |
2085 hb->x + gdk_string_measure(hb->font, hb->text), | |
2086 hb->y - html->yoffset - (hb->height / 3)); | |
1 | 2087 |
2088 } | |
12 | 2089 } |
2090 else if (hb->type == HTML_BIT_SEP) | |
2091 { | |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2092 if (hb->back != NULL) { |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2093 int hwidth, hheight, hei, tmpcnt; |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
2094 hei = get_line_height(html, hb); |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2095 gdk_window_get_size(html->html_area, &hwidth, &hheight); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2096 gdk_gc_set_foreground(gc, hb->back); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2097 gdk_draw_rectangle(html->html_area, gc, TRUE, |
938 | 2098 2, hb->y - html->yoffset, |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2099 hwidth, 5); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2100 for (tmpcnt = 0; tmpcnt < hb->newline; tmpcnt++) { |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2101 int eoff = hei + hei + 2; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2102 eoff *= tmpcnt; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2103 eoff += 5; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2104 gdk_draw_rectangle(html->html_area, gc, TRUE, |
938 | 2105 2, hb->y - html->yoffset + eoff, |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2106 hwidth, hei + hei + 2); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2107 } |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2108 } |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2109 |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2110 if (hb->fore != NULL) |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2111 gdk_gc_set_foreground(gc, hb->fore); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2112 else |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2113 gdk_gc_set_foreground(gc, &widget->style->fg[GTK_STATE_NORMAL]); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2114 |
12 | 2115 gdk_draw_line(html->html_area, gc, hb->x + 2, |
2116 hb->y - html->yoffset - (hb->height / 2 - 1), | |
2117 hb->x + hb->width, | |
2118 hb->y - html->yoffset - (hb->height / 2 - 1)); | |
2119 | |
2120 } | |
2121 else if (hb->type == HTML_BIT_PIXMAP) | |
2122 { | |
907
08d5037c9296
[gaim-migrate @ 917]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
897
diff
changeset
|
2123 area.x = hb->x - html->xoffset; |
08d5037c9296
[gaim-migrate @ 917]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
897
diff
changeset
|
2124 area.y = hb->y - hb->height + 5 - html->yoffset; |
911
65c8bd1feec5
[gaim-migrate @ 921]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
907
diff
changeset
|
2125 area.width = hb->width; |
907
08d5037c9296
[gaim-migrate @ 917]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
897
diff
changeset
|
2126 area.height = hb->height; |
08d5037c9296
[gaim-migrate @ 917]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
897
diff
changeset
|
2127 clear_area(html, &area); |
918
5871e1eec10c
[gaim-migrate @ 928]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
914
diff
changeset
|
2128 if (hb->back != NULL) { |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2129 int hwidth, hheight, hei, tmpcnt; |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
2130 hei = get_line_height(html, hb); |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2131 gdk_window_get_size(html->html_area, &hwidth, &hheight); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2132 gdk_gc_set_foreground(gc, hb->back); |
918
5871e1eec10c
[gaim-migrate @ 928]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
914
diff
changeset
|
2133 for (tmpcnt = 0; tmpcnt < hb->newline; tmpcnt++) { |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2134 int eoff = hei + hei + 2; |
918
5871e1eec10c
[gaim-migrate @ 928]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
914
diff
changeset
|
2135 eoff *= tmpcnt; |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2136 eoff += 5; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2137 gdk_draw_rectangle(html->html_area, gc, TRUE, |
938 | 2138 2, hb->y - html->yoffset + eoff, |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2139 hwidth, hei + hei + 2); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2140 } |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2141 } |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2142 |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2143 if (hb->fore != NULL) |
918
5871e1eec10c
[gaim-migrate @ 928]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
914
diff
changeset
|
2144 gdk_gc_set_foreground(gc, hb->fore); |
5871e1eec10c
[gaim-migrate @ 928]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
914
diff
changeset
|
2145 else |
5871e1eec10c
[gaim-migrate @ 928]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
914
diff
changeset
|
2146 gdk_gc_set_foreground(gc, &widget->style->fg[GTK_STATE_NORMAL]); |
5871e1eec10c
[gaim-migrate @ 928]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
914
diff
changeset
|
2147 |
12 | 2148 gdk_draw_pixmap(html->html_area, gc, hb->pm, 0, 0, hb->x, |
492
56399273ed8d
[gaim-migrate @ 502]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
481
diff
changeset
|
2149 hb->y - html->yoffset - (hb->height) + 4, -1, -1); |
1 | 2150 } |
2151 } | |
2152 | |
2153 | |
2154 | |
12 | 2155 gint compare_types(GtkHtmlBit * hb, GtkHtmlBit * hb2) |
1 | 2156 { |
12 | 2157 /* |
2158 * In this function, it's OK to accidently return a | |
2159 * * 0, but will cause problems on an accidental 1 | |
2160 */ | |
1 | 2161 |
2162 if (!hb || !hb2) | |
2163 return 0; | |
12 | 2164 |
2165 | |
1 | 2166 if (hb->uline != hb2->uline) |
2167 return 0; | |
2168 if (hb->strike != hb2->strike) | |
12 | 2169 return 0; |
2170 if (hb->font && hb2->font) | |
2171 { | |
1 | 2172 if (!gdk_font_equal(hb->font, hb2->font)) |
2173 return 0; | |
12 | 2174 } |
2175 else if (hb->font && !hb2->font) | |
2176 { | |
1 | 2177 return 0; |
12 | 2178 } |
2179 else if (!hb->font && hb2->font) | |
2180 { | |
1 | 2181 return 0; |
2182 } | |
2183 if (hb->type != hb2->type) | |
2184 return 0; | |
12 | 2185 |
2186 if (hb->fore && hb2->fore) | |
2187 { | |
1 | 2188 if (!gdk_color_equal(hb->fore, hb2->fore)) |
2189 return 0; | |
12 | 2190 } |
2191 else if (hb->fore && !hb2->fore) | |
2192 { | |
1 | 2193 return 0; |
12 | 2194 } |
2195 else if (!hb->fore && hb2->fore) | |
2196 { | |
1 | 2197 return 0; |
2198 } | |
2199 | |
12 | 2200 if (hb->back && hb2->back) |
2201 { | |
1 | 2202 if (!gdk_color_equal(hb->back, hb2->back)) |
2203 return 0; | |
12 | 2204 } |
2205 else if (hb->back && !hb2->back) | |
2206 { | |
1 | 2207 return 0; |
12 | 2208 } |
2209 else if (!hb->back && hb2->back) | |
2210 { | |
1 | 2211 return 0; |
2212 } | |
2213 | |
2214 if ((hb->url != NULL && hb2->url == NULL) || | |
12 | 2215 (hb->url == NULL && hb2->url != NULL)) |
1 | 2216 return 0; |
12 | 2217 |
2218 if (hb->url != NULL && hb2->url != NULL) | |
1 | 2219 if (strcasecmp(hb->url, hb2->url)) |
2220 return 0; | |
12 | 2221 |
1 | 2222 return 1; |
2223 } | |
2224 | |
12 | 2225 static gint html_bit_is_onscreen(GtkHtml * html, GtkHtmlBit * hb) |
1 | 2226 { |
12 | 2227 gint width, |
2228 height; | |
1 | 2229 |
2230 gdk_window_get_size(html->html_area, &width, &height); | |
12 | 2231 |
2232 if (hb->y < html->yoffset) | |
2233 { | |
1 | 2234 return 0; |
2235 } | |
2236 | |
12 | 2237 if ((hb->y - hb->height) > (html->yoffset + height)) |
2238 { | |
1 | 2239 return 0; |
2240 } | |
2241 return 1; | |
2242 } | |
2243 | |
12 | 2244 static void draw_cursor(GtkHtml * html) |
1 | 2245 { |
12 | 2246 if (html->editable && |
2247 html->cursor_hb && | |
2248 GTK_WIDGET_DRAWABLE(html) && | |
2249 html_bit_is_onscreen(html, html->cursor_hb)) | |
2250 { | |
2251 gint x, | |
2252 y; | |
1 | 2253 gint width; |
2254 | |
2255 GdkFont *font = html->cursor_hb->font; | |
2256 | |
12 | 2257 gdk_text_extents(font, html->cursor_hb->text, html->cursor_pos, NULL, |
2258 NULL, &width, NULL, NULL); | |
2259 | |
2260 gdk_gc_set_foreground(html->gc, | |
2261 >K_WIDGET(html)->style->text[GTK_STATE_NORMAL]); | |
1 | 2262 |
2263 y = html->cursor_hb->y - html->yoffset; | |
2264 x = html->cursor_hb->x + width; | |
2265 | |
2266 | |
12 | 2267 gdk_draw_line(html->html_area, html->gc, x, y, x, y - font->ascent); |
1 | 2268 |
2269 } | |
2270 } | |
2271 | |
12 | 2272 static void undraw_cursor(GtkHtml * html) |
1 | 2273 { |
12 | 2274 if (html->editable && |
2275 html->cursor_hb && | |
2276 GTK_WIDGET_DRAWABLE(html) && | |
2277 html_bit_is_onscreen(html, html->cursor_hb)) | |
2278 { | |
2279 gint x, | |
2280 y; | |
1 | 2281 gint width; |
12 | 2282 GdkRectangle area; |
2283 | |
1 | 2284 GdkFont *font = html->cursor_hb->font; |
2285 | |
12 | 2286 gdk_text_extents(font, html->cursor_hb->text, html->cursor_pos, NULL, |
2287 NULL, &width, NULL, NULL); | |
1 | 2288 |
2289 y = html->cursor_hb->y - html->yoffset; | |
2290 x = html->cursor_hb->x + width; | |
2291 | |
2292 area.x = x; | |
2293 area.y = y - font->ascent; | |
2294 area.height = font->ascent + 1; | |
2295 area.width = 1; | |
2296 | |
2297 | |
12 | 2298 clear_area(html, &area); |
1 | 2299 |
897
b2ce6a6a8633
[gaim-migrate @ 907]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
896
diff
changeset
|
2300 gtk_html_draw_bit(html, html->cursor_hb, 1); |
12 | 2301 |
2302 | |
2303 } | |
1 | 2304 } |
2305 | |
2306 | |
12 | 2307 static void expose_html(GtkHtml * html, GdkRectangle * area, gboolean cursor) |
1 | 2308 { |
12 | 2309 GList *hbits; |
2310 GtkHtmlBit *hb; | |
2311 gint width, | |
2312 height; | |
2313 gint realy; | |
2314 | |
2315 | |
2316 if (html->frozen > 0) | |
2317 return; | |
2318 | |
2319 | |
2320 hbits = html->html_bits; | |
1 | 2321 |
2322 gdk_window_get_size(html->html_area, &width, &height); | |
2323 | |
12 | 2324 realy = area->y + html->yoffset; |
2325 | |
895 | 2326 /* this is needed since background colors draw across the entire window width |
2327 if anyone knows of a cleaner way to work bg colors, please submit code =) */ | |
2328 area->x = 0; | |
2329 area->width = width; | |
2330 | |
12 | 2331 clear_area(html, area); |
2332 | |
2333 while (hbits) | |
2334 { | |
2335 | |
2336 hb = (GtkHtmlBit *) hbits->data; | |
1 | 2337 |
2338 if (html_bit_is_onscreen(html, hb)) | |
12 | 2339 gtk_html_draw_bit(html, hb, 1); |
2340 | |
2341 | |
2342 hbits = hbits->next; | |
2343 } | |
1 | 2344 } |
2345 | |
12 | 2346 static void resize_html(GtkHtml * html) |
1 | 2347 { |
2348 GList *hbits = html->html_bits; | |
2349 GList *html_bits = html->html_bits; | |
12 | 2350 GtkHtmlBit *hb, |
2351 *hb2; | |
1 | 2352 char *str; |
2353 gint height; | |
2354 | |
12 | 2355 if (!hbits) |
2356 return; | |
2357 | |
2358 | |
2359 html->html_bits = NULL; | |
2360 | |
2361 html->current_x = 0; | |
1 | 2362 html->current_y = 0; |
2363 | |
12 | 2364 html->vadj->upper = 0; |
2365 | |
2366 gtk_html_freeze(html); | |
2367 | |
2368 while (hbits) | |
2369 { | |
2370 hb = (GtkHtmlBit *) hbits->data; | |
2371 if (hb->type == HTML_BIT_SEP) | |
2372 { | |
2373 | |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2374 gtk_html_add_seperator(html, hb->font, hb->fore, hb->back); |
1 | 2375 |
2376 g_free(hb); | |
2377 | |
2378 hbits = hbits->next; | |
2379 continue; | |
2380 } | |
12 | 2381 if (hb->type == HTML_BIT_PIXMAP) |
2382 { | |
1 | 2383 |
536
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2384 gtk_html_add_pixmap(html, hb->pm, hb->fit, hb->newline); |
1 | 2385 |
2386 g_free(hb); | |
2387 | |
2388 hbits = hbits->next; | |
2389 continue; | |
2390 } | |
12 | 2391 |
2392 if (hb->newline) | |
2393 { | |
1 | 2394 int i; |
2395 | |
12 | 2396 if (!hb->text) |
2397 { | |
1 | 2398 hb->text = g_malloc(1); |
2399 hb->text[0] = 0; | |
2400 } | |
12 | 2401 for (i = 0; i < hb->newline; i++) |
2402 { | |
2403 str = hb->text; | |
1 | 2404 hb->text = g_strconcat(str, "\n", NULL); |
506
58af37870fdd
[gaim-migrate @ 516]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
499
diff
changeset
|
2405 if (str) g_free(str); |
1 | 2406 } |
2407 } | |
2408 | |
12 | 2409 if (hbits->next) |
2410 { | |
2411 hb2 = (GtkHtmlBit *) hbits->next->data; | |
2412 } | |
2413 else | |
2414 { | |
2415 hb2 = NULL; | |
2416 } | |
2417 | |
2418 | |
2419 | |
2420 if (!hb->newline && compare_types(hb, hb2)) | |
2421 { | |
1 | 2422 str = hb2->text; |
2423 hb2->text = g_strconcat(hb->text, hb2->text, NULL); | |
537
d050f88321a1
[gaim-migrate @ 547]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
536
diff
changeset
|
2424 if (str) g_free(str); |
1 | 2425 hb2 = NULL; |
12 | 2426 } |
2427 else if (hb->text) | |
2428 { | |
1 | 2429 gtk_html_add_text(html, hb->font, hb->fore, hb->back, |
12 | 2430 hb->text, strlen(hb->text), hb->uline, hb->strike, |
2431 hb->url); | |
1 | 2432 } |
2433 | |
12 | 2434 |
2435 | |
2436 /* | |
2437 * Font stays, so do colors (segfaults if I free) | |
2438 */ | |
1 | 2439 if (hb->fore) |
2440 gdk_color_free(hb->fore); | |
2441 if (hb->back) | |
2442 gdk_color_free(hb->back); | |
2443 if (hb->text) | |
2444 g_free(hb->text); | |
2445 if (hb->url) | |
2446 g_free(hb->url); | |
2447 | |
12 | 2448 g_free(hb); |
1 | 2449 |
2450 hbits = hbits->next; | |
2451 } | |
2452 | |
12 | 2453 g_list_free(html_bits); |
2454 | |
2455 | |
2456 gtk_html_thaw(html); | |
2457 | |
1 | 2458 gdk_window_get_size(html->html_area, NULL, &height); |
12 | 2459 gtk_adjustment_set_value(html->vadj, html->vadj->upper - height); |
1 | 2460 |
2461 } | |
2462 | |
12 | 2463 static GdkGC *create_bg_gc(GtkHtml * html) |
1 | 2464 { |
12 | 2465 GdkGCValues values; |
2466 | |
2467 values.tile = GTK_WIDGET(html)->style->bg_pixmap[GTK_STATE_NORMAL]; | |
2468 values.fill = GDK_TILED; | |
2469 | |
2470 return gdk_gc_new_with_values(html->html_area, &values, | |
2471 GDK_GC_FILL | GDK_GC_TILE); | |
1 | 2472 } |
2473 | |
12 | 2474 static void clear_area(GtkHtml * html, GdkRectangle * area) |
1 | 2475 { |
12 | 2476 GtkWidget *widget = GTK_WIDGET(html); |
2477 gint x, | |
2478 y; | |
2479 | |
2480 | |
2481 if (html->transparent) | |
2482 { | |
1 | 2483 if (html->pm == NULL) |
2484 html->pm = get_desktop_pixmap(widget); | |
2485 | |
12 | 2486 if (html->pm == NULL) |
2487 return; | |
2488 | |
2489 if (html->bg_gc == NULL) | |
2490 { | |
2491 GdkGCValues values; | |
2492 | |
2493 values.tile = html->pm; | |
2494 values.fill = GDK_TILED; | |
2495 | |
2496 html->bg_gc = gdk_gc_new_with_values(html->html_area, &values, | |
2497 GDK_GC_FILL | GDK_GC_TILE); | |
2498 | |
2499 } | |
2500 | |
1 | 2501 gdk_window_get_deskrelative_origin(html->html_area, &x, &y); |
2502 | |
12 | 2503 gdk_draw_pixmap(html->html_area, html->bg_gc, html->pm, |
2504 x + area->x, y + area->y, area->x, area->y, area->width, | |
2505 area->height); | |
1 | 2506 |
2507 return; | |
2508 | |
2509 } | |
12 | 2510 if (html->bg_gc) |
2511 { | |
2512 | |
2513 gint width, | |
2514 height; | |
2515 | |
2516 gdk_window_get_size(widget->style->bg_pixmap[GTK_STATE_NORMAL], &width, | |
2517 &height); | |
2518 | |
2519 gdk_gc_set_ts_origin(html->bg_gc, | |
2520 (-html->xoffset) % width, | |
2521 (-html->yoffset) % height); | |
2522 | |
2523 gdk_draw_rectangle(html->html_area, html->bg_gc, TRUE, | |
2524 area->x, area->y, area->width, area->height); | |
2525 } | |
2526 else | |
2527 gdk_window_clear_area(html->html_area, area->x, area->y, area->width, | |
2528 area->height); | |
1 | 2529 } |
2530 | |
2531 | |
2532 | |
2533 | |
12 | 2534 static void gtk_html_destroy(GtkObject * object) |
1 | 2535 { |
12 | 2536 GtkHtml *html; |
2537 | |
2538 g_return_if_fail(object != NULL); | |
2539 g_return_if_fail(GTK_IS_HTML(object)); | |
2540 | |
2541 html = (GtkHtml *) object; | |
2542 | |
2543 | |
2544 gtk_signal_disconnect_by_data(GTK_OBJECT(html->hadj), html); | |
2545 gtk_signal_disconnect_by_data(GTK_OBJECT(html->vadj), html); | |
2546 | |
2547 if (html->timer) | |
2548 { | |
2549 gtk_timeout_remove(html->timer); | |
2550 html->timer = 0; | |
1 | 2551 } |
2552 | |
12 | 2553 if (html->tooltip_timer) |
2554 { | |
2555 gtk_timeout_remove(html->tooltip_timer); | |
1 | 2556 html->tooltip_timer = -1; |
2557 } | |
2558 | |
12 | 2559 |
2560 GTK_OBJECT_CLASS(parent_class)->destroy(object); | |
2561 | |
1 | 2562 } |
2563 | |
12 | 2564 static void gtk_html_finalize(GtkObject * object) |
1 | 2565 { |
12 | 2566 GList *hbits; |
2567 GtkHtml *html; | |
1 | 2568 GtkHtmlBit *hb; |
2569 | |
2570 | |
12 | 2571 g_return_if_fail(object != NULL); |
2572 g_return_if_fail(GTK_IS_HTML(object)); | |
2573 | |
2574 html = (GtkHtml *) object; | |
2575 | |
2576 gtk_object_unref(GTK_OBJECT(html->hadj)); | |
2577 gtk_object_unref(GTK_OBJECT(html->vadj)); | |
2578 | |
2579 hbits = html->html_bits; | |
2580 | |
2581 while (hbits) | |
2582 { | |
2583 hb = (GtkHtmlBit *) hbits->data; | |
2584 if (hb->fore) | |
2585 gdk_color_free(hb->fore); | |
2586 if (hb->back) | |
2587 gdk_color_free(hb->back); | |
2588 if (hb->text) | |
2589 g_free(hb->text); | |
2590 if (hb->url) | |
2591 g_free(hb->url); | |
2592 if (hb->pm) | |
2593 gdk_pixmap_unref(hb->pm); | |
2594 | |
2595 g_free(hb); | |
2596 hbits = hbits->next; | |
2597 } | |
2598 if (html->html_bits) | |
2599 g_list_free(html->html_bits); | |
2600 | |
2601 if (html->urls) | |
2602 g_list_free(html->urls); | |
2603 | |
2604 if (html->selected_text) | |
2605 g_free(html->selected_text); | |
2606 | |
2607 if (html->gc) | |
2608 gdk_gc_destroy(html->gc); | |
2609 | |
2610 if (html->bg_gc) | |
2611 gdk_gc_destroy(html->bg_gc); | |
1 | 2612 |
2613 if (html->tooltip_window) | |
2614 gtk_widget_destroy(html->tooltip_window); | |
12 | 2615 |
2616 GTK_OBJECT_CLASS(parent_class)->finalize(object); | |
1 | 2617 } |
2618 | |
12 | 2619 static void gtk_html_realize(GtkWidget * widget) |
1 | 2620 { |
12 | 2621 GtkHtml *html; |
2622 GdkWindowAttr attributes; | |
2623 gint attributes_mask; | |
2624 | |
2625 g_return_if_fail(widget != NULL); | |
2626 g_return_if_fail(GTK_IS_HTML(widget)); | |
2627 | |
2628 html = GTK_HTML(widget); | |
2629 GTK_WIDGET_SET_FLAGS(html, GTK_REALIZED); | |
2630 | |
2631 attributes.window_type = GDK_WINDOW_CHILD; | |
2632 attributes.x = widget->allocation.x; | |
2633 attributes.y = widget->allocation.y; | |
2634 attributes.width = widget->allocation.width; | |
2635 attributes.height = widget->allocation.height; | |
2636 attributes.wclass = GDK_INPUT_OUTPUT; | |
2637 attributes.visual = gtk_widget_get_visual(widget); | |
2638 attributes.colormap = gtk_widget_get_colormap(widget); | |
2639 attributes.event_mask = gtk_widget_get_events(widget); | |
2640 attributes.event_mask |= (GDK_EXPOSURE_MASK | | |
2641 GDK_BUTTON_PRESS_MASK | | |
2642 GDK_BUTTON_RELEASE_MASK | | |
2643 GDK_BUTTON_MOTION_MASK | | |
2644 GDK_ENTER_NOTIFY_MASK | | |
2645 GDK_LEAVE_NOTIFY_MASK | | |
2646 GDK_POINTER_MOTION_MASK | | |
2647 GDK_POINTER_MOTION_HINT_MASK | | |
2648 GDK_VISIBILITY_NOTIFY_MASK | GDK_KEY_PRESS_MASK); | |
2649 | |
2650 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; | |
2651 | |
2652 widget->window = | |
2653 gdk_window_new(gtk_widget_get_parent_window(widget), &attributes, | |
2654 attributes_mask); | |
2655 gdk_window_set_user_data(widget->window, html); | |
2656 | |
2657 attributes.x = (widget->style->klass->xthickness + BORDER_WIDTH); | |
2658 attributes.y = (widget->style->klass->ythickness + BORDER_WIDTH); | |
2659 attributes.width = | |
2660 MAX(1, (gint) widget->allocation.width - (gint) attributes.x * 2); | |
2661 attributes.height = | |
2662 MAX(1, (gint) widget->allocation.height - (gint) attributes.y * 2); | |
2663 | |
2664 html->html_area = | |
2665 gdk_window_new(widget->window, &attributes, attributes_mask); | |
2666 gdk_window_set_user_data(html->html_area, html); | |
2667 | |
2668 widget->style = gtk_style_attach(widget->style, widget->window); | |
2669 | |
2670 /* | |
2671 * Can't call gtk_style_set_background here because it's handled specially | |
2672 */ | |
2673 gdk_window_set_background(widget->window, | |
2674 &widget->style->base[GTK_STATE_NORMAL]); | |
2675 gdk_window_set_background(html->html_area, | |
2676 &widget->style->base[GTK_STATE_NORMAL]); | |
2677 | |
2678 if (widget->style->bg_pixmap[GTK_STATE_NORMAL]) | |
2679 html->bg_gc = create_bg_gc(html); | |
2680 | |
2681 html->gc = gdk_gc_new(html->html_area); | |
2682 gdk_gc_set_exposures(html->gc, TRUE); | |
2683 gdk_gc_set_foreground(html->gc, &widget->style->text[GTK_STATE_NORMAL]); | |
2684 | |
2685 gdk_window_show(html->html_area); | |
1 | 2686 |
2687 } | |
2688 | |
12 | 2689 static void gtk_html_style_set(GtkWidget * widget, GtkStyle * previous_style) |
1 | 2690 { |
12 | 2691 GtkHtml *html; |
2692 | |
2693 g_return_if_fail(widget != NULL); | |
2694 g_return_if_fail(GTK_IS_HTML(widget)); | |
2695 | |
2696 html = GTK_HTML(widget); | |
2697 if (GTK_WIDGET_REALIZED(widget)) | |
2698 { | |
2699 gdk_window_set_background(widget->window, | |
2700 &widget->style->base[GTK_STATE_NORMAL]); | |
2701 gdk_window_set_background(html->html_area, | |
2702 &widget->style->base[GTK_STATE_NORMAL]); | |
2703 | |
2704 if (html->bg_gc) | |
2705 { | |
2706 gdk_gc_destroy(html->bg_gc); | |
2707 html->bg_gc = NULL; | |
2708 } | |
2709 | |
2710 if (widget->style->bg_pixmap[GTK_STATE_NORMAL]) | |
2711 { | |
2712 html->bg_gc = create_bg_gc(html); | |
2713 } | |
2714 | |
2715 } | |
1 | 2716 } |
2717 | |
12 | 2718 static void gtk_html_unrealize(GtkWidget * widget) |
1 | 2719 { |
12 | 2720 GtkHtml *html; |
2721 | |
2722 g_return_if_fail(widget != NULL); | |
2723 g_return_if_fail(GTK_IS_HTML(widget)); | |
2724 | |
2725 html = GTK_HTML(widget); | |
2726 | |
2727 gdk_window_set_user_data(html->html_area, NULL); | |
2728 gdk_window_destroy(html->html_area); | |
2729 html->html_area = NULL; | |
2730 | |
2731 gdk_gc_destroy(html->gc); | |
2732 html->gc = NULL; | |
2733 | |
2734 if (html->bg_gc) | |
2735 { | |
2736 gdk_gc_destroy(html->bg_gc); | |
2737 html->bg_gc = NULL; | |
2738 } | |
2739 | |
2740 if (GTK_WIDGET_CLASS(parent_class)->unrealize) | |
2741 (*GTK_WIDGET_CLASS(parent_class)->unrealize) (widget); | |
1 | 2742 } |
2743 | |
2744 | |
536
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2745 void gtk_html_add_pixmap(GtkHtml * html, GdkPixmap * pm, int fit, int newline) |
1 | 2746 { |
12 | 2747 GtkHtmlBit *last_hb; |
2748 GtkHtmlBit *hb = g_new0(GtkHtmlBit, 1); | |
2749 GdkWindowPrivate *private = (GdkWindowPrivate *) pm; | |
536
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2750 int width, height; |
12 | 2751 |
2752 last_hb = (GtkHtmlBit *) g_list_last(html->html_bits)->data; | |
1 | 2753 |
536
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2754 /* wrap pixmaps */ |
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2755 gdk_window_get_size(html->html_area, &width, &height); |
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2756 if ((html->current_x + private->width) >= width) { |
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2757 html->current_x = 0; |
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2758 } |
499
3ebd3ca4c3d4
[gaim-migrate @ 509]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
492
diff
changeset
|
2759 |
1 | 2760 hb->fit = fit; |
542
872d68495410
[gaim-migrate @ 552]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
540
diff
changeset
|
2761 html->current_x += 2; |
1 | 2762 hb->x = html->current_x; |
2763 hb->y = html->current_y; | |
12 | 2764 if (fit) |
1 | 2765 hb->height = last_hb->height; |
2766 else | |
2767 hb->height = private->height; | |
2768 hb->type = HTML_BIT_PIXMAP; | |
2769 hb->width = private->width; | |
2770 hb->text = NULL; | |
2771 hb->url = NULL; | |
918
5871e1eec10c
[gaim-migrate @ 928]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
914
diff
changeset
|
2772 if (last_hb->fore) hb->fore = gdk_color_copy(last_hb->fore); |
5871e1eec10c
[gaim-migrate @ 928]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
914
diff
changeset
|
2773 else hb->fore = NULL; |
5871e1eec10c
[gaim-migrate @ 928]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
914
diff
changeset
|
2774 if (last_hb->back) hb->back = gdk_color_copy(last_hb->back); |
5871e1eec10c
[gaim-migrate @ 928]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
914
diff
changeset
|
2775 else hb->back = NULL; |
5871e1eec10c
[gaim-migrate @ 928]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
914
diff
changeset
|
2776 hb->font = last_hb->font; |
12 | 2777 hb->uline = 0; |
2778 hb->strike = 0; | |
1 | 2779 hb->was_selected = 0; |
536
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2780 hb->newline = newline; |
12 | 2781 hb->pm = pm; |
2782 | |
2783 if (html->current_x == BORDER_WIDTH) | |
2784 { | |
540
f586c3819574
[gaim-migrate @ 550]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
537
diff
changeset
|
2785 html->current_y += hb->height + 3; |
f586c3819574
[gaim-migrate @ 550]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
537
diff
changeset
|
2786 hb->y += hb->height + 3; |
1 | 2787 } |
2788 | |
2789 | |
542
872d68495410
[gaim-migrate @ 552]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
540
diff
changeset
|
2790 html->current_x += hb->width + 1; |
12 | 2791 |
1 | 2792 gtk_html_draw_bit(html, hb, 1); |
2793 | |
536
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2794 if (hb->newline) |
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2795 html->current_x = 0; |
c9f994ea5833
[gaim-migrate @ 546]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
526
diff
changeset
|
2796 |
1 | 2797 html->html_bits = g_list_append(html->html_bits, hb); |
2798 | |
2799 | |
2800 } | |
2801 | |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2802 static void gtk_html_add_seperator(GtkHtml * html, GdkFont *font, GdkColor *fore, GdkColor *back) |
1 | 2803 { |
12 | 2804 GtkHtmlBit *hb = g_new0(GtkHtmlBit, 1); |
2805 gint width, | |
2806 height; | |
2807 | |
1 | 2808 html->current_x = 0; |
2809 html->current_y += 5; | |
2810 | |
12 | 2811 gdk_window_get_size(html->html_area, &width, &height); |
2812 | |
1 | 2813 hb->x = html->current_x; |
2814 hb->y = html->current_y; | |
2815 hb->height = 5; | |
2816 hb->type = HTML_BIT_SEP; | |
12 | 2817 hb->width = |
2818 width - | |
2819 GTK_SCROLLED_WINDOW(GTK_WIDGET(html)->parent)->vscrollbar->allocation. | |
2820 width - 10; | |
1 | 2821 hb->text = NULL; |
2822 hb->url = NULL; | |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2823 if (fore) |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2824 hb->fore = gdk_color_copy(fore); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2825 else |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2826 hb->fore = NULL; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2827 |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2828 if (back) |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2829 hb->back = gdk_color_copy(back); |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2830 else |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2831 hb->back = NULL; |
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
2832 hb->font = font; |
12 | 2833 hb->uline = 0; |
2834 hb->strike = 0; | |
1 | 2835 hb->was_selected = 0; |
12 | 2836 hb->newline = 0; |
2837 hb->pm = NULL; | |
1 | 2838 |
2839 gtk_html_draw_bit(html, hb, 1); | |
2840 | |
2841 html->html_bits = g_list_append(html->html_bits, hb); | |
2842 | |
2843 } | |
2844 | |
12 | 2845 static void gtk_html_add_text(GtkHtml * html, |
2846 GdkFont * cfont, | |
2847 GdkColor * fore, | |
2848 GdkColor * back, | |
2849 char *chars, | |
2850 gint length, gint uline, gint strike, char *url) | |
1 | 2851 { |
12 | 2852 char *nextline = NULL, |
2853 *c, | |
2854 *text, | |
2855 *tmp; | |
2856 GdkGC *gc; | |
2857 int nl = 0, | |
2858 nl2 = 0; | |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
2859 int maxwidth; |
12 | 2860 gint lb; |
2861 GList *hbits; | |
79 | 2862 size_t num = 0; |
2863 int i, | |
12 | 2864 height; |
2865 GtkHtmlBit *hb; | |
2866 gint hwidth, | |
2867 hheight; | |
2868 | |
2869 if (length == 1 && chars[0] == '\n') | |
2870 { | |
2871 GtkHtmlBit *h; | |
2872 hbits = g_list_last(html->html_bits); | |
2873 if (!hbits) | |
2874 return; | |
2875 /* | |
2876 * I realize this loses a \n sometimes | |
2877 * * if it's the first thing in the widget. | |
2878 * * so fucking what. | |
2879 */ | |
2880 | |
2881 h = (GtkHtmlBit *) hbits->data; | |
2882 h->newline++; | |
2883 if (html->current_x > 0) | |
2884 html->current_x = 0; | |
2885 else | |
540
f586c3819574
[gaim-migrate @ 550]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
537
diff
changeset
|
2886 html->current_y += cfont->ascent + cfont->descent + 5; |
12 | 2887 return; |
2888 } | |
2889 | |
2890 | |
2891 | |
2892 c = text = g_malloc(length + 2); | |
2893 strncpy(text, chars, length); | |
2894 text[length] = 0; | |
2895 | |
2896 | |
2897 gc = html->gc; | |
2898 | |
2899 if (gc == NULL) | |
2900 gc = html->gc = gdk_gc_new(html->html_area); | |
2901 | |
2902 gdk_gc_set_font(gc, cfont); | |
2903 | |
2904 | |
2905 while (*c) | |
2906 { | |
2907 if (*c == '\n') | |
2908 { | |
2909 if (*(c + 1) == '\0') | |
2910 { | |
2911 nl = 1; | |
2912 length--; | |
2913 c[0] = '\0'; | |
2914 break; | |
2915 } | |
2916 if (*c) | |
2917 { | |
2918 gtk_html_add_text(html, cfont, fore, back, text, num + 1, uline, | |
2919 strike, url); | |
2920 tmp = text; | |
2921 length -= (num + 1); | |
2922 text = g_malloc(length + 2); | |
2923 strncpy(text, (c + 1), length); | |
2924 text[length] = 0; | |
2925 c = text; | |
2926 num = 0; | |
2927 g_free(tmp); | |
1 | 2928 continue; |
12 | 2929 } |
2930 } | |
2931 | |
2932 num++; | |
2933 c++; | |
2934 } | |
2935 | |
2936 /* | |
2937 * Note, yG is chosen because G is damn high, and y is damn low, | |
2938 */ | |
2939 /* | |
2940 * it should be just fine. :) | |
2941 */ | |
2942 | |
2943 gdk_window_get_size(html->html_area, &hwidth, &hheight); | |
2944 | |
2945 num = strlen(text); | |
2946 | |
2947 while (GTK_WIDGET(html)->allocation.width < 20) | |
2948 { | |
2949 while (gtk_events_pending()) | |
1 | 2950 gtk_main_iteration(); |
2951 } | |
2952 | |
12 | 2953 maxwidth = (hwidth - html->current_x - 8); |
2954 /* | |
2955 * HTK_SCROLLED_WINDOW(GTK_WIDGET(layout)->parent)->vscrollbar->allocation.width) - 8; | |
2956 */ | |
2957 | |
851
2cee5577224b
[gaim-migrate @ 861]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
850
diff
changeset
|
2958 if ((maxwidth == (hwidth - 8) && gdk_text_measure(cfont, text, num) > 2 * maxwidth) || |
2cee5577224b
[gaim-migrate @ 861]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
850
diff
changeset
|
2959 gdk_text_measure(cfont, text, num) < 0) { |
847
430a88eb4a68
[gaim-migrate @ 857]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
842
diff
changeset
|
2960 int pos = num / 2; |
842
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2961 static int count = 0; |
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2962 count ++; |
850
902be73a6a43
[gaim-migrate @ 860]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
847
diff
changeset
|
2963 while (pos < num && (!isspace(text[pos]) || text[pos] == '\n')) pos++; |
1004
69c936ca2b04
[gaim-migrate @ 1014]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
985
diff
changeset
|
2964 if (pos >= num - 1) { |
847
430a88eb4a68
[gaim-migrate @ 857]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
842
diff
changeset
|
2965 pos = num/2; |
850
902be73a6a43
[gaim-migrate @ 860]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
847
diff
changeset
|
2966 while (pos > 0 && (!isspace(text[pos]) || text[pos] == '\n')) pos--; |
847
430a88eb4a68
[gaim-migrate @ 857]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
842
diff
changeset
|
2967 if (!pos) pos = num / 2; |
430a88eb4a68
[gaim-migrate @ 857]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
842
diff
changeset
|
2968 } |
850
902be73a6a43
[gaim-migrate @ 860]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
847
diff
changeset
|
2969 gtk_html_add_text(html, cfont, fore, back, text, pos + 1, uline, strike, url); |
902be73a6a43
[gaim-migrate @ 860]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
847
diff
changeset
|
2970 gtk_html_add_text(html, cfont, fore, back, &text[pos+1], 1, uline, strike, url); |
902be73a6a43
[gaim-migrate @ 860]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
847
diff
changeset
|
2971 gtk_html_add_text(html, cfont, fore, back, &text[pos+2], num - pos + 1, uline, strike, url); |
842
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2972 g_free(text); |
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2973 count--; |
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2974 if (!count) { |
853
050f244b6829
[gaim-migrate @ 863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
852
diff
changeset
|
2975 /* FIXME : sometimes we need to add newline, sometimes we don't */ |
842
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2976 hbits = g_list_last(html->html_bits); |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
2977 if (!hbits) return; /* does this ever happen? */ |
842
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2978 hb = (GtkHtmlBit *)hbits->data; |
850
902be73a6a43
[gaim-migrate @ 860]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
847
diff
changeset
|
2979 hb->newline++; |
842
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2980 } |
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2981 return; |
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2982 } |
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
2983 |
12 | 2984 while (gdk_text_measure(cfont, text, num) > maxwidth) |
2985 { | |
2986 if (num > 1) | |
2987 num--; | |
2988 else | |
2989 { | |
26 | 2990 if (html->current_x != 0) { |
2991 html->current_x = 0; | |
2992 if (nl) { | |
2993 text[length] = '\n'; | |
2994 length++; | |
2995 } | |
2996 gtk_html_add_text(html, cfont, fore, back, text, length, uline, strike, url); | |
2997 g_free(text); | |
2998 return; | |
2999 } else { | |
3000 num = strlen (text); | |
3001 break; | |
1 | 3002 } |
3003 } | |
3004 | |
3005 } | |
3006 | |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3007 height = cfont->ascent + cfont->descent + 2; |
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3008 |
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3009 |
12 | 3010 if ((int) (html->vadj->upper - html->current_y) < (int) (height * 2)) |
3011 { | |
3012 int val; | |
3013 val = (height * 2) + html->current_y; | |
3014 html->vadj->upper = val; | |
3015 adjust_adj(html, html->vadj); | |
1 | 3016 } |
3017 | |
12 | 3018 |
3019 if (html->current_x == 0) | |
3020 { | |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3021 html->current_y += height + 3; |
12 | 3022 gdk_text_extents(cfont, text, 1, &lb, NULL, NULL, NULL, NULL); |
3023 html->current_x += (2 - lb); | |
3024 } | |
3025 else if ((hbits = g_list_last(html->html_bits)) != NULL) | |
3026 { | |
3027 int diff, | |
3028 y; | |
3029 hb = (GtkHtmlBit *) hbits->data; | |
3030 if (height > hb->height) | |
3031 { | |
1 | 3032 diff = height - hb->height; |
3033 y = hb->y; | |
3034 html->current_y += diff; | |
12 | 3035 while (hbits) |
3036 { | |
3037 hb = (GtkHtmlBit *) hbits->data; | |
1 | 3038 if (hb->y != y) |
12 | 3039 break; |
492
56399273ed8d
[gaim-migrate @ 502]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
481
diff
changeset
|
3040 if (hb->type != HTML_BIT_PIXMAP) |
56399273ed8d
[gaim-migrate @ 502]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
481
diff
changeset
|
3041 hb->height = height; |
12 | 3042 hb->y += diff; ////////////my thing here ///////////////// |
3043 gtk_html_draw_bit(html, hb, FALSE); | |
3044 | |
3045 hbits = hbits->prev; | |
1 | 3046 } |
3047 } | |
3048 } | |
3049 | |
3050 | |
3051 | |
3052 | |
12 | 3053 if (num != strlen(text)) |
3054 { | |
3055 /* | |
3056 * This is kinda cheesy but it may make things | |
3057 * * much better lookin | |
3058 */ | |
26 | 3059 |
842
2804dc8e9ba0
[gaim-migrate @ 852]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
829
diff
changeset
|
3060 for (i=2; (num > i); i++) { |
26 | 3061 if (text[num - i] == ' ') { |
12 | 3062 num = num - (i - 1); |
1 | 3063 nl2 = 1; |
3064 break; | |
3065 } | |
3066 } | |
3067 | |
3068 nextline = g_malloc(length - num + 2); | |
12 | 3069 strncpy(nextline, (char *) (text + num), length - num); |
1 | 3070 nextline[length - num] = 0; |
12 | 3071 if (nl) |
3072 { | |
1 | 3073 nextline[length - num] = '\n'; |
3074 nextline[length - num + 1] = 0; | |
3075 nl = 0; | |
3076 } | |
3077 | |
3078 | |
3079 text[num] = 0; | |
3080 } | |
3081 | |
3082 | |
52 | 3083 if (url != NULL) { |
53 | 3084 fore = get_color(3355647, gdk_window_get_colormap(html->html_area)); |
52 | 3085 } |
1 | 3086 |
3087 hb = g_new0(GtkHtmlBit, 1); | |
3088 | |
3089 hb->text = g_strdup(text); | |
3090 | |
52 | 3091 if (fore) |
3092 hb->fore = gdk_color_copy(fore); | |
3093 else | |
3094 hb->fore = NULL; | |
49 | 3095 |
1 | 3096 if (back) |
3097 hb->back = gdk_color_copy(back); | |
3098 else | |
3099 hb->back = NULL; | |
3100 hb->font = cfont; | |
3101 hb->uline = uline; | |
3102 hb->strike = strike; | |
3103 hb->height = height; | |
3104 gdk_text_extents(cfont, text, num, &lb, NULL, &hb->width, NULL, NULL); | |
3105 hb->x = html->current_x; | |
3106 hb->y = html->current_y; | |
12 | 3107 hb->type = HTML_BIT_TEXT; |
3108 hb->pm = NULL; | |
3109 if (url != NULL) | |
3110 { | |
1 | 3111 uline = 1; |
3112 hb->uline = 1; | |
3113 hb->url = g_strdup(url); | |
12 | 3114 } |
3115 else | |
3116 { | |
1 | 3117 hb->url = NULL; |
3118 } | |
3119 html->current_x += hb->width; | |
3120 | |
3121 html->html_bits = g_list_append(html->html_bits, hb); | |
12 | 3122 if (url != NULL) |
3123 { | |
3124 html->urls = g_list_append(html->urls, hb); | |
3125 } | |
3126 | |
3127 | |
3128 | |
3129 gtk_html_draw_bit(html, hb, 1); | |
3130 | |
3131 if (nl || nl2) | |
3132 { | |
3133 if (nl) | |
3134 hb->newline = 1; | |
3135 html->current_x = 0; | |
3136 } | |
3137 else | |
3138 hb->newline = 0; | |
3139 | |
3140 | |
3141 if (nextline != NULL) | |
3142 { | |
3143 gtk_html_add_text(html, cfont, fore, back, nextline, strlen(nextline), | |
3144 uline, strike, url); | |
3145 g_free(nextline); | |
3146 } | |
3147 | |
3148 g_free(text); | |
137 | 3149 if (url != NULL) |
3150 g_free(fore); | |
1 | 3151 } |
3152 | |
12 | 3153 static char * html_strtok( char * input, char delim ) |
1 | 3154 { |
12 | 3155 static char * end; |
3156 static char * curr_offset; | |
3157 int i; | |
3158 int num_quotes=0; | |
3159 | |
3160 if( input != NULL) | |
3161 { | |
3162 curr_offset = input; | |
3163 end = input+strlen(input); | |
3164 } | |
3165 else | |
3166 { | |
3167 if( curr_offset + strlen(curr_offset) < end ) | |
3168 { | |
3169 curr_offset += strlen(curr_offset) + 1; | |
3170 } | |
3171 else | |
3172 { | |
3173 return NULL; | |
3174 } | |
3175 } | |
3176 for( i=0; curr_offset+i < end && | |
3177 (curr_offset[i] != delim || num_quotes != 0) | |
3178 ; i++ ) | |
3179 { | |
3180 if( curr_offset[i] == '\"' ) | |
3181 { | |
3182 num_quotes = (num_quotes+1)%2; | |
3183 } | |
3184 } | |
3185 curr_offset[i] = '\0'; | |
3186 return curr_offset; | |
3187 } | |
3188 | |
3189 | |
3190 void gtk_html_append_text(GtkHtml * html, char *text, gint options) | |
3191 { | |
3192 GdkColormap *map; | |
1 | 3193 GdkFont *cfont; |
12 | 3194 GdkRectangle area; |
829
9a123b171f46
[gaim-migrate @ 839]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
791
diff
changeset
|
3195 char *ws, |
1079
a4635c7c2128
[gaim-migrate @ 1089]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1057
diff
changeset
|
3196 *tag, |
12 | 3197 *c, |
3198 *url = NULL; | |
3199 gint intag = 0, | |
3200 wpos = 0, | |
481
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3201 tpos = 0; |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3202 static gint colorv, |
12 | 3203 bold = 0, |
3204 italic = 0, | |
3205 fixed = 0, | |
3206 uline = 0, | |
3207 strike = 0, | |
481
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3208 title = 0, |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3209 height; |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3210 static struct font_state *current = NULL, |
12 | 3211 *tmp; |
481
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3212 static struct font_state def_state = { 3, 0, 0, "", NULL, NULL, NULL }; |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3213 |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3214 if (text == NULL) { |
740
01d3c96867e2
[gaim-migrate @ 750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
737
diff
changeset
|
3215 bold = 0; |
01d3c96867e2
[gaim-migrate @ 750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
737
diff
changeset
|
3216 italic = 0; |
01d3c96867e2
[gaim-migrate @ 750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
737
diff
changeset
|
3217 fixed = 0; |
01d3c96867e2
[gaim-migrate @ 750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
737
diff
changeset
|
3218 uline = 0; |
01d3c96867e2
[gaim-migrate @ 750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
737
diff
changeset
|
3219 strike = 0; |
01d3c96867e2
[gaim-migrate @ 750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
737
diff
changeset
|
3220 title = 0; |
481
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3221 while (current->next) |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3222 { |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3223 if (current->ownbg) |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3224 g_free(current->bgcol); |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3225 if (current->owncolor) |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3226 g_free(current->color); |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3227 tmp = current; |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3228 current = current->next; |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3229 g_free(tmp); |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3230 } |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3231 return; |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3232 } |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3233 |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
3234 if (!current) current = &def_state; |
12 | 3235 map = gdk_window_get_colormap(html->html_area); |
3236 cfont = getfont(current->font, bold, italic, fixed, current->size); | |
1 | 3237 c = text; |
3238 | |
829
9a123b171f46
[gaim-migrate @ 839]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
791
diff
changeset
|
3239 ws = g_malloc(strlen(text) + 2); |
1079
a4635c7c2128
[gaim-migrate @ 1089]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1057
diff
changeset
|
3240 tag = g_malloc(strlen(text) + 2); |
1 | 3241 |
12 | 3242 while (*c) |
3243 { | |
3244 if (*c == '<') | |
3245 { | |
3246 if (!intag) | |
3247 { | |
3248 ws[wpos] = 0; | |
3249 if (wpos) | |
3250 { | |
3251 if (title) | |
3252 { | |
3253 if (html->title) | |
3254 g_free(html->title); | |
3255 html->title = g_strdup(ws); | |
3256 } | |
3257 else | |
3258 gtk_html_add_text(html, cfont, current->color, | |
3259 current->bgcol, ws, strlen(ws), uline, | |
3260 strike, url); | |
3261 } | |
3262 wpos = 0; | |
3263 intag = 1; | |
3264 } | |
3265 else | |
3266 { | |
3267 /* | |
3268 * Assuming you NEVER have nested tags | |
3269 * * (and I mean <tag <tag>> by this, not | |
3270 * * <tag><tag2></tag2><tag>.. | |
3271 */ | |
3272 tag[tpos] = 0; | |
3273 gtk_html_add_text(html, cfont, current->color, current->bgcol, | |
3274 "<", 1, 0, 0, NULL); | |
3275 gtk_html_add_text(html, cfont, current->color, current->bgcol, | |
3276 tag, strlen(tag), 0, 0, NULL); | |
1 | 3277 tpos = 0; |
12 | 3278 |
3279 tag[0] = *c; | |
1 | 3280 } |
12 | 3281 } |
3282 else if (*c == '>') | |
3283 { | |
3284 if (intag) | |
3285 { | |
3286 tag[tpos] = 0; | |
1 | 3287 if (!strcasecmp(tag, "B")) |
3288 bold = 1; | |
732 | 3289 else if (!strcasecmp(tag, "STRIKE") || !strcasecmp(tag, "S")) |
1 | 3290 strike = 1; |
3291 else if (!strcasecmp(tag, "I")) | |
3292 italic = 1; | |
3293 else if (!strcasecmp(tag, "U")) | |
3294 uline = 1; | |
3295 else if (!strcasecmp(tag, "PRE")) | |
3296 fixed = 1; | |
3297 else if (!strcasecmp(tag, "HR")) | |
914
215fe9039ae1
[gaim-migrate @ 924]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
911
diff
changeset
|
3298 gtk_html_add_seperator(html, cfont, current->color, current->bgcol); |
1 | 3299 else if (!strcasecmp(tag, "/B")) |
3300 bold = 0; | |
732 | 3301 else if (!strcasecmp(tag, "/STRIKE") || !strcasecmp(tag, "/S")) |
1 | 3302 strike = 0; |
3303 else if (!strcasecmp(tag, "/I")) | |
3304 italic = 0; | |
3305 else if (!strcasecmp(tag, "/U")) | |
3306 uline = 0; | |
3307 else if (!strcasecmp(tag, "/PRE")) | |
3308 fixed = 0; | |
3309 else if (!strcasecmp(tag, "TITLE")) | |
3310 title = 1; | |
3311 else if (!strcasecmp(tag, "/TITLE")) | |
3312 title = 0; | |
12 | 3313 else if (!strncasecmp(tag, "IMG", 3)) |
3314 { | |
549 | 3315 GdkPixmap *legend_i; |
3316 GdkBitmap *legend_m; | |
3317 | |
3318 if (strstr(tag, "SRC=\"aol_icon.gif\"") != NULL) | |
3319 { | |
3320 legend_i = gdk_pixmap_create_from_xpm_d(GTK_WIDGET(html)->window, &legend_m, NULL, aol_icon_xpm); | |
3321 gtk_html_add_pixmap(html, legend_i, 0, 0); | |
3322 } | |
3323 | |
3324 if (strstr(tag, "SRC=\"admin_icon.gif\"") != NULL) | |
3325 { | |
3326 legend_i = gdk_pixmap_create_from_xpm_d(GTK_WIDGET(html)->window, &legend_m, NULL, admin_icon_xpm); | |
3327 gtk_html_add_pixmap(html, legend_i, 0, 0); | |
3328 } | |
3329 if (strstr(tag, "SRC=\"dt_icon.gif\"") != NULL) | |
3330 { | |
3331 legend_i = gdk_pixmap_create_from_xpm_d(GTK_WIDGET(html)->window, &legend_m, NULL, dt_icon_xpm); | |
3332 gtk_html_add_pixmap(html, legend_i, 0, 0); | |
3333 } | |
3334 if (strstr(tag, "SRC=\"free_icon.gif\"") != NULL) | |
3335 { | |
3336 legend_i = gdk_pixmap_create_from_xpm_d(GTK_WIDGET(html)->window, &legend_m, NULL, free_icon_xpm); | |
3337 gtk_html_add_pixmap(html, legend_i, 0, 0); | |
3338 } | |
12 | 3339 } |
3340 else if (!strcasecmp(tag, "H3")) | |
3341 { | |
1 | 3342 current = push_state(current); |
3343 current->size = 4; | |
12 | 3344 } |
3345 else if (!strcasecmp(tag, "/H3")) | |
3346 { | |
3347 gtk_html_add_text(html, cfont, current->color, | |
3348 current->bgcol, "\n", 1, 0, 0, NULL); | |
3349 | |
3350 if (current->next) | |
3351 { | |
1 | 3352 if (current->ownbg) |
3353 g_free(current->bgcol); | |
3354 if (current->owncolor) | |
3355 g_free(current->color); | |
12 | 3356 tmp = current; |
3357 current = current->next; | |
3358 g_free(tmp); | |
1 | 3359 } |
12 | 3360 } |
3361 else if (!strcasecmp(tag, "TABLE")) | |
3362 { | |
3363 } | |
3364 else if (!strcasecmp(tag, "/TABLE")) | |
3365 { | |
3366 } | |
3367 else if (!strcasecmp(tag, "TR")) | |
3368 { | |
3369 } | |
3370 else if (!strcasecmp(tag, "/TR")) | |
3371 { | |
3372 } | |
3373 else if (!strcasecmp(tag, "/TD")) | |
3374 { | |
3375 } | |
3376 else if (!strcasecmp(tag, "TD")) | |
3377 { | |
3378 gtk_html_add_text(html, cfont, current->color, | |
3379 current->bgcol, " ", 2, 0, 0, NULL); | |
3380 } | |
3381 else if (!strncasecmp(tag, "A ", 2)) | |
3382 { | |
1 | 3383 char *d; |
3384 char *temp = d = g_strdup(tag); | |
3385 int flag = 0; | |
12 | 3386 strtok(tag, " "); |
3387 while ((d = strtok(NULL, " "))) | |
3388 { | |
1 | 3389 if (strlen(d) < 7) |
3390 break; | |
12 | 3391 if (!strncasecmp(d, "HREF=\"", strlen("HREF=\""))) |
3392 { | |
3393 d += strlen("HREF=\""); | |
1 | 3394 d[strlen(d) - 1] = 0; |
3395 url = g_malloc(strlen(d) + 1); | |
3396 strcpy(url, d); | |
3397 flag = 1; | |
12 | 3398 } |
3399 } | |
1 | 3400 g_free(temp); |
12 | 3401 if (!flag) |
3402 { | |
3403 gtk_html_add_text(html, cfont, current->color, | |
3404 current->bgcol, "<", 1, 0, 0, NULL); | |
3405 gtk_html_add_text(html, cfont, current->color, | |
3406 current->bgcol, tag, strlen(tag), 0, | |
3407 0, NULL); | |
3408 gtk_html_add_text(html, cfont, current->color, | |
3409 current->bgcol, ">", 1, 0, 0, NULL); | |
1 | 3410 } |
12 | 3411 } |
3412 else if (!strcasecmp(tag, "/A")) | |
3413 { | |
3414 if (url) | |
3415 { | |
1 | 3416 g_free(url); |
3417 url = NULL; | |
3418 } | |
12 | 3419 } |
3420 else if (!strncasecmp(tag, "FONT", strlen("FONT"))) | |
3421 { | |
3422 char *d; | |
3423 /* | |
3424 * Push a new state onto the stack, based on the old state | |
3425 */ | |
3426 current = push_state(current); | |
3427 html_strtok(tag, ' '); | |
3428 while ((d = html_strtok(NULL, ' '))) | |
3429 { | |
1106
5bc8fdacd2cb
[gaim-migrate @ 1116]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1079
diff
changeset
|
3430 if (!strncasecmp(d, "style=", strlen("style="))) |
5bc8fdacd2cb
[gaim-migrate @ 1116]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1079
diff
changeset
|
3431 { |
5bc8fdacd2cb
[gaim-migrate @ 1116]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1079
diff
changeset
|
3432 d += strlen("style="); |
5bc8fdacd2cb
[gaim-migrate @ 1116]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1079
diff
changeset
|
3433 if (*d == '\"') { |
5bc8fdacd2cb
[gaim-migrate @ 1116]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1079
diff
changeset
|
3434 d++; |
5bc8fdacd2cb
[gaim-migrate @ 1116]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1079
diff
changeset
|
3435 while (*d != '\0' && *d != '\"') d++; |
5bc8fdacd2cb
[gaim-migrate @ 1116]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1079
diff
changeset
|
3436 if (*d == '\0') |
5bc8fdacd2cb
[gaim-migrate @ 1116]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1079
diff
changeset
|
3437 html_strtok(tag, ' '); |
5bc8fdacd2cb
[gaim-migrate @ 1116]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1079
diff
changeset
|
3438 } |
5bc8fdacd2cb
[gaim-migrate @ 1116]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1079
diff
changeset
|
3439 } |
12 | 3440 if (!strncasecmp(d, "COLOR=", strlen("COLOR="))) |
3441 { | |
3442 d += strlen("COLOR="); | |
3443 if (*d == '\"') | |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3444 { |
12 | 3445 d++; |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3446 } |
12 | 3447 if (*d == '#') |
3448 d++; | |
3449 if (d[strlen(d) - 1] == '\"') | |
3450 d[strlen(d) - 1] = 0; | |
3451 if (sscanf(d, "%x", &colorv) | |
3452 && !(options & HTML_OPTION_NO_COLOURS)) | |
3453 { | |
677
05f6f7dabb7e
[gaim-migrate @ 687]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
674
diff
changeset
|
3454 current->color = get_color(colorv, map); |
05f6f7dabb7e
[gaim-migrate @ 687]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
674
diff
changeset
|
3455 current->owncolor = 1; |
12 | 3456 } |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3457 else |
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3458 { |
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3459 } |
12 | 3460 } |
3461 if (!strncasecmp(d, "FACE=", strlen("FACE="))) | |
3462 { | |
3463 d += strlen("FACE="); | |
3464 if (*d == '\"') | |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3465 { |
12 | 3466 d++; |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3467 } |
1 | 3468 if (d[strlen(d) - 1] == '\"') |
3469 d[strlen(d) - 1] = 0; | |
12 | 3470 strcpy(current->font, d); |
3471 } | |
3472 else if (!strncasecmp(d, "BACK=", strlen("BACK="))) | |
3473 { | |
3474 d += strlen("BACK="); | |
3475 if (*d == '\"') | |
3476 d++; | |
3477 if (*d == '#') | |
3478 d++; | |
3479 if (d[strlen(d) - 1] == '\"') | |
3480 d[strlen(d) - 1] = 0; | |
3481 if (sscanf(d, "%x", &colorv) | |
3482 && !(options & HTML_OPTION_NO_COLOURS)) | |
3483 { | |
1 | 3484 current->bgcol = get_color(colorv, map); |
3485 current->ownbg = 1; | |
12 | 3486 } |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3487 else |
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3488 { |
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3489 } |
12 | 3490 } |
3491 else if (!strncasecmp(d, "SIZE=", strlen("SIZE="))) | |
3492 { | |
3493 d += strlen("SIZE="); | |
3494 if (*d == '\"') | |
3495 d++; | |
3496 if (*d == '+') | |
3497 d++; | |
3498 if (sscanf(d, "%d", &colorv)) | |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3499 { |
12 | 3500 current->size = colorv; |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3501 } |
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3502 else |
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3503 { |
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3504 } |
12 | 3505 } |
3506 else if (strncasecmp(d, "PTSIZE=", strlen("PTSIZE="))) | |
3507 { | |
3508 } | |
1 | 3509 } |
12 | 3510 } |
669
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3511 else if (!strncasecmp(tag, "BODY", strlen("BODY"))) |
12 | 3512 { |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
3513 |
669
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3514 char *d; |
632
21c63b26c604
[gaim-migrate @ 642]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
629
diff
changeset
|
3515 current = push_state(current); |
669
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3516 html_strtok(tag, ' '); |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3517 while ((d = html_strtok(NULL, ' '))) |
12 | 3518 { |
669
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3519 if (!strncasecmp(d, "BGCOLOR=", strlen("BGCOLOR="))) |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3520 { |
677
05f6f7dabb7e
[gaim-migrate @ 687]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
674
diff
changeset
|
3521 d += strlen("BGCOLOR="); |
669
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3522 if (*d == '\"') |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3523 d++; |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3524 if (*d == '#') |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3525 d++; |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3526 if (d[strlen(d) - 1] == '\"') |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3527 d[strlen(d) - 1] = 0; |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3528 if (sscanf(d, "%x", &colorv) |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3529 && !(options & HTML_OPTION_NO_COLOURS)) |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3530 { |
677
05f6f7dabb7e
[gaim-migrate @ 687]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
674
diff
changeset
|
3531 if (colorv != 0xffffff || |
669
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3532 !(display_options & OPT_DISP_IGN_WHITE)) { |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3533 current->bgcol = get_color(colorv, map); |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3534 current->ownbg = 1; |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3535 } |
e871081839d0
[gaim-migrate @ 679]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
667
diff
changeset
|
3536 } |
667
45ed2ca0756e
[gaim-migrate @ 677]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
666
diff
changeset
|
3537 } |
12 | 3538 } |
3539 } | |
3540 else if (!strncasecmp(tag, "/FONT", strlen("/FONT"))) | |
3541 { | |
3542 /* | |
3543 * Pop a font state off the list if possible, freeing | |
3544 * any resources it used | |
3545 */ | |
3546 if (current->next) | |
3547 { | |
1 | 3548 if (current->ownbg) |
3549 g_free(current->bgcol); | |
3550 if (current->owncolor) | |
3551 g_free(current->color); | |
12 | 3552 tmp = current; |
3553 current = current->next; | |
3554 g_free(tmp); | |
3555 } | |
3556 | |
3557 } | |
3558 else if (!strcasecmp(tag, "/BODY")) | |
3559 { | |
3560 if (current->next) | |
3561 { | |
3562 if (current->ownbg) | |
3563 g_free(current->bgcol); | |
3564 if (current->owncolor) | |
3565 g_free(current->color); | |
3566 tmp = current; | |
3567 current = current->next; | |
1 | 3568 g_free(tmp); |
12 | 3569 } /* |
3570 * tags we ignore below | |
3571 */ | |
3572 } | |
3573 else if (!strncasecmp(tag, "BR", 2)) | |
3574 { | |
3575 gtk_html_add_text(html, cfont, current->color, | |
3576 current->bgcol, "\n", 1, 0, 0, NULL); | |
3577 } | |
3578 else if (strncasecmp(tag, "HTML", 4) | |
3579 && strncasecmp(tag, "/HTML", 5) | |
3580 && strncasecmp(tag, "BODY", 4) | |
3581 && strncasecmp(tag, "/BODY", 5) | |
627
da0a1238874d
[gaim-migrate @ 637]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
604
diff
changeset
|
3582 && (strncasecmp(tag, "P", 1) || tag[1] != '>') |
da0a1238874d
[gaim-migrate @ 637]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
604
diff
changeset
|
3583 && (strncasecmp(tag, "/P", 2) || tag[3] != '>') |
12 | 3584 && strncasecmp(tag, "HEAD", 4) |
3585 && strncasecmp(tag, "/HEAD", 5)) | |
3586 { | |
3587 if (tpos) | |
3588 { | |
3589 gtk_html_add_text(html, cfont, current->color, | |
3590 current->bgcol, "<", 1, 0, 0, NULL); | |
3591 gtk_html_add_text(html, cfont, current->color, | |
3592 current->bgcol, tag, strlen(tag), 0, | |
3593 0, NULL); | |
3594 gtk_html_add_text(html, cfont, current->color, | |
3595 current->bgcol, ">", 1, 0, 0, NULL); | |
1 | 3596 |
3597 } | |
3598 } | |
12 | 3599 cfont = getfont(current->font, bold, italic, fixed, current->size); |
3600 tpos = 0; | |
1 | 3601 intag = 0; |
3602 } | |
12 | 3603 else |
3604 { | |
1 | 3605 ws[wpos++] = *c; |
3606 } | |
12 | 3607 } |
3608 else if (!intag && *c == '&') | |
3609 { | |
3610 if (!strncasecmp(c, "&", 5)) | |
3611 { | |
3612 ws[wpos++] = '&'; | |
3613 c += 4; | |
3614 } | |
3615 else if (!strncasecmp(c, "<", 4)) | |
3616 { | |
3617 ws[wpos++] = '<'; | |
3618 c += 3; | |
3619 } | |
3620 else if (!strncasecmp(c, ">", 4)) | |
3621 { | |
3622 ws[wpos++] = '>'; | |
3623 c += 3; | |
3624 } | |
3625 else if (!strncasecmp(c, " ", 6)) | |
3626 { | |
3627 ws[wpos++] = ' '; | |
3628 c += 5; | |
3629 } | |
526
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3630 else if (!strncasecmp(c, "©", 6)) |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3631 { |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3632 ws[wpos++] = '©'; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3633 c += 5; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3634 } |
737
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3635 else if (!strncasecmp(c, """, 6)) |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3636 { |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3637 ws[wpos++] = '\"'; |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3638 c += 5; |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3639 } |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3640 else if (!strncasecmp(c, "®", 5)) |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3641 { |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3642 ws[wpos++] = 174; |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3643 c += 4; |
c3a920cee3fc
[gaim-migrate @ 747]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
732
diff
changeset
|
3644 } |
526
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3645 else if (*(c + 1) == '#') |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3646 { |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3647 int pound = 0; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3648 debug_print("got &#;\n"); |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3649 if (sscanf(c, "&#%d;", £) > 0) { |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3650 ws[wpos++] = (char)pound; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3651 c += 2; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3652 while (isdigit(*c)) c++; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3653 if (*c != ';') c--; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3654 } else { |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3655 ws[wpos++] = *c; |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3656 } |
5bf71b39cba2
[gaim-migrate @ 536]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
523
diff
changeset
|
3657 } |
12 | 3658 else |
3659 { | |
3660 ws[wpos++] = *c; | |
3661 } | |
3662 } | |
3663 else | |
3664 { | |
3665 if (intag) | |
3666 { | |
3667 tag[tpos++] = *c; | |
3668 } | |
3669 else | |
3670 { | |
3671 ws[wpos++] = *c; | |
1 | 3672 } |
3673 } | |
3674 c++; | |
3675 } | |
12 | 3676 ws[wpos] = 0; |
3677 tag[tpos] = 0; | |
3678 if (wpos) | |
3679 { | |
3680 gtk_html_add_text(html, cfont, current->color, current->bgcol, ws, | |
3681 strlen(ws), uline, strike, url); | |
1 | 3682 } |
12 | 3683 if (tpos) |
3684 { | |
3685 gtk_html_add_text(html, cfont, current->color, current->bgcol, "<", 1, | |
3686 0, 0, NULL); | |
3687 gtk_html_add_text(html, cfont, current->color, current->bgcol, tag, | |
3688 strlen(tag), 0, 0, NULL); | |
523
023c3851db0a
[gaim-migrate @ 533]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
506
diff
changeset
|
3689 /* gtk_html_add_text(html, cfont, current->color, current->bgcol, ">", 1, |
12 | 3690 0, 0, NULL); |
523
023c3851db0a
[gaim-migrate @ 533]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
506
diff
changeset
|
3691 */ } |
12 | 3692 |
3693 | |
829
9a123b171f46
[gaim-migrate @ 839]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
791
diff
changeset
|
3694 g_free(ws); |
1079
a4635c7c2128
[gaim-migrate @ 1089]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1057
diff
changeset
|
3695 g_free(tag); |
12 | 3696 |
3697 gdk_window_get_size(html->html_area, NULL, &height); | |
3698 area.height = height; | |
1 | 3699 gtk_adjustment_set_value(html->vadj, html->vadj->upper - area.height); |
3700 | |
12 | 3701 return; |
1 | 3702 } |
3703 | |
3704 | |
12 | 3705 static void adjust_adj(GtkHtml * html, GtkAdjustment * adj) |
1 | 3706 { |
12 | 3707 gint height; |
3708 | |
3709 gdk_window_get_size(html->html_area, NULL, &height); | |
3710 | |
3711 adj->step_increment = MIN(adj->upper, (float) SCROLL_PIXELS); | |
3712 adj->page_increment = MIN(adj->upper, height - (float) KEY_SCROLL_PIXELS); | |
3713 adj->page_size = MIN(adj->upper, height); | |
3714 adj->value = MIN(adj->value, adj->upper - adj->page_size); | |
3715 adj->value = MAX(adj->value, 0.0); | |
3716 | |
3717 gtk_signal_emit_by_name(GTK_OBJECT(adj), "changed"); | |
1 | 3718 } |
3719 | |
3720 | |
12 | 3721 static void scroll_down(GtkHtml * html, gint diff0) |
1 | 3722 { |
12 | 3723 GdkRectangle rect; |
3724 gint width, | |
3725 height; | |
3726 | |
3727 html->yoffset += diff0; | |
3728 | |
3729 gdk_window_get_size(html->html_area, &width, &height); | |
3730 | |
3731 if (html->transparent) | |
3732 { | |
1 | 3733 rect.x = 0; |
3734 rect.y = 0; | |
3735 rect.width = width; | |
3736 rect.height = height; | |
12 | 3737 } |
3738 else | |
3739 { | |
3740 | |
1 | 3741 |
3742 if (height > diff0 && !html->transparent) | |
12 | 3743 gdk_draw_pixmap(html->html_area, |
3744 html->gc, | |
3745 html->html_area, | |
3746 0, diff0, 0, 0, width, height - diff0); | |
3747 | |
3748 rect.x = 0; | |
3749 rect.y = MAX(0, height - diff0); | |
3750 rect.width = width; | |
3751 rect.height = MIN(height, diff0); | |
1 | 3752 } |
12 | 3753 |
3754 expose_html(html, &rect, FALSE); | |
3755 gtk_html_draw_focus((GtkWidget *) html); | |
1 | 3756 |
3757 } | |
3758 | |
12 | 3759 static void scroll_up(GtkHtml * html, gint diff0) |
1 | 3760 { |
12 | 3761 GdkRectangle rect; |
3762 gint width, | |
3763 height; | |
3764 | |
1 | 3765 html->yoffset -= diff0; |
3766 | |
3767 | |
12 | 3768 gdk_window_get_size(html->html_area, &width, &height); |
3769 | |
3770 if (html->transparent) | |
3771 { | |
1 | 3772 rect.x = 0; |
3773 rect.y = 0; | |
3774 rect.width = width; | |
3775 rect.height = height; | |
12 | 3776 } |
3777 else | |
3778 { | |
3779 | |
1 | 3780 if (height > diff0) |
12 | 3781 gdk_draw_pixmap(html->html_area, |
3782 html->gc, | |
3783 html->html_area, | |
3784 0, 0, 0, diff0, width, height - diff0); | |
3785 | |
3786 rect.x = 0; | |
3787 rect.y = 0; | |
3788 rect.width = width; | |
3789 rect.height = MIN(height, diff0); | |
1 | 3790 } |
3791 | |
12 | 3792 expose_html(html, &rect, FALSE); |
3793 gtk_html_draw_focus((GtkWidget *) html); | |
1 | 3794 |
3795 } | |
3796 | |
3797 | |
3798 | |
12 | 3799 static void gtk_html_adjustment(GtkAdjustment * adjustment, GtkHtml * html) |
1 | 3800 { |
12 | 3801 g_return_if_fail(adjustment != NULL); |
3802 g_return_if_fail(GTK_IS_ADJUSTMENT(adjustment)); | |
3803 g_return_if_fail(html != NULL); | |
3804 g_return_if_fail(GTK_IS_HTML(html)); | |
3805 | |
3806 /* | |
3807 * Just ignore it if we haven't been size-allocated and realized yet | |
3808 */ | |
3809 if (html->html_area == NULL) | |
3810 return; | |
3811 | |
3812 if (adjustment == html->hadj) | |
3813 { | |
3814 g_warning("horizontal scrolling not implemented"); | |
3815 } | |
3816 else | |
3817 { | |
3818 gint diff = ((gint) adjustment->value) - html->last_ver_value; | |
3819 | |
3820 if (diff != 0) | |
3821 { | |
3822 /* | |
3823 * undraw_cursor (text, FALSE); | |
3824 */ | |
3825 | |
3826 if (diff > 0) | |
3827 { | |
3828 scroll_down(html, diff); | |
3829 } | |
3830 else | |
3831 { /* | |
3832 * if (diff < 0) | |
3833 */ | |
3834 scroll_up(html, -diff); | |
3835 } | |
3836 /* | |
3837 * draw_cursor (text, FALSE); | |
3838 */ | |
3839 | |
3840 html->last_ver_value = adjustment->value; | |
3841 } | |
3842 } | |
1 | 3843 } |
12 | 3844 |
3845 static gint gtk_html_visibility_notify(GtkWidget * widget, | |
3846 GdkEventVisibility * event) | |
1 | 3847 { |
3848 GtkHtml *html; | |
3849 GdkRectangle rect; | |
12 | 3850 gint width, |
3851 height; | |
3852 | |
3853 g_return_val_if_fail(widget != NULL, FALSE); | |
3854 g_return_val_if_fail(GTK_IS_HTML(widget), FALSE); | |
3855 | |
3856 html = GTK_HTML(widget); | |
3857 | |
3858 if (GTK_WIDGET_REALIZED(widget) && html->transparent) | |
3859 { | |
3860 gdk_window_get_size(html->html_area, &width, &height); | |
3861 rect.x = 0; | |
3862 rect.y = 0; | |
3863 rect.width = width; | |
3864 rect.height = height; | |
3865 expose_html(html, &rect, FALSE); | |
3866 gtk_html_draw_focus((GtkWidget *) html); | |
3867 } | |
3868 else | |
3869 { | |
1 | 3870 } |
3871 | |
3872 | |
12 | 3873 return FALSE; |
1 | 3874 } |
3875 | |
3876 | |
3877 | |
12 | 3878 static void gtk_html_disconnect(GtkAdjustment * adjustment, GtkHtml * html) |
1 | 3879 { |
12 | 3880 g_return_if_fail(adjustment != NULL); |
3881 g_return_if_fail(GTK_IS_ADJUSTMENT(adjustment)); | |
3882 g_return_if_fail(html != NULL); | |
3883 g_return_if_fail(GTK_IS_HTML(html)); | |
3884 | |
3885 if (adjustment == html->hadj) | |
3886 gtk_html_set_adjustments(html, NULL, html->vadj); | |
3887 if (adjustment == html->vadj) | |
3888 gtk_html_set_adjustments(html, html->hadj, NULL); | |
1 | 3889 } |
3890 | |
12 | 3891 static void move_cursor_ver(GtkHtml * html, int count) |
1 | 3892 { |
3893 GList *hbits = g_list_find(html->html_bits, html->cursor_hb); | |
12 | 3894 GtkHtmlBit *hb = NULL, |
3895 *hb2 = NULL; | |
1 | 3896 gint y; |
79 | 3897 size_t len, |
12 | 3898 len2 = 0; |
3899 | |
1 | 3900 undraw_cursor(html); |
3901 | |
3902 if (!html->html_bits) | |
3903 return; | |
12 | 3904 |
1 | 3905 if (!html->cursor_hb) |
12 | 3906 html->cursor_hb = (GtkHtmlBit *) html->html_bits->data; |
1 | 3907 |
3908 hb = html->cursor_hb; | |
3909 | |
3910 len = html->cursor_pos; | |
3911 hbits = hbits->prev; | |
12 | 3912 while (hbits) |
3913 { | |
3914 hb2 = (GtkHtmlBit *) hbits->data; | |
1 | 3915 |
3916 if (hb2->y != hb->y) | |
3917 break; | |
3918 | |
12 | 3919 len += strlen(hb2->text); |
3920 | |
1 | 3921 hbits = hbits->prev; |
3922 } | |
3923 | |
12 | 3924 hbits = g_list_find(html->html_bits, html->cursor_hb); |
3925 | |
3926 if (count < 0) | |
3927 { | |
3928 while (hbits) | |
3929 { | |
3930 hb2 = (GtkHtmlBit *) hbits->data; | |
1 | 3931 |
3932 if (hb2->y != hb->y) | |
3933 break; | |
12 | 3934 |
1 | 3935 hbits = hbits->prev; |
3936 } | |
12 | 3937 if (!hbits) |
3938 { | |
1 | 3939 draw_cursor(html); |
3940 return; | |
3941 } | |
3942 y = hb2->y; | |
3943 hb = hb2; | |
12 | 3944 while (hbits) |
3945 { | |
3946 hb2 = (GtkHtmlBit *) hbits->data; | |
1 | 3947 |
3948 if (hb2->y != y) | |
3949 break; | |
3950 | |
3951 hb = hb2; | |
12 | 3952 |
1 | 3953 hbits = hbits->prev; |
3954 } | |
3955 hbits = g_list_find(html->html_bits, hb); | |
12 | 3956 while (hbits) |
3957 { | |
3958 hb2 = (GtkHtmlBit *) hbits->data; | |
3959 | |
3960 if (hb->y != hb2->y) | |
3961 { | |
1 | 3962 html->cursor_hb = hb; |
3963 html->cursor_pos = strlen(hb->text); | |
12 | 3964 break; |
1 | 3965 } |
3966 | |
3967 | |
12 | 3968 if (len < len2 + strlen(hb2->text)) |
3969 { | |
1 | 3970 html->cursor_hb = hb2; |
3971 html->cursor_pos = len - len2; | |
3972 break; | |
3973 } | |
3974 | |
3975 len2 += strlen(hb2->text); | |
3976 | |
3977 hb = hb2; | |
3978 | |
12 | 3979 hbits = hbits->next; |
1 | 3980 } |
12 | 3981 } |
3982 else | |
3983 { | |
3984 while (hbits) | |
3985 { | |
3986 hb2 = (GtkHtmlBit *) hbits->data; | |
1 | 3987 |
3988 if (hb2->y != hb->y) | |
3989 break; | |
12 | 3990 |
1 | 3991 hbits = hbits->next; |
3992 } | |
12 | 3993 if (!hbits) |
3994 { | |
1 | 3995 draw_cursor(html); |
3996 return; | |
3997 } | |
3998 hb = hb2; | |
12 | 3999 while (hbits) |
4000 { | |
4001 hb2 = (GtkHtmlBit *) hbits->data; | |
4002 | |
4003 if (hb->y != hb2->y) | |
4004 { | |
1 | 4005 html->cursor_hb = hb; |
4006 html->cursor_pos = strlen(hb->text); | |
12 | 4007 break; |
1 | 4008 } |
4009 | |
4010 | |
12 | 4011 if (len < len2 + strlen(hb2->text)) |
4012 { | |
1 | 4013 html->cursor_hb = hb2; |
4014 html->cursor_pos = len - len2; | |
4015 break; | |
4016 } | |
4017 | |
4018 len2 += strlen(hb2->text); | |
4019 | |
4020 hb = hb2; | |
4021 | |
12 | 4022 hbits = hbits->next; |
1 | 4023 } |
4024 } | |
4025 | |
4026 draw_cursor(html); | |
4027 | |
4028 } | |
4029 | |
12 | 4030 static void move_cursor_hor(GtkHtml * html, int count) |
1 | 4031 { |
4032 GList *hbits = g_list_find(html->html_bits, html->cursor_hb); | |
12 | 4033 GtkHtmlBit *hb, |
4034 *hb2; | |
1 | 4035 |
4036 undraw_cursor(html); | |
4037 | |
4038 if (!html->html_bits) | |
4039 return; | |
12 | 4040 |
1 | 4041 if (!html->cursor_hb) |
12 | 4042 html->cursor_hb = (GtkHtmlBit *) html->html_bits->data; |
4043 | |
4044 html->cursor_pos += count; | |
4045 | |
4046 if (html->cursor_pos < 0) | |
4047 { | |
4048 if (hbits->prev) | |
4049 { | |
1 | 4050 gint diff; |
4051 hb = html->cursor_hb; | |
12 | 4052 hb2 = (GtkHtmlBit *) hbits->prev->data; |
1 | 4053 diff = html->cursor_pos + strlen(hb2->text) + 1; |
4054 if (hb->y == hb2->y) | |
4055 --diff; | |
12 | 4056 |
1 | 4057 html->cursor_pos = diff; |
12 | 4058 |
4059 html->cursor_hb = (GtkHtmlBit *) hbits->prev->data; | |
4060 } | |
4061 else | |
4062 { | |
1 | 4063 html->cursor_pos = 0; |
4064 } | |
12 | 4065 } |
79 | 4066 else if ((unsigned) html->cursor_pos > strlen(html->cursor_hb->text)) |
12 | 4067 { |
4068 if (hbits->next) | |
4069 { | |
1 | 4070 gint diff; |
4071 hb = html->cursor_hb; | |
12 | 4072 hb2 = (GtkHtmlBit *) hbits->next->data; |
1 | 4073 |
4074 diff = html->cursor_pos - strlen(html->cursor_hb->text) - 1; | |
4075 if (hb->y == hb2->y) | |
12 | 4076 ++diff; |
1 | 4077 html->cursor_pos = diff; |
12 | 4078 html->cursor_hb = (GtkHtmlBit *) hbits->next->data; |
4079 } | |
4080 else | |
4081 { | |
1 | 4082 html->cursor_pos = strlen(html->cursor_hb->text); |
4083 } | |
4084 | |
4085 } | |
4086 | |
4087 draw_cursor(html); | |
4088 } | |
4089 | |
12 | 4090 static void move_beginning_of_line(GtkHtml * html) |
1 | 4091 { |
4092 GList *hbits = g_list_find(html->html_bits, html->cursor_hb); | |
4093 GtkHtmlBit *hb = NULL; | |
12 | 4094 gint y; |
4095 | |
1 | 4096 undraw_cursor(html); |
4097 | |
4098 if (!html->html_bits) | |
4099 return; | |
4100 | |
4101 if (!html->cursor_hb) | |
12 | 4102 html->cursor_hb = (GtkHtmlBit *) html->html_bits->data; |
1 | 4103 |
4104 y = html->cursor_hb->y; | |
12 | 4105 |
4106 while (hbits) | |
4107 { | |
4108 hb = (GtkHtmlBit *) hbits->data; | |
4109 | |
4110 if (y != hb->y) | |
4111 { | |
4112 hb = (GtkHtmlBit *) hbits->next->data; | |
1 | 4113 break; |
4114 } | |
12 | 4115 |
1 | 4116 hbits = hbits->prev; |
4117 } | |
4118 if (!hbits) | |
12 | 4119 html->cursor_hb = (GtkHtmlBit *) html->html_bits->data; |
1 | 4120 else |
4121 html->cursor_hb = hb; | |
4122 | |
4123 html->cursor_pos = 0; | |
4124 | |
4125 | |
4126 draw_cursor(html); | |
4127 | |
4128 | |
4129 } | |
4130 | |
12 | 4131 static void move_end_of_line(GtkHtml * html) |
1 | 4132 { |
4133 GList *hbits = g_list_find(html->html_bits, html->cursor_hb); | |
4134 GtkHtmlBit *hb = NULL; | |
12 | 4135 gint y; |
4136 | |
1 | 4137 undraw_cursor(html); |
4138 | |
4139 if (!html->html_bits) | |
4140 return; | |
4141 | |
4142 if (!html->cursor_hb) | |
12 | 4143 html->cursor_hb = (GtkHtmlBit *) html->html_bits->data; |
1 | 4144 |
4145 y = html->cursor_hb->y; | |
12 | 4146 |
4147 while (hbits) | |
4148 { | |
4149 hb = (GtkHtmlBit *) hbits->data; | |
4150 | |
4151 if (y != hb->y) | |
4152 { | |
4153 hb = (GtkHtmlBit *) hbits->prev->data; | |
1 | 4154 break; |
4155 } | |
12 | 4156 |
1 | 4157 hbits = hbits->next; |
4158 } | |
4159 if (!hbits) | |
12 | 4160 html->cursor_hb = (GtkHtmlBit *) g_list_last(html->html_bits)->data; |
1 | 4161 else |
4162 html->cursor_hb = hb; | |
4163 | |
4164 html->cursor_pos = strlen(html->cursor_hb->text); | |
4165 | |
4166 | |
4167 draw_cursor(html); | |
4168 | |
4169 | |
4170 } | |
4171 | |
4172 | |
4173 | |
12 | 4174 static gint gtk_html_key_press(GtkWidget * widget, GdkEventKey * event) |
1 | 4175 { |
4176 GtkHtml *html; | |
4177 gchar key; | |
4178 gint return_val; | |
12 | 4179 |
4180 g_return_val_if_fail(widget != NULL, FALSE); | |
4181 g_return_val_if_fail(GTK_IS_HTML(widget), FALSE); | |
4182 g_return_val_if_fail(event != NULL, FALSE); | |
4183 | |
1 | 4184 return_val = FALSE; |
12 | 4185 |
4186 html = GTK_HTML(widget); | |
4187 | |
1 | 4188 key = event->keyval; |
4189 return_val = TRUE; | |
4190 | |
4191 | |
12 | 4192 if (html->editable == FALSE) |
4193 { | |
4194 /* | |
4195 * switch (event->keyval) { | |
4196 * case GDK_Home: | |
4197 * if (event->state & GDK_CONTROL_MASK) | |
4198 * scroll_int (text, -text->vadj->value); | |
4199 * else | |
4200 * return_val = FALSE; | |
4201 * break; | |
4202 * case GDK_End: | |
4203 * if (event->state & GDK_CONTROL_MASK) | |
4204 * scroll_int (text, +text->vadj->upper); | |
4205 * else | |
4206 * return_val = FALSE; | |
4207 * break; | |
4208 * case GDK_Page_Up: scroll_int (text, -text->vadj->page_increment); break; | |
4209 * case GDK_Page_Down: scroll_int (text, +text->vadj->page_increment); break; | |
4210 * case GDK_Up: scroll_int (text, -KEY_SCROLL_PIXELS); break; | |
4211 * case GDK_Down: scroll_int (text, +KEY_SCROLL_PIXELS); break; | |
4212 * case GDK_Return: | |
4213 * if (event->state & GDK_CONTROL_MASK) | |
4214 * gtk_signal_emit_by_name (GTK_OBJECT (text), "activate"); | |
4215 * else | |
4216 * return_val = FALSE; | |
4217 * break; | |
4218 * default: | |
4219 * return_val = FALSE; | |
4220 * break; | |
4221 * } | |
4222 */ | |
4223 } | |
4224 else | |
4225 { | |
4226 | |
4227 switch (event->keyval) | |
4228 { | |
1 | 4229 case GDK_Home: |
12 | 4230 move_beginning_of_line(html); |
1 | 4231 break; |
4232 case GDK_End: | |
12 | 4233 move_end_of_line(html); |
1 | 4234 break; |
4235 /* | |
12 | 4236 * case GDK_Page_Up: |
4237 * move_cursor_page_ver (html, -1); | |
4238 * break; | |
4239 * case GDK_Page_Down: | |
4240 * move_cursor_page_ver (html, +1); | |
4241 * break; | |
4242 */ | |
4243 /* | |
4244 * CUA has Ctrl-Up/Ctrl-Down as paragraph up down | |
4245 */ | |
1 | 4246 case GDK_Up: |
12 | 4247 move_cursor_ver(html, -1); |
1 | 4248 break; |
4249 case GDK_Down: | |
12 | 4250 move_cursor_ver(html, +1); |
1 | 4251 break; |
4252 case GDK_Left: | |
12 | 4253 move_cursor_hor(html, -1); |
1 | 4254 break; |
4255 case GDK_Right: | |
12 | 4256 move_cursor_hor(html, +1); |
1 | 4257 break; |
4258 #if 0 | |
4259 case GDK_BackSpace: | |
4260 if (event->state & GDK_CONTROL_MASK) | |
12 | 4261 gtk_text_delete_backward_word(text); |
1 | 4262 else |
12 | 4263 gtk_text_delete_backward_character(text); |
1 | 4264 break; |
4265 case GDK_Clear: | |
12 | 4266 gtk_text_delete_line(text); |
1 | 4267 break; |
4268 case GDK_Insert: | |
4269 if (event->state & GDK_SHIFT_MASK) | |
4270 { | |
4271 extend_selection = FALSE; | |
12 | 4272 gtk_editable_paste_clipboard(editable); |
1 | 4273 } |
4274 else if (event->state & GDK_CONTROL_MASK) | |
4275 { | |
12 | 4276 gtk_editable_copy_clipboard(editable); |
1 | 4277 } |
4278 else | |
4279 { | |
12 | 4280 /* |
4281 * gtk_toggle_insert(text) -- IMPLEMENT | |
4282 */ | |
1 | 4283 } |
4284 break; | |
4285 case GDK_Delete: | |
4286 if (event->state & GDK_CONTROL_MASK) | |
12 | 4287 gtk_text_delete_forward_word(text); |
1 | 4288 else if (event->state & GDK_SHIFT_MASK) |
4289 { | |
4290 extend_selection = FALSE; | |
12 | 4291 gtk_editable_cut_clipboard(editable); |
1 | 4292 } |
4293 else | |
12 | 4294 gtk_text_delete_forward_character(text); |
1 | 4295 break; |
4296 case GDK_Tab: | |
4297 position = text->point.index; | |
12 | 4298 gtk_editable_insert_text(editable, "\t", 1, &position); |
1 | 4299 break; |
4300 case GDK_Return: | |
4301 if (event->state & GDK_CONTROL_MASK) | |
12 | 4302 gtk_signal_emit_by_name(GTK_OBJECT(text), "activate"); |
1 | 4303 else |
4304 { | |
4305 position = text->point.index; | |
12 | 4306 gtk_editable_insert_text(editable, "\n", 1, &position); |
1 | 4307 } |
4308 break; | |
4309 case GDK_Escape: | |
12 | 4310 /* |
4311 * Don't insert literally | |
4312 */ | |
1 | 4313 return_val = FALSE; |
4314 break; | |
4315 #endif | |
4316 default: | |
4317 return_val = FALSE; | |
4318 | |
4319 #if 0 | |
12 | 4320 if (event->state & GDK_CONTROL_MASK) |
4321 { | |
1 | 4322 if ((key >= 'A') && (key <= 'Z')) |
4323 key -= 'A' - 'a'; | |
4324 | |
12 | 4325 if ((key >= 'a') && (key <= 'z') |
4326 && control_keys[(int) (key - 'a')]) | |
1 | 4327 { |
12 | 4328 (*control_keys[(int) (key - 'a')]) (editable, event->time); |
1 | 4329 return_val = TRUE; |
4330 } | |
4331 | |
4332 break; | |
4333 } | |
4334 else if (event->state & GDK_MOD1_MASK) | |
4335 { | |
4336 if ((key >= 'A') && (key <= 'Z')) | |
4337 key -= 'A' - 'a'; | |
4338 | |
4339 if ((key >= 'a') && (key <= 'z') && alt_keys[(int) (key - 'a')]) | |
4340 { | |
12 | 4341 (*alt_keys[(int) (key - 'a')]) (editable, event->time); |
1 | 4342 return_val = TRUE; |
4343 } | |
4344 break; | |
4345 } | |
4346 #endif | |
4347 /* | |
12 | 4348 * if (event->length > 0) { |
4349 * html->cursor_pos++; | |
4350 * gtk_editable_insert_text (editable, event->string, event->length, &position); | |
4351 * | |
4352 * return_val = TRUE; | |
4353 * } | |
4354 * else | |
4355 * return_val = FALSE; | |
4356 */ | |
1 | 4357 } |
4358 | |
4359 } | |
4360 | |
4361 return return_val; | |
4362 } | |
12 | 4363 |
4364 void gtk_html_freeze(GtkHtml * html) | |
1 | 4365 { |
12 | 4366 g_return_if_fail(html != NULL); |
4367 g_return_if_fail(GTK_IS_HTML(html)); | |
1 | 4368 |
4369 html->frozen++; | |
4370 } | |
4371 | |
12 | 4372 void gtk_html_thaw(GtkHtml * html) |
1 | 4373 { |
4374 GdkRectangle area; | |
12 | 4375 |
4376 g_return_if_fail(html != NULL); | |
4377 g_return_if_fail(GTK_IS_HTML(html)); | |
1 | 4378 |
481
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
4379 gtk_html_append_text(html, NULL, 0); |
64afc8f41bcb
[gaim-migrate @ 491]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
353
diff
changeset
|
4380 |
1 | 4381 html->frozen--; |
4382 | |
4383 if (html->frozen < 0) | |
12 | 4384 html->frozen = 0; |
4385 | |
4386 if (html->frozen == 0) | |
4387 { | |
4388 if (html->html_area) | |
4389 { | |
4390 gint width, | |
4391 height; | |
1 | 4392 area.x = 0; |
4393 area.y = 0; | |
4394 | |
4395 gdk_window_get_size(html->html_area, &width, &height); | |
4396 | |
12 | 4397 area.width = width; |
4398 area.height = height; | |
4399 | |
1 | 4400 expose_html(html, &area, TRUE); |
4401 } | |
4402 } | |
4403 } | |
895 | 4404 |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
4405 static int get_line_height(GtkHtml *html, GtkHtmlBit *start) |
948 | 4406 { |
1057
d50d3abb9eb7
[gaim-migrate @ 1067]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1004
diff
changeset
|
4407 int height = 1, max_height = 0; |
948 | 4408 GList *hbits = html->html_bits; |
4409 GtkHtmlBit *hbit = start; /* default this in case hbits is NULL */ | |
4410 | |
4411 hbits = g_list_find(hbits, start); | |
4412 | |
4413 while (hbits) | |
4414 { | |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
4415 hbit = hbits->data; |
948 | 4416 if (hbit->font) |
4417 height = gdk_text_height(hbit->font, "C", 1); | |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
4418 |
948 | 4419 if (max_height < height) |
4420 max_height = height; | |
4421 if (hbit->newline) | |
4422 break; | |
4423 hbits = hbits->next; | |
4424 } | |
4425 | |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
4426 if (max_height == 0) |
948 | 4427 max_height = gdk_text_height(hbit->font, "C", 1); |
985
056bd26615ea
[gaim-migrate @ 995]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
957
diff
changeset
|
4428 |
948 | 4429 return max_height; |
4430 } |