comparison src/menubar.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 576fb035e263
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */ 20 Boston, MA 02111-1307, USA. */
21 21
22 /* Synched up with: Not in FSF. */ 22 /* Synched up with: Not in FSF. */
23 23
24 /* #### There ain't much here because menubars have not been 24 /* Authorship:
25 properly abstracted yet. */ 25
26 Created by Ben Wing as part of device-abstraction work for 19.12.
27 Menu filters and many other keywords added by Stig for 19.12.
28 Menu accelerators c. 1997? by ??. Moved here from event-stream.c.
29 Much other work post-1996 by ??.
30 */
26 31
27 #include <config.h> 32 #include <config.h>
28 #include "lisp.h" 33 #include "lisp.h"
29 34
30 #include "buffer.h" 35 #include "buffer.h"
31 #include "device.h" 36 #include "device.h"
32 #include "frame.h" 37 #include "frame.h"
33 #include "gui.h" 38 #include "gui.h"
39 #include "keymap.h"
34 #include "menubar.h" 40 #include "menubar.h"
35 #include "redisplay.h" 41 #include "redisplay.h"
36 #include "window.h" 42 #include "window.h"
37 43
38 int menubar_show_keybindings; 44 int menubar_show_keybindings;
52 58
53 int popup_menu_titles; 59 int popup_menu_titles;
54 60
55 Lisp_Object Vmenubar_pointer_glyph; 61 Lisp_Object Vmenubar_pointer_glyph;
56 62
63 /* prefix key(s) that must match in order to activate menu.
64 This is ugly. fix me.
65 */
66 Lisp_Object Vmenu_accelerator_prefix;
67
68 /* list of modifier keys to match accelerator for top level menus */
69 Lisp_Object Vmenu_accelerator_modifiers;
70
71 /* whether menu accelerators are enabled */
72 Lisp_Object Vmenu_accelerator_enabled;
73
74 /* keymap for auxiliary menu accelerator functions */
75 Lisp_Object Vmenu_accelerator_map;
76
77 Lisp_Object Qmenu_force;
78 Lisp_Object Qmenu_fallback;
79 Lisp_Object Qmenu_quit;
80 Lisp_Object Qmenu_up;
81 Lisp_Object Qmenu_down;
82 Lisp_Object Qmenu_left;
83 Lisp_Object Qmenu_right;
84 Lisp_Object Qmenu_select;
85 Lisp_Object Qmenu_escape;
86
57 static int 87 static int
58 menubar_variable_changed (Lisp_Object sym, Lisp_Object *val, 88 menubar_variable_changed (Lisp_Object sym, Lisp_Object *val,
59 Lisp_Object in_object, int flags) 89 Lisp_Object in_object, int flags)
60 { 90 {
61 MARK_MENUBAR_CHANGED; 91 MARK_MENUBAR_CHANGED;
93 { 123 {
94 update_frame_menubars (f); 124 update_frame_menubars (f);
95 } 125 }
96 126
97 Lisp_Object 127 Lisp_Object
98 current_frame_menubar (CONST struct frame* f) 128 current_frame_menubar (const struct frame* f)
99 { 129 {
100 struct window *w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f)); 130 struct window *w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f));
101 return symbol_value_in_buffer (Qcurrent_menubar, w->buffer); 131 return symbol_value_in_buffer (Qcurrent_menubar, w->buffer);
102 } 132 }
103 133
104 Lisp_Object 134 Lisp_Object
105 menu_parse_submenu_keywords (Lisp_Object desc, Lisp_Object gui_item) 135 menu_parse_submenu_keywords (Lisp_Object desc, Lisp_Object gui_item)
106 { 136 {
107 Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item); 137 Lisp_Gui_Item *pgui_item = XGUI_ITEM (gui_item);
108 138
109 /* Menu descriptor should be a list */ 139 /* Menu descriptor should be a list */
110 CHECK_CONS (desc); 140 CHECK_CONS (desc);
111 141
112 /* First element may be menu name, although can be omitted. 142 /* First element may be menu name, although can be omitted.
151 See also 'find-menu-item'. 181 See also 'find-menu-item'.
152 */ 182 */
153 (desc, path)) 183 (desc, path))
154 { 184 {
155 Lisp_Object path_entry, submenu_desc, submenu; 185 Lisp_Object path_entry, submenu_desc, submenu;
156 struct gcpro gcpro1; 186 struct gcpro gcpro1, gcpro2;
157 Lisp_Object gui_item = allocate_gui_item (); 187 Lisp_Object gui_item = allocate_gui_item ();
158 Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item); 188 Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item);
159 189
160 GCPRO1 (gui_item); 190 GCPRO2 (gui_item, desc);
161 191
162 EXTERNAL_LIST_LOOP (path_entry, path) 192 EXTERNAL_LIST_LOOP (path_entry, path)
163 { 193 {
164 /* Verify that DESC describes a menu, not single item */ 194 /* Verify that DESC describes a menu, not single item */
165 if (!CONSP (desc)) 195 if (!CONSP (desc))
290 } 320 }
291 321
292 DEFUN ("normalize-menu-item-name", Fnormalize_menu_item_name, 1, 2, 0, /* 322 DEFUN ("normalize-menu-item-name", Fnormalize_menu_item_name, 1, 2, 0, /*
293 Convert a menu item name string into normal form, and return the new string. 323 Convert a menu item name string into normal form, and return the new string.
294 Menu item names should be converted to normal form before being compared. 324 Menu item names should be converted to normal form before being compared.
325 This removes %_'s (accelerator indications) and converts %% to %.
295 */ 326 */
296 (name, buffer)) 327 (name, buffer))
297 { 328 {
298 struct buffer *buf = decode_buffer (buffer, 0); 329 struct buffer *buf = decode_buffer (buffer, 0);
299 Lisp_String *n; 330 Lisp_String *n;
338 else 369 else
339 string_result_ptr += set_charptr_emchar (string_result_ptr, elt); 370 string_result_ptr += set_charptr_emchar (string_result_ptr, elt);
340 INC_CHARPTR (name_data); 371 INC_CHARPTR (name_data);
341 } 372 }
342 373
374 if (string_result_ptr - string_result == XSTRING_LENGTH (name)
375 && !memcmp (string_result, XSTRING_DATA (name), XSTRING_LENGTH (name)))
376 return name;
377
343 return make_string (string_result, string_result_ptr - string_result); 378 return make_string (string_result, string_result_ptr - string_result);
344 } 379 }
345 380
346 void 381 void
347 syms_of_menubar (void) 382 syms_of_menubar (void)
348 { 383 {
349 defsymbol (&Qcurrent_menubar, "current-menubar"); 384 defsymbol (&Qcurrent_menubar, "current-menubar");
385
386 defsymbol (&Qmenu_force, "menu-force");
387 defsymbol (&Qmenu_fallback, "menu-fallback");
388
389 defsymbol (&Qmenu_quit, "menu-quit");
390 defsymbol (&Qmenu_up, "menu-up");
391 defsymbol (&Qmenu_down, "menu-down");
392 defsymbol (&Qmenu_left, "menu-left");
393 defsymbol (&Qmenu_right, "menu-right");
394 defsymbol (&Qmenu_select, "menu-select");
395 defsymbol (&Qmenu_escape, "menu-escape");
396
350 DEFSUBR (Fpopup_menu); 397 DEFSUBR (Fpopup_menu);
351 DEFSUBR (Fnormalize_menu_item_name); 398 DEFSUBR (Fnormalize_menu_item_name);
352 DEFSUBR (Fmenu_find_real_submenu); 399 DEFSUBR (Fmenu_find_real_submenu);
353 } 400 }
354 401
395 The first element of a menu must be a string, which is the name of the menu. 442 The first element of a menu must be a string, which is the name of the menu.
396 This is the string that will be displayed in the parent menu, if any. For 443 This is the string that will be displayed in the parent menu, if any. For
397 toplevel menus, it is ignored. This string is not displayed in the menu 444 toplevel menus, it is ignored. This string is not displayed in the menu
398 itself. 445 itself.
399 446
400 Immediately following the name string of the menu, any of three 447 Menu accelerators can be indicated in the string by putting the
401 optional keyword-value pairs is permitted. 448 sequence "%_" before the character corresponding to the key that will
449 invoke the menu or menu item. Uppercase and lowercase accelerators
450 are equivalent. The sequence "%%" is also special, and is translated
451 into a single %.
452
453 If no menu accelerator is present in the string, XEmacs will act as if
454 the first character has been tagged as an accelerator.
455
456 Immediately following the name string of the menu, various optional
457 keyword-value pairs are permitted: currently, :filter, :active, :included,
458 and :config. (See below.)
402 459
403 If an element of a menu (or menubar) is a string, then that string will be 460 If an element of a menu (or menubar) is a string, then that string will be
404 presented as unselectable text. 461 presented as unselectable text.
405 462
406 If an element of a menu is a string consisting solely of hyphens, then that 463 If an element of a menu is a string consisting solely of hyphens, then that
407 item will be presented as a solid horizontal line. 464 item will be presented as a solid horizontal line.
465
466 If an element of a menu is a string beginning with "--:", it will be
467 presented as a line whose appearance is controlled by the rest of the
468 text in the string. The allowed line specs are system-dependent, and
469 currently work only under X Windows (with Lucid and Motif menubars);
470 otherwise, a solid horizontal line is presented, as if the string were
471 all hyphens.
472
473 The possibilities are:
474
475 "--:singleLine"
476 "--:doubleLine"
477 "--:singleDashedLine"
478 "--:doubleDashedLine"
479 "--:noLine"
480 "--:shadowEtchedIn"
481 "--:shadowEtchedOut"
482 "--:shadowEtchedInDash"
483 "--:shadowEtchedOutDash"
484 "--:shadowDoubleEtchedIn" (Lucid menubars only)
485 "--:shadowDoubleEtchedOut" (Lucid menubars only)
486 "--:shadowDoubleEtchedInDash" (Lucid menubars only)
487 "--:shadowDoubleEtchedOutDash" (Lucid menubars only)
408 488
409 If an element of a menu is a list, it is treated as a submenu. The name of 489 If an element of a menu is a list, it is treated as a submenu. The name of
410 that submenu (the first element in the list) will be used as the name of the 490 that submenu (the first element in the list) will be used as the name of the
411 item representing this menu on the parent. 491 item representing this menu on the parent.
412 492
413 If an element of a menubar is `nil', then it is used to represent the 493 If an element of a menubar is `nil', then it is used to represent the
414 division between the set of menubar-items which are flushleft and those 494 division between the set of menubar-items which are flushleft and those
415 which are flushright. 495 which are flushright.
416 496
417 Otherwise, the element must be a vector, which describes a menu item. 497 Otherwise, the element must be a vector, which describes a menu item.
418 A menu item can have any of the following forms: 498 A menu item is of the following form:
499
500 [ "name" callback :<keyword> <value> :<keyword> <value> ... ]
501
502 The following forms are also accepted for compatibility, but deprecated:
419 503
420 [ "name" callback <active-p> ] 504 [ "name" callback <active-p> ]
421 [ "name" callback <active-p> <suffix> ] 505 [ "name" callback <active-p> <suffix> ]
422 [ "name" callback :<keyword> <value> :<keyword> <value> ... ]
423 506
424 The name is the string to display on the menu; it is filtered through the 507 The name is the string to display on the menu; it is filtered through the
425 resource database, so it is possible for resources to override what string 508 resource database, so it is possible for resources to override what string
426 is actually displayed. 509 is actually displayed. Menu accelerator indicators (the sequence `%_') are
510 also processed; see above. If the name is not a string, it will be
511 evaluated with `eval', and the result should be a string.
427 512
428 If the `callback' of a menu item is a symbol, then it must name a command. 513 If the `callback' of a menu item is a symbol, then it must name a command.
429 It will be invoked with `call-interactively'. If it is a list, then it is 514 It will be invoked with `call-interactively'. If it is a list, then it is
430 evaluated with `eval'. 515 evaluated with `eval'.
431 516
432 The possible keywords are this: 517 In the deprecated forms, <active-p> is equivalent to using the :active
433 518 keyword, and <suffix> is equivalent to using the :suffix keyword.
434 :active <form> Same as <active-p> in the first two forms: the 519
435 expression is evaluated just before the menu is 520 The possible keywords are:
521
522 :active <form> The expression is evaluated just before the menu is
436 displayed, and the menu will be selectable only if 523 displayed, and the menu will be selectable only if
437 the result is non-nil. 524 the result is non-nil.
438 525
439 :suffix <form> Same as <suffix> in the second form: the expression 526 :suffix <form> The expression is evaluated just before the menu is
440 is evaluated just before the menu is displayed and 527 displayed and the resulting string is appended to
441 resulting string is appended to the displayed name, 528 the displayed name, providing a convenient way of
442 providing a convenient way of adding the name of a 529 adding the name of a command's ``argument'' to the
443 command's ``argument'' to the menu, like 530 menu, like ``Kill Buffer NAME''.
444 ``Kill Buffer NAME''.
445 531
446 :keys "string" Normally, the keyboard equivalents of commands in 532 :keys "string" Normally, the keyboard equivalents of commands in
447 menus are displayed when the `callback' is a symbol. 533 menus are displayed when the `callback' is a symbol.
448 This can be used to specify keys for more complex menu 534 This can be used to specify keys for more complex menu
449 items. It is passed through `substitute-command-keys' 535 items. It is passed through `substitute-command-keys'
475 561
476 :config <symbol> This is an efficient shorthand for 562 :config <symbol> This is an efficient shorthand for
477 :included (memq symbol menubar-configuration) 563 :included (memq symbol menubar-configuration)
478 See the variable `menubar-configuration'. 564 See the variable `menubar-configuration'.
479 565
480 :filter <function> A menu filter can only be used in a menu item list. 566 :filter <function> A menu filter can only be used at the beginning of a
481 (i.e.: not in a menu item itself). It is used to 567 submenu description (i.e. not in a menu item itself).
482 sensitize or incrementally create a submenu only when 568 (Remember that most of the keywords can take evaluated
483 it is selected by the user and not every time the 569 expressions as well as constants.) The filter is used to
484 menubar is activated. The filter function is passed 570 incrementally create a submenu only when it is selected
485 the list of menu items in the submenu and must return a 571 by the user and not every time the menubar is activated.
486 list of menu items to be used for the menu. It is 572 The filter function is passed the list of menu items in
487 called only when the menu is about to be displayed, so 573 the submenu and must return the modified list to be
488 other menus may already be displayed. Vile and 574 actually used. The filter MUST NOT destructively modify
489 terrible things will happen if a menu filter function 575 the list of menu items passed to it. It is called only
490 changes the current buffer, window, or frame. It 576 when the menu is about to be displayed, so other menus
491 also should not raise, lower, or iconify any frames. 577 may already be displayed. Vile and terrible things will
492 Basically, the filter function should have no 578 happen if a menu filter function changes the current
493 side-effects. 579 buffer, window, or frame. It also should not raise,
580 lower, or iconify any frames. Basically, the filter
581 function should have no side-effects.
494 582
495 :key-sequence keys Used in FSF Emacs as an hint to an equivalent keybinding. 583 :key-sequence keys Used in FSF Emacs as an hint to an equivalent keybinding.
496 Ignored by XEnacs for easymenu.el compatibility. 584 Ignored by XEmacs for easymenu.el compatibility.
497 585 (XEmacs computes this information automatically.)
498 :label <form> (unimplemented!) Like :suffix, but replaces label
499 completely.
500 (might be added in 21.2).
501 586
502 For example: 587 For example:
503 588
504 ("File" 589 ("%_File"
505 :filter file-menu-filter ; file-menu-filter is a function that takes 590 :filter file-menu-filter ; file-menu-filter is a function that takes
506 ; one argument (a list of menu items) and 591 ; one argument (a list of menu items) and
507 ; returns a list of menu items 592 ; returns a list of menu items
508 [ "Save As..." write-file t ] 593 [ "Save %_As..." write-file t ]
509 [ "Revert Buffer" revert-buffer (buffer-modified-p) ] 594 [ "%_Revert Buffer" revert-buffer (buffer-modified-p) ]
510 [ "Read Only" toggle-read-only :style toggle 595 [ "R%_ead Only" toggle-read-only :style toggle
511 :selected buffer-read-only ] 596 :selected buffer-read-only ]
512 ) 597 )
513 598
514 See x-menubar.el for many more examples. 599 See menubar-items.el for many more examples.
515 600
516 After the menubar is clicked upon, but before any menus are popped up, 601 After the menubar is clicked upon, but before any menus are popped up,
517 the functions on the `activate-menubar-hook' are invoked to make top-level 602 the functions on the `activate-menubar-hook' are invoked to make top-level
518 changes to the menus and menubar. Note, however, that the use of menu 603 changes to the menus and menubar. Note, however, that the use of menu
519 filters (using the :filter keyword) is usually a more efficient way to 604 filters (using the :filter keyword) is usually a more efficient way to
520 dynamically alter or sensitize menus. 605 dynamically alter or sensitize menus. */, menubar_variable_changed);
521 */, menubar_variable_changed);
522 606
523 Vcurrent_menubar = Qnil; 607 Vcurrent_menubar = Qnil;
524 608
525 DEFVAR_LISP ("activate-menubar-hook", &Vactivate_menubar_hook /* 609 DEFVAR_LISP ("activate-menubar-hook", &Vactivate_menubar_hook /*
526 Function or functions called before a menubar menu is pulled down. 610 Function or functions called before a menubar menu is pulled down.
562 This is a glyph; use `set-glyph-image' to change it. 646 This is a glyph; use `set-glyph-image' to change it.
563 If unspecified in a particular domain, the window-system-provided 647 If unspecified in a particular domain, the window-system-provided
564 default pointer is used. 648 default pointer is used.
565 */ ); 649 */ );
566 650
651 DEFVAR_LISP ("menu-accelerator-prefix", &Vmenu_accelerator_prefix /*
652 Prefix key(s) that must be typed before menu accelerators will be activated.
653 Set this to a value acceptable by define-key.
654
655 NOTE: This currently only has any effect under X Windows.
656 */ );
657 Vmenu_accelerator_prefix = Qnil;
658
659 DEFVAR_LISP ("menu-accelerator-modifiers", &Vmenu_accelerator_modifiers /*
660 Modifier keys which must be pressed to get to the top level menu accelerators.
661 This is a list of modifier key symbols. All modifier keys must be held down
662 while a valid menu accelerator key is pressed in order for the top level
663 menu to become active.
664
665 NOTE: This currently only has any effect under X Windows.
666
667 See also menu-accelerator-enabled and menu-accelerator-prefix.
668 */ );
669 Vmenu_accelerator_modifiers = list1 (Qmeta);
670
671 DEFVAR_LISP ("menu-accelerator-enabled", &Vmenu_accelerator_enabled /*
672 Whether menu accelerator keys can cause the menubar to become active.
673 If 'menu-force or 'menu-fallback, then menu accelerator keys can
674 be used to activate the top level menu. Once the menubar becomes active, the
675 accelerator keys can be used regardless of the value of this variable.
676
677 menu-force is used to indicate that the menu accelerator key takes
678 precedence over bindings in the current keymap(s). menu-fallback means
679 that bindings in the current keymap take precedence over menu accelerator keys.
680 Thus a top level menu with an accelerator of "T" would be activated on a
681 keypress of Meta-t if menu-accelerator-enabled is menu-force.
682 However, if menu-accelerator-enabled is menu-fallback, then
683 Meta-t will not activate the menubar and will instead run the function
684 transpose-words, to which it is normally bound.
685
686 See also menu-accelerator-modifiers and menu-accelerator-prefix.
687 */ );
688 Vmenu_accelerator_enabled = Qnil;
689
690 DEFVAR_LISP ("menu-accelerator-map", &Vmenu_accelerator_map /*
691 Keymap for use when the menubar is active.
692 The actions menu-quit, menu-up, menu-down, menu-left, menu-right,
693 menu-select and menu-escape can be mapped to keys in this map.
694 NOTE: This currently only has any effect under X Windows.
695
696 menu-quit Immediately deactivate the menubar and any open submenus without
697 selecting an item.
698 menu-up Move the menu cursor up one row in the current menu. If the
699 move extends past the top of the menu, wrap around to the bottom.
700 menu-down Move the menu cursor down one row in the current menu. If the
701 move extends past the bottom of the menu, wrap around to the top.
702 If executed while the cursor is in the top level menu, move down
703 into the selected menu.
704 menu-left Move the cursor from a submenu into the parent menu. If executed
705 while the cursor is in the top level menu, move the cursor to the
706 left. If the move extends past the left edge of the menu, wrap
707 around to the right edge.
708 menu-right Move the cursor into a submenu. If the cursor is located in the
709 top level menu or is not currently on a submenu heading, then move
710 the cursor to the next top level menu entry. If the move extends
711 past the right edge of the menu, wrap around to the left edge.
712 menu-select Activate the item under the cursor. If the cursor is located on
713 a submenu heading, then move the cursor into the submenu.
714 menu-escape Pop up to the next level of menus. Moves from a submenu into its
715 parent menu. From the top level menu, this deactivates the
716 menubar.
717
718 This keymap can also contain normal key-command bindings, in which case the
719 menubar is deactivated and the corresponding command is executed.
720
721 The action bindings used by the menu accelerator code are designed to mimic
722 the actions of menu traversal keys in a commonly used PC operating system.
723 */ );
724
567 Fprovide (intern ("menubar")); 725 Fprovide (intern ("menubar"));
568 } 726 }
569 727
570 void 728 void
571 specifier_vars_of_menubar (void) 729 specifier_vars_of_menubar (void)
586 744
587 void 745 void
588 complex_vars_of_menubar (void) 746 complex_vars_of_menubar (void)
589 { 747 {
590 Vmenubar_pointer_glyph = Fmake_glyph_internal (Qpointer); 748 Vmenubar_pointer_glyph = Fmake_glyph_internal (Qpointer);
591 } 749
750 Vmenu_accelerator_map = Fmake_keymap (Qnil);
751 }