Mercurial > emacs
comparison src/w32menu.c @ 46815:52f36f4b0e4f
(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.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Mon, 05 Aug 2002 16:33:44 +0000 |
parents | 40db0673e6f0 |
children | 4d7b83cc03aa |
comparison
equal
deleted
inserted
replaced
46814:f7dd9a44324f | 46815:52f36f4b0e4f |
---|---|
110 */ | 110 */ |
111 struct _widget_value *free_list; | 111 struct _widget_value *free_list; |
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 |
121 #ifndef TRUE | 125 #ifndef TRUE |
122 #define TRUE 1 | 126 #define TRUE 1 |
316 push_submenu_start () | 320 push_submenu_start () |
317 { | 321 { |
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 |
325 /* End a submenu. */ | 329 /* End a submenu. */ |
326 | 330 |
328 push_submenu_end () | 332 push_submenu_end () |
329 { | 333 { |
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 |
337 /* Indicate boundary between left and right. */ | 341 /* Indicate boundary between left and right. */ |
338 | 342 |
340 push_left_right_boundary () | 344 push_left_right_boundary () |
341 { | 345 { |
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. |
349 NAME is the pane name. PREFIX_VEC is a prefix key for this pane. */ | 353 NAME is the pane name. PREFIX_VEC is a prefix key for this pane. */ |
350 | 354 |
355 if (menu_items_used + MENU_ITEMS_PANE_LENGTH > menu_items_allocated) | 359 if (menu_items_used + MENU_ITEMS_PANE_LENGTH > menu_items_allocated) |
356 grow_menu_items (); | 360 grow_menu_items (); |
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 |
366 display. ENABLE if non-nil means this item can be selected. KEY | 370 display. ENABLE if non-nil means this item can be selected. KEY |
367 is the key generated by choosing this item, or nil if this item | 371 is the key generated by choosing this item, or nil if this item |
375 Lisp_Object name, enable, key, def, equiv, type, selected, help; | 379 Lisp_Object name, enable, key, def, equiv, type, selected, help; |
376 { | 380 { |
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, |
391 and generate menu panes for them in menu_items. | 395 and generate menu panes for them in menu_items. |
392 If NOTREAL is nonzero, | 396 If NOTREAL is nonzero, |
448 single_menu_item (XCAR (item), XCDR (item), | 452 single_menu_item (XCAR (item), XCDR (item), |
449 &pending_maps, notreal, maxdepth); | 453 &pending_maps, 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 } |
463 UNGCPRO; | 467 UNGCPRO; |
464 } | 468 } |
502 res = parse_menu_item (item, notreal, 0); | 506 res = parse_menu_item (item, notreal, 0); |
503 UNGCPRO; | 507 UNGCPRO; |
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 { |
511 /* We don't want to make a menu, just traverse the keymaps to | 515 /* We don't want to make a menu, just traverse the keymaps to |
512 precompute equivalent key bindings. */ | 516 precompute equivalent key bindings. */ |
513 if (!NILP (map)) | 517 if (!NILP (map)) |
514 single_keymap_panes (map, Qnil, key, 1, maxdepth - 1); | 518 single_keymap_panes (map, Qnil, key, 1, maxdepth - 1); |
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 { |
523 if (!NILP (enabled)) | 527 if (!NILP (enabled)) |
524 /* An enabled separate pane. Remember this to handle it later. */ | 528 /* An enabled separate pane. Remember this to handle it later. */ |
526 *pending_maps_ptr); | 530 *pending_maps_ptr); |
527 return; | 531 return; |
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))) |
539 { | 543 { |
540 push_submenu_start (); | 544 push_submenu_start (); |
743 if (NILP (title) && !NILP (prompt)) | 747 if (NILP (title) && !NILP (prompt)) |
744 title = prompt; | 748 title = prompt; |
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 } |
752 else if (CONSP (menu) && KEYMAPP (XCAR (menu))) | 756 else if (CONSP (menu) && KEYMAPP (XCAR (menu))) |
753 { | 757 { |
775 /* Extract the detailed info to make one pane. */ | 779 /* Extract the detailed info to make one pane. */ |
776 keymap_panes (maps, nmaps, NILP (position)); | 780 keymap_panes (maps, nmaps, NILP (position)); |
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 } |
784 else | 788 else |
785 { | 789 { |
798 UNGCPRO; | 802 UNGCPRO; |
799 return Qnil; | 803 return Qnil; |
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 |
806 selection = w32_menu_show (f, xpos, ypos, for_click, | 820 selection = w32_menu_show (f, xpos, ypos, for_click, |
807 keymaps, title, &error_name); | 821 keymaps, title, &error_name); |
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; |
817 } | 831 } |
818 | 832 |
979 vector = f->menu_bar_vector; | 993 vector = f->menu_bar_vector; |
980 prefix = Qnil; | 994 prefix = Qnil; |
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) |
1006 { | 1020 { |
1007 int j; | 1021 int j; |
1073 void | 1087 void |
1074 free_menubar_widget_value_tree (wv) | 1088 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)) |
1082 { | 1096 { |
1083 free_menubar_widget_value_tree (wv->contents); | 1097 free_menubar_widget_value_tree (wv->contents); |
1091 BLOCK_INPUT; | 1105 BLOCK_INPUT; |
1092 free_widget_value (wv); | 1106 free_widget_value (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 |
1100 static widget_value * | 1114 static int |
1101 single_submenu (item_key, item_name, maps) | 1115 parse_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); |
1115 len = XINT (length); | 1125 len = XINT (length); |
1116 | 1126 |
1119 for (i = 0; i < len; i++) | 1129 for (i = 0; i < len; i++) |
1120 { | 1130 { |
1121 mapvec[i] = Fcar (maps); | 1131 mapvec[i] = Fcar (maps); |
1122 maps = Fcdr (maps); | 1132 maps = Fcdr (maps); |
1123 } | 1133 } |
1124 | |
1125 menu_items_n_panes = 0; | |
1126 | 1134 |
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++) |
1130 { | 1138 { |
1139 Qnil, Qnil, Qnil, Qnil); | 1147 Qnil, Qnil, Qnil, Qnil); |
1140 } | 1148 } |
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 } |
1144 | 1152 |
1145 /* Create a tree of widget_value objects | 1153 return top_level_items; |
1146 representing the panes and their items. */ | 1154 } |
1155 | |
1156 | |
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 | |
1161 static widget_value * | |
1162 digest_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 *)); |
1150 wv = xmalloc_widget_value (); | 1172 wv = xmalloc_widget_value (); |
1151 wv->name = "menu"; | 1173 wv->name = "menu"; |
1159 | 1181 |
1160 /* Loop over all panes and items made during this call | 1182 /* Loop over all panes and items made during this call |
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) |
1204 ? "" : (char *) SDATA (pane_name)); | 1226 ? "" : (char *) SDATA (pane_name)); |
1205 /* If there is just one top-level pane, put all its items directly | 1227 /* If there is just one top-level pane, put all its items directly |
1247 | 1269 |
1248 #ifndef HAVE_MULTILINGUAL_MENU | 1270 #ifndef HAVE_MULTILINGUAL_MENU |
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 |
1262 wv = xmalloc_widget_value (); | 1284 wv = xmalloc_widget_value (); |
1263 if (prev_wv) | 1285 if (prev_wv) |
1318 int deep_p; | 1340 int deep_p; |
1319 { | 1341 { |
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) |
1327 return; | 1351 return; |
1328 | 1352 |
1330 | 1354 |
1331 if (! menubar_widget) | 1355 if (! menubar_widget) |
1332 deep_p = 1; | 1356 deep_p = 1; |
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 | |
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 | 1359 |
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. */ |
1347 | 1363 |
1382 safe_run_hooks (Qmenu_bar_update_hook); | 1398 safe_run_hooks (Qmenu_bar_update_hook); |
1383 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f)); | 1399 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f)); |
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 |
1412 first_wv->contents = wv; | 1458 first_wv->contents = wv; |
1413 /* Don't set wv->name here; GC during the loop might relocate it. */ | 1459 /* Don't set wv->name here; GC during the loop might relocate it. */ |
1414 wv->enabled = 1; | 1460 wv->enabled = 1; |
1415 wv->button_type = BUTTON_TYPE_NONE; | 1461 wv->button_type = BUTTON_TYPE_NONE; |
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 |
1424 /* If there has been no change in the Lisp-level contents | 1468 /* If there has been no change in the Lisp-level contents |
1425 of the menu bar, skip redisplaying it. Just exit. */ | 1469 of the menu bar, skip redisplaying it. Just exit. */ |
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 { |
1433 free_menubar_widget_value_tree (first_wv); | 1477 free_menubar_widget_value_tree (first_wv); |
1434 menu_items = Qnil; | 1478 menu_items = Qnil; |
1440 so it's safe to store data from a Lisp_String, as long as | 1484 so it's safe to store data from a Lisp_String, as long as |
1441 local copies are made when the actual menu is created. | 1485 local copies are made when the actual menu is created. |
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); |
1452 wv = wv->next; | 1496 wv = wv->next; |
1453 } | 1497 } |
1459 else | 1503 else |
1460 { | 1504 { |
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 |
1473 wv = xmalloc_widget_value (); | 1525 wv = xmalloc_widget_value (); |
1474 wv->name = (char *) SDATA (string); | 1526 wv->name = (char *) SDATA (string); |
1623 | 1675 |
1624 /* Loop over all panes and items, filling in the tree. */ | 1676 /* Loop over all panes and items, filling in the tree. */ |
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; |
1632 prev_wv = 0; | 1684 prev_wv = 0; |
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; |
1654 char *pane_string; | 1706 char *pane_string; |
1655 pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME); | 1707 pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME); |
1656 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); | 1708 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); |
1657 #ifndef HAVE_MULTILINGUAL_MENU | 1709 #ifndef HAVE_MULTILINGUAL_MENU |
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) |
1665 ? "" : (char *) SDATA (pane_name)); | 1717 ? "" : (char *) SDATA (pane_name)); |
1666 /* If there is just one top-level pane, put all its items directly | 1718 /* If there is just one top-level pane, put all its items directly |
1711 | 1763 |
1712 #ifndef HAVE_MULTILINGUAL_MENU | 1764 #ifndef HAVE_MULTILINGUAL_MENU |
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 |
1725 wv = xmalloc_widget_value (); | 1777 wv = xmalloc_widget_value (); |
1726 if (prev_wv) | 1778 if (prev_wv) |
1816 | 1868 |
1817 prefix = entry = Qnil; | 1869 prefix = entry = Qnil; |
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) |
1849 { | 1899 { |
1850 int j; | 1900 int j; |
1901 /* Create a tree of widget_value objects | 1951 /* Create a tree of widget_value objects |
1902 representing the text label and buttons. */ | 1952 representing the text label and buttons. */ |
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 (); |
1911 prev_wv->value = pane_string; | 1961 prev_wv->value = pane_string; |
1912 if (keymaps && !NILP (prefix)) | 1962 if (keymaps && !NILP (prefix)) |
1922 { | 1972 { |
1923 | 1973 |
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 { |
1935 free_menubar_widget_value_tree (first_wv); | 1984 free_menubar_widget_value_tree (first_wv); |
1936 *error = "Submenu in dialog items"; | 1985 *error = "Submenu in dialog items"; |
1955 prev_wv->next = wv; | 2004 prev_wv->next = wv; |
1956 wv->name = (char *) button_names[nb_buttons]; | 2005 wv->name = (char *) button_names[nb_buttons]; |
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; |
1964 | 2013 |
1965 if (! boundary_seen) | 2014 if (! boundary_seen) |
2025 i = 0; | 2074 i = 0; |
2026 while (i < menu_items_used) | 2075 while (i < menu_items_used) |
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) |
2043 { | 2090 { |
2044 entry = Fcons (entry, Qnil); | 2091 entry = Fcons (entry, Qnil); |
2115 { | 2162 { |
2116 /* Only use MF_OWNERDRAW if GetMenuItemInfo is usable, since | 2163 /* Only use MF_OWNERDRAW if GetMenuItemInfo is usable, since |
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 |
2128 fuFlags = MF_DISABLED; | 2175 fuFlags = MF_DISABLED; |
2129 } | 2176 } |
2275 if ((info.fType & MF_OWNERDRAW) && info.dwItemData) | 2322 if ((info.fType & MF_OWNERDRAW) && info.dwItemData) |
2276 { | 2323 { |
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. */ |
2284 if (info.hSubMenu) | 2331 if (info.hSubMenu) |
2285 w32_free_submenu_strings (info.hSubMenu); | 2332 w32_free_submenu_strings (info.hSubMenu); |