Add the latest changes to etags behaviour.
[bpt/emacs.git] / src / w32menu.c
index 995c3ef..043e673 100644 (file)
@@ -24,9 +24,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"
 #include "charset.h"
@@ -45,7 +45,7 @@ Boston, MA 02111-1307, USA.  */
 #include "dispextern.h"
 
 #undef HAVE_MULTILINGUAL_MENU
-#undef HAVE_DIALOGS /* NTEMACS_TODO: Implement native dialogs.  */
+#undef HAVE_DIALOGS /* TODO: Implement native dialogs.  */
 
 /******************************************************************/
 /* Definitions copied from lwlib.h */
@@ -53,9 +53,6 @@ Boston, MA 02111-1307, USA.  */
 typedef void * XtPointer;
 typedef char Boolean;
 
-#define True 1
-#define False 0
-
 enum button_type
 {
   BUTTON_TYPE_NONE,
@@ -399,7 +396,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 ();
 }
@@ -641,7 +639,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 ();
@@ -720,15 +719,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));
@@ -745,7 +740,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));
@@ -761,7 +756,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))
@@ -839,13 +834,14 @@ on the left of the dialog box and all following items on the right.\n\
 
   /* 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.  */
       FRAME_PTR new_f = SELECTED_FRAME ();
       Lisp_Object bar_window;
-      int part;
+      enum scroll_bar_part part;
       unsigned long time;
       Lisp_Object x, y;
 
@@ -1114,8 +1110,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.  */
@@ -1346,7 +1341,7 @@ set_frame_menubar (f, first_time, deep_p)
       set_buffer_internal_1 (XBUFFER (buffer));
 
       /* Run the Lucid hook.  */
-      call1 (Vrun_hooks, Qactivate_menubar_hook);
+      safe_run_hooks (Qactivate_menubar_hook);
       /* If it has changed current-menubar from previous value,
         really recompute the menubar from the value.  */
       if (! NILP (Vlucid_menu_bar_dirty_flag))
@@ -1568,7 +1563,6 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
     = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object));
   int submenu_depth = 0;
   int first_pane;
-  int next_release_must_exit = 0;
 
   *error = NULL;
 
@@ -1732,7 +1726,8 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
        title = ENCODE_SYSTEM (title);
 #endif
       wv_title->name = (char *) XSTRING (title)->data;
-      wv_title->enabled = True;
+      wv_title->enabled = TRUE;
+      wv_title->title = TRUE;
       wv_title->button_type = BUTTON_TYPE_NONE;
       wv_title->next = wv_sep;
       first_wv->contents = wv_title;
@@ -1747,9 +1742,6 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
   pos.y = y;
   ClientToScreen (FRAME_W32_WINDOW (f), &pos);
 
-  /* Free the widget_value objects we used to specify the contents.  */
-  free_menubar_widget_value_tree (first_wv);
-
   /* No selection has been chosen yet.  */
   menu_item_selection = 0;
 
@@ -1762,6 +1754,9 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
      during the call. */
   discard_mouse_events ();
 
+  /* Free the widget_value objects we used to specify the contents.  */
+  free_menubar_widget_value_tree (first_wv);
+
   DestroyMenu (menu);
 
   /* Find the selected item, and its pane, to return
@@ -1951,7 +1946,7 @@ w32_dialog_show (f, keymaps, title, error)
   menu = lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv,
                           f->output_data.w32->widget, 1, 0,
                           dialog_selection_callback, 0);
-  lw_modify_all_widgets (dialog_id, first_wv->contents, True);
+  lw_modify_all_widgets (dialog_id, first_wv->contents, TRUE);
 #endif
 
   /* Free the widget_value objects we used to specify the contents.  */
@@ -2038,7 +2033,10 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
   int return_value;
 
   if (name_is_separator (wv->name))
-    fuFlags = MF_SEPARATOR;
+    {
+      fuFlags = MF_SEPARATOR;
+      out_string = NULL;
+    }
   else 
     {
       if (wv->enabled)
@@ -2064,16 +2062,14 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
 #endif
          fuFlags = MF_OWNERDRAW | MF_DISABLED;
        }
-
       /* Draw radio buttons and tickboxes. */
-      {
-      if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE ||
+      else if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE ||
                            wv->button_type == BUTTON_TYPE_RADIO))
