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 |
|
|
322 |
if (menu_items_used + 1 > menu_items_allocated) |
if (menu_items_used + 1 > menu_items_allocated) |
323 |
grow_menu_items (); |
grow_menu_items (); |
324 |
|
|
325 |
XVECTOR (menu_items)->contents[menu_items_used++] = Qnil; |
ASET (menu_items, menu_items_used++, Qnil); |
326 |
menu_items_submenu_depth++; |
menu_items_submenu_depth++; |
327 |
} |
} |
328 |
|
|
334 |
if (menu_items_used + 1 > menu_items_allocated) |
if (menu_items_used + 1 > menu_items_allocated) |
335 |
grow_menu_items (); |
grow_menu_items (); |
336 |
|
|
337 |
XVECTOR (menu_items)->contents[menu_items_used++] = Qlambda; |
ASET (menu_items, menu_items_used++, Qlambda); |
338 |
menu_items_submenu_depth--; |
menu_items_submenu_depth--; |
339 |
} |
} |
340 |
|
|
346 |
if (menu_items_used + 1 > menu_items_allocated) |
if (menu_items_used + 1 > menu_items_allocated) |
347 |
grow_menu_items (); |
grow_menu_items (); |
348 |
|
|
349 |
XVECTOR (menu_items)->contents[menu_items_used++] = Qquote; |
ASET (menu_items, menu_items_used++, Qquote); |
350 |
} |
} |
351 |
|
|
352 |
/* Start a new menu pane in menu_items. |
/* Start a new menu pane in menu_items. |
361 |
|
|
362 |
if (menu_items_submenu_depth == 0) |
if (menu_items_submenu_depth == 0) |
363 |
menu_items_n_panes++; |
menu_items_n_panes++; |
364 |
XVECTOR (menu_items)->contents[menu_items_used++] = Qt; |
ASET (menu_items, menu_items_used++, Qt); |
365 |
XVECTOR (menu_items)->contents[menu_items_used++] = name; |
ASET (menu_items, menu_items_used++, name); |
366 |
XVECTOR (menu_items)->contents[menu_items_used++] = prefix_vec; |
ASET (menu_items, menu_items_used++, prefix_vec); |
367 |
} |
} |
368 |
|
|
369 |
/* 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 |
381 |
if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated) |
if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated) |
382 |
grow_menu_items (); |
grow_menu_items (); |
383 |
|
|
384 |
XVECTOR (menu_items)->contents[menu_items_used++] = name; |
ASET (menu_items, menu_items_used++, name); |
385 |
XVECTOR (menu_items)->contents[menu_items_used++] = enable; |
ASET (menu_items, menu_items_used++, enable); |
386 |
XVECTOR (menu_items)->contents[menu_items_used++] = key; |
ASET (menu_items, menu_items_used++, key); |
387 |
XVECTOR (menu_items)->contents[menu_items_used++] = equiv; |
ASET (menu_items, menu_items_used++, equiv); |
388 |
XVECTOR (menu_items)->contents[menu_items_used++] = def; |
ASET (menu_items, menu_items_used++, def); |
389 |
XVECTOR (menu_items)->contents[menu_items_used++] = type; |
ASET (menu_items, menu_items_used++, type); |
390 |
XVECTOR (menu_items)->contents[menu_items_used++] = selected; |
ASET (menu_items, menu_items_used++, selected); |
391 |
XVECTOR (menu_items)->contents[menu_items_used++] = help; |
ASET (menu_items, menu_items_used++, help); |
392 |
} |
} |
393 |
|
|
394 |
/* Look through KEYMAPS, a vector of keymaps that is NMAPS long, |
/* Look through KEYMAPS, a vector of keymaps that is NMAPS long, |
454 |
else if (VECTORP (item)) |
else if (VECTORP (item)) |
455 |
{ |
{ |
456 |
/* Loop over the char values represented in the vector. */ |
/* Loop over the char values represented in the vector. */ |
457 |
int len = XVECTOR (item)->size; |
int len = ASIZE (item); |
458 |
int c; |
int c; |
459 |
for (c = 0; c < len; c++) |
for (c = 0; c < len; c++) |
460 |
{ |
{ |
461 |
Lisp_Object character; |
Lisp_Object character; |
462 |
XSETFASTINT (character, c); |
XSETFASTINT (character, c); |
463 |
single_menu_item (character, XVECTOR (item)->contents[c], |
single_menu_item (character, AREF (item, c), |
464 |
&pending_maps, notreal, maxdepth); |
&pending_maps, notreal, maxdepth); |
465 |
} |
} |
466 |
} |
} |
508 |
if (!res) |
if (!res) |
509 |
return; /* Not a menu item. */ |
return; /* Not a menu item. */ |
510 |
|
|
511 |
map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP]; |
map = AREF (item_properties, ITEM_PROPERTY_MAP); |
512 |
|
|
513 |
if (notreal) |
if (notreal) |
514 |
{ |
{ |
519 |
return; |
return; |
520 |
} |
} |
521 |
|
|
522 |
enabled = XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE]; |
enabled = AREF (item_properties, ITEM_PROPERTY_ENABLE); |
523 |
item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME]; |
item_string = AREF (item_properties, ITEM_PROPERTY_NAME); |
524 |
|
|
525 |
if (!NILP (map) && SREF (item_string, 0) == '@') |
if (!NILP (map) && SREF (item_string, 0) == '@') |
526 |
{ |
{ |
532 |
} |
} |
533 |
|
|
534 |
push_menu_item (item_string, enabled, key, |
push_menu_item (item_string, enabled, key, |
535 |
XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF], |
AREF (item_properties, ITEM_PROPERTY_DEF), |
536 |
XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ], |
AREF (item_properties, ITEM_PROPERTY_KEYEQ), |
537 |
XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE], |
AREF (item_properties, ITEM_PROPERTY_TYPE), |
538 |
XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED], |
AREF (item_properties, ITEM_PROPERTY_SELECTED), |
539 |
XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]); |
AREF (item_properties, ITEM_PROPERTY_HELP)); |
540 |
|
|
541 |
/* Display a submenu using the toolkit. */ |
/* Display a submenu using the toolkit. */ |
542 |
if (! (NILP (map) || NILP (enabled))) |
if (! (NILP (map) || NILP (enabled))) |
749 |
|
|
750 |
/* Make that be the pane title of the first pane. */ |
/* Make that be the pane title of the first pane. */ |
751 |
if (!NILP (prompt) && menu_items_n_panes >= 0) |
if (!NILP (prompt) && menu_items_n_panes >= 0) |
752 |
XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = prompt; |
ASET (menu_items, MENU_ITEMS_PANE_NAME, prompt); |
753 |
|
|
754 |
keymaps = 1; |
keymaps = 1; |
755 |
} |
} |
781 |
|
|
782 |
/* Make the title be the pane title of the first pane. */ |
/* Make the title be the pane title of the first pane. */ |
783 |
if (!NILP (title) && menu_items_n_panes >= 0) |
if (!NILP (title) && menu_items_n_panes >= 0) |
784 |
XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = title; |
ASET (menu_items, MENU_ITEMS_PANE_NAME, title); |
785 |
|
|
786 |
keymaps = 1; |
keymaps = 1; |
787 |
} |
} |
804 |
} |
} |
805 |
|
|
806 |
#ifdef HAVE_MENUS |
#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 |
|
|
817 |
/* Display them in a menu. */ |
/* Display them in a menu. */ |
818 |
BLOCK_INPUT; |
BLOCK_INPUT; |
819 |
|
|
822 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
823 |
|
|
824 |
discard_menu_items (); |
discard_menu_items (); |
825 |
|
#endif /* HAVE_MENUS */ |
826 |
|
|
827 |
UNGCPRO; |
UNGCPRO; |
|
#endif /* HAVE_MENUS */ |
|
828 |
|
|
829 |
if (error_name) error (error_name); |
if (error_name) error (error_name); |
830 |
return selection; |
return selection; |
995 |
i = 0; |
i = 0; |
996 |
while (i < f->menu_bar_items_used) |
while (i < f->menu_bar_items_used) |
997 |
{ |
{ |
998 |
if (EQ (XVECTOR (vector)->contents[i], Qnil)) |
if (EQ (AREF (vector, i), Qnil)) |
999 |
{ |
{ |
1000 |
subprefix_stack[submenu_depth++] = prefix; |
subprefix_stack[submenu_depth++] = prefix; |
1001 |
prefix = entry; |
prefix = entry; |
1002 |
i++; |
i++; |
1003 |
} |
} |
1004 |
else if (EQ (XVECTOR (vector)->contents[i], Qlambda)) |
else if (EQ (AREF (vector, i), Qlambda)) |
1005 |
{ |
{ |
1006 |
prefix = subprefix_stack[--submenu_depth]; |
prefix = subprefix_stack[--submenu_depth]; |
1007 |
i++; |
i++; |
1008 |
} |
} |
1009 |
else if (EQ (XVECTOR (vector)->contents[i], Qt)) |
else if (EQ (AREF (vector, i), Qt)) |
1010 |
{ |
{ |
1011 |
prefix = XVECTOR (vector)->contents[i + MENU_ITEMS_PANE_PREFIX]; |
prefix = AREF (vector, i + MENU_ITEMS_PANE_PREFIX); |
1012 |
i += MENU_ITEMS_PANE_LENGTH; |
i += MENU_ITEMS_PANE_LENGTH; |
1013 |
} |
} |
1014 |
else |
else |
1015 |
{ |
{ |
1016 |
entry = XVECTOR (vector)->contents[i + MENU_ITEMS_ITEM_VALUE]; |
entry = AREF (vector, i + MENU_ITEMS_ITEM_VALUE); |
1017 |
/* The EMACS_INT cast avoids a warning. There's no problem |
/* The EMACS_INT cast avoids a warning. There's no problem |
1018 |
as long as pointers have enough bits to hold small integers. */ |
as long as pointers have enough bits to hold small integers. */ |
1019 |
if ((int) (EMACS_INT) client_data == i) |
if ((int) (EMACS_INT) client_data == i) |
1089 |
widget_value *wv; |
widget_value *wv; |
1090 |
{ |
{ |
1091 |
if (! wv) return; |
if (! wv) return; |
1092 |
|
|
1093 |
wv->name = wv->value = wv->key = (char *) 0xDEADBEEF; |
wv->name = wv->value = wv->key = (char *) 0xDEADBEEF; |
1094 |
|
|
1095 |
if (wv->contents && (wv->contents != (widget_value*)1)) |
if (wv->contents && (wv->contents != (widget_value*)1)) |
1107 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
1108 |
} |
} |
1109 |
|
|
1110 |
/* Return a tree of widget_value structures for a menu bar item |
/* Set up data i menu_items for a menu bar item |
1111 |
whose event type is ITEM_KEY (with string ITEM_NAME) |
whose event type is ITEM_KEY (with string ITEM_NAME) |
1112 |
and whose contents come from the list of keymaps MAPS. */ |
and whose contents come from the list of keymaps MAPS. */ |
1113 |
|
|
1114 |
static widget_value * |
static int |
1115 |
single_submenu (item_key, item_name, maps) |
parse_single_submenu (item_key, item_name, maps) |
1116 |
Lisp_Object item_key, item_name, maps; |
Lisp_Object item_key, item_name, maps; |
1117 |
{ |
{ |
|
widget_value *wv, *prev_wv, *save_wv, *first_wv; |
|
|
int i; |
|
|
int submenu_depth = 0; |
|
1118 |
Lisp_Object length; |
Lisp_Object length; |
1119 |
int len; |
int len; |
1120 |
Lisp_Object *mapvec; |
Lisp_Object *mapvec; |
1121 |
widget_value **submenu_stack; |
int i; |
|
int previous_items = menu_items_used; |
|
1122 |
int top_level_items = 0; |
int top_level_items = 0; |
1123 |
|
|
1124 |
length = Flength (maps); |
length = Flength (maps); |
1132 |
maps = Fcdr (maps); |
maps = Fcdr (maps); |
1133 |
} |
} |
1134 |
|
|
|
menu_items_n_panes = 0; |
|
|
|
|
1135 |
/* Loop over the given keymaps, making a pane for each map. |
/* Loop over the given keymaps, making a pane for each map. |
1136 |
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. */ |
1137 |
for (i = 0; i < len; i++) |
for (i = 0; i < len; i++) |
1149 |
else |
else |
1150 |
single_keymap_panes (mapvec[i], item_name, item_key, 0, 10); |
single_keymap_panes (mapvec[i], item_name, item_key, 0, 10); |
1151 |
} |
} |
1152 |
|
|
1153 |
|
return top_level_items; |
1154 |
|
} |
1155 |
|
|
1156 |
/* Create a tree of widget_value objects |
|
1157 |
representing the panes and their items. */ |
/* 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; |
1169 |
|
|
1170 |
submenu_stack |
submenu_stack |
1171 |
= (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); |
= (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); |
1183 |
and construct a tree of widget_value objects. |
and construct a tree of widget_value objects. |
1184 |
Ignore the panes and items made by previous calls to |
Ignore the panes and items made by previous calls to |
1185 |
single_submenu, even though those are also in menu_items. */ |
single_submenu, even though those are also in menu_items. */ |
1186 |
i = previous_items; |
i = start; |
1187 |
while (i < menu_items_used) |
while (i < end) |
1188 |
{ |
{ |
1189 |
if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) |
if (EQ (AREF (menu_items, i), Qnil)) |
1190 |
{ |
{ |
1191 |
submenu_stack[submenu_depth++] = save_wv; |
submenu_stack[submenu_depth++] = save_wv; |
1192 |
save_wv = prev_wv; |
save_wv = prev_wv; |
1193 |
prev_wv = 0; |
prev_wv = 0; |
1194 |
i++; |
i++; |
1195 |
} |
} |
1196 |
else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda)) |
else if (EQ (AREF (menu_items, i), Qlambda)) |
1197 |
{ |
{ |
1198 |
prev_wv = save_wv; |
prev_wv = save_wv; |
1199 |
save_wv = submenu_stack[--submenu_depth]; |
save_wv = submenu_stack[--submenu_depth]; |
1200 |
i++; |
i++; |
1201 |
} |
} |
1202 |
else if (EQ (XVECTOR (menu_items)->contents[i], Qt) |
else if (EQ (AREF (menu_items, i), Qt) |
1203 |
&& submenu_depth != 0) |
&& submenu_depth != 0) |
1204 |
i += MENU_ITEMS_PANE_LENGTH; |
i += MENU_ITEMS_PANE_LENGTH; |
1205 |
/* Ignore a nil in the item list. |
/* Ignore a nil in the item list. |
1206 |
It's meaningful only for dialog boxes. */ |
It's meaningful only for dialog boxes. */ |
1207 |
else if (EQ (XVECTOR (menu_items)->contents[i], Qquote)) |
else if (EQ (AREF (menu_items, i), Qquote)) |
1208 |
i += 1; |
i += 1; |
1209 |
else if (EQ (XVECTOR (menu_items)->contents[i], Qt)) |
else if (EQ (AREF (menu_items, i), Qt)) |
1210 |
{ |
{ |
1211 |
/* Create a new pane. */ |
/* Create a new pane. */ |
1212 |
Lisp_Object pane_name, prefix; |
Lisp_Object pane_name, prefix; |
1213 |
char *pane_string; |
char *pane_string; |
1214 |
|
|
1215 |
pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME]; |
pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME); |
1216 |
prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; |
prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); |
1217 |
|
|
1218 |
#ifndef HAVE_MULTILINGUAL_MENU |
#ifndef HAVE_MULTILINGUAL_MENU |
1219 |
if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) |
if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) |
1220 |
{ |
{ |
1221 |
pane_name = ENCODE_SYSTEM (pane_name); |
pane_name = ENCODE_SYSTEM (pane_name); |
1222 |
AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name; |
ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name); |
1223 |
} |
} |
1224 |
#endif |
#endif |
1225 |
pane_string = (NILP (pane_name) |
pane_string = (NILP (pane_name) |
1271 |
if (STRING_MULTIBYTE (item_name)) |
if (STRING_MULTIBYTE (item_name)) |
1272 |
{ |
{ |
1273 |
item_name = ENCODE_SYSTEM (item_name); |
item_name = ENCODE_SYSTEM (item_name); |
1274 |
AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; |
ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name); |
1275 |
} |
} |
1276 |
|
|
1277 |
if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) |
if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) |
1278 |
{ |
{ |
1279 |
descrip = ENCODE_SYSTEM (descrip); |
descrip = ENCODE_SYSTEM (descrip); |
1280 |
AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; |
ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip); |
1281 |
} |
} |
1282 |
#endif /* not HAVE_MULTILINGUAL_MENU */ |
#endif /* not HAVE_MULTILINGUAL_MENU */ |
1283 |
|
|
1342 |
HMENU menubar_widget = f->output_data.w32->menubar_widget; |
HMENU menubar_widget = f->output_data.w32->menubar_widget; |
1343 |
Lisp_Object items; |
Lisp_Object items; |
1344 |
widget_value *wv, *first_wv, *prev_wv = 0; |
widget_value *wv, *first_wv, *prev_wv = 0; |
1345 |
int i; |
int i, last_i; |
1346 |
|
int *submenu_start, *submenu_end; |
1347 |
|
int *submenu_top_level_items; |
1348 |
|
|
1349 |
/* We must not change the menubar when actually in use. */ |
/* We must not change the menubar when actually in use. */ |
1350 |
if (f->output_data.w32->menubar_active) |
if (f->output_data.w32->menubar_active) |
1357 |
else if (pending_menu_activation && !deep_p) |
else if (pending_menu_activation && !deep_p) |
1358 |
deep_p = 1; |
deep_p = 1; |
1359 |
|
|
|
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; |
|
|
|
|
1360 |
if (deep_p) |
if (deep_p) |
1361 |
{ |
{ |
1362 |
/* Make a widget-value tree representing the entire menu trees. */ |
/* Make a widget-value tree representing the entire menu trees. */ |
1400 |
|
|
1401 |
items = FRAME_MENU_BAR_ITEMS (f); |
items = FRAME_MENU_BAR_ITEMS (f); |
1402 |
|
|
|
inhibit_garbage_collection (); |
|
|
|
|
1403 |
/* Save the frame's previous menu bar contents data. */ |
/* Save the frame's previous menu bar contents data. */ |
1404 |
if (previous_menu_items_used) |
if (previous_menu_items_used) |
1405 |
bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, |
bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, |
1406 |
previous_menu_items_used * sizeof (Lisp_Object)); |
previous_menu_items_used * sizeof (Lisp_Object)); |
1407 |
|
|
1408 |
/* Fill in the current menu bar contents. */ |
/* Fill in menu_items with the current menu bar contents. |
1409 |
|
This can evaluate Lisp code. */ |
1410 |
menu_items = f->menu_bar_vector; |
menu_items = f->menu_bar_vector; |
1411 |
menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; |
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 *)); |
1416 |
init_menu_items (); |
init_menu_items (); |
1417 |
for (i = 0; i < XVECTOR (items)->size; i += 4) |
for (i = 0; i < ASIZE (items); i += 4) |
1418 |
{ |
{ |
1419 |
Lisp_Object key, string, maps; |
Lisp_Object key, string, maps; |
1420 |
|
|
1421 |
key = XVECTOR (items)->contents[i]; |
last_i = i; |
1422 |
string = XVECTOR (items)->contents[i + 1]; |
|
1423 |
maps = XVECTOR (items)->contents[i + 2]; |
key = AREF (items, i); |
1424 |
|
string = AREF (items, i + 1); |
1425 |
|
maps = AREF (items, i + 2); |
1426 |
if (NILP (string)) |
if (NILP (string)) |
1427 |
break; |
break; |
1428 |
|
|
1429 |
wv = single_submenu (key, string, maps); |
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]); |
1455 |
if (prev_wv) |
if (prev_wv) |
1456 |
prev_wv->next = wv; |
prev_wv->next = wv; |
1457 |
else |
else |
1462 |
prev_wv = wv; |
prev_wv = wv; |
1463 |
} |
} |
1464 |
|
|
|
finish_menu_items (); |
|
|
|
|
1465 |
set_buffer_internal_1 (prev); |
set_buffer_internal_1 (prev); |
1466 |
unbind_to (specpdl_count, Qnil); |
unbind_to (specpdl_count, Qnil); |
1467 |
|
|
1470 |
|
|
1471 |
for (i = 0; i < previous_menu_items_used; i++) |
for (i = 0; i < previous_menu_items_used; i++) |
1472 |
if (menu_items_used == i |
if (menu_items_used == i |
1473 |
|| (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i]))) |
|| (!EQ (previous_items[i], AREF (menu_items, i)))) |
1474 |
break; |
break; |
1475 |
if (i == menu_items_used && i == previous_menu_items_used && i != 0) |
if (i == menu_items_used && i == previous_menu_items_used && i != 0) |
1476 |
{ |
{ |
1486 |
Windows takes care of this for normal string items, but |
Windows takes care of this for normal string items, but |
1487 |
not for owner-drawn items or additional item-info. */ |
not for owner-drawn items or additional item-info. */ |
1488 |
wv = first_wv->contents; |
wv = first_wv->contents; |
1489 |
for (i = 0; i < XVECTOR (items)->size; i += 4) |
for (i = 0; i < ASIZE (items); i += 4) |
1490 |
{ |
{ |
1491 |
Lisp_Object string; |
Lisp_Object string; |
1492 |
string = XVECTOR (items)->contents[i + 1]; |
string = AREF (items, i + 1); |
1493 |
if (NILP (string)) |
if (NILP (string)) |
1494 |
break; |
break; |
1495 |
wv->name = (char *) SDATA (string); |
wv->name = (char *) SDATA (string); |
1505 |
/* Make a widget-value tree containing |
/* Make a widget-value tree containing |
1506 |
just the top level menu bar strings. */ |
just the top level menu bar strings. */ |
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 |
|
|
1516 |
items = FRAME_MENU_BAR_ITEMS (f); |
items = FRAME_MENU_BAR_ITEMS (f); |
1517 |
for (i = 0; i < XVECTOR (items)->size; i += 4) |
for (i = 0; i < ASIZE (items); i += 4) |
1518 |
{ |
{ |
1519 |
Lisp_Object string; |
Lisp_Object string; |
1520 |
|
|
1521 |
string = XVECTOR (items)->contents[i + 1]; |
string = AREF (items, i + 1); |
1522 |
if (NILP (string)) |
if (NILP (string)) |
1523 |
break; |
break; |
1524 |
|
|
1677 |
i = 0; |
i = 0; |
1678 |
while (i < menu_items_used) |
while (i < menu_items_used) |
1679 |
{ |
{ |
1680 |
if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) |
if (EQ (AREF (menu_items, i), Qnil)) |
1681 |
{ |
{ |
1682 |
submenu_stack[submenu_depth++] = save_wv; |
submenu_stack[submenu_depth++] = save_wv; |
1683 |
save_wv = prev_wv; |
save_wv = prev_wv; |
1685 |
first_pane = 1; |
first_pane = 1; |
1686 |
i++; |
i++; |
1687 |
} |
} |
1688 |
else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda)) |
else if (EQ (AREF (menu_items, i), Qlambda)) |
1689 |
{ |
{ |
1690 |
prev_wv = save_wv; |
prev_wv = save_wv; |
1691 |
save_wv = submenu_stack[--submenu_depth]; |
save_wv = submenu_stack[--submenu_depth]; |
1692 |
first_pane = 0; |
first_pane = 0; |
1693 |
i++; |
i++; |
1694 |
} |
} |
1695 |
else if (EQ (XVECTOR (menu_items)->contents[i], Qt) |
else if (EQ (AREF (menu_items, i), Qt) |
1696 |
&& submenu_depth != 0) |
&& submenu_depth != 0) |
1697 |
i += MENU_ITEMS_PANE_LENGTH; |
i += MENU_ITEMS_PANE_LENGTH; |
1698 |
/* Ignore a nil in the item list. |
/* Ignore a nil in the item list. |
1699 |
It's meaningful only for dialog boxes. */ |
It's meaningful only for dialog boxes. */ |
1700 |
else if (EQ (XVECTOR (menu_items)->contents[i], Qquote)) |
else if (EQ (AREF (menu_items, i), Qquote)) |
1701 |
i += 1; |
i += 1; |
1702 |
else if (EQ (XVECTOR (menu_items)->contents[i], Qt)) |
else if (EQ (AREF (menu_items, i), Qt)) |
1703 |
{ |
{ |
1704 |
/* Create a new pane. */ |
/* Create a new pane. */ |
1705 |
Lisp_Object pane_name, prefix; |
Lisp_Object pane_name, prefix; |
1710 |
if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) |
if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) |
1711 |
{ |
{ |
1712 |
pane_name = ENCODE_SYSTEM (pane_name); |
pane_name = ENCODE_SYSTEM (pane_name); |
1713 |
AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name; |
ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name); |
1714 |
} |
} |
1715 |
#endif |
#endif |
1716 |
pane_string = (NILP (pane_name) |
pane_string = (NILP (pane_name) |
1765 |
if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) |
if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) |
1766 |
{ |
{ |
1767 |
item_name = ENCODE_SYSTEM (item_name); |
item_name = ENCODE_SYSTEM (item_name); |
1768 |
AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; |
ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name); |
1769 |
} |
} |
1770 |
if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) |
if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) |
1771 |
{ |
{ |
1772 |
descrip = ENCODE_SYSTEM (descrip); |
descrip = ENCODE_SYSTEM (descrip); |
1773 |
AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; |
ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip); |
1774 |
} |
} |
1775 |
#endif /* not HAVE_MULTILINGUAL_MENU */ |
#endif /* not HAVE_MULTILINGUAL_MENU */ |
1776 |
|
|
1870 |
i = 0; |
i = 0; |
1871 |
while (i < menu_items_used) |
while (i < menu_items_used) |
1872 |
{ |
{ |
1873 |
if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) |
if (EQ (AREF (menu_items, i), Qnil)) |
1874 |
{ |
{ |
1875 |
subprefix_stack[submenu_depth++] = prefix; |
subprefix_stack[submenu_depth++] = prefix; |
1876 |
prefix = entry; |
prefix = entry; |
1877 |
i++; |
i++; |
1878 |
} |
} |
1879 |
else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda)) |
else if (EQ (AREF (menu_items, i), Qlambda)) |
1880 |
{ |
{ |
1881 |
prefix = subprefix_stack[--submenu_depth]; |
prefix = subprefix_stack[--submenu_depth]; |
1882 |
i++; |
i++; |
1883 |
} |
} |
1884 |
else if (EQ (XVECTOR (menu_items)->contents[i], Qt)) |
else if (EQ (AREF (menu_items, i), Qt)) |
1885 |
{ |
{ |
1886 |
prefix |
prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); |
|
= XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; |
|
1887 |
i += MENU_ITEMS_PANE_LENGTH; |
i += MENU_ITEMS_PANE_LENGTH; |
1888 |
} |
} |
1889 |
/* Ignore a nil in the item list. |
/* Ignore a nil in the item list. |
1890 |
It's meaningful only for dialog boxes. */ |
It's meaningful only for dialog boxes. */ |
1891 |
else if (EQ (XVECTOR (menu_items)->contents[i], Qquote)) |
else if (EQ (AREF (menu_items, i), Qquote)) |
1892 |
i += 1; |
i += 1; |
1893 |
else |
else |
1894 |
{ |
{ |
1895 |
entry |
entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE); |
|
= XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE]; |
|
1896 |
if (menu_item_selection == i) |
if (menu_item_selection == i) |
1897 |
{ |
{ |
1898 |
if (keymaps != 0) |
if (keymaps != 0) |
1953 |
{ |
{ |
1954 |
Lisp_Object pane_name, prefix; |
Lisp_Object pane_name, prefix; |
1955 |
char *pane_string; |
char *pane_string; |
1956 |
pane_name = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME]; |
pane_name = AREF (menu_items, MENU_ITEMS_PANE_NAME); |
1957 |
prefix = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_PREFIX]; |
prefix = AREF (menu_items, MENU_ITEMS_PANE_PREFIX); |
1958 |
pane_string = (NILP (pane_name) |
pane_string = (NILP (pane_name) |
1959 |
? "" : (char *) SDATA (pane_name)); |
? "" : (char *) SDATA (pane_name)); |
1960 |
prev_wv = xmalloc_widget_value (); |
prev_wv = xmalloc_widget_value (); |
1974 |
/* Create a new item within current pane. */ |
/* Create a new item within current pane. */ |
1975 |
Lisp_Object item_name, enable, descrip, help; |
Lisp_Object item_name, enable, descrip, help; |
1976 |
|
|
1977 |
item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME]; |
item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); |
1978 |
enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; |
enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); |
1979 |
descrip |
descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY); |
1980 |
= XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; |
help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP); |
|
help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP]; |
|
1981 |
|
|
1982 |
if (NILP (item_name)) |
if (NILP (item_name)) |
1983 |
{ |
{ |
2006 |
if (!NILP (descrip)) |
if (!NILP (descrip)) |
2007 |
wv->key = (char *) SDATA (descrip); |
wv->key = (char *) SDATA (descrip); |
2008 |
wv->value = (char *) SDATA (item_name); |
wv->value = (char *) SDATA (item_name); |
2009 |
wv->call_data = (void *) &XVECTOR (menu_items)->contents[i]; |
wv->call_data = (void *) &AREF (menu_items, i); |
2010 |
wv->enabled = !NILP (enable); |
wv->enabled = !NILP (enable); |
2011 |
wv->help = Qnil; |
wv->help = Qnil; |
2012 |
prev_wv = wv; |
prev_wv = wv; |
2076 |
{ |
{ |
2077 |
Lisp_Object entry; |
Lisp_Object entry; |
2078 |
|
|
2079 |
if (EQ (XVECTOR (menu_items)->contents[i], Qt)) |
if (EQ (AREF (menu_items, i), Qt)) |
2080 |
{ |
{ |
2081 |
prefix |
prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); |
|
= XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; |
|
2082 |
i += MENU_ITEMS_PANE_LENGTH; |
i += MENU_ITEMS_PANE_LENGTH; |
2083 |
} |
} |
2084 |
else |
else |
2085 |
{ |
{ |
2086 |
entry |
entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE); |
|
= XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE]; |
|
2087 |
if (menu_item_selection == i) |
if (menu_item_selection == i) |
2088 |
{ |
{ |
2089 |
if (keymaps != 0) |
if (keymaps != 0) |
2164 |
we can't deallocate the memory otherwise. */ |
we can't deallocate the memory otherwise. */ |
2165 |
if (get_menu_item_info) |
if (get_menu_item_info) |
2166 |
{ |
{ |
2167 |
out_string = (char *) LocalAlloc (LPTR, strlen (wv->name) + 1); |
out_string = (char *) local_alloc (strlen (wv->name) + 1); |
2168 |
|
strcpy (out_string, wv->name); |
2169 |
#ifdef MENU_DEBUG |
#ifdef MENU_DEBUG |
2170 |
DebPrint ("Menu: allocing %ld for owner-draw", info.dwItemData); |
DebPrint ("Menu: allocing %ld for owner-draw", out_string); |
2171 |
#endif |
#endif |
|
strcpy (out_string, wv->name); |
|
2172 |
fuFlags = MF_OWNERDRAW | MF_DISABLED; |
fuFlags = MF_OWNERDRAW | MF_DISABLED; |
2173 |
} |
} |
2174 |
else |
else |
2324 |
#ifdef MENU_DEBUG |
#ifdef MENU_DEBUG |
2325 |
DebPrint ("Menu: freeing %ld for owner-draw", info.dwItemData); |
DebPrint ("Menu: freeing %ld for owner-draw", info.dwItemData); |
2326 |
#endif |
#endif |
2327 |
LocalFree (info.dwItemData); |
local_free (info.dwItemData); |
2328 |
} |
} |
2329 |
|
|
2330 |
/* Recurse down submenus. */ |
/* Recurse down submenus. */ |