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. */
29 #include "console-x.h"
31 #include "objects-x.h"
32 #include "EmacsFrame.h"
33 #include "EmacsFrameP.h"
41 x_draw_blank_toolbar_button (struct frame *f, int x, int y, int width,
42 int height, int threed, int border_width,
45 struct device *d = XDEVICE (f->device);
46 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
47 int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness;
48 int sx = x, sy = y, swidth = width, sheight = height;
50 Display *dpy = DEVICE_X_DISPLAY (d);
51 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
52 GC top_shadow_gc, bottom_shadow_gc, background_gc;
54 background_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
58 top_shadow_gc = FRAME_X_TOOLBAR_TOP_SHADOW_GC (f);
59 bottom_shadow_gc = FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f);
63 top_shadow_gc = background_gc;
64 bottom_shadow_gc = background_gc;
70 swidth -= 2 * border_width;
75 sheight -= 2 * border_width;
78 /* Draw the outline. */
79 x_output_shadows (f, sx, sy, swidth, sheight, top_shadow_gc,
80 bottom_shadow_gc, background_gc, shadow_thickness);
82 /* Blank the middle. */
83 XFillRectangle (dpy, x_win, background_gc, sx + shadow_thickness,
84 sy + shadow_thickness, swidth - shadow_thickness * 2,
85 sheight - shadow_thickness * 2);
88 XFillRectangle (dpy, x_win, background_gc, x, y,
89 (vertical ? border_width : width),
90 (vertical ? height : border_width));
91 XFillRectangle (dpy, x_win, background_gc,
92 (vertical ? sx + swidth : x),
93 (vertical ? y : sy + sheight),
94 (vertical ? border_width : width),
95 (vertical ? height : border_width));
99 x_output_toolbar_button (struct frame *f, Lisp_Object button)
101 struct device *d = XDEVICE (f->device);
102 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
103 int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness;
104 int x_adj, y_adj, width_adj, height_adj;
106 Display *dpy = DEVICE_X_DISPLAY (d);
107 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
108 GC top_shadow_gc, bottom_shadow_gc, background_gc;
109 Lisp_Object instance, frame, window, glyph;
110 struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
111 struct Lisp_Image_Instance *p;
113 int vertical = tb->vertical;
114 int border_width = tb->border_width;
118 x_adj = border_width;
119 width_adj = - 2 * border_width;
127 y_adj = border_width;
128 height_adj = - 2 * border_width;
131 XSETFRAME (frame, f);
132 window = FRAME_LAST_NONMINIBUF_WINDOW (f);
133 w = XWINDOW (window);
135 glyph = get_toolbar_button_glyph (w, tb);
141 top_shadow_gc = FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f);
142 bottom_shadow_gc = FRAME_X_TOOLBAR_TOP_SHADOW_GC (f);
146 top_shadow_gc = FRAME_X_TOOLBAR_TOP_SHADOW_GC (f);
147 bottom_shadow_gc = FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f);
152 top_shadow_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
153 bottom_shadow_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
155 background_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
157 /* Draw the outline. */
158 x_output_shadows (f, tb->x + x_adj, tb->y + y_adj,
159 tb->width + width_adj, tb->height + height_adj,
161 bottom_shadow_gc, background_gc, shadow_thickness);
163 /* Clear the pixmap area. */
164 XFillRectangle (dpy, x_win, background_gc, tb->x + x_adj + shadow_thickness,
165 tb->y + y_adj + shadow_thickness,
166 tb->width + width_adj - shadow_thickness * 2,
167 tb->height + height_adj - shadow_thickness * 2);
170 XFillRectangle (dpy, x_win, background_gc, tb->x, tb->y,
171 (vertical ? border_width : tb->width),
172 (vertical ? tb->height : border_width));
174 XFillRectangle (dpy, x_win, background_gc,
175 (vertical ? tb->x + tb->width - border_width : tb->x),
176 (vertical ? tb->y : tb->y + tb->height - border_width),
177 (vertical ? border_width : tb->width),
178 (vertical ? tb->height : border_width));
180 background_gc = FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f);
182 /* #### It is currently possible for users to trash us by directly
183 changing the toolbar glyphs. Avoid crashing in that case. */
185 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1);
189 if (IMAGE_INSTANCEP (instance))
191 int width = tb->width + width_adj - shadow_thickness * 2;
192 int height = tb->height + height_adj - shadow_thickness * 2;
193 int x_offset = x_adj + shadow_thickness;
194 int y_offset = y_adj + shadow_thickness;
196 p = XIMAGE_INSTANCE (instance);
198 if (IMAGE_INSTANCE_PIXMAP_TYPE_P (p))
200 if (width > (int) IMAGE_INSTANCE_PIXMAP_WIDTH (p))
202 x_offset += ((int) (width - IMAGE_INSTANCE_PIXMAP_WIDTH (p))
204 width = IMAGE_INSTANCE_PIXMAP_WIDTH (p);
206 if (height > (int) IMAGE_INSTANCE_PIXMAP_HEIGHT (p))
208 y_offset += ((int) (height - IMAGE_INSTANCE_PIXMAP_HEIGHT (p))
210 height = IMAGE_INSTANCE_PIXMAP_HEIGHT (p);
213 x_output_x_pixmap (f, XIMAGE_INSTANCE (instance), tb->x + x_offset,
214 tb->y + y_offset, 0, 0, 0, 0, width, height,
215 0, 0, 0, background_gc);
217 else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_TEXT)
219 /* #### We need to make the face used configurable. */
220 struct face_cachel *cachel =
221 WINDOW_FACE_CACHEL (w, DEFAULT_INDEX);
222 struct display_line dl;
223 Lisp_Object string = IMAGE_INSTANCE_TEXT_STRING (p);
224 unsigned char charsets[NUM_LEADING_BYTES];
226 struct font_metric_info fm;
228 /* This could be true if we were called via the Expose event
229 handler. Mark the button as dirty and return
231 if (f->window_face_cache_reset)
234 MARK_TOOLBAR_CHANGED;
237 buf = Dynarr_new (Emchar);
238 convert_bufbyte_string_into_emchar_dynarr
239 (XSTRING_DATA (string), XSTRING_LENGTH (string), buf);
240 find_charsets_in_emchar_string (charsets, Dynarr_atp (buf, 0),
241 Dynarr_length (buf));
242 ensure_face_cachel_complete (cachel, window, charsets);
243 face_cachel_charset_font_metric_info (cachel, charsets, &fm);
245 dl.ascent = fm.ascent;
246 dl.descent = fm.descent;
247 dl.ypos = tb->y + y_offset + fm.ascent;
249 if (fm.ascent + fm.descent <= height)
251 dl.ypos += (height - fm.ascent - fm.descent) / 2;
256 dl.clip = fm.ascent + fm.descent - height;
259 x_output_string (w, &dl, buf, tb->x + x_offset, 0, 0, width,
260 DEFAULT_INDEX, 0, 0, 0, 0);
264 /* We silently ignore the image if it isn't a pixmap or text. */
271 x_get_button_size (struct frame *f, Lisp_Object window,
272 struct toolbar_button *tb, int vert, int pos)
274 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
275 int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness;
280 if (!NILP (tb->down_glyph))
281 size = XINT (tb->down_glyph);
283 size = DEFAULT_TOOLBAR_BLANK_SIZE;
287 struct window *w = XWINDOW (window);
288 Lisp_Object glyph = get_toolbar_button_glyph (w, tb);
290 /* Unless, of course, the user has done something stupid like
291 change the glyph out from under us. Use a blank placeholder
294 return XINT (f->toolbar_size[pos]);
297 size = glyph_height (glyph, Vdefault_face, 0, window);
299 size = glyph_width (glyph, Vdefault_face, 0, window);
304 /* If the glyph doesn't have a size we'll insert a blank
305 placeholder instead. */
306 return XINT (f->toolbar_size[pos]);
309 size += shadow_thickness * 2;
314 #define X_OUTPUT_BUTTONS_LOOP(left) \
316 while (!NILP (button)) \
318 struct toolbar_button *tb = XTOOLBAR_BUTTON (button); \
319 int size, height, width; \
321 if (left && tb->pushright) \
324 size = x_get_button_size (f, window, tb, vert, pos); \
329 if (y + size > max_pixpos) \
330 height = max_pixpos - y; \
336 if (x + size > max_pixpos) \
337 width = max_pixpos - x; \
340 height = bar_height; \
345 || tb->width != width \
346 || tb->height != height \
349 if (width && height) \
354 tb->height = height; \
355 tb->border_width = border_width; \
356 tb->vertical = vert; \
358 if (tb->blank || NILP (tb->up_glyph)) \
360 int threed = (EQ (Qt, tb->up_glyph) ? 1 : 0); \
361 x_draw_blank_toolbar_button (f, x, y, width, \
363 border_width, vert); \
366 x_output_toolbar_button (f, button); \
375 if ((vert && y == max_pixpos) || (!vert && x == max_pixpos)) \
382 #define SET_TOOLBAR_WAS_VISIBLE_FLAG(frame, pos, flag) \
387 (frame)->top_toolbar_was_visible = flag; \
389 case BOTTOM_TOOLBAR: \
390 (frame)->bottom_toolbar_was_visible = flag; \
393 (frame)->left_toolbar_was_visible = flag; \
395 case RIGHT_TOOLBAR: \
396 (frame)->right_toolbar_was_visible = flag; \
404 x_output_toolbar (struct frame *f, enum toolbar_pos pos)
406 struct device *d = XDEVICE (f->device);
407 int x, y, bar_width, bar_height, vert;
408 int max_pixpos, right_size, right_start, blank_size;
409 int border_width = FRAME_REAL_TOOLBAR_BORDER_WIDTH (f, pos);
410 Lisp_Object button, window;
411 Display *dpy = DEVICE_X_DISPLAY (d);
412 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
413 GC background_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
415 get_toolbar_coords (f, pos, &x, &y, &bar_width, &bar_height, &vert, 1);
416 window = FRAME_LAST_NONMINIBUF_WINDOW (f);
419 XFillRectangle (dpy, x_win, background_gc, x, y,
420 (vert ? bar_width : border_width),
421 (vert ? border_width : bar_height));
422 XFillRectangle (dpy, x_win, background_gc,
423 (vert ? x : x + bar_width - border_width),
424 (vert ? y + bar_height - border_width : y),
425 (vert ? bar_width : border_width),
426 (vert ? border_width : bar_height));
430 max_pixpos = y + bar_height - border_width;
435 max_pixpos = x + bar_width - border_width;
439 button = FRAME_TOOLBAR_BUTTONS (f, pos);
442 /* First loop over all of the buttons to determine how much room we
443 need for left hand and right hand buttons. This loop will also
444 make sure that all instances are instantiated so when we actually
445 output them they will come up immediately. */
446 while (!NILP (button))
448 struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
449 int size = x_get_button_size (f, window, tb, vert, pos);
457 button = FRAME_TOOLBAR_BUTTONS (f, pos);
459 /* Loop over the left buttons, updating and outputting them. */
460 X_OUTPUT_BUTTONS_LOOP (1);
462 /* Now determine where the right buttons start. */
463 right_start = max_pixpos - right_size;
464 if (right_start < (vert ? y : x))
465 right_start = (vert ? y : x);
467 /* Output the blank which goes from the end of the left buttons to
468 the start of the right. */
469 blank_size = right_start - (vert ? y : x);
486 * Use a 3D pushright separator only if there isn't a toolbar
487 * border. A flat separator meshes with the border and looks
490 x_draw_blank_toolbar_button (f, x, y, width, height, !border_width,
499 /* Loop over the right buttons, updating and outputting them. */
500 X_OUTPUT_BUTTONS_LOOP (0);
506 XSETFRAME (frame, f);
507 redisplay_clear_region (frame,
508 DEFAULT_INDEX, FRAME_PIXWIDTH (f) - 1, y, 1,
512 SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 1);
514 XFlush (DEVICE_X_DISPLAY (d));
518 x_clear_toolbar (struct frame *f, enum toolbar_pos pos, int thickness_change)
521 struct device *d = XDEVICE (f->device);
522 int x, y, width, height, vert;
524 get_toolbar_coords (f, pos, &x, &y, &width, &height, &vert, 1);
525 XSETFRAME (frame, f);
527 /* The thickness_change parameter is used by the toolbar resize routines
528 to clear any excess toolbar if the size shrinks. */
529 if (thickness_change < 0)
531 if (pos == LEFT_TOOLBAR || pos == RIGHT_TOOLBAR)
533 x = x + width + thickness_change;
534 width = -thickness_change;
538 y = y + height + thickness_change;
539 height = -thickness_change;
543 SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 0);
545 redisplay_clear_region (frame, DEFAULT_INDEX, x, y, width, height);
546 XFlush (DEVICE_X_DISPLAY (d));
550 x_output_frame_toolbars (struct frame *f)
552 assert (FRAME_X_P (f));
554 if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f))
555 x_output_toolbar (f, TOP_TOOLBAR);
556 else if (f->top_toolbar_was_visible)
557 x_clear_toolbar (f, TOP_TOOLBAR, 0);
559 if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f))
560 x_output_toolbar (f, BOTTOM_TOOLBAR);
561 else if (f->bottom_toolbar_was_visible)
562 x_clear_toolbar (f, BOTTOM_TOOLBAR, 0);
564 if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f))
565 x_output_toolbar (f, LEFT_TOOLBAR);
566 else if (f->left_toolbar_was_visible)
567 x_clear_toolbar (f, LEFT_TOOLBAR, 0);
569 if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f))
570 x_output_toolbar (f, RIGHT_TOOLBAR);
571 else if (f->right_toolbar_was_visible)
572 x_clear_toolbar (f, RIGHT_TOOLBAR, 0);
576 x_redraw_exposed_toolbar (struct frame *f, enum toolbar_pos pos, int x, int y,
577 int width, int height)
579 int bar_x, bar_y, bar_width, bar_height, vert;
580 Lisp_Object button = FRAME_TOOLBAR_BUTTONS (f, pos);
582 get_toolbar_coords (f, pos, &bar_x, &bar_y, &bar_width, &bar_height,
585 if (((y + height) < bar_y) || (y > (bar_y + bar_height)))
587 if (((x + width) < bar_x) || (x > (bar_x + bar_width)))
590 while (!NILP (button))
592 struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
596 if (((tb->y + tb->height) > y) && (tb->y < (y + height)))
599 /* If this is true we have gone past the exposed region. */
600 if (tb->y > (y + height))
605 if (((tb->x + tb->width) > x) && (tb->x < (x + width)))
608 /* If this is true we have gone past the exposed region. */
609 if (tb->x > (x + width))
616 /* Even if none of the buttons is in the area, the blank region at
617 the very least must be because the first thing we did is verify
618 that some portion of the toolbar is in the exposed region. */
619 x_output_toolbar (f, pos);
623 x_redraw_exposed_toolbars (struct frame *f, int x, int y, int width,
626 assert (FRAME_X_P (f));
628 if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f))
629 x_redraw_exposed_toolbar (f, TOP_TOOLBAR, x, y, width, height);
631 if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f))
632 x_redraw_exposed_toolbar (f, BOTTOM_TOOLBAR, x, y, width, height);
634 if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f))
635 x_redraw_exposed_toolbar (f, LEFT_TOOLBAR, x, y, width, height);
637 if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f))
638 x_redraw_exposed_toolbar (f, RIGHT_TOOLBAR, x, y, width, height);
642 x_redraw_frame_toolbars (struct frame *f)
644 /* There are certain startup paths that lead to update_EmacsFrame in
645 faces.c being called before a new frame is fully initialized. In
646 particular before we have actually mapped it. That routine can
647 call this one. So, we need to make sure that the frame is
648 actually ready before we try and draw all over it. */
650 if (XtIsRealized (FRAME_X_SHELL_WIDGET (f)))
651 x_redraw_exposed_toolbars (f, 0, 0, FRAME_PIXWIDTH (f),
652 FRAME_PIXHEIGHT (f));
657 x_initialize_frame_toolbar_gcs (struct frame *f)
659 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
660 EmacsFramePart *efp = &(ef->emacs_frame);
662 unsigned long flags = (GCForeground | GCBackground | GCGraphicsExposures);
665 * If backgroundToolBarColor is specified, use it.
666 * Otherwise use the background resource.
668 if (efp->background_toolbar_pixel == (Pixel) (-1))
669 efp->background_toolbar_pixel = efp->background_pixel;
673 * If foregroundToolBarColor is specified, use it.
674 * Otherwise use the foreground resource.
676 * The foreground pixel is currently unused, but will likely be
677 * used when toolbar captions are generated by the toolbar code
678 * instead being incorporated into the icon image.
680 if (efp->foreground_toolbar_pixel == (Pixel) (-1))
681 efp->foreground_toolbar_pixel = efp->foreground_pixel;
683 gcv.foreground = efp->background_toolbar_pixel;
684 gcv.background = ef->core.background_pixel;
685 gcv.graphics_exposures = False;
686 FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f) =
687 XtGetGC ((Widget) ef, flags, &gcv);
689 if (efp->top_toolbar_shadow_pixel == efp->bottom_toolbar_shadow_pixel)
691 efp->top_toolbar_shadow_pixel = efp->background_toolbar_pixel;
692 efp->bottom_toolbar_shadow_pixel = efp->background_toolbar_pixel;
695 x_generate_shadow_pixels (f, &efp->top_toolbar_shadow_pixel,
696 &efp->bottom_toolbar_shadow_pixel,
697 efp->background_toolbar_pixel,
698 ef->core.background_pixel);
700 gcv.foreground = efp->top_toolbar_shadow_pixel;
701 gcv.background = ef->core.background_pixel;
702 gcv.graphics_exposures = False;
703 flags = GCForeground | GCBackground | GCGraphicsExposures;
704 if (efp->top_toolbar_shadow_pixmap)
706 gcv.fill_style = FillOpaqueStippled;
707 gcv.stipple = efp->top_toolbar_shadow_pixmap;
708 flags |= GCStipple | GCFillStyle;
710 FRAME_X_TOOLBAR_TOP_SHADOW_GC (f) = XtGetGC ((Widget) ef, flags, &gcv);
712 gcv.foreground = efp->bottom_toolbar_shadow_pixel;
713 gcv.background = ef->core.background_pixel;
714 gcv.graphics_exposures = False;
715 flags = GCForeground | GCBackground | GCGraphicsExposures;
716 if (efp->bottom_toolbar_shadow_pixmap)
718 gcv.fill_style = FillOpaqueStippled;
719 gcv.stipple = efp->bottom_toolbar_shadow_pixmap;
720 flags |= GCStipple | GCFillStyle;
722 FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f) = XtGetGC ((Widget) ef, flags, &gcv);
725 FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f) =
726 FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
729 struct device *d = XDEVICE (f->device);
730 Display *dpy = DEVICE_X_DISPLAY (d);
732 gcv.background = WhitePixelOfScreen (DefaultScreenOfDisplay (dpy));
733 gcv.foreground = BlackPixelOfScreen (DefaultScreenOfDisplay (dpy));
734 gcv.graphics_exposures = False;
735 flags = GCForeground | GCBackground | GCGraphicsExposures;
736 FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f) =
737 XtGetGC ((Widget) ef, flags, &gcv);
743 x_release_frame_toolbar_gcs (struct frame *f)
745 Widget ew = (Widget) FRAME_X_TEXT_WIDGET (f);
746 XtReleaseGC (ew, FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f));
747 /* If compiled with XPM support, this is a pointer to the same GC as
748 FRAME_X_BLANK_BACKGROUND_GC so we need to make sure we don't
751 XtReleaseGC (ew, FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f));
753 XtReleaseGC (ew, FRAME_X_TOOLBAR_TOP_SHADOW_GC (f));
754 XtReleaseGC (ew, FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f));
756 /* Seg fault if we try and use these again. */
757 FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f) = (GC) - 1;
758 FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f) = (GC) - 1;
759 FRAME_X_TOOLBAR_TOP_SHADOW_GC (f) = (GC) - 1;
760 FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f) = (GC) - 1;
764 x_initialize_frame_toolbars (struct frame *f)
766 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
768 if (ef->emacs_frame.toolbar_shadow_thickness < MINIMUM_SHADOW_THICKNESS)
769 Xt_SET_VALUE (FRAME_X_TEXT_WIDGET (f),
770 XtNtoolBarShadowThickness, MINIMUM_SHADOW_THICKNESS);
772 x_initialize_frame_toolbar_gcs (f);
775 /* This only calls one function but we go ahead and create this in
776 case we ever do decide that we need to do more work. */
778 x_free_frame_toolbars (struct frame *f)
780 x_release_frame_toolbar_gcs (f);
784 /************************************************************************/
786 /************************************************************************/
789 console_type_create_toolbar_x (void)
791 CONSOLE_HAS_METHOD (x, output_frame_toolbars);
792 CONSOLE_HAS_METHOD (x, initialize_frame_toolbars);
793 CONSOLE_HAS_METHOD (x, free_frame_toolbars);
794 CONSOLE_HAS_METHOD (x, output_toolbar_button);
795 CONSOLE_HAS_METHOD (x, redraw_exposed_toolbars);
796 CONSOLE_HAS_METHOD (x, redraw_frame_toolbars);