aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32menu.c
diff options
context:
space:
mode:
authorRichard M. Stallman2002-08-05 16:33:44 +0000
committerRichard M. Stallman2002-08-05 16:33:44 +0000
commit6ed09cf02000ed8ffc3e0b0e89dfd885b0e518ff (patch)
tree1c9196469c59446e3d66b4af7e7be7e87ca7329f /src/w32menu.c
parent2a51c0262a98a857525f40359cf6cab66315012a (diff)
downloademacs-6ed09cf02000ed8ffc3e0b0e89dfd885b0e518ff.tar.gz
emacs-6ed09cf02000ed8ffc3e0b0e89dfd885b0e518ff.zip
(local_heap, local_alloc, local_free): New macros.
(malloc_widget_value, free_widget_value) (w32_free_submenu_strings): Use them. (push_submenu_start, push_submenu_end, push_left_right_boundary) (push_menu_pane, push_menu_item, single_keymap_panes) (single_menu_item, Fx_popup_menu, menubar_selection_callback) (single_submenu, set_frame_menubar) (w32_menu_show, w32_dialog_show): Use AREF, ASET, ASIZE. (Fx_popup_menu): Don't show pop up menu until preceding one is actually cleaned up. Moved UNGCPRO outside #ifdef HAVE_MENUS block. Changes adapted from xmenu.c (set_frame_menubar): First parse all submenus, then make widget_value trees from them. Don't allocate any widget_value objects until we are done with the parsing. (parse_single_submenu): New function. (digest_single_submenu): New function. (single_submenu): Function deleted, replaced by those two.
Diffstat (limited to 'src/w32menu.c')
-rw-r--r--src/w32menu.c281
1 files changed, 164 insertions, 117 deletions
diff --git a/src/w32menu.c b/src/w32menu.c
index 1816e33875b..44791448d94 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -112,9 +112,13 @@ typedef struct _widget_value
112#endif 112#endif
113} widget_value; 113} widget_value;
114 114
115/* LocalAlloc/Free is a reasonably good allocator. */ 115/* Local memory management */
116#define malloc_widget_value() (void*)LocalAlloc (LMEM_ZEROINIT, sizeof (widget_value)) 116#define local_heap (GetProcessHeap ())
117#define free_widget_value(wv) LocalFree (wv) 117#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)))
118 122
119/******************************************************************/ 123/******************************************************************/
120 124
@@ -318,7 +322,7 @@ push_submenu_start ()
318 if (menu_items_used + 1 > menu_items_allocated) 322 if (menu_items_used + 1 > menu_items_allocated)
319 grow_menu_items (); 323 grow_menu_items ();
320 324
321 XVECTOR (menu_items)->contents[menu_items_used++] = Qnil; 325 ASET (menu_items, menu_items_used++, Qnil);
322 menu_items_submenu_depth++; 326 menu_items_submenu_depth++;
323} 327}
324 328
@@ -330,7 +334,7 @@ push_submenu_end ()
330 if (menu_items_used + 1 > menu_items_allocated) 334 if (menu_items_used + 1 > menu_items_allocated)
331 grow_menu_items (); 335 grow_menu_items ();
332 336
333 XVECTOR (menu_items)->contents[menu_items_used++] = Qlambda; 337 ASET (menu_items, menu_items_used++, Qlambda);
334 menu_items_submenu_depth--; 338 menu_items_submenu_depth--;
335} 339}
336 340
@@ -342,7 +346,7 @@ push_left_right_boundary ()
342 if (menu_items_used + 1 > menu_items_allocated) 346 if (menu_items_used + 1 > menu_items_allocated)
343 grow_menu_items (); 347 grow_menu_items ();
344 348
345 XVECTOR (menu_items)->contents[menu_items_used++] = Qquote; 349 ASET (menu_items, menu_items_used++, Qquote);
346} 350}
347 351
348/* Start a new menu pane in menu_items. 352/* Start a new menu pane in menu_items.
@@ -357,9 +361,9 @@ push_menu_pane (name, prefix_vec)
357 361
358 if (menu_items_submenu_depth == 0) 362 if (menu_items_submenu_depth == 0)
359 menu_items_n_panes++; 363 menu_items_n_panes++;
360 XVECTOR (menu_items)->contents[menu_items_used++] = Qt; 364 ASET (menu_items, menu_items_used++, Qt);
361 XVECTOR (menu_items)->contents[menu_items_used++] = name; 365 ASET (menu_items, menu_items_used++, name);
362 XVECTOR (menu_items)->contents[menu_items_used++] = prefix_vec; 366 ASET (menu_items, menu_items_used++, prefix_vec);
363} 367}
364 368
365/* Push one menu item into the current pane. NAME is the string to 369/* Push one menu item into the current pane. NAME is the string to
@@ -377,14 +381,14 @@ push_menu_item (name, enable, key, def, equiv, type, selected, help)
377 if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated) 381 if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated)
378 grow_menu_items (); 382 grow_menu_items ();
379 383
380 XVECTOR (menu_items)->contents[menu_items_used++] = name; 384 ASET (menu_items, menu_items_used++, name);
381 XVECTOR (menu_items)->contents[menu_items_used++] = enable; 385 ASET (menu_items, menu_items_used++, enable);
382 XVECTOR (menu_items)->contents[menu_items_used++] = key; 386 ASET (menu_items, menu_items_used++, key);
383 XVECTOR (menu_items)->contents[menu_items_used++] = equiv; 387 ASET (menu_items, menu_items_used++, equiv);
384 XVECTOR (menu_items)->contents[menu_items_used++] = def; 388 ASET (menu_items, menu_items_used++, def);
385 XVECTOR (menu_items)->contents[menu_items_used++] = type; 389 ASET (menu_items, menu_items_used++, type);
386 XVECTOR (menu_items)->contents[menu_items_used++] = selected; 390 ASET (menu_items, menu_items_used++, selected);
387 XVECTOR (menu_items)->contents[menu_items_used++] = help; 391 ASET (menu_items, menu_items_used++, help);
388} 392}
389 393
390/* Look through KEYMAPS, a vector of keymaps that is NMAPS long, 394/* Look through KEYMAPS, a vector of keymaps that is NMAPS long,
@@ -450,13 +454,13 @@ single_keymap_panes (keymap, pane_name, prefix, notreal, maxdepth)
450 else if (VECTORP (item)) 454 else if (VECTORP (item))
451 { 455 {
452 /* Loop over the char values represented in the vector. */ 456 /* Loop over the char values represented in the vector. */
453 int len = XVECTOR (item)->size; 457 int len = ASIZE (item);
454 int c; 458 int c;
455 for (c = 0; c < len; c++) 459 for (c = 0; c < len; c++)
456 { 460 {
457 Lisp_Object character; 461 Lisp_Object character;
458 XSETFASTINT (character, c); 462 XSETFASTINT (character, c);
459 single_menu_item (character, XVECTOR (item)->contents[c], 463 single_menu_item (character, AREF (item, c),
460 &pending_maps, notreal, maxdepth); 464 &pending_maps, notreal, maxdepth);
461 } 465 }
462 } 466 }
@@ -504,7 +508,7 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth)
504 if (!res) 508 if (!res)
505 return; /* Not a menu item. */ 509 return; /* Not a menu item. */
506 510
507 map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP]; 511 map = AREF (item_properties, ITEM_PROPERTY_MAP);
508 512
509 if (notreal) 513 if (notreal)
510 { 514 {
@@ -515,8 +519,8 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth)
515 return; 519 return;
516 } 520 }
517 521
518 enabled = XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE]; 522 enabled = AREF (item_properties, ITEM_PROPERTY_ENABLE);
519 item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME]; 523 item_string = AREF (item_properties, ITEM_PROPERTY_NAME);
520 524
521 if (!NILP (map) && SREF (item_string, 0) == '@') 525 if (!NILP (map) && SREF (item_string, 0) == '@')
522 { 526 {
@@ -528,11 +532,11 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth)
528 } 532 }
529 533
530 push_menu_item (item_string, enabled, key, 534 push_menu_item (item_string, enabled, key,
531 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF], 535 AREF (item_properties, ITEM_PROPERTY_DEF),
532 XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ], 536 AREF (item_properties, ITEM_PROPERTY_KEYEQ),
533 XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE], 537 AREF (item_properties, ITEM_PROPERTY_TYPE),
534 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED], 538 AREF (item_properties, ITEM_PROPERTY_SELECTED),
535 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]); 539 AREF (item_properties, ITEM_PROPERTY_HELP));
536 540
537 /* Display a submenu using the toolkit. */ 541 /* Display a submenu using the toolkit. */
538 if (! (NILP (map) || NILP (enabled))) 542 if (! (NILP (map) || NILP (enabled)))
@@ -745,7 +749,7 @@ cached information about equivalent key sequences. */)
745 749
746 /* Make that be the pane title of the first pane. */ 750 /* Make that be the pane title of the first pane. */
747 if (!NILP (prompt) && menu_items_n_panes >= 0) 751 if (!NILP (prompt) && menu_items_n_panes >= 0)
748 XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = prompt; 752 ASET (menu_items, MENU_ITEMS_PANE_NAME, prompt);
749 753
750 keymaps = 1; 754 keymaps = 1;
751 } 755 }
@@ -777,7 +781,7 @@ cached information about equivalent key sequences. */)
777 781
778 /* Make the title be the pane title of the first pane. */ 782 /* Make the title be the pane title of the first pane. */
779 if (!NILP (title) && menu_items_n_panes >= 0) 783 if (!NILP (title) && menu_items_n_panes >= 0)
780 XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = title; 784 ASET (menu_items, MENU_ITEMS_PANE_NAME, title);
781 785
782 keymaps = 1; 786 keymaps = 1;
783 } 787 }
@@ -800,6 +804,16 @@ cached information about equivalent key sequences. */)
800 } 804 }
801 805
802#ifdef HAVE_MENUS 806#ifdef HAVE_MENUS
807 /* If resources from a previous popup menu exist yet, does nothing
808 until the `menu_free_timer' has freed them (see w32fns.c).
809 */
810 if (current_popup_menu)
811 {
812 discard_menu_items ();
813 UNGCPRO;
814 return Qnil;
815 }
816
803 /* Display them in a menu. */ 817 /* Display them in a menu. */
804 BLOCK_INPUT; 818 BLOCK_INPUT;
805 819
@@ -808,9 +822,9 @@ cached information about equivalent key sequences. */)
808 UNBLOCK_INPUT; 822 UNBLOCK_INPUT;
809 823
810 discard_menu_items (); 824 discard_menu_items ();
825#endif /* HAVE_MENUS */
811 826
812 UNGCPRO; 827 UNGCPRO;
813#endif /* HAVE_MENUS */
814 828
815 if (error_name) error (error_name); 829 if (error_name) error (error_name);
816 return selection; 830 return selection;
@@ -981,25 +995,25 @@ menubar_selection_callback (FRAME_PTR f, void * client_data)
981 i = 0; 995 i = 0;
982 while (i < f->menu_bar_items_used) 996 while (i < f->menu_bar_items_used)
983 { 997 {
984 if (EQ (XVECTOR (vector)->contents[i], Qnil)) 998 if (EQ (AREF (vector, i), Qnil))
985 { 999 {
986 subprefix_stack[submenu_depth++] = prefix; 1000 subprefix_stack[submenu_depth++] = prefix;
987 prefix = entry; 1001 prefix = entry;
988 i++; 1002 i++;
989 } 1003 }
990 else if (EQ (XVECTOR (vector)->contents[i], Qlambda)) 1004 else if (EQ (AREF (vector, i), Qlambda))
991 { 1005 {
992 prefix = subprefix_stack[--submenu_depth]; 1006 prefix = subprefix_stack[--submenu_depth];
993 i++; 1007 i++;
994 } 1008 }
995 else if (EQ (XVECTOR (vector)->contents[i], Qt)) 1009 else if (EQ (AREF (vector, i), Qt))
996 { 1010 {
997 prefix = XVECTOR (vector)->contents[i + MENU_ITEMS_PANE_PREFIX]; 1011 prefix = AREF (vector, i + MENU_ITEMS_PANE_PREFIX);
998 i += MENU_ITEMS_PANE_LENGTH; 1012 i += MENU_ITEMS_PANE_LENGTH;
999 } 1013 }
1000 else 1014 else
1001 { 1015 {
1002 entry = XVECTOR (vector)->contents[i + MENU_ITEMS_ITEM_VALUE]; 1016 entry = AREF (vector, i + MENU_ITEMS_ITEM_VALUE);
1003 /* The EMACS_INT cast avoids a warning. There's no problem 1017 /* The EMACS_INT cast avoids a warning. There's no problem
1004 as long as pointers have enough bits to hold small integers. */ 1018 as long as pointers have enough bits to hold small integers. */
1005 if ((int) (EMACS_INT) client_data == i) 1019 if ((int) (EMACS_INT) client_data == i)
@@ -1075,7 +1089,7 @@ free_menubar_widget_value_tree (wv)
1075 widget_value *wv; 1089 widget_value *wv;
1076{ 1090{
1077 if (! wv) return; 1091 if (! wv) return;
1078 1092
1079 wv->name = wv->value = wv->key = (char *) 0xDEADBEEF; 1093 wv->name = wv->value = wv->key = (char *) 0xDEADBEEF;
1080 1094
1081 if (wv->contents && (wv->contents != (widget_value*)1)) 1095 if (wv->contents && (wv->contents != (widget_value*)1))
@@ -1093,22 +1107,18 @@ free_menubar_widget_value_tree (wv)
1093 UNBLOCK_INPUT; 1107 UNBLOCK_INPUT;
1094} 1108}
1095 1109
1096/* Return a tree of widget_value structures for a menu bar item 1110/* Set up data i menu_items for a menu bar item
1097 whose event type is ITEM_KEY (with string ITEM_NAME) 1111 whose event type is ITEM_KEY (with string ITEM_NAME)
1098 and whose contents come from the list of keymaps MAPS. */ 1112 and whose contents come from the list of keymaps MAPS. */
1099 1113
1100static widget_value * 1114static int
1101single_submenu (item_key, item_name, maps) 1115parse_single_submenu (item_key, item_name, maps)
1102 Lisp_Object item_key, item_name, maps; 1116 Lisp_Object item_key, item_name, maps;
1103{ 1117{
1104 widget_value *wv, *prev_wv, *save_wv, *first_wv;
1105 int i;
1106 int submenu_depth = 0;
1107 Lisp_Object length; 1118 Lisp_Object length;
1108 int len; 1119 int len;
1109 Lisp_Object *mapvec; 1120 Lisp_Object *mapvec;
1110 widget_value **submenu_stack; 1121 int i;
1111 int previous_items = menu_items_used;
1112 int top_level_items = 0; 1122 int top_level_items = 0;
1113 1123
1114 length = Flength (maps); 1124 length = Flength (maps);
@@ -1122,8 +1132,6 @@ single_submenu (item_key, item_name, maps)
1122 maps = Fcdr (maps); 1132 maps = Fcdr (maps);
1123 } 1133 }
1124 1134
1125 menu_items_n_panes = 0;
1126
1127 /* Loop over the given keymaps, making a pane for each map. 1135 /* Loop over the given keymaps, making a pane for each map.
1128 But don't make a pane that is empty--ignore that map instead. */ 1136 But don't make a pane that is empty--ignore that map instead. */
1129 for (i = 0; i < len; i++) 1137 for (i = 0; i < len; i++)
@@ -1141,9 +1149,23 @@ single_submenu (item_key, item_name, maps)
1141 else 1149 else
1142 single_keymap_panes (mapvec[i], item_name, item_key, 0, 10); 1150 single_keymap_panes (mapvec[i], item_name, item_key, 0, 10);
1143 } 1151 }
1152
1153 return top_level_items;
1154}
1144 1155
1145 /* Create a tree of widget_value objects 1156
1146 representing the panes and their items. */ 1157/* Create a tree of widget_value objects
1158 representing the panes and items
1159 in menu_items starting at index START, up to index END. */
1160
1161static widget_value *
1162digest_single_submenu (start, end, top_level_items)
1163 int start, end;
1164{
1165 widget_value *wv, *prev_wv, *save_wv, *first_wv;
1166 int i;
1167 int submenu_depth = 0;
1168 widget_value **submenu_stack;
1147 1169
1148 submenu_stack 1170 submenu_stack
1149 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); 1171 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
@@ -1161,43 +1183,43 @@ single_submenu (item_key, item_name, maps)
1161 and construct a tree of widget_value objects. 1183 and construct a tree of widget_value objects.
1162 Ignore the panes and items made by previous calls to 1184 Ignore the panes and items made by previous calls to
1163 single_submenu, even though those are also in menu_items. */ 1185 single_submenu, even though those are also in menu_items. */
1164 i = previous_items; 1186 i = start;
1165 while (i < menu_items_used) 1187 while (i < end)
1166 { 1188 {
1167 if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) 1189 if (EQ (AREF (menu_items, i), Qnil))
1168 { 1190 {
1169 submenu_stack[submenu_depth++] = save_wv; 1191 submenu_stack[submenu_depth++] = save_wv;
1170 save_wv = prev_wv; 1192 save_wv = prev_wv;
1171 prev_wv = 0; 1193 prev_wv = 0;
1172 i++; 1194 i++;
1173 } 1195 }
1174 else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda)) 1196 else if (EQ (AREF (menu_items, i), Qlambda))
1175 { 1197 {
1176 prev_wv = save_wv; 1198 prev_wv = save_wv;
1177 save_wv = submenu_stack[--submenu_depth]; 1199 save_wv = submenu_stack[--submenu_depth];
1178 i++; 1200 i++;
1179 } 1201 }
1180 else if (EQ (XVECTOR (menu_items)->contents[i], Qt) 1202 else if (EQ (AREF (menu_items, i), Qt)
1181 && submenu_depth != 0) 1203 && submenu_depth != 0)
1182 i += MENU_ITEMS_PANE_LENGTH; 1204 i += MENU_ITEMS_PANE_LENGTH;
1183 /* Ignore a nil in the item list. 1205 /* Ignore a nil in the item list.
1184 It's meaningful only for dialog boxes. */ 1206 It's meaningful only for dialog boxes. */
1185 else if (EQ (XVECTOR (menu_items)->contents[i], Qquote)) 1207 else if (EQ (AREF (menu_items, i), Qquote))
1186 i += 1; 1208 i += 1;
1187 else if (EQ (XVECTOR (menu_items)->contents[i], Qt)) 1209 else if (EQ (AREF (menu_items, i), Qt))
1188 { 1210 {
1189 /* Create a new pane. */ 1211 /* Create a new pane. */
1190 Lisp_Object pane_name, prefix; 1212 Lisp_Object pane_name, prefix;
1191 char *pane_string; 1213 char *pane_string;
1192 1214
1193 pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME]; 1215 pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
1194 prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; 1216 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
1195 1217
1196#ifndef HAVE_MULTILINGUAL_MENU 1218#ifndef HAVE_MULTILINGUAL_MENU
1197 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) 1219 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
1198 { 1220 {
1199 pane_name = ENCODE_SYSTEM (pane_name); 1221 pane_name = ENCODE_SYSTEM (pane_name);
1200 AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name; 1222 ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
1201 } 1223 }
1202#endif 1224#endif
1203 pane_string = (NILP (pane_name) 1225 pane_string = (NILP (pane_name)
@@ -1249,13 +1271,13 @@ single_submenu (item_key, item_name, maps)
1249 if (STRING_MULTIBYTE (item_name)) 1271 if (STRING_MULTIBYTE (item_name))
1250 { 1272 {
1251 item_name = ENCODE_SYSTEM (item_name); 1273 item_name = ENCODE_SYSTEM (item_name);
1252 AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; 1274 ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
1253 } 1275 }
1254 1276
1255 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) 1277 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
1256 { 1278 {
1257 descrip = ENCODE_SYSTEM (descrip); 1279 descrip = ENCODE_SYSTEM (descrip);
1258 AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; 1280 ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
1259 } 1281 }
1260#endif /* not HAVE_MULTILINGUAL_MENU */ 1282#endif /* not HAVE_MULTILINGUAL_MENU */
1261 1283
@@ -1320,7 +1342,9 @@ set_frame_menubar (f, first_time, deep_p)
1320 HMENU menubar_widget = f->output_data.w32->menubar_widget; 1342 HMENU menubar_widget = f->output_data.w32->menubar_widget;
1321 Lisp_Object items; 1343 Lisp_Object items;
1322 widget_value *wv, *first_wv, *prev_wv = 0; 1344 widget_value *wv, *first_wv, *prev_wv = 0;
1323 int i; 1345 int i, last_i;
1346 int *submenu_start, *submenu_end;
1347 int *submenu_top_level_items;
1324 1348
1325 /* We must not change the menubar when actually in use. */ 1349 /* We must not change the menubar when actually in use. */
1326 if (f->output_data.w32->menubar_active) 1350 if (f->output_data.w32->menubar_active)
@@ -1333,14 +1357,6 @@ set_frame_menubar (f, first_time, deep_p)
1333 else if (pending_menu_activation && !deep_p) 1357 else if (pending_menu_activation && !deep_p)
1334 deep_p = 1; 1358 deep_p = 1;
1335 1359
1336 wv = xmalloc_widget_value ();
1337 wv->name = "menubar";
1338 wv->value = 0;
1339 wv->enabled = 1;
1340 wv->button_type = BUTTON_TYPE_NONE;
1341 wv->help = Qnil;
1342 first_wv = wv;
1343
1344 if (deep_p) 1360 if (deep_p)
1345 { 1361 {
1346 /* Make a widget-value tree representing the entire menu trees. */ 1362 /* Make a widget-value tree representing the entire menu trees. */
@@ -1384,28 +1400,58 @@ set_frame_menubar (f, first_time, deep_p)
1384 1400
1385 items = FRAME_MENU_BAR_ITEMS (f); 1401 items = FRAME_MENU_BAR_ITEMS (f);
1386 1402
1387 inhibit_garbage_collection ();
1388
1389 /* Save the frame's previous menu bar contents data. */ 1403 /* Save the frame's previous menu bar contents data. */
1390 if (previous_menu_items_used) 1404 if (previous_menu_items_used)
1391 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, 1405 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
1392 previous_menu_items_used * sizeof (Lisp_Object)); 1406 previous_menu_items_used * sizeof (Lisp_Object));
1393 1407
1394 /* Fill in the current menu bar contents. */ 1408 /* Fill in menu_items with the current menu bar contents.
1409 This can evaluate Lisp code. */
1395 menu_items = f->menu_bar_vector; 1410 menu_items = f->menu_bar_vector;
1396 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; 1411 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
1412 submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1413 submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1414 submenu_top_level_items
1415 = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1397 init_menu_items (); 1416 init_menu_items ();
1398 for (i = 0; i < XVECTOR (items)->size; i += 4) 1417 for (i = 0; i < ASIZE (items); i += 4)
1399 { 1418 {
1400 Lisp_Object key, string, maps; 1419 Lisp_Object key, string, maps;
1401 1420
1402 key = XVECTOR (items)->contents[i]; 1421 last_i = i;
1403 string = XVECTOR (items)->contents[i + 1]; 1422
1404 maps = XVECTOR (items)->contents[i + 2]; 1423 key = AREF (items, i);
1424 string = AREF (items, i + 1);
1425 maps = AREF (items, i + 2);
1405 if (NILP (string)) 1426 if (NILP (string))
1406 break; 1427 break;
1407 1428
1408 wv = single_submenu (key, string, maps); 1429 submenu_start[i] = menu_items_used;
1430
1431 menu_items_n_panes = 0;
1432 submenu_top_level_items[i]
1433 = parse_single_submenu (key, string, maps);
1434
1435 submenu_end[i] = menu_items_used;
1436 }
1437
1438 finish_menu_items ();
1439
1440 /* Convert menu_items into widget_value trees
1441 to display the menu. This cannot evaluate Lisp code. */
1442
1443 wv = xmalloc_widget_value ();
1444 wv->name = "menubar";
1445 wv->value = 0;
1446 wv->enabled = 1;
1447 wv->button_type = BUTTON_TYPE_NONE;
1448 wv->help = Qnil;
1449 first_wv = wv;
1450
1451 for (i = 0; i < last_i; i += 4)
1452 {
1453 wv = digest_single_submenu (submenu_start[i], submenu_end[i],
1454 submenu_top_level_items[i]);
1409 if (prev_wv) 1455 if (prev_wv)
1410 prev_wv->next = wv; 1456 prev_wv->next = wv;
1411 else 1457 else
@@ -1416,8 +1462,6 @@ set_frame_menubar (f, first_time, deep_p)
1416 prev_wv = wv; 1462 prev_wv = wv;
1417 } 1463 }
1418 1464
1419 finish_menu_items ();
1420
1421 set_buffer_internal_1 (prev); 1465 set_buffer_internal_1 (prev);
1422 unbind_to (specpdl_count, Qnil); 1466 unbind_to (specpdl_count, Qnil);
1423 1467
@@ -1426,7 +1470,7 @@ set_frame_menubar (f, first_time, deep_p)
1426 1470
1427 for (i = 0; i < previous_menu_items_used; i++) 1471 for (i = 0; i < previous_menu_items_used; i++)
1428 if (menu_items_used == i 1472 if (menu_items_used == i
1429 || (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i]))) 1473 || (!EQ (previous_items[i], AREF (menu_items, i))))
1430 break; 1474 break;
1431 if (i == menu_items_used && i == previous_menu_items_used && i != 0) 1475 if (i == menu_items_used && i == previous_menu_items_used && i != 0)
1432 { 1476 {
@@ -1442,10 +1486,10 @@ set_frame_menubar (f, first_time, deep_p)
1442 Windows takes care of this for normal string items, but 1486 Windows takes care of this for normal string items, but
1443 not for owner-drawn items or additional item-info. */ 1487 not for owner-drawn items or additional item-info. */
1444 wv = first_wv->contents; 1488 wv = first_wv->contents;
1445 for (i = 0; i < XVECTOR (items)->size; i += 4) 1489 for (i = 0; i < ASIZE (items); i += 4)
1446 { 1490 {
1447 Lisp_Object string; 1491 Lisp_Object string;
1448 string = XVECTOR (items)->contents[i + 1]; 1492 string = AREF (items, i + 1);
1449 if (NILP (string)) 1493 if (NILP (string))
1450 break; 1494 break;
1451 wv->name = (char *) SDATA (string); 1495 wv->name = (char *) SDATA (string);
@@ -1461,12 +1505,20 @@ set_frame_menubar (f, first_time, deep_p)
1461 /* Make a widget-value tree containing 1505 /* Make a widget-value tree containing
1462 just the top level menu bar strings. */ 1506 just the top level menu bar strings. */
1463 1507
1508 wv = xmalloc_widget_value ();
1509 wv->name = "menubar";
1510 wv->value = 0;
1511 wv->enabled = 1;
1512 wv->button_type = BUTTON_TYPE_NONE;
1513 wv->help = Qnil;
1514 first_wv = wv;
1515
1464 items = FRAME_MENU_BAR_ITEMS (f); 1516 items = FRAME_MENU_BAR_ITEMS (f);
1465 for (i = 0; i < XVECTOR (items)->size; i += 4) 1517 for (i = 0; i < ASIZE (items); i += 4)
1466 { 1518 {
1467 Lisp_Object string; 1519 Lisp_Object string;
1468 1520
1469 string = XVECTOR (items)->contents[i + 1]; 1521 string = AREF (items, i + 1);
1470 if (NILP (string)) 1522 if (NILP (string))
1471 break; 1523 break;
1472 1524
@@ -1625,7 +1677,7 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
1625 i = 0; 1677 i = 0;
1626 while (i < menu_items_used) 1678 while (i < menu_items_used)
1627 { 1679 {
1628 if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) 1680 if (EQ (AREF (menu_items, i), Qnil))
1629 { 1681 {
1630 submenu_stack[submenu_depth++] = save_wv; 1682 submenu_stack[submenu_depth++] = save_wv;
1631 save_wv = prev_wv; 1683 save_wv = prev_wv;
@@ -1633,21 +1685,21 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
1633 first_pane = 1; 1685 first_pane = 1;
1634 i++; 1686 i++;
1635 } 1687 }
1636 else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda)) 1688 else if (EQ (AREF (menu_items, i), Qlambda))
1637 { 1689 {
1638 prev_wv = save_wv; 1690 prev_wv = save_wv;
1639 save_wv = submenu_stack[--submenu_depth]; 1691 save_wv = submenu_stack[--submenu_depth];
1640 first_pane = 0; 1692 first_pane = 0;
1641 i++; 1693 i++;
1642 } 1694 }
1643 else if (EQ (XVECTOR (menu_items)->contents[i], Qt) 1695 else if (EQ (AREF (menu_items, i), Qt)
1644 && submenu_depth != 0) 1696 && submenu_depth != 0)
1645 i += MENU_ITEMS_PANE_LENGTH; 1697 i += MENU_ITEMS_PANE_LENGTH;
1646 /* Ignore a nil in the item list. 1698 /* Ignore a nil in the item list.
1647 It's meaningful only for dialog boxes. */ 1699 It's meaningful only for dialog boxes. */
1648 else if (EQ (XVECTOR (menu_items)->contents[i], Qquote)) 1700 else if (EQ (AREF (menu_items, i), Qquote))
1649 i += 1; 1701 i += 1;
1650 else if (EQ (XVECTOR (menu_items)->contents[i], Qt)) 1702 else if (EQ (AREF (menu_items, i), Qt))
1651 { 1703 {
1652 /* Create a new pane. */ 1704 /* Create a new pane. */
1653 Lisp_Object pane_name, prefix; 1705 Lisp_Object pane_name, prefix;
@@ -1658,7 +1710,7 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
1658 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) 1710 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
1659 { 1711 {
1660 pane_name = ENCODE_SYSTEM (pane_name); 1712 pane_name = ENCODE_SYSTEM (pane_name);
1661 AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name; 1713 ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
1662 } 1714 }
1663#endif 1715#endif
1664 pane_string = (NILP (pane_name) 1716 pane_string = (NILP (pane_name)
@@ -1713,12 +1765,12 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
1713 if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) 1765 if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
1714 { 1766 {
1715 item_name = ENCODE_SYSTEM (item_name); 1767 item_name = ENCODE_SYSTEM (item_name);
1716 AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; 1768 ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
1717 } 1769 }
1718 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) 1770 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
1719 { 1771 {
1720 descrip = ENCODE_SYSTEM (descrip); 1772 descrip = ENCODE_SYSTEM (descrip);
1721 AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; 1773 ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
1722 } 1774 }
1723#endif /* not HAVE_MULTILINGUAL_MENU */ 1775#endif /* not HAVE_MULTILINGUAL_MENU */
1724 1776
@@ -1818,31 +1870,29 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
1818 i = 0; 1870 i = 0;
1819 while (i < menu_items_used) 1871 while (i < menu_items_used)
1820 { 1872 {
1821 if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) 1873 if (EQ (AREF (menu_items, i), Qnil))
1822 { 1874 {
1823 subprefix_stack[submenu_depth++] = prefix; 1875 subprefix_stack[submenu_depth++] = prefix;
1824 prefix = entry; 1876 prefix = entry;
1825 i++; 1877 i++;
1826 } 1878 }
1827 else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda)) 1879 else if (EQ (AREF (menu_items, i), Qlambda))
1828 { 1880 {
1829 prefix = subprefix_stack[--submenu_depth]; 1881 prefix = subprefix_stack[--submenu_depth];
1830 i++; 1882 i++;
1831 } 1883 }
1832 else if (EQ (XVECTOR (menu_items)->contents[i], Qt)) 1884 else if (EQ (AREF (menu_items, i), Qt))
1833 { 1885 {
1834 prefix 1886 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
1835 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
1836 i += MENU_ITEMS_PANE_LENGTH; 1887 i += MENU_ITEMS_PANE_LENGTH;
1837 } 1888 }
1838 /* Ignore a nil in the item list. 1889 /* Ignore a nil in the item list.
1839 It's meaningful only for dialog boxes. */ 1890 It's meaningful only for dialog boxes. */
1840 else if (EQ (XVECTOR (menu_items)->contents[i], Qquote)) 1891 else if (EQ (AREF (menu_items, i), Qquote))
1841 i += 1; 1892 i += 1;
1842 else 1893 else
1843 { 1894 {
1844 entry 1895 entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
1845 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];
1846 if (menu_item_selection == i) 1896 if (menu_item_selection == i)
1847 { 1897 {
1848 if (keymaps != 0) 1898 if (keymaps != 0)
@@ -1903,8 +1953,8 @@ w32_dialog_show (f, keymaps, title, error)
1903 { 1953 {
1904 Lisp_Object pane_name, prefix; 1954 Lisp_Object pane_name, prefix;
1905 char *pane_string; 1955 char *pane_string;
1906 pane_name = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME]; 1956 pane_name = AREF (menu_items, MENU_ITEMS_PANE_NAME);
1907 prefix = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_PREFIX]; 1957 prefix = AREF (menu_items, MENU_ITEMS_PANE_PREFIX);
1908 pane_string = (NILP (pane_name) 1958 pane_string = (NILP (pane_name)
1909 ? "" : (char *) SDATA (pane_name)); 1959 ? "" : (char *) SDATA (pane_name));
1910 prev_wv = xmalloc_widget_value (); 1960 prev_wv = xmalloc_widget_value ();
@@ -1924,11 +1974,10 @@ w32_dialog_show (f, keymaps, title, error)
1924 /* Create a new item within current pane. */ 1974 /* Create a new item within current pane. */
1925 Lisp_Object item_name, enable, descrip, help; 1975 Lisp_Object item_name, enable, descrip, help;
1926 1976
1927 item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME]; 1977 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
1928 enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; 1978 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
1929 descrip 1979 descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
1930 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; 1980 help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
1931 help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP];
1932 1981
1933 if (NILP (item_name)) 1982 if (NILP (item_name))
1934 { 1983 {
@@ -1957,7 +2006,7 @@ w32_dialog_show (f, keymaps, title, error)
1957 if (!NILP (descrip)) 2006 if (!NILP (descrip))
1958 wv->key = (char *) SDATA (descrip); 2007 wv->key = (char *) SDATA (descrip);
1959 wv->value = (char *) SDATA (item_name); 2008 wv->value = (char *) SDATA (item_name);
1960 wv->call_data = (void *) &XVECTOR (menu_items)->contents[i]; 2009 wv->call_data = (void *) &AREF (menu_items, i);
1961 wv->enabled = !NILP (enable); 2010 wv->enabled = !NILP (enable);
1962 wv->help = Qnil; 2011 wv->help = Qnil;
1963 prev_wv = wv; 2012 prev_wv = wv;
@@ -2027,16 +2076,14 @@ w32_dialog_show (f, keymaps, title, error)
2027 { 2076 {
2028 Lisp_Object entry; 2077 Lisp_Object entry;
2029 2078
2030 if (EQ (XVECTOR (menu_items)->contents[i], Qt)) 2079 if (EQ (AREF (menu_items, i), Qt))
2031 { 2080 {
2032 prefix 2081 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
2033 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
2034 i += MENU_ITEMS_PANE_LENGTH; 2082 i += MENU_ITEMS_PANE_LENGTH;
2035 } 2083 }
2036 else 2084 else
2037 { 2085 {
2038 entry 2086 entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
2039 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];
2040 if (menu_item_selection == i) 2087 if (menu_item_selection == i)
2041 { 2088 {
2042 if (keymaps != 0) 2089 if (keymaps != 0)
@@ -2117,11 +2164,11 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
2117 we can't deallocate the memory otherwise. */ 2164 we can't deallocate the memory otherwise. */
2118 if (get_menu_item_info) 2165 if (get_menu_item_info)
2119 { 2166 {
2120 out_string = (char *) LocalAlloc (LPTR, strlen (wv->name) + 1); 2167 out_string = (char *) local_alloc (strlen (wv->name) + 1);
2168 strcpy (out_string, wv->name);
2121#ifdef MENU_DEBUG 2169#ifdef MENU_DEBUG
2122 DebPrint ("Menu: allocing %ld for owner-draw", info.dwItemData); 2170 DebPrint ("Menu: allocing %ld for owner-draw", out_string);
2123#endif 2171#endif
2124 strcpy (out_string, wv->name);
2125 fuFlags = MF_OWNERDRAW | MF_DISABLED; 2172 fuFlags = MF_OWNERDRAW | MF_DISABLED;
2126 } 2173 }
2127 else 2174 else
@@ -2277,7 +2324,7 @@ w32_free_submenu_strings (menu)
2277#ifdef MENU_DEBUG 2324#ifdef MENU_DEBUG
2278 DebPrint ("Menu: freeing %ld for owner-draw", info.dwItemData); 2325 DebPrint ("Menu: freeing %ld for owner-draw", info.dwItemData);
2279#endif 2326#endif
2280 LocalFree (info.dwItemData); 2327 local_free (info.dwItemData);
2281 } 2328 }
2282 2329
2283 /* Recurse down submenus. */ 2330 /* Recurse down submenus. */