90 |
typedef struct _widget_value |
typedef struct _widget_value |
91 |
{ |
{ |
92 |
/* name of widget */ |
/* name of widget */ |
93 |
|
Lisp_Object lname; |
94 |
char* name; |
char* name; |
95 |
/* value (meaning depend on widget type) */ |
/* value (meaning depend on widget type) */ |
96 |
char* value; |
char* value; |
97 |
/* keyboard equivalent. no implications for XtTranslations */ |
/* keyboard equivalent. no implications for XtTranslations */ |
98 |
|
Lisp_Object lkey; |
99 |
char* key; |
char* key; |
100 |
/* Help string or nil if none. |
/* Help string or nil if none. |
101 |
GC finds this string through the frame's menu_bar_vector |
GC finds this string through the frame's menu_bar_vector |
165 |
|
|
166 |
extern Lisp_Object Qmenu_bar_update_hook; |
extern Lisp_Object Qmenu_bar_update_hook; |
167 |
|
|
168 |
|
#if TARGET_API_MAC_CARBON |
169 |
|
#define ENCODE_MENU_STRING(str) ENCODE_UTF_8 (str) |
170 |
|
#else |
171 |
|
#define ENCODE_MENU_STRING(str) ENCODE_SYSTEM (str) |
172 |
|
#endif |
173 |
|
|
174 |
void set_frame_menubar (); |
void set_frame_menubar (); |
175 |
|
|
176 |
static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, |
static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, |
1223 |
save_wv->next = wv; |
save_wv->next = wv; |
1224 |
else |
else |
1225 |
first_wv->contents = wv; |
first_wv->contents = wv; |
1226 |
wv->name = pane_string; |
wv->lname = pane_name; |
1227 |
/* Ignore the @ that means "separate pane". |
/* Set value to 1 so update_submenu_strings can handle '@' */ |
1228 |
This is a kludge, but this isn't worth more time. */ |
wv->value = (char *)1; |
|
if (!NILP (prefix) && wv->name[0] == '@') |
|
|
wv->name++; |
|
|
wv->value = 0; |
|
1229 |
wv->enabled = 1; |
wv->enabled = 1; |
1230 |
wv->button_type = BUTTON_TYPE_NONE; |
wv->button_type = BUTTON_TYPE_NONE; |
1231 |
wv->help = Qnil; |
wv->help = Qnil; |
1251 |
#ifndef HAVE_MULTILINGUAL_MENU |
#ifndef HAVE_MULTILINGUAL_MENU |
1252 |
if (STRING_MULTIBYTE (item_name)) |
if (STRING_MULTIBYTE (item_name)) |
1253 |
{ |
{ |
1254 |
item_name = ENCODE_SYSTEM (item_name); |
item_name = ENCODE_MENU_STRING (item_name); |
1255 |
AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; |
AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; |
1256 |
} |
} |
1257 |
|
|
1258 |
if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) |
if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) |
1259 |
{ |
{ |
1260 |
descrip = ENCODE_SYSTEM (descrip); |
descrip = ENCODE_MENU_STRING (descrip); |
1261 |
AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; |
AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; |
1262 |
} |
} |
1263 |
#endif /* not HAVE_MULTILINGUAL_MENU */ |
#endif /* not HAVE_MULTILINGUAL_MENU */ |
1268 |
else |
else |
1269 |
save_wv->contents = wv; |
save_wv->contents = wv; |
1270 |
|
|
1271 |
wv->name = (char *) SDATA (item_name); |
wv->lname = item_name; |
1272 |
if (!NILP (descrip)) |
if (!NILP (descrip)) |
1273 |
wv->key = (char *) SDATA (descrip); |
wv->lkey = descrip; |
1274 |
wv->value = 0; |
wv->value = 0; |
1275 |
/* The EMACS_INT cast avoids a warning. There's no problem |
/* The EMACS_INT cast avoids a warning. There's no problem |
1276 |
as long as pointers have enough bits to hold small integers. */ |
as long as pointers have enough bits to hold small integers. */ |
1309 |
|
|
1310 |
return first_wv; |
return first_wv; |
1311 |
} |
} |
1312 |
|
/* Walk through the widget_value tree starting at FIRST_WV and update |
1313 |
|
the char * pointers from the corresponding lisp values. |
1314 |
|
We do this after building the whole tree, since GC may happen while the |
1315 |
|
tree is constructed, and small strings are relocated. So we must wait |
1316 |
|
until no GC can happen before storing pointers into lisp values. */ |
1317 |
|
static void |
1318 |
|
update_submenu_strings (first_wv) |
1319 |
|
widget_value *first_wv; |
1320 |
|
{ |
1321 |
|
widget_value *wv; |
1322 |
|
|
1323 |
|
for (wv = first_wv; wv; wv = wv->next) |
1324 |
|
{ |
1325 |
|
if (wv->lname && ! NILP (wv->lname)) |
1326 |
|
{ |
1327 |
|
wv->name = SDATA (wv->lname); |
1328 |
|
|
1329 |
|
/* Ignore the @ that means "separate pane". |
1330 |
|
This is a kludge, but this isn't worth more time. */ |
1331 |
|
if (wv->value == (char *)1) |
1332 |
|
{ |
1333 |
|
if (wv->name[0] == '@') |
1334 |
|
wv->name++; |
1335 |
|
wv->value = 0; |
1336 |
|
} |
1337 |
|
} |
1338 |
|
|
1339 |
|
if (wv->lkey && ! NILP (wv->lkey)) |
1340 |
|
wv->key = SDATA (wv->lkey); |
1341 |
|
|
1342 |
|
if (wv->contents) |
1343 |
|
update_submenu_strings (wv->contents); |
1344 |
|
} |
1345 |
|
} |
1346 |
|
|
1347 |
|
|
1348 |
/* Set the contents of the menubar widgets of frame F. |
/* Set the contents of the menubar widgets of frame F. |
1349 |
The argument FIRST_TIME is currently ignored; |
The argument FIRST_TIME is currently ignored; |
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, |
1486 |
if (NILP (string)) |
if (NILP (string)) |
1487 |
break; |
break; |
1488 |
wv->name = (char *) SDATA (string); |
wv->name = (char *) SDATA (string); |
1489 |
|
update_submenu_strings (wv->contents); |
1490 |
wv = wv->next; |
wv = wv->next; |
1491 |
} |
} |
1492 |
|
|
1744 |
#ifndef HAVE_MULTILINGUAL_MENU |
#ifndef HAVE_MULTILINGUAL_MENU |
1745 |
if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) |
if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) |
1746 |
{ |
{ |
1747 |
item_name = ENCODE_SYSTEM (item_name); |
item_name = ENCODE_MENU_STRING (item_name); |
1748 |
AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; |
AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; |
1749 |
} |
} |
1750 |
if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) |
if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) |
1751 |
{ |
{ |
1752 |
descrip = ENCODE_SYSTEM (descrip); |
descrip = ENCODE_MENU_STRING (descrip); |
1753 |
AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; |
AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; |
1754 |
} |
} |
1755 |
#endif /* not HAVE_MULTILINGUAL_MENU */ |
#endif /* not HAVE_MULTILINGUAL_MENU */ |
1803 |
|
|
1804 |
#ifndef HAVE_MULTILINGUAL_MENU |
#ifndef HAVE_MULTILINGUAL_MENU |
1805 |
if (STRING_MULTIBYTE (title)) |
if (STRING_MULTIBYTE (title)) |
1806 |
title = ENCODE_SYSTEM (title); |
title = ENCODE_MENU_STRING (title); |
1807 |
#endif |
#endif |
1808 |
wv_title->name = (char *) SDATA (title); |
wv_title->name = (char *) SDATA (title); |
1809 |
wv_title->enabled = TRUE; |
wv_title->enabled = TRUE; |
1840 |
/* Get the refcon to find the correct item*/ |
/* Get the refcon to find the correct item*/ |
1841 |
if (menu_item_selection) |
if (menu_item_selection) |
1842 |
{ |
{ |
1843 |
menu = GetMenuHandle (HiWord (menu_item_choice)); |
MenuHandle sel_menu = GetMenuHandle (HiWord (menu_item_choice)); |
1844 |
if (menu) { |
if (sel_menu) { |
1845 |
GetMenuItemRefCon (menu, menu_item_selection, &refcon); |
GetMenuItemRefCon (sel_menu, menu_item_selection, &refcon); |
1846 |
} |
} |
1847 |
} |
} |
1848 |
|
|
1852 |
discard_mouse_events (); |
discard_mouse_events (); |
1853 |
#endif |
#endif |
1854 |
|
|
1855 |
|
/* Must reset this manually because the button release event is not |
1856 |
|
passed to Emacs event loop. */ |
1857 |
|
FRAME_MAC_DISPLAY_INFO (f)->grabbed = 0; |
1858 |
|
|
1859 |
/* Free the widget_value objects we used to specify the |
/* Free the widget_value objects we used to specify the |
1860 |
contents. */ |
contents. */ |
1861 |
free_menubar_widget_value_tree (first_wv); |
free_menubar_widget_value_tree (first_wv); |
1864 |
{ |
{ |
1865 |
int i = MIN_POPUP_SUBMENU_ID; |
int i = MIN_POPUP_SUBMENU_ID; |
1866 |
MenuHandle submenu = GetMenuHandle (i); |
MenuHandle submenu = GetMenuHandle (i); |
1867 |
while (menu != NULL) |
while (submenu != NULL) |
1868 |
{ |
{ |
1869 |
DeleteMenu (i); |
DeleteMenu (i); |
1870 |
DisposeMenu (menu); |
DisposeMenu (submenu); |
1871 |
menu = GetMenuHandle (++i); |
submenu = GetMenuHandle (++i); |
1872 |
} |
} |
1873 |
} |
} |
1874 |
|
|
2240 |
int force_disable) |
int force_disable) |
2241 |
{ |
{ |
2242 |
Str255 item_name; |
Str255 item_name; |
2243 |
int pos, i; |
int pos; |
2244 |
|
|
2245 |
if (name_is_separator (wv->name)) |
if (name_is_separator (wv->name)) |
2246 |
AppendMenu (menu, "\p-"); |
AppendMenu (menu, "\p-"); |
2262 |
strncat (item_name, wv->key, 255); |
strncat (item_name, wv->key, 255); |
2263 |
} |
} |
2264 |
item_name[255] = 0; |
item_name[255] = 0; |
2265 |
|
#if TARGET_API_MAC_CARBON |
2266 |
|
{ |
2267 |
|
CFStringRef string = |
2268 |
|
CFStringCreateWithCString (NULL, item_name, kCFStringEncodingUTF8); |
2269 |
|
|
2270 |
|
SetMenuItemTextWithCFString (menu, pos, string); |
2271 |
|
CFRelease (string); |
2272 |
|
} |
2273 |
|
#else |
2274 |
c2pstr (item_name); |
c2pstr (item_name); |
2275 |
SetMenuItemText (menu, pos, item_name); |
SetMenuItemText (menu, pos, item_name); |
2276 |
|
#endif |
2277 |
|
|
2278 |
if (wv->enabled && !force_disable) |
if (wv->enabled && !force_disable) |
2279 |
#if TARGET_API_MAC_CARBON |
#if TARGET_API_MAC_CARBON |
2296 |
else |
else |
2297 |
SetItemMark (menu, pos, noMark); |
SetItemMark (menu, pos, noMark); |
2298 |
} |
} |
|
} |
|
2299 |
|
|
2300 |
SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data); |
SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data); |
2301 |
|
} |
2302 |
|
|
2303 |
if (submenu != NULL) |
if (submenu != NULL) |
2304 |
SetMenuItemHierarchicalID (menu, pos, submenu); |
SetMenuItemHierarchicalID (menu, pos, submenu); |