-}
-\f
-/* Figure out the current keyboard equivalent of a menu item ITEM1.
- The item string for menu display should be ITEM_STRING.
- Store the equivalent keyboard key sequence's
- textual description into *DESCRIP_PTR.
- Also cache them in the item itself.
- Return the real definition to execute. */
-
-static Lisp_Object
-menu_item_equiv_key (item_string, item1, descrip_ptr)
- Lisp_Object item_string;
- Lisp_Object item1;
- Lisp_Object *descrip_ptr;
-{
- /* This is the real definition--the function to run. */
- Lisp_Object def;
- /* This is the sublist that records cached equiv key data
- so we can save time. */
- Lisp_Object cachelist;
- /* These are the saved equivalent keyboard key sequence
- and its key-description. */
- Lisp_Object savedkey, descrip;
- Lisp_Object def1;
- int changed = 0;
- struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
-
- /* If a help string follows the item string, skip it. */
- if (CONSP (XCONS (item1)->cdr)
- && STRINGP (XCONS (XCONS (item1)->cdr)->car))
- item1 = XCONS (item1)->cdr;
-
- def = Fcdr (item1);
-
- /* Get out the saved equivalent-keyboard-key info. */
- cachelist = savedkey = descrip = Qnil;
- if (CONSP (def) && CONSP (XCONS (def)->car)
- && (NILP (XCONS (XCONS (def)->car)->car)
- || VECTORP (XCONS (XCONS (def)->car)->car)))
- {
- cachelist = XCONS (def)->car;
- def = XCONS (def)->cdr;
- savedkey = XCONS (cachelist)->car;
- descrip = XCONS (cachelist)->cdr;
- }
-
- GCPRO4 (def, def1, savedkey, descrip);
-
- /* Is it still valid? */
- def1 = Qnil;
- if (!NILP (savedkey))
- def1 = Fkey_binding (savedkey, Qnil);
- /* If not, update it. */
- if (! EQ (def1, def)
- /* If the command is an alias for another
- (such as easymenu.el and lmenu.el set it up),
- check if the original command matches the cached command. */
- && !(SYMBOLP (def) && SYMBOLP (XSYMBOL (def)->function)
- && EQ (def1, XSYMBOL (def)->function))
- /* If something had no key binding before, don't recheck it
- because that is too slow--except if we have a list of rebound
- commands in Vdefine_key_rebound_commands, do recheck any command
- that appears in that list. */
- && (NILP (cachelist) || !NILP (savedkey)
- || (! EQ (Qt, Vdefine_key_rebound_commands)
- && !NILP (Fmemq (def, Vdefine_key_rebound_commands)))))
- {
- changed = 1;
- descrip = Qnil;
- /* If the command is an alias for another
- (such as easymenu.el and lmenu.el set it up),
- see if the original command name has equivalent keys. */
- if (SYMBOLP (def) && SYMBOLP (XSYMBOL (def)->function))
- savedkey = Fwhere_is_internal (XSYMBOL (def)->function,
- Qnil, Qt, Qnil);
- else
- /* Otherwise look up the specified command itself.
- We don't try both, because that makes easymenu menus slow. */
- savedkey = Fwhere_is_internal (def, Qnil, Qt, Qnil);
-
- if (!NILP (savedkey))
- {
- descrip = Fkey_description (savedkey);
- descrip = concat2 (make_string (" (", 3), descrip);
- descrip = concat2 (descrip, make_string (")", 1));
- }
- }
-
- /* Cache the data we just got in a sublist of the menu binding. */
- if (NILP (cachelist))
- {
- CHECK_IMPURE (item1);
- XCONS (item1)->cdr = Fcons (Fcons (savedkey, descrip), def);
- }
- else if (changed)
- {
- XCONS (cachelist)->car = savedkey;
- XCONS (cachelist)->cdr = descrip;
- }
-
- UNGCPRO;
- *descrip_ptr = descrip;
- return def;
-}
-
-/* This is used as the handler when calling internal_condition_case_1. */
-
-static Lisp_Object
-menu_item_enabled_p_1 (arg)
- Lisp_Object arg;
-{
- /* If we got a quit from within the menu computation,
- quit all the way out of it. This takes care of C-] in the debugger. */
- if (CONSP (arg) && EQ (XCONS (arg)->car, Qquit))
- Fsignal (Qquit, Qnil);
-
- return Qnil;
-}
-
-/* Return non-nil if the command DEF is enabled when used as a menu item.
- This is based on looking for a menu-enable property.
- If NOTREAL is set, don't bother really computing this. */
-
-static Lisp_Object
-menu_item_enabled_p (def, notreal)
- Lisp_Object def;
- int notreal;
-{
- Lisp_Object enabled, tem;
-
- enabled = Qt;
- if (notreal)
- return enabled;
- if (SYMBOLP (def))
- {
- /* No property, or nil, means enable.
- Otherwise, enable if value is not nil. */
- tem = Fget (def, Qmenu_enable);
- if (!NILP (tem))
- /* (condition-case nil (eval tem)
- (error nil)) */
- enabled = internal_condition_case_1 (Feval, tem, Qerror,
- menu_item_enabled_p_1);
- }
- return enabled;