aboutsummaryrefslogtreecommitdiffstats
path: root/src/macmenu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/macmenu.c')
-rw-r--r--src/macmenu.c95
1 files changed, 74 insertions, 21 deletions
diff --git a/src/macmenu.c b/src/macmenu.c
index d205ee3b877..88012b01f73 100644
--- a/src/macmenu.c
+++ b/src/macmenu.c
@@ -90,10 +90,12 @@ enum button_type
90typedef struct _widget_value 90typedef struct _widget_value
91{ 91{
92 /* name of widget */ 92 /* name of widget */
93 Lisp_Object lname;
93 char* name; 94 char* name;
94 /* value (meaning depend on widget type) */ 95 /* value (meaning depend on widget type) */
95 char* value; 96 char* value;
96 /* keyboard equivalent. no implications for XtTranslations */ 97 /* keyboard equivalent. no implications for XtTranslations */
98 Lisp_Object lkey;
97 char* key; 99 char* key;
98 /* Help string or nil if none. 100 /* Help string or nil if none.
99 GC finds this string through the frame's menu_bar_vector 101 GC finds this string through the frame's menu_bar_vector
@@ -163,6 +165,12 @@ extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
163 165
164extern Lisp_Object Qmenu_bar_update_hook; 166extern Lisp_Object Qmenu_bar_update_hook;
165 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
166void set_frame_menubar (); 174void set_frame_menubar ();
167 175
168static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, 176static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
@@ -1215,12 +1223,9 @@ single_submenu (item_key, item_name, maps)
1215 save_wv->next = wv; 1223 save_wv->next = wv;
1216 else 1224 else
1217 first_wv->contents = wv; 1225 first_wv->contents = wv;
1218 wv->name = pane_string; 1226 wv->lname = pane_name;
1219 /* Ignore the @ that means "separate pane". 1227 /* Set value to 1 so update_submenu_strings can handle '@' */
1220 This is a kludge, but this isn't worth more time. */ 1228 wv->value = (char *)1;
1221 if (!NILP (prefix) && wv->name[0] == '@')
1222 wv->name++;
1223 wv->value = 0;
1224 wv->enabled = 1; 1229 wv->enabled = 1;
1225 wv->button_type = BUTTON_TYPE_NONE; 1230 wv->button_type = BUTTON_TYPE_NONE;
1226 wv->help = Qnil; 1231 wv->help = Qnil;
@@ -1246,13 +1251,13 @@ single_submenu (item_key, item_name, maps)
1246#ifndef HAVE_MULTILINGUAL_MENU 1251#ifndef HAVE_MULTILINGUAL_MENU
1247 if (STRING_MULTIBYTE (item_name)) 1252 if (STRING_MULTIBYTE (item_name))
1248 { 1253 {
1249 item_name = ENCODE_SYSTEM (item_name); 1254 item_name = ENCODE_MENU_STRING (item_name);
1250 AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; 1255 AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name;
1251 } 1256 }
1252 1257
1253 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) 1258 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
1254 { 1259 {
1255 descrip = ENCODE_SYSTEM (descrip); 1260 descrip = ENCODE_MENU_STRING (descrip);
1256 AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; 1261 AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip;
1257 } 1262 }
1258#endif /* not HAVE_MULTILINGUAL_MENU */ 1263#endif /* not HAVE_MULTILINGUAL_MENU */
@@ -1263,9 +1268,9 @@ single_submenu (item_key, item_name, maps)
1263 else 1268 else
1264 save_wv->contents = wv; 1269 save_wv->contents = wv;
1265 1270
1266 wv->name = (char *) SDATA (item_name); 1271 wv->lname = item_name;
1267 if (!NILP (descrip)) 1272 if (!NILP (descrip))
1268 wv->key = (char *) SDATA (descrip); 1273 wv->lkey = descrip;
1269 wv->value = 0; 1274 wv->value = 0;
1270 /* The EMACS_INT cast avoids a warning. There's no problem 1275 /* The EMACS_INT cast avoids a warning. There's no problem
1271 as long as pointers have enough bits to hold small integers. */ 1276 as long as pointers have enough bits to hold small integers. */
@@ -1304,6 +1309,41 @@ single_submenu (item_key, item_name, maps)
1304 1309
1305 return first_wv; 1310 return first_wv;
1306} 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. */
1317static void
1318update_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
1307 1347
1308/* Set the contents of the menubar widgets of frame F. 1348/* Set the contents of the menubar widgets of frame F.
1309 The argument FIRST_TIME is currently ignored; 1349 The argument FIRST_TIME is currently ignored;
@@ -1382,8 +1422,6 @@ set_frame_menubar (f, first_time, deep_p)
1382 1422
1383 items = FRAME_MENU_BAR_ITEMS (f); 1423 items = FRAME_MENU_BAR_ITEMS (f);
1384 1424
1385 inhibit_garbage_collection ();
1386
1387 /* Save the frame's previous menu bar contents data. */ 1425 /* Save the frame's previous menu bar contents data. */
1388 if (previous_menu_items_used) 1426 if (previous_menu_items_used)
1389 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, 1427 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
@@ -1448,6 +1486,7 @@ set_frame_menubar (f, first_time, deep_p)
1448 if (NILP (string)) 1486 if (NILP (string))
1449 break; 1487 break;
1450 wv->name = (char *) SDATA (string); 1488 wv->name = (char *) SDATA (string);
1489 update_submenu_strings (wv->contents);
1451 wv = wv->next; 1490 wv = wv->next;
1452 } 1491 }
1453 1492
@@ -1705,12 +1744,12 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1705#ifndef HAVE_MULTILINGUAL_MENU 1744#ifndef HAVE_MULTILINGUAL_MENU
1706 if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) 1745 if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
1707 { 1746 {
1708 item_name = ENCODE_SYSTEM (item_name); 1747 item_name = ENCODE_MENU_STRING (item_name);
1709 AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; 1748 AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name;
1710 } 1749 }
1711 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) 1750 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
1712 { 1751 {
1713 descrip = ENCODE_SYSTEM (descrip); 1752 descrip = ENCODE_MENU_STRING (descrip);
1714 AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; 1753 AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip;
1715 } 1754 }
1716#endif /* not HAVE_MULTILINGUAL_MENU */ 1755#endif /* not HAVE_MULTILINGUAL_MENU */
@@ -1764,7 +1803,7 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1764 1803
1765#ifndef HAVE_MULTILINGUAL_MENU 1804#ifndef HAVE_MULTILINGUAL_MENU
1766 if (STRING_MULTIBYTE (title)) 1805 if (STRING_MULTIBYTE (title))
1767 title = ENCODE_SYSTEM (title); 1806 title = ENCODE_MENU_STRING (title);
1768#endif 1807#endif
1769 wv_title->name = (char *) SDATA (title); 1808 wv_title->name = (char *) SDATA (title);
1770 wv_title->enabled = TRUE; 1809 wv_title->enabled = TRUE;
@@ -1801,9 +1840,9 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1801 /* Get the refcon to find the correct item*/ 1840 /* Get the refcon to find the correct item*/
1802 if (menu_item_selection) 1841 if (menu_item_selection)
1803 { 1842 {
1804 menu = GetMenuHandle (HiWord (menu_item_choice)); 1843 MenuHandle sel_menu = GetMenuHandle (HiWord (menu_item_choice));
1805 if (menu) { 1844 if (sel_menu) {
1806 GetMenuItemRefCon (menu, menu_item_selection, &refcon); 1845 GetMenuItemRefCon (sel_menu, menu_item_selection, &refcon);
1807 } 1846 }
1808 } 1847 }
1809 1848
@@ -1813,6 +1852,10 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1813 discard_mouse_events (); 1852 discard_mouse_events ();
1814#endif 1853#endif
1815 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
1816 /* Free the widget_value objects we used to specify the 1859 /* Free the widget_value objects we used to specify the
1817 contents. */ 1860 contents. */
1818 free_menubar_widget_value_tree (first_wv); 1861 free_menubar_widget_value_tree (first_wv);
@@ -1821,11 +1864,11 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1821 { 1864 {
1822 int i = MIN_POPUP_SUBMENU_ID; 1865 int i = MIN_POPUP_SUBMENU_ID;
1823 MenuHandle submenu = GetMenuHandle (i); 1866 MenuHandle submenu = GetMenuHandle (i);
1824 while (menu != NULL) 1867 while (submenu != NULL)
1825 { 1868 {
1826 DeleteMenu (i); 1869 DeleteMenu (i);
1827 DisposeMenu (menu); 1870 DisposeMenu (submenu);
1828 menu = GetMenuHandle (++i); 1871 submenu = GetMenuHandle (++i);
1829 } 1872 }
1830 } 1873 }
1831 1874
@@ -2219,8 +2262,18 @@ add_menu_item (MenuHandle menu, widget_value *wv, int submenu,
2219 strncat (item_name, wv->key, 255); 2262 strncat (item_name, wv->key, 255);
2220 } 2263 }
2221 item_name[255] = 0; 2264 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
2222 c2pstr (item_name); 2274 c2pstr (item_name);
2223 SetMenuItemText (menu, pos, item_name); 2275 SetMenuItemText (menu, pos, item_name);
2276#endif
2224 2277
2225 if (wv->enabled && !force_disable) 2278 if (wv->enabled && !force_disable)
2226#if TARGET_API_MAC_CARBON 2279#if TARGET_API_MAC_CARBON