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, void (*markobj) (Lisp_Object))
62 struct toolbar_button *data = (struct toolbar_button *) XPNTR (obj);
63 ((markobj) (data->next));
64 ((markobj) (data->frame));
65 ((markobj) (data->up_glyph));
66 ((markobj) (data->down_glyph));
67 ((markobj) (data->disabled_glyph));
68 ((markobj) (data->cap_up_glyph));
69 ((markobj) (data->cap_down_glyph));
70 ((markobj) (data->cap_disabled_glyph));
71 ((markobj) (data->callback));
72 ((markobj) (data->enabled_p));
73 return data->help_string;
77 print_toolbar_button (Lisp_Object obj, Lisp_Object printcharfun,
80 struct toolbar_button *tb = XTOOLBAR_BUTTON (obj);
84 error ("printing unreadable object #<toolbar-button 0x%x>",
87 sprintf (buf, "#<toolbar-button 0x%x>", tb->header.uid);
88 write_c_string (buf, printcharfun);
91 DEFINE_LRECORD_IMPLEMENTATION ("toolbar-button", toolbar_button,
92 mark_toolbar_button, print_toolbar_button,
94 struct toolbar_button);
96 DEFUN ("toolbar-button-p", Ftoolbar_button_p, 1, 1, 0, /*
97 Return non-nil if OBJECT is a toolbar button.
101 return TOOLBAR_BUTTONP (object) ? Qt : Qnil;
104 /* Only query functions are provided for toolbar buttons. They are
105 generated and updated from a toolbar description list. Any
106 directly made changes would be wiped out the first time the toolbar
107 was marked as dirty and was regenerated. The exception to this is
108 set-toolbar-button-down-flag. Having this allows us to control the
109 toolbar from elisp. Since we only trigger the button callbacks on
110 up-mouse events and we reset the flag first, there shouldn't be any
111 way for this to get us in trouble (like if someone decides to
112 change the toolbar from a toolbar callback). */
114 DEFUN ("toolbar-button-callback", Ftoolbar_button_callback, 1, 1, 0, /*
115 Return the callback function associated with the toolbar BUTTON.
119 CHECK_TOOLBAR_BUTTON (button);
121 return XTOOLBAR_BUTTON (button)->callback;
124 DEFUN ("toolbar-button-help-string", Ftoolbar_button_help_string, 1, 1, 0, /*
125 Return the help string function associated with the toolbar BUTTON.
129 CHECK_TOOLBAR_BUTTON (button);
131 return XTOOLBAR_BUTTON (button)->help_string;
134 DEFUN ("toolbar-button-enabled-p", Ftoolbar_button_enabled_p, 1, 1, 0, /*
135 Return t if BUTTON is active.
139 CHECK_TOOLBAR_BUTTON (button);
141 return XTOOLBAR_BUTTON (button)->enabled ? Qt : Qnil;
144 DEFUN ("set-toolbar-button-down-flag", Fset_toolbar_button_down_flag, 2, 2, 0, /*
149 struct toolbar_button *tb;
152 CHECK_TOOLBAR_BUTTON (button);
153 tb = XTOOLBAR_BUTTON (button);
156 /* If the button is ignored, don't do anything. */
160 /* If flag is nil, unset the down flag, otherwise set it to true.
161 This also triggers an immediate redraw of the button if the flag
169 if (tb->down != old_flag)
171 struct frame *f = XFRAME (tb->frame);
174 if (DEVICEP (f->device))
176 d = XDEVICE (f->device);
178 if (DEVICE_LIVE_P (XDEVICE (f->device)))
181 MAYBE_DEVMETH (d, output_toolbar_button, (f, button));
190 get_toolbar_button_glyph (struct window *w, struct toolbar_button *tb)
192 Lisp_Object glyph = Qnil;
194 /* The selected glyph logic:
198 DISABLED: disabled -> up
200 CAP-DOWN: cap-down -> cap-up -> down -> up
201 CAP-DISABLED: cap-disabled -> cap-up -> disabled -> up
204 if (!NILP (w->toolbar_buttons_captioned_p))
206 if (tb->enabled && tb->down)
207 glyph = tb->cap_down_glyph;
208 else if (!tb->enabled)
209 glyph = tb->cap_disabled_glyph;
212 glyph = tb->cap_up_glyph;
217 if (tb->enabled && tb->down)
218 glyph = tb->down_glyph;
219 else if (!tb->enabled)
220 glyph = tb->disabled_glyph;
223 /* The non-captioned up button is the ultimate fallback. It is
224 the only one we guarantee exists. */
226 glyph = tb->up_glyph;
232 static enum toolbar_pos
233 decode_toolbar_position (Lisp_Object position)
235 if (EQ (position, Qtop)) return TOP_TOOLBAR;
236 if (EQ (position, Qbottom)) return BOTTOM_TOOLBAR;
237 if (EQ (position, Qleft)) return LEFT_TOOLBAR;
238 if (EQ (position, Qright)) return RIGHT_TOOLBAR;
239 signal_simple_error ("Invalid toolbar position", position);
241 return TOP_TOOLBAR; /* not reached */
244 DEFUN ("set-default-toolbar-position", Fset_default_toolbar_position, 1, 1, 0, /*
245 Set the position that the `default-toolbar' will be displayed at.
246 Valid positions are 'top, 'bottom, 'left and 'right.
247 See `default-toolbar-position'.
251 enum toolbar_pos cur = decode_toolbar_position (Vdefault_toolbar_position);
252 enum toolbar_pos new = decode_toolbar_position (position);
256 /* The following calls will automatically cause the dirty
257 flags to be set; we delay frame size changes to avoid
258 lots of frame flickering. */
259 /* #### I think this should be GC protected. -sb */
260 hold_frame_size_changes ();
261 set_specifier_fallback (Vtoolbar[cur], list1 (Fcons (Qnil, Qnil)));
262 set_specifier_fallback (Vtoolbar[new], Vdefault_toolbar);
263 set_specifier_fallback (Vtoolbar_size[cur], list1 (Fcons (Qnil, Qzero)));
264 set_specifier_fallback (Vtoolbar_size[new],
265 new == TOP_TOOLBAR || new == BOTTOM_TOOLBAR
266 ? Vdefault_toolbar_height
267 : Vdefault_toolbar_width);
268 set_specifier_fallback (Vtoolbar_border_width[cur],
269 list1 (Fcons (Qnil, Qzero)));
270 set_specifier_fallback (Vtoolbar_border_width[new],
271 Vdefault_toolbar_border_width);
272 set_specifier_fallback (Vtoolbar_visible_p[cur],
273 list1 (Fcons (Qnil, Qt)));
274 set_specifier_fallback (Vtoolbar_visible_p[new],
275 Vdefault_toolbar_visible_p);
276 Vdefault_toolbar_position = position;
277 unhold_frame_size_changes ();
283 DEFUN ("default-toolbar-position", Fdefault_toolbar_position, 0, 0, 0, /*
284 Return the position that the `default-toolbar' will be displayed at.
285 The `default-toolbar' will only be displayed here if the corresponding
286 position-specific toolbar specifier does not provide a value.
290 return Vdefault_toolbar_position;
295 update_toolbar_button (struct frame *f, struct toolbar_button *tb,
296 Lisp_Object desc, int pushright)
298 Lisp_Object *elt, glyphs, retval, buffer;
299 struct gcpro gcpro1, gcpro2;
301 elt = XVECTOR_DATA (desc);
302 buffer = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f))->buffer;
306 tb = alloc_lcrecord_type (struct toolbar_button, lrecord_toolbar_button);
308 XSETFRAME (tb->frame, f);
310 tb->down_glyph = Qnil;
311 tb->disabled_glyph = Qnil;
312 tb->cap_up_glyph = Qnil;
313 tb->cap_down_glyph = Qnil;
314 tb->cap_disabled_glyph = Qnil;
316 tb->enabled_p = Qnil;
317 tb->help_string = Qnil;
321 tb->pushright = pushright;
323 tb->x = tb->y = tb->width = tb->height = -1;
326 XSETTOOLBAR_BUTTON (retval, tb);
328 /* Let's make sure nothing gets mucked up by the potential call to
329 eval farther down. */
330 GCPRO2 (retval, desc);
332 glyphs = (CONSP (elt[0]) ? elt[0] : symbol_value_in_buffer (elt[0], buffer));
334 /* If this is true we have a blank, otherwise it is an actual
336 if (KEYWORDP (glyphs))
341 int len = XVECTOR_LENGTH (desc);
349 for (pos = 0; pos < len; pos += 2)
351 Lisp_Object key = elt[pos];
352 Lisp_Object val = elt[pos + 1];
354 if (EQ (key, Q_style))
358 if (EQ (val, Q2D) || EQ (val, Q2d))
360 if (!EQ (Qnil, tb->up_glyph) || !EQ (Qt, tb->disabled_glyph))
363 tb->disabled_glyph = Qt;
367 else if (EQ (val, Q3D) || (EQ (val, Q3d)))
369 if (!EQ (Qt, tb->up_glyph) || !EQ (Qnil, tb->disabled_glyph))
372 tb->disabled_glyph = Qnil;
377 else if (EQ (key, Q_size))
381 if (!EQ (val, tb->down_glyph))
383 tb->down_glyph = val;
391 /* The default style is 3D. */
392 if (!EQ (Qt, tb->up_glyph) || !EQ (Qnil, tb->disabled_glyph))
395 tb->disabled_glyph = Qnil;
402 /* The default width is set to nil. The device specific
403 code will fill it in at its discretion. */
404 if (!NILP (tb->down_glyph))
406 tb->down_glyph = Qnil;
411 /* The rest of these fields are not used by blanks. We make
412 sure they are nulled out in case this button object formerly
413 represented a real button. */
414 if (!NILP (tb->callback)
415 || !NILP (tb->enabled_p)
416 || !NILP (tb->help_string))
418 tb->cap_up_glyph = Qnil;
419 tb->cap_down_glyph = Qnil;
420 tb->cap_disabled_glyph = Qnil;
422 tb->enabled_p = Qnil;
423 tb->help_string = Qnil;
435 /* We know that we at least have an up_glyph. Well, no, we
436 don't. The user may have changed the button glyph on us. */
439 if (!EQ (XCAR (glyphs), tb->up_glyph))
441 tb->up_glyph = XCAR (glyphs);
444 glyphs = XCDR (glyphs);
449 /* We might have a down_glyph. */
452 if (!EQ (XCAR (glyphs), tb->down_glyph))
454 tb->down_glyph = XCAR (glyphs);
457 glyphs = XCDR (glyphs);
460 tb->down_glyph = Qnil;
462 /* We might have a disabled_glyph. */
465 if (!EQ (XCAR (glyphs), tb->disabled_glyph))
467 tb->disabled_glyph = XCAR (glyphs);
470 glyphs = XCDR (glyphs);
473 tb->disabled_glyph = Qnil;
475 /* We might have a cap_up_glyph. */
478 if (!EQ (XCAR (glyphs), tb->cap_up_glyph))
480 tb->cap_up_glyph = XCAR (glyphs);
483 glyphs = XCDR (glyphs);
486 tb->cap_up_glyph = Qnil;
488 /* We might have a cap_down_glyph. */
491 if (!EQ (XCAR (glyphs), tb->cap_down_glyph))
493 tb->cap_down_glyph = XCAR (glyphs);
496 glyphs = XCDR (glyphs);
499 tb->cap_down_glyph = Qnil;
501 /* We might have a cap_disabled_glyph. */
504 if (!EQ (XCAR (glyphs), tb->cap_disabled_glyph))
506 tb->cap_disabled_glyph = XCAR (glyphs);
511 tb->cap_disabled_glyph = Qnil;
513 /* Update the callback. */
514 if (!EQ (tb->callback, elt[1]))
516 tb->callback = elt[1];
517 /* This does not have an impact on the display properties of the
518 button so we do not mark it as dirty if it has changed. */
521 /* Update the enabled field. */
522 if (!EQ (tb->enabled_p, elt[2]))
524 tb->enabled_p = elt[2];
528 /* We always do the following because if the enabled status is
529 determined by a function its decision may change without us being
530 able to detect it. */
532 int old_enabled = tb->enabled;
534 if (NILP (tb->enabled_p))
536 else if (EQ (tb->enabled_p, Qt))
540 if (NILP (tb->enabled_p) || EQ (tb->enabled_p, Qt))
541 /* short-circuit the common case for speed */
542 tb->enabled = !NILP (tb->enabled_p);
546 eval_in_buffer_trapping_errors
547 ("Error in toolbar enabled-p form",
550 (XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f)))),
552 if (UNBOUNDP (result))
553 /* #### if there was an error in the enabled-p
554 form, should we pretend like it's enabled
558 tb->enabled = !NILP (result);
562 if (old_enabled != tb->enabled)
566 /* Update the help echo string. */
567 if (!EQ (tb->help_string, elt[3]))
569 tb->help_string = elt[3];
570 /* This does not have an impact on the display properties of the
571 button so we do not mark it as dirty if it has changed. */
575 /* If this flag changes, the position is changing for sure unless
576 some very unlikely geometry occurs. */
577 if (tb->pushright != pushright)
579 tb->pushright = pushright;
583 /* The position and size fields are only manipulated in the
584 device-dependent code. */
590 mark_frame_toolbar_buttons_dirty (struct frame *f, enum toolbar_pos pos)
592 Lisp_Object button = FRAME_TOOLBAR_BUTTONS (f, pos);
594 while (!NILP (button))
596 struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
604 compute_frame_toolbar_buttons (struct frame *f, enum toolbar_pos pos,
607 Lisp_Object buttons, prev_button, first_button;
608 Lisp_Object orig_toolbar = toolbar;
609 int pushright_seen = 0;
610 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
612 first_button = FRAME_TOOLBAR_BUTTONS (f, pos);
613 buttons = prev_button = first_button;
615 /* Yes, we're being paranoid. */
616 GCPRO5 (toolbar, buttons, prev_button, first_button, orig_toolbar);
620 /* The output mechanisms will take care of clearing the former
626 if (!CONSP (toolbar))
627 signal_simple_error ("toolbar description must be a list", toolbar);
629 /* First synchronize any existing buttons. */
630 while (!NILP (toolbar) && !NILP (buttons))
632 struct toolbar_button *tb;
634 if (NILP (XCAR (toolbar)))
638 ("more than one partition (nil) in toolbar description",
645 tb = XTOOLBAR_BUTTON (buttons);
646 update_toolbar_button (f, tb, XCAR (toolbar), pushright_seen);
647 prev_button = buttons;
651 toolbar = XCDR (toolbar);
654 /* If we hit the end of the toolbar, then clean up any excess
655 buttons and return. */
660 /* If this is the case the only thing we saw was a
662 if (EQ (buttons, first_button))
668 XTOOLBAR_BUTTON (prev_button)->next = Qnil;
674 /* At this point there are more buttons on the toolbar than we
675 actually have in existence. */
676 while (!NILP (toolbar))
678 Lisp_Object new_button;
680 if (NILP (XCAR (toolbar)))
684 ("more than one partition (nil) in toolbar description",
691 new_button = update_toolbar_button (f, NULL, XCAR (toolbar),
694 if (NILP (first_button))
696 first_button = prev_button = new_button;
700 XTOOLBAR_BUTTON (prev_button)->next = new_button;
701 prev_button = new_button;
705 toolbar = XCDR (toolbar);
713 set_frame_toolbar (struct frame *f, enum toolbar_pos pos)
715 struct window *w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f));
716 Lisp_Object toolbar = w->toolbar[pos];
717 f->toolbar_buttons[pos] = (FRAME_REAL_TOOLBAR_VISIBLE (f, pos)
718 ? compute_frame_toolbar_buttons (f, pos, toolbar)
723 compute_frame_toolbars_data (struct frame *f)
725 set_frame_toolbar (f, TOP_TOOLBAR);
726 set_frame_toolbar (f, BOTTOM_TOOLBAR);
727 set_frame_toolbar (f, LEFT_TOOLBAR);
728 set_frame_toolbar (f, RIGHT_TOOLBAR);
732 update_frame_toolbars (struct frame *f)
734 struct device *d = XDEVICE (f->device);
736 if (DEVICE_SUPPORTS_TOOLBARS_P (d)
737 && (f->toolbar_changed || f->frame_changed || f->clear))
741 /* We're not officially "in redisplay", so we still have a
742 chance to re-layout toolbars and windows. This is done here,
743 because toolbar is the only thing which currently might
744 necesseritate this layout, as it is outside any windows. We
745 take care not to change size if toolbar geometry is really
746 unchanged, as it will hose windows whose pixsizes are not
747 multiple of character sizes */
749 for (pos = 0; pos < 4; pos++)
750 if (FRAME_REAL_TOOLBAR_SIZE (f, pos)
751 != FRAME_CURRENT_TOOLBAR_SIZE (f, pos))
754 pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
756 change_frame_size (f, height, width, 0);
760 for (pos = 0; pos < 4; pos++)
761 f->current_toolbar_size[pos] = FRAME_REAL_TOOLBAR_SIZE (f, pos);
763 /* Removed the check for the minibuffer here. We handle this
764 more correctly now by consistently using
765 FRAME_LAST_NONMINIBUF_WINDOW instead of FRAME_SELECTED_WINDOW
766 throughout the toolbar code. */
767 compute_frame_toolbars_data (f);
769 DEVMETH (d, output_frame_toolbars, (f));
772 f->toolbar_changed = 0;
776 init_frame_toolbars (struct frame *f)
778 struct device *d = XDEVICE (f->device);
780 if (DEVICE_SUPPORTS_TOOLBARS_P (d))
785 compute_frame_toolbars_data (f);
786 XSETFRAME (frame, f);
787 call_critical_lisp_code (XDEVICE (FRAME_DEVICE (f)),
788 Qinit_toolbar_from_resources,
790 MAYBE_DEVMETH (d, initialize_frame_toolbars, (f));
792 /* We are here as far in frame creation so cached specifiers are
793 already recomputed, and possibly modified by resource
794 initialization. Remember current toolbar geometry so next
795 redisplay will not needlessly relayout toolbars. */
796 for (pos = 0; pos < 4; pos++)
797 f->current_toolbar_size[pos] = FRAME_REAL_TOOLBAR_SIZE (f, pos);
802 init_device_toolbars (struct device *d)
806 XSETDEVICE (device, d);
807 if (DEVICE_SUPPORTS_TOOLBARS_P (d))
808 call_critical_lisp_code (d,
809 Qinit_toolbar_from_resources,
814 init_global_toolbars (struct device *d)
816 if (DEVICE_SUPPORTS_TOOLBARS_P (d))
817 call_critical_lisp_code (d,
818 Qinit_toolbar_from_resources,
823 free_frame_toolbars (struct frame *f)
825 /* If we had directly allocated any memory for the toolbars instead
826 of using all Lisp_Objects this is where we would now free it. */
828 MAYBE_FRAMEMETH (f, free_frame_toolbars, (f));
832 get_toolbar_coords (struct frame *f, enum toolbar_pos pos, int *x, int *y,
833 int *width, int *height, int *vert, int for_layout)
835 int visible_top_toolbar_height, visible_bottom_toolbar_height;
836 int adjust = (for_layout ? 1 : 0);
838 /* The top and bottom toolbars take precedence over the left and
840 visible_top_toolbar_height = (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f)
841 ? FRAME_REAL_TOP_TOOLBAR_HEIGHT (f) +
842 2 * FRAME_REAL_TOP_TOOLBAR_BORDER_WIDTH (f)
844 visible_bottom_toolbar_height = (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f)
845 ? FRAME_REAL_BOTTOM_TOOLBAR_HEIGHT (f) +
847 FRAME_REAL_BOTTOM_TOOLBAR_BORDER_WIDTH (f)
850 /* We adjust the width and height by one to give us a narrow border
851 at the outside edges. However, when we are simply determining
852 toolbar location we don't want to do that. */
858 *y = 0; /* #### should be 1 if no menubar */
859 *width = FRAME_PIXWIDTH (f) - 2;
860 *height = FRAME_REAL_TOP_TOOLBAR_HEIGHT (f) +
861 2 * FRAME_REAL_TOP_TOOLBAR_BORDER_WIDTH (f) - adjust;
866 *y = FRAME_PIXHEIGHT (f) - FRAME_REAL_BOTTOM_TOOLBAR_HEIGHT (f) -
867 2 * FRAME_REAL_BOTTOM_TOOLBAR_BORDER_WIDTH (f);
868 *width = FRAME_PIXWIDTH (f) - 2;
869 *height = FRAME_REAL_BOTTOM_TOOLBAR_HEIGHT (f) +
870 2 * FRAME_REAL_BOTTOM_TOOLBAR_BORDER_WIDTH (f) - adjust;
875 *y = visible_top_toolbar_height;
876 *width = FRAME_REAL_LEFT_TOOLBAR_WIDTH (f) +
877 2 * FRAME_REAL_LEFT_TOOLBAR_BORDER_WIDTH (f) - adjust;
878 *height = (FRAME_PIXHEIGHT (f) - visible_top_toolbar_height -
879 visible_bottom_toolbar_height - 1);
883 *x = FRAME_PIXWIDTH (f) - FRAME_REAL_RIGHT_TOOLBAR_WIDTH (f) -
884 2 * FRAME_REAL_RIGHT_TOOLBAR_BORDER_WIDTH (f);
885 *y = visible_top_toolbar_height;
886 *width = FRAME_REAL_RIGHT_TOOLBAR_WIDTH (f) +
887 2 * FRAME_REAL_RIGHT_TOOLBAR_BORDER_WIDTH (f) - adjust;
888 *height = (FRAME_PIXHEIGHT (f) - visible_top_toolbar_height -
889 visible_bottom_toolbar_height);
897 #define CHECK_TOOLBAR(pos) \
900 get_toolbar_coords (f, pos, &x, &y, &width, &height, &vert, 0); \
901 if ((x_coord >= x) && (x_coord < (x + width))) \
903 if ((y_coord >= y) && (y_coord < (y + height))) \
904 return FRAME_TOOLBAR_BUTTONS (f, pos); \
909 toolbar_buttons_at_pixpos (struct frame *f, int x_coord, int y_coord)
911 int x, y, width, height, vert;
913 if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f))
914 CHECK_TOOLBAR (TOP_TOOLBAR);
915 if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f))
916 CHECK_TOOLBAR (BOTTOM_TOOLBAR);
917 if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f))
918 CHECK_TOOLBAR (LEFT_TOOLBAR);
919 if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f))
920 CHECK_TOOLBAR (RIGHT_TOOLBAR);
926 /* The device dependent code actually does the work of positioning the
927 buttons, but we are free to access that information at this
930 toolbar_button_at_pixpos (struct frame *f, int x_coord, int y_coord)
932 Lisp_Object buttons = toolbar_buttons_at_pixpos (f, x_coord, y_coord);
937 while (!NILP (buttons))
939 struct toolbar_button *tb = XTOOLBAR_BUTTON (buttons);
941 if ((x_coord >= tb->x) && (x_coord < (tb->x + tb->width)))
943 if ((y_coord >= tb->y) && (y_coord < (tb->y + tb->height)))
945 /* If we are over a blank, return nil. */
956 /* We must be over a blank in the toolbar. */
961 /************************************************************************/
962 /* Toolbar specifier type */
963 /************************************************************************/
965 DEFINE_SPECIFIER_TYPE (toolbar);
967 #define CTB_ERROR(msg) \
970 maybe_signal_simple_error (msg, button, Qtoolbar, errb); \
975 /* Returns Q_style if key was :style, Qt if ok otherwise, Qnil if error. */
977 check_toolbar_button_keywords (Lisp_Object button, Lisp_Object key,
978 Lisp_Object val, Error_behavior errb)
982 maybe_signal_simple_error_2 ("not a keyword", key, button, Qtoolbar,
987 if (EQ (key, Q_style))
993 CTB_ERROR ("unrecognized toolbar blank style");
997 else if (EQ (key, Q_size))
1000 CTB_ERROR ("invalid toolbar blank size");
1004 CTB_ERROR ("invalid toolbar blank keyword");
1010 /* toolbar button spec is [pixmap-pair function enabled-p help]
1011 or [:style 2d-or-3d :size width-or-height] */
1013 DEFUN ("check-toolbar-button-syntax", Fcheck_toolbar_button_syntax, 1, 2, 0, /*
1014 Verify the syntax of entry BUTTON in a toolbar description list.
1015 If you want to verify the syntax of a toolbar description list as a
1016 whole, use `check-valid-instantiator' with a specifier type of 'toolbar.
1020 Lisp_Object *elt, glyphs, value;
1022 Error_behavior errb = decode_error_behavior_flag (no_error);
1024 if (!VECTORP (button))
1025 CTB_ERROR ("toolbar button descriptors must be vectors");
1026 elt = XVECTOR_DATA (button);
1028 if (XVECTOR_LENGTH (button) == 2)
1030 if (!EQ (Q_style, check_toolbar_button_keywords (button, elt[0],
1032 CTB_ERROR ("must specify toolbar blank style");
1037 if (XVECTOR_LENGTH (button) != 4)
1038 CTB_ERROR ("toolbar button descriptors must be 2 or 4 long");
1040 /* The first element must be a list of glyphs of length 1-6. The
1041 first entry is the pixmap for the up state, the second for the
1042 down state, the third for the disabled state, the fourth for the
1043 captioned up state, the fifth for the captioned down state and
1044 the sixth for the captioned disabled state. Only the up state is
1046 if (!CONSP (elt[0]))
1048 /* We can't check the buffer-local here because we don't know
1049 which buffer to check in. #### I think this is a bad thing.
1050 See if we can't get enough information to this function so
1053 #### Wrong. We shouldn't be checking the value at all here.
1054 The user might set or change the value at any time. */
1055 value = Fsymbol_value (elt[0]);
1059 if (KEYWORDP (elt[0]))
1063 if (EQ (Q_style, check_toolbar_button_keywords (button, elt[0],
1068 if (EQ (Q_style, check_toolbar_button_keywords (button, elt[2],
1074 CTB_ERROR ("must specify toolbar blank style");
1075 else if (EQ (elt[0], elt[2]))
1077 ("duplicate keywords in toolbar button blank description");
1082 CTB_ERROR ("first element of button must be a list (of glyphs)");
1088 len = XINT (Flength (value));
1090 CTB_ERROR ("toolbar button glyph list must have at least 1 entry");
1093 CTB_ERROR ("toolbar button glyph list can have at most 6 entries");
1096 while (!NILP (glyphs))
1098 if (!GLYPHP (XCAR (glyphs)))
1100 /* We allow nil for the down and disabled glyphs but not for
1102 if (EQ (glyphs, value) || !NILP (XCAR (glyphs)))
1105 ("all elements of toolbar button glyph list must be glyphs.");
1108 glyphs = XCDR (glyphs);
1111 /* The second element is the function to run when the button is
1112 activated. We do not do any checking on it because it is legal
1113 for the function to not be defined until after the toolbar is.
1114 It is the user's problem to get this right.
1116 The third element is either a boolean indicating the enabled
1117 status or a function used to determine it. Again, it is the
1118 user's problem if this is wrong.
1120 The fourth element, if not nil, must be a string which will be
1121 displayed as the help echo. */
1123 /* #### This should be allowed to be a function returning a string
1124 as well as just a string. */
1125 if (!NILP (elt[3]) && !STRINGP (elt[3]))
1126 CTB_ERROR ("toolbar button help echo string must be a string");
1133 toolbar_validate (Lisp_Object instantiator)
1135 int pushright_seen = 0;
1138 if (NILP (instantiator))
1141 if (!CONSP (instantiator))
1142 signal_simple_error ("toolbar spec must be list or nil", instantiator);
1144 for (rest = instantiator; !NILP (rest); rest = XCDR (rest))
1147 signal_simple_error ("bad list in toolbar spec", instantiator);
1149 if (NILP (XCAR (rest)))
1153 ("more than one partition (nil) in instantiator description");
1158 Fcheck_toolbar_button_syntax (XCAR (rest), Qnil);
1163 toolbar_after_change (Lisp_Object specifier, Lisp_Object locale)
1165 /* #### This is overkill. I really need to rethink the after-change
1166 functions to make them easier to use. */
1167 MARK_TOOLBAR_CHANGED;
1170 DEFUN ("toolbar-specifier-p", Ftoolbar_specifier_p, 1, 1, 0, /*
1171 Return non-nil if OBJECT is a toolbar specifier.
1172 Toolbar specifiers are used to specify the format of a toolbar.
1173 The values of the variables `default-toolbar', `top-toolbar',
1174 `left-toolbar', `right-toolbar', and `bottom-toolbar' are always
1177 Valid toolbar instantiators are called "toolbar descriptors"
1178 and are lists of vectors. See `default-toolbar' for a description
1179 of the exact format.
1183 return TOOLBAR_SPECIFIERP (object) ? Qt : Qnil;
1188 Helper for invalidating the real specifier when default
1189 specifier caching changes
1192 recompute_overlaying_specifier (Lisp_Object real_one[4])
1194 enum toolbar_pos pos = decode_toolbar_position (Vdefault_toolbar_position);
1195 Fset_specifier_dirty_flag (real_one[pos]);
1199 toolbar_specs_changed (Lisp_Object specifier, struct window *w,
1202 /* This could be smarter but I doubt that it would make any
1203 noticable difference given the infrequency with which this is
1204 probably going to be called.
1206 MARK_TOOLBAR_CHANGED;
1210 default_toolbar_specs_changed (Lisp_Object specifier, struct window *w,
1213 recompute_overlaying_specifier (Vtoolbar);
1217 default_toolbar_size_changed_in_frame (Lisp_Object specifier, struct frame *f,
1220 recompute_overlaying_specifier (Vtoolbar_size);
1224 default_toolbar_border_width_changed_in_frame (Lisp_Object specifier,
1228 recompute_overlaying_specifier (Vtoolbar_border_width);
1232 default_toolbar_visible_p_changed_in_frame (Lisp_Object specifier,
1236 recompute_overlaying_specifier (Vtoolbar_visible_p);
1240 toolbar_geometry_changed_in_window (Lisp_Object specifier, struct window *w,
1243 MARK_TOOLBAR_CHANGED;
1244 MARK_WINDOWS_CHANGED (w);
1248 default_toolbar_size_changed_in_window (Lisp_Object specifier, struct window *w,
1251 recompute_overlaying_specifier (Vtoolbar_size);
1255 default_toolbar_border_width_changed_in_window (Lisp_Object specifier,
1259 recompute_overlaying_specifier (Vtoolbar_border_width);
1263 default_toolbar_visible_p_changed_in_window (Lisp_Object specifier,
1267 recompute_overlaying_specifier (Vtoolbar_visible_p);
1271 toolbar_buttons_captioned_p_changed (Lisp_Object specifier, struct window *w,
1274 /* This could be smarter but I doubt that it would make any
1275 noticable difference given the infrequency with which this is
1276 probably going to be called. */
1277 MARK_TOOLBAR_CHANGED;
1282 syms_of_toolbar (void)
1284 defsymbol (&Qtoolbar_buttonp, "toolbar-button-p");
1285 defsymbol (&Q2D, "2D");
1286 defsymbol (&Q3D, "3D");
1287 defsymbol (&Q2d, "2d");
1288 defsymbol (&Q3d, "3d");
1289 defsymbol (&Q_size, ":size"); Fset (Q_size, Q_size);
1291 defsymbol (&Qinit_toolbar_from_resources, "init-toolbar-from-resources");
1292 DEFSUBR (Ftoolbar_button_p);
1293 DEFSUBR (Ftoolbar_button_callback);
1294 DEFSUBR (Ftoolbar_button_help_string);
1295 DEFSUBR (Ftoolbar_button_enabled_p);
1296 DEFSUBR (Fset_toolbar_button_down_flag);
1297 DEFSUBR (Fcheck_toolbar_button_syntax);
1298 DEFSUBR (Fset_default_toolbar_position);
1299 DEFSUBR (Fdefault_toolbar_position);
1300 DEFSUBR (Ftoolbar_specifier_p);
1304 vars_of_toolbar (void)
1306 staticpro (&Vdefault_toolbar_position);
1307 Vdefault_toolbar_position = Qtop;
1309 #ifdef HAVE_WINDOW_SYSTEM
1310 Fprovide (Qtoolbar);
1315 specifier_type_create_toolbar (void)
1317 INITIALIZE_SPECIFIER_TYPE (toolbar, "toolbar", "toolbar-specifier-p");
1319 SPECIFIER_HAS_METHOD (toolbar, validate);
1320 SPECIFIER_HAS_METHOD (toolbar, after_change);
1324 specifier_vars_of_toolbar (void)
1328 DEFVAR_SPECIFIER ("default-toolbar", &Vdefault_toolbar /*
1329 Specifier for a fallback toolbar.
1330 Use `set-specifier' to change this.
1332 The position of this toolbar is specified in the function
1333 `default-toolbar-position'. If the corresponding position-specific
1334 toolbar (e.g. `top-toolbar' if `default-toolbar-position' is 'top)
1335 does not specify a toolbar in a particular domain (usually a window),
1336 then the value of `default-toolbar' in that domain, if any, will be
1339 Note that the toolbar at any particular position will not be
1340 displayed unless its visibility flag is true and its thickness
1341 \(width or height, depending on orientation) is non-zero. The
1342 visibility is controlled by the specifiers `top-toolbar-visible-p',
1343 `bottom-toolbar-visible-p', `left-toolbar-visible-p', and
1344 `right-toolbar-visible-p', and the thickness is controlled by the
1345 specifiers `top-toolbar-height', `bottom-toolbar-height',
1346 `left-toolbar-width', and `right-toolbar-width'.
1348 Note that one of the four visibility specifiers inherits from
1349 `default-toolbar-visibility' and one of the four thickness
1350 specifiers inherits from either `default-toolbar-width' or
1351 `default-toolbar-height' (depending on orientation), just
1352 like for the toolbar description specifiers (e.g. `top-toolbar')
1355 Therefore, if you are setting `default-toolbar', you should control
1356 the visibility and thickness using `default-toolbar-visible-p',
1357 `default-toolbar-width', and `default-toolbar-height', rather than
1358 using position-specific specifiers. That way, you will get sane
1359 behavior if the user changes the default toolbar position.
1361 The format of the instantiator for a toolbar is a list of
1362 toolbar-button-descriptors. Each toolbar-button-descriptor
1363 is a vector in one of the following formats:
1365 [GLYPH-LIST FUNCTION ENABLED-P HELP] or
1366 [:style 2D-OR-3D] or
1367 [:style 2D-OR-3D :size WIDTH-OR-HEIGHT] or
1368 [:size WIDTH-OR-HEIGHT :style 2D-OR-3D]
1370 Optionally, one of the toolbar-button-descriptors may be nil
1371 instead of a vector; this signifies the division between
1372 the toolbar buttons that are to be displayed flush-left,
1373 and the buttons to be displayed flush-right.
1375 The first vector format above specifies a normal toolbar button;
1376 the others specify blank areas in the toolbar.
1378 For the first vector format:
1380 -- GLYPH-LIST should be a list of one to six glyphs (as created by
1381 `make-glyph') or a symbol whose value is such a list. The first
1382 glyph, which must be provided, is the glyph used to display the
1383 toolbar button when it is in the "up" (not pressed) state. The
1384 optional second glyph is for displaying the button when it is in
1385 the "down" (pressed) state. The optional third glyph is for when
1386 the button is disabled. The optional fourth, fifth and sixth glyphs
1387 are used to specify captioned versions for the up, down and disabled
1388 states respectively. The function `toolbar-make-button-list' is
1389 useful in creating these glyph lists. The specifier variable
1390 `toolbar-buttons-captioned-p' controls which glyphs are actually used.
1392 -- Even if you do not provide separate down-state and disabled-state
1393 glyphs, the user will still get visual feedback to indicate which
1394 state the button is in. Buttons in the up-state are displayed
1395 with a shadowed border that gives a raised appearance to the
1396 button. Buttons in the down-state are displayed with shadows that
1397 give a recessed appearance. Buttons in the disabled state are
1398 displayed with no shadows, giving a 2-d effect.
1400 -- If some of the toolbar glyphs are not provided, they inherit as follows:
1404 DISABLED: disabled -> up
1405 CAP-UP: cap-up -> up
1406 CAP-DOWN: cap-down -> cap-up -> down -> up
1407 CAP-DISABLED: cap-disabled -> cap-up -> disabled -> up
1409 -- The second element FUNCTION is a function to be called when the
1410 toolbar button is activated (i.e. when the mouse is released over
1411 the toolbar button, if the press occurred in the toolbar). It
1412 can be any form accepted by `call-interactively', since this is
1415 -- The third element ENABLED-P specifies whether the toolbar button
1416 is enabled (disabled buttons do nothing when they are activated,
1417 and are displayed differently; see above). It should be either
1418 a boolean or a form that evaluates to a boolean.
1420 -- The fourth element HELP, if non-nil, should be a string. This
1421 string is displayed in the echo area when the mouse passes over
1424 For the other vector formats (specifying blank areas of the toolbar):
1426 -- 2D-OR-3D should be one of the symbols '2d or '3d, indicating
1427 whether the area is displayed with shadows (giving it a raised,
1428 3-d appearance) or without shadows (giving it a flat appearance).
1430 -- WIDTH-OR-HEIGHT specifies the length, in pixels, of the blank
1431 area. If omitted, it defaults to a device-specific value
1432 (8 pixels for X devices).
1435 Vdefault_toolbar = Fmake_specifier (Qtoolbar);
1436 /* #### It would be even nicer if the specifier caching
1437 automatically knew about specifier fallbacks, so we didn't
1438 have to do it ourselves. */
1439 set_specifier_caching (Vdefault_toolbar,
1440 slot_offset (struct window,
1442 default_toolbar_specs_changed,
1445 DEFVAR_SPECIFIER ("top-toolbar",
1446 &Vtoolbar[TOP_TOOLBAR] /*
1447 Specifier for the toolbar at the top of the frame.
1448 Use `set-specifier' to change this.
1449 See `default-toolbar' for a description of a valid toolbar instantiator.
1451 Vtoolbar[TOP_TOOLBAR] = Fmake_specifier (Qtoolbar);
1452 set_specifier_caching (Vtoolbar[TOP_TOOLBAR],
1453 slot_offset (struct window,
1454 toolbar[TOP_TOOLBAR]),
1455 toolbar_specs_changed,
1458 DEFVAR_SPECIFIER ("bottom-toolbar",
1459 &Vtoolbar[BOTTOM_TOOLBAR] /*
1460 Specifier for the toolbar at the bottom of the frame.
1461 Use `set-specifier' to change this.
1462 See `default-toolbar' for a description of a valid toolbar instantiator.
1464 Note that, unless the `default-toolbar-position' is `bottom', by
1465 default the height of the bottom toolbar (controlled by
1466 `bottom-toolbar-height') is 0; thus, a bottom toolbar will not be
1467 displayed even if you provide a value for `bottom-toolbar'.
1469 Vtoolbar[BOTTOM_TOOLBAR] = Fmake_specifier (Qtoolbar);
1470 set_specifier_caching (Vtoolbar[BOTTOM_TOOLBAR],
1471 slot_offset (struct window,
1472 toolbar[BOTTOM_TOOLBAR]),
1473 toolbar_specs_changed,
1476 DEFVAR_SPECIFIER ("left-toolbar",
1477 &Vtoolbar[LEFT_TOOLBAR] /*
1478 Specifier for the toolbar at the left edge of the frame.
1479 Use `set-specifier' to change this.
1480 See `default-toolbar' for a description of a valid toolbar instantiator.
1482 Note that, unless the `default-toolbar-position' is `left', by
1483 default the height of the left toolbar (controlled by
1484 `left-toolbar-width') is 0; thus, a left toolbar will not be
1485 displayed even if you provide a value for `left-toolbar'.
1487 Vtoolbar[LEFT_TOOLBAR] = Fmake_specifier (Qtoolbar);
1488 set_specifier_caching (Vtoolbar[LEFT_TOOLBAR],
1489 slot_offset (struct window,
1490 toolbar[LEFT_TOOLBAR]),
1491 toolbar_specs_changed,
1494 DEFVAR_SPECIFIER ("right-toolbar",
1495 &Vtoolbar[RIGHT_TOOLBAR] /*
1496 Specifier for the toolbar at the right edge of the frame.
1497 Use `set-specifier' to change this.
1498 See `default-toolbar' for a description of a valid toolbar instantiator.
1500 Note that, unless the `default-toolbar-position' is `right', by
1501 default the height of the right toolbar (controlled by
1502 `right-toolbar-width') is 0; thus, a right toolbar will not be
1503 displayed even if you provide a value for `right-toolbar'.
1505 Vtoolbar[RIGHT_TOOLBAR] = Fmake_specifier (Qtoolbar);
1506 set_specifier_caching (Vtoolbar[RIGHT_TOOLBAR],
1507 slot_offset (struct window,
1508 toolbar[RIGHT_TOOLBAR]),
1509 toolbar_specs_changed,
1512 /* initially, top inherits from default; this can be
1513 changed with `set-default-toolbar-position'. */
1514 fb = list1 (Fcons (Qnil, Qnil));
1515 set_specifier_fallback (Vdefault_toolbar, fb);
1516 set_specifier_fallback (Vtoolbar[TOP_TOOLBAR], Vdefault_toolbar);
1517 set_specifier_fallback (Vtoolbar[BOTTOM_TOOLBAR], fb);
1518 set_specifier_fallback (Vtoolbar[LEFT_TOOLBAR], fb);
1519 set_specifier_fallback (Vtoolbar[RIGHT_TOOLBAR], fb);
1521 DEFVAR_SPECIFIER ("default-toolbar-height", &Vdefault_toolbar_height /*
1522 *Height of the default toolbar, if it's oriented horizontally.
1523 This is a specifier; use `set-specifier' to change it.
1525 The position of the default toolbar is specified by the function
1526 `set-default-toolbar-position'. If the corresponding position-specific
1527 toolbar thickness specifier (e.g. `top-toolbar-height' if
1528 `default-toolbar-position' is 'top) does not specify a thickness in a
1529 particular domain (a window or a frame), then the value of
1530 `default-toolbar-height' or `default-toolbar-width' (depending on the
1531 toolbar orientation) in that domain, if any, will be used instead.
1533 Note that `default-toolbar-height' is only used when
1534 `default-toolbar-position' is 'top or 'bottom, and `default-toolbar-width'
1535 is only used when `default-toolbar-position' is 'left or 'right.
1537 Note that all of the position-specific toolbar thickness specifiers
1538 have a fallback value of zero when they do not correspond to the
1539 default toolbar. Therefore, you will have to set a non-zero thickness
1540 value if you want a position-specific toolbar to be displayed.
1542 Internally, toolbar thickness specifiers are instantiated in both
1543 window and frame domains, for different purposes. The value in the
1544 domain of a frame's selected window specifies the actual toolbar
1545 thickness that you will see in that frame. The value in the domain of
1546 a frame itself specifies the toolbar thickness that is used in frame
1547 geometry calculations.
1549 Thus, for example, if you set the frame width to 80 characters and the
1550 left toolbar width for that frame to 68 pixels, then the frame will
1551 be sized to fit 80 characters plus a 68-pixel left toolbar. If you
1552 then set the left toolbar width to 0 for a particular buffer (or if
1553 that buffer does not specify a left toolbar or has a nil value
1554 specified for `left-toolbar-visible-p'), you will find that, when
1555 that buffer is displayed in the selected window, the window will have
1556 a width of 86 or 87 characters -- the frame is sized for a 68-pixel
1557 left toolbar but the selected window specifies that the left toolbar
1558 is not visible, so it is expanded to take up the slack.
1560 Vdefault_toolbar_height = Fmake_specifier (Qnatnum);
1561 set_specifier_caching (Vdefault_toolbar_height,
1562 slot_offset (struct window,
1563 default_toolbar_height),
1564 default_toolbar_size_changed_in_window,
1565 slot_offset (struct frame,
1566 default_toolbar_height),
1567 default_toolbar_size_changed_in_frame);
1569 DEFVAR_SPECIFIER ("default-toolbar-width", &Vdefault_toolbar_width /*
1570 *Width of the default toolbar, if it's oriented vertically.
1571 This is a specifier; use `set-specifier' to change it.
1573 See `default-toolbar-height' for more information.
1575 Vdefault_toolbar_width = Fmake_specifier (Qnatnum);
1576 set_specifier_caching (Vdefault_toolbar_width,
1577 slot_offset (struct window,
1578 default_toolbar_width),
1579 default_toolbar_size_changed_in_window,
1580 slot_offset (struct frame,
1581 default_toolbar_width),
1582 default_toolbar_size_changed_in_frame);
1584 DEFVAR_SPECIFIER ("top-toolbar-height",
1585 &Vtoolbar_size[TOP_TOOLBAR] /*
1586 *Height of the top toolbar.
1587 This is a specifier; use `set-specifier' to change it.
1589 See `default-toolbar-height' for more information.
1591 Vtoolbar_size[TOP_TOOLBAR] = Fmake_specifier (Qnatnum);
1592 set_specifier_caching (Vtoolbar_size[TOP_TOOLBAR],
1593 slot_offset (struct window,
1594 toolbar_size[TOP_TOOLBAR]),
1595 toolbar_geometry_changed_in_window,
1596 slot_offset (struct frame,
1597 toolbar_size[TOP_TOOLBAR]),
1598 frame_size_slipped);
1600 DEFVAR_SPECIFIER ("bottom-toolbar-height",
1601 &Vtoolbar_size[BOTTOM_TOOLBAR] /*
1602 *Height of the bottom toolbar.
1603 This is a specifier; use `set-specifier' to change it.
1605 See `default-toolbar-height' for more information.
1607 Vtoolbar_size[BOTTOM_TOOLBAR] = Fmake_specifier (Qnatnum);
1608 set_specifier_caching (Vtoolbar_size[BOTTOM_TOOLBAR],
1609 slot_offset (struct window,
1610 toolbar_size[BOTTOM_TOOLBAR]),
1611 toolbar_geometry_changed_in_window,
1612 slot_offset (struct frame,
1613 toolbar_size[BOTTOM_TOOLBAR]),
1614 frame_size_slipped);
1616 DEFVAR_SPECIFIER ("left-toolbar-width",
1617 &Vtoolbar_size[LEFT_TOOLBAR] /*
1618 *Width of left toolbar.
1619 This is a specifier; use `set-specifier' to change it.
1621 See `default-toolbar-height' for more information.
1623 Vtoolbar_size[LEFT_TOOLBAR] = Fmake_specifier (Qnatnum);
1624 set_specifier_caching (Vtoolbar_size[LEFT_TOOLBAR],
1625 slot_offset (struct window,
1626 toolbar_size[LEFT_TOOLBAR]),
1627 toolbar_geometry_changed_in_window,
1628 slot_offset (struct frame,
1629 toolbar_size[LEFT_TOOLBAR]),
1630 frame_size_slipped);
1632 DEFVAR_SPECIFIER ("right-toolbar-width",
1633 &Vtoolbar_size[RIGHT_TOOLBAR] /*
1634 *Width of right toolbar.
1635 This is a specifier; use `set-specifier' to change it.
1637 See `default-toolbar-height' for more information.
1639 Vtoolbar_size[RIGHT_TOOLBAR] = Fmake_specifier (Qnatnum);
1640 set_specifier_caching (Vtoolbar_size[RIGHT_TOOLBAR],
1641 slot_offset (struct window,
1642 toolbar_size[RIGHT_TOOLBAR]),
1643 toolbar_geometry_changed_in_window,
1644 slot_offset (struct frame,
1645 toolbar_size[RIGHT_TOOLBAR]),
1646 frame_size_slipped);
1650 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1652 #ifdef HAVE_X_WINDOWS
1653 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_TOOLBAR_HEIGHT)), fb);
1655 #ifdef HAVE_MS_WINDOWS
1656 fb = Fcons (Fcons (list1 (Qmswindows),
1657 make_int (MSWINDOWS_DEFAULT_TOOLBAR_HEIGHT)), fb);
1660 set_specifier_fallback (Vdefault_toolbar_height, fb);
1664 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1666 #ifdef HAVE_X_WINDOWS
1667 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_TOOLBAR_WIDTH)), fb);
1669 #ifdef HAVE_MS_WINDOWS
1670 fb = Fcons (Fcons (list1 (Qmswindows),
1671 make_int (MSWINDOWS_DEFAULT_TOOLBAR_WIDTH)), fb);
1674 set_specifier_fallback (Vdefault_toolbar_width, fb);
1676 set_specifier_fallback (Vtoolbar_size[TOP_TOOLBAR], Vdefault_toolbar_height);
1677 fb = list1 (Fcons (Qnil, Qzero));
1678 set_specifier_fallback (Vtoolbar_size[BOTTOM_TOOLBAR], fb);
1679 set_specifier_fallback (Vtoolbar_size[LEFT_TOOLBAR], fb);
1680 set_specifier_fallback (Vtoolbar_size[RIGHT_TOOLBAR], fb);
1682 DEFVAR_SPECIFIER ("default-toolbar-border-width",
1683 &Vdefault_toolbar_border_width /*
1684 *Width of the border around the default toolbar.
1685 This is a specifier; use `set-specifier' to change it.
1687 The position of the default toolbar is specified by the function
1688 `set-default-toolbar-position'. If the corresponding position-specific
1689 toolbar border width specifier (e.g. `top-toolbar-border-width' if
1690 `default-toolbar-position' is 'top) does not specify a border width in a
1691 particular domain (a window or a frame), then the value of
1692 `default-toolbar-border-width' in that domain, if any, will be used
1695 Internally, toolbar border width specifiers are instantiated in both
1696 window and frame domains, for different purposes. The value in the
1697 domain of a frame's selected window specifies the actual toolbar border
1698 width that you will see in that frame. The value in the domain of a
1699 frame itself specifies the toolbar border width that is used in frame
1700 geometry calculations. Changing the border width value in the frame
1701 domain will result in a size change in the frame itself, while changing
1702 the value in a window domain will not.
1704 Vdefault_toolbar_border_width = Fmake_specifier (Qnatnum);
1705 set_specifier_caching (Vdefault_toolbar_border_width,
1706 slot_offset (struct window,
1707 default_toolbar_border_width),
1708 default_toolbar_border_width_changed_in_window,
1709 slot_offset (struct frame,
1710 default_toolbar_border_width),
1711 default_toolbar_border_width_changed_in_frame);
1713 DEFVAR_SPECIFIER ("top-toolbar-border-width",
1714 &Vtoolbar_border_width[TOP_TOOLBAR] /*
1715 *Border width of the top toolbar.
1716 This is a specifier; use `set-specifier' to change it.
1718 See `default-toolbar-height' for more information.
1720 Vtoolbar_border_width[TOP_TOOLBAR] = Fmake_specifier (Qnatnum);
1721 set_specifier_caching (Vtoolbar_border_width[TOP_TOOLBAR],
1722 slot_offset (struct window,
1723 toolbar_border_width[TOP_TOOLBAR]),
1724 toolbar_geometry_changed_in_window,
1725 slot_offset (struct frame,
1726 toolbar_border_width[TOP_TOOLBAR]),
1727 frame_size_slipped);
1729 DEFVAR_SPECIFIER ("bottom-toolbar-border-width",
1730 &Vtoolbar_border_width[BOTTOM_TOOLBAR] /*
1731 *Border width of the bottom toolbar.
1732 This is a specifier; use `set-specifier' to change it.
1734 See `default-toolbar-height' for more information.
1736 Vtoolbar_border_width[BOTTOM_TOOLBAR] = Fmake_specifier (Qnatnum);
1737 set_specifier_caching (Vtoolbar_border_width[BOTTOM_TOOLBAR],
1738 slot_offset (struct window,
1739 toolbar_border_width[BOTTOM_TOOLBAR]),
1740 toolbar_geometry_changed_in_window,
1741 slot_offset (struct frame,
1742 toolbar_border_width[BOTTOM_TOOLBAR]),
1743 frame_size_slipped);
1745 DEFVAR_SPECIFIER ("left-toolbar-border-width",
1746 &Vtoolbar_border_width[LEFT_TOOLBAR] /*
1747 *Border width of left toolbar.
1748 This is a specifier; use `set-specifier' to change it.
1750 See `default-toolbar-height' for more information.
1752 Vtoolbar_border_width[LEFT_TOOLBAR] = Fmake_specifier (Qnatnum);
1753 set_specifier_caching (Vtoolbar_border_width[LEFT_TOOLBAR],
1754 slot_offset (struct window,
1755 toolbar_border_width[LEFT_TOOLBAR]),
1756 toolbar_geometry_changed_in_window,
1757 slot_offset (struct frame,
1758 toolbar_border_width[LEFT_TOOLBAR]),
1759 frame_size_slipped);
1761 DEFVAR_SPECIFIER ("right-toolbar-border-width",
1762 &Vtoolbar_border_width[RIGHT_TOOLBAR] /*
1763 *Border width of right toolbar.
1764 This is a specifier; use `set-specifier' to change it.
1766 See `default-toolbar-height' for more information.
1768 Vtoolbar_border_width[RIGHT_TOOLBAR] = Fmake_specifier (Qnatnum);
1769 set_specifier_caching (Vtoolbar_border_width[RIGHT_TOOLBAR],
1770 slot_offset (struct window,
1771 toolbar_border_width[RIGHT_TOOLBAR]),
1772 toolbar_geometry_changed_in_window,
1773 slot_offset (struct frame,
1774 toolbar_border_width[RIGHT_TOOLBAR]),
1775 frame_size_slipped);
1779 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1781 #ifdef HAVE_X_WINDOWS
1782 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_TOOLBAR_BORDER_WIDTH)), fb);
1784 #ifdef HAVE_MS_WINDOWS
1785 fb = Fcons (Fcons (list1 (Qmswindows), make_int (MSWINDOWS_DEFAULT_TOOLBAR_BORDER_WIDTH)), fb);
1788 set_specifier_fallback (Vdefault_toolbar_border_width, fb);
1790 set_specifier_fallback (Vtoolbar_border_width[TOP_TOOLBAR], Vdefault_toolbar_border_width);
1791 fb = list1 (Fcons (Qnil, Qzero));
1792 set_specifier_fallback (Vtoolbar_border_width[BOTTOM_TOOLBAR], fb);
1793 set_specifier_fallback (Vtoolbar_border_width[LEFT_TOOLBAR], fb);
1794 set_specifier_fallback (Vtoolbar_border_width[RIGHT_TOOLBAR], fb);
1796 DEFVAR_SPECIFIER ("default-toolbar-visible-p", &Vdefault_toolbar_visible_p /*
1797 *Whether the default toolbar is visible.
1798 This is a specifier; use `set-specifier' to change it.
1800 The position of the default toolbar is specified by the function
1801 `set-default-toolbar-position'. If the corresponding position-specific
1802 toolbar visibility specifier (e.g. `top-toolbar-visible-p' if
1803 `default-toolbar-position' is 'top) does not specify a visible-p value
1804 in a particular domain (a window or a frame), then the value of
1805 `default-toolbar-visible-p' in that domain, if any, will be used
1808 Both window domains and frame domains are used internally, for
1809 different purposes. The distinction here is exactly the same as
1810 for thickness specifiers; see `default-toolbar-height' for more
1813 `default-toolbar-visible-p' and all of the position-specific toolbar
1814 visibility specifiers have a fallback value of true.
1816 Vdefault_toolbar_visible_p = Fmake_specifier (Qboolean);
1817 set_specifier_caching (Vdefault_toolbar_visible_p,
1818 slot_offset (struct window,
1819 default_toolbar_visible_p),
1820 default_toolbar_visible_p_changed_in_window,
1821 slot_offset (struct frame,
1822 default_toolbar_visible_p),
1823 default_toolbar_visible_p_changed_in_frame);
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 slot_offset (struct window,
1835 toolbar_visible_p[TOP_TOOLBAR]),
1836 toolbar_geometry_changed_in_window,
1837 slot_offset (struct frame,
1838 toolbar_visible_p[TOP_TOOLBAR]),
1839 frame_size_slipped);
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 slot_offset (struct window,
1851 toolbar_visible_p[BOTTOM_TOOLBAR]),
1852 toolbar_geometry_changed_in_window,
1853 slot_offset (struct frame,
1854 toolbar_visible_p[BOTTOM_TOOLBAR]),
1855 frame_size_slipped);
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 slot_offset (struct window,
1867 toolbar_visible_p[LEFT_TOOLBAR]),
1868 toolbar_geometry_changed_in_window,
1869 slot_offset (struct frame,
1870 toolbar_visible_p[LEFT_TOOLBAR]),
1871 frame_size_slipped);
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 slot_offset (struct window,
1883 toolbar_visible_p[RIGHT_TOOLBAR]),
1884 toolbar_geometry_changed_in_window,
1885 slot_offset (struct frame,
1886 toolbar_visible_p[RIGHT_TOOLBAR]),
1887 frame_size_slipped);
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 slot_offset (struct window,
1909 toolbar_buttons_captioned_p),
1910 toolbar_buttons_captioned_p_changed,
1912 set_specifier_fallback (Vtoolbar_buttons_captioned_p,
1913 list1 (Fcons (Qnil, Qt)));