]> code.delx.au - gnu-emacs/blobdiff - src/xmenu.c
* xfns.c (xpm_load) [!ALLOC_XPM_COLORS]: Declare local variable I in inner block.
[gnu-emacs] / src / xmenu.c
index c84a6d7b332bb52333239c2dc82f768f179f13ec..f3e27be2225888aaa63b4769a49b6ac596758b74 100644 (file)
@@ -1,5 +1,5 @@
 /* X Communication module for terminals which understand the X protocol.
-   Copyright (C) 1986, 88, 93, 94, 96, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1986, 88, 93, 94, 96, 99, 2000 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -38,9 +38,9 @@ Boston, MA 02111-1307, USA.  */
 #include <stdio.h>
 #include "lisp.h"
 #include "termhooks.h"
+#include "keyboard.h"
 #include "frame.h"
 #include "window.h"
-#include "keyboard.h"
 #include "blockinput.h"
 #include "buffer.h"
 
@@ -380,7 +380,8 @@ keymap_panes (keymaps, nmaps, notreal)
      But don't make a pane that is empty--ignore that map instead.
      P is the number of panes we have made so far.  */
   for (mapno = 0; mapno < nmaps; mapno++)
-    single_keymap_panes (keymaps[mapno], Qnil, Qnil, notreal, 10);
+    single_keymap_panes (keymaps[mapno],
+                        map_prompt (keymaps[mapno]), Qnil, notreal, 10);
 
   finish_menu_items ();
 }
@@ -690,11 +691,11 @@ cached information about equivalent key sequences.")
      Lisp_Object position, menu;
 {
   Lisp_Object keymap, tem;
-  int xpos, ypos;
+  int xpos = 0, ypos = 0;
   Lisp_Object title;
   char *error_name;
   Lisp_Object selection;
-  FRAME_PTR f;
+  struct frame *f = NULL;
   Lisp_Object x, y, window;
   int keymaps = 0;
   int for_click = 0;
@@ -707,7 +708,8 @@ cached information about equivalent key sequences.")
 
       /* Decode the first argument: find the window and the coordinates.  */
       if (EQ (position, Qt)
-         || (CONSP (position) && EQ (XCAR (position), Qmenu_bar)))
+         || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
+                                  || EQ (XCAR (position), Qtool_bar))))
        {
          /* Use the mouse's current position.  */
          FRAME_PTR new_f = SELECTED_FRAME ();
@@ -786,15 +788,11 @@ cached information about equivalent key sequences.")
 
   /* Decode the menu items from what was specified.  */
 
-  keymap = Fkeymapp (menu);
-  tem = Qnil;
-  if (CONSP (menu))
-    tem = Fkeymapp (Fcar (menu));
-  if (!NILP (keymap))
+  keymap = get_keymap (menu, 0, 0);
+  if (CONSP (keymap))
     {
       /* We were given a keymap.  Extract menu info from the keymap.  */
       Lisp_Object prompt;
-      keymap = get_keymap (menu);
 
       /* Extract the detailed info to make one pane.  */
       keymap_panes (&menu, 1, NILP (position));
@@ -811,7 +809,7 @@ cached information about equivalent key sequences.")
 
       keymaps = 1;
     }
-  else if (!NILP (tem))
+  else if (CONSP (menu) && KEYMAPP (XCAR (menu)))
     {
       /* We were given a list of keymaps.  */
       int nmaps = XFASTINT (Flength (menu));
@@ -827,7 +825,7 @@ cached information about equivalent key sequences.")
        {
          Lisp_Object prompt;
 
-         maps[i++] = keymap = get_keymap (Fcar (tem));
+         maps[i++] = keymap = get_keymap (Fcar (tem), 1, 0);
 
          prompt = map_prompt (keymap);
          if (NILP (title) && !NILP (prompt))
@@ -898,14 +896,15 @@ on the left of the dialog box and all following items on the right.\n\
   (position, contents)
      Lisp_Object position, contents;
 {
-  FRAME_PTR f;
+  struct frame * f = NULL;
   Lisp_Object window;
 
   check_x ();
 
   /* Decode the first argument: find the window or frame to use.  */
   if (EQ (position, Qt)
-      || (CONSP (position) && EQ (XCAR (position), Qmenu_bar)))
+      || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
+                              || EQ (XCAR (position), Qtool_bar))))
     {
 #if 0 /* Using the frame the mouse is on may not be right.  */
       /* Use the mouse's current position.  */
@@ -1078,14 +1077,10 @@ popup_get_selection (initial_event, dpyinfo, id)
          && (event.xany.display != dpyinfo->display
              || x_non_menubar_window_to_frame (dpyinfo, event.xany.window)))
        {
-         queue_tmp = (struct event_queue *) malloc (sizeof (struct event_queue));
-
-         if (queue_tmp != NULL) 
-           {
-             queue_tmp->event = event;
-             queue_tmp->next = queue;
-             queue = queue_tmp;
-           }
+         queue_tmp = (struct event_queue *) xmalloc (sizeof *queue_tmp);
+         queue_tmp->event = event;
+         queue_tmp->next = queue;
+         queue = queue_tmp;
        }
       else
        XtDispatchEvent (&event);
@@ -1101,7 +1096,7 @@ popup_get_selection (initial_event, dpyinfo, id)
       queue_tmp = queue;
       XPutBackEvent (queue_tmp->event.xany.display, &queue_tmp->event);
       queue = queue_tmp->next;
-      free ((char *)queue_tmp);
+      xfree ((char *)queue_tmp);
       /* Cause these events to get read as soon as we UNBLOCK_INPUT.  */
       interrupt_input_pending = 1;
     }
