aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1998-03-21 05:49:49 +0000
committerRichard M. Stallman1998-03-21 05:49:49 +0000
commite8886a1d99b949b889f67d93bb2325a96be51429 (patch)
tree864bdabeea25c94ba8fb299cf160dd9e5ef05f55 /src
parent2db5082ff442ba59a7cbc572143910aa5d845f88 (diff)
downloademacs-e8886a1d99b949b889f67d93bb2325a96be51429.tar.gz
emacs-e8886a1d99b949b889f67d93bb2325a96be51429.zip
Include puresize.h for CHECK_IMPURE.
(parse_menu_item): New function. (menu_item_eval_property_1, menu_item_eval_property) New suroutines. (menu_bar_one_keymap): Moved some code to menu_bar_item. (menu_bar_item): Rewritten to use parse_menu_item. (menu_bar_item_1): Function deleted. (QCenable, QCvisible, QChelp, QCfilter, QCbutton, QCtoggle, QCradio): (Qmenu_alias): New variables. (syms_of_keyboard): Initialize them, and item_properties.
Diffstat (limited to 'src')
-rw-r--r--src/keyboard.c441
1 files changed, 370 insertions, 71 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 6e7eb42c7b9..6bb2b0c3627 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -39,6 +39,7 @@ Boston, MA 02111-1307, USA. */
39#include "syntax.h" 39#include "syntax.h"
40#include "intervals.h" 40#include "intervals.h"
41#include "blockinput.h" 41#include "blockinput.h"
42#include "puresize.h"
42#include <setjmp.h> 43#include <setjmp.h>
43#include <errno.h> 44#include <errno.h>
44 45
@@ -456,7 +457,12 @@ Lisp_Object Qmouse_wheel;
456Lisp_Object Qevent_kind; 457Lisp_Object Qevent_kind;
457Lisp_Object Qevent_symbol_elements; 458Lisp_Object Qevent_symbol_elements;
458 459
460/* menu item parts */
461Lisp_Object Qmenu_alias;
459Lisp_Object Qmenu_enable; 462Lisp_Object Qmenu_enable;
463Lisp_Object QCenable, QCvisible, QChelp, QCfilter, QCbutton, QCtoggle, QCradio;
464extern Lisp_Object Vdefine_key_rebound_commands;
465extern Lisp_Object Qmenu_item;
460 466
461/* An event header symbol HEAD may have a property named 467/* An event header symbol HEAD may have a property named
462 Qevent_symbol_element_mask, which is of the form (BASE MODIFIERS); 468 Qevent_symbol_element_mask, which is of the form (BASE MODIFIERS);
@@ -477,8 +483,6 @@ Lisp_Object Qvertical_line;
477Lisp_Object Qvertical_scroll_bar; 483Lisp_Object Qvertical_scroll_bar;
478Lisp_Object Qmenu_bar; 484Lisp_Object Qmenu_bar;
479 485
480extern Lisp_Object Qmenu_enable;
481
482Lisp_Object recursive_edit_unwind (), command_loop (); 486Lisp_Object recursive_edit_unwind (), command_loop ();
483Lisp_Object Fthis_command_keys (); 487Lisp_Object Fthis_command_keys ();
484Lisp_Object Qextended_command_history; 488Lisp_Object Qextended_command_history;
@@ -3505,7 +3509,7 @@ char *lispy_function_keys[] =
3505 3509
3506 /* 3510 /*
3507 * VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys. 3511 * VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys.
3508 * Used only as parameters to GetAsyncKeyState() and GetKeyState(). 3512 * Used only as parameters to GetAsyncKeyState and GetKeyState.
3509 * No other API or message will distinguish left and right keys this way. 3513 * No other API or message will distinguish left and right keys this way.
3510 */ 3514 */
3511 /* 0xA0 .. 0xEF */ 3515 /* 0xA0 .. 0xEF */
@@ -4114,12 +4118,12 @@ make_lispy_event (event)
4114 portion_whole = Fcons (event->x, event->y); 4118 portion_whole = Fcons (event->x, event->y);
4115 part = *scroll_bar_parts[(int) event->part]; 4119 part = *scroll_bar_parts[(int) event->part];
4116 4120
4117 position = 4121 position
4118 Fcons (window, 4122 = Fcons (window,
4119 Fcons (Qvertical_scroll_bar, 4123 Fcons (Qvertical_scroll_bar,
4120 Fcons (portion_whole, 4124 Fcons (portion_whole,
4121 Fcons (make_number (event->timestamp), 4125 Fcons (make_number (event->timestamp),
4122 Fcons (part, Qnil))))); 4126 Fcons (part, Qnil)))));
4123 } 4127 }
4124 4128
4125 /* Always treat W32 scroll bar events as clicks. */ 4129 /* Always treat W32 scroll bar events as clicks. */
@@ -5084,7 +5088,7 @@ read_avail_input (expected)
5084#endif 5088#endif
5085 /* POSIX infers that processes which are not in the session leader's 5089 /* POSIX infers that processes which are not in the session leader's
5086 process group won't get SIGHUP's at logout time. BSDI adheres to 5090 process group won't get SIGHUP's at logout time. BSDI adheres to
5087 this part standard and returns -1 from read(0) with errno==EIO 5091 this part standard and returns -1 from read (0) with errno==EIO
5088 when the control tty is taken away. 5092 when the control tty is taken away.
5089 Jeffrey Honig <jch@bsdi.com> says this is generally safe. */ 5093 Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
5090 if (nread == -1 && errno == EIO) 5094 if (nread == -1 && errno == EIO)
@@ -5398,25 +5402,14 @@ static void
5398menu_bar_one_keymap (keymap) 5402menu_bar_one_keymap (keymap)
5399 Lisp_Object keymap; 5403 Lisp_Object keymap;
5400{ 5404{
5401 Lisp_Object tail, item, key, binding, item_string, table; 5405 Lisp_Object tail, item, table;
5402 5406
5403 /* Loop over all keymap entries that have menu strings. */ 5407 /* Loop over all keymap entries that have menu strings. */
5404 for (tail = keymap; CONSP (tail); tail = XCONS (tail)->cdr) 5408 for (tail = keymap; CONSP (tail); tail = XCONS (tail)->cdr)
5405 { 5409 {
5406 item = XCONS (tail)->car; 5410 item = XCONS (tail)->car;
5407 if (CONSP (item)) 5411 if (CONSP (item))
5408 { 5412 menu_bar_item (XCONS (item)->car, XCONS (item)->cdr);
5409 key = XCONS (item)->car;
5410 binding = XCONS (item)->cdr;
5411 if (CONSP (binding))
5412 {
5413 item_string = XCONS (binding)->car;
5414 if (STRINGP (item_string))
5415 menu_bar_item (key, item_string, Fcdr (binding));
5416 }
5417 else if (EQ (binding, Qundefined))
5418 menu_bar_item (key, Qnil, binding);
5419 }
5420 else if (VECTORP (item)) 5413 else if (VECTORP (item))
5421 { 5414 {
5422 /* Loop over the char values represented in the vector. */ 5415 /* Loop over the char values represented in the vector. */
@@ -5426,45 +5419,25 @@ menu_bar_one_keymap (keymap)
5426 { 5419 {
5427 Lisp_Object character; 5420 Lisp_Object character;
5428 XSETFASTINT (character, c); 5421 XSETFASTINT (character, c);
5429 binding = XVECTOR (item)->contents[c]; 5422 menu_bar_item (character, XVECTOR (item)->contents[c]);
5430 if (CONSP (binding))
5431 {
5432 item_string = XCONS (binding)->car;
5433 if (STRINGP (item_string))
5434 menu_bar_item (key, item_string, Fcdr (binding));
5435 }
5436 else if (EQ (binding, Qundefined))
5437 menu_bar_item (key, Qnil, binding);
5438 } 5423 }
5439 } 5424 }
5440 } 5425 }
5441} 5426}
5442 5427
5443/* This is used as the handler when calling internal_condition_case_1. */
5444
5445static Lisp_Object
5446menu_bar_item_1 (arg)
5447 Lisp_Object arg;
5448{
5449 return Qnil;
5450}
5451
5452/* Add one item to menu_bar_items_vector, for KEY, ITEM_STRING and DEF. 5428/* Add one item to menu_bar_items_vector, for KEY, ITEM_STRING and DEF.
5453 If there's already an item for KEY, add this DEF to it. */ 5429 If there's already an item for KEY, add this DEF to it. */
5454 5430
5431Lisp_Object item_properties;
5432
5455static void 5433static void
5456menu_bar_item (key, item_string, def) 5434menu_bar_item (key, item)
5457 Lisp_Object key, item_string, def; 5435 Lisp_Object key, item;
5458{ 5436{
5459 Lisp_Object tem; 5437 struct gcpro gcpro1;
5460 Lisp_Object enabled;
5461 int i; 5438 int i;
5462 5439
5463 /* Skip menu-bar equiv keys data. */ 5440 if (EQ (item, Qundefined))
5464 if (CONSP (def) && CONSP (XCONS (def)->car))
5465 def = XCONS (def)->cdr;
5466
5467 if (EQ (def, Qundefined))
5468 { 5441 {
5469 /* If a map has an explicit `undefined' as definition, 5442 /* If a map has an explicit `undefined' as definition,
5470 discard any previously made menu bar item. */ 5443 discard any previously made menu bar item. */
@@ -5485,25 +5458,14 @@ menu_bar_item (key, item_string, def)
5485 return; 5458 return;
5486 } 5459 }
5487 5460
5488 /* See if this entry is enabled. */ 5461 GCPRO1 (key); /* Is this necessary? */
5489 enabled = Qt; 5462 i = parse_menu_item (item, 0, 1);
5490 5463 UNGCPRO;
5491 if (SYMBOLP (def)) 5464 if (!i)
5492 {
5493 /* No property, or nil, means enable.
5494 Otherwise, enable if value is not nil. */
5495 tem = Fget (def, Qmenu_enable);
5496 if (!NILP (tem))
5497 /* (condition-case nil (eval tem)
5498 (error nil)) */
5499 enabled = internal_condition_case_1 (Feval, tem, Qerror,
5500 menu_bar_item_1);
5501 }
5502
5503 /* Ignore this item if it's not enabled. */
5504 if (NILP (enabled))
5505 return; 5465 return;
5506 5466
5467 item = XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF];
5468
5507 /* Find any existing item for this KEY. */ 5469 /* Find any existing item for this KEY. */
5508 for (i = 0; i < menu_bar_items_index; i += 4) 5470 for (i = 0; i < menu_bar_items_index; i += 4)
5509 if (EQ (key, XVECTOR (menu_bar_items_vector)->contents[i])) 5471 if (EQ (key, XVECTOR (menu_bar_items_vector)->contents[i]))
@@ -5522,22 +5484,342 @@ menu_bar_item (key, item_string, def)
5522 XVECTOR (tem)->contents, i * sizeof (Lisp_Object)); 5484 XVECTOR (tem)->contents, i * sizeof (Lisp_Object));
5523 menu_bar_items_vector = tem; 5485 menu_bar_items_vector = tem;
5524 } 5486 }
5487
5525 /* Add this item. */ 5488 /* Add this item. */
5526 XVECTOR (menu_bar_items_vector)->contents[i++] = key; 5489 XVECTOR (menu_bar_items_vector)->contents[i++] = key;
5527 XVECTOR (menu_bar_items_vector)->contents[i++] = item_string; 5490 XVECTOR (menu_bar_items_vector)->contents[i++]
5528 XVECTOR (menu_bar_items_vector)->contents[i++] = Fcons (def, Qnil); 5491 = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
5492 XVECTOR (menu_bar_items_vector)->contents[i++] = Fcons (item, Qnil);
5529 XVECTOR (menu_bar_items_vector)->contents[i++] = make_number (0); 5493 XVECTOR (menu_bar_items_vector)->contents[i++] = make_number (0);
5530 menu_bar_items_index = i; 5494 menu_bar_items_index = i;
5531 } 5495 }
5532 /* We did find an item for this KEY. Add DEF to its list of maps. */ 5496 /* We did find an item for this KEY. Add ITEM to its list of maps. */
5533 else 5497 else
5534 { 5498 {
5535 Lisp_Object old; 5499 Lisp_Object old;
5536 old = XVECTOR (menu_bar_items_vector)->contents[i + 2]; 5500 old = XVECTOR (menu_bar_items_vector)->contents[i + 2];
5537 XVECTOR (menu_bar_items_vector)->contents[i + 2] = Fcons (def, old); 5501 XVECTOR (menu_bar_items_vector)->contents[i + 2] = Fcons (item, old);
5538 } 5502 }
5539} 5503}
5540 5504
5505 /* This is used as the handler when calling menu_item_eval_property. */
5506static Lisp_Object
5507menu_item_eval_property_1 (arg)
5508 Lisp_Object arg;
5509{
5510 /* If we got a quit from within the menu computation,
5511 quit all the way out of it. This takes care of C-] in the debugger. */
5512 if (CONSP (arg) && EQ (XCONS (arg)->car, Qquit))
5513 Fsignal (Qquit, Qnil);
5514
5515 return Qnil;
5516}
5517
5518/* Evaluate an expression and return the result (or nil if something
5519 went wrong). Used to evaluate dynamic parts of menu items. */
5520static Lisp_Object
5521menu_item_eval_property (sexpr)
5522 Lisp_Object sexpr;
5523{
5524 Lisp_Object val;
5525 val = internal_condition_case_1 (Feval, sexpr, Qerror,
5526 menu_item_eval_property_1);
5527 return val;
5528}
5529
5530/* This function parses a menu item and leaves the result in the
5531 vector item_properties.
5532 ITEM is a key binding, a possible menu item.
5533 If NOTREAL is nonzero, only check for equivalent key bindings, don't
5534 evaluate dynamic expressions in the menu item.
5535 INMENUBAR is true when this is considered for an entry in a menu bar
5536 top level.
5537 parse_menu_item returns true if the item is a menu item and false
5538 otherwise. */
5539
5540int
5541parse_menu_item (item, notreal, inmenubar)
5542 Lisp_Object item;
5543 int notreal, inmenubar;
5544{
5545 Lisp_Object def, tem;
5546
5547 Lisp_Object type = Qnil;
5548 Lisp_Object cachelist = Qnil;
5549 Lisp_Object filter = Qnil;
5550 Lisp_Object item_string, start;
5551 int i;
5552 struct gcpro gcpro1, gcpro2, gcpro3;
5553
5554#define RET0 \
5555 if (1) \
5556 { \
5557 UNGCPRO; \
5558 return 0; \
5559 } \
5560 else
5561
5562 if (!CONSP (item))
5563 return 0;
5564
5565 GCPRO3 (item, notreal, inmenubar);
5566
5567 /* Create item_properties vector if necessary. */
5568 if (NILP (item_properties))
5569 item_properties
5570 = Fmake_vector (make_number (ITEM_PROPERTY_ENABLE + 1), Qnil);
5571
5572 /* Initialize optional entries. */
5573 for (i = ITEM_PROPERTY_DEF; i < ITEM_PROPERTY_ENABLE; i++)
5574 XVECTOR (item_properties)->contents[i] = Qnil;
5575 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE] = Qt;
5576
5577 /* Save the item here to protect it from GC. */
5578 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ITEM] = item;
5579
5580 item_string = XCONS (item)->car;
5581
5582 start = item;
5583 item = XCONS (item)->cdr;
5584 if (STRINGP (item_string))
5585 {
5586 /* Old format menu item. */
5587 XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME] = item_string;
5588
5589 /* Maybe help string. */
5590 if (CONSP (item) && STRINGP (XCONS (item)->car))
5591 {
5592 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]
5593 = XCONS (item)->car;
5594 start = item;
5595 item = XCONS (item)->cdr;
5596 }
5597
5598 /* Maybee key binding cache. */
5599 if (CONSP (item) && CONSP (XCONS (item)->car)
5600 && (NILP (XCONS (XCONS (item)->car)->car)
5601 || VECTORP (XCONS (XCONS (item)->car)->car)))
5602 {
5603 cachelist = XCONS (item)->car;
5604 item = XCONS (item)->cdr;
5605 }
5606
5607 /* This is the real definition--the function to run. */
5608 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF] = item;
5609
5610 /* Get enable property, if any. */
5611 if (SYMBOLP (item))
5612 {
5613 tem = Fget (item, Qmenu_enable);
5614 if (!NILP (tem))
5615 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE] = tem;
5616 }
5617 }
5618 else if (EQ (item_string, Qmenu_item) && CONSP (item))
5619 {
5620 /* New format menu item. */
5621 XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME]
5622 = XCONS (item)->car;
5623 start = XCONS (item)->cdr;
5624 if (CONSP (start))
5625 {
5626 /* We have a real binding. */
5627 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF]
5628 = XCONS (start)->car;
5629
5630 item = XCONS (start)->cdr;
5631 /* Is there a cache list with key equivalences. */
5632 if (CONSP (item) && CONSP (XCONS (item)->car))
5633 {
5634 cachelist = XCONS (item)->car;
5635 item = XCONS (item)->cdr;
5636 }
5637
5638 /* Parse properties. */
5639 while (CONSP (item) && CONSP (XCONS (item)->cdr))
5640 {
5641 tem = XCONS (item)->car;
5642 item = XCONS (item)->cdr;
5643
5644 if (EQ (tem, QCenable))
5645 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE]
5646 = XCONS (item)->car;
5647 else if (EQ (tem, QCvisible) && !notreal)
5648 {
5649 /* If got a visible property and that evaluates to nil
5650 then ignore this item. */
5651 tem = menu_item_eval_property (XCONS (item)->car);
5652 if (NILP (tem))
5653 RET0;
5654 }
5655 else if (EQ (tem, QChelp))
5656 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]
5657 = XCONS (item)->car;
5658 else if (EQ (tem, QCfilter))
5659 filter = XCONS (item)->car;
5660 else if (EQ (tem, QCbutton) && CONSP (XCONS (item)->car))
5661 {
5662 tem = XCONS (item)->car;
5663 type = XCONS (tem)->car;
5664 if (EQ (type, QCtoggle) || EQ (type, QCradio))
5665 {
5666 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED]
5667 = XCONS (tem)->cdr;
5668 XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE]
5669 = type;
5670 }
5671 }
5672 item = XCONS (item)->cdr;
5673 }
5674 }
5675 else if (inmenubar || !NILP (start))
5676 RET0;
5677 }
5678 else
5679 RET0;
5680
5681 /* If item string is not a string, evaluate it to get string.
5682 If we don't get a string, skip this item. */
5683 item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
5684 if (!(STRINGP (item_string) || notreal))
5685 {
5686 item_string = menu_item_eval_property (item_string);
5687 if (!STRINGP (item_string))
5688 RET0;
5689 XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME] = item_string;
5690 }
5691
5692 /* If got a filter apply it on definition. */
5693 def = XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF];
5694 if (!NILP (filter))
5695 {
5696 def = menu_item_eval_property (Fcons (filter, Fcons (def, Qnil)));
5697 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF] = def;
5698 }
5699
5700 /* If we got no definition, this item is just unselectable text which
5701 is ok when in a submenu and if there is an item string. */
5702 item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
5703 if (NILP (def))
5704 {
5705 UNGCPRO;
5706 return (!inmenubar && STRINGP (item_string) ? 1 : 0);
5707 }
5708
5709 /* Enable or disable selection of item. */
5710 tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE];
5711 if (!EQ (tem, Qt))
5712 {
5713 if (notreal)
5714 tem = Qt;
5715 else
5716 tem = menu_item_eval_property (tem);
5717 if (inmenubar && NILP (tem))
5718 RET0; /* Ignore disabled items in menu bar. */
5719 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE] = tem;
5720 }
5721
5722 /* See if this is a separate pane or a submenu. */
5723 tem = get_keymap_1 (def, 0, 1);
5724 if (!NILP (tem))
5725 {
5726 XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP] = tem;
5727 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF] = tem;
5728 UNGCPRO;
5729 return 1;
5730 }
5731 else if (inmenubar)
5732 RET0; /* Entries in menu bar must be submenus. */
5733
5734 /* This is a command. See if there is an equivalent key binding. */
5735 if (NILP (cachelist))
5736 {
5737 /* We have to create a cachelist. */
5738 CHECK_IMPURE (start);
5739 XCONS (start)->cdr = Fcons (Fcons (Qnil, Qnil), XCONS (start)->cdr);
5740 cachelist = XCONS (XCONS (start)->cdr)->car;
5741 /* We have not checked this before so check it now. */
5742 tem = def;
5743 }
5744 else if (VECTORP (XCONS (cachelist)->car)) /* Saved key */
5745 {
5746 tem = Fkey_binding (XCONS (cachelist)->car, Qnil);
5747 if (EQ (tem, def)
5748 /* If the command is an alias for another
5749 (such as easymenu.el and lmenu.el set it up),
5750 check if the original command matches the cached command. */
5751 || (SYMBOLP (def) && EQ (tem, XSYMBOL (def)->function)))
5752 tem = Qnil; /* Don't need to recompute key binding. */
5753 else
5754 tem = def;
5755 }
5756 /* If something had no key binding before, don't recheck it
5757 because that is too slow--except if we have a list of rebound
5758 commands in Vdefine_key_rebound_commands, do recheck any command
5759 that appears in that list. */
5760 else if (!NILP (XCONS (cachelist)->car))
5761 tem = def; /* Should signal an error here. */
5762 else if (
5763 /* Should we check everything when precomputing key bindings? */
5764 /* notreal || */
5765 CONSP (Vdefine_key_rebound_commands)
5766 && !NILP (Fmemq (def, Vdefine_key_rebound_commands)))
5767 tem = def;
5768 else
5769 tem = Qnil;
5770
5771 if (!NILP (tem))
5772 {
5773 /* Recompute equivalent key binding.
5774 If the command is an alias for another
5775 (such as easymenu.el and lmenu.el set it up),
5776 see if the original command name has equivalent keys.
5777 Otherwise look up the specified command itself.
5778 We don't try both, because that makes easymenu menus slow. */
5779 if (SYMBOLP (def) && SYMBOLP (XSYMBOL (def)->function)
5780 && ! NILP (Fget (def, Qmenu_alias)))
5781 tem = XSYMBOL (def)->function;
5782 tem = Fwhere_is_internal (tem, Qnil, Qt, Qnil);
5783 XCONS (cachelist)->car = tem;
5784 XCONS (cachelist)->cdr
5785 = (NILP (tem) ? Qnil
5786 :
5787 concat2 (build_string (" ("),
5788 concat2 (Fkey_description (tem), build_string (")"))));
5789 }
5790
5791 /* If we only want to precompute equivalent key bindings, stop here. */
5792 if (notreal)
5793 {
5794 UNGCPRO;
5795 return 1;
5796 }
5797
5798 /* If we have an equivalent key binding, use that. */
5799 XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ]
5800 = XCONS (cachelist)->cdr;
5801
5802 /* Include this when menu help is implemented.
5803 tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP];
5804 if (!(NILP (tem) || STRINGP (tem)))
5805 {
5806 tem = menu_item_eval_property (tem);
5807 if (!STRINGP (tem))
5808 tem = Qnil;
5809 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP] = tem;
5810 }
5811 */
5812
5813 /* Handle radio buttons or toggle boxes. */
5814 tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED];
5815 if (!NILP (tem))
5816 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED]
5817 = menu_item_eval_property (tem);
5818
5819 UNGCPRO;
5820 return 1;
5821}
5822
5541/* Read a character using menus based on maps in the array MAPS. 5823/* Read a character using menus based on maps in the array MAPS.
5542 NMAPS is the length of MAPS. Return nil if there are no menus in the maps. 5824 NMAPS is the length of MAPS. Return nil if there are no menus in the maps.
5543 Return t if we displayed a menu but the user rejected it. 5825 Return t if we displayed a menu but the user rejected it.
@@ -8124,6 +8406,9 @@ struct event_head head_table[] = {
8124 8406
8125syms_of_keyboard () 8407syms_of_keyboard ()
8126{ 8408{
8409 staticpro (&item_properties);
8410 item_properties = Qnil;
8411
8127 Qtimer_event_handler = intern ("timer-event-handler"); 8412 Qtimer_event_handler = intern ("timer-event-handler");
8128 staticpro (&Qtimer_event_handler); 8413 staticpro (&Qtimer_event_handler);
8129 8414
@@ -8171,6 +8456,20 @@ syms_of_keyboard ()
8171 8456
8172 Qmenu_enable = intern ("menu-enable"); 8457 Qmenu_enable = intern ("menu-enable");
8173 staticpro (&Qmenu_enable); 8458 staticpro (&Qmenu_enable);
8459 Qmenu_alias = intern ("menu-alias");
8460 staticpro (&Qmenu_alias);
8461 QCenable = intern (":enable");
8462 staticpro (&QCenable);
8463 QCvisible = intern (":visible");
8464 staticpro (&QCvisible);
8465 QCfilter = intern (":filter");
8466 staticpro (&QCfilter);
8467 QCbutton = intern (":button");
8468 staticpro (&QCbutton);
8469 QCtoggle = intern (":toggle");
8470 staticpro (&QCtoggle);
8471 QCradio = intern (":radio");
8472 staticpro (&QCradio);
8174 8473
8175 Qmode_line = intern ("mode-line"); 8474 Qmode_line = intern ("mode-line");
8176 staticpro (&Qmode_line); 8475 staticpro (&Qmode_line);