1 /* Generic toolbar implementation.
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 /* Original implementation by Chuck Thompson for 19.12.
27 Default-toolbar-position and specifier-related stuff by Ben Wing. */
36 #include "redisplay.h"
40 Lisp_Object Vtoolbar[4];
41 Lisp_Object Vtoolbar_size[4];
42 Lisp_Object Vtoolbar_visible_p[4];
43 Lisp_Object Vtoolbar_border_width[4];
45 Lisp_Object Vdefault_toolbar, Vdefault_toolbar_visible_p;
46 Lisp_Object Vdefault_toolbar_width, Vdefault_toolbar_height;
47 Lisp_Object Vdefault_toolbar_border_width;
49 Lisp_Object Vdefault_toolbar_position;
50 Lisp_Object Vtoolbar_buttons_captioned_p;
52 Lisp_Object Qtoolbar_buttonp;
53 Lisp_Object Q2D, Q3D, Q2d, Q3d;
56 Lisp_Object Qinit_toolbar_from_resources;
60 mark_toolbar_button (Lisp_Object obj)
62 struct toolbar_button *data = XTOOLBAR_BUTTON (obj);
63 mark_object (data->next);
64 mark_object (data->frame);
65 mark_object (data->up_glyph);
66 mark_object (data->down_glyph);
67 mark_object (data->disabled_glyph);
68 mark_object (data->cap_up_glyph);
69 mark_object (data->cap_down_glyph);
70 mark_object (data->cap_disabled_glyph);
71 mark_object (data->callback);
72 mark_object (data->enabled_p);
73 return data->help_string;
76 DEFINE_LRECORD_IMPLEMENTATION ("toolbar-button", toolbar_button,
77 mark_toolbar_button, 0, 0, 0, 0, 0,
78 struct toolbar_button);
80 DEFUN ("toolbar-button-p", Ftoolbar_button_p, 1, 1, 0, /*
81 Return non-nil if OBJECT is a toolbar button.
85 return TOOLBAR_BUTTONP (object) ? Qt : Qnil;
88 /* Only query functions are provided for toolbar buttons. They are
89 generated and updated from a toolbar description list. Any
90 directly made changes would be wiped out the first time the toolbar
91 was marked as dirty and was regenerated. The exception to this is
92 set-toolbar-button-down-flag. Having this allows us to control the
93 toolbar from elisp. Since we only trigger the button callbacks on
94 up-mouse events and we reset the flag first, there shouldn't be any
95 way for this to get us in trouble (like if someone decides to
96 change the toolbar from a toolbar callback). */
98 DEFUN ("toolbar-button-callback", Ftoolbar_button_callback, 1, 1, 0, /*
99 Return the callback function associated with the toolbar BUTTON.
103 CHECK_TOOLBAR_BUTTON (button);
105 return XTOOLBAR_BUTTON (button)->callback;
108 DEFUN ("toolbar-button-help-string", Ftoolbar_button_help_string, 1, 1, 0, /*
109 Return the help string function associated with the toolbar BUTTON.
113 CHECK_TOOLBAR_BUTTON (button);
115 return XTOOLBAR_BUTTON (button)->help_string;
118 DEFUN ("toolbar-button-enabled-p", Ftoolbar_button_enabled_p, 1, 1, 0, /*
119 Return t if BUTTON is active.
123 CHECK_TOOLBAR_BUTTON (button);
125 return XTOOLBAR_BUTTON (button)->enabled ? Qt : Qnil;
128 DEFUN ("set-toolbar-button-down-flag", Fset_toolbar_button_down_flag, 2, 2, 0, /*
133 struct toolbar_button *tb;
136 CHECK_TOOLBAR_BUTTON (button);
137 tb = XTOOLBAR_BUTTON (button);
140 /* If the button is ignored, don't do anything. */
144 /* If flag is nil, unset the down flag, otherwise set it to true.
145 This also triggers an immediate redraw of the button if the flag
153 if (tb->down != old_flag)
155 struct frame *f = XFRAME (tb->frame);
158 if (DEVICEP (f->device))
160 d = XDEVICE (f->device);
162 if (DEVICE_LIVE_P (XDEVICE (f->device)))
165 MAYBE_DEVMETH (d, output_toolbar_button, (f, button));
174 get_toolbar_button_glyph (struct window *w, struct toolbar_button *tb)
176 Lisp_Object glyph = Qnil;
178 /* The selected glyph logic:
182 DISABLED: disabled -> up
184 CAP-DOWN: cap-down -> cap-up -> down -> up
185 CAP-DISABLED: cap-disabled -> cap-up -> disabled -> up
188 if (!NILP (w->toolbar_buttons_captioned_p))
190 if (tb->enabled && tb->down)
191 glyph = tb->cap_down_glyph;
192 else if (!tb->enabled)
193 glyph = tb->cap_disabled_glyph;
196 glyph = tb->cap_up_glyph;
201 if (tb->enabled && tb->down)
202 glyph = tb->down_glyph;
203 else if (!tb->enabled)
204 glyph = tb->disabled_glyph;
207 /* The non-captioned up button is the ultimate fallback. It is
208 the only one we guarantee exists. */
210 glyph = tb->up_glyph;
216 static enum toolbar_pos
217 decode_toolbar_position (Lisp_Object position)
219 if (EQ (position, Qtop)) return TOP_TOOLBAR;
220 if (EQ (position, Qbottom)) return BOTTOM_TOOLBAR;
221 if (EQ (position, Qleft)) return LEFT_TOOLBAR;
222 if (EQ (position, Qright)) return RIGHT_TOOLBAR;
223 signal_simple_error ("Invalid toolbar position", position);
225 return TOP_TOOLBAR; /* not reached */
228 DEFUN ("set-default-toolbar-position", Fset_default_toolbar_position, 1, 1, 0, /*
229 Set the position that the `default-toolbar' will be displayed at.
230 Valid positions are 'top, 'bottom, 'left and 'right.
231 See `default-toolbar-position'.
235 enum toolbar_pos cur = decode_toolbar_position (Vdefault_toolbar_position);
236 enum toolbar_pos new = decode_toolbar_position (position);
240 /* The following calls will automatically cause the dirty
241 flags to be set; we delay frame size changes to avoid
242 lots of frame flickering. */
243 /* #### I think this should be GC protected. -sb */
244 hold_frame_size_changes ();
245 set_specifier_fallback (Vtoolbar[cur], list1 (Fcons (Qnil, Qnil)));
246 set_specifier_fallback (Vtoolbar[new], Vdefault_toolbar);
247 set_specifier_fallback (Vtoolbar_size[cur], list1 (Fcons (Qnil, Qzero)));
248 set_specifier_fallback (Vtoolbar_size[new],
249 new == TOP_TOOLBAR || new == BOTTOM_TOOLBAR
250 ? Vdefault_toolbar_height
251 : Vdefault_toolbar_width);
252 set_specifier_fallback (Vtoolbar_border_width[cur],
253 list1 (Fcons (Qnil, Qzero)));
254 set_specifier_fallback (Vtoolbar_border_width[new],
255 Vdefault_toolbar_border_width);
256 set_specifier_fallback (Vtoolbar_visible_p[cur],
257 list1 (Fcons (Qnil, Qt)));
258 set_specifier_fallback (Vtoolbar_visible_p[new],
259 Vdefault_toolbar_visible_p);
260 Vdefault_toolbar_position = position;
261 unhold_frame_size_changes ();
267 DEFUN ("default-toolbar-position", Fdefault_toolbar_position, 0, 0, 0, /*
268 Return the position that the `default-toolbar' will be displayed at.
269 The `default-toolbar' will only be displayed here if the corresponding
270 position-specific toolbar specifier does not provide a value.
274 return Vdefault_toolbar_position;
279 update_toolbar_button (struct frame *f, struct toolbar_button *tb,
280 Lisp_Object desc, int pushright)
282 Lisp_Object *elt, glyphs, retval, buffer;
283 struct gcpro gcpro1, gcpro2;
285 elt = XVECTOR_DATA (desc);
286 buffer = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f))->buffer;
290 tb = alloc_lcrecord_type (struct toolbar_button, &lrecord_toolbar_button);
292 XSETFRAME (tb->frame, f);
294 tb->down_glyph = Qnil;
295 tb->disabled_glyph = Qnil;
296 tb->cap_up_glyph = Qnil;
297 tb->cap_down_glyph = Qnil;
298 tb->cap_disabled_glyph = Qnil;
300 tb->enabled_p = Qnil;
301 tb->help_string = Qnil;
305 tb->pushright = pushright;
307 tb->x = tb->y = tb->width = tb->height = -1;
310 XSETTOOLBAR_BUTTON (retval, tb);
312 /* Let's make sure nothing gets mucked up by the potential call to
313 eval farther down. */
314 GCPRO2 (retval, desc);
316 glyphs = (CONSP (elt[0]) ? elt[0] : symbol_value_in_buffer (elt[0], buffer));
318 /* If this is true we have a blank, otherwise it is an actual
320 if (KEYWORDP (glyphs))
325 int len = XVECTOR_LENGTH (desc);
333 for (pos = 0; pos < len; pos += 2)
335 Lisp_Object key = elt[pos];
336 Lisp_Object val = elt[pos + 1];
338 if (EQ (key, Q_style))
342 if (EQ (val, Q2D) || EQ (val, Q2d))
344 if (!EQ (Qnil, tb->up_glyph) || !EQ (Qt, tb->disabled_glyph))
347 tb->disabled_glyph = Qt;
351 else if (EQ (val, Q3D) || (EQ (val, Q3d)))
353 if (!EQ (Qt, tb->up_glyph) || !EQ (Qnil, tb->disabled_glyph))
356 tb->disabled_glyph = Qnil;
361 else if (EQ (key, Q_size))
365 if (!EQ (val, tb->down_glyph))
367 tb->down_glyph = val;
375 /* The default style is 3D. */
376 if (!EQ (Qt, tb->up_glyph) || !EQ (Qnil, tb->disabled_glyph))
379 tb->disabled_glyph = Qnil;
386 /* The default width is set to nil. The device specific
387 code will fill it in at its discretion. */
388 if (!NILP (tb->down_glyph))
390 tb->down_glyph = Qnil;
395 /* The rest of these fields are not used by blanks. We make
396 sure they are nulled out in case this button object formerly
397 represented a real button. */
398 if (!NILP (tb->callback)
399 || !NILP (tb->enabled_p)
400 || !NILP (tb->help_string))
402 tb->cap_up_glyph = Qnil;
403 tb->cap_down_glyph = Qnil;
404 tb->cap_disabled_glyph = Qnil;
406 tb->enabled_p = Qnil;
407 tb->help_string = Qnil;
419 /* We know that we at least have an up_glyph. Well, no, we
420 don't. The user may have changed the button glyph on us. */
423 if (!EQ (XCAR (glyphs), tb->up_glyph))
425 tb->up_glyph = XCAR (glyphs);
428 glyphs = XCDR (glyphs);
433 /* We might have a down_glyph. */
436 if (!EQ (XCAR (glyphs), tb->down_glyph))
438 tb->down_glyph = XCAR (glyphs);
441 glyphs = XCDR (glyphs);
444 tb->down_glyph = Qnil;
446 /* We might have a disabled_glyph. */
449 if (!EQ (XCAR (glyphs), tb->disabled_glyph))
451 tb->disabled_glyph = XCAR (glyphs);
454 glyphs = XCDR (glyphs);
457 tb->disabled_glyph = Qnil;
459 /* We might have a cap_up_glyph. */
462 if (!EQ (XCAR (glyphs), tb->cap_up_glyph))
464 tb->cap_up_glyph = XCAR (glyphs);
467 glyphs = XCDR (glyphs);
470 tb->cap_up_glyph = Qnil;
472 /* We might have a cap_down_glyph. */
475 if (!EQ (XCAR (glyphs), tb->cap_down_glyph))
477 tb->cap_down_glyph = XCAR (glyphs);
480 glyphs = XCDR (glyphs);
483 tb->cap_down_glyph = Qnil;
485 /* We might have a cap_disabled_glyph. */
488 if (!EQ (XCAR (glyphs), tb->cap_disabled_glyph))
490 tb->cap_disabled_glyph = XCAR (glyphs);
495 tb->cap_disabled_glyph = Qnil;
497 /* Update the callback. */
498 if (!EQ (tb->callback, elt[1]))
500 tb->callback = elt[1];
501 /* This does not have an impact on the display properties of the
502 button so we do not mark it as dirty if it has changed. */
505 /* Update the enabled field. */
506 if (!EQ (tb->enabled_p, elt[2]))
508 tb->enabled_p = elt[2];
512 /* We always do the following because if the enabled status is
513 determined by a function its decision may change without us being
514 able to detect it. */
516 int old_enabled = tb->enabled;
518 if (NILP (tb->enabled_p))
520 else if (EQ (tb->enabled_p, Qt))
524 if (NILP (tb->enabled_p) || EQ (tb->enabled_p, Qt))
525 /* short-circuit the common case for speed */
526 tb->enabled = !NILP (tb->enabled_p);
530 eval_in_buffer_trapping_errors
531 ("Error in toolbar enabled-p form",
534 (XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f)))),
536 if (UNBOUNDP (result))
537 /* #### if there was an error in the enabled-p
538 form, should we pretend like it's enabled
542 tb->enabled = !NILP (result);
546 if (old_enabled != tb->enabled)
550 /* Update the help echo string. */
551 if (!EQ (tb->help_string, elt[3]))
553 tb->help_string = elt[3];
554 /* This does not have an impact on the display properties of the
555 button so we do not mark it as dirty if it has changed. */
559 /* If this flag changes, the position is changing for sure unless
560 some very unlikely geometry occurs. */
561 if (tb->pushright != pushright)
563 tb->pushright = pushright;
567 /* The position and size fields are only manipulated in the
568 device-dependent code. */
574 mark_frame_toolbar_buttons_dirty (struct frame *f, enum toolbar_pos pos)
576 Lisp_Object button = FRAME_TOOLBAR_BUTTONS (f, pos);
578 while (!NILP (button))
580 struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
588 compute_frame_toolbar_buttons (struct frame *f, enum toolbar_pos pos,
591 Lisp_Object buttons, prev_button, first_button;
592 Lisp_Object orig_toolbar = toolbar;
593 int pushright_seen = 0;
594 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
596 first_button = FRAME_TOOLBAR_BUTTONS (f, pos);
597 buttons = prev_button = first_button;
599 /* Yes, we're being paranoid. */
600 GCPRO5 (toolbar, buttons, prev_button, first_button, orig_toolbar);
604 /* The output mechanisms will take care of clearing the former
610 if (!CONSP (toolbar))
611 signal_simple_error ("toolbar description must be a list", toolbar);
613 /* First synchronize any existing buttons. */
614 while (!NILP (toolbar) && !NILP (buttons))
616 struct toolbar_button *tb;
618 if (NILP (XCAR (toolbar)))
622 ("more than one partition (nil) in toolbar description",
629 tb = XTOOLBAR_BUTTON (buttons);
630 update_toolbar_button (f, tb, XCAR (toolbar), pushright_seen);
631 prev_button = buttons;
635 toolbar = XCDR (toolbar);
638 /* If we hit the end of the toolbar, then clean up any excess
639 buttons and return. */
644 /* If this is the case the only thing we saw was a
646 if (EQ (buttons, first_button))
652 XTOOLBAR_BUTTON (prev_button)->next = Qnil;
658 /* At this point there are more buttons on the toolbar than we
659 actually have in existence. */
660 while (!NILP (toolbar))
662 Lisp_Object new_button;
664 if (NILP (XCAR (toolbar)))
668 ("more than one partition (nil) in toolbar description",
675 new_button = update_toolbar_button (f, NULL, XCAR (toolbar),
678 if (NILP (first_button))
680 first_button = prev_button = new_button;
684 XTOOLBAR_BUTTON (prev_button)->next = new_button;
685 prev_button = new_button;
689 toolbar = XCDR (toolbar);
697 set_frame_toolbar (struct frame *f, enum toolbar_pos pos)
699 struct window *w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f));
700 Lisp_Object toolbar = w->toolbar[pos];
701 f->toolbar_buttons[pos] = (FRAME_REAL_TOOLBAR_VISIBLE (f, pos)
702 ? compute_frame_toolbar_buttons (f, pos, toolbar)
707 compute_frame_toolbars_data (struct frame *f)
709 set_frame_toolbar (f, TOP_TOOLBAR);
710 set_frame_toolbar (f, BOTTOM_TOOLBAR);
711 set_frame_toolbar (f, LEFT_TOOLBAR);
712 set_frame_toolbar (f, RIGHT_TOOLBAR);
715 /* Update the toolbar geometry separately from actually displaying the
716 toolbar. This is necessary because both the gutter and the toolbar
717 are competing for redisplay cycles and, unfortunately, gutter
718 updates happen late in the game. Firstly they are done inside of
719 redisplay proper and secondly subcontrols may not get moved until
720 the next screen refresh. Only after subcontrols have been moved to
721 their final destinations can we be certain of updating the
722 toolbar. Under X this probably is exacerbated by the toolbar button
723 dirty flags which prevent updates happening when they possibly
726 update_frame_toolbars_geometry (struct frame *f)
728 struct device *d = XDEVICE (f->device);
730 if (DEVICE_SUPPORTS_TOOLBARS_P (d)
731 && (f->toolbar_changed
732 || f->frame_layout_changed
738 /* We're not officially "in redisplay", so we still have a
739 chance to re-layout toolbars and windows. This is done here,
740 because toolbar is the only thing which currently might
741 necessitate this layout, as it is outside any windows. We
742 take care not to change size if toolbar geometry is really
743 unchanged, as it will hose windows whose pixsizes are not
744 multiple of character sizes. */
746 for (pos = 0; pos < 4; pos++)
747 if (FRAME_REAL_TOOLBAR_SIZE (f, pos)
748 != FRAME_CURRENT_TOOLBAR_SIZE (f, pos))
751 pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
753 change_frame_size (f, height, width, 0);
754 MARK_FRAME_LAYOUT_CHANGED (f);
758 for (pos = 0; pos < 4; pos++) {
759 f->current_toolbar_size[pos] = FRAME_REAL_TOOLBAR_SIZE (f, pos);
762 /* Removed the check for the minibuffer here. We handle this
763 more correctly now by consistently using
764 FRAME_LAST_NONMINIBUF_WINDOW instead of FRAME_SELECTED_WINDOW
765 throughout the toolbar code. */
766 compute_frame_toolbars_data (f);
768 /* Clear the previous toolbar locations. If we do it later
769 (after redisplay) we end up clearing what we have just
771 MAYBE_DEVMETH (d, clear_frame_toolbars, (f));
775 /* Actually redisplay the toolbar buttons. */
777 update_frame_toolbars (struct frame *f)
779 struct device *d = XDEVICE (f->device);
781 if (DEVICE_SUPPORTS_TOOLBARS_P (d)
782 && (f->toolbar_changed
783 || f->frame_layout_changed
787 DEVMETH (d, output_frame_toolbars, (f));
790 f->toolbar_changed = 0;
794 init_frame_toolbars (struct frame *f)
796 struct device *d = XDEVICE (f->device);
798 if (DEVICE_SUPPORTS_TOOLBARS_P (d))
803 compute_frame_toolbars_data (f);
804 XSETFRAME (frame, f);
805 call_critical_lisp_code (XDEVICE (FRAME_DEVICE (f)),
806 Qinit_toolbar_from_resources,
808 MAYBE_DEVMETH (d, initialize_frame_toolbars, (f));
810 /* We are here as far in frame creation so cached specifiers are
811 already recomputed, and possibly modified by resource
812 initialization. Remember current toolbar geometry so next
813 redisplay will not needlessly relayout toolbars. */
814 for (pos = 0; pos < 4; pos++)
815 f->current_toolbar_size[pos] = FRAME_REAL_TOOLBAR_SIZE (f, pos);
820 init_device_toolbars (struct device *d)
824 XSETDEVICE (device, d);
825 if (DEVICE_SUPPORTS_TOOLBARS_P (d))
826 call_critical_lisp_code (d,
827 Qinit_toolbar_from_resources,
832 init_global_toolbars (struct device *d)
834 if (DEVICE_SUPPORTS_TOOLBARS_P (d))
835 call_critical_lisp_code (d,
836 Qinit_toolbar_from_resources,
841 free_frame_toolbars (struct frame *f)
843 /* If we had directly allocated any memory for the toolbars instead
844 of using all Lisp_Objects this is where we would now free it. */
846 MAYBE_FRAMEMETH (f, free_frame_toolbars, (f));
850 get_toolbar_coords (struct frame *f, enum toolbar_pos pos, int *x, int *y,
851 int *width, int *height, int *vert, int for_layout)
853 int visible_top_toolbar_height, visible_bottom_toolbar_height;
854 int adjust = (for_layout ? 1 : 0);
856 /* The top and bottom toolbars take precedence over the left and
858 visible_top_toolbar_height = (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f)
859 ? FRAME_REAL_TOP_TOOLBAR_HEIGHT (f) +
860 2 * FRAME_REAL_TOP_TOOLBAR_BORDER_WIDTH (f)
862 visible_bottom_toolbar_height = (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f)
863 ? FRAME_REAL_BOTTOM_TOOLBAR_HEIGHT (f) +
865 FRAME_REAL_BOTTOM_TOOLBAR_BORDER_WIDTH (f)
868 /* We adjust the width and height by one to give us a narrow border
869 at the outside edges. However, when we are simply determining
870 toolbar location we don't want to do that. */
876 *y = 0; /* #### should be 1 if no menubar */
877 *width = FRAME_PIXWIDTH (f) - 2;
878 *height = FRAME_REAL_TOP_TOOLBAR_HEIGHT (f) +
879 2 * FRAME_REAL_TOP_TOOLBAR_BORDER_WIDTH (f) - adjust;
884 *y = FRAME_PIXHEIGHT (f) - FRAME_REAL_BOTTOM_TOOLBAR_HEIGHT (f) -
885 2 * FRAME_REAL_BOTTOM_TOOLBAR_BORDER_WIDTH (f);
886 *width = FRAME_PIXWIDTH (f) - 2;
887 *height = FRAME_REAL_BOTTOM_TOOLBAR_HEIGHT (f) +
888 2 * FRAME_REAL_BOTTOM_TOOLBAR_BORDER_WIDTH (f) - adjust;
893 *y = visible_top_toolbar_height;
894 *width = FRAME_REAL_LEFT_TOOLBAR_WIDTH (f) +
895 2 * FRAME_REAL_LEFT_TOOLBAR_BORDER_WIDTH (f) - adjust;
896 *height = (FRAME_PIXHEIGHT (f) - visible_top_toolbar_height -
897 visible_bottom_toolbar_height - 1);
901 *x = FRAME_PIXWIDTH (f) - FRAME_REAL_RIGHT_TOOLBAR_WIDTH (f) -
902 2 * FRAME_REAL_RIGHT_TOOLBAR_BORDER_WIDTH (f);
903 *y = visible_top_toolbar_height;
904 *width = FRAME_REAL_RIGHT_TOOLBAR_WIDTH (f) +
905 2 * FRAME_REAL_RIGHT_TOOLBAR_BORDER_WIDTH (f) - adjust;
906 *height = (FRAME_PIXHEIGHT (f) - visible_top_toolbar_height -
907 visible_bottom_toolbar_height);
915 #define CHECK_TOOLBAR(pos) do { \
916 if (FRAME_REAL_##pos##_VISIBLE (f)) \
918 int x, y, width, height, vert; \
920 get_toolbar_coords (f, pos, &x, &y, &width, &height, &vert, 0); \
921 if ((x_coord >= x) && (x_coord < (x + width))) \
923 if ((y_coord >= y) && (y_coord < (y + height))) \
924 return FRAME_TOOLBAR_BUTTONS (f, pos); \
930 toolbar_buttons_at_pixpos (struct frame *f, int x_coord, int y_coord)
932 CHECK_TOOLBAR (TOP_TOOLBAR);
933 CHECK_TOOLBAR (BOTTOM_TOOLBAR);
934 CHECK_TOOLBAR (LEFT_TOOLBAR);
935 CHECK_TOOLBAR (RIGHT_TOOLBAR);
941 /* The device dependent code actually does the work of positioning the
942 buttons, but we are free to access that information at this
945 toolbar_button_at_pixpos (struct frame *f, int x_coord, int y_coord)
947 Lisp_Object buttons = toolbar_buttons_at_pixpos (f, x_coord, y_coord);
949 while (!NILP (buttons))
951 struct toolbar_button *tb = XTOOLBAR_BUTTON (buttons);
953 if ((x_coord >= tb->x) && (x_coord < (tb->x + tb->width)))
955 if ((y_coord >= tb->y) && (y_coord < (tb->y + tb->height)))
957 /* If we are over a blank, return nil. */
968 /* We are not over a toolbar or we are over a blank in the toolbar. */
973 /************************************************************************/
974 /* Toolbar specifier type */
975 /************************************************************************/
977 DEFINE_SPECIFIER_TYPE (toolbar);
979 #define CTB_ERROR(msg) do { \
980 maybe_signal_simple_error (msg, button, Qtoolbar, errb); \
981 RETURN_SANS_WARNINGS Qnil; \
984 /* Returns Q_style if key was :style, Qt if ok otherwise, Qnil if error. */
986 check_toolbar_button_keywords (Lisp_Object button, Lisp_Object key,
987 Lisp_Object val, Error_behavior errb)
991 maybe_signal_simple_error_2 ("Not a keyword", key, button, Qtoolbar,
996 if (EQ (key, Q_style))
1002 CTB_ERROR ("Unrecognized toolbar blank style");
1006 else if (EQ (key, Q_size))
1009 CTB_ERROR ("invalid toolbar blank size");
1013 CTB_ERROR ("invalid toolbar blank keyword");
1019 /* toolbar button spec is [pixmap-pair function enabled-p help]
1020 or [:style 2d-or-3d :size width-or-height] */
1022 DEFUN ("check-toolbar-button-syntax", Fcheck_toolbar_button_syntax, 1, 2, 0, /*
1023 Verify the syntax of entry BUTTON in a toolbar description list.
1024 If you want to verify the syntax of a toolbar description list as a
1025 whole, use `check-valid-instantiator' with a specifier type of 'toolbar.
1029 Lisp_Object *elt, glyphs, value;
1031 Error_behavior errb = decode_error_behavior_flag (noerror);
1033 if (!VECTORP (button))
1034 CTB_ERROR ("toolbar button descriptors must be vectors");
1035 elt = XVECTOR_DATA (button);
1037 if (XVECTOR_LENGTH (button) == 2)
1039 if (!EQ (Q_style, check_toolbar_button_keywords (button, elt[0],
1041 CTB_ERROR ("must specify toolbar blank style");
1046 if (XVECTOR_LENGTH (button) != 4)
1047 CTB_ERROR ("toolbar button descriptors must be 2 or 4 long");
1049 /* The first element must be a list of glyphs of length 1-6. The
1050 first entry is the pixmap for the up state, the second for the
1051 down state, the third for the disabled state, the fourth for the
1052 captioned up state, the fifth for the captioned down state and
1053 the sixth for the captioned disabled state. Only the up state is
1055 if (!CONSP (elt[0]))
1057 /* We can't check the buffer-local here because we don't know
1058 which buffer to check in. #### I think this is a bad thing.
1059 See if we can't get enough information to this function so
1062 #### Wrong. We shouldn't be checking the value at all here.
1063 The user might set or change the value at any time. */
1064 value = Fsymbol_value (elt[0]);
1068 if (KEYWORDP (elt[0]))
1072 if (EQ (Q_style, check_toolbar_button_keywords (button, elt[0],
1077 if (EQ (Q_style, check_toolbar_button_keywords (button, elt[2],
1083 CTB_ERROR ("must specify toolbar blank style");
1084 else if (EQ (elt[0], elt[2]))
1086 ("duplicate keywords in toolbar button blank description");
1091 CTB_ERROR ("first element of button must be a list (of glyphs)");
1097 len = XINT (Flength (value));
1099 CTB_ERROR ("toolbar button glyph list must have at least 1 entry");
1102 CTB_ERROR ("toolbar button glyph list can have at most 6 entries");
1105 while (!NILP (glyphs))
1107 if (!GLYPHP (XCAR (glyphs)))
1109 /* We allow nil for the down and disabled glyphs but not for
1111 if (EQ (glyphs, value) || !NILP (XCAR (glyphs)))
1114 ("all elements of toolbar button glyph list must be glyphs.");
1117 glyphs = XCDR (glyphs);
1120 /* The second element is the function to run when the button is
1121 activated. We do not do any checking on it because it is legal
1122 for the function to not be defined until after the toolbar is.
1123 It is the user's problem to get this right.
1125 The third element is either a boolean indicating the enabled
1126 status or a function used to determine it. Again, it is the
1127 user's problem if this is wrong.
1129 The fourth element, if not nil, must be a string which will be
1130 displayed as the help echo. */
1132 /* #### This should be allowed to be a function returning a string
1133 as well as just a string. */
1134 if (!NILP (elt[3]) && !STRINGP (elt[3]))
1135 CTB_ERROR ("toolbar button help echo string must be a string");
1142 toolbar_validate (Lisp_Object instantiator)
1144 int pushright_seen = 0;
1147 if (NILP (instantiator))
1150 if (!CONSP (instantiator))
1151 signal_simple_error ("Toolbar spec must be list or nil", instantiator);
1153 for (rest = instantiator; !NILP (rest); rest = XCDR (rest))
1156 signal_simple_error ("Bad list in toolbar spec", instantiator);
1158 if (NILP (XCAR (rest)))
1162 ("More than one partition (nil) in instantiator description");
1167 Fcheck_toolbar_button_syntax (XCAR (rest), Qnil);
1172 toolbar_after_change (Lisp_Object specifier, Lisp_Object locale)
1174 /* #### This is overkill. I really need to rethink the after-change
1175 functions to make them easier to use. */
1176 MARK_TOOLBAR_CHANGED;
1179 DEFUN ("toolbar-specifier-p", Ftoolbar_specifier_p, 1, 1, 0, /*
1180 Return non-nil if OBJECT is a toolbar specifier.
1182 See `make-toolbar-specifier' for a description of possible toolbar
1187 return TOOLBAR_SPECIFIERP (object) ? Qt : Qnil;
1192 Helper for invalidating the real specifier when default
1193 specifier caching changes
1196 recompute_overlaying_specifier (Lisp_Object real_one[4])
1198 enum toolbar_pos pos = decode_toolbar_position (Vdefault_toolbar_position);
1199 Fset_specifier_dirty_flag (real_one[pos]);
1203 toolbar_specs_changed (Lisp_Object specifier, struct window *w,
1206 /* This could be smarter but I doubt that it would make any
1207 noticeable difference given the infrequency with which this is
1208 probably going to be called.
1210 MARK_TOOLBAR_CHANGED;
1214 default_toolbar_specs_changed (Lisp_Object specifier, struct window *w,
1217 recompute_overlaying_specifier (Vtoolbar);
1221 default_toolbar_size_changed_in_frame (Lisp_Object specifier, struct frame *f,
1224 recompute_overlaying_specifier (Vtoolbar_size);
1228 default_toolbar_border_width_changed_in_frame (Lisp_Object specifier,
1232 recompute_overlaying_specifier (Vtoolbar_border_width);
1236 default_toolbar_visible_p_changed_in_frame (Lisp_Object specifier,
1240 recompute_overlaying_specifier (Vtoolbar_visible_p);
1244 toolbar_geometry_changed_in_window (Lisp_Object specifier, struct window *w,
1247 MARK_TOOLBAR_CHANGED;
1248 MARK_WINDOWS_CHANGED (w);
1252 default_toolbar_size_changed_in_window (Lisp_Object specifier, struct window *w,
1255 recompute_overlaying_specifier (Vtoolbar_size);
1259 default_toolbar_border_width_changed_in_window (Lisp_Object specifier,
1263 recompute_overlaying_specifier (Vtoolbar_border_width);
1267 default_toolbar_visible_p_changed_in_window (Lisp_Object specifier,
1271 recompute_overlaying_specifier (Vtoolbar_visible_p);
1275 toolbar_buttons_captioned_p_changed (Lisp_Object specifier, struct window *w,
1278 /* This could be smarter but I doubt that it would make any
1279 noticeable difference given the infrequency with which this is
1280 probably going to be called. */
1281 MARK_TOOLBAR_CHANGED;
1286 syms_of_toolbar (void)
1288 INIT_LRECORD_IMPLEMENTATION (toolbar_button);
1290 defsymbol (&Qtoolbar_buttonp, "toolbar-button-p");
1291 defsymbol (&Q2D, "2D");
1292 defsymbol (&Q3D, "3D");
1293 defsymbol (&Q2d, "2d");
1294 defsymbol (&Q3d, "3d");
1295 defsymbol (&Q_size, ":size"); Fset (Q_size, Q_size);
1297 defsymbol (&Qinit_toolbar_from_resources, "init-toolbar-from-resources");
1298 DEFSUBR (Ftoolbar_button_p);
1299 DEFSUBR (Ftoolbar_button_callback);
1300 DEFSUBR (Ftoolbar_button_help_string);
1301 DEFSUBR (Ftoolbar_button_enabled_p);
1302 DEFSUBR (Fset_toolbar_button_down_flag);
1303 DEFSUBR (Fcheck_toolbar_button_syntax);
1304 DEFSUBR (Fset_default_toolbar_position);
1305 DEFSUBR (Fdefault_toolbar_position);
1306 DEFSUBR (Ftoolbar_specifier_p);
1310 vars_of_toolbar (void)
1312 staticpro (&Vdefault_toolbar_position);
1313 Vdefault_toolbar_position = Qtop;
1315 #ifdef HAVE_WINDOW_SYSTEM
1316 Fprovide (Qtoolbar);
1321 specifier_type_create_toolbar (void)
1323 INITIALIZE_SPECIFIER_TYPE (toolbar, "toolbar", "toolbar-specifier-p");
1325 SPECIFIER_HAS_METHOD (toolbar, validate);
1326 SPECIFIER_HAS_METHOD (toolbar, after_change);
1330 reinit_specifier_type_create_toolbar (void)
1332 REINITIALIZE_SPECIFIER_TYPE (toolbar);
1336 specifier_vars_of_toolbar (void)
1340 DEFVAR_SPECIFIER ("default-toolbar", &Vdefault_toolbar /*
1341 Specifier for a fallback toolbar.
1342 Use `set-specifier' to change this.
1344 The position of this toolbar is specified in the function
1345 `default-toolbar-position'. If the corresponding position-specific
1346 toolbar (e.g. `top-toolbar' if `default-toolbar-position' is 'top)
1347 does not specify a toolbar in a particular domain (usually a window),
1348 then the value of `default-toolbar' in that domain, if any, will be
1351 Note that the toolbar at any particular position will not be
1352 displayed unless its visibility flag is true and its thickness
1353 \(width or height, depending on orientation) is non-zero. The
1354 visibility is controlled by the specifiers `top-toolbar-visible-p',
1355 `bottom-toolbar-visible-p', `left-toolbar-visible-p', and
1356 `right-toolbar-visible-p', and the thickness is controlled by the
1357 specifiers `top-toolbar-height', `bottom-toolbar-height',
1358 `left-toolbar-width', and `right-toolbar-width'.
1360 Note that one of the four visibility specifiers inherits from
1361 `default-toolbar-visibility' and one of the four thickness
1362 specifiers inherits from either `default-toolbar-width' or
1363 `default-toolbar-height' (depending on orientation), just
1364 like for the toolbar description specifiers (e.g. `top-toolbar')
1367 Therefore, if you are setting `default-toolbar', you should control
1368 the visibility and thickness using `default-toolbar-visible-p',
1369 `default-toolbar-width', and `default-toolbar-height', rather than
1370 using position-specific specifiers. That way, you will get sane
1371 behavior if the user changes the default toolbar position.
1373 The format of the instantiator for a toolbar is a list of
1374 toolbar-button-descriptors. Each toolbar-button-descriptor
1375 is a vector in one of the following formats:
1377 [GLYPH-LIST FUNCTION ENABLED-P HELP] or
1378 [:style 2D-OR-3D] or
1379 [:style 2D-OR-3D :size WIDTH-OR-HEIGHT] or
1380 [:size WIDTH-OR-HEIGHT :style 2D-OR-3D]
1382 Optionally, one of the toolbar-button-descriptors may be nil
1383 instead of a vector; this signifies the division between
1384 the toolbar buttons that are to be displayed flush-left,
1385 and the buttons to be displayed flush-right.
1387 The first vector format above specifies a normal toolbar button;
1388 the others specify blank areas in the toolbar.
1390 For the first vector format:
1392 -- GLYPH-LIST should be a list of one to six glyphs (as created by
1393 `make-glyph') or a symbol whose value is such a list. The first
1394 glyph, which must be provided, is the glyph used to display the
1395 toolbar button when it is in the "up" (not pressed) state. The
1396 optional second glyph is for displaying the button when it is in
1397 the "down" (pressed) state. The optional third glyph is for when
1398 the button is disabled. The optional fourth, fifth and sixth glyphs
1399 are used to specify captioned versions for the up, down and disabled
1400 states respectively. The function `toolbar-make-button-list' is
1401 useful in creating these glyph lists. The specifier variable
1402 `toolbar-buttons-captioned-p' controls which glyphs are actually used.
1404 -- Even if you do not provide separate down-state and disabled-state
1405 glyphs, the user will still get visual feedback to indicate which
1406 state the button is in. Buttons in the up-state are displayed
1407 with a shadowed border that gives a raised appearance to the
1408 button. Buttons in the down-state are displayed with shadows that
1409 give a recessed appearance. Buttons in the disabled state are
1410 displayed with no shadows, giving a 2-d effect.
1412 -- If some of the toolbar glyphs are not provided, they inherit as follows:
1416 DISABLED: disabled -> up
1417 CAP-UP: cap-up -> up
1418 CAP-DOWN: cap-down -> cap-up -> down -> up
1419 CAP-DISABLED: cap-disabled -> cap-up -> disabled -> up
1421 -- The second element FUNCTION is a function to be called when the
1422 toolbar button is activated (i.e. when the mouse is released over
1423 the toolbar button, if the press occurred in the toolbar). It
1424 can be any form accepted by `call-interactively', since this is
1427 -- The third element ENABLED-P specifies whether the toolbar button
1428 is enabled (disabled buttons do nothing when they are activated,
1429 and are displayed differently; see above). It should be either
1430 a boolean or a form that evaluates to a boolean.
1432 -- The fourth element HELP, if non-nil, should be a string. This
1433 string is displayed in the echo area when the mouse passes over
1436 For the other vector formats (specifying blank areas of the toolbar):
1438 -- 2D-OR-3D should be one of the symbols '2d or '3d, indicating
1439 whether the area is displayed with shadows (giving it a raised,
1440 3-d appearance) or without shadows (giving it a flat appearance).
1442 -- WIDTH-OR-HEIGHT specifies the length, in pixels, of the blank
1443 area. If omitted, it defaults to a device-specific value
1444 (8 pixels for X devices).
1447 Vdefault_toolbar = Fmake_specifier (Qtoolbar);
1448 /* #### It would be even nicer if the specifier caching
1449 automatically knew about specifier fallbacks, so we didn't
1450 have to do it ourselves. */
1451 set_specifier_caching (Vdefault_toolbar,
1452 offsetof (struct window, default_toolbar),
1453 default_toolbar_specs_changed,
1456 DEFVAR_SPECIFIER ("top-toolbar",
1457 &Vtoolbar[TOP_TOOLBAR] /*
1458 Specifier for the toolbar at the top of the frame.
1459 Use `set-specifier' to change this.
1460 See `default-toolbar' for a description of a valid toolbar instantiator.
1462 Vtoolbar[TOP_TOOLBAR] = Fmake_specifier (Qtoolbar);
1463 set_specifier_caching (Vtoolbar[TOP_TOOLBAR],
1464 offsetof (struct window, toolbar[TOP_TOOLBAR]),
1465 toolbar_specs_changed,
1468 DEFVAR_SPECIFIER ("bottom-toolbar",
1469 &Vtoolbar[BOTTOM_TOOLBAR] /*
1470 Specifier for the toolbar at the bottom of the frame.
1471 Use `set-specifier' to change this.
1472 See `default-toolbar' for a description of a valid toolbar instantiator.
1474 Note that, unless the `default-toolbar-position' is `bottom', by
1475 default the height of the bottom toolbar (controlled by
1476 `bottom-toolbar-height') is 0; thus, a bottom toolbar will not be
1477 displayed even if you provide a value for `bottom-toolbar'.
1479 Vtoolbar[BOTTOM_TOOLBAR] = Fmake_specifier (Qtoolbar);
1480 set_specifier_caching (Vtoolbar[BOTTOM_TOOLBAR],
1481 offsetof (struct window, toolbar[BOTTOM_TOOLBAR]),
1482 toolbar_specs_changed,
1485 DEFVAR_SPECIFIER ("left-toolbar",
1486 &Vtoolbar[LEFT_TOOLBAR] /*
1487 Specifier for the toolbar at the left edge of the frame.
1488 Use `set-specifier' to change this.
1489 See `default-toolbar' for a description of a valid toolbar instantiator.
1491 Note that, unless the `default-toolbar-position' is `left', by
1492 default the height of the left toolbar (controlled by
1493 `left-toolbar-width') is 0; thus, a left toolbar will not be
1494 displayed even if you provide a value for `left-toolbar'.
1496 Vtoolbar[LEFT_TOOLBAR] = Fmake_specifier (Qtoolbar);
1497 set_specifier_caching (Vtoolbar[LEFT_TOOLBAR],
1498 offsetof (struct window, toolbar[LEFT_TOOLBAR]),
1499 toolbar_specs_changed,
1502 DEFVAR_SPECIFIER ("right-toolbar",
1503 &Vtoolbar[RIGHT_TOOLBAR] /*
1504 Specifier for the toolbar at the right edge of the frame.
1505 Use `set-specifier' to change this.
1506 See `default-toolbar' for a description of a valid toolbar instantiator.
1508 Note that, unless the `default-toolbar-position' is `right', by
1509 default the height of the right toolbar (controlled by
1510 `right-toolbar-width') is 0; thus, a right toolbar will not be
1511 displayed even if you provide a value for `right-toolbar'.
1513 Vtoolbar[RIGHT_TOOLBAR] = Fmake_specifier (Qtoolbar);
1514 set_specifier_caching (Vtoolbar[RIGHT_TOOLBAR],
1515 offsetof (struct window, toolbar[RIGHT_TOOLBAR]),
1516 toolbar_specs_changed,
1519 /* initially, top inherits from default; this can be
1520 changed with `set-default-toolbar-position'. */
1521 fb = list1 (Fcons (Qnil, Qnil));
1522 set_specifier_fallback (Vdefault_toolbar, fb);
1523 set_specifier_fallback (Vtoolbar[TOP_TOOLBAR], Vdefault_toolbar);
1524 set_specifier_fallback (Vtoolbar[BOTTOM_TOOLBAR], fb);
1525 set_specifier_fallback (Vtoolbar[LEFT_TOOLBAR], fb);
1526 set_specifier_fallback (Vtoolbar[RIGHT_TOOLBAR], fb);
1528 DEFVAR_SPECIFIER ("default-toolbar-height", &Vdefault_toolbar_height /*
1529 *Height of the default toolbar, if it's oriented horizontally.
1530 This is a specifier; use `set-specifier' to change it.
1532 The position of the default toolbar is specified by the function
1533 `set-default-toolbar-position'. If the corresponding position-specific
1534 toolbar thickness specifier (e.g. `top-toolbar-height' if
1535 `default-toolbar-position' is 'top) does not specify a thickness in a
1536 particular domain (a window or a frame), then the value of
1537 `default-toolbar-height' or `default-toolbar-width' (depending on the
1538 toolbar orientation) in that domain, if any, will be used instead.
1540 Note that `default-toolbar-height' is only used when
1541 `default-toolbar-position' is 'top or 'bottom, and `default-toolbar-width'
1542 is only used when `default-toolbar-position' is 'left or 'right.
1544 Note that all of the position-specific toolbar thickness specifiers
1545 have a fallback value of zero when they do not correspond to the
1546 default toolbar. Therefore, you will have to set a non-zero thickness
1547 value if you want a position-specific toolbar to be displayed.
1549 Internally, toolbar thickness specifiers are instantiated in both
1550 window and frame domains, for different purposes. The value in the
1551 domain of a frame's selected window specifies the actual toolbar
1552 thickness that you will see in that frame. The value in the domain of
1553 a frame itself specifies the toolbar thickness that is used in frame
1554 geometry calculations.
1556 Thus, for example, if you set the frame width to 80 characters and the
1557 left toolbar width for that frame to 68 pixels, then the frame will
1558 be sized to fit 80 characters plus a 68-pixel left toolbar. If you
1559 then set the left toolbar width to 0 for a particular buffer (or if
1560 that buffer does not specify a left toolbar or has a nil value
1561 specified for `left-toolbar-visible-p'), you will find that, when
1562 that buffer is displayed in the selected window, the window will have
1563 a width of 86 or 87 characters -- the frame is sized for a 68-pixel
1564 left toolbar but the selected window specifies that the left toolbar
1565 is not visible, so it is expanded to take up the slack.
1567 Vdefault_toolbar_height = Fmake_specifier (Qnatnum);
1568 set_specifier_caching (Vdefault_toolbar_height,
1569 offsetof (struct window, default_toolbar_height),
1570 default_toolbar_size_changed_in_window,
1571 offsetof (struct frame, default_toolbar_height),
1572 default_toolbar_size_changed_in_frame, 0);
1574 DEFVAR_SPECIFIER ("default-toolbar-width", &Vdefault_toolbar_width /*
1575 *Width of the default toolbar, if it's oriented vertically.
1576 This is a specifier; use `set-specifier' to change it.
1578 See `default-toolbar-height' for more information.
1580 Vdefault_toolbar_width = Fmake_specifier (Qnatnum);
1581 set_specifier_caching (Vdefault_toolbar_width,
1582 offsetof (struct window, default_toolbar_width),
1583 default_toolbar_size_changed_in_window,
1584 offsetof (struct frame, default_toolbar_width),
1585 default_toolbar_size_changed_in_frame, 0);
1587 DEFVAR_SPECIFIER ("top-toolbar-height",
1588 &Vtoolbar_size[TOP_TOOLBAR] /*
1589 *Height of the top toolbar.
1590 This is a specifier; use `set-specifier' to change it.
1592 See `default-toolbar-height' for more information.
1594 Vtoolbar_size[TOP_TOOLBAR] = Fmake_specifier (Qnatnum);
1595 set_specifier_caching (Vtoolbar_size[TOP_TOOLBAR],
1596 offsetof (struct window, toolbar_size[TOP_TOOLBAR]),
1597 toolbar_geometry_changed_in_window,
1598 offsetof (struct frame, toolbar_size[TOP_TOOLBAR]),
1599 frame_size_slipped, 0);
1601 DEFVAR_SPECIFIER ("bottom-toolbar-height",
1602 &Vtoolbar_size[BOTTOM_TOOLBAR] /*
1603 *Height of the bottom toolbar.
1604 This is a specifier; use `set-specifier' to change it.
1606 See `default-toolbar-height' for more information.
1608 Vtoolbar_size[BOTTOM_TOOLBAR] = Fmake_specifier (Qnatnum);
1609 set_specifier_caching (Vtoolbar_size[BOTTOM_TOOLBAR],
1610 offsetof (struct window, toolbar_size[BOTTOM_TOOLBAR]),
1611 toolbar_geometry_changed_in_window,
1612 offsetof (struct frame, toolbar_size[BOTTOM_TOOLBAR]),
1613 frame_size_slipped, 0);
1615 DEFVAR_SPECIFIER ("left-toolbar-width",
1616 &Vtoolbar_size[LEFT_TOOLBAR] /*
1617 *Width of left toolbar.
1618 This is a specifier; use `set-specifier' to change it.
1620 See `default-toolbar-height' for more information.
1622 Vtoolbar_size[LEFT_TOOLBAR] = Fmake_specifier (Qnatnum);
1623 set_specifier_caching (Vtoolbar_size[LEFT_TOOLBAR],
1624 offsetof (struct window, toolbar_size[LEFT_TOOLBAR]),
1625 toolbar_geometry_changed_in_window,
1626 offsetof (struct frame, toolbar_size[LEFT_TOOLBAR]),
1627 frame_size_slipped, 0);
1629 DEFVAR_SPECIFIER ("right-toolbar-width",
1630 &Vtoolbar_size[RIGHT_TOOLBAR] /*
1631 *Width of right toolbar.
1632 This is a specifier; use `set-specifier' to change it.
1634 See `default-toolbar-height' for more information.
1636 Vtoolbar_size[RIGHT_TOOLBAR] = Fmake_specifier (Qnatnum);
1637 set_specifier_caching (Vtoolbar_size[RIGHT_TOOLBAR],
1638 offsetof (struct window, toolbar_size[RIGHT_TOOLBAR]),
1639 toolbar_geometry_changed_in_window,
1640 offsetof (struct frame, toolbar_size[RIGHT_TOOLBAR]),
1641 frame_size_slipped, 0);
1645 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1648 fb = Fcons (Fcons (list1 (Qgtk), make_int (DEFAULT_TOOLBAR_HEIGHT)), fb);
1650 #ifdef HAVE_X_WINDOWS
1651 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_TOOLBAR_HEIGHT)), fb);
1653 #ifdef HAVE_MS_WINDOWS
1654 fb = Fcons (Fcons (list1 (Qmswindows),
1655 make_int (MSWINDOWS_DEFAULT_TOOLBAR_HEIGHT)), fb);
1658 set_specifier_fallback (Vdefault_toolbar_height, fb);
1662 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1665 fb = Fcons (Fcons (list1 (Qgtk), make_int (DEFAULT_TOOLBAR_WIDTH)), fb);
1667 #ifdef HAVE_X_WINDOWS
1668 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_TOOLBAR_WIDTH)), fb);
1670 #ifdef HAVE_MS_WINDOWS
1671 fb = Fcons (Fcons (list1 (Qmswindows),
1672 make_int (MSWINDOWS_DEFAULT_TOOLBAR_WIDTH)), fb);
1675 set_specifier_fallback (Vdefault_toolbar_width, fb);
1677 set_specifier_fallback (Vtoolbar_size[TOP_TOOLBAR], Vdefault_toolbar_height);
1678 fb = list1 (Fcons (Qnil, Qzero));
1679 set_specifier_fallback (Vtoolbar_size[BOTTOM_TOOLBAR], fb);
1680 set_specifier_fallback (Vtoolbar_size[LEFT_TOOLBAR], fb);
1681 set_specifier_fallback (Vtoolbar_size[RIGHT_TOOLBAR], fb);
1683 DEFVAR_SPECIFIER ("default-toolbar-border-width",
1684 &Vdefault_toolbar_border_width /*
1685 *Width of the border around the default toolbar.
1686 This is a specifier; use `set-specifier' to change it.
1688 The position of the default toolbar is specified by the function
1689 `set-default-toolbar-position'. If the corresponding position-specific
1690 toolbar border width specifier (e.g. `top-toolbar-border-width' if
1691 `default-toolbar-position' is 'top) does not specify a border width in a
1692 particular domain (a window or a frame), then the value of
1693 `default-toolbar-border-width' in that domain, if any, will be used
1696 Internally, toolbar border width specifiers are instantiated in both
1697 window and frame domains, for different purposes. The value in the
1698 domain of a frame's selected window specifies the actual toolbar border
1699 width that you will see in that frame. The value in the domain of a
1700 frame itself specifies the toolbar border width that is used in frame
1701 geometry calculations. Changing the border width value in the frame
1702 domain will result in a size change in the frame itself, while changing
1703 the value in a window domain will not.
1705 Vdefault_toolbar_border_width = Fmake_specifier (Qnatnum);
1706 set_specifier_caching (Vdefault_toolbar_border_width,
1707 offsetof (struct window, default_toolbar_border_width),
1708 default_toolbar_border_width_changed_in_window,
1709 offsetof (struct frame, default_toolbar_border_width),
1710 default_toolbar_border_width_changed_in_frame, 0);
1712 DEFVAR_SPECIFIER ("top-toolbar-border-width",
1713 &Vtoolbar_border_width[TOP_TOOLBAR] /*
1714 *Border width of the top toolbar.
1715 This is a specifier; use `set-specifier' to change it.
1717 See `default-toolbar-height' for more information.
1719 Vtoolbar_border_width[TOP_TOOLBAR] = Fmake_specifier (Qnatnum);
1720 set_specifier_caching (Vtoolbar_border_width[TOP_TOOLBAR],
1721 offsetof (struct window,
1722 toolbar_border_width[TOP_TOOLBAR]),
1723 toolbar_geometry_changed_in_window,
1724 offsetof (struct frame,
1725 toolbar_border_width[TOP_TOOLBAR]),
1726 frame_size_slipped, 0);
1728 DEFVAR_SPECIFIER ("bottom-toolbar-border-width",
1729 &Vtoolbar_border_width[BOTTOM_TOOLBAR] /*
1730 *Border width of the bottom toolbar.
1731 This is a specifier; use `set-specifier' to change it.
1733 See `default-toolbar-height' for more information.
1735 Vtoolbar_border_width[BOTTOM_TOOLBAR] = Fmake_specifier (Qnatnum);
1736 set_specifier_caching (Vtoolbar_border_width[BOTTOM_TOOLBAR],
1737 offsetof (struct window,
1738 toolbar_border_width[BOTTOM_TOOLBAR]),
1739 toolbar_geometry_changed_in_window,
1740 offsetof (struct frame,
1741 toolbar_border_width[BOTTOM_TOOLBAR]),
1742 frame_size_slipped, 0);
1744 DEFVAR_SPECIFIER ("left-toolbar-border-width",
1745 &Vtoolbar_border_width[LEFT_TOOLBAR] /*
1746 *Border width of left toolbar.
1747 This is a specifier; use `set-specifier' to change it.
1749 See `default-toolbar-height' for more information.
1751 Vtoolbar_border_width[LEFT_TOOLBAR] = Fmake_specifier (Qnatnum);
1752 set_specifier_caching (Vtoolbar_border_width[LEFT_TOOLBAR],
1753 offsetof (struct window,
1754 toolbar_border_width[LEFT_TOOLBAR]),
1755 toolbar_geometry_changed_in_window,
1756 offsetof (struct frame,
1757 toolbar_border_width[LEFT_TOOLBAR]),
1758 frame_size_slipped, 0);
1760 DEFVAR_SPECIFIER ("right-toolbar-border-width",
1761 &Vtoolbar_border_width[RIGHT_TOOLBAR] /*
1762 *Border width of right toolbar.
1763 This is a specifier; use `set-specifier' to change it.
1765 See `default-toolbar-height' for more information.
1767 Vtoolbar_border_width[RIGHT_TOOLBAR] = Fmake_specifier (Qnatnum);
1768 set_specifier_caching (Vtoolbar_border_width[RIGHT_TOOLBAR],
1769 offsetof (struct window,
1770 toolbar_border_width[RIGHT_TOOLBAR]),
1771 toolbar_geometry_changed_in_window,
1772 offsetof (struct frame,
1773 toolbar_border_width[RIGHT_TOOLBAR]),
1774 frame_size_slipped, 0);
1778 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1780 #ifdef HAVE_X_WINDOWS
1781 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_TOOLBAR_BORDER_WIDTH)), fb);
1784 fb = Fcons (Fcons (list1 (Qgtk), make_int (DEFAULT_TOOLBAR_BORDER_WIDTH)), fb);
1786 #ifdef HAVE_MS_WINDOWS
1787 fb = Fcons (Fcons (list1 (Qmswindows), make_int (MSWINDOWS_DEFAULT_TOOLBAR_BORDER_WIDTH)), fb);
1790 set_specifier_fallback (Vdefault_toolbar_border_width, fb);
1792 set_specifier_fallback (Vtoolbar_border_width[TOP_TOOLBAR], Vdefault_toolbar_border_width);
1793 fb = list1 (Fcons (Qnil, Qzero));
1794 set_specifier_fallback (Vtoolbar_border_width[BOTTOM_TOOLBAR], fb);
1795 set_specifier_fallback (Vtoolbar_border_width[LEFT_TOOLBAR], fb);
1796 set_specifier_fallback (Vtoolbar_border_width[RIGHT_TOOLBAR], fb);
1798 DEFVAR_SPECIFIER ("default-toolbar-visible-p", &Vdefault_toolbar_visible_p /*
1799 *Whether the default toolbar is visible.
1800 This is a specifier; use `set-specifier' to change it.
1802 The position of the default toolbar is specified by the function
1803 `set-default-toolbar-position'. If the corresponding position-specific
1804 toolbar visibility specifier (e.g. `top-toolbar-visible-p' if
1805 `default-toolbar-position' is 'top) does not specify a visible-p value
1806 in a particular domain (a window or a frame), then the value of
1807 `default-toolbar-visible-p' in that domain, if any, will be used
1810 Both window domains and frame domains are used internally, for
1811 different purposes. The distinction here is exactly the same as
1812 for thickness specifiers; see `default-toolbar-height' for more
1815 `default-toolbar-visible-p' and all of the position-specific toolbar
1816 visibility specifiers have a fallback value of true.
1818 Vdefault_toolbar_visible_p = Fmake_specifier (Qboolean);
1819 set_specifier_caching (Vdefault_toolbar_visible_p,
1820 offsetof (struct window, default_toolbar_visible_p),
1821 default_toolbar_visible_p_changed_in_window,
1822 offsetof (struct frame, default_toolbar_visible_p),
1823 default_toolbar_visible_p_changed_in_frame, 0);
1825 DEFVAR_SPECIFIER ("top-toolbar-visible-p",
1826 &Vtoolbar_visible_p[TOP_TOOLBAR] /*
1827 *Whether the top toolbar is visible.
1828 This is a specifier; use `set-specifier' to change it.
1830 See `default-toolbar-visible-p' for more information.
1832 Vtoolbar_visible_p[TOP_TOOLBAR] = Fmake_specifier (Qboolean);
1833 set_specifier_caching (Vtoolbar_visible_p[TOP_TOOLBAR],
1834 offsetof (struct window,
1835 toolbar_visible_p[TOP_TOOLBAR]),
1836 toolbar_geometry_changed_in_window,
1837 offsetof (struct frame,
1838 toolbar_visible_p[TOP_TOOLBAR]),
1839 frame_size_slipped, 0);
1841 DEFVAR_SPECIFIER ("bottom-toolbar-visible-p",
1842 &Vtoolbar_visible_p[BOTTOM_TOOLBAR] /*
1843 *Whether the bottom toolbar is visible.
1844 This is a specifier; use `set-specifier' to change it.
1846 See `default-toolbar-visible-p' for more information.
1848 Vtoolbar_visible_p[BOTTOM_TOOLBAR] = Fmake_specifier (Qboolean);
1849 set_specifier_caching (Vtoolbar_visible_p[BOTTOM_TOOLBAR],
1850 offsetof (struct window,
1851 toolbar_visible_p[BOTTOM_TOOLBAR]),
1852 toolbar_geometry_changed_in_window,
1853 offsetof (struct frame,
1854 toolbar_visible_p[BOTTOM_TOOLBAR]),
1855 frame_size_slipped, 0);
1857 DEFVAR_SPECIFIER ("left-toolbar-visible-p",
1858 &Vtoolbar_visible_p[LEFT_TOOLBAR] /*
1859 *Whether the left toolbar is visible.
1860 This is a specifier; use `set-specifier' to change it.
1862 See `default-toolbar-visible-p' for more information.
1864 Vtoolbar_visible_p[LEFT_TOOLBAR] = Fmake_specifier (Qboolean);
1865 set_specifier_caching (Vtoolbar_visible_p[LEFT_TOOLBAR],
1866 offsetof (struct window,
1867 toolbar_visible_p[LEFT_TOOLBAR]),
1868 toolbar_geometry_changed_in_window,
1869 offsetof (struct frame,
1870 toolbar_visible_p[LEFT_TOOLBAR]),
1871 frame_size_slipped, 0);
1873 DEFVAR_SPECIFIER ("right-toolbar-visible-p",
1874 &Vtoolbar_visible_p[RIGHT_TOOLBAR] /*
1875 *Whether the right toolbar is visible.
1876 This is a specifier; use `set-specifier' to change it.
1878 See `default-toolbar-visible-p' for more information.
1880 Vtoolbar_visible_p[RIGHT_TOOLBAR] = Fmake_specifier (Qboolean);
1881 set_specifier_caching (Vtoolbar_visible_p[RIGHT_TOOLBAR],
1882 offsetof (struct window,
1883 toolbar_visible_p[RIGHT_TOOLBAR]),
1884 toolbar_geometry_changed_in_window,
1885 offsetof (struct frame,
1886 toolbar_visible_p[RIGHT_TOOLBAR]),
1887 frame_size_slipped, 0);
1889 /* initially, top inherits from default; this can be
1890 changed with `set-default-toolbar-position'. */
1891 fb = list1 (Fcons (Qnil, Qt));
1892 set_specifier_fallback (Vdefault_toolbar_visible_p, fb);
1893 set_specifier_fallback (Vtoolbar_visible_p[TOP_TOOLBAR],
1894 Vdefault_toolbar_visible_p);
1895 set_specifier_fallback (Vtoolbar_visible_p[BOTTOM_TOOLBAR], fb);
1896 set_specifier_fallback (Vtoolbar_visible_p[LEFT_TOOLBAR], fb);
1897 set_specifier_fallback (Vtoolbar_visible_p[RIGHT_TOOLBAR], fb);
1899 DEFVAR_SPECIFIER ("toolbar-buttons-captioned-p",
1900 &Vtoolbar_buttons_captioned_p /*
1901 *Whether the toolbar buttons are captioned.
1902 This will only have a visible effect for those toolbar buttons which had
1903 captioned versions specified.
1904 This is a specifier; use `set-specifier' to change it.
1906 Vtoolbar_buttons_captioned_p = Fmake_specifier (Qboolean);
1907 set_specifier_caching (Vtoolbar_buttons_captioned_p,
1908 offsetof (struct window, toolbar_buttons_captioned_p),
1909 toolbar_buttons_captioned_p_changed,
1911 set_specifier_fallback (Vtoolbar_buttons_captioned_p,
1912 list1 (Fcons (Qnil, Qt)));