Merge remote-tracking branch 'origin/master' into for-steve
[sxemacs] / src / ui / menubar.c
1 /* Implements an elisp-programmable menubar.
2    Copyright (C) 1993, 1994 Free Software Foundation, Inc.
3    Copyright (C) 1995 Tinker Systems and INS Engineering Corp.
4
5 This file is part of SXEmacs
6
7 SXEmacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 SXEmacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
19
20
21 /* Synched up with: Not in FSF. */
22
23 /* Authorship:
24
25    Created by Ben Wing as part of device-abstraction work for 19.12.
26    Menu filters and many other keywords added by Stig for 19.12.
27    Menu accelerators c. 1997? by ??.  Moved here from event-stream.c.
28    Much other work post-1996 by ??.
29 */
30
31 #include <config.h>
32 #include "lisp.h"
33
34 #include "buffer.h"
35 #include "device.h"
36 #include "frame.h"
37 #include "gui.h"
38 #include "keymap.h"
39 #include "menubar.h"
40 #include "redisplay.h"
41 #include "window.h"
42
43 int menubar_show_keybindings;
44 Lisp_Object Vmenubar_configuration;
45
46 Lisp_Object Qcurrent_menubar;
47
48 Lisp_Object Qactivate_menubar_hook, Vactivate_menubar_hook;
49
50 Lisp_Object Vmenubar_visible_p;
51
52 static Lisp_Object Vcurrent_menubar;    /* DO NOT ever reference this.
53                                            Always go through Qcurrent_menubar.
54                                            See below. */
55
56 Lisp_Object Vblank_menubar;
57
58 int popup_menu_titles;
59
60 Lisp_Object Vmenubar_pointer_glyph;
61
62 /* prefix key(s) that must match in order to activate menu.
63    This is ugly.  fix me.
64    */
65 Lisp_Object Vmenu_accelerator_prefix;
66
67 /* list of modifier keys to match accelerator for top level menus */
68 Lisp_Object Vmenu_accelerator_modifiers;
69
70 /* whether menu accelerators are enabled */
71 Lisp_Object Vmenu_accelerator_enabled;
72
73 /* keymap for auxiliary menu accelerator functions */
74 Lisp_Object Vmenu_accelerator_map;
75
76 Lisp_Object Qmenu_force;
77 Lisp_Object Qmenu_fallback;
78 Lisp_Object Qmenu_quit;
79 Lisp_Object Qmenu_up;
80 Lisp_Object Qmenu_down;
81 Lisp_Object Qmenu_left;
82 Lisp_Object Qmenu_right;
83 Lisp_Object Qmenu_select;
84 Lisp_Object Qmenu_escape;
85
86 static int
87 menubar_variable_changed(Lisp_Object sym, Lisp_Object * val,
88                          Lisp_Object in_object, int flags)
89 {
90         MARK_MENUBAR_CHANGED;
91         return 0;
92 }
93
94 void update_frame_menubars(struct frame *f)
95 {
96         if (f->menubar_changed || f->windows_changed)
97                 MAYBE_FRAMEMETH(f, update_frame_menubars, (f));
98
99         f->menubar_changed = 0;
100 }
101
102 void free_frame_menubars(struct frame *f)
103 {
104         /* If we had directly allocated any memory for the menubars instead
105            of using all Lisp_Objects this is where we would now free it. */
106
107         MAYBE_FRAMEMETH(f, free_frame_menubars, (f));
108 }
109
110 static void
111 menubar_visible_p_changed(Lisp_Object specifier, struct window *w,
112                           Lisp_Object oldval)
113 {
114         MARK_MENUBAR_CHANGED;
115 }
116
117 static void
118 menubar_visible_p_changed_in_frame(Lisp_Object specifier, struct frame *f,
119                                    Lisp_Object oldval)
120 {
121         update_frame_menubars(f);
122 }
123
124 Lisp_Object current_frame_menubar(const struct frame *f)
125 {
126         struct window *w = XWINDOW(FRAME_LAST_NONMINIBUF_WINDOW(f));
127         return symbol_value_in_buffer(Qcurrent_menubar, w->buffer);
128 }
129
130 Lisp_Object menu_parse_submenu_keywords(Lisp_Object desc, Lisp_Object gui_item)
131 {
132         Lisp_Gui_Item *pgui_item = XGUI_ITEM(gui_item);
133
134         /* Menu descriptor should be a list */
135         CHECK_CONS(desc);
136
137         /* First element may be menu name, although can be omitted.
138            Let's think that if stuff begins with anything than a keyword
139            or a list (submenu), this is a menu name, expected to be a string */
140         if (!KEYWORDP(XCAR(desc)) && !CONSP(XCAR(desc))) {
141                 CHECK_STRING(XCAR(desc));
142                 pgui_item->name = XCAR(desc);
143                 desc = XCDR(desc);
144                 if (!NILP(desc))
145                         CHECK_CONS(desc);
146         }
147
148         /* Walk along all key-value pairs */
149         while (!NILP(desc) && KEYWORDP(XCAR(desc))) {
150                 Lisp_Object key, val;
151                 key = XCAR(desc);
152                 desc = XCDR(desc);
153                 CHECK_CONS(desc);
154                 val = XCAR(desc);
155                 desc = XCDR(desc);
156                 if (!NILP(desc))
157                         CHECK_CONS(desc);
158                 gui_item_add_keyval_pair(gui_item, key, val, ERROR_ME);
159         }
160
161         /* Return the rest - supposed to be a list of items */
162         return desc;
163 }
164
165 DEFUN("menu-find-real-submenu", Fmenu_find_real_submenu, 2, 2, 0,       /*
166 Find a submenu descriptor within DESC by following PATH.
167 This function finds a submenu descriptor, either from the description
168 DESC or generated by a filter within DESC. The function regards :config
169 and :included keywords in the DESC, and expands submenus along the
170 PATH using :filter functions. Return value is a descriptor for the
171 submenu, NOT expanded and NOT checked against :config and :included.
172 Also, individual menu items are not looked for, only submenus.
173
174 See also 'find-menu-item'.
175 */
176       (desc, path))
177 {
178         Lisp_Object path_entry, submenu_desc, submenu;
179         struct gcpro gcpro1, gcpro2;
180         Lisp_Object gui_item = allocate_gui_item();
181         Lisp_Gui_Item *pgui_item = XGUI_ITEM(gui_item);
182
183         GCPRO2(gui_item, desc);
184
185         EXTERNAL_LIST_LOOP(path_entry, path) {
186                 /* Verify that DESC describes a menu, not single item */
187                 if (!CONSP(desc))
188                         RETURN_UNGCPRO(Qnil);
189
190                 /* Parse this menu */
191                 desc = menu_parse_submenu_keywords(desc, gui_item);
192
193                 /* Check that this (sub)menu is active */
194                 if (!gui_item_active_p(gui_item))
195                         RETURN_UNGCPRO(Qnil);
196
197                 /* Apply :filter */
198                 if (!NILP(pgui_item->filter))
199                         desc = call1(pgui_item->filter, desc);
200
201                 /* Find the next menu on the path inside this one */
202                 EXTERNAL_LIST_LOOP(submenu_desc, desc) {
203                         submenu = XCAR(submenu_desc);
204                         if (CONSP(submenu)
205                             && STRINGP(XCAR(submenu))
206                             &&
207                             !NILP(Fstring_equal
208                                   (XCAR(submenu), XCAR(path_entry)))) {
209                                 desc = submenu;
210                                 goto descend;
211                         }
212                 }
213                 /* Submenu not found */
214                 RETURN_UNGCPRO(Qnil);
215
216               descend:
217                 /* Prepare for the next iteration */
218                 gui_item_init(gui_item);
219         }
220
221         /* We have successfully descended down the end of the path */
222         UNGCPRO;
223         return desc;
224 }
225
226 DEFUN("popup-menu", Fpopup_menu, 1, 2, 0,       /*
227 Pop up the menu described by MENU-DESCRIPTION.
228 A menu description is a list of menu items, strings, and submenus.
229
230 The first element of a menu must be a string, which is the name of the menu.
231 This is the string that will be displayed in the parent menu, if any.  For
232 toplevel menus, it is ignored.  This string is not displayed in the menu
233 itself.
234
235 If an element of a menu is a string, then that string will be presented in
236 the menu as unselectable text.
237
238 If an element of a menu is a string consisting solely of hyphens, then that
239 item will be presented as a solid horizontal line.
240
241 If an element of a menu is a list, it is treated as a submenu.  The name of
242 that submenu (the first element in the list) will be used as the name of the
243 item representing this menu on the parent.
244
245 Otherwise, the element must be a vector, which describes a menu item.
246 A menu item can have any of the following forms:
247
248 [ "name" callback <active-p> ]
249 [ "name" callback <active-p> <suffix> ]
250 [ "name" callback :<keyword> <value>  :<keyword> <value> ... ]
251
252 The name is the string to display on the menu; it is filtered through the
253 resource database, so it is possible for resources to override what string
254 is actually displayed.
255
256 If the `callback' of a menu item is a symbol, then it must name a command.
257 It will be invoked with `call-interactively'.  If it is a list, then it is
258 evaluated with `eval'.
259
260 The possible keywords are this:
261
262 :active   <form>    Same as <active-p> in the first two forms: the
263 expression is evaluated just before the menu is
264 displayed, and the menu will be selectable only if
265 the result is non-nil.
266
267 :suffix   <form>    Same as <suffix> in the second form: the expression
268 is evaluated just before the menu is displayed and
269 resulting string is appended to the displayed name,
270 providing a convenient way of adding the name of a
271 command's ``argument'' to the menu, like
272 ``Kill Buffer NAME''.
273
274 :keys     "string"  Normally, the keyboard equivalents of commands in
275 menus are displayed when the `callback' is a symbol.
276 This can be used to specify keys for more complex menu
277 items.  It is passed through `substitute-command-keys'
278 first.
279
280 :style    <style>   Specifies what kind of object this menu item is:
281
282 nil     A normal menu item.
283 toggle  A toggle button.
284 radio   A radio button.
285
286 The only difference between toggle and radio buttons is
287 how they are displayed.  But for consistency, a toggle
288 button should be used when there is one option whose
289 value can be turned on or off, and radio buttons should
290 be used when there is a set of mutually exclusive
291 options.  When using a group of radio buttons, you
292 should arrange for no more than one to be marked as
293 selected at a time.
294
295 :selected <form>    Meaningful only when STYLE is `toggle' or `radio'.
296 This specifies whether the button will be in the
297 selected or unselected state.
298
299 For example:
300
301 [ "Save As..."    write-file  t ]
302 [ "Revert Buffer" revert-buffer (buffer-modified-p) ]
303 [ "Read Only"     toggle-read-only :style toggle :selected buffer-read-only ]
304
305 See menubar.el for many more examples.
306 */
307       (menu_description, event))
308 {
309         struct frame *f = decode_frame(Qnil);
310         MAYBE_FRAMEMETH(f, popup_menu, (menu_description, event));
311         return Qnil;
312 }
313
314 DEFUN("normalize-menu-item-name", Fnormalize_menu_item_name, 1, 2, 0,   /*
315 Convert a menu item name string into normal form, and return the new string.
316 Menu item names should be converted to normal form before being compared.
317 This removes %_'s (accelerator indications) and converts %% to %.
318 */
319       (name, buffer))
320 {
321         struct buffer *buf = decode_buffer(buffer, 0);
322         Lisp_String *n;
323         Charcount end;
324         int i;
325         Bufbyte *name_data;
326         Bufbyte *string_result;
327         Bufbyte *string_result_ptr;
328         Emchar elt;
329         int expecting_underscore = 0;
330
331         CHECK_STRING(name);
332
333         n = XSTRING(name);
334         end = string_char_length(n);
335         name_data = string_data(n);
336
337         string_result = (Bufbyte *) alloca(end * MAX_EMCHAR_LEN);
338         string_result_ptr = string_result;
339         for (i = 0; i < end; i++) {
340                 elt = charptr_emchar(name_data);
341                 elt = DOWNCASE(buf, elt);
342                 if (expecting_underscore) {
343                         expecting_underscore = 0;
344                         switch (elt) {
345                         case '%':
346                                 /* Allow `%%' to mean `%'.  */
347                                 string_result_ptr +=
348                                     set_charptr_emchar(string_result_ptr, '%');
349                                 break;
350                         case '_':
351                                 break;
352                         default:
353                                 string_result_ptr +=
354                                     set_charptr_emchar(string_result_ptr, '%');
355                                 string_result_ptr +=
356                                     set_charptr_emchar(string_result_ptr, elt);
357                         }
358                 } else if (elt == '%')
359                         expecting_underscore = 1;
360                 else
361                         string_result_ptr +=
362                             set_charptr_emchar(string_result_ptr, elt);
363                 INC_CHARPTR(name_data);
364         }
365
366         if (string_result_ptr - string_result == XSTRING_LENGTH(name)
367             && !memcmp(string_result, XSTRING_DATA(name), XSTRING_LENGTH(name)))
368                 return name;
369
370         return make_string(string_result, string_result_ptr - string_result);
371 }
372
373 void syms_of_menubar(void)
374 {
375         defsymbol(&Qcurrent_menubar, "current-menubar");
376
377         defsymbol(&Qmenu_force, "menu-force");
378         defsymbol(&Qmenu_fallback, "menu-fallback");
379
380         defsymbol(&Qmenu_quit, "menu-quit");
381         defsymbol(&Qmenu_up, "menu-up");
382         defsymbol(&Qmenu_down, "menu-down");
383         defsymbol(&Qmenu_left, "menu-left");
384         defsymbol(&Qmenu_right, "menu-right");
385         defsymbol(&Qmenu_select, "menu-select");
386         defsymbol(&Qmenu_escape, "menu-escape");
387
388         DEFSUBR(Fpopup_menu);
389         DEFSUBR(Fnormalize_menu_item_name);
390         DEFSUBR(Fmenu_find_real_submenu);
391 }
392
393 void vars_of_menubar(void)
394 {
395         /* put in Vblank_menubar a menubar value which has no visible
396          * items.  This is a bit tricky due to various quirks.  We
397          * could use '(["" nil nil]), but this is apparently equivalent
398          * to '(nil), and a new frame created with this menubar will
399          * get a vertically-squished menubar.  If we use " " as the
400          * button title instead of "", we get an etched button border.
401          * So we use
402          *  '(("No active menubar" ["" nil nil]))
403          * which creates a menu whose title is "No active menubar",
404          * and this works fine.
405          */
406
407         Vblank_menubar = list1(list2(build_string("No active menubar"),
408                                      vector3(build_string(""), Qnil, Qnil)));
409         staticpro(&Vblank_menubar);
410
411         DEFVAR_BOOL("popup-menu-titles", &popup_menu_titles     /*
412 If true, popup menus will have title bars at the top.
413                                                                  */ );
414         popup_menu_titles = 1;
415
416         /* #### Replace current menubar with a specifier. */
417
418         /* All C code must access the menubar via Qcurrent_menubar
419            because it can be buffer-local.  Note that Vcurrent_menubar
420            doesn't need to exist at all, except for the magic function. */
421
422         DEFVAR_LISP_MAGIC("current-menubar", &Vcurrent_menubar  /*
423 The current menubar.  This may be buffer-local.
424
425 When the menubar is changed, the function `set-menubar-dirty-flag' has to
426 be called for the menubar to be updated on the frame.  See `set-menubar'
427 and `set-buffer-menubar'.
428
429 A menubar is a list of menus and menu-items.
430 A menu is a list of menu items, keyword-value pairs, strings, and submenus.
431
432 The first element of a menu must be a string, which is the name of the menu.
433 This is the string that will be displayed in the parent menu, if any.  For
434 toplevel menus, it is ignored.  This string is not displayed in the menu
435 itself.
436
437 Menu accelerators can be indicated in the string by putting the
438 sequence "%_" before the character corresponding to the key that will
439 invoke the menu or menu item.  Uppercase and lowercase accelerators
440 are equivalent.  The sequence "%%" is also special, and is translated
441 into a single %.
442
443 If no menu accelerator is present in the string, SXEmacs will act as if
444 the first character has been tagged as an accelerator.
445
446 Immediately following the name string of the menu, various optional
447 keyword-value pairs are permitted: currently, :filter, :active, :included,
448 and :config. (See below.)
449
450 If an element of a menu (or menubar) is a string, then that string will be
451 presented as unselectable text.
452
453 If an element of a menu is a string consisting solely of hyphens, then that
454 item will be presented as a solid horizontal line.
455
456 If an element of a menu is a string beginning with "--:", it will be
457 presented as a line whose appearance is controlled by the rest of the
458 text in the string.  The allowed line specs are system-dependent, and
459 currently work only under X Windows (with Lucid and Motif menubars);
460 otherwise, a solid horizontal line is presented, as if the string were
461 all hyphens.
462
463 The possibilities are:
464
465 "--:singleLine"
466 "--:doubleLine"
467 "--:singleDashedLine"
468 "--:doubleDashedLine"
469 "--:noLine"
470 "--:shadowEtchedIn"
471 "--:shadowEtchedOut"
472 "--:shadowEtchedInDash"
473 "--:shadowEtchedOutDash"
474 "--:shadowDoubleEtchedIn" (Lucid menubars only)
475 "--:shadowDoubleEtchedOut" (Lucid menubars only)
476 "--:shadowDoubleEtchedInDash" (Lucid menubars only)
477 "--:shadowDoubleEtchedOutDash" (Lucid menubars only)
478
479 If an element of a menu is a list, it is treated as a submenu.  The name of
480 that submenu (the first element in the list) will be used as the name of the
481 item representing this menu on the parent.
482
483 If an element of a menubar is `nil', then it is used to represent the
484 division between the set of menubar-items which are flushleft and those
485 which are flushright.
486
487 Otherwise, the element must be a vector, which describes a menu item.
488 A menu item is of the following form:
489
490 [ "name" callback :<keyword> <value> :<keyword> <value> ... ]
491
492 The following forms are also accepted for compatibility, but deprecated:
493
494 [ "name" callback <active-p> ]
495 [ "name" callback <active-p> <suffix> ]
496
497 The name is the string to display on the menu; it is filtered through the
498 resource database, so it is possible for resources to override what string
499 is actually displayed.  Menu accelerator indicators (the sequence `%_') are
500 also processed; see above.  If the name is not a string, it will be
501 evaluated with `eval', and the result should be a string.
502
503 If the `callback' of a menu item is a symbol, then it must name a command.
504 It will be invoked with `call-interactively'.  If it is a list, then it is
505 evaluated with `eval'.
506
507 In the deprecated forms, <active-p> is equivalent to using the :active
508 keyword, and <suffix> is equivalent to using the :suffix keyword.
509
510 The possible keywords are:
511
512 :active   <form>    The expression is evaluated just before the menu is
513 displayed, and the menu will be selectable only if
514 the result is non-nil.
515
516 :suffix   <form>    The expression is evaluated just before the menu is
517 displayed and the resulting string is appended to
518 the displayed name, providing a convenient way of
519 adding the name of a command's ``argument'' to the
520 menu, like ``Kill Buffer NAME''.
521
522 :keys     "string"  Normally, the keyboard equivalents of commands in
523 menus are displayed when the `callback' is a symbol.
524 This can be used to specify keys for more complex menu
525 items.  It is passed through `substitute-command-keys'
526 first.
527
528 :style    <style>   Specifies what kind of object this menu item is:
529
530 nil     A normal menu item.
531 toggle  A toggle button.
532 radio   A radio button.
533 button  A menubar button.
534
535 The only difference between toggle and radio buttons is
536 how they are displayed.  But for consistency, a toggle
537 button should be used when there is one option whose
538 value can be turned on or off, and radio buttons should
539 be used when there is a set of mutually exclusive
540 options.  When using a group of radio buttons, you
541 should arrange for no more than one to be marked as
542 selected at a time.
543
544 :selected <form>    Meaningful only when STYLE is `toggle', `radio' or
545 `button'.  This specifies whether the button will be in
546 the selected or unselected state.
547
548 :included <form>    This can be used to control the visibility of a menu or
549 menu item.  The form is evaluated and the menu or menu
550 item is only displayed if the result is non-nil.
551
552 :config  <symbol>   This is an efficient shorthand for
553 :included (memq symbol menubar-configuration)
554 See the variable `menubar-configuration'.
555
556 :filter <function>  A menu filter can only be used at the beginning of a
557 submenu description (i.e. not in a menu item itself).
558 (Remember that most of the keywords can take evaluated
559 expressions as well as constants.)  The filter is used to
560 incrementally create a submenu only when it is selected
561 by the user and not every time the menubar is activated.
562 The filter function is passed the list of menu items in
563 the submenu and must return the modified list to be
564 actually used.  The filter MUST NOT destructively modify
565 the list of menu items passed to it.  It is called only
566 when the menu is about to be displayed, so other menus
567 may already be displayed.  Vile and terrible things will
568 happen if a menu filter function changes the current
569 buffer, window, or frame.  It also should not raise,
570 lower, or iconify any frames.  Basically, the filter
571 function should have no side-effects.
572
573 :key-sequence keys  Used in FSF Emacs as an hint to an equivalent keybinding.
574 Ignored by SXEmacs for easymenu.el compatibility.
575 (SXEmacs computes this information automatically.)
576
577 For example:
578
579 ("%_File"
580 :filter file-menu-filter   ; file-menu-filter is a function that takes
581 ; one argument (a list of menu items) and
582 ; returns a list of menu items
583 [ "Save %_As..."    write-file  t ]
584 [ "%_Revert Buffer" revert-buffer (buffer-modified-p) ]
585 [ "R%_ead Only"     toggle-read-only :style toggle
586 :selected buffer-read-only ]
587 )
588
589 See menubar-items.el for many more examples.
590
591 After the menubar is clicked upon, but before any menus are popped up,
592 the functions on the `activate-menubar-hook' are invoked to make top-level
593 changes to the menus and menubar.  Note, however, that the use of menu
594 filters (using the :filter keyword) is usually a more efficient way to
595 dynamically alter or sensitize menus.
596 */ ,
597                           menubar_variable_changed);
598
599         Vcurrent_menubar = Qnil;
600
601         DEFVAR_LISP("activate-menubar-hook", &Vactivate_menubar_hook    /*
602 Function or functions called before a menubar menu is pulled down.
603 These functions are called with no arguments, and should interrogate and
604 modify the value of `current-menubar' as desired.
605
606 The functions on this hook are invoked after the mouse goes down, but before
607 the menu is mapped, and may be used to activate, deactivate, add, or delete
608 items from the menus.  However, it is probably the case that using a :filter
609 keyword in a submenu would be a more efficient way of updating menus.  See
610 the documentation of `current-menubar'.
611
612 These functions may return the symbol `t' to assert that they have made
613 no changes to the menubar.  If any other value is returned, the menubar is
614 recomputed.  If `t' is returned but the menubar has been changed, then the
615 changes may not show up right away.  Returning `nil' when the menubar has
616 not changed is not so bad; more computation will be done, but redisplay of
617 the menubar will still be performed optimally.
618                                                                          */ );
619         Vactivate_menubar_hook = Qnil;
620         defsymbol(&Qactivate_menubar_hook, "activate-menubar-hook");
621
622         DEFVAR_BOOL("menubar-show-keybindings", &menubar_show_keybindings       /*
623 If true, the menubar will display keyboard equivalents.
624 If false, only the command names will be displayed.
625                                                                                  */ );
626         menubar_show_keybindings = 1;
627
628         DEFVAR_LISP_MAGIC("menubar-configuration", &Vmenubar_configuration      /*
629 A list of symbols, against which the value of the :config tag for each
630 menubar item will be compared.  If a menubar item has a :config tag, then
631 it is omitted from the menubar if that tag is not a member of the
632 `menubar-configuration' list.
633                                                                                  */ , menubar_variable_changed);
634         Vmenubar_configuration = Qnil;
635
636         DEFVAR_LISP("menubar-pointer-glyph", &Vmenubar_pointer_glyph    /*
637 *The shape of the mouse-pointer when over the menubar.
638 This is a glyph; use `set-glyph-image' to change it.
639 If unspecified in a particular domain, the window-system-provided
640 default pointer is used.
641                                                                          */ );
642
643         DEFVAR_LISP("menu-accelerator-prefix", &Vmenu_accelerator_prefix        /*
644 Prefix key(s) that must be typed before menu accelerators will be activated.
645 Set this to a value acceptable by define-key.
646
647 NOTE: This currently only has any effect under X Windows.
648                                                                                  */ );
649         Vmenu_accelerator_prefix = Qnil;
650
651         DEFVAR_LISP("menu-accelerator-modifiers", &Vmenu_accelerator_modifiers  /*
652 Modifier keys which must be pressed to get to the top level menu accelerators.
653 This is a list of modifier key symbols.  All modifier keys must be held down
654 while a valid menu accelerator key is pressed in order for the top level
655 menu to become active.
656
657 NOTE: This currently only has any effect under X Windows.
658
659 See also menu-accelerator-enabled and menu-accelerator-prefix.
660                                                                                  */ );
661         Vmenu_accelerator_modifiers = list1(Qmeta);
662
663         DEFVAR_LISP("menu-accelerator-enabled", &Vmenu_accelerator_enabled      /*
664 Whether menu accelerator keys can cause the menubar to become active.
665 If 'menu-force or 'menu-fallback, then menu accelerator keys can
666 be used to activate the top level menu.  Once the menubar becomes active, the
667 accelerator keys can be used regardless of the value of this variable.
668
669 menu-force is used to indicate that the menu accelerator key takes
670 precedence over bindings in the current keymap(s).  menu-fallback means
671 that bindings in the current keymap take precedence over menu accelerator keys.
672 Thus a top level menu with an accelerator of "T" would be activated on a
673 keypress of Meta-t if menu-accelerator-enabled is menu-force.
674 However, if menu-accelerator-enabled is menu-fallback, then
675 Meta-t will not activate the menubar and will instead run the function
676 transpose-words, to which it is normally bound.
677
678 See also menu-accelerator-modifiers and menu-accelerator-prefix.
679                                                                                  */ );
680         Vmenu_accelerator_enabled = Qnil;
681
682         DEFVAR_LISP("menu-accelerator-map", &Vmenu_accelerator_map      /*
683 Keymap for use when the menubar is active.
684 The actions menu-quit, menu-up, menu-down, menu-left, menu-right,
685 menu-select and menu-escape can be mapped to keys in this map.
686 NOTE: This currently only has any effect under X Windows.
687
688 menu-quit    Immediately deactivate the menubar and any open submenus without
689 selecting an item.
690 menu-up      Move the menu cursor up one row in the current menu.  If the
691 move extends past the top of the menu, wrap around to the bottom.
692 menu-down    Move the menu cursor down one row in the current menu.  If the
693 move extends past the bottom of the menu, wrap around to the top.
694 If executed while the cursor is in the top level menu, move down
695 into the selected menu.
696 menu-left    Move the cursor from a submenu into the parent menu.  If executed
697 while the cursor is in the top level menu, move the cursor to the
698 left.  If the move extends past the left edge of the menu, wrap
699 around to the right edge.
700 menu-right   Move the cursor into a submenu.  If the cursor is located in the
701 top level menu or is not currently on a submenu heading, then move
702 the cursor to the next top level menu entry.  If the move extends
703 past the right edge of the menu, wrap around to the left edge.
704 menu-select  Activate the item under the cursor.  If the cursor is located on
705 a submenu heading, then move the cursor into the submenu.
706 menu-escape  Pop up to the next level of menus.  Moves from a submenu into its
707 parent menu.  From the top level menu, this deactivates the
708 menubar.
709
710 This keymap can also contain normal key-command bindings, in which case the
711 menubar is deactivated and the corresponding command is executed.
712
713 The action bindings used by the menu accelerator code are designed to mimic
714 the actions of menu traversal keys in a commonly used PC operating system.
715                                                                          */ );
716
717         Fprovide(intern("menubar"));
718         Fprovide(intern("menu-accelerator-support"));
719 }
720
721 void specifier_vars_of_menubar(void)
722 {
723         DEFVAR_SPECIFIER("menubar-visible-p", &Vmenubar_visible_p       /*
724 *Whether the menubar is visible.
725 This is a specifier; use `set-specifier' to change it.
726                                                                          */ );
727         Vmenubar_visible_p = Fmake_specifier(Qboolean);
728
729         set_specifier_fallback(Vmenubar_visible_p, list1(Fcons(Qnil, Qt)));
730         set_specifier_caching(Vmenubar_visible_p,
731                               offsetof(struct window, menubar_visible_p),
732                               menubar_visible_p_changed,
733                               offsetof(struct frame, menubar_visible_p),
734                               menubar_visible_p_changed_in_frame, 0);
735 }
736
737 void complex_vars_of_menubar(void)
738 {
739         Vmenubar_pointer_glyph = Fmake_glyph_internal(Qpointer);
740
741         Vmenu_accelerator_map = Fmake_keymap(Qnil);
742 }