@@ -1196,12 +1191,16 @@ menu_highlight_callback (widget, id, call_data)
   widget_value *wv = (widget_value *) call_data;
   struct frame *f;
   Lisp_Object frame, help;
-  struct input_event buf;
 
+  help = wv && wv->help ? build_string (wv->help) : Qnil;
+  
   /* Determine the frame for the help event.  */
   f = menubar_id_to_frame (id);
   if (f)
-    XSETFRAME (frame, f);
+    {
+      XSETFRAME (frame, f);
+      kbd_buffer_store_help_event (frame, help);
+    }
   else
     {
       /* WIDGET is the popup menu.  It's parent is the frame's 
@@ -1217,14 +1216,9 @@ menu_highlight_callback (widget, id, call_data)
                  FRAME_X_P (f) && f->output_data.x->widget == frame_widget))
            break;
        }
-    }
 
-  /* Store the help event.  */
-  help = wv && wv->help ? build_string (wv->help) : Qnil;
-  buf.kind = HELP_EVENT;
-  buf.frame_or_window = frame;
-  buf.arg = help;
-  kbd_buffer_store_event (&buf);
+      show_help_echo (help, Qnil, Qnil, Qnil, 1);
+    }
 }
 
 /* This callback is called from the menu bar pulldown menu
@@ -1247,6 +1241,7 @@ menubar_selection_callback (widget, id, client_data)
 
   if (!f)
     return;
+  entry = Qnil;
   subprefix_stack = (Lisp_Object *) alloca (f->menu_bar_items_used * sizeof (Lisp_Object));
   vector = f->menu_bar_vector;
   prefix = Qnil;
@@ -1393,8 +1388,7 @@ single_submenu (item_key, item_name, maps)
   for (i = 0; i < len; i++)
     {
       if (SYMBOLP (mapvec[i])
-         || (CONSP (mapvec[i])
-             && NILP (Fkeymapp (mapvec[i]))))
+         || (CONSP (mapvec[i]) && !KEYMAPP (mapvec[i])))
        {
          /* Here we have a command at top level in the menu bar
             as opposed to a submenu.  */
@@ -1603,7 +1597,7 @@ update_frame_menubar (f)
     {
       XtManageChild (x->menubar_widget);
       XtMapWidget (x->menubar_widget);
-      XtVaSetValues (x->menubar_widget, XtNmappedWhenManaged, 1, 0);
+      XtVaSetValues (x->menubar_widget, XtNmappedWhenManaged, 1, NULL);
     }
 
   /* Re-manage the text-area widget, and then thrash the sizes.  */
