/[emacs]/emacs/src/w32menu.c
ViewVC logotype

Diff of /emacs/src/w32menu.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.55 by jasonr, Sat Feb 23 00:01:34 2002 UTC revision 1.55.4.1 by miles, Fri Apr 4 06:21:04 2003 UTC
# Line 69  typedef struct _widget_value Line 69  typedef struct _widget_value
69    char*         name;    char*         name;
70    /* value (meaning depend on widget type) */    /* value (meaning depend on widget type) */
71    char*         value;    char*         value;
72    /* keyboard equivalent. no implications for XtTranslations */    /* keyboard equivalent. no implications for XtTranslations */
73    char*         key;    char*         key;
74    /* Help string or nil if none.    /* Help string or nil if none.
75       GC finds this string through the frame's menu_bar_vector       GC finds this string through the frame's menu_bar_vector
# Line 112  typedef struct _widget_value Line 112  typedef struct _widget_value
112  #endif  #endif
113  } widget_value;  } widget_value;
114    
115  /* LocalAlloc/Free is a reasonably good allocator.  */  /* Local memory management */
116  #define malloc_widget_value() (void*)LocalAlloc (LMEM_ZEROINIT, sizeof (widget_value))  #define local_heap (GetProcessHeap ())
117  #define free_widget_value(wv) LocalFree (wv)  #define local_alloc(n) (HeapAlloc (local_heap, HEAP_ZERO_MEMORY, (n)))
118    #define local_free(p) (HeapFree (local_heap, 0, ((LPVOID) (p))))
119    
120    #define malloc_widget_value() ((widget_value *) local_alloc (sizeof (widget_value)))
121    #define free_widget_value(wv) (local_free ((wv)))
122    
123  /******************************************************************/  /******************************************************************/
124    
# Line 125  typedef struct _widget_value Line 129  typedef struct _widget_value
129    
130  static HMENU current_popup_menu;  static HMENU current_popup_menu;
131    
132  FARPROC get_menu_item_info;  void syms_of_w32menu ();
133  FARPROC set_menu_item_info;  void globals_of_w32menu ();
134    
135    typedef BOOL (WINAPI * GetMenuItemInfoA_Proc) (
136        IN HMENU,
137        IN UINT,
138        IN BOOL,
139        IN OUT LPMENUITEMINFOA
140        );
141    typedef BOOL (WINAPI * SetMenuItemInfoA_Proc) (
142        IN HMENU,
143        IN UINT,
144        IN BOOL,
145        IN LPCMENUITEMINFOA
146        );
147    
148    GetMenuItemInfoA_Proc get_menu_item_info=NULL;
149    SetMenuItemInfoA_Proc set_menu_item_info=NULL;
150    
151  Lisp_Object Vmenu_updating_frame;  Lisp_Object Vmenu_updating_frame;
152    
# Line 318  push_submenu_start () Line 338  push_submenu_start ()
338    if (menu_items_used + 1 > menu_items_allocated)    if (menu_items_used + 1 > menu_items_allocated)
339      grow_menu_items ();      grow_menu_items ();
340    
341    XVECTOR (menu_items)->contents[menu_items_used++] = Qnil;    ASET (menu_items, menu_items_used++, Qnil);
342    menu_items_submenu_depth++;    menu_items_submenu_depth++;
343  }  }
344    
# Line 330  push_submenu_end () Line 350  push_submenu_end ()
350    if (menu_items_used + 1 > menu_items_allocated)    if (menu_items_used + 1 > menu_items_allocated)
351      grow_menu_items ();      grow_menu_items ();
352    
353    XVECTOR (menu_items)->contents[menu_items_used++] = Qlambda;    ASET (menu_items, menu_items_used++, Qlambda);
354    menu_items_submenu_depth--;    menu_items_submenu_depth--;
355  }  }
356    
# Line 342  push_left_right_boundary () Line 362  push_left_right_boundary ()
362    if (menu_items_used + 1 > menu_items_allocated)    if (menu_items_used + 1 > menu_items_allocated)
363      grow_menu_items ();      grow_menu_items ();
364    
365    XVECTOR (menu_items)->contents[menu_items_used++] = Qquote;    ASET (menu_items, menu_items_used++, Qquote);
366  }  }
367    
368  /* Start a new menu pane in menu_items.  /* Start a new menu pane in menu_items.
# Line 357  push_menu_pane (name, prefix_vec) Line 377  push_menu_pane (name, prefix_vec)
377    
378    if (menu_items_submenu_depth == 0)    if (menu_items_submenu_depth == 0)
379      menu_items_n_panes++;      menu_items_n_panes++;
380    XVECTOR (menu_items)->contents[menu_items_used++] = Qt;    ASET (menu_items, menu_items_used++, Qt);
381    XVECTOR (menu_items)->contents[menu_items_used++] = name;    ASET (menu_items, menu_items_used++, name);
382    XVECTOR (menu_items)->contents[menu_items_used++] = prefix_vec;    ASET (menu_items, menu_items_used++, prefix_vec);
383  }  }
384    
385  /* Push one menu item into the current pane.  NAME is the string to  /* Push one menu item into the current pane.  NAME is the string to
# Line 377  push_menu_item (name, enable, key, def, Line 397  push_menu_item (name, enable, key, def,
397    if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated)    if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated)
398      grow_menu_items ();      grow_menu_items ();
399    
400    XVECTOR (menu_items)->contents[menu_items_used++] = name;    ASET (menu_items, menu_items_used++, name);
401    XVECTOR (menu_items)->contents[menu_items_used++] = enable;    ASET (menu_items, menu_items_used++, enable);
402    XVECTOR (menu_items)->contents[menu_items_used++] = key;    ASET (menu_items, menu_items_used++, key);
403    XVECTOR (menu_items)->contents[menu_items_used++] = equiv;    ASET (menu_items, menu_items_used++, equiv);
404    XVECTOR (menu_items)->contents[menu_items_used++] = def;    ASET (menu_items, menu_items_used++, def);
405    XVECTOR (menu_items)->contents[menu_items_used++] = type;    ASET (menu_items, menu_items_used++, type);
406    XVECTOR (menu_items)->contents[menu_items_used++] = selected;    ASET (menu_items, menu_items_used++, selected);
407    XVECTOR (menu_items)->contents[menu_items_used++] = help;    ASET (menu_items, menu_items_used++, help);
408  }  }
409    
410  /* Look through KEYMAPS, a vector of keymaps that is NMAPS long,  /* Look through KEYMAPS, a vector of keymaps that is NMAPS long,
# Line 450  single_keymap_panes (keymap, pane_name, Line 470  single_keymap_panes (keymap, pane_name,
470        else if (VECTORP (item))        else if (VECTORP (item))
471          {          {
472            /* Loop over the char values represented in the vector.  */            /* Loop over the char values represented in the vector.  */
473            int len = XVECTOR (item)->size;            int len = ASIZE (item);
474            int c;            int c;
475            for (c = 0; c < len; c++)            for (c = 0; c < len; c++)
476              {              {
477                Lisp_Object character;                Lisp_Object character;
478                XSETFASTINT (character, c);                XSETFASTINT (character, c);
479                single_menu_item (character, XVECTOR (item)->contents[c],                single_menu_item (character, AREF (item, c),
480                                  &pending_maps, notreal, maxdepth);                                  &pending_maps, notreal, maxdepth);
481              }              }
482          }          }
# Line 480  single_keymap_panes (keymap, pane_name, Line 500  single_keymap_panes (keymap, pane_name,
500    
501  /* This is a subroutine of single_keymap_panes that handles one  /* This is a subroutine of single_keymap_panes that handles one
502     keymap entry.     keymap entry.
503     KEY is a key in a keymap and ITEM is its binding.     KEY is a key in a keymap and ITEM is its binding.
504     PENDING_MAPS_PTR points to a list of keymaps waiting to be made into     PENDING_MAPS_PTR points to a list of keymaps waiting to be made into
505     separate panes.     separate panes.
506     If NOTREAL is nonzero, only check for equivalent key bindings, don't     If NOTREAL is nonzero, only check for equivalent key bindings, don't
# Line 496  single_menu_item (key, item, pending_map Line 516  single_menu_item (key, item, pending_map
516    Lisp_Object map, item_string, enabled;    Lisp_Object map, item_string, enabled;
517    struct gcpro gcpro1, gcpro2;    struct gcpro gcpro1, gcpro2;
518    int res;    int res;
519      
520    /* Parse the menu item and leave the result in item_properties.  */    /* Parse the menu item and leave the result in item_properties.  */
521    GCPRO2 (key, item);    GCPRO2 (key, item);
522    res = parse_menu_item (item, notreal, 0);    res = parse_menu_item (item, notreal, 0);
# Line 504  single_menu_item (key, item, pending_map Line 524  single_menu_item (key, item, pending_map
524    if (!res)    if (!res)
525      return;                     /* Not a menu item.  */      return;                     /* Not a menu item.  */
526    
527    map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP];    map = AREF (item_properties, ITEM_PROPERTY_MAP);
528      
529    if (notreal)    if (notreal)
530      {      {
531        /* We don't want to make a menu, just traverse the keymaps to        /* We don't want to make a menu, just traverse the keymaps to
# Line 515  single_menu_item (key, item, pending_map Line 535  single_menu_item (key, item, pending_map
535        return;        return;
536      }      }
537    
538    enabled = XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE];    enabled = AREF (item_properties, ITEM_PROPERTY_ENABLE);
539    item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];    item_string = AREF (item_properties, ITEM_PROPERTY_NAME);
540    
541    if (!NILP (map) && XSTRING (item_string)->data[0] == '@')    if (!NILP (map) && SREF (item_string, 0) == '@')
542      {      {
543        if (!NILP (enabled))        if (!NILP (enabled))
544          /* An enabled separate pane. Remember this to handle it later.  */          /* An enabled separate pane. Remember this to handle it later.  */
# Line 528  single_menu_item (key, item, pending_map Line 548  single_menu_item (key, item, pending_map
548      }      }
549    
550    push_menu_item (item_string, enabled, key,    push_menu_item (item_string, enabled, key,
551                    XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF],                    AREF (item_properties, ITEM_PROPERTY_DEF),
552                    XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ],                    AREF (item_properties, ITEM_PROPERTY_KEYEQ),
553                    XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE],                    AREF (item_properties, ITEM_PROPERTY_TYPE),
554                    XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED],                    AREF (item_properties, ITEM_PROPERTY_SELECTED),
555                    XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]);                    AREF (item_properties, ITEM_PROPERTY_HELP));
556    
557    /* Display a submenu using the toolkit.  */    /* Display a submenu using the toolkit.  */
558    if (! (NILP (map) || NILP (enabled)))    if (! (NILP (map) || NILP (enabled)))
# Line 745  cached information about equivalent key Line 765  cached information about equivalent key
765    
766        /* Make that be the pane title of the first pane.  */        /* Make that be the pane title of the first pane.  */
767        if (!NILP (prompt) && menu_items_n_panes >= 0)        if (!NILP (prompt) && menu_items_n_panes >= 0)
768          XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = prompt;          ASET (menu_items, MENU_ITEMS_PANE_NAME, prompt);
769    
770        keymaps = 1;        keymaps = 1;
771      }      }
# Line 777  cached information about equivalent key Line 797  cached information about equivalent key
797    
798        /* Make the title be the pane title of the first pane.  */        /* Make the title be the pane title of the first pane.  */
799        if (!NILP (title) && menu_items_n_panes >= 0)        if (!NILP (title) && menu_items_n_panes >= 0)
800          XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = title;          ASET (menu_items, MENU_ITEMS_PANE_NAME, title);
801    
802        keymaps = 1;        keymaps = 1;
803      }      }
# Line 791  cached information about equivalent key Line 811  cached information about equivalent key
811    
812        keymaps = 0;        keymaps = 0;
813      }      }
814      
815    if (NILP (position))    if (NILP (position))
816      {      {
817        discard_menu_items ();        discard_menu_items ();
# Line 800  cached information about equivalent key Line 820  cached information about equivalent key
820      }      }
821    
822  #ifdef HAVE_MENUS  #ifdef HAVE_MENUS
823      /* If resources from a previous popup menu exist yet, does nothing
824         until the `menu_free_timer' has freed them (see w32fns.c).
825      */
826      if (current_popup_menu)
827        {
828          discard_menu_items ();
829          UNGCPRO;
830          return Qnil;
831        }
832    
833    /* Display them in a menu.  */    /* Display them in a menu.  */
834    BLOCK_INPUT;    BLOCK_INPUT;
835    
# Line 808  cached information about equivalent key Line 838  cached information about equivalent key
838    UNBLOCK_INPUT;    UNBLOCK_INPUT;
839    
840    discard_menu_items ();    discard_menu_items ();
841    #endif /* HAVE_MENUS */
842    
843    UNGCPRO;    UNGCPRO;
 #endif /* HAVE_MENUS */  
