Mercurial > hg > xemacs-beta
comparison src/menubar.c @ 404:2f8bb876ab1d r21-2-32
Import from CVS: tag r21-2-32
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:16:07 +0200 |
parents | 74fd4e045ea6 |
children | 697ef44129c6 |
comparison
equal
deleted
inserted
replaced
403:9f011ab08d48 | 404:2f8bb876ab1d |
---|---|
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; |
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; |
345 | 376 |
346 void | 377 void |
347 syms_of_menubar (void) | 378 syms_of_menubar (void) |
348 { | 379 { |
349 defsymbol (&Qcurrent_menubar, "current-menubar"); | 380 defsymbol (&Qcurrent_menubar, "current-menubar"); |
381 | |
382 defsymbol (&Qmenu_force, "menu-force"); | |
383 defsymbol (&Qmenu_fallback, "menu-fallback"); | |
384 | |
385 defsymbol (&Qmenu_quit, "menu-quit"); | |
386 defsymbol (&Qmenu_up, "menu-up"); | |
387 defsymbol (&Qmenu_down, "menu-down"); | |
388 defsymbol (&Qmenu_left, "menu-left"); | |
389 defsymbol (&Qmenu_right, "menu-right"); | |
390 defsymbol (&Qmenu_select, "menu-select"); | |
391 defsymbol (&Qmenu_escape, "menu-escape"); | |
392 | |
350 DEFSUBR (Fpopup_menu); | 393 DEFSUBR (Fpopup_menu); |
351 DEFSUBR (Fnormalize_menu_item_name); | 394 DEFSUBR (Fnormalize_menu_item_name); |
352 DEFSUBR (Fmenu_find_real_submenu); | 395 DEFSUBR (Fmenu_find_real_submenu); |
353 } | 396 } |
354 | 397 |
395 The first element of a menu must be a string, which is the name of the menu. | 438 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 | 439 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 | 440 toplevel menus, it is ignored. This string is not displayed in the menu |
398 itself. | 441 itself. |
399 | 442 |
400 Immediately following the name string of the menu, any of three | 443 Menu accelerators can be indicated in the string by putting the |
401 optional keyword-value pairs is permitted. | 444 sequence "%_" before the character corresponding to the key that will |
445 invoke the menu or menu item. Uppercase and lowercase accelerators | |
446 are equivalent. The sequence "%%" is also special, and is translated | |
447 into a single %. | |
448 | |
449 If no menu accelerator is present in the string, XEmacs will act as if | |
450 the first character has been tagged as an accelerator. | |
451 | |
452 Immediately following the name string of the menu, various optional | |
453 keyword-value pairs are permitted: currently, :filter, :active, :included, | |
454 and :config. (See below.) | |
402 | 455 |
403 If an element of a menu (or menubar) is a string, then that string will be | 456 If an element of a menu (or menubar) is a string, then that string will be |
404 presented as unselectable text. | 457 presented as unselectable text. |
405 | 458 |
406 If an element of a menu is a string consisting solely of hyphens, then that | 459 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. | 460 item will be presented as a solid horizontal line. |
461 | |
462 If an element of a menu is a string beginning with "--:", it will be | |
463 presented as a line whose appearance is controlled by the rest of the | |
464 text in the string. The allowed line specs are system-dependent, and | |
465 currently work only under X Windows (with Lucid and Motif menubars); | |
466 otherwise, a solid horizontal line is presented, as if the string were | |
467 all hyphens. | |
468 | |
469 The possibilities are: | |
470 | |
471 "--:singleLine" | |
472 "--:doubleLine" | |
473 "--:singleDashedLine" | |
474 "--:doubleDashedLine" | |
475 "--:noLine" | |
476 "--:shadowEtchedIn" | |
477 "--:shadowEtchedOut" | |
478 "--:shadowEtchedInDash" | |
479 "--:shadowEtchedOutDash" | |
480 "--:shadowDoubleEtchedIn" (Lucid menubars only) | |
481 "--:shadowDoubleEtchedOut" (Lucid menubars only) | |
482 "--:shadowDoubleEtchedInDash" (Lucid menubars only) | |
483 "--:shadowDoubleEtchedOutDash" (Lucid menubars only) | |
408 | 484 |
409 If an element of a menu is a list, it is treated as a submenu. The name of | 485 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 | 486 that submenu (the first element in the list) will be used as the name of the |
411 item representing this menu on the parent. | 487 item representing this menu on the parent. |
412 | 488 |
413 If an element of a menubar is `nil', then it is used to represent the | 489 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 | 490 division between the set of menubar-items which are flushleft and those |
415 which are flushright. | 491 which are flushright. |
416 | 492 |
417 Otherwise, the element must be a vector, which describes a menu item. | 493 Otherwise, the element must be a vector, which describes a menu item. |
418 A menu item can have any of the following forms: | 494 A menu item is of the following form: |
495 | |
496 [ "name" callback :<keyword> <value> :<keyword> <value> ... ] | |
497 | |
498 The following forms are also accepted for compatibility, but deprecated: | |
419 | 499 |
420 [ "name" callback <active-p> ] | 500 [ "name" callback <active-p> ] |
421 [ "name" callback <active-p> <suffix> ] | 501 [ "name" callback <active-p> <suffix> ] |
422 [ "name" callback :<keyword> <value> :<keyword> <value> ... ] | |
423 | 502 |
424 The name is the string to display on the menu; it is filtered through the | 503 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 | 504 resource database, so it is possible for resources to override what string |
426 is actually displayed. | 505 is actually displayed. Menu accelerator indicators (the sequence `%_') are |
506 also processed; see above. If the name is not a string, it will be | |
507 evaluated with `eval', and the result should be a string. | |
427 | 508 |
428 If the `callback' of a menu item is a symbol, then it must name a command. | 509 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 | 510 It will be invoked with `call-interactively'. If it is a list, then it is |
430 evaluated with `eval'. | 511 evaluated with `eval'. |
431 | 512 |
432 The possible keywords are this: | 513 In the deprecated forms, <active-p> is equivalent to using the :active |
433 | 514 keyword, and <suffix> is equivalent to using the :suffix keyword. |
434 :active <form> Same as <active-p> in the first two forms: the | 515 |
435 expression is evaluated just before the menu is | 516 The possible keywords are: |
517 | |
518 :active <form> The expression is evaluated just before the menu is | |
436 displayed, and the menu will be selectable only if | 519 displayed, and the menu will be selectable only if |
437 the result is non-nil. | 520 the result is non-nil. |
438 | 521 |
439 :suffix <form> Same as <suffix> in the second form: the expression | 522 :suffix <form> The expression is evaluated just before the menu is |
440 is evaluated just before the menu is displayed and | 523 displayed and the resulting string is appended to |
441 resulting string is appended to the displayed name, | 524 the displayed name, providing a convenient way of |
442 providing a convenient way of adding the name of a | 525 adding the name of a command's ``argument'' to the |
443 command's ``argument'' to the menu, like | 526 menu, like ``Kill Buffer NAME''. |
444 ``Kill Buffer NAME''. | |
445 | 527 |
446 :keys "string" Normally, the keyboard equivalents of commands in | 528 :keys "string" Normally, the keyboard equivalents of commands in |
447 menus are displayed when the `callback' is a symbol. | 529 menus are displayed when the `callback' is a symbol. |
448 This can be used to specify keys for more complex menu | 530 This can be used to specify keys for more complex menu |
449 items. It is passed through `substitute-command-keys' | 531 items. It is passed through `substitute-command-keys' |
476 :config <symbol> This is an efficient shorthand for | 558 :config <symbol> This is an efficient shorthand for |
477 :included (memq symbol menubar-configuration) | 559 :included (memq symbol menubar-configuration) |
478 See the variable `menubar-configuration'. | 560 See the variable `menubar-configuration'. |
479 | 561 |
480 :filter <function> A menu filter can only be used in a menu item list. | 562 :filter <function> A menu filter can only be used in a menu item list. |
481 (i.e.: not in a menu item itself). It is used to | 563 (i.e. not in a menu item itself). It is used to |
482 sensitize or incrementally create a submenu only when | 564 incrementally create a submenu only when it is selected |
483 it is selected by the user and not every time the | 565 by the user and not every time the menubar is activated. |
484 menubar is activated. The filter function is passed | 566 The filter function is passed the list of menu items in |
485 the list of menu items in the submenu and must return a | 567 the submenu and must return a list of menu items to be |
486 list of menu items to be used for the menu. It is | 568 used for the menu. It must not destructively modify |
487 called only when the menu is about to be displayed, so | 569 the list of menu items passed to it. It is called only |
488 other menus may already be displayed. Vile and | 570 when the menu is about to be displayed, so other menus |
489 terrible things will happen if a menu filter function | 571 may already be displayed. Vile and terrible things will |
490 changes the current buffer, window, or frame. It | 572 happen if a menu filter function changes the current |
491 also should not raise, lower, or iconify any frames. | 573 buffer, window, or frame. It also should not raise, |
492 Basically, the filter function should have no | 574 lower, or iconify any frames. Basically, the filter |
493 side-effects. | 575 function should have no side-effects. |
494 | 576 |
495 :key-sequence keys Used in FSF Emacs as an hint to an equivalent keybinding. | 577 :key-sequence keys Used in FSF Emacs as an hint to an equivalent keybinding. |
496 Ignored by XEnacs for easymenu.el compatibility. | 578 Ignored by XEmacs for easymenu.el compatibility. |
497 | |
498 :label <form> (unimplemented!) Like :suffix, but replaces label | |
499 completely. | |
500 (might be added in 21.2). | |
501 | 579 |
502 For example: | 580 For example: |
503 | 581 |
504 ("File" | 582 ("%_File" |
505 :filter file-menu-filter ; file-menu-filter is a function that takes | 583 :filter file-menu-filter ; file-menu-filter is a function that takes |
506 ; one argument (a list of menu items) and | 584 ; one argument (a list of menu items) and |
507 ; returns a list of menu items | 585 ; returns a list of menu items |
508 [ "Save As..." write-file t ] | 586 [ "Save %_As..." write-file t ] |
509 [ "Revert Buffer" revert-buffer (buffer-modified-p) ] | 587 [ "%_Revert Buffer" revert-buffer (buffer-modified-p) ] |
510 [ "Read Only" toggle-read-only :style toggle | 588 [ "R%_ead Only" toggle-read-only :style toggle |
511 :selected buffer-read-only ] | 589 :selected buffer-read-only ] |
512 ) | 590 ) |
513 | 591 |
514 See x-menubar.el for many more examples. | 592 See menubar-items.el for many more examples. |
515 | 593 |
516 After the menubar is clicked upon, but before any menus are popped up, | 594 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 | 595 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 | 596 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 | 597 filters (using the :filter keyword) is usually a more efficient way to |
520 dynamically alter or sensitize menus. | 598 dynamically alter or sensitize menus. */, menubar_variable_changed); |
521 */, menubar_variable_changed); | |
522 | 599 |
523 Vcurrent_menubar = Qnil; | 600 Vcurrent_menubar = Qnil; |
524 | 601 |
525 DEFVAR_LISP ("activate-menubar-hook", &Vactivate_menubar_hook /* | 602 DEFVAR_LISP ("activate-menubar-hook", &Vactivate_menubar_hook /* |
526 Function or functions called before a menubar menu is pulled down. | 603 Function or functions called before a menubar menu is pulled down. |
562 This is a glyph; use `set-glyph-image' to change it. | 639 This is a glyph; use `set-glyph-image' to change it. |
563 If unspecified in a particular domain, the window-system-provided | 640 If unspecified in a particular domain, the window-system-provided |
564 default pointer is used. | 641 default pointer is used. |
565 */ ); | 642 */ ); |
566 | 643 |
644 DEFVAR_LISP ("menu-accelerator-prefix", &Vmenu_accelerator_prefix /* | |
645 Prefix key(s) that must be typed before menu accelerators will be activated. | |
646 Set this to a value acceptable by define-key. | |
647 | |
648 NOTE: This currently only has any effect under X Windows. | |
649 */ ); | |
650 Vmenu_accelerator_prefix = Qnil; | |
651 | |
652 DEFVAR_LISP ("menu-accelerator-modifiers", &Vmenu_accelerator_modifiers /* | |
653 Modifier keys which must be pressed to get to the top level menu accelerators. | |
654 This is a list of modifier key symbols. All modifier keys must be held down | |
655 while a valid menu accelerator key is pressed in order for the top level | |
656 menu to become active. | |
657 | |
658 NOTE: This currently only has any effect under X Windows. | |
659 | |
660 See also menu-accelerator-enabled and menu-accelerator-prefix. | |
661 */ ); | |
662 Vmenu_accelerator_modifiers = list1 (Qmeta); | |
663 | |
664 DEFVAR_LISP ("menu-accelerator-enabled", &Vmenu_accelerator_enabled /* | |
665 Whether menu accelerator keys can cause the menubar to become active. | |
666 If 'menu-force or 'menu-fallback, then menu accelerator keys can | |
667 be used to activate the top level menu. Once the menubar becomes active, the | |
668 accelerator keys can be used regardless of the value of this variable. | |
669 | |
670 menu-force is used to indicate that the menu accelerator key takes | |
671 precedence over bindings in the current keymap(s). menu-fallback means | |
672 that bindings in the current keymap take precedence over menu accelerator keys. | |
673 Thus a top level menu with an accelerator of "T" would be activated on a | |
674 keypress of Meta-t if menu-accelerator-enabled is menu-force. | |
675 However, if menu-accelerator-enabled is menu-fallback, then | |
676 Meta-t will not activate the menubar and will instead run the function | |
677 transpose-words, to which it is normally bound. | |
678 | |
679 See also menu-accelerator-modifiers and menu-accelerator-prefix. | |
680 */ ); | |
681 Vmenu_accelerator_enabled = Qnil; | |
682 | |
683 DEFVAR_LISP ("menu-accelerator-map", &Vmenu_accelerator_map /* | |
684 Keymap for use when the menubar is active. | |
685 The actions menu-quit, menu-up, menu-down, menu-left, menu-right, | |
686 menu-select and menu-escape can be mapped to keys in this map. | |
687 NOTE: This currently only has any effect under X Windows. | |
688 | |
689 menu-quit Immediately deactivate the menubar and any open submenus without | |
690 selecting an item. | |
691 menu-up Move the menu cursor up one row in the current menu. If the | |
692 move extends past the top of the menu, wrap around to the bottom. | |
693 menu-down Move the menu cursor down one row in the current menu. If the | |
694 move extends past the bottom of the menu, wrap around to the top. | |
695 If executed while the cursor is in the top level menu, move down | |
696 into the selected menu. | |
697 menu-left Move the cursor from a submenu into the parent menu. If executed | |
698 while the cursor is in the top level menu, move the cursor to the | |
699 left. If the move extends past the left edge of the menu, wrap | |
700 around to the right edge. | |
701 menu-right Move the cursor into a submenu. If the cursor is located in the | |
702 top level menu or is not currently on a submenu heading, then move | |
703 the cursor to the next top level menu entry. If the move extends | |
704 past the right edge of the menu, wrap around to the left edge. | |
705 menu-select Activate the item under the cursor. If the cursor is located on | |
706 a submenu heading, then move the cursor into the submenu. | |
707 menu-escape Pop up to the next level of menus. Moves from a submenu into its | |
708 parent menu. From the top level menu, this deactivates the | |
709 menubar. | |
710 | |
711 This keymap can also contain normal key-command bindings, in which case the | |
712 menubar is deactivated and the corresponding command is executed. | |
713 | |
714 The action bindings used by the menu accelerator code are designed to mimic | |
715 the actions of menu traversal keys in a commonly used PC operating system. | |
716 */ ); | |
717 | |
567 Fprovide (intern ("menubar")); | 718 Fprovide (intern ("menubar")); |
568 } | 719 } |
569 | 720 |
570 void | 721 void |
571 specifier_vars_of_menubar (void) | 722 specifier_vars_of_menubar (void) |
586 | 737 |
587 void | 738 void |
588 complex_vars_of_menubar (void) | 739 complex_vars_of_menubar (void) |
589 { | 740 { |
590 Vmenubar_pointer_glyph = Fmake_glyph_internal (Qpointer); | 741 Vmenubar_pointer_glyph = Fmake_glyph_internal (Qpointer); |
591 } | 742 |
743 Vmenu_accelerator_map = Fmake_keymap (Qnil); | |
744 } |