]> code.delx.au - gnu-emacs/blobdiff - src/w32menu.c
(Fcall_process_region): Doc fix.
[gnu-emacs] / src / w32menu.c
index 44791448d9480e6227b1277d3fae57809755cc95..dbf14aaeeb8a1b9203ab07342cd02143cad7ac34 100644 (file)
@@ -69,7 +69,7 @@ typedef struct _widget_value
   char*                name;
   /* value (meaning depend on widget type) */
   char*                value;
-  /* keyboard equivalent. no implications for XtTranslations */ 
+  /* keyboard equivalent. no implications for XtTranslations */
   char*                key;
   /* Help string or nil if none.
      GC finds this string through the frame's menu_bar_vector
@@ -129,8 +129,24 @@ typedef struct _widget_value
 
 static HMENU current_popup_menu;
 
-FARPROC get_menu_item_info;
-FARPROC set_menu_item_info;
+void syms_of_w32menu ();
+void globals_of_w32menu ();
+
+typedef BOOL (WINAPI * GetMenuItemInfoA_Proc) (
+    IN HMENU,
+    IN UINT,
+    IN BOOL,
+    IN OUT LPMENUITEMINFOA
+    );
+typedef BOOL (WINAPI * SetMenuItemInfoA_Proc) (
+    IN HMENU,
+    IN UINT,
+    IN BOOL,
+    IN LPCMENUITEMINFOA
+    );
+
+GetMenuItemInfoA_Proc get_menu_item_info=NULL;
+SetMenuItemInfoA_Proc set_menu_item_info=NULL;
 
 Lisp_Object Vmenu_updating_frame;
 
@@ -484,7 +500,7 @@ single_keymap_panes (keymap, pane_name, prefix, notreal, maxdepth)
 \f
 /* This is a subroutine of single_keymap_panes that handles one
    keymap entry.
-   KEY is a key in a keymap and ITEM is its binding. 
+   KEY is a key in a keymap and ITEM is its binding.
    PENDING_MAPS_PTR points to a list of keymaps waiting to be made into
    separate panes.
    If NOTREAL is nonzero, only check for equivalent key bindings, don't
@@ -500,7 +516,7 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth)
   Lisp_Object map, item_string, enabled;
   struct gcpro gcpro1, gcpro2;
   int res;
-  
+
   /* Parse the menu item and leave the result in item_properties.  */
   GCPRO2 (key, item);
   res = parse_menu_item (item, notreal, 0);
@@ -509,7 +525,7 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth)
     return;                    /* Not a menu item.  */
 
   map = AREF (item_properties, ITEM_PROPERTY_MAP);
-  
+
   if (notreal)
     {
       /* We don't want to make a menu, just traverse the keymaps to
@@ -520,7 +536,7 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth)
     }
 
   enabled = AREF (item_properties, ITEM_PROPERTY_ENABLE);
-  item_string = AREF (item_properties, ITEM_PROPERTY_NAME); 
+  item_string = AREF (item_properties, ITEM_PROPERTY_NAME);
 
   if (!NILP (map) && SREF (item_string, 0) == '@')
     {
@@ -795,7 +811,7 @@ cached information about equivalent key sequences.  */)
 
       keymaps = 0;
     }
-  
+
   if (NILP (position))
     {
       discard_menu_items ();
@@ -812,8 +828,8 @@ cached information about equivalent key sequences.  */)
       discard_menu_items ();
       UNGCPRO;
       return Qnil;
-    }    
-  
+    }
+
   /* Display them in a menu.  */
   BLOCK_INPUT;
 
@@ -958,7 +974,7 @@ on the left of the dialog box and all following items on the right.
    But first we recompute the menu bar contents (the whole tree).
 
    This way we can safely execute Lisp code.  */
-   
+
 void
 x_activate_menubar (f)
      FRAME_PTR f;
@@ -1089,7 +1105,7 @@ free_menubar_widget_value_tree (wv)
      widget_value *wv;
 {
   if (! wv) return;
-  
+
   wv->name = wv->value = wv->key = (char *) 0xDEADBEEF;
 
   if (wv->contents && (wv->contents != (widget_value*)1))
@@ -1147,9 +1163,15 @@ parse_single_submenu (item_key, item_name, maps)
                           Qnil, Qnil, Qnil, Qnil);
        }
       else
