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