844    
845    if (error_name) error (error_name);    if (error_name) error (error_name);
846    return selection;    return selection;
# Line 935  on the left of the dialog box and all fo Line 965  on the left of the dialog box and all fo
965    
966  /* Activate the menu bar of frame F.  /* Activate the menu bar of frame F.
967     This is called from keyboard.c when it gets the     This is called from keyboard.c when it gets the
968     menu_bar_activate_event out of the Emacs event queue.     MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue.
969    
970     To activate the menu bar, we signal to the input thread that it can     To activate the menu bar, we signal to the input thread that it can
971     return from the WM_INITMENU message, allowing the normal Windows     return from the WM_INITMENU message, allowing the normal Windows
# Line 944  on the left of the dialog box and all fo Line 974  on the left of the dialog box and all fo
974     But first we recompute the menu bar contents (the whole tree).     But first we recompute the menu bar contents (the whole tree).
975    
976     This way we can safely execute Lisp code.  */     This way we can safely execute Lisp code.  */
977      
978  void  void
979  x_activate_menubar (f)  x_activate_menubar (f)
980       FRAME_PTR f;       FRAME_PTR f;
# Line 981  menubar_selection_callback (FRAME_PTR f, Line 1011  menubar_selection_callback (FRAME_PTR f,
1011    i = 0;    i = 0;
1012    while (i < f->menu_bar_items_used)    while (i < f->menu_bar_items_used)
1013      {      {
1014        if (EQ (XVECTOR (vector)->contents[i], Qnil))        if (EQ (AREF (vector, i), Qnil))
1015          {          {
1016            subprefix_stack[submenu_depth++] = prefix;            subprefix_stack[submenu_depth++] = prefix;
1017            prefix = entry;            prefix = entry;
1018            i++;            i++;
1019          }          }
1020        else if (EQ (XVECTOR (vector)->contents[i], Qlambda))        else if (EQ (AREF (vector, i), Qlambda))
1021          {          {
1022            prefix = subprefix_stack[--submenu_depth];            prefix = subprefix_stack[--submenu_depth];
1023            i++;            i++;
1024          }          }
1025        else if (EQ (XVECTOR (vector)->contents[i], Qt))        else if (EQ (AREF (vector, i), Qt))
1026          {          {
1027            prefix = XVECTOR (vector)->contents[i + MENU_ITEMS_PANE_PREFIX];            prefix = AREF (vector, i + MENU_ITEMS_PANE_PREFIX);
1028            i += MENU_ITEMS_PANE_LENGTH;            i += MENU_ITEMS_PANE_LENGTH;
1029          }          }
1030        else        else
1031          {          {
1032            entry = XVECTOR (vector)->contents[i + MENU_ITEMS_ITEM_VALUE];            entry = AREF (vector, i + MENU_ITEMS_ITEM_VALUE);
1033            /* The EMACS_INT cast avoids a warning.  There's no problem            /* The EMACS_INT cast avoids a warning.  There's no problem
1034               as long as pointers have enough bits to hold small integers.  */               as long as pointers have enough bits to hold small integers.  */
1035            if ((int) (EMACS_INT) client_data == i)            if ((int) (EMACS_INT) client_data == i)
# Line 1093  free_menubar_widget_value_tree (wv) Line 1123  free_menubar_widget_value_tree (wv)
1123    UNBLOCK_INPUT;    UNBLOCK_INPUT;
1124  }  }
1125    
1126  /* Return a tree of widget_value structures for a menu bar item  /* Set up data i menu_items for a menu bar item
1127     whose event type is ITEM_KEY (with string ITEM_NAME)     whose event type is ITEM_KEY (with string ITEM_NAME)
1128     and whose contents come from the list of keymaps MAPS.  */     and whose contents come from the list of keymaps MAPS.  */
1129    
1130  static widget_value *  static int
1131  single_submenu (item_key, item_name, maps)  parse_single_submenu (item_key, item_name, maps)
1132       Lisp_Object item_key, item_name, maps;       Lisp_Object item_key, item_name, maps;
1133  {  {
   widget_value *wv, *prev_wv, *save_wv, *first_wv;  
   int i;  
   int submenu_depth = 0;  
1134    Lisp_Object length;    Lisp_Object length;
1135    int len;    int len;
1136    Lisp_Object *mapvec;    Lisp_Object *mapvec;
1137    widget_value **submenu_stack;    int i;
   int previous_items = menu_items_used;  
1138    int top_level_items = 0;    int top_level_items = 0;
1139    
1140    length = Flength (maps);    length = Flength (maps);
# Line 1122  single_submenu (item_key, item_name, map Line 1148  single_submenu (item_key, item_name, map
1148        maps = Fcdr (maps);        maps = Fcdr (maps);
1149      }      }
1150    
   menu_items_n_panes = 0;  
   
1151    /* Loop over the given keymaps, making a pane for each map.    /* Loop over the given keymaps, making a pane for each map.
1152       But don't make a pane that is empty--ignore that map instead.  */       But don't make a pane that is empty--ignore that map instead.  */
1153    for (i = 0; i < len; i++)    for (i = 0; i < len; i++)
# Line 1139  single_submenu (item_key, item_name, map Line 1163  single_submenu (item_key, item_name, map
1163                            Qnil, Qnil, Qnil, Qnil);                            Qnil, Qnil, Qnil, Qnil);
1164          }          }
1165        else        else
1166          single_keymap_panes (mapvec[i], item_name, item_key, 0, 10);          {
1167              Lisp_Object prompt;
1168              prompt = Fkeymap_prompt (mapvec[i]);
1169              single_keymap_panes (mapvec[i],
1170                                   !NILP (prompt) ? prompt : item_name,
1171                                   item_key, 0, 10);
1172            }
1173      }      }
1174    
1175    /* Create a tree of widget_value objects    return top_level_items;
1176       representing the panes and their items.  */  }
1177    
1178    
1179    /* Create a tree of widget_value objects
1180       representing the panes and items
1181       in menu_items starting at index START, up to index END.  */
1182    
1183    static widget_value *
1184    digest_single_submenu (start, end, top_level_items)
1185         int start, end, top_level_items;
1186    {
1187      widget_value *wv, *prev_wv, *save_wv, *first_wv;
1188      int i;
1189      int submenu_depth = 0;
1190      widget_value **submenu_stack;
1191    
1192    submenu_stack    submenu_stack
1193      = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));      = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
# Line 1156  single_submenu (item_key, item_name, map Line 1200  single_submenu (item_key, item_name, map
1200    first_wv = wv;    first_wv = wv;
1201    save_wv = 0;    save_wv = 0;
1202    prev_wv = 0;    prev_wv = 0;
1203    
1204    /* Loop over all panes and items made during this call    /* Loop over all panes and items made by the preceding call
1205       and construct a tree of widget_value objects.       to parse_single_submenu and construct a tree of widget_value objects.
1206       Ignore the panes and items made by previous calls to       Ignore the panes and items used by previous calls to
1207       single_submenu, even though those are also in menu_items.  */       digest_single_submenu, even though those are also in menu_items.  */
1208    i = previous_items;    i = start;
1209    while (i < menu_items_used)    while (i < end)
1210      {      {
1211        if (EQ (XVECTOR (menu_items)->contents[i], Qnil))        if (EQ (AREF (menu_items, i), Qnil))
1212          {          {
1213            submenu_stack[submenu_depth++] = save_wv;            submenu_stack[submenu_depth++] = save_wv;
1214            save_wv = prev_wv;            save_wv = prev_wv;
1215            prev_wv = 0;            prev_wv = 0;
1216            i++;            i++;
1217          }          }
1218        else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))        else if (EQ (AREF (menu_items, i), Qlambda))
1219          {          {
1220            prev_wv = save_wv;            prev_wv = save_wv;
1221            save_wv = submenu_stack[--submenu_depth];            save_wv = submenu_stack[--submenu_depth];
1222            i++;            i++;
1223          }          }
1224        else if (EQ (XVECTOR (menu_items)->contents[i], Qt)        else if (EQ (AREF (menu_items, i), Qt)
1225                 && submenu_depth != 0)                 && submenu_depth != 0)
1226          i += MENU_ITEMS_PANE_LENGTH;          i += MENU_ITEMS_PANE_LENGTH;
1227        /* Ignore a nil in the item list.        /* Ignore a nil in the item list.
1228           It's meaningful only for dialog boxes.  */           It's meaningful only for dialog boxes.  */
1229        else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))        else if (EQ (AREF (menu_items, i), Qquote))
1230          i += 1;          i += 1;
1231        else if (EQ (XVECTOR (menu_items)->contents[i], Qt))        else if (EQ (AREF (menu_items, i), Qt))
1232          {          {
1233            /* Create a new pane.  */            /* Create a new pane.  */
1234            Lisp_Object pane_name, prefix;            Lisp_Object pane_name, prefix;
1235            char *pane_string;            char *pane_string;
1236    
1237            pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME];            pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
1238            prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];            prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
1239    
1240  #ifndef HAVE_MULTILINGUAL_MENU  #ifndef HAVE_MULTILINGUAL_MENU
1241            if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))            if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
1242              {              {
1243                pane_name = ENCODE_SYSTEM (pane_name);                pane_name = ENCODE_SYSTEM (pane_name);
1244                AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name;                ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
1245              }              }
1246  #endif  #endif
1247            pane_string = (NILP (pane_name)            pane_string = (NILP (pane_name)
1248                           ? "" : (char *) XSTRING (pane_name)->data);                           ? "" : (char *) SDATA (pane_name));
1249            /* If there is just one top-level pane, put all its items directly            /* If there is just one top-level pane, put all its items directly
1250               under the top-level menu.  */               under the top-level menu.  */
1251            if (menu_items_n_panes == 1)            if (menu_items_n_panes == 1)
# Line 1249  single_submenu (item_key, item_name, map Line 1293  single_submenu (item_key, item_name, map
1293            if (STRING_MULTIBYTE (item_name))            if (STRING_MULTIBYTE (item_name))
1294              {              {
1295                item_name = ENCODE_SYSTEM (item_name);                item_name = ENCODE_SYSTEM (item_name);
1296                AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name;                ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
1297              }              }
1298    
1299            if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))            if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
1300              {              {
1301                descrip = ENCODE_SYSTEM (descrip);                descrip = ENCODE_SYSTEM (descrip);
1302                AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip;                ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
1303              }              }
1304  #endif /* not HAVE_MULTILINGUAL_MENU */  #endif /* not HAVE_MULTILINGUAL_MENU */
1305    
1306            wv = xmalloc_widget_value ();            wv = xmalloc_widget_value ();
1307            if (prev_wv)            if (prev_wv)
1308              prev_wv->next = wv;              prev_wv->next = wv;
1309            else            else
1310              save_wv->contents = wv;              save_wv->contents = wv;
1311    
1312            wv->name = (char *) XSTRING (item_name)->data;            wv->name = (char *) SDATA (item_name);
1313            if (!NILP (descrip))            if (!NILP (descrip))
1314              wv->key = (char *) XSTRING (descrip)->data;              wv->key = (char *) SDATA (descrip);
1315            wv->value = 0;            wv->value = 0;
1316            /* The EMACS_INT cast avoids a warning.  There's no problem            /* The EMACS_INT cast avoids a warning.  There's no problem
1317               as long as pointers have enough bits to hold small integers.  */               as long as pointers have enough bits to hold small integers.  */
# Line 1320  set_frame_menubar (f, first_time, deep_p Line 1364  set_frame_menubar (f, first_time, deep_p
1364    HMENU menubar_widget = f->output_data.w32->menubar_widget;    HMENU menubar_widget = f->output_data.w32->menubar_widget;
1365    Lisp_Object items;    Lisp_Object items;
1366    widget_value *wv, *first_wv, *prev_wv = 0;    widget_value *wv, *first_wv, *prev_wv = 0;
1367    int i;    int i, last_i;
1368      int *submenu_start, *submenu_end;
1369      int *submenu_top_level_items, *submenu_n_panes;
1370    
1371    /* We must not change the menubar when actually in use.  */    /* We must not change the menubar when actually in use.  */
1372    if (f->output_data.w32->menubar_active)    if (f->output_data.w32->menubar_active)
# Line 1333  set_frame_menubar (f, first_time, deep_p Line 1379  set_frame_menubar (f, first_time, deep_p
1379    else if (pending_menu_activation && !deep_p)    else if (pending_menu_activation && !deep_p)
1380      deep_p = 1;      deep_p = 1;
1381    
   wv = xmalloc_widget_value ();  
   wv->name = "menubar";  
   wv->value = 0;  
   wv->enabled = 1;  
   wv->button_type = BUTTON_TYPE_NONE;  
   wv->help = Qnil;  
   first_wv = wv;  
   