-       single_keymap_panes (mapvec[i], item_name, item_key, 0, 10);
+       {
+         Lisp_Object prompt;
+         prompt = Fkeymap_prompt (mapvec[i]);
+         single_keymap_panes (mapvec[i],
+                              !NILP (prompt) ? prompt : item_name,
+                              item_key, 0, 10);
+       }
     }
-  
+
   return top_level_items;
 }
 
@@ -1160,7 +1182,7 @@ parse_single_submenu (item_key, item_name, maps)
 
 static widget_value *
 digest_single_submenu (start, end, top_level_items)
-     int start, end;
+     int start, end, top_level_items;
 {
   widget_value *wv, *prev_wv, *save_wv, *first_wv;
   int i;
@@ -1178,11 +1200,11 @@ digest_single_submenu (start, end, top_level_items)
   first_wv = wv;
   save_wv = 0;
   prev_wv = 0;
-  /* Loop over all panes and items made during this call
-     and construct a tree of widget_value objects.
-     Ignore the panes and items made by previous calls to
-     single_submenu, even though those are also in menu_items.  */
+
+  /* Loop over all panes and items made by the preceding call
+     to parse_single_submenu and construct a tree of widget_value objects.
+     Ignore the panes and items used by previous calls to
+     digest_single_submenu, even though those are also in menu_items.  */
   i = start;
   while (i < end)
     {
@@ -1282,7 +1304,7 @@ digest_single_submenu (start, end, top_level_items)
 #endif /* not HAVE_MULTILINGUAL_MENU */
 
          wv = xmalloc_widget_value ();
-         if (prev_wv) 
+         if (prev_wv)
            prev_wv->next = wv;
          else
            save_wv->contents = wv;
@@ -1344,7 +1366,7 @@ set_frame_menubar (f, first_time, deep_p)
   widget_value *wv, *first_wv, *prev_wv = 0;
   int i, last_i;
   int *submenu_start, *submenu_end;
-  int *submenu_top_level_items;
+  int *submenu_top_level_items, *submenu_n_panes;
 
   /* We must not change the menubar when actually in use.  */
   if (f->output_data.w32->menubar_active)
@@ -1411,6 +1433,7 @@ set_frame_menubar (f, first_time, deep_p)
       menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
       submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
       submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
+      submenu_n_panes = (int *) alloca (XVECTOR (items)->size * sizeof (int));
       submenu_top_level_items
        = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
       init_menu_items ();
@@ -1431,6 +1454,7 @@ set_frame_menubar (f, first_time, deep_p)
          menu_items_n_panes = 0;
          submenu_top_level_items[i]
            = parse_single_submenu (key, string, maps);
+         submenu_n_panes[i] = menu_items_n_panes;
 
          submenu_end[i] = menu_items_used;
        }
@@ -1450,9 +1474,10 @@ set_frame_menubar (f, first_time, deep_p)
 
       for (i = 0; i < last_i; i += 4)
        {
+         menu_items_n_panes = submenu_n_panes[i];
          wv = digest_single_submenu (submenu_start[i], submenu_end[i],
                                      submenu_top_level_items[i]);
-         if (prev_wv) 
+         if (prev_wv)
            prev_wv->next = wv;
          else
            first_wv->contents = wv;
@@ -1534,7 +1559,7 @@ set_frame_menubar (f, first_time, deep_p)
             This value just has to be different from small integers.  */
          wv->call_data = (void *) (EMACS_INT) (-1);
 
-         if (prev_wv) 
+         if (prev_wv)
            prev_wv->next = wv;
          else
            first_wv->contents = wv;
@@ -1570,7 +1595,7 @@ set_frame_menubar (f, first_time, deep_p)
 
     f->output_data.w32->menubar_widget = menubar_widget;
     SetMenu (FRAME_W32_WINDOW (f), f->output_data.w32->menubar_widget);
-    /* Causes flicker when menu bar is updated 
+    /* Causes flicker when menu bar is updated
     DrawMenuBar (FRAME_W32_WINDOW (f)); */
 
     /* Force the window size to be recomputed so that the frame's text
@@ -1672,7 +1697,7 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
   wv->help = Qnil;
   first_wv = wv;
   first_pane = 1;
+
   /* Loop over all panes and items, filling in the tree.  */
   i = 0;
   while (i < menu_items_used)
@@ -1775,9 +1800,9 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
 #endif /* not HAVE_MULTILINGUAL_MENU */
 
          wv = xmalloc_widget_value ();
-         if (prev_wv) 
+         if (prev_wv)
            prev_wv->next = wv;
-         else 
+         else
            save_wv->contents = wv;
          wv->name = (char *) SDATA (item_name);
          if (!NILP (descrip))
@@ -1847,7 +1872,7 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
   menu_item_selection = 0;
 
   /* Display the menu.  */
-  menu_item_selection = SendMessage (FRAME_W32_WINDOW (f), 
+  menu_item_selection = SendMessage (FRAME_W32_WINDOW (f),
                                     WM_EMACS_TRACKPOPUPMENU,
                                     (WPARAM)menu, (LPARAM)&pos);
 
@@ -1956,7 +1981,7 @@ w32_dialog_show (f, keymaps, title, error)
     pane_name = AREF (menu_items, MENU_ITEMS_PANE_NAME);
     prefix = AREF (menu_items, MENU_ITEMS_PANE_PREFIX);
     pane_string = (NILP (pane_name)
-                  ? "" : (char *) SDATA (pane_name));  
+                  ? "" : (char *) SDATA (pane_name));
     prev_wv = xmalloc_widget_value ();
     prev_wv->value = pane_string;
     if (keymaps && !NILP (prefix))
@@ -1965,12 +1990,12 @@ w32_dialog_show (f, keymaps, title, error)
     prev_wv->name = "message";
     prev_wv->help = Qnil;
     first_wv = prev_wv;
+
     /* Loop over all panes and items, filling in the tree.  */
     i = MENU_ITEMS_PANE_LENGTH;
     while (i < menu_items_used)
       {
-       
+
        /* Create a new item within current pane.  */
        Lisp_Object item_name, enable, descrip, help;
 
@@ -1978,7 +2003,7 @@ w32_dialog_show (f, keymaps, title, error)
        enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
        descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
         help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
-       
+
        if (NILP (item_name))
          {
            free_menubar_widget_value_tree (first_wv);
@@ -2062,7 +2087,7 @@ w32_dialog_show (f, keymaps, title, error)
   /* Process events that apply to the menu.  */
   popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id);
 
-  lw_destroy_all_widgets (dialog_id); 
+  lw_destroy_all_widgets (dialog_id);
 
   /* Find the selected item, and its pane, to return
      the proper value.  */
@@ -2139,7 +2164,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
       fuFlags = MF_SEPARATOR;
       out_string = NULL;
     }
-  else 
+  else
     {
       if (wv->enabled)
        fuFlags = MF_STRING;
@@ -2355,14 +2380,9 @@ w32_free_menu_strings (hwnd)
 
 #endif /* HAVE_MENUS */
 
-\f
-syms_of_w32menu ()
+void syms_of_w32menu ()
 {
-  /* See if Get/SetMenuItemInfo functions are available.  */
-  HMODULE user32 = GetModuleHandle ("user32.dll");
-  get_menu_item_info = GetProcAddress (user32, "GetMenuItemInfoA");
-  set_menu_item_info = GetProcAddress (user32, "SetMenuItemInfoA");
-
+       globals_of_w32menu ();
   staticpro (&menu_items);
   menu_items = Qnil;
 
@@ -2381,3 +2401,19 @@ The enable predicate for a menu command should check this variable.  */);
   defsubr (&Sx_popup_dialog);
 #endif
 }
+
+/*
+       globals_of_w32menu is used to initialize those global variables that
+       must always be initialized on startup even when the global variable
+       initialized is non zero (see the function main in emacs.c).
+       globals_of_w32menu is called from syms_of_w32menu when the global
+       variable initialized is 0 and directly from main when initialized
+       is non zero.
+ */
+void globals_of_w32menu ()
+{
+       /* See if Get/SetMenuItemInfo functions are available.  */
+  HMODULE user32 = GetModuleHandle ("user32.dll");
+  get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
+  set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
+}