@@ -2057,7 +2051,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
       else
        {
          /* Create a new item within current pane.  */
-         Lisp_Object item_name, enable, descrip, def, type, selected;
+         Lisp_Object item_name, enable, descrip, def, type, selected, help;
          item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME];
          enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];
          descrip
@@ -2065,6 +2059,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
          def = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_DEFINITION];
          type = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_TYPE];
          selected = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_SELECTED];
+         help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP];
 
 #ifndef HAVE_MULTILINGUAL_MENU
           if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
@@ -2099,6 +2094,8 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
            abort ();
 
          wv->selected = !NILP (selected);
+         if (STRINGP (help))
+           wv->help = XSTRING (help)->data;
          
          prev_wv = wv;
 
@@ -2194,12 +2191,14 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
   /* Free the widget_value objects we used to specify the contents.  */
   free_menubar_widget_value_tree (first_wv);
 
+  /* Override any default settings with ones from the `menu' face.  */
+  x_set_menu_resources_from_menu_face (f, menu);
+
   /* No selection has been chosen yet.  */
   menu_item_selection = 0;
 
   /* Display the menu.  */
   lw_popup_menu (menu, (XEvent *) &dummy);
-  x_set_menu_resources_from_menu_face (f, menu);
   popup_activated_flag = 1;
 
   /* Process events that apply to the menu.  */
@@ -2228,7 +2227,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
     {
       Lisp_Object prefix, entry;
 
-      prefix = Qnil;
+      prefix = entry = Qnil;
       i = 0;
       while (i < menu_items_used)
        {
@@ -2456,6 +2455,12 @@ xdialog_show (f, keymaps, title, error)
                = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
              i += MENU_ITEMS_PANE_LENGTH;
            }
+         else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
+           {
+             /* This is the boundary between left-side elts and
+                right-side elts.  */
+             ++i;
+           }
          else
            {
              entry
@@ -2477,6 +2482,7 @@ xdialog_show (f, keymaps, title, error)
 
   return Qnil;
 }
+
 #else /* not USE_X_TOOLKIT */
 
 /* The frame of the last activated non-toolkit menu bar.
@@ -2485,17 +2491,42 @@ xdialog_show (f, keymaps, title, error)
 static struct frame *menu_help_frame;
 
 
-/* Show help HELP_STRING, or clear help if HELP_STRING is null.  This
-   cannot be done with generating a HELP_EVENT because XMenuActivate
-   contains a loop that doesn't let Emacs process keyboard events.  */
+/* Show help HELP_STRING, or clear help if HELP_STRING is null.
+
+   PANE is the pane number, and ITEM is the menu item number in
+   the menu (currently not used).
+   
+   This cannot be done with generating a HELP_EVENT because
+   XMenuActivate contains a loop that doesn't let Emacs process
+   keyboard events.  */
 
 static void
-menu_help_callback (help_string)
+menu_help_callback (help_string, pane, item)
      char *help_string;
+     int pane, item;
 {
-  show_help_echo (help_string ? build_string (help_string) : Qnil, 1);
+  extern Lisp_Object Qmenu_item;
+  Lisp_Object *first_item;
+  Lisp_Object pane_name;
+  Lisp_Object menu_object;
+  first_item = XVECTOR (menu_items)->contents;
+  if (EQ (first_item[0], Qt))
+    pane_name = first_item[MENU_ITEMS_PANE_NAME];
+  else if (EQ (first_item[0], Qquote))
+    /* This shouldn't happen, see xmenu_show.  */
+    pane_name = build_string ("");
+  else
+    pane_name = first_item[MENU_ITEMS_ITEM_NAME];
+  /* (menu-item MENU-NAME PANE-NUMBER)  */
+  menu_object = Fcons (Qmenu_item,
+                      Fcons (pane_name,
+                             Fcons (make_number (pane), Qnil)));
+  show_help_echo (help_string ? build_string (help_string) : Qnil,
+                 Qnil, menu_object, make_number (item), 1);
 }
-
+  
 
 static Lisp_Object
 xmenu_show (f, x, y, for_click, keymaps, title, error)