1382    if (deep_p)    if (deep_p)
1383      {      {
1384        /* Make a widget-value tree representing the entire menu trees.  */        /* Make a widget-value tree representing the entire menu trees.  */
1385    
1386        struct buffer *prev = current_buffer;        struct buffer *prev = current_buffer;
1387        Lisp_Object buffer;        Lisp_Object buffer;
1388        int specpdl_count = specpdl_ptr - specpdl;        int specpdl_count = SPECPDL_INDEX ();
1389        int previous_menu_items_used = f->menu_bar_items_used;        int previous_menu_items_used = f->menu_bar_items_used;
1390        Lisp_Object *previous_items        Lisp_Object *previous_items
1391          = (Lisp_Object *) alloca (previous_menu_items_used          = (Lisp_Object *) alloca (previous_menu_items_used
# Line 1384  set_frame_menubar (f, first_time, deep_p Line 1422  set_frame_menubar (f, first_time, deep_p
1422    
1423        items = FRAME_MENU_BAR_ITEMS (f);        items = FRAME_MENU_BAR_ITEMS (f);
1424    
       inhibit_garbage_collection ();  
   
1425        /* Save the frame's previous menu bar contents data.  */        /* Save the frame's previous menu bar contents data.  */
1426        if (previous_menu_items_used)        if (previous_menu_items_used)
1427          bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,          bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
1428                 previous_menu_items_used * sizeof (Lisp_Object));                 previous_menu_items_used * sizeof (Lisp_Object));
1429    
1430        /* Fill in the current menu bar contents.  */        /* Fill in menu_items with the current menu bar contents.
1431             This can evaluate Lisp code.  */
1432        menu_items = f->menu_bar_vector;        menu_items = f->menu_bar_vector;
1433        menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;        menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
1434          submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1435          submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1436          submenu_n_panes = (int *) alloca (XVECTOR (items)->size * sizeof (int));
1437          submenu_top_level_items
1438            = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1439        init_menu_items ();        init_menu_items ();
1440        for (i = 0; i < XVECTOR (items)->size; i += 4)        for (i = 0; i < ASIZE (items); i += 4)
1441          {          {
1442            Lisp_Object key, string, maps;            Lisp_Object key, string, maps;
1443    
1444            key = XVECTOR (items)->contents[i];            last_i = i;
1445            string = XVECTOR (items)->contents[i + 1];  
1446            maps = XVECTOR (items)->contents[i + 2];            key = AREF (items, i);
1447              string = AREF (items, i + 1);
1448              maps = AREF (items, i + 2);
1449            if (NILP (string))            if (NILP (string))
1450              break;              break;
1451    
1452            wv = single_submenu (key, string, maps);            submenu_start[i] = menu_items_used;
1453            if (prev_wv)  
1454              menu_items_n_panes = 0;
1455              submenu_top_level_items[i]
1456                = parse_single_submenu (key, string, maps);
1457              submenu_n_panes[i] = menu_items_n_panes;
1458    
1459              submenu_end[i] = menu_items_used;
1460            }
1461    
1462          finish_menu_items ();
1463    
1464          /* Convert menu_items into widget_value trees
1465             to display the menu.  This cannot evaluate Lisp code.  */
1466    
1467          wv = xmalloc_widget_value ();
1468          wv->name = "menubar";
1469          wv->value = 0;
1470          wv->enabled = 1;
1471          wv->button_type = BUTTON_TYPE_NONE;
1472          wv->help = Qnil;
1473          first_wv = wv;
1474    
1475          for (i = 0; i < last_i; i += 4)
1476            {
1477              menu_items_n_panes = submenu_n_panes[i];
1478              wv = digest_single_submenu (submenu_start[i], submenu_end[i],
1479                                          submenu_top_level_items[i]);
1480              if (prev_wv)
1481              prev_wv->next = wv;              prev_wv->next = wv;
1482            else            else
1483              first_wv->contents = wv;              first_wv->contents = wv;
# Line 1416  set_frame_menubar (f, first_time, deep_p Line 1487  set_frame_menubar (f, first_time, deep_p
1487            prev_wv = wv;            prev_wv = wv;
1488          }          }
1489    
       finish_menu_items ();  
   
1490        set_buffer_internal_1 (prev);        set_buffer_internal_1 (prev);
1491        unbind_to (specpdl_count, Qnil);        unbind_to (specpdl_count, Qnil);
1492    
# Line 1426  set_frame_menubar (f, first_time, deep_p Line 1495  set_frame_menubar (f, first_time, deep_p
1495    
1496        for (i = 0; i < previous_menu_items_used; i++)        for (i = 0; i < previous_menu_items_used; i++)
1497          if (menu_items_used == i          if (menu_items_used == i
1498              || (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i])))              || (!EQ (previous_items[i], AREF (menu_items, i))))
1499            break;            break;
1500        if (i == menu_items_used && i == previous_menu_items_used && i != 0)        if (i == menu_items_used && i == previous_menu_items_used && i != 0)
1501          {          {
# Line 1442  set_frame_menubar (f, first_time, deep_p Line 1511  set_frame_menubar (f, first_time, deep_p
1511           Windows takes care of this for normal string items, but           Windows takes care of this for normal string items, but
1512           not for owner-drawn items or additional item-info.  */           not for owner-drawn items or additional item-info.  */
1513        wv = first_wv->contents;        wv = first_wv->contents;
1514        for (i = 0; i < XVECTOR (items)->size; i += 4)        for (i = 0; i < ASIZE (items); i += 4)
1515          {          {
1516            Lisp_Object string;            Lisp_Object string;
1517            string = XVECTOR (items)->contents[i + 1];            string = AREF (items, i + 1);
1518            if (NILP (string))            if (NILP (string))
1519              break;              break;
1520            wv->name = (char *) XSTRING (string)->data;            wv->name = (char *) SDATA (string);
1521            wv = wv->next;            wv = wv->next;
1522          }          }
1523    
# Line 1461  set_frame_menubar (f, first_time, deep_p Line 1530  set_frame_menubar (f, first_time, deep_p
1530        /* Make a widget-value tree containing        /* Make a widget-value tree containing
1531           just the top level menu bar strings.  */           just the top level menu bar strings.  */
1532    
1533          wv = xmalloc_widget_value ();
1534          wv->name = "menubar";
1535          wv->value = 0;
1536          wv->enabled = 1;
1537          wv->button_type = BUTTON_TYPE_NONE;
1538          wv->help = Qnil;
1539          first_wv = wv;
1540    
1541        items = FRAME_MENU_BAR_ITEMS (f);        items = FRAME_MENU_BAR_ITEMS (f);
1542        for (i = 0; i < XVECTOR (items)->size; i += 4)        for (i = 0; i < ASIZE (items); i += 4)
1543          {          {
1544            Lisp_Object string;            Lisp_Object string;
1545    
1546            string = XVECTOR (items)->contents[i + 1];            string = AREF (items, i + 1);
1547            if (NILP (string))            if (NILP (string))
1548              break;              break;
1549    
1550            wv = xmalloc_widget_value ();            wv = xmalloc_widget_value ();
1551            wv->name = (char *) XSTRING (string)->data;            wv->name = (char *) SDATA (string);
1552            wv->value = 0;            wv->value = 0;
1553            wv->enabled = 1;            wv->enabled = 1;
1554            wv->button_type = BUTTON_TYPE_NONE;            wv->button_type = BUTTON_TYPE_NONE;
# Line 1482  set_frame_menubar (f, first_time, deep_p Line 1559  set_frame_menubar (f, first_time, deep_p
1559               This value just has to be different from small integers.  */               This value just has to be different from small integers.  */
1560            wv->call_data = (void *) (EMACS_INT) (-1);            wv->call_data = (void *) (EMACS_INT) (-1);
1561    
1562            if (prev_wv)            if (prev_wv)
1563              prev_wv->next = wv;              prev_wv->next = wv;
1564            else            else
1565              first_wv->contents = wv;              first_wv->contents = wv;
# Line 1518  set_frame_menubar (f, first_time, deep_p Line 1595  set_frame_menubar (f, first_time, deep_p
1595    
1596      f->output_data.w32->menubar_widget = menubar_widget;      f->output_data.w32->menubar_widget = menubar_widget;
1597      SetMenu (FRAME_W32_WINDOW (f), f->output_data.w32->menubar_widget);      SetMenu (FRAME_W32_WINDOW (f), f->output_data.w32->menubar_widget);
1598      /* Causes flicker when menu bar is updated      /* Causes flicker when menu bar is updated
1599      DrawMenuBar (FRAME_W32_WINDOW (f)); */      DrawMenuBar (FRAME_W32_WINDOW (f)); */
1600    
1601      /* Force the window size to be recomputed so that the frame's text      /* Force the window size to be recomputed so that the frame's text
# Line 1620  w32_menu_show (f, x, y, for_click, keyma Line 1697  w32_menu_show (f, x, y, for_click, keyma
1697    wv->help = Qnil;    wv->help = Qnil;
1698    first_wv = wv;    first_wv = wv;
1699    first_pane = 1;    first_pane = 1;
1700    
1701    /* Loop over all panes and items, filling in the tree.  */    /* Loop over all panes and items, filling in the tree.  */
1702    i = 0;    i = 0;
1703    while (i < menu_items_used)    while (i < menu_items_used)
1704      {      {
1705        if (EQ (XVECTOR (menu_items)->contents[i], Qnil))        if (EQ (AREF (menu_items, i), Qnil))
1706          {          {
1707            submenu_stack[submenu_depth++] = save_wv;            submenu_stack[submenu_depth++] = save_wv;
1708            save_wv = prev_wv;            save_wv = prev_wv;
# Line 1633  w32_menu_show (f, x, y, for_click, keyma Line 1710  w32_menu_show (f, x, y, for_click, keyma
1710            first_pane = 1;            first_pane = 1;
1711            i++;            i++;
1712          }          }
1713        else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))        else if (EQ (AREF (menu_items, i), Qlambda))
1714          {          {
1715            prev_wv = save_wv;            prev_wv = save_wv;
1716            save_wv = submenu_stack[--submenu_depth];            save_wv = submenu_stack[--submenu_depth];
1717            first_pane = 0;            first_pane = 0;
1718            i++;            i++;
1719          }          }
1720        else if (EQ (XVECTOR (menu_items)->contents[i], Qt)        else if (EQ (AREF (menu_items, i), Qt)
1721                 && submenu_depth != 0)                 && submenu_depth != 0)
1722          i += MENU_ITEMS_PANE_LENGTH;          i += MENU_ITEMS_PANE_LENGTH;
1723        /* Ignore a nil in the item list.        /* Ignore a nil in the item list.
1724           It's meaningful only for dialog boxes.  */           It's meaningful only for dialog boxes.  */
1725        else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))        else if (EQ (AREF (menu_items, i), Qquote))
1726          i += 1;          i += 1;
1727        else if (EQ (XVECTOR (menu_items)->contents[i], Qt))        else if (EQ (AREF (menu_items, i), Qt))
1728          {          {
1729            /* Create a new pane.  */            /* Create a new pane.  */
1730            Lisp_Object pane_name, prefix;            Lisp_Object pane_name, prefix;
# Line 1658  w32_menu_show (f, x, y, for_click, keyma Line 1735  w32_menu_show (f, x, y, for_click, keyma
1735            if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))            if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
1736              {              {
1737                pane_name = ENCODE_SYSTEM (pane_name);                pane_name = ENCODE_SYSTEM (pane_name);
1738                AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name;                ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
1739              }              }
1740  #endif  #endif
1741            pane_string = (NILP (pane_name)            pane_string = (NILP (pane_name)
1742                           ? "" : (char *) XSTRING (pane_name)->data);                           ? "" : (char *) SDATA (pane_name));
1743            /* If there is just one top-level pane, put all its items directly            /* If there is just one top-level pane, put all its items directly
1744               under the top-level menu.  */               under the top-level menu.  */
1745            if (menu_items_n_panes == 1)            if (menu_items_n_panes == 1)
# Line 1713  w32_menu_show (f, x, y, for_click, keyma Line 1790  w32_menu_show (f, x, y, for_click, keyma
1790            if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))            if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
1791              {              {
1792                item_name = ENCODE_SYSTEM (item_name);                item_name = ENCODE_SYSTEM (item_name);
1793                AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name;                ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
1794              }              }
1795            if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))            if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
1796              {              {
1797                descrip = ENCODE_SYSTEM (descrip);                descrip = ENCODE_SYSTEM (descrip);
1798                AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip;                ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
1799              }              }
1800  #endif /* not HAVE_MULTILINGUAL_MENU */  #endif /* not HAVE_MULTILINGUAL_MENU */
1801    
1802            wv = xmalloc_widget_value ();            wv = xmalloc_widget_value ();
1803            if (prev_wv)            if (prev_wv)
1804              prev_wv->next = wv;              prev_wv->next = wv;
1805            else            else
1806              save_wv->contents = wv;              save_wv->contents = wv;
1807            wv->name = (char *) XSTRING (item_name)->data;            wv->name = (char *) SDATA (item_name);
1808            if (!NILP (descrip))            if (!NILP (descrip))
1809              wv->key = (char *) XSTRING (descrip)->data;              wv->key = (char *) SDATA (descrip);
1810            wv->value = 0;            wv->value = 0;
1811            /* Use the contents index as call_data, since we are            /* Use the contents index as call_data, since we are
1812               restricted to 16-bits.  */               restricted to 16-bits.  */
# Line 1773  w32_menu_show (f, x, y, for_click, keyma Line 1850  w32_menu_show (f, x, y, for_click, keyma
1850        if (STRING_MULTIBYTE (title))        if (STRING_MULTIBYTE (title))
1851          title = ENCODE_SYSTEM (title);          title = ENCODE_SYSTEM (title);
1852  #endif  #endif
1853        wv_title->name = (char *) XSTRING (title)->data;        wv_title->name = (char *) SDATA (title);
1854        wv_title->enabled = TRUE;        wv_title->enabled = TRUE;
1855        wv_title->title = TRUE;        wv_title->title = TRUE;
1856        wv_title->button_type = BUTTON_TYPE_NONE;        wv_title->button_type = BUTTON_TYPE_NONE;
# Line 1795  w32_menu_show (f, x, y, for_click, keyma Line 1872  w32_menu_show (f, x, y, for_click, keyma
1872    menu_item_selection = 0;    menu_item_selection = 0;
1873    
1874    /* Display the menu.  */    /* Display the menu.  */
1875    menu_item_selection = SendMessage (FRAME_W32_WINDOW (f),    menu_item_selection = SendMessage (FRAME_W32_WINDOW (f),
1876                                       WM_EMACS_TRACKPOPUPMENU,                                       WM_EMACS_TRACKPOPUPMENU,
1877                                       (WPARAM)menu, (LPARAM)&pos);                                       (WPARAM)menu, (LPARAM)&pos);
1878    
# Line 1818  w32_menu_show (f, x, y, for_click, keyma Line 1895  w32_menu_show (f, x, y, for_click, keyma
1895        i = 0;        i = 0;
1896        while (i < menu_items_used)        while (i < menu_items_used)
1897          {          {
1898            if (EQ (XVECTOR (menu_items)->contents[i], Qnil))            if (EQ (AREF (menu_items, i), Qnil))
1899              {              {
1900                subprefix_stack[submenu_depth++] = prefix;                subprefix_stack[submenu_depth++] = prefix;
1901                prefix = entry;                prefix = entry;
1902                i++;                i++;
1903              }              }
1904            else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))            else if (EQ (AREF (menu_items, i), Qlambda))
1905              {              {
1906                prefix = subprefix_stack[--submenu_depth];                prefix = subprefix_stack[--submenu_depth];
1907                i++;                i++;
1908              }              }
1909            else if (EQ (XVECTOR (menu_items)->contents[i], Qt))            else if (EQ (AREF (menu_items, i), Qt))
1910              {              {
1911                prefix                prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
                 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];  
1912                i += MENU_ITEMS_PANE_LENGTH;                i += MENU_ITEMS_PANE_LENGTH;
1913              }              }
1914            /* Ignore a nil in the item list.            /* Ignore a nil in the item list.
1915               It's meaningful only for dialog boxes.  */               It's meaningful only for dialog boxes.  */
1916            else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))            else if (EQ (AREF (menu_items, i), Qquote))
1917              i += 1;              i += 1;
1918            else            else
1919              {              {
1920                entry                entry     = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
                 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];  
1921                if (menu_item_selection == i)                if (menu_item_selection == i)
1922                  {                  {
1923                    if (keymaps != 0)                    if (keymaps != 0)
# Line 1903  w32_dialog_show (f, keymaps, title, erro Line 1978  w32_dialog_show (f, keymaps, title, erro
1978    {    {
1979      Lisp_Object pane_name, prefix;      Lisp_Object pane_name, prefix;
1980      char *pane_string;      char *pane_string;
1981      pane_name = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME];      pane_name = AREF (menu_items, MENU_ITEMS_PANE_NAME);
1982      prefix = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_PREFIX];      prefix = AREF (menu_items, MENU_ITEMS_PANE_PREFIX);
1983      pane_string = (NILP (pane_name)      pane_string = (NILP (pane_name)
1984                     ? "" : (char *) XSTRING (pane_name)->data);                       ? "" : (char *) SDATA (pane_name));
1985      prev_wv = xmalloc_widget_value ();      prev_wv = xmalloc_widget_value ();
1986      prev_wv->value = pane_string;      prev_wv->value = pane_string;
1987      if (keymaps && !NILP (prefix))      if (keymaps && !NILP (prefix))
# Line 1915  w32_dialog_show (f, keymaps, title, erro Line 1990  w32_dialog_show (f, keymaps, title, erro
1990      prev_wv->name = "message";      prev_wv->name = "message";
1991      prev_wv->help = Qnil;      prev_wv->help = Qnil;
1992      first_wv = prev_wv;      first_wv = prev_wv;
1993    
1994      /* Loop over all panes and items, filling in the tree.  */      /* Loop over all panes and items, filling in the tree.  */
1995      i = MENU_ITEMS_PANE_LENGTH;      i = MENU_ITEMS_PANE_LENGTH;
1996      while (i < menu_items_used)      while (i < menu_items_used)
1997        {        {
1998            
1999          /* Create a new item within current pane.  */          /* Create a new item within current pane.  */
2000          Lisp_Object item_name, enable, descrip, help;          Lisp_Object item_name, enable, descrip, help;
2001    
2002          item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME];          item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
2003          enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];          enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
2004          descrip          descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
2005            = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];          help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
2006          help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP];  
           
2007          if (NILP (item_name))          if (NILP (item_name))
2008            {            {
2009              free_menubar_widget_value_tree (first_wv);              free_menubar_widget_value_tree (first_wv);
# Line 1955  w32_dialog_show (f, keymaps, title, erro Line 2029  w32_dialog_show (f, keymaps, title, erro
2029          prev_wv->next = wv;          prev_wv->next = wv;
2030          wv->name = (char *) button_names[nb_buttons];          wv->name = (char *) button_names[nb_buttons];
2031          if (!NILP (descrip))          if (!NILP (descrip))
2032            wv->key = (char *) XSTRING (descrip)->data;            wv->key = (char *) SDATA (descrip);
2033          wv->value = (char *) XSTRING (item_name)->data;          wv->value = (char *) SDATA (item_name);
2034          wv->call_data = (void *) &XVECTOR (menu_items)->contents[i];          wv->call_data = (void *) &AREF (menu_items, i);
2035          wv->enabled = !NILP (enable);          wv->enabled = !NILP (enable);
2036          wv->help = Qnil;          wv->help = Qnil;
2037          prev_wv = wv;          prev_wv = wv;
# Line 2013  w32_dialog_show (f, keymaps, title, erro Line 2087  w32_dialog_show (f, keymaps, title, erro
2087    /* Process events that apply to the menu.  */    /* Process events that apply to the menu.  */
2088    popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id);    popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id);
2089    
2090    lw_destroy_all_widgets (dialog_id);    lw_destroy_all_widgets (dialog_id);
2091    
2092    /* Find the selected item, and its pane, to return    /* Find the selected item, and its pane, to return
2093       the proper value.  */       the proper value.  */
# Line 2027  w32_dialog_show (f, keymaps, title, erro Line 2101  w32_dialog_show (f, keymaps, title, erro
2101          {          {
2102            Lisp_Object entry;            Lisp_Object entry;
2103    
2104            if (EQ (XVECTOR (menu_items)->contents[i], Qt))            if (EQ (AREF (menu_items, i), Qt))
2105              {              {
2106                prefix                prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
                 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];  
2107                i += MENU_ITEMS_PANE_LENGTH;                i += MENU_ITEMS_PANE_LENGTH;
2108              }              }
2109            else            else
2110              {              {
2111                entry                entry     = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
                 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];  
2112                if (menu_item_selection == i)                if (menu_item_selection == i)
2113                  {                  {
2114                    if (keymaps != 0)                    if (keymaps != 0)
# Line 2092  add_menu_item (HMENU menu, widget_value Line 2164  add_menu_item (HMENU menu, widget_value
2164        fuFlags = MF_SEPARATOR;        fuFlags = MF_SEPARATOR;
2165        out_string = NULL;        out_string = NULL;
2166      }      }
2167    else    else
2168      {      {
2169        if (wv->enabled)        if (wv->enabled)
2170          fuFlags = MF_STRING;          fuFlags = MF_STRING;
# Line 2117  add_menu_item (HMENU menu, widget_value Line 2189  add_menu_item (HMENU menu, widget_value
2189               we can't deallocate the memory otherwise.  */               we can't deallocate the memory otherwise.  */
2190            if (get_menu_item_info)            if (get_menu_item_info)
2191              {              {
2192                out_string = (char *) LocalAlloc (LPTR, strlen (wv->name) + 1);                out_string = (char *) local_alloc (strlen (wv->name) + 1);
2193                  strcpy (out_string, wv->name);
2194  #ifdef MENU_DEBUG  #ifdef MENU_DEBUG
2195                DebPrint ("Menu: allocing %ld for owner-draw", info.dwItemData);                DebPrint ("Menu: allocing %ld for owner-draw", out_string);
2196  #endif  #endif
               strcpy (out_string, wv->name);  
2197                fuFlags = MF_OWNERDRAW | MF_DISABLED;                fuFlags = MF_OWNERDRAW | MF_DISABLED;
2198              }              }
2199            else            else
# Line 2277  w32_free_submenu_strings (menu) Line 2349  w32_free_submenu_strings (menu)
2349  #ifdef MENU_DEBUG  #ifdef MENU_DEBUG
2350            DebPrint ("Menu: freeing %ld for owner-draw", info.dwItemData);            DebPrint ("Menu: freeing %ld for owner-draw", info.dwItemData);
2351  #endif  #endif
2352            LocalFree (info.dwItemData);            local_free (info.dwItemData);
2353          }          }
2354    
2355        /* Recurse down submenus.  */        /* Recurse down submenus.  */
# Line 2308  w32_free_menu_strings (hwnd) Line 2380  w32_free_menu_strings (hwnd)
2380    
2381  #endif /* HAVE_MENUS */  #endif /* HAVE_MENUS */
2382    
2383    void syms_of_w32menu ()
 syms_of_w32menu ()  
2384  {  {
2385    /* See if Get/SetMenuItemInfo functions are available.  */          globals_of_w32menu ();
   HMODULE user32 = GetModuleHandle ("user32.dll");  
   get_menu_item_info = GetProcAddress (user32, "GetMenuItemInfoA");  
   set_menu_item_info = GetProcAddress (user32, "SetMenuItemInfoA");  
   
2386    staticpro (&menu_items);    staticpro (&menu_items);
2387    menu_items = Qnil;    menu_items = Qnil;
2388    
# Line 2334  The enable predicate for a menu command Line 2401  The enable predicate for a menu command
2401    defsubr (&Sx_popup_dialog);    defsubr (&Sx_popup_dialog);
2402  #endif  #endif
2403  }  }
2404    
2405    /*
2406            globals_of_w32menu is used to initialize those global variables that
2407            must always be initialized on startup even when the global variable
2408            initialized is non zero (see the function main in emacs.c).
2409            globals_of_w32menu is called from syms_of_w32menu when the global
2410            variable initialized is 0 and directly from main when initialized
2411            is non zero.
2412     */
2413    void globals_of_w32menu ()
2414    {
2415            /* See if Get/SetMenuItemInfo functions are available.  */
2416      HMODULE user32 = GetModuleHandle ("user32.dll");
2417      get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
2418      set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
2419    }

Legend:
Removed from v.1.55  
changed lines
  Added in v.1.55.4.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26