-        fuFlags |= MF_CHECKED;
+       fuFlags |= MF_CHECKED;
       else
-        fuFlags |= MF_UNCHECKED;
-      }
+       fuFlags |= MF_UNCHECKED;
     }
+
   if (item != NULL)
     fuFlags = MF_POPUP;
 
@@ -2081,40 +2077,44 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
     AppendMenu (menu,
                 fuFlags,
                 item != NULL ? (UINT) item : (UINT) wv->call_data,
-                (fuFlags == MF_SEPARATOR) ? NULL: out_string );
+                out_string );
 
   /* This must be done after the menu item is created.  */
-  {
-    HMODULE user32 = GetModuleHandle ("user32.dll");
-    FARPROC set_menu_item_info = GetProcAddress (user32, "SetMenuItemInfoA");
+  if ((fuFlags & MF_STRING) != 0)
+    {
+      HMODULE user32 = GetModuleHandle ("user32.dll");
+      FARPROC set_menu_item_info = GetProcAddress (user32, "SetMenuItemInfoA");
 
-    if (set_menu_item_info)
-      {
-        MENUITEMINFO info;
-        bzero (&info, sizeof (info));
-        info.cbSize = sizeof (info);
-        info.fMask = MIIM_DATA;
-        /* Set help string for menu item. */
-        info.dwItemData = (DWORD)wv->help;
-
-        if (wv->button_type == BUTTON_TYPE_RADIO)
-          {
-            /* CheckMenuRadioItem allows us to differentiate TOGGLE and
-               RADIO items, but is not available on NT 3.51 and earlier.  */
-            info.fMask |= MIIM_TYPE | MIIM_STATE;
-            info.fType = MFT_RADIOCHECK;
-            info.fState = wv->selected ? MFS_CHECKED : MFS_UNCHECKED;
-          }
-        set_menu_item_info (menu,
-                            item != NULL ? (UINT) item : (UINT) wv->call_data,
-                            FALSE, &info);
-      }
-  }
+      if (set_menu_item_info)
+       {
+         MENUITEMINFO info;
+         bzero (&info, sizeof (info));
+         info.cbSize = sizeof (info);
+         info.fMask = MIIM_DATA;
+
+         /* Set help string for menu item.  */
+         info.dwItemData = (DWORD)wv->help;
+
+         if (wv->button_type == BUTTON_TYPE_RADIO)
+           {
+             /* CheckMenuRadioItem allows us to differentiate TOGGLE and
+                RADIO items, but is not available on NT 3.51 and earlier.  */
+             info.fMask |= MIIM_TYPE | MIIM_STATE;
+             info.fType = MFT_RADIOCHECK | MFT_STRING;
+             info.dwTypeData = out_string;
+             info.fState = wv->selected ? MFS_CHECKED : MFS_UNCHECKED;
+           }
+
+         set_menu_item_info (menu,
+                             item != NULL ? (UINT) item : (UINT) wv->call_data,
+                             FALSE, &info);
+       }
+    }
   return return_value;
 }
 
 /* Construct native Windows menu(bar) based on widget_value tree.  */
-static int
+int
 fill_in_menu (HMENU menu, widget_value *wv)
 {
   int items_added = 0;
@@ -2157,11 +2157,17 @@ popup_activated ()
 void
 w32_menu_display_help (HMENU menu, UINT item, UINT flags)
 {
+  int pane = 0; /* TODO: Set this to pane number.  */
+
   HMODULE user32 = GetModuleHandle ("user32.dll");
   FARPROC get_menu_item_info = GetProcAddress (user32, "GetMenuItemInfoA");
 
   if (get_menu_item_info)
     {
+      extern Lisp_Object Qmenu_item;
+      Lisp_Object *first_item;
+      Lisp_Object pane_name;
+      Lisp_Object menu_object;
       MENUITEMINFO info;
 
       bzero (&info, sizeof (info));
@@ -2169,8 +2175,23 @@ w32_menu_display_help (HMENU menu, UINT item, UINT flags)
       info.fMask = MIIM_DATA;
       get_menu_item_info (menu, item, FALSE, &info);
 
+      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 w32_menu_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 (info.dwItemData ?
-                     build_string ((char *) info.dwItemData) : Qnil, 1);
+                     build_string ((char *) info.dwItemData) : Qnil,
+                      Qnil, menu_object, make_number (item), 1);
     }
 }