-#if defined(HAVE_X_WINDOWS) && defined(LWLIB_MENUBARS_LUCID)
-static void
-menu_move_up (void)
-{
- widget_value *current = lw_get_entries (False);
- widget_value *entries = lw_get_entries (True);
- widget_value *prev = NULL;
-
- while (entries != current)
- {
- if (entries->name /*&& entries->enabled*/) prev = entries;
- entries = entries->next;
- assert (entries);
- }
-
- if (!prev)
- /* move to last item */
- {
- while (entries->next)
- {
- if (entries->name /*&& entries->enabled*/) prev = entries;
- entries = entries->next;
- }
- if (prev)
- {
- if (entries->name /*&& entries->enabled*/)
- prev = entries;
- }
- else
- {
- /* no selectable items in this menu, pop up to previous level */
- lw_pop_menu ();
- return;
- }
- }
- lw_set_item (prev);
-}
-
-static void
-menu_move_down (void)
-{
- widget_value *current = lw_get_entries (False);
- widget_value *new = current;
-
- while (new->next)
- {
- new = new->next;
- if (new->name /*&& new->enabled*/) break;
- }
-
- if (new==current||!(new->name/*||new->enabled*/))
- {
- new = lw_get_entries (True);
- while (new!=current)
- {
- if (new->name /*&& new->enabled*/) break;
- new = new->next;
- }
- if (new==current&&!(new->name /*|| new->enabled*/))
- {
- lw_pop_menu ();
- return;
- }
- }
-
- lw_set_item (new);
-}
-
-static void
-menu_move_left (void)
-{
- int level = lw_menu_level ();
- int l = level;
- widget_value *current;
-
- while (level-- >= 3)
- lw_pop_menu ();
-
- menu_move_up ();
- current = lw_get_entries (False);
- if (l > 2 && current->contents)
- lw_push_menu (current->contents);
-}
-
-static void
-menu_move_right (void)
-{
- int level = lw_menu_level ();
- int l = level;
- widget_value *current;
-
- while (level-- >= 3)
- lw_pop_menu ();
-
- menu_move_down ();
- current = lw_get_entries (False);
- if (l > 2 && current->contents)
- lw_push_menu (current->contents);
-}
-
-static void
-menu_select_item (widget_value *val)
-{
- if (val == NULL)
- val = lw_get_entries (False);
-
- /* is match a submenu? */
-
- if (val->contents)
- {
- /* enter the submenu */
-
- lw_set_item (val);
- lw_push_menu (val->contents);
- }
- else
- {
- /* Execute the menu entry by calling the menu's `select'
- callback function
- */
- lw_kill_menus (val);
- }
-}
-
-static Lisp_Object
-command_builder_operate_menu_accelerator (struct command_builder *builder)
-{
- /* this function can GC */
-
- struct console *con = XCONSOLE (Vselected_console);
- Lisp_Object evee = builder->most_current_event;
- Lisp_Object binding;
- widget_value *entries;
-
- extern int lw_menu_accelerate; /* lwlib.c */
-
-#if 0
- {
- int i;
- Lisp_Object t;
- char buf[50];
-
- t = builder->current_events;
- i = 0;
- while (!NILP (t))
- {
- i++;
- sprintf (buf,"OPERATE (%d): ",i);
- write_c_string (buf, Qexternal_debugging_output);
- print_internal (t, Qexternal_debugging_output, 1);
- write_c_string ("\n", Qexternal_debugging_output);
- t = XEVENT_NEXT (t);
- }
- }
-#endif /* 0 */
-
- /* menu accelerator keys don't go into keyboard macros */
- if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro))
- con->kbd_macro_ptr = con->kbd_macro_end;
-
- /* don't echo menu accelerator keys */
- /*reset_key_echo (builder, 1);*/
-
- if (!lw_menu_accelerate)
- {
- /* `convert' mouse display to keyboard display
- by entering the open submenu
- */
- entries = lw_get_entries (False);
- if (entries->contents)
- {
- lw_push_menu (entries->contents);
- lw_display_menu (CurrentTime);
- }
- }
-
- /* compare event to the current menu accelerators */
-
- entries=lw_get_entries (True);
-
- while (entries)
- {
- Lisp_Object accel;
- VOID_TO_LISP (accel, entries->accel);
- if (entries->name && !NILP (accel))
- {
- if (event_matches_key_specifier_p (XEVENT (evee), accel))
- {
- /* a match! */
-
- menu_select_item (entries);
-
- if (lw_menu_active) lw_display_menu (CurrentTime);
-
- reset_this_command_keys (Vselected_console, 1);
- /*reset_command_builder_event_chain (builder);*/
- return Vmenu_accelerator_map;
- }
- }
- entries = entries->next;
- }
-
- /* try to look up event in menu-accelerator-map */
-
- binding = event_binding_in (evee, Vmenu_accelerator_map, 1);
-
- if (NILP (binding))
- {
- /* beep at user for undefined key */
- return Qnil;
- }
- else
- {
- if (EQ (binding, Qmenu_quit))
- {
- /* turn off menus and set quit flag */
- lw_kill_menus (NULL);
- Vquit_flag = Qt;
- }
- else if (EQ (binding, Qmenu_up))
- {
- int level = lw_menu_level ();
- if (level > 2)
- menu_move_up ();
- }
- else if (EQ (binding, Qmenu_down))
- {
- int level = lw_menu_level ();
- if (level > 2)
- menu_move_down ();
- else
- menu_select_item (NULL);
- }
- else if (EQ (binding, Qmenu_left))
- {
- int level = lw_menu_level ();
- if (level > 3)
- {
- lw_pop_menu ();
- lw_display_menu (CurrentTime);
- }
- else
- menu_move_left ();
- }
- else if (EQ (binding, Qmenu_right))
- {
- int level = lw_menu_level ();
- if (level > 2 &&
- lw_get_entries (False)->contents)
- {
- widget_value *current = lw_get_entries (False);
- if (current->contents)
- menu_select_item (NULL);
- }
- else
- menu_move_right ();
- }
- else if (EQ (binding, Qmenu_select))
- menu_select_item (NULL);
- else if (EQ (binding, Qmenu_escape))
- {
- int level = lw_menu_level ();
-
- if (level > 2)
- {
- lw_pop_menu ();
- lw_display_menu (CurrentTime);
- }
- else
- {
- /* turn off menus quietly */
- lw_kill_menus (NULL);
- }
- }
- else if (KEYMAPP (binding))
- {
- /* prefix key */
- reset_this_command_keys (Vselected_console, 1);
- /*reset_command_builder_event_chain (builder);*/
- return binding;
- }
- else
- {
- /* turn off menus and execute binding */
- lw_kill_menus (NULL);
- reset_this_command_keys (Vselected_console, 1);
- /*reset_command_builder_event_chain (builder);*/
- return binding;
- }
- }
-
- if (lw_menu_active) lw_display_menu (CurrentTime);
-
- reset_this_command_keys (Vselected_console, 1);
- /*reset_command_builder_event_chain (builder);*/
-
- return Vmenu_accelerator_map;
-}
-
-static Lisp_Object
-menu_accelerator_junk_on_error (Lisp_Object errordata, Lisp_Object ignored)
-{
- Vmenu_accelerator_prefix = Qnil;
- Vmenu_accelerator_modifiers = Qnil;
- Vmenu_accelerator_enabled = Qnil;
- if (!NILP (errordata))
- {
- Lisp_Object args[2];
-
- args[0] = build_string ("Error in menu accelerators (setting to nil)");
- /* #### This should call
- (with-output-to-string (display-error errordata))
- but that stuff is all in Lisp currently. */
- args[1] = errordata;
- warn_when_safe_lispobj
- (Qerror, Qwarning,
- emacs_doprnt_string_lisp ((CONST Bufbyte *) "%s: %s",
- Qnil, -1, 2, args));
- }
-
- return Qnil;
-}
-
-static Lisp_Object
-menu_accelerator_safe_compare (Lisp_Object event0)
-{
- if (CONSP (Vmenu_accelerator_prefix))
- {
- Lisp_Object t;
- t=Vmenu_accelerator_prefix;
- while (!NILP (t)
- && !NILP (event0)
- && event_matches_key_specifier_p (XEVENT (event0), Fcar (t)))
- {
- t = Fcdr (t);
- event0 = XEVENT_NEXT (event0);
- }
- if (!NILP (t))
- return Qnil;
- }
- else if (NILP (event0))
- return Qnil;
- else if (event_matches_key_specifier_p (XEVENT (event0), Vmenu_accelerator_prefix))
- event0 = XEVENT_NEXT (event0);
- else
- return Qnil;
- return event0;
-}
-
-static Lisp_Object
-menu_accelerator_safe_mod_compare (Lisp_Object cons)
-{
- return (event_matches_key_specifier_p (XEVENT (XCAR (cons)), XCDR (cons))
- ? Qt
- : Qnil);
-}
-
-static Lisp_Object
-command_builder_find_menu_accelerator (struct command_builder *builder)
-{
- /* this function can GC */
- Lisp_Object event0 = builder->current_events;
- struct console *con = XCONSOLE (Vselected_console);
- struct frame *f = XFRAME (CONSOLE_SELECTED_FRAME (con));
- Widget menubar_widget;
-
- /* compare entries in event0 against the menu prefix */
-
- if ((!CONSOLE_X_P (XCONSOLE (builder->console))) || NILP (event0) ||
- XEVENT (event0)->event_type != key_press_event)
- return Qnil;
-
- if (!NILP (Vmenu_accelerator_prefix))
- {
- event0 = condition_case_1 (Qerror,
- menu_accelerator_safe_compare,
- event0,
- menu_accelerator_junk_on_error,
- Qnil);
- }
-
- if (NILP (event0))
- return Qnil;
-
- menubar_widget = FRAME_X_MENUBAR_WIDGET (f);
- if (menubar_widget
- && CONSP (Vmenu_accelerator_modifiers))
- {
- Lisp_Object fake;
- Lisp_Object last = Qnil;
- struct gcpro gcpro1;
- Lisp_Object matchp;
-
- widget_value *val;
- LWLIB_ID id = XPOPUP_DATA (f->menubar_data)->id;
-
- val = lw_get_all_values (id);
- if (val)
- {
- val = val->contents;
-
- fake = Fcopy_sequence (Vmenu_accelerator_modifiers);
- last = fake;
-
- while (!NILP (Fcdr (last)))
- last = Fcdr (last);
-
- Fsetcdr (last, Fcons (Qnil, Qnil));
- last = Fcdr (last);
- }
-
- fake = Fcons (Qnil, fake);
-
- GCPRO1 (fake);
-
- while (val)
- {
- Lisp_Object accel;
- VOID_TO_LISP (accel, val->accel);
- if (val->name && !NILP (accel))
- {
- Fsetcar (last, accel);
- Fsetcar (fake, event0);
- matchp = condition_case_1 (Qerror,
- menu_accelerator_safe_mod_compare,
- fake,
- menu_accelerator_junk_on_error,
- Qnil);
- if (!NILP (matchp))
- {
- /* we found one! */
-
- lw_set_menu (menubar_widget, val);
- /* yah - yet another hack.
- pretend emacs timestamp is the same as an X timestamp,
- which for the moment it is. (read events.h)
- */
- lw_map_menu (XEVENT (event0)->timestamp);
-
- if (val->contents)
- lw_push_menu (val->contents);
-
- lw_display_menu (CurrentTime);
-
- /* menu accelerator keys don't go into keyboard macros */
- if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro))
- con->kbd_macro_ptr = con->kbd_macro_end;
-
- /* don't echo menu accelerator keys */
- /*reset_key_echo (builder, 1);*/
- reset_this_command_keys (Vselected_console, 1);
- UNGCPRO;
-
- return Vmenu_accelerator_map;
- }
- }
-
- val = val->next;
- }
-
- UNGCPRO;
- }
- return Qnil;
-}
-
-
-DEFUN ("accelerate-menu", Faccelerate_menu, 0, 0, "_", /*
-Make the menubar active. Menu items can be selected using menu accelerators
-or by actions defined in menu-accelerator-map.
-*/
- ())
-{
- struct console *con = XCONSOLE (Vselected_console);
- struct frame *f = XFRAME (CONSOLE_SELECTED_FRAME (con));
- LWLIB_ID id;
- widget_value *val;
-
- if (NILP (f->menubar_data))
- error ("Frame has no menubar.");
-
- id = XPOPUP_DATA (f->menubar_data)->id;
- val = lw_get_all_values (id);
- val = val->contents;
- lw_set_menu (FRAME_X_MENUBAR_WIDGET (f), val);
- lw_map_menu (CurrentTime);
-
- lw_display_menu (CurrentTime);
-
- /* menu accelerator keys don't go into keyboard macros */
- if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro))
- con->kbd_macro_ptr = con->kbd_macro_end;
-
- return Qnil;
-}
-#endif /* HAVE_X_WINDOWS && HAVE_MENUBARS */
-