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.
7 This file is part of XEmacs.
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
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
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. */
24 /* Synched up with: Not in FSF. */
26 /* This file Mule-ized (more like Mule-verified) by Ben Wing, 7-8-00. */
31 #include "console-x.h"
33 #include "objects-x.h"
34 #include "EmacsFrame.h"
35 #include "EmacsFrameP.h"
43 x_draw_blank_toolbar_button (struct frame *f, int x, int y, int width,
44 int height, int threed, int border_width,
47 struct device *d = XDEVICE (f->device);
48 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
49 int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness;
50 int sx = x, sy = y, swidth = width, sheight = height;
52 Display *dpy = DEVICE_X_DISPLAY (d);
53 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
54 GC top_shadow_gc, bottom_shadow_gc, background_gc;
56 background_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
60 top_shadow_gc = FRAME_X_TOOLBAR_TOP_SHADOW_GC (f);
61 bottom_shadow_gc = FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f);
65 top_shadow_gc = background_gc;
66 bottom_shadow_gc = background_gc;
72 swidth -= 2 * border_width;
77 sheight -= 2 * border_width;
80 /* Draw the outline. */
81 x_output_shadows (f, sx, sy, swidth, sheight, top_shadow_gc,
82 bottom_shadow_gc, background_gc, shadow_thickness,
85 /* Blank the middle. */
86 XFillRectangle (dpy, x_win, background_gc, sx + shadow_thickness,
87 sy + shadow_thickness, swidth - shadow_thickness * 2,
88 sheight - shadow_thickness * 2);
91 XFillRectangle (dpy, x_win, background_gc, x, y,
92 (vertical ? border_width : width),
93 (vertical ? height : border_width));
94 XFillRectangle (dpy, x_win, background_gc,
95 (vertical ? sx + swidth : x),
96 (vertical ? y : sy + sheight),
97 (vertical ? border_width : width),
98 (vertical ? height : border_width));
102 x_output_toolbar_button (struct frame *f, Lisp_Object button)
104 struct device *d = XDEVICE (f->device);
105 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
106 int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness;
107 int x_adj, y_adj, width_adj, height_adj;
109 Display *dpy = DEVICE_X_DISPLAY (d);
110 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
111 GC top_shadow_gc, bottom_shadow_gc, background_gc;
112 Lisp_Object instance, frame, window, glyph;
113 struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
114 Lisp_Image_Instance *p;
116 int vertical = tb->vertical;
117 int border_width = tb->border_width;
121 x_adj = border_width;
122 width_adj = - 2 * border_width;
130 y_adj = border_width;
131 height_adj = - 2 * border_width;
134 XSETFRAME (frame, f);
135 window = FRAME_LAST_NONMINIBUF_WINDOW (f);
136 w = XWINDOW (window);
138 glyph = get_toolbar_button_glyph (w, tb);
144 top_shadow_gc = FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f);
145 bottom_shadow_gc = FRAME_X_TOOLBAR_TOP_SHADOW_GC (f);
149 top_shadow_gc = FRAME_X_TOOLBAR_TOP_SHADOW_GC (f);
150 bottom_shadow_gc = FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f);
155 top_shadow_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
156 bottom_shadow_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
158 background_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
160 /* Draw the outline. */
161 x_output_shadows (f, tb->x + x_adj, tb->y + y_adj,
162 tb->width + width_adj, tb->height + height_adj,
164 bottom_shadow_gc, background_gc, shadow_thickness,
167 /* Clear the pixmap area. */
168 XFillRectangle (dpy, x_win, background_gc, tb->x + x_adj + shadow_thickness,
169 tb->y + y_adj + shadow_thickness,
170 tb->width + width_adj - shadow_thickness * 2,
171 tb->height + height_adj - shadow_thickness * 2);
174 XFillRectangle (dpy, x_win, background_gc, tb->x, tb->y,
175 (vertical ? border_width : tb->width),
176 (vertical ? tb->height : border_width));
178 XFillRectangle (dpy, x_win, background_gc,
179 (vertical ? tb->x + tb->width - border_width : tb->x),
180 (vertical ? tb->y : tb->y + tb->height - border_width),
181 (vertical ? border_width : tb->width),
182 (vertical ? tb->height : border_width));
184 background_gc = FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f);
186 /* #### It is currently possible for users to trash us by directly
187 changing the toolbar glyphs. Avoid crashing in that case. */
189 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1);
193 if (IMAGE_INSTANCEP (instance))
195 int width = tb->width + width_adj - shadow_thickness * 2;
196 int height = tb->height + height_adj - shadow_thickness * 2;
197 int x_offset = x_adj + shadow_thickness;
198 int y_offset = y_adj + shadow_thickness;
200 p = XIMAGE_INSTANCE (instance);
202 if (IMAGE_INSTANCE_PIXMAP_TYPE_P (p))
204 if (width > (int) IMAGE_INSTANCE_PIXMAP_WIDTH (p))
206 x_offset += ((int) (width - IMAGE_INSTANCE_PIXMAP_WIDTH (p))
208 width = IMAGE_INSTANCE_PIXMAP_WIDTH (p);
210 if (height > (int) IMAGE_INSTANCE_PIXMAP_HEIGHT (p))
212 y_offset += ((int) (height - IMAGE_INSTANCE_PIXMAP_HEIGHT (p))
214 height = IMAGE_INSTANCE_PIXMAP_HEIGHT (p);
217 x_output_x_pixmap (f, XIMAGE_INSTANCE (instance), tb->x + x_offset,
218 tb->y + y_offset, 0, 0, width, height,
219 0, 0, background_gc);
221 else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_TEXT)
223 /* #### We need to make the face used configurable. */
224 struct face_cachel *cachel =
225 WINDOW_FACE_CACHEL (w, DEFAULT_INDEX);
226 struct display_line dl;
227 Lisp_Object string = IMAGE_INSTANCE_TEXT_STRING (p);
228 unsigned char charsets[NUM_LEADING_BYTES];
230 struct font_metric_info fm;
232 /* This could be true if we were called via the Expose event
233 handler. Mark the button as dirty and return
235 if (f->window_face_cache_reset)
238 MARK_TOOLBAR_CHANGED;
241 buf = Dynarr_new (Emchar);
242 convert_bufbyte_string_into_emchar_dynarr
243 (XSTRING_DATA (string), XSTRING_LENGTH (string), buf);
244 find_charsets_in_emchar_string (charsets, Dynarr_atp (buf, 0),
245 Dynarr_length (buf));
246 ensure_face_cachel_complete (cachel, window, charsets);
247 face_cachel_charset_font_metric_info (cachel, charsets, &fm);
249 dl.ascent = fm.ascent;
250 dl.descent = fm.descent;
251 dl.ypos = tb->y + y_offset + fm.ascent;
253 if (fm.ascent + fm.descent <= height)
255 dl.ypos += (height - fm.ascent - fm.descent) / 2;
260 dl.clip = fm.ascent + fm.descent - height;
263 x_output_string (w, &dl, buf, tb->x + x_offset, 0, 0, width,
264 DEFAULT_INDEX, 0, 0, 0, 0);
268 /* We silently ignore the image if it isn't a pixmap or text. */
275 x_get_button_size (struct frame *f, Lisp_Object window,
276 struct toolbar_button *tb, int vert, int pos)
278 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
279 int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness;
284 if (!NILP (tb->down_glyph))
285 size = XINT (tb->down_glyph);
287 size = DEFAULT_TOOLBAR_BLANK_SIZE;
291 struct window *w = XWINDOW (window);
292 Lisp_Object glyph = get_toolbar_button_glyph (w, tb);
294 /* Unless, of course, the user has done something stupid like
295 change the glyph out from under us. Use a blank placeholder
298 return XINT (f->toolbar_size[pos]);
301 size = glyph_height (glyph, window);
303 size = glyph_width (glyph, window);
308 /* If the glyph doesn't have a size we'll insert a blank
309 placeholder instead. */
310 return XINT (f->toolbar_size[pos]);
313 size += shadow_thickness * 2;
318 #define X_OUTPUT_BUTTONS_LOOP(left) \
320 while (!NILP (button)) \
322 struct toolbar_button *tb = XTOOLBAR_BUTTON (button); \
323 int size, height, width; \
325 if (left && tb->pushright) \
328 size = x_get_button_size (f, window, tb, vert, pos); \
333 if (y + size > max_pixpos) \
334 height = max_pixpos - y; \
340 if (x + size > max_pixpos) \
341 width = max_pixpos - x; \
344 height = bar_height; \
349 || tb->width != width \
350 || tb->height != height \
353 if (width && height) \
358 tb->height = height; \
359 tb->border_width = border_width; \
360 tb->vertical = vert; \
362 if (tb->blank || NILP (tb->up_glyph)) \
364 int threed = (EQ (Qt, tb->up_glyph) ? 1 : 0); \
365 x_draw_blank_toolbar_button (f, x, y, width, \
367 border_width, vert); \
370 x_output_toolbar_button (f, button); \
379 if ((vert && y == max_pixpos) || (!vert && x == max_pixpos)) \
386 #define SET_TOOLBAR_WAS_VISIBLE_FLAG(frame, pos, flag) \
391 (frame)->top_toolbar_was_visible = flag; \
393 case BOTTOM_TOOLBAR: \
394 (frame)->bottom_toolbar_was_visible = flag; \
397 (frame)->left_toolbar_was_visible = flag; \
399 case RIGHT_TOOLBAR: \
400 (frame)->right_toolbar_was_visible = flag; \
408 x_output_toolbar (struct frame *f, enum toolbar_pos pos)
410 struct device *d = XDEVICE (f->device);
411 int x, y, bar_width, bar_height, vert;
412 int max_pixpos, right_size, right_start, blank_size;
413 int border_width = FRAME_REAL_TOOLBAR_BORDER_WIDTH (f, pos);
414 Lisp_Object button, window;
415 Display *dpy = DEVICE_X_DISPLAY (d);
416 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
417 GC background_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
419 get_toolbar_coords (f, pos, &x, &y, &bar_width, &bar_height, &vert, 1);
420 window = FRAME_LAST_NONMINIBUF_WINDOW (f);
423 XFillRectangle (dpy, x_win, background_gc, x, y,
424 (vert ? bar_width : border_width),
425 (vert ? border_width : bar_height));
426 XFillRectangle (dpy, x_win, background_gc,
427 (vert ? x : x + bar_width - border_width),
428 (vert ? y + bar_height - border_width : y),
429 (vert ? bar_width : border_width),
430 (vert ? border_width : bar_height));
434 max_pixpos = y + bar_height - border_width;
439 max_pixpos = x + bar_width - border_width;
443 button = FRAME_TOOLBAR_BUTTONS (f, pos);
446 /* First loop over all of the buttons to determine how much room we
447 need for left hand and right hand buttons. This loop will also
448 make sure that all instances are instantiated so when we actually
449 output them they will come up immediately. */
450 while (!NILP (button))
452 struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
453 int size = x_get_button_size (f, window, tb, vert, pos);
461 button = FRAME_TOOLBAR_BUTTONS (f, pos);
463 /* Loop over the left buttons, updating and outputting them. */
464 X_OUTPUT_BUTTONS_LOOP (1);
466 /* Now determine where the right buttons start. */
467 right_start = max_pixpos - right_size;
468 if (right_start < (vert ? y : x))
469 right_start = (vert ? y : x);
471 /* Output the blank which goes from the end of the left buttons to
472 the start of the right. */
473 blank_size = right_start - (vert ? y : x);
490 * Use a 3D pushright separator only if there isn't a toolbar
491 * border. A flat separator meshes with the border and looks
494 x_draw_blank_toolbar_button (f, x, y, width, height, !border_width,
503 /* Loop over the right buttons, updating and outputting them. */
504 X_OUTPUT_BUTTONS_LOOP (0);
510 XSETFRAME (frame, f);
511 redisplay_clear_region (frame,
512 DEFAULT_INDEX, FRAME_PIXWIDTH (f) - 1, y, 1,
516 SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 1);
518 XFlush (DEVICE_X_DISPLAY (d));
522 x_clear_toolbar (struct frame *f, enum toolbar_pos pos, int thickness_change)
525 struct device *d = XDEVICE (f->device);
526 int x, y, width, height, vert;
528 get_toolbar_coords (f, pos, &x, &y, &width, &height, &vert, 1);
529 XSETFRAME (frame, f);
531 /* The thickness_change parameter is used by the toolbar resize routines
532 to clear any excess toolbar if the size shrinks. */
533 if (thickness_change < 0)
535 if (pos == LEFT_TOOLBAR || pos == RIGHT_TOOLBAR)
537 x = x + width + thickness_change;
538 width = -thickness_change;
542 y = y + height + thickness_change;
543 height = -thickness_change;
547 SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 0);
549 redisplay_clear_region (frame, DEFAULT_INDEX, x, y, width, height);
550 XFlush (DEVICE_X_DISPLAY (d));
554 x_output_frame_toolbars (struct frame *f)
556 assert (FRAME_X_P (f));
558 if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f))
559 x_output_toolbar (f, TOP_TOOLBAR);
560 else if (f->top_toolbar_was_visible)
561 x_clear_toolbar (f, TOP_TOOLBAR, 0);
563 if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f))
564 x_output_toolbar (f, BOTTOM_TOOLBAR);
565 else if (f->bottom_toolbar_was_visible)
566 x_clear_toolbar (f, BOTTOM_TOOLBAR, 0);
568 if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f))
569 x_output_toolbar (f, LEFT_TOOLBAR);
570 else if (f->left_toolbar_was_visible)
571 x_clear_toolbar (f, LEFT_TOOLBAR, 0);
573 if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f))
574 x_output_toolbar (f, RIGHT_TOOLBAR);
575 else if (f->right_toolbar_was_visible)
576 x_clear_toolbar (f, RIGHT_TOOLBAR, 0);
580 x_redraw_exposed_toolbar (struct frame *f, enum toolbar_pos pos, int x, int y,
581 int width, int height)
583 int bar_x, bar_y, bar_width, bar_height, vert;
584 Lisp_Object button = FRAME_TOOLBAR_BUTTONS (f, pos);
586 get_toolbar_coords (f, pos, &bar_x, &bar_y, &bar_width, &bar_height,
589 if (((y + height) < bar_y) || (y > (bar_y + bar_height)))
591 if (((x + width) < bar_x) || (x > (bar_x + bar_width)))
594 while (!NILP (button))
596 struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
600 if (((tb->y + tb->height) > y) && (tb->y < (y + height)))
603 /* If this is true we have gone past the exposed region. */
604 if (tb->y > (y + height))
609 if (((tb->x + tb->width) > x) && (tb->x < (x + width)))
612 /* If this is true we have gone past the exposed region. */
613 if (tb->x > (x + width))
620 /* Even if none of the buttons is in the area, the blank region at
621 the very least must be because the first thing we did is verify
622 that some portion of the toolbar is in the exposed region. */
623 x_output_toolbar (f, pos);
627 x_redraw_exposed_toolbars (struct frame *f, int x, int y, int width,
630 assert (FRAME_X_P (f));
632 if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f))
633 x_redraw_exposed_toolbar (f, TOP_TOOLBAR, x, y, width, height);
635 if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f))
636 x_redraw_exposed_toolbar (f, BOTTOM_TOOLBAR, x, y, width, height);
638 if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f))
639 x_redraw_exposed_toolbar (f, LEFT_TOOLBAR, x, y, width, height);
641 if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f))
642 x_redraw_exposed_toolbar (f, RIGHT_TOOLBAR, x, y, width, height);
646 x_redraw_frame_toolbars (struct frame *f)
648 /* There are certain startup paths that lead to update_EmacsFrame in
649 faces.c being called before a new frame is fully initialized. In
650 particular before we have actually mapped it. That routine can
651 call this one. So, we need to make sure that the frame is
652 actually ready before we try and draw all over it. */
654 if (XtIsRealized (FRAME_X_SHELL_WIDGET (f)))
655 x_redraw_exposed_toolbars (f, 0, 0, FRAME_PIXWIDTH (f),
656 FRAME_PIXHEIGHT (f));
661 x_initialize_frame_toolbar_gcs (struct frame *f)
663 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
664 EmacsFramePart *efp = &(ef->emacs_frame);
666 unsigned long flags = (GCForeground | GCBackground | GCGraphicsExposures);
669 * If backgroundToolBarColor is specified, use it.
670 * Otherwise use the background resource.
672 if (efp->background_toolbar_pixel == (Pixel) (-1))
673 efp->background_toolbar_pixel = efp->background_pixel;
677 * If foregroundToolBarColor is specified, use it.
678 * Otherwise use the foreground resource.
680 * The foreground pixel is currently unused, but will likely be
681 * used when toolbar captions are generated by the toolbar code
682 * instead being incorporated into the icon image.
684 if (efp->foreground_toolbar_pixel == (Pixel) (-1))
685 efp->foreground_toolbar_pixel = efp->foreground_pixel;
687 gcv.foreground = efp->background_toolbar_pixel;
688 gcv.background = ef->core.background_pixel;
689 gcv.graphics_exposures = False;
690 FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f) =
691 XtGetGC ((Widget) ef, flags, &gcv);
693 if (efp->top_toolbar_shadow_pixel == efp->bottom_toolbar_shadow_pixel)
695 efp->top_toolbar_shadow_pixel = efp->background_toolbar_pixel;
696 efp->bottom_toolbar_shadow_pixel = efp->background_toolbar_pixel;
699 x_generate_shadow_pixels (f, &efp->top_toolbar_shadow_pixel,
700 &efp->bottom_toolbar_shadow_pixel,
701 efp->background_toolbar_pixel,
702 ef->core.background_pixel);
704 gcv.foreground = efp->top_toolbar_shadow_pixel;
705 gcv.background = ef->core.background_pixel;
706 gcv.graphics_exposures = False;
707 flags = GCForeground | GCBackground | GCGraphicsExposures;
708 if (efp->top_toolbar_shadow_pixmap)
710 gcv.fill_style = FillOpaqueStippled;
711 gcv.stipple = efp->top_toolbar_shadow_pixmap;
712 flags |= GCStipple | GCFillStyle;
714 FRAME_X_TOOLBAR_TOP_SHADOW_GC (f) = XtGetGC ((Widget) ef, flags, &gcv);
716 gcv.foreground = efp->bottom_toolbar_shadow_pixel;
717 gcv.background = ef->core.background_pixel;
718 gcv.graphics_exposures = False;
719 flags = GCForeground | GCBackground | GCGraphicsExposures;
720 if (efp->bottom_toolbar_shadow_pixmap)
722 gcv.fill_style = FillOpaqueStippled;
723 gcv.stipple = efp->bottom_toolbar_shadow_pixmap;
724 flags |= GCStipple | GCFillStyle;
726 FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f) = XtGetGC ((Widget) ef, flags, &gcv);
729 FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f) =
730 FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
733 struct device *d = XDEVICE (f->device);
734 Display *dpy = DEVICE_X_DISPLAY (d);
736 gcv.background = WhitePixelOfScreen (DefaultScreenOfDisplay (dpy));
737 gcv.foreground = BlackPixelOfScreen (DefaultScreenOfDisplay (dpy));
738 gcv.graphics_exposures = False;
739 flags = GCForeground | GCBackground | GCGraphicsExposures;
740 FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f) =
741 XtGetGC ((Widget) ef, flags, &gcv);
747 x_release_frame_toolbar_gcs (struct frame *f)
749 Widget ew = (Widget) FRAME_X_TEXT_WIDGET (f);
750 XtReleaseGC (ew, FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f));
751 /* If compiled with XPM support, this is a pointer to the same GC as
752 FRAME_X_BLANK_BACKGROUND_GC so we need to make sure we don't
755 XtReleaseGC (ew, FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f));
757 XtReleaseGC (ew, FRAME_X_TOOLBAR_TOP_SHADOW_GC (f));
758 XtReleaseGC (ew, FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f));
760 /* Seg fault if we try and use these again. */
761 FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f) = (GC) - 1;
762 FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f) = (GC) - 1;
763 FRAME_X_TOOLBAR_TOP_SHADOW_GC (f) = (GC) - 1;
764 FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f) = (GC) - 1;
768 x_initialize_frame_toolbars (struct frame *f)
770 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
772 if (ef->emacs_frame.toolbar_shadow_thickness < MINIMUM_SHADOW_THICKNESS)
773 Xt_SET_VALUE (FRAME_X_TEXT_WIDGET (f),
774 XtNtoolBarShadowThickness, MINIMUM_SHADOW_THICKNESS);
776 x_initialize_frame_toolbar_gcs (f);
779 /* This only calls one function but we go ahead and create this in
780 case we ever do decide that we need to do more work. */
782 x_free_frame_toolbars (struct frame *f)
784 x_release_frame_toolbar_gcs (f);
788 /************************************************************************/
790 /************************************************************************/
793 console_type_create_toolbar_x (void)
795 CONSOLE_HAS_METHOD (x, output_frame_toolbars);
796 CONSOLE_HAS_METHOD (x, initialize_frame_toolbars);
797 CONSOLE_HAS_METHOD (x, free_frame_toolbars);
798 CONSOLE_HAS_METHOD (x, output_toolbar_button);
799 CONSOLE_HAS_METHOD (x, redraw_exposed_toolbars);
800 CONSOLE_HAS_METHOD (x, redraw_frame_toolbars);