Mercurial > hg > xemacs-beta
comparison src/toolbar-gtk.c @ 462:0784d089fdc9 r21-2-46
Import from CVS: tag r21-2-46
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:44:37 +0200 |
parents | |
children | fdefd0186b75 |
comparison
equal
deleted
inserted
replaced
461:120ed4009e51 | 462:0784d089fdc9 |
---|---|
1 /* toolbar implementation -- X interface. | |
2 Copyright (C) 1995 Board of Trustees, University of Illinois. | |
3 Copyright (C) 1995 Sun Microsystems, Inc. | |
4 Copyright (C) 1995, 1996 Ben Wing. | |
5 Copyright (C) 1996 Chuck Thompson. | |
6 | |
7 This file is part of XEmacs. | |
8 | |
9 XEmacs is free software; you can redistribute it and/or modify it | |
10 under the terms of the GNU General Public License as published by the | |
11 Free Software Foundation; either version 2, or (at your option) any | |
12 later version. | |
13 | |
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
20 along with XEmacs; see the file COPYING. If not, write to | |
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
22 Boston, MA 02111-1307, USA. */ | |
23 | |
24 /* Synched up with: Not in FSF. */ | |
25 | |
26 #include <config.h> | |
27 #include "lisp.h" | |
28 | |
29 #include "console-gtk.h" | |
30 #include "glyphs-gtk.h" | |
31 #include "objects-gtk.h" | |
32 #include "gtk-xemacs.h" | |
33 #include "gccache-gtk.h" | |
34 | |
35 #include "faces.h" | |
36 #include "frame.h" | |
37 #include "toolbar.h" | |
38 #include "window.h" | |
39 | |
40 extern GdkGC *gtk_get_gc (struct device *d, Lisp_Object font, Lisp_Object fg, Lisp_Object bg, | |
41 Lisp_Object bg_pmap, Lisp_Object lwidth); | |
42 | |
43 static GdkGC *get_toolbar_gc (struct frame *f) | |
44 { | |
45 Lisp_Object fg, bg; | |
46 Lisp_Object frame; | |
47 | |
48 XSETFRAME (frame, f); | |
49 | |
50 fg = Fspecifier_instance (Fget (Vtoolbar_face, Qforeground, Qnil), frame, Qnil, Qnil); | |
51 bg = Fspecifier_instance (Fget (Vtoolbar_face, Qbackground, Qnil), frame, Qnil, Qnil); | |
52 | |
53 /* Need to swap the foreground/background here or most themes look bug ugly */ | |
54 return (gtk_get_gc (XDEVICE (FRAME_DEVICE (f)), Qnil, bg, fg, Qnil, Qnil)); | |
55 } | |
56 | |
57 static void | |
58 gtk_draw_blank_toolbar_button (struct frame *f, int x, int y, int width, | |
59 int height, int threed, int border_width, | |
60 int vertical) | |
61 { | |
62 GtkXEmacs *ef = GTK_XEMACS (FRAME_GTK_TEXT_WIDGET (f)); | |
63 int sx = x, sy = y, swidth = width, sheight = height; | |
64 GdkWindow *x_win = GTK_WIDGET (ef)->window; | |
65 GdkGC *background_gc = get_toolbar_gc (f); | |
66 | |
67 if (vertical) | |
68 { | |
69 sx += border_width; | |
70 swidth -= 2 * border_width; | |
71 } | |
72 else | |
73 { | |
74 sy += border_width; | |
75 sheight -= 2 * border_width; | |
76 } | |
77 | |
78 /* Blank the entire area. */ | |
79 gdk_draw_rectangle (x_win, background_gc, TRUE, sx, sy, swidth, sheight); | |
80 | |
81 /* Draw the outline. */ | |
82 if (threed) | |
83 gtk_output_shadows (f, sx, sy, swidth, sheight, 2); | |
84 | |
85 /* Do the border */ | |
86 gdk_draw_rectangle (x_win, background_gc, TRUE, x, y, | |
87 (vertical ? border_width : width), | |
88 (vertical ? height : border_width)); | |
89 gdk_draw_rectangle (x_win, background_gc, TRUE, | |
90 (vertical ? sx + swidth : x), | |
91 (vertical ? y : sy + sheight), | |
92 (vertical ? border_width : width), | |
93 (vertical ? height : border_width)); | |
94 } | |
95 | |
96 static void | |
97 gtk_output_toolbar_button (struct frame *f, Lisp_Object button) | |
98 { | |
99 int shadow_thickness = 2; | |
100 int x_adj, y_adj, width_adj, height_adj; | |
101 GdkWindow *x_win = FRAME_GTK_TEXT_WIDGET (f)->window; | |
102 GdkGC *background_gc = get_toolbar_gc (f); | |
103 Lisp_Object instance, frame, window, glyph; | |
104 struct toolbar_button *tb = XTOOLBAR_BUTTON (button); | |
105 struct Lisp_Image_Instance *p; | |
106 struct window *w; | |
107 int vertical = tb->vertical; | |
108 int border_width = tb->border_width; | |
109 | |
110 if (vertical) | |
111 { | |
112 x_adj = border_width; | |
113 width_adj = - 2 * border_width; | |
114 y_adj = 0; | |
115 height_adj = 0; | |
116 } | |
117 else | |
118 { | |
119 x_adj = 0; | |
120 width_adj = 0; | |
121 y_adj = border_width; | |
122 height_adj = - 2 * border_width; | |
123 } | |
124 | |
125 XSETFRAME (frame, f); | |
126 window = FRAME_LAST_NONMINIBUF_WINDOW (f); | |
127 w = XWINDOW (window); | |
128 | |
129 glyph = get_toolbar_button_glyph (w, tb); | |
130 | |
131 if (tb->enabled) | |
132 { | |
133 if (tb->down) | |
134 { | |
135 shadow_thickness = -2; | |
136 } | |
137 else | |
138 { | |
139 shadow_thickness = 2; | |
140 } | |
141 } | |
142 else | |
143 { | |
144 shadow_thickness = 0; | |
145 } | |
146 | |
147 background_gc = get_toolbar_gc (f); | |
148 | |
149 /* Clear the entire area. */ | |
150 gdk_draw_rectangle (x_win, background_gc, TRUE, | |
151 tb->x + x_adj, | |
152 tb->y + y_adj, | |
153 tb->width + width_adj, | |
154 tb->height + height_adj); | |
155 | |
156 /* Draw the outline. */ | |
157 if (shadow_thickness) | |
158 gtk_output_shadows (f, tb->x + x_adj, tb->y + y_adj, | |
159 tb->width + width_adj, tb->height + height_adj, | |
160 shadow_thickness); | |
161 | |
162 /* Do the border. */ | |
163 gdk_draw_rectangle (x_win, background_gc, TRUE, tb->x, tb->y, | |
164 (vertical ? border_width : tb->width), | |
165 (vertical ? tb->height : border_width)); | |
166 | |
167 gdk_draw_rectangle (x_win, background_gc, TRUE, | |
168 (vertical ? tb->x + tb->width - border_width : tb->x), | |
169 (vertical ? tb->y : tb->y + tb->height - border_width), | |
170 (vertical ? border_width : tb->width), | |
171 (vertical ? tb->height : border_width)); | |
172 | |
173 background_gc = get_toolbar_gc (f); | |
174 | |
175 /* #### It is currently possible for users to trash us by directly | |
176 changing the toolbar glyphs. Avoid crashing in that case. */ | |
177 if (GLYPHP (glyph)) | |
178 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); | |
179 else | |
180 instance = Qnil; | |
181 | |
182 if (IMAGE_INSTANCEP (instance)) | |
183 { | |
184 int width = tb->width + width_adj - shadow_thickness * 2; | |
185 int height = tb->height + height_adj - shadow_thickness * 2; | |
186 int x_offset = x_adj + shadow_thickness; | |
187 int y_offset = y_adj + shadow_thickness; | |
188 | |
189 p = XIMAGE_INSTANCE (instance); | |
190 | |
191 if (IMAGE_INSTANCE_PIXMAP_TYPE_P (p)) | |
192 { | |
193 if (width > (int) IMAGE_INSTANCE_PIXMAP_WIDTH (p)) | |
194 { | |
195 x_offset += ((int) (width - IMAGE_INSTANCE_PIXMAP_WIDTH (p)) | |
196 / 2); | |
197 width = IMAGE_INSTANCE_PIXMAP_WIDTH (p); | |
198 } | |
199 if (height > (int) IMAGE_INSTANCE_PIXMAP_HEIGHT (p)) | |
200 { | |
201 y_offset += ((int) (height - IMAGE_INSTANCE_PIXMAP_HEIGHT (p)) | |
202 / 2); | |
203 height = IMAGE_INSTANCE_PIXMAP_HEIGHT (p); | |
204 } | |
205 | |
206 gtk_output_gdk_pixmap (f, XIMAGE_INSTANCE (instance), tb->x + x_offset, | |
207 tb->y + y_offset, 0, 0, 0, 0, width, height, | |
208 0, 0, 0, background_gc); | |
209 } | |
210 else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_TEXT) | |
211 { | |
212 /* #### We need to make the face used configurable. */ | |
213 struct face_cachel *cachel = | |
214 WINDOW_FACE_CACHEL (w, DEFAULT_INDEX); | |
215 struct display_line dl; | |
216 Lisp_Object string = IMAGE_INSTANCE_TEXT_STRING (p); | |
217 unsigned char charsets[NUM_LEADING_BYTES]; | |
218 Emchar_dynarr *buf; | |
219 struct font_metric_info fm; | |
220 | |
221 /* This could be true if we were called via the Expose event | |
222 handler. Mark the button as dirty and return | |
223 immediately. */ | |
224 if (f->window_face_cache_reset) | |
225 { | |
226 tb->dirty = 1; | |
227 MARK_TOOLBAR_CHANGED; | |
228 return; | |
229 } | |
230 buf = Dynarr_new (Emchar); | |
231 convert_bufbyte_string_into_emchar_dynarr | |
232 (XSTRING_DATA (string), XSTRING_LENGTH (string), buf); | |
233 find_charsets_in_emchar_string (charsets, Dynarr_atp (buf, 0), | |
234 Dynarr_length (buf)); | |
235 ensure_face_cachel_complete (cachel, window, charsets); | |
236 face_cachel_charset_font_metric_info (cachel, charsets, &fm); | |
237 | |
238 dl.ascent = fm.ascent; | |
239 dl.descent = fm.descent; | |
240 dl.ypos = tb->y + y_offset + fm.ascent; | |
241 | |
242 if (fm.ascent + fm.descent <= height) | |
243 { | |
244 dl.ypos += (height - fm.ascent - fm.descent) / 2; | |
245 dl.clip = 0; | |
246 } | |
247 else | |
248 { | |
249 dl.clip = fm.ascent + fm.descent - height; | |
250 } | |
251 | |
252 gtk_output_string (w, &dl, buf, tb->x + x_offset, 0, 0, width, | |
253 DEFAULT_INDEX, 0, 0, 0, 0); | |
254 Dynarr_free (buf); | |
255 } | |
256 | |
257 /* We silently ignore the image if it isn't a pixmap or text. */ | |
258 } | |
259 | |
260 tb->dirty = 0; | |
261 } | |
262 | |
263 static int | |
264 gtk_get_button_size (struct frame *f, Lisp_Object window, | |
265 struct toolbar_button *tb, int vert, int pos) | |
266 { | |
267 int shadow_thickness = 2; | |
268 int size; | |
269 | |
270 if (tb->blank) | |
271 { | |
272 if (!NILP (tb->down_glyph)) | |
273 size = XINT (tb->down_glyph); | |
274 else | |
275 size = DEFAULT_TOOLBAR_BLANK_SIZE; | |
276 } | |
277 else | |
278 { | |
279 struct window *w = XWINDOW (window); | |
280 Lisp_Object glyph = get_toolbar_button_glyph (w, tb); | |
281 | |
282 /* Unless, of course, the user has done something stupid like | |
283 change the glyph out from under us. Use a blank placeholder | |
284 in that case. */ | |
285 if (NILP (glyph)) | |
286 return XINT (f->toolbar_size[pos]); | |
287 | |
288 if (vert) | |
289 size = glyph_height (glyph, window); | |
290 else | |
291 size = glyph_width (glyph, window); | |
292 } | |
293 | |
294 if (!size) | |
295 { | |
296 /* If the glyph doesn't have a size we'll insert a blank | |
297 placeholder instead. */ | |
298 return XINT (f->toolbar_size[pos]); | |
299 } | |
300 | |
301 size += shadow_thickness * 2; | |
302 | |
303 return (size); | |
304 } | |
305 | |
306 #define GTK_OUTPUT_BUTTONS_LOOP(left) \ | |
307 do { \ | |
308 while (!NILP (button)) \ | |
309 { \ | |
310 struct toolbar_button *tb = XTOOLBAR_BUTTON (button); \ | |
311 int size, height, width; \ | |
312 \ | |
313 if (left && tb->pushright) \ | |
314 break; \ | |
315 \ | |
316 size = gtk_get_button_size (f, window, tb, vert, pos); \ | |
317 \ | |
318 if (vert) \ | |
319 { \ | |
320 width = bar_width; \ | |
321 if (y + size > max_pixpos) \ | |
322 height = max_pixpos - y; \ | |
323 else \ | |
324 height = size; \ | |
325 } \ | |
326 else \ | |
327 { \ | |
328 if (x + size > max_pixpos) \ | |
329 width = max_pixpos - x; \ | |
330 else \ | |
331 width = size; \ | |
332 height = bar_height; \ | |
333 } \ | |
334 \ | |
335 if (tb->x != x \ | |
336 || tb->y != y \ | |
337 || tb->width != width \ | |
338 || tb->height != height \ | |
339 || tb->dirty) \ | |
340 { \ | |
341 if (width && height) \ | |
342 { \ | |
343 tb->x = x; \ | |
344 tb->y = y; \ | |
345 tb->width = width; \ | |
346 tb->height = height; \ | |
347 tb->border_width = border_width; \ | |
348 tb->vertical = vert; \ | |
349 \ | |
350 if (tb->blank || NILP (tb->up_glyph)) \ | |
351 { \ | |
352 int threed = (EQ (Qt, tb->up_glyph) ? 1 : 0); \ | |
353 gtk_draw_blank_toolbar_button (f, x, y, width, \ | |
354 height, threed, \ | |
355 border_width, vert); \ | |
356 } \ | |
357 else \ | |
358 gtk_output_toolbar_button (f, button); \ | |
359 } \ | |
360 } \ | |
361 \ | |
362 if (vert) \ | |
363 y += height; \ | |
364 else \ | |
365 x += width; \ | |
366 \ | |
367 if ((vert && y == max_pixpos) || (!vert && x == max_pixpos)) \ | |
368 button = Qnil; \ | |
369 else \ | |
370 button = tb->next; \ | |
371 } \ | |
372 } while (0) | |
373 | |
374 #define SET_TOOLBAR_WAS_VISIBLE_FLAG(frame, pos, flag) \ | |
375 do { \ | |
376 switch (pos) \ | |
377 { \ | |
378 case TOP_TOOLBAR: \ | |
379 (frame)->top_toolbar_was_visible = flag; \ | |
380 break; \ | |
381 case BOTTOM_TOOLBAR: \ | |
382 (frame)->bottom_toolbar_was_visible = flag; \ | |
383 break; \ | |
384 case LEFT_TOOLBAR: \ | |
385 (frame)->left_toolbar_was_visible = flag; \ | |
386 break; \ | |
387 case RIGHT_TOOLBAR: \ | |
388 (frame)->right_toolbar_was_visible = flag; \ | |
389 break; \ | |
390 default: \ | |
391 abort (); \ | |
392 } \ | |
393 } while (0) | |
394 | |
395 static void | |
396 gtk_output_toolbar (struct frame *f, enum toolbar_pos pos) | |
397 { | |
398 int x, y, bar_width, bar_height, vert; | |
399 int max_pixpos, right_size, right_start, blank_size; | |
400 int border_width = FRAME_REAL_TOOLBAR_BORDER_WIDTH (f, pos); | |
401 Lisp_Object button, window; | |
402 GdkWindow *x_win = FRAME_GTK_TEXT_WIDGET (f)->window; | |
403 GdkGC *background_gc = get_toolbar_gc (f); | |
404 | |
405 get_toolbar_coords (f, pos, &x, &y, &bar_width, &bar_height, &vert, 1); | |
406 window = FRAME_LAST_NONMINIBUF_WINDOW (f); | |
407 | |
408 /* Do the border */ | |
409 gdk_draw_rectangle (x_win, background_gc, TRUE, x, y, | |
410 (vert ? bar_width : border_width), | |
411 (vert ? border_width : bar_height)); | |
412 gdk_draw_rectangle (x_win, background_gc, TRUE, | |
413 (vert ? x : x + bar_width - border_width), | |
414 (vert ? y + bar_height - border_width : y), | |
415 (vert ? bar_width : border_width), | |
416 (vert ? border_width : bar_height)); | |
417 | |
418 if (vert) | |
419 { | |
420 max_pixpos = y + bar_height - border_width; | |
421 y += border_width; | |
422 } | |
423 else | |
424 { | |
425 max_pixpos = x + bar_width - border_width; | |
426 x += border_width; | |
427 } | |
428 | |
429 button = FRAME_TOOLBAR_BUTTONS (f, pos); | |
430 right_size = 0; | |
431 | |
432 /* First loop over all of the buttons to determine how much room we | |
433 need for left hand and right hand buttons. This loop will also | |
434 make sure that all instances are instantiated so when we actually | |
435 output them they will come up immediately. */ | |
436 while (!NILP (button)) | |
437 { | |
438 struct toolbar_button *tb = XTOOLBAR_BUTTON (button); | |
439 int size = gtk_get_button_size (f, window, tb, vert, pos); | |
440 | |
441 if (tb->pushright) | |
442 right_size += size; | |
443 | |
444 button = tb->next; | |
445 } | |
446 | |
447 button = FRAME_TOOLBAR_BUTTONS (f, pos); | |
448 | |
449 /* Loop over the left buttons, updating and outputting them. */ | |
450 GTK_OUTPUT_BUTTONS_LOOP (1); | |
451 | |
452 /* Now determine where the right buttons start. */ | |
453 right_start = max_pixpos - right_size; | |
454 if (right_start < (vert ? y : x)) | |
455 right_start = (vert ? y : x); | |
456 | |
457 /* Output the blank which goes from the end of the left buttons to | |
458 the start of the right. */ | |
459 blank_size = right_start - (vert ? y : x); | |
460 if (blank_size) | |
461 { | |
462 int height, width; | |
463 | |
464 if (vert) | |
465 { | |
466 width = bar_width; | |
467 height = blank_size; | |
468 } | |
469 else | |
470 { | |
471 width = blank_size; | |
472 height = bar_height; | |
473 } | |
474 | |
475 /* | |
476 * Use a 3D pushright separator only if there isn't a toolbar | |
477 * border. A flat separator meshes with the border and looks | |
478 * better. | |
479 */ | |
480 gtk_draw_blank_toolbar_button (f, x, y, width, height, !border_width, | |
481 border_width, vert); | |
482 | |
483 if (vert) | |
484 y += height; | |
485 else | |
486 x += width; | |
487 } | |
488 | |
489 /* Loop over the right buttons, updating and outputting them. */ | |
490 GTK_OUTPUT_BUTTONS_LOOP (0); | |
491 | |
492 if (!vert) | |
493 { | |
494 Lisp_Object frame; | |
495 | |
496 XSETFRAME (frame, f); | |
497 redisplay_clear_region (frame, | |
498 DEFAULT_INDEX, FRAME_PIXWIDTH (f) - 1, y, 1, | |
499 bar_height); | |
500 } | |
501 | |
502 SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 1); | |
503 | |
504 gdk_flush (); | |
505 } | |
506 | |
507 static void | |
508 gtk_clear_toolbar (struct frame *f, enum toolbar_pos pos, int thickness_change) | |
509 { | |
510 Lisp_Object frame; | |
511 int x, y, width, height, vert; | |
512 | |
513 get_toolbar_coords (f, pos, &x, &y, &width, &height, &vert, 1); | |
514 XSETFRAME (frame, f); | |
515 | |
516 /* The thickness_change parameter is used by the toolbar resize routines | |
517 to clear any excess toolbar if the size shrinks. */ | |
518 if (thickness_change < 0) | |
519 { | |
520 if (pos == LEFT_TOOLBAR || pos == RIGHT_TOOLBAR) | |
521 { | |
522 x = x + width + thickness_change; | |
523 width = -thickness_change; | |
524 } | |
525 else | |
526 { | |
527 y = y + height + thickness_change; | |
528 height = -thickness_change; | |
529 } | |
530 } | |
531 | |
532 SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 0); | |
533 | |
534 redisplay_clear_region (frame, DEFAULT_INDEX, x, y, width, height); | |
535 gdk_flush (); | |
536 } | |
537 | |
538 static void | |
539 gtk_output_frame_toolbars (struct frame *f) | |
540 { | |
541 assert (FRAME_GTK_P (f)); | |
542 | |
543 if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f)) | |
544 gtk_output_toolbar (f, TOP_TOOLBAR); | |
545 else if (f->top_toolbar_was_visible) | |
546 gtk_clear_toolbar (f, TOP_TOOLBAR, 0); | |
547 | |
548 if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f)) | |
549 gtk_output_toolbar (f, BOTTOM_TOOLBAR); | |
550 else if (f->bottom_toolbar_was_visible) | |
551 gtk_clear_toolbar (f, BOTTOM_TOOLBAR, 0); | |
552 | |
553 if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f)) | |
554 gtk_output_toolbar (f, LEFT_TOOLBAR); | |
555 else if (f->left_toolbar_was_visible) | |
556 gtk_clear_toolbar (f, LEFT_TOOLBAR, 0); | |
557 | |
558 if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f)) | |
559 gtk_output_toolbar (f, RIGHT_TOOLBAR); | |
560 else if (f->right_toolbar_was_visible) | |
561 gtk_clear_toolbar (f, RIGHT_TOOLBAR, 0); | |
562 } | |
563 | |
564 static void | |
565 gtk_redraw_exposed_toolbar (struct frame *f, enum toolbar_pos pos, int x, int y, | |
566 int width, int height) | |
567 { | |
568 int bar_x, bar_y, bar_width, bar_height, vert; | |
569 Lisp_Object button = FRAME_TOOLBAR_BUTTONS (f, pos); | |
570 | |
571 get_toolbar_coords (f, pos, &bar_x, &bar_y, &bar_width, &bar_height, | |
572 &vert, 1); | |
573 | |
574 if (((y + height) < bar_y) || (y > (bar_y + bar_height))) | |
575 return; | |
576 if (((x + width) < bar_x) || (x > (bar_x + bar_width))) | |
577 return; | |
578 | |
579 while (!NILP (button)) | |
580 { | |
581 struct toolbar_button *tb = XTOOLBAR_BUTTON (button); | |
582 | |
583 if (vert) | |
584 { | |
585 if (((tb->y + tb->height) > y) && (tb->y < (y + height))) | |
586 tb->dirty = 1; | |
587 | |
588 /* If this is true we have gone past the exposed region. */ | |
589 if (tb->y > (y + height)) | |
590 break; | |
591 } | |
592 else | |
593 { | |
594 if (((tb->x + tb->width) > x) && (tb->x < (x + width))) | |
595 tb->dirty = 1; | |
596 | |
597 /* If this is true we have gone past the exposed region. */ | |
598 if (tb->x > (x + width)) | |
599 break; | |
600 } | |
601 | |
602 button = tb->next; | |
603 } | |
604 | |
605 /* Even if none of the buttons is in the area, the blank region at | |
606 the very least must be because the first thing we did is verify | |
607 that some portion of the toolbar is in the exposed region. */ | |
608 gtk_output_toolbar (f, pos); | |
609 } | |
610 | |
611 static void | |
612 gtk_redraw_exposed_toolbars (struct frame *f, int x, int y, int width, | |
613 int height) | |
614 { | |
615 assert (FRAME_GTK_P (f)); | |
616 | |
617 if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f)) | |
618 gtk_redraw_exposed_toolbar (f, TOP_TOOLBAR, x, y, width, height); | |
619 | |
620 if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f)) | |
621 gtk_redraw_exposed_toolbar (f, BOTTOM_TOOLBAR, x, y, width, height); | |
622 | |
623 if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f)) | |
624 gtk_redraw_exposed_toolbar (f, LEFT_TOOLBAR, x, y, width, height); | |
625 | |
626 if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f)) | |
627 gtk_redraw_exposed_toolbar (f, RIGHT_TOOLBAR, x, y, width, height); | |
628 } | |
629 | |
630 static void | |
631 gtk_redraw_frame_toolbars (struct frame *f) | |
632 { | |
633 /* There are certain startup paths that lead to update_EmacsFrame in | |
634 faces.c being called before a new frame is fully initialized. In | |
635 particular before we have actually mapped it. That routine can | |
636 call this one. So, we need to make sure that the frame is | |
637 actually ready before we try and draw all over it. */ | |
638 | |
639 if (GTK_WIDGET_REALIZED (FRAME_GTK_TEXT_WIDGET (f))) | |
640 gtk_redraw_exposed_toolbars (f, 0, 0, FRAME_PIXWIDTH (f), | |
641 FRAME_PIXHEIGHT (f)); | |
642 } | |
643 | |
644 | |
645 static void | |
646 gtk_initialize_frame_toolbars (struct frame *f) | |
647 { | |
648 } | |
649 | |
650 /* This only calls one function but we go ahead and create this in | |
651 case we ever do decide that we need to do more work. */ | |
652 static void | |
653 gtk_free_frame_toolbars (struct frame *f) | |
654 { | |
655 } | |
656 | |
657 | |
658 /************************************************************************/ | |
659 /* initialization */ | |
660 /************************************************************************/ | |
661 | |
662 void | |
663 console_type_create_toolbar_gtk (void) | |
664 { | |
665 CONSOLE_HAS_METHOD (gtk, output_frame_toolbars); | |
666 CONSOLE_HAS_METHOD (gtk, initialize_frame_toolbars); | |
667 CONSOLE_HAS_METHOD (gtk, free_frame_toolbars); | |
668 CONSOLE_HAS_METHOD (gtk, output_toolbar_button); | |
669 CONSOLE_HAS_METHOD (gtk, redraw_exposed_toolbars); | |
670 CONSOLE_HAS_METHOD (gtk, redraw_frame_toolbars); | |
671 } |