aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiles Bader2004-09-04 09:14:28 +0000
committerMiles Bader2004-09-04 09:14:28 +0000
commit6f7dde8273383c74cc722196c9b37c04faeb263f (patch)
tree5a4126925b754a52e74fa30de6521b3454f57a6d /src
parent32d61209ceb2b6c4b32e9d3ccc477014cc666c25 (diff)
parent90e118abf2dcc4aca4d7a7642247fa488554351e (diff)
downloademacs-6f7dde8273383c74cc722196c9b37c04faeb263f.tar.gz
emacs-6f7dde8273383c74cc722196c9b37c04faeb263f.zip
Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-34
Merge from emacs--cvs-trunk--0 Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-514 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-522 Update from CVS
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog86
-rw-r--r--src/fileio.c2
-rw-r--r--src/gtkutil.c2
-rw-r--r--src/gtkutil.h2
-rw-r--r--src/macfns.c49
-rw-r--r--src/macmenu.c71
-rw-r--r--src/macterm.c10
-rw-r--r--src/s/darwin.h17
-rw-r--r--src/w32fns.c12
-rw-r--r--src/w32menu.c198
-rw-r--r--src/xdisp.c77
-rw-r--r--src/xfns.c187
-rw-r--r--src/xmenu.c56
13 files changed, 533 insertions, 236 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index aa3721d9106..8fd72a29c29 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,89 @@
12004-09-03 Jason Rumney <jasonr@gnu.org>
2
3 * w32menu.c (_widget_value): Added lname and lkey.
4 (digest_single_submenu): Set lname and lkey in widget_value
5 instead of name and key.
6 (update_submenu_strings): New function.
7 (set_frame_menubar): Remove call to inhibit_garbage_collection,
8 call update_submenu_strings.
9
10 * w32menu.c (globals_of_w32menu): Check for Unicode API.
11 (digest_single_submenu, w32_menu_show): Encode menu strings as
12 UTF-8 if Unicode API is available.
13 (utf8to16): New function.
14 (add_menu_item): Use it when calling Unicode API.
15
162004-09-03 Kim F. Storm <storm@cua.dk>
17
18 * xdisp.c (set_cursor_from_row): Look for non-nil `cursor' property
19 in overlay or text-property strings; set cursor on corresponding
20 glyph rather than at end of the string.
21
222004-09-02 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
23
24 * macfns.c (x_real_positions): Save the current window port and
25 set a new one before obtaining the global coordinate. Use
26 FRAME_MAC_WINDOW.
27 (x_set_name, x_set_title): Encode title to UTF8. Use
28 SetWindowTitleWithCFString.
29 (Fx_server_version): Get correct OS version.
30
31 * macmenu.c (add_menu_item): Remove unused variable `i'. Don't
32 let separator items destroy refence constants of other menu items.
33
34 * macterm.c (x_update_end): Move SetPortWindowPort to inside
35 BLOCK_INPUT.
36 (x_set_offset): Use FRAME_MAC_WINDOW.
37
38 * xdisp.c (note_mouse_highlight): Set the mouse pointer shape to
39 nontext_cursor if it is on a scroll bar.
40
41 * s/darwin.h (LIBS_CARBON): New define to specify libraries for
42 Carbon support.
43 (LD_SWITCH_SYSTEM_TEMACS): Don't link with unused libstdc++. Use
44 LIBS_CARBON.
45
462004-09-02 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
47
48 * xfns.c (x_set_name_internal): New function. Check if we shall call
49 xfree before ENCODE_UTF_8.
50 (x_set_name, x_set_title): Call x_set_name_internal.
51
522004-08-31 NAKAMURA Toshikazu <nr-tkz@nifty.com> (tiny change)
53
54 * w32fns.c (w32_load_font): If a BDF font is already loaded, do not
55 reload it.
56
572004-08-30 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
58
59 * macmenu.c (_widget_value): Added lname and lkey.
60 (single_submenu): Set lname and lkey in widget_value
61 instead of name and key.
62 (update_submenu_strings): New function.
63 (set_frame_menubar): Remove call to inhibit_garbage_collection,
64 call update_submenu_strings.
65
66 * xmenu.c (digest_single_submenu): Set lname and lkey in widget_value
67 instead of name and key.
68 (update_submenu_strings): New function.
69 (set_frame_menubar): Remove call to inhibit_garbage_collection,
70 call update_submenu_strings.
71
72 * gtkutil.h (_widget_value): Added lname and lkey.
73
742004-08-30 Steven Tamm <steventamm@mac.com>
75
76 * macmenu.c (mac_menu_show): Remove shadowing of menu variable
77 by using different names for inner loop variables.
78
792004-08-27 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
80
81 * xmenu.c (set_frame_menubar): Reintroduce inhibit_garbage_collection
82 from 2002-07-15T00:01:34Z!raeburn@raeburn.org so that strings from ENCODE_UTF_8 isn't GC:ed before used.
83
84 * gtkutil.c (xg_create_frame_widgets): Compensate for tool bar when
85 tool bar items is 0.
86
12004-08-26 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> 872004-08-26 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
2 88
3 * macmenu.c (ENCODE_MENU_STRING): Added to handle multibyte 89 * macmenu.c (ENCODE_MENU_STRING): Added to handle multibyte
diff --git a/src/fileio.c b/src/fileio.c
index 66b7d8b83fc..8290f01b58e 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -6217,7 +6217,7 @@ and `read-file-name-function'. */)
6217 6217
6218 GCPRO2 (insdef, default_filename); 6218 GCPRO2 (insdef, default_filename);
6219 6219
6220#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) || defined(TARGET_API_MAC_CARBON) 6220#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) || defined (TARGET_API_MAC_CARBON)
6221 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event)) 6221 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
6222 && use_dialog_box 6222 && use_dialog_box
6223 && use_file_dialog 6223 && use_file_dialog
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 3ffba0ba745..fabdae74dc6 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -793,7 +793,7 @@ xg_create_frame_widgets (f)
793 up in the wrong place as tool bar height has not been taken into account. 793 up in the wrong place as tool bar height has not been taken into account.
794 So we cheat a bit by setting a height that is what it will have 794 So we cheat a bit by setting a height that is what it will have
795 later on when tool bar items are added. */ 795 later on when tool bar items are added. */
796 if (FRAME_EXTERNAL_TOOL_BAR (f) && FRAME_TOOLBAR_HEIGHT (f) == 0) 796 if (FRAME_EXTERNAL_TOOL_BAR (f) && f->n_tool_bar_items == 0)
797 FRAME_TOOLBAR_HEIGHT (f) = 34; 797 FRAME_TOOLBAR_HEIGHT (f) = 34;
798 798
799 799
diff --git a/src/gtkutil.h b/src/gtkutil.h
index b31ec8c2a1f..b35ab94b2cb 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -96,10 +96,12 @@ typedef struct xg_menu_item_cb_data_
96typedef struct _widget_value 96typedef struct _widget_value
97{ 97{
98 /* name of widget */ 98 /* name of widget */
99 Lisp_Object lname;
99 char *name; 100 char *name;
100 /* value (meaning depend on widget type) */ 101 /* value (meaning depend on widget type) */
101 char *value; 102 char *value;
102 /* keyboard equivalent. no implications for XtTranslations */ 103 /* keyboard equivalent. no implications for XtTranslations */
104 Lisp_Object lkey;
103 char *key; 105 char *key;
104 /* Help string or nil if none. 106 /* Help string or nil if none.
105 GC finds this string through the frame's menu_bar_vector 107 GC finds this string through the frame's menu_bar_vector
diff --git a/src/macfns.c b/src/macfns.c
index fbade05ea17..3b09b344a55 100644
--- a/src/macfns.c
+++ b/src/macfns.c
@@ -324,19 +324,21 @@ x_real_positions (f, xptr, yptr)
324 Point pt; 324 Point pt;
325 GrafPtr oldport; 325 GrafPtr oldport;
326 326
327#ifdef TARGET_API_MAC_CARBON 327 GetPort (&oldport);
328 SetPortWindowPort (FRAME_MAC_WINDOW (f));
329
330#if TARGET_API_MAC_CARBON
328 { 331 {
329 Rect r; 332 Rect r;
330 333
331 GetWindowPortBounds (f->output_data.mac->mWP, &r); 334 GetWindowPortBounds (FRAME_MAC_WINDOW (f), &r);
332 SetPt (&pt, r.left, r.top); 335 SetPt (&pt, r.left, r.top);
333 } 336 }
334#else /* not TARGET_API_MAC_CARBON */ 337#else /* not TARGET_API_MAC_CARBON */
335 SetPt (&pt, 338 SetPt (&pt,
336 f->output_data.mac->mWP->portRect.left, 339 FRAME_MAC_WINDOW (f)->portRect.left,
337 f->output_data.mac->mWP->portRect.top); 340 FRAME_MAC_WINDOW (f)->portRect.top);
338#endif /* not TARGET_API_MAC_CARBON */ 341#endif /* not TARGET_API_MAC_CARBON */
339 GetPort (&oldport);
340 LocalToGlobal (&pt); 342 LocalToGlobal (&pt);
341 SetPort (oldport); 343 SetPort (oldport);
342 344
@@ -1934,8 +1936,8 @@ x_set_name (f, name, explicit)
1934 if (FRAME_MAC_WINDOW (f)) 1936 if (FRAME_MAC_WINDOW (f))
1935 { 1937 {
1936 if (STRING_MULTIBYTE (name)) 1938 if (STRING_MULTIBYTE (name))
1937#if 0 /* MAC_TODO: encoding title string */ 1939#if TARGET_API_MAC_CARBON
1938 name = ENCODE_SYSTEM (name); 1940 name = ENCODE_UTF_8 (name);
1939#else 1941#else
1940 return; 1942 return;
1941#endif 1943#endif
@@ -1943,6 +1945,14 @@ x_set_name (f, name, explicit)
1943 BLOCK_INPUT; 1945 BLOCK_INPUT;
1944 1946
1945 { 1947 {
1948#if TARGET_API_MAC_CARBON
1949 CFStringRef windowTitle =
1950 CFStringCreateWithCString (NULL, SDATA (name),
1951 kCFStringEncodingUTF8);
1952
1953 SetWindowTitleWithCFString (FRAME_MAC_WINDOW (f), windowTitle);
1954 CFRelease (windowTitle);
1955#else
1946 Str255 windowTitle; 1956 Str255 windowTitle;
1947 if (strlen (SDATA (name)) < 255) 1957 if (strlen (SDATA (name)) < 255)
1948 { 1958 {
@@ -1950,6 +1960,7 @@ x_set_name (f, name, explicit)
1950 c2pstr (windowTitle); 1960 c2pstr (windowTitle);
1951 SetWTitle (FRAME_MAC_WINDOW (f), windowTitle); 1961 SetWTitle (FRAME_MAC_WINDOW (f), windowTitle);
1952 } 1962 }
1963#endif
1953 } 1964 }
1954 1965
1955 UNBLOCK_INPUT; 1966 UNBLOCK_INPUT;
@@ -2008,8 +2019,8 @@ x_set_title (f, name, old_name)
2008 if (FRAME_MAC_WINDOW (f)) 2019 if (FRAME_MAC_WINDOW (f))
2009 { 2020 {
2010 if (STRING_MULTIBYTE (name)) 2021 if (STRING_MULTIBYTE (name))
2011#if 0 /* MAC_TODO: encoding title string */ 2022#if TARGET_API_MAC_CARBON
2012 name = ENCODE_SYSTEM (name); 2023 name = ENCODE_UTF_8 (name);
2013#else 2024#else
2014 return; 2025 return;
2015#endif 2026#endif
@@ -2017,6 +2028,14 @@ x_set_title (f, name, old_name)
2017 BLOCK_INPUT; 2028 BLOCK_INPUT;
2018 2029
2019 { 2030 {
2031#if TARGET_API_MAC_CARBON
2032 CFStringRef windowTitle =
2033 CFStringCreateWithCString (NULL, SDATA (name),
2034 kCFStringEncodingUTF8);
2035
2036 SetWindowTitleWithCFString (FRAME_MAC_WINDOW (f), windowTitle);
2037 CFRelease (windowTitle);
2038#else
2020 Str255 windowTitle; 2039 Str255 windowTitle;
2021 if (strlen (SDATA (name)) < 255) 2040 if (strlen (SDATA (name)) < 255)
2022 { 2041 {
@@ -2024,6 +2043,7 @@ x_set_title (f, name, old_name)
2024 c2pstr (windowTitle); 2043 c2pstr (windowTitle);
2025 SetWTitle (FRAME_MAC_WINDOW (f), windowTitle); 2044 SetWTitle (FRAME_MAC_WINDOW (f), windowTitle);
2026 } 2045 }
2046#endif
2027 } 2047 }
2028 2048
2029 UNBLOCK_INPUT; 2049 UNBLOCK_INPUT;
@@ -2981,17 +3001,20 @@ If omitted or nil, that stands for the selected frame's display. */)
2981 (display) 3001 (display)
2982 Lisp_Object display; 3002 Lisp_Object display;
2983{ 3003{
2984 int mac_major_version, mac_minor_version; 3004 int mac_major_version;
2985 SInt32 response; 3005 SInt32 response;
2986 3006
2987 if (Gestalt (gestaltSystemVersion, &response) != noErr) 3007 if (Gestalt (gestaltSystemVersion, &response) != noErr)
2988 error ("Cannot get Mac OS version"); 3008 error ("Cannot get Mac OS version");
2989 3009
2990 mac_major_version = (response >> 8) & 0xf; 3010 mac_major_version = (response >> 8) & 0xff;
2991 mac_minor_version = (response >> 4) & 0xf; 3011 /* convert BCD to int */
3012 mac_major_version -= (mac_major_version >> 4) * 6;
2992 3013
2993 return Fcons (make_number (mac_major_version), 3014 return Fcons (make_number (mac_major_version),
2994 Fcons (make_number (mac_minor_version), Qnil)); 3015 Fcons (make_number ((response >> 4) & 0xf),
3016 Fcons (make_number (response & 0xf),
3017 Qnil)));
2995} 3018}
2996 3019
2997DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0, 3020DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
diff --git a/src/macmenu.c b/src/macmenu.c
index 67e18481a1b..740bda261d8 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
@@ -1221,12 +1223,9 @@ single_submenu (item_key, item_name, maps)
1221 save_wv->next = wv; 1223 save_wv->next = wv;
1222 else 1224 else
1223 first_wv->contents = wv; 1225 first_wv->contents = wv;
1224 wv->name = pane_string; 1226 wv->lname = pane_name;
1225 /* Ignore the @ that means "separate pane". 1227 /* Set value to 1 so update_submenu_strings can handle '@' */
1226 This is a kludge, but this isn't worth more time. */ 1228 wv->value = (char *)1;
1227 if (!NILP (prefix) && wv->name[0] == '@')
1228 wv->name++;
1229 wv->value = 0;
1230 wv->enabled = 1; 1229 wv->enabled = 1;
1231 wv->button_type = BUTTON_TYPE_NONE; 1230 wv->button_type = BUTTON_TYPE_NONE;
1232 wv->help = Qnil; 1231 wv->help = Qnil;
@@ -1269,9 +1268,9 @@ single_submenu (item_key, item_name, maps)
1269 else 1268 else
1270 save_wv->contents = wv; 1269 save_wv->contents = wv;
1271 1270
1272 wv->name = (char *) SDATA (item_name); 1271 wv->lname = item_name;
1273 if (!NILP (descrip)) 1272 if (!NILP (descrip))
1274 wv->key = (char *) SDATA (descrip); 1273 wv->lkey = descrip;
1275 wv->value = 0; 1274 wv->value = 0;
1276 /* The EMACS_INT cast avoids a warning. There's no problem 1275 /* The EMACS_INT cast avoids a warning. There's no problem
1277 as long as pointers have enough bits to hold small integers. */ 1276 as long as pointers have enough bits to hold small integers. */
@@ -1310,6 +1309,41 @@ single_submenu (item_key, item_name, maps)
1310 1309
1311 return first_wv; 1310 return first_wv;
1312} 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
1313 1347
1314/* Set the contents of the menubar widgets of frame F. 1348/* Set the contents of the menubar widgets of frame F.
1315 The argument FIRST_TIME is currently ignored; 1349 The argument FIRST_TIME is currently ignored;
@@ -1388,8 +1422,6 @@ set_frame_menubar (f, first_time, deep_p)
1388 1422
1389 items = FRAME_MENU_BAR_ITEMS (f); 1423 items = FRAME_MENU_BAR_ITEMS (f);
1390 1424
1391 inhibit_garbage_collection ();
1392
1393 /* Save the frame's previous menu bar contents data. */ 1425 /* Save the frame's previous menu bar contents data. */
1394 if (previous_menu_items_used) 1426 if (previous_menu_items_used)
1395 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, 1427 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
@@ -1454,6 +1486,7 @@ set_frame_menubar (f, first_time, deep_p)
1454 if (NILP (string)) 1486 if (NILP (string))
1455 break; 1487 break;
1456 wv->name = (char *) SDATA (string); 1488 wv->name = (char *) SDATA (string);
1489 update_submenu_strings (wv->contents);
1457 wv = wv->next; 1490 wv = wv->next;
1458 } 1491 }
1459 1492
@@ -1807,9 +1840,9 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1807 /* Get the refcon to find the correct item*/ 1840 /* Get the refcon to find the correct item*/
1808 if (menu_item_selection) 1841 if (menu_item_selection)
1809 { 1842 {
1810 menu = GetMenuHandle (HiWord (menu_item_choice)); 1843 MenuHandle sel_menu = GetMenuHandle (HiWord (menu_item_choice));
1811 if (menu) { 1844 if (sel_menu) {
1812 GetMenuItemRefCon (menu, menu_item_selection, &refcon); 1845 GetMenuItemRefCon (sel_menu, menu_item_selection, &refcon);
1813 } 1846 }
1814 } 1847 }
1815 1848
@@ -1831,11 +1864,11 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1831 { 1864 {
1832 int i = MIN_POPUP_SUBMENU_ID; 1865 int i = MIN_POPUP_SUBMENU_ID;
1833 MenuHandle submenu = GetMenuHandle (i); 1866 MenuHandle submenu = GetMenuHandle (i);
1834 while (menu != NULL) 1867 while (submenu != NULL)
1835 { 1868 {
1836 DeleteMenu (i); 1869 DeleteMenu (i);
1837 DisposeMenu (menu); 1870 DisposeMenu (submenu);
1838 menu = GetMenuHandle (++i); 1871 submenu = GetMenuHandle (++i);
1839 } 1872 }
1840 } 1873 }
1841 1874
@@ -2207,7 +2240,7 @@ add_menu_item (MenuHandle menu, widget_value *wv, int submenu,
2207 int force_disable) 2240 int force_disable)
2208{ 2241{
2209 Str255 item_name; 2242 Str255 item_name;
2210 int pos, i; 2243 int pos;
2211 2244
2212 if (name_is_separator (wv->name)) 2245 if (name_is_separator (wv->name))
2213 AppendMenu (menu, "\p-"); 2246 AppendMenu (menu, "\p-");
@@ -2263,9 +2296,9 @@ add_menu_item (MenuHandle menu, widget_value *wv, int submenu,
2263 else 2296 else
2264 SetItemMark (menu, pos, noMark); 2297 SetItemMark (menu, pos, noMark);
2265 } 2298 }
2266 }
2267 2299
2268 SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data); 2300 SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data);
2301 }
2269 2302
2270 if (submenu != NULL) 2303 if (submenu != NULL)
2271 SetMenuItemHierarchicalID (menu, pos, submenu); 2304 SetMenuItemHierarchicalID (menu, pos, submenu);
diff --git a/src/macterm.c b/src/macterm.c
index 297683f6d9b..e1b8d49ddfa 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -1327,6 +1327,10 @@ static void
1327x_update_end (f) 1327x_update_end (f)
1328 struct frame *f; 1328 struct frame *f;
1329{ 1329{
1330 /* Mouse highlight may be displayed again. */
1331 FRAME_MAC_DISPLAY_INFO (f)->mouse_face_defer = 0;
1332
1333 BLOCK_INPUT;
1330 /* Reset the background color of Mac OS Window to that of the frame after 1334 /* Reset the background color of Mac OS Window to that of the frame after
1331 update so that it is used by Mac Toolbox to clear the update region before 1335 update so that it is used by Mac Toolbox to clear the update region before
1332 an update event is generated. */ 1336 an update event is generated. */
@@ -1334,10 +1338,6 @@ x_update_end (f)
1334 1338
1335 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f)); 1339 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f));
1336 1340
1337 /* Mouse highlight may be displayed again. */
1338 FRAME_MAC_DISPLAY_INFO (f)->mouse_face_defer = 0;
1339
1340 BLOCK_INPUT;
1341 XFlush (FRAME_MAC_DISPLAY (f)); 1341 XFlush (FRAME_MAC_DISPLAY (f));
1342 UNBLOCK_INPUT; 1342 UNBLOCK_INPUT;
1343} 1343}
@@ -5140,7 +5140,7 @@ x_set_offset (f, xoff, yoff, change_gravity)
5140 modified_left = f->left_pos; 5140 modified_left = f->left_pos;
5141 modified_top = f->top_pos; 5141 modified_top = f->top_pos;
5142 5142
5143 MoveWindow (f->output_data.mac->mWP, modified_left + 6, 5143 MoveWindow (FRAME_MAC_WINDOW (f), modified_left + 6,
5144 modified_top + 42, false); 5144 modified_top + 42, false);
5145 5145
5146 UNBLOCK_INPUT; 5146 UNBLOCK_INPUT;
diff --git a/src/s/darwin.h b/src/s/darwin.h
index 814de2c2c51..f854ed9380b 100644
--- a/src/s/darwin.h
+++ b/src/s/darwin.h
@@ -243,11 +243,18 @@ Boston, MA 02111-1307, USA. */
243 specific headers. */ 243 specific headers. */
244#define C_SWITCH_SYSTEM -fpascal-strings -fno-common -DMAC_OSX -I../mac/src 244#define C_SWITCH_SYSTEM -fpascal-strings -fno-common -DMAC_OSX -I../mac/src
245 245
246/* Link in the Carbon lib. The -headerpad option tells ld (see man 246/* Link in the Carbon lib. */
247 page) to leave room at the end of the header for adding load 247#ifdef HAVE_CARBON
248 commands. Needed for dumping. 0x690 is the total size of 30 248#define LIBS_CARBON -framework Carbon -framework QuickTime
249 segment load commands (at 56 each). */ 249#else
250#define LD_SWITCH_SYSTEM_TEMACS -prebind -framework Carbon -framework QuickTime -lstdc++ -Xlinker -headerpad -Xlinker 690 250#define LIBS_CARBON -framework Carbon
251#endif
252
253/* The -headerpad option tells ld (see man page) to leave room at the
254 end of the header for adding load commands. Needed for dumping.
255 0x690 is the total size of 30 segment load commands (at 56
256 each). */
257#define LD_SWITCH_SYSTEM_TEMACS -prebind LIBS_CARBON -Xlinker -headerpad -Xlinker 690
251 258
252#define C_SWITCH_SYSTEM_TEMACS -Dtemacs 259#define C_SWITCH_SYSTEM_TEMACS -Dtemacs
253 260
diff --git a/src/w32fns.c b/src/w32fns.c
index 3599078b3a3..d2231772bf4 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -4644,6 +4644,7 @@ int size;
4644{ 4644{
4645 Lisp_Object bdf_fonts; 4645 Lisp_Object bdf_fonts;
4646 struct font_info *retval = NULL; 4646 struct font_info *retval = NULL;
4647 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
4647 4648
4648 bdf_fonts = w32_list_bdf_fonts (build_string (fontname), 1); 4649 bdf_fonts = w32_list_bdf_fonts (build_string (fontname), 1);
4649 4650
@@ -4651,11 +4652,22 @@ int size;
4651 { 4652 {
4652 char *bdf_name, *bdf_file; 4653 char *bdf_name, *bdf_file;
4653 Lisp_Object bdf_pair; 4654 Lisp_Object bdf_pair;
4655 int i;
4654 4656
4655 bdf_name = SDATA (XCAR (bdf_fonts)); 4657 bdf_name = SDATA (XCAR (bdf_fonts));
4656 bdf_pair = Fassoc (XCAR (bdf_fonts), Vw32_bdf_filename_alist); 4658 bdf_pair = Fassoc (XCAR (bdf_fonts), Vw32_bdf_filename_alist);
4657 bdf_file = SDATA (XCDR (bdf_pair)); 4659 bdf_file = SDATA (XCDR (bdf_pair));
4658 4660
4661 // If the font is already loaded, do not load it again.
4662 for (i = 0; i < dpyinfo->n_fonts; i++)
4663 {
4664 if ((dpyinfo->font_table[i].name
4665 && !strcmp (dpyinfo->font_table[i].name, bdf_name))
4666 || (dpyinfo->font_table[i].full_name
4667 && !strcmp (dpyinfo->font_table[i].full_name, bdf_name)))
4668 return dpyinfo->font_table + i;
4669 }
4670
4659 retval = w32_load_bdf_font (f, bdf_name, size, bdf_file); 4671 retval = w32_load_bdf_font (f, bdf_name, size, bdf_file);
4660 4672
4661 bdf_fonts = XCDR (bdf_fonts); 4673 bdf_fonts = XCDR (bdf_fonts);
diff --git a/src/w32menu.c b/src/w32menu.c
index cc0932d7bf5..f3f3eb785b0 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -45,7 +45,6 @@ Boston, MA 02111-1307, USA. */
45 45
46#include "dispextern.h" 46#include "dispextern.h"
47 47
48#undef HAVE_MULTILINGUAL_MENU
49#undef HAVE_DIALOGS /* TODO: Implement native dialogs. */ 48#undef HAVE_DIALOGS /* TODO: Implement native dialogs. */
50 49
51/******************************************************************/ 50/******************************************************************/
@@ -66,10 +65,12 @@ enum button_type
66typedef struct _widget_value 65typedef struct _widget_value
67{ 66{
68 /* name of widget */ 67 /* name of widget */
68 Lisp_Object lname;
69 char* name; 69 char* name;
70 /* value (meaning depend on widget type) */ 70 /* value (meaning depend on widget type) */
71 char* value; 71 char* value;
72 /* keyboard equivalent. no implications for XtTranslations */ 72 /* keyboard equivalent. no implications for XtTranslations */
73 Lisp_Object lkey;
73 char* key; 74 char* key;
74 /* Help string or nil if none. 75 /* Help string or nil if none.
75 GC finds this string through the frame's menu_bar_vector 76 GC finds this string through the frame's menu_bar_vector
@@ -136,17 +137,21 @@ typedef BOOL (WINAPI * GetMenuItemInfoA_Proc) (
136 IN HMENU, 137 IN HMENU,
137 IN UINT, 138 IN UINT,
138 IN BOOL, 139 IN BOOL,
139 IN OUT LPMENUITEMINFOA 140 IN OUT LPMENUITEMINFOA);
140 );
141typedef BOOL (WINAPI * SetMenuItemInfoA_Proc) ( 141typedef BOOL (WINAPI * SetMenuItemInfoA_Proc) (
142 IN HMENU, 142 IN HMENU,
143 IN UINT, 143 IN UINT,
144 IN BOOL, 144 IN BOOL,
145 IN LPCMENUITEMINFOA 145 IN LPCMENUITEMINFOA);
146 ); 146typedef BOOL (WINAPI * AppendMenuW_Proc) (
147 IN HMENU,
148 IN UINT,
149 IN UINT_PTR,
150 IN LPCWSTR);
147 151
148GetMenuItemInfoA_Proc get_menu_item_info=NULL; 152GetMenuItemInfoA_Proc get_menu_item_info = NULL;
149SetMenuItemInfoA_Proc set_menu_item_info=NULL; 153SetMenuItemInfoA_Proc set_menu_item_info = NULL;
154AppendMenuW_Proc unicode_append_menu = NULL;
150 155
151Lisp_Object Vmenu_updating_frame; 156Lisp_Object Vmenu_updating_frame;
152 157
@@ -1235,13 +1240,17 @@ digest_single_submenu (start, end, top_level_items)
1235 pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME); 1240 pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
1236 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); 1241 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
1237 1242
1238#ifndef HAVE_MULTILINGUAL_MENU 1243 if (STRINGP (pane_name))
1239 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
1240 { 1244 {
1241 pane_name = ENCODE_SYSTEM (pane_name); 1245 if (unicode_append_menu)
1246 /* Encode as UTF-8 for now. */
1247 pane_name = ENCODE_UTF_8 (pane_name);
1248 else if (STRING_MULTIBYTE (pane_name))
1249 pane_name = ENCODE_SYSTEM (pane_name);
1250
1242 ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name); 1251 ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
1243 } 1252 }
1244#endif 1253
1245 pane_string = (NILP (pane_name) 1254 pane_string = (NILP (pane_name)
1246 ? "" : (char *) SDATA (pane_name)); 1255 ? "" : (char *) SDATA (pane_name));
1247 /* If there is just one top-level pane, put all its items directly 1256 /* If there is just one top-level pane, put all its items directly
@@ -1259,12 +1268,9 @@ digest_single_submenu (start, end, top_level_items)
1259 save_wv->next = wv; 1268 save_wv->next = wv;
1260 else 1269 else
1261 first_wv->contents = wv; 1270 first_wv->contents = wv;
1262 wv->name = pane_string; 1271 wv->lname = pane_name;
1263 /* Ignore the @ that means "separate pane". 1272 /* Set value to 1 so update_submenu_strings can handle '@' */
1264 This is a kludge, but this isn't worth more time. */ 1273 wv->value = (char *) 1;
1265 if (!NILP (prefix) && wv->name[0] == '@')
1266 wv->name++;
1267 wv->value = 0;
1268 wv->enabled = 1; 1274 wv->enabled = 1;
1269 wv->button_type = BUTTON_TYPE_NONE; 1275 wv->button_type = BUTTON_TYPE_NONE;
1270 wv->help = Qnil; 1276 wv->help = Qnil;
@@ -1287,10 +1293,13 @@ digest_single_submenu (start, end, top_level_items)
1287 selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED); 1293 selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
1288 help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP); 1294 help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
1289 1295
1290#ifndef HAVE_MULTILINGUAL_MENU 1296 if (STRINGP (item_name))
1291 if (STRING_MULTIBYTE (item_name))
1292 { 1297 {
1293 item_name = ENCODE_SYSTEM (item_name); 1298 if (unicode_append_menu)
1299 item_name = ENCODE_UTF_8 (item_name);
1300 else if (STRING_MULTIBYTE (item_name))
1301 item_name = ENCODE_SYSTEM (item_name);
1302
1294 ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name); 1303 ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
1295 } 1304 }
1296 1305
@@ -1299,7 +1308,6 @@ digest_single_submenu (start, end, top_level_items)
1299 descrip = ENCODE_SYSTEM (descrip); 1308 descrip = ENCODE_SYSTEM (descrip);
1300 ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip); 1309 ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
1301 } 1310 }
1302#endif /* not HAVE_MULTILINGUAL_MENU */
1303 1311
1304 wv = xmalloc_widget_value (); 1312 wv = xmalloc_widget_value ();
1305 if (prev_wv) 1313 if (prev_wv)
@@ -1307,9 +1315,9 @@ digest_single_submenu (start, end, top_level_items)
1307 else 1315 else
1308 save_wv->contents = wv; 1316 save_wv->contents = wv;
1309 1317
1310 wv->name = (char *) SDATA (item_name); 1318 wv->lname = item_name;
1311 if (!NILP (descrip)) 1319 if (!NILP (descrip))
1312 wv->key = (char *) SDATA (descrip); 1320 wv->lkey = descrip;
1313 wv->value = 0; 1321 wv->value = 0;
1314 /* The EMACS_INT cast avoids a warning. There's no problem 1322 /* The EMACS_INT cast avoids a warning. There's no problem
1315 as long as pointers have enough bits to hold small integers. */ 1323 as long as pointers have enough bits to hold small integers. */
@@ -1348,6 +1356,43 @@ digest_single_submenu (start, end, top_level_items)
1348 1356
1349 return first_wv; 1357 return first_wv;
1350} 1358}
1359
1360
1361/* Walk through the widget_value tree starting at FIRST_WV and update
1362 the char * pointers from the corresponding lisp values.
1363 We do this after building the whole tree, since GC may happen while the
1364 tree is constructed, and small strings are relocated. So we must wait
1365 until no GC can happen before storing pointers into lisp values. */
1366static void
1367update_submenu_strings (first_wv)
1368 widget_value *first_wv;
1369{
1370 widget_value *wv;
1371
1372 for (wv = first_wv; wv; wv = wv->next)
1373 {
1374 if (wv->lname && ! NILP (wv->lname))
1375 {
1376 wv->name = SDATA (wv->lname);
1377
1378 /* Ignore the @ that means "separate pane".
1379 This is a kludge, but this isn't worth more time. */
1380 if (wv->value == (char *)1)
1381 {
1382 if (wv->name[0] == '@')
1383 wv->name++;
1384 wv->value = 0;
1385 }
1386 }
1387
1388 if (wv->lkey && ! NILP (wv->lkey))
1389 wv->key = SDATA (wv->lkey);
1390
1391 if (wv->contents)
1392 update_submenu_strings (wv->contents);
1393 }
1394}
1395
1351 1396
1352/* Set the contents of the menubar widgets of frame F. 1397/* Set the contents of the menubar widgets of frame F.
1353 The argument FIRST_TIME is currently ignored; 1398 The argument FIRST_TIME is currently ignored;
@@ -1516,6 +1561,7 @@ set_frame_menubar (f, first_time, deep_p)
1516 if (NILP (string)) 1561 if (NILP (string))
1517 break; 1562 break;
1518 wv->name = (char *) SDATA (string); 1563 wv->name = (char *) SDATA (string);
1564 update_submenu_strings (wv->contents);
1519 wv = wv->next; 1565 wv = wv->next;
1520 } 1566 }
1521 1567
@@ -1729,13 +1775,17 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
1729 char *pane_string; 1775 char *pane_string;
1730 pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME); 1776 pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
1731 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); 1777 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
1732#ifndef HAVE_MULTILINGUAL_MENU 1778
1733 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) 1779 if (STRINGP (pane_name))
1734 { 1780 {
1735 pane_name = ENCODE_SYSTEM (pane_name); 1781 if (unicode_append_menu)
1782 pane_name = ENCODE_UTF_8 (pane_name);
1783 else if (STRING_MULTIBYTE (pane_name))
1784 pane_name = ENCODE_SYSTEM (pane_name);
1785
1736 ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name); 1786 ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
1737 } 1787 }
1738#endif 1788
1739 pane_string = (NILP (pane_name) 1789 pane_string = (NILP (pane_name)
1740 ? "" : (char *) SDATA (pane_name)); 1790 ? "" : (char *) SDATA (pane_name));
1741 /* If there is just one top-level pane, put all its items directly 1791 /* If there is just one top-level pane, put all its items directly
@@ -1784,18 +1834,21 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
1784 selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED); 1834 selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
1785 help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP); 1835 help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
1786 1836
1787#ifndef HAVE_MULTILINGUAL_MENU 1837 if (STRINGP (item_name))
1788 if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
1789 { 1838 {
1790 item_name = ENCODE_SYSTEM (item_name); 1839 if (unicode_append_menu)
1840 item_name = ENCODE_UTF_8 (item_name);
1841 else if (STRING_MULTIBYTE (item_name))
1842 item_name = ENCODE_SYSTEM (item_name);
1843
1791 ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name); 1844 ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
1792 } 1845 }
1793 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) 1846
1847 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
1794 { 1848 {
1795 descrip = ENCODE_SYSTEM (descrip); 1849 descrip = ENCODE_SYSTEM (descrip);
1796 ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip); 1850 ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
1797 } 1851 }
1798#endif /* not HAVE_MULTILINGUAL_MENU */
1799 1852
1800 wv = xmalloc_widget_value (); 1853 wv = xmalloc_widget_value ();
1801 if (prev_wv) 1854 if (prev_wv)
@@ -1844,10 +1897,11 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
1844 wv_sep->next = first_wv->contents; 1897 wv_sep->next = first_wv->contents;
1845 wv_sep->help = Qnil; 1898 wv_sep->help = Qnil;
1846 1899
1847#ifndef HAVE_MULTILINGUAL_MENU 1900 if (unicode_append_menu)
1848 if (STRING_MULTIBYTE (title)) 1901 title = ENCODE_UTF_8 (title);
1902 else if (STRING_MULTIBYTE (title))
1849 title = ENCODE_SYSTEM (title); 1903 title = ENCODE_SYSTEM (title);
1850#endif 1904
1851 wv_title->name = (char *) SDATA (title); 1905 wv_title->name = (char *) SDATA (title);
1852 wv_title->enabled = TRUE; 1906 wv_title->enabled = TRUE;
1853 wv_title->title = TRUE; 1907 wv_title->title = TRUE;
@@ -2150,6 +2204,46 @@ add_left_right_boundary (HMENU menu)
2150 return AppendMenu (menu, MF_MENUBARBREAK, 0, NULL); 2204 return AppendMenu (menu, MF_MENUBARBREAK, 0, NULL);
2151} 2205}
2152 2206
2207/* UTF8: 0xxxxxxx, 110xxxxx 10xxxxxx, 1110xxxx, 10xxxxxx, 10xxxxxx */
2208static void
2209utf8to16 (unsigned char * src, int len, WCHAR * dest)
2210{
2211 while (len > 0)
2212 {
2213 int utf16;
2214 if (*src < 0x80)
2215 {
2216 *dest = (WCHAR) *src;
2217 dest++; src++; len--;
2218 }
2219 /* Since we might get >3 byte sequences which we don't handle, ignore the extra parts. */
2220 else if (*src < 0xC0)
2221 {
2222 src++; len--;
2223 }
2224 /* 2 char UTF-8 sequence. */
2225 else if (*src < 0xE0)
2226 {
2227 *dest = (WCHAR) (((*src & 0x1f) << 6)
2228 | (*(src + 1) & 0x3f));
2229 src += 2; len -= 2; dest++;
2230 }
2231 else if (*src < 0xF0)
2232 {
2233 *dest = (WCHAR) (((*src & 0x0f) << 12)
2234 | ((*(src + 1) & 0x3f) << 6)
2235 | (*(src + 2) & 0x3f));
2236 src += 3; len -= 3; dest++;
2237 }
2238 else /* Not encodable. Insert Unicode Substitution char. */
2239 {
2240 *dest = (WCHAR) 0xfffd;
2241 src++; len--; dest++;
2242 }
2243 }
2244 *dest = 0;
2245}
2246
2153static int 2247static int
2154add_menu_item (HMENU menu, widget_value *wv, HMENU item) 2248add_menu_item (HMENU menu, widget_value *wv, HMENU item)
2155{ 2249{
@@ -2206,11 +2300,32 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
2206 fuFlags |= MF_UNCHECKED; 2300 fuFlags |= MF_UNCHECKED;
2207 } 2301 }
2208 2302
2209 return_value = 2303 if (unicode_append_menu && out_string)
2210 AppendMenu (menu, 2304 {
2211 fuFlags, 2305 /* Convert out_string from UTF-8 to UTF-16-LE. */
2212 item != NULL ? (UINT) item : (UINT) wv->call_data, 2306 int utf8_len = strlen (out_string);
2213 out_string ); 2307 WCHAR * utf16_string;
2308 if (fuFlags & MF_OWNERDRAW)
2309 utf16_string = local_alloc ((utf8_len + 1) * sizeof (WCHAR));
2310 else
2311 utf16_string = alloca ((utf8_len + 1) * sizeof (WCHAR));
2312
2313 utf8to16 (out_string, utf8_len, utf16_string);
2314 return_value = unicode_append_menu (menu, fuFlags,
2315 item != NULL ? (UINT) item
2316 : (UINT) wv->call_data,
2317 utf16_string);
2318 if (fuFlags & MF_OWNERDRAW)
2319 local_free (out_string);
2320 }
2321 else
2322 {
2323 return_value =
2324 AppendMenu (menu,
2325 fuFlags,
2326 item != NULL ? (UINT) item : (UINT) wv->call_data,
2327 out_string );
2328 }
2214 2329
2215 /* This must be done after the menu item is created. */ 2330 /* This must be done after the menu item is created. */
2216 if (!wv->title && wv->call_data != 0) 2331 if (!wv->title && wv->call_data != 0)
@@ -2298,7 +2413,7 @@ w32_menu_display_help (HWND owner, HMENU menu, UINT item, UINT flags)
2298 struct frame *f = x_window_to_frame (&one_w32_display_info, owner); 2413 struct frame *f = x_window_to_frame (&one_w32_display_info, owner);
2299 Lisp_Object frame, help; 2414 Lisp_Object frame, help;
2300 2415
2301 // No help echo on owner-draw menu items. 2416 /* No help echo on owner-draw menu items. */
2302 if (flags & MF_OWNERDRAW || flags & MF_POPUP) 2417 if (flags & MF_OWNERDRAW || flags & MF_POPUP)
2303 help = Qnil; 2418 help = Qnil;
2304 else 2419 else
@@ -2422,6 +2537,7 @@ void globals_of_w32menu ()
2422 HMODULE user32 = GetModuleHandle ("user32.dll"); 2537 HMODULE user32 = GetModuleHandle ("user32.dll");
2423 get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA"); 2538 get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
2424 set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA"); 2539 set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
2540 unicode_append_menu = (AppendMenuW_Proc) GetProcAddress (user32, "AppendMenuW");
2425} 2541}
2426 2542
2427/* arch-tag: 0eaed431-bb4e-4aac-a527-95a1b4f1fed0 2543/* arch-tag: 0eaed431-bb4e-4aac-a527-95a1b4f1fed0
diff --git a/src/xdisp.c b/src/xdisp.c
index 35a4d755577..779109b83ab 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -307,6 +307,7 @@ Lisp_Object Qline_height, Qtotal;
307extern Lisp_Object Qheight; 307extern Lisp_Object Qheight;
308extern Lisp_Object QCwidth, QCheight, QCascent; 308extern Lisp_Object QCwidth, QCheight, QCascent;
309extern Lisp_Object Qscroll_bar; 309extern Lisp_Object Qscroll_bar;
310extern Lisp_Object Qcursor;
310 311
311/* Non-nil means highlight trailing whitespace. */ 312/* Non-nil means highlight trailing whitespace. */
312 313
@@ -10747,6 +10748,7 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10747{ 10748{
10748 struct glyph *glyph = row->glyphs[TEXT_AREA]; 10749 struct glyph *glyph = row->glyphs[TEXT_AREA];
10749 struct glyph *end = glyph + row->used[TEXT_AREA]; 10750 struct glyph *end = glyph + row->used[TEXT_AREA];
10751 struct glyph *cursor = NULL;
10750 /* The first glyph that starts a sequence of glyphs from string. */ 10752 /* The first glyph that starts a sequence of glyphs from string. */
10751 struct glyph *string_start; 10753 struct glyph *string_start;
10752 /* The X coordinate of string_start. */ 10754 /* The X coordinate of string_start. */
@@ -10756,6 +10758,7 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10756 /* The last known character position before string_start. */ 10758 /* The last known character position before string_start. */
10757 int string_before_pos; 10759 int string_before_pos;
10758 int x = row->x; 10760 int x = row->x;
10761 int cursor_x = x;
10759 int pt_old = PT - delta; 10762 int pt_old = PT - delta;
10760 10763
10761 /* Skip over glyphs not having an object at the start of the row. 10764 /* Skip over glyphs not having an object at the start of the row.
@@ -10788,12 +10791,29 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10788 string_start = glyph; 10791 string_start = glyph;
10789 string_start_x = x; 10792 string_start_x = x;
10790 /* Skip all glyphs from string. */ 10793 /* Skip all glyphs from string. */
10791 SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object)); 10794 do
10795 {
10796 if ((cursor == NULL || glyph > cursor)
10797 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
10798 Qcursor, (glyph)->object)))
10799 {
10800 cursor = glyph;
10801 cursor_x = x;
10802 }
10803 x += glyph->pixel_width;
10804 ++glyph;
10805 }
10806 while (glyph < end && STRINGP (glyph->object));
10792 } 10807 }
10793 } 10808 }
10794 10809
10795 if (string_start 10810 if (cursor != NULL)
10796 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old)) 10811 {
10812 glyph = cursor;
10813 x = cursor_x;
10814 }
10815 else if (string_start
10816 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10797 { 10817 {
10798 /* We may have skipped over point because the previous glyphs 10818 /* We may have skipped over point because the previous glyphs
10799 are from string. As there's no easy way to know the 10819 are from string. As there's no easy way to know the
@@ -11185,8 +11205,8 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
11185 start_display (&it, w, startp); 11205 start_display (&it, w, startp);
11186 11206
11187 if (scroll_conservatively) 11207 if (scroll_conservatively)
11188 amount_to_scroll = 11208 amount_to_scroll
11189 max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step)); 11209 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11190 else if (scroll_step || temp_scroll_step) 11210 else if (scroll_step || temp_scroll_step)
11191 amount_to_scroll = scroll_max; 11211 amount_to_scroll = scroll_max;
11192 else 11212 else
@@ -11465,8 +11485,7 @@ try_cursor_movement (window, startp, scroll_step)
11465 else if (PT < XFASTINT (w->last_point)) 11485 else if (PT < XFASTINT (w->last_point))
11466 { 11486 {
11467 /* Cursor has to be moved backward. Note that PT >= 11487 /* Cursor has to be moved backward. Note that PT >=
11468 CHARPOS (startp) because of the outer 11488 CHARPOS (startp) because of the outer if-statement. */
11469 if-statement. */
11470 while (!row->mode_line_p 11489 while (!row->mode_line_p
11471 && (MATRIX_ROW_START_CHARPOS (row) > PT 11490 && (MATRIX_ROW_START_CHARPOS (row) > PT
11472 || (MATRIX_ROW_START_CHARPOS (row) == PT 11491 || (MATRIX_ROW_START_CHARPOS (row) == PT
@@ -11978,8 +11997,8 @@ redisplay_window (window, just_this_one_p)
11978 buffer. */ 11997 buffer. */
11979 || !NILP (Vwindow_scroll_functions) 11998 || !NILP (Vwindow_scroll_functions)
11980 || MINI_WINDOW_P (w) 11999 || MINI_WINDOW_P (w)
11981 || !(used_current_matrix_p = 12000 || !(used_current_matrix_p
11982 try_window_reusing_current_matrix (w))) 12001 = try_window_reusing_current_matrix (w)))
11983 { 12002 {
11984 IF_DEBUG (debug_method_add (w, "1")); 12003 IF_DEBUG (debug_method_add (w, "1"));
11985 try_window (window, startp); 12004 try_window (window, startp);
@@ -12108,8 +12127,8 @@ redisplay_window (window, just_this_one_p)
12108 || !NILP (Vwindow_scroll_functions) 12127 || !NILP (Vwindow_scroll_functions)
12109 || !just_this_one_p 12128 || !just_this_one_p
12110 || MINI_WINDOW_P (w) 12129 || MINI_WINDOW_P (w)
12111 || !(used_current_matrix_p = 12130 || !(used_current_matrix_p
12112 try_window_reusing_current_matrix (w))) 12131 = try_window_reusing_current_matrix (w)))
12113 try_window (window, startp); 12132 try_window (window, startp);
12114 12133
12115 /* If new fonts have been loaded (due to fontsets), give up. We 12134 /* If new fonts have been loaded (due to fontsets), give up. We
@@ -15774,7 +15793,8 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
15774 The mode_line_string_face face property is always added to the string. 15793 The mode_line_string_face face property is always added to the string.
15775 */ 15794 */
15776 15795
15777static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props) 15796static int
15797store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15778 char *string; 15798 char *string;
15779 Lisp_Object lisp_string; 15799 Lisp_Object lisp_string;
15780 int copy_string; 15800 int copy_string;
@@ -15886,32 +15906,32 @@ If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15886 15906
15887 if (NILP (format) || EQ (format, Qt)) 15907 if (NILP (format) || EQ (format, Qt))
15888 { 15908 {
15889 face_id = NILP (format) 15909 face_id = (NILP (format)
15890 ? CURRENT_MODE_LINE_FACE_ID (w) : 15910 ? CURRENT_MODE_LINE_FACE_ID (w)
15891 HEADER_LINE_FACE_ID; 15911 : HEADER_LINE_FACE_ID);
15892 format = NILP (format) 15912 format = (NILP (format)
15893 ? current_buffer->mode_line_format 15913 ? current_buffer->mode_line_format
15894 : current_buffer->header_line_format; 15914 : current_buffer->header_line_format);
15895 } 15915 }
15896 15916
15897 init_iterator (&it, w, -1, -1, NULL, face_id); 15917 init_iterator (&it, w, -1, -1, NULL, face_id);
15898 15918
15899 if (NILP (no_props)) 15919 if (NILP (no_props))
15900 { 15920 {
15901 mode_line_string_face = 15921 mode_line_string_face
15902 (face_id == MODE_LINE_FACE_ID ? Qmode_line : 15922 = (face_id == MODE_LINE_FACE_ID ? Qmode_line
15903 face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive : 15923 : face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive
15904 face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil); 15924 : face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15905 15925
15906 mode_line_string_face_prop = 15926 mode_line_string_face_prop
15907 NILP (mode_line_string_face) ? Qnil : 15927 = (NILP (mode_line_string_face) ? Qnil
15908 Fcons (Qface, Fcons (mode_line_string_face, Qnil)); 15928 : Fcons (Qface, Fcons (mode_line_string_face, Qnil)));
15909 15929
15910 /* We need a dummy last element in mode_line_string_list to 15930 /* We need a dummy last element in mode_line_string_list to
15911 indicate we are building the propertized mode-line string. 15931 indicate we are building the propertized mode-line string.
15912 Using mode_line_string_face_prop here GC protects it. */ 15932 Using mode_line_string_face_prop here GC protects it. */
15913 mode_line_string_list = 15933 mode_line_string_list
15914 Fcons (mode_line_string_face_prop, Qnil); 15934 = Fcons (mode_line_string_face_prop, Qnil);
15915 frame_title_ptr = NULL; 15935 frame_title_ptr = NULL;
15916 } 15936 }
15917 else 15937 else
@@ -21038,7 +21058,8 @@ note_mouse_highlight (f, x, y)
21038 21058
21039 if (part == ON_VERTICAL_BORDER) 21059 if (part == ON_VERTICAL_BORDER)
21040 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor; 21060 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21041 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE) 21061 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
21062 || part == ON_SCROLL_BAR)
21042 cursor = FRAME_X_OUTPUT (f)->nontext_cursor; 21063 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21043 else 21064 else
21044 cursor = FRAME_X_OUTPUT (f)->text_cursor; 21065 cursor = FRAME_X_OUTPUT (f)->text_cursor;
diff --git a/src/xfns.c b/src/xfns.c
index f392757b949..b0864cbdffe 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1540,61 +1540,15 @@ x_encode_text (string, coding_system, selectionp, text_bytes, stringp)
1540} 1540}
1541 1541
1542 1542
1543/* Change the name of frame F to NAME. If NAME is nil, set F's name to 1543/* Set the WM name to NAME for frame F. Also set the icon name.
1544 x_id_name. 1544 If the frame already has an icon name, use that, otherwise set the
1545 1545 icon name to NAME. */
1546 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1547 name; if NAME is a string, set F's name to NAME and set
1548 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1549 1546
1550 If EXPLICIT is zero, that indicates that Emacs redisplay code is 1547static void
1551 suggesting a new name, which lisp code should override; if 1548x_set_name_internal (f, name)
1552 F->explicit_name is set, ignore the new name; otherwise, set it. */ 1549 FRAME_PTR f;
1553
1554void
1555x_set_name (f, name, explicit)
1556 struct frame *f;
1557 Lisp_Object name; 1550 Lisp_Object name;
1558 int explicit;
1559{ 1551{
1560 /* Make sure that requests from lisp code override requests from
1561 Emacs redisplay code. */
1562 if (explicit)
1563 {
1564 /* If we're switching from explicit to implicit, we had better
1565 update the mode lines and thereby update the title. */
1566 if (f->explicit_name && NILP (name))
1567 update_mode_lines = 1;
1568
1569 f->explicit_name = ! NILP (name);
1570 }
1571 else if (f->explicit_name)
1572 return;
1573
1574 /* If NAME is nil, set the name to the x_id_name. */
1575 if (NILP (name))
1576 {
1577 /* Check for no change needed in this very common case
1578 before we do any consing. */
1579 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1580 SDATA (f->name)))
1581 return;
1582 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1583 }
1584 else
1585 CHECK_STRING (name);
1586
1587 /* Don't change the name if it's already NAME. */
1588 if (! NILP (Fstring_equal (name, f->name)))
1589 return;
1590
1591 f->name = name;
1592
1593 /* For setting the frame title, the title parameter should override
1594 the name parameter. */
1595 if (! NILP (f->title))
1596 name = f->title;
1597
1598 if (FRAME_X_WINDOW (f)) 1552 if (FRAME_X_WINDOW (f))
1599 { 1553 {
1600 BLOCK_INPUT; 1554 BLOCK_INPUT;
@@ -1602,8 +1556,10 @@ x_set_name (f, name, explicit)
1602 { 1556 {
1603 XTextProperty text, icon; 1557 XTextProperty text, icon;
1604 int bytes, stringp; 1558 int bytes, stringp;
1559 int do_free_icon_value = 0, do_free_text_value = 0;
1605 Lisp_Object coding_system; 1560 Lisp_Object coding_system;
1606 1561
1562 coding_system = Qcompound_text;
1607 /* Note: Encoding strategy 1563 /* Note: Encoding strategy
1608 1564
1609 We encode NAME by compound-text and use "COMPOUND-TEXT" in 1565 We encode NAME by compound-text and use "COMPOUND-TEXT" in
@@ -1618,13 +1574,16 @@ x_set_name (f, name, explicit)
1618 in the future which can encode all Unicode characters. 1574 in the future which can encode all Unicode characters.
1619 But, for the moment, there's no way to know that the 1575 But, for the moment, there's no way to know that the
1620 current window manager supports it or not. */ 1576 current window manager supports it or not. */
1621 coding_system = Qcompound_text;
1622 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp); 1577 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
1623 text.encoding = (stringp ? XA_STRING 1578 text.encoding = (stringp ? XA_STRING
1624 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT); 1579 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1625 text.format = 8; 1580 text.format = 8;
1626 text.nitems = bytes; 1581 text.nitems = bytes;
1627 1582
1583 /* Check early, because ENCODE_UTF_8 below may GC and name may be
1584 relocated. */
1585 do_free_text_value = text.value != SDATA (name);
1586
1628 if (NILP (f->icon_name)) 1587 if (NILP (f->icon_name))
1629 { 1588 {
1630 icon = text; 1589 icon = text;
@@ -1638,7 +1597,9 @@ x_set_name (f, name, explicit)
1638 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT); 1597 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1639 icon.format = 8; 1598 icon.format = 8;
1640 icon.nitems = bytes; 1599 icon.nitems = bytes;
1600 do_free_icon_value = icon.value != SDATA (f->icon_name);
1641 } 1601 }
1602
1642#ifdef USE_GTK 1603#ifdef USE_GTK
1643 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 1604 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1644 SDATA (ENCODE_UTF_8 (name))); 1605 SDATA (ENCODE_UTF_8 (name)));
@@ -1648,10 +1609,9 @@ x_set_name (f, name, explicit)
1648 1609
1649 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon); 1610 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1650 1611
1651 if (!NILP (f->icon_name) 1612 if (do_free_icon_value)
1652 && icon.value != (unsigned char *) SDATA (f->icon_name))
1653 xfree (icon.value); 1613 xfree (icon.value);
1654 if (text.value != (unsigned char *) SDATA (name)) 1614 if (do_free_text_value)
1655 xfree (text.value); 1615 xfree (text.value);
1656 } 1616 }
1657#else /* not HAVE_X11R4 */ 1617#else /* not HAVE_X11R4 */
@@ -1664,6 +1624,64 @@ x_set_name (f, name, explicit)
1664 } 1624 }
1665} 1625}
1666 1626
1627/* Change the name of frame F to NAME. If NAME is nil, set F's name to
1628 x_id_name.
1629
1630 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1631 name; if NAME is a string, set F's name to NAME and set
1632 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1633
1634 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1635 suggesting a new name, which lisp code should override; if
1636 F->explicit_name is set, ignore the new name; otherwise, set it. */
1637
1638void
1639x_set_name (f, name, explicit)
1640 struct frame *f;
1641 Lisp_Object name;
1642 int explicit;
1643{
1644 /* Make sure that requests from lisp code override requests from
1645 Emacs redisplay code. */
1646 if (explicit)
1647 {
1648 /* If we're switching from explicit to implicit, we had better
1649 update the mode lines and thereby update the title. */
1650 if (f->explicit_name && NILP (name))
1651 update_mode_lines = 1;
1652
1653 f->explicit_name = ! NILP (name);
1654 }
1655 else if (f->explicit_name)
1656 return;
1657
1658 /* If NAME is nil, set the name to the x_id_name. */
1659 if (NILP (name))
1660 {
1661 /* Check for no change needed in this very common case
1662 before we do any consing. */
1663 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1664 SDATA (f->name)))
1665 return;
1666 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1667 }
1668 else
1669 CHECK_STRING (name);
1670
1671 /* Don't change the name if it's already NAME. */
1672 if (! NILP (Fstring_equal (name, f->name)))
1673 return;
1674
1675 f->name = name;
1676
1677 /* For setting the frame title, the title parameter should override
1678 the name parameter. */
1679 if (! NILP (f->title))
1680 name = f->title;
1681
1682 x_set_name_internal (f, name);
1683}
1684
1667/* This function should be called when the user's lisp code has 1685/* This function should be called when the user's lisp code has
1668 specified a name for the frame; the name will override any set by the 1686 specified a name for the frame; the name will override any set by the
1669 redisplay code. */ 1687 redisplay code. */
@@ -1715,62 +1733,7 @@ x_set_title (f, name, old_name)
1715 else 1733 else
1716 CHECK_STRING (name); 1734 CHECK_STRING (name);
1717 1735
1718 if (FRAME_X_WINDOW (f)) 1736 x_set_name_internal (f, name);
1719 {
1720 BLOCK_INPUT;
1721#ifdef HAVE_X11R4
1722 {
1723 XTextProperty text, icon;
1724 int bytes, stringp;
1725 Lisp_Object coding_system;
1726
1727 coding_system = Qcompound_text;
1728 /* See the comment "Note: Encoding strategy" in x_set_name. */
1729 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
1730 text.encoding = (stringp ? XA_STRING
1731 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1732 text.format = 8;
1733 text.nitems = bytes;
1734
1735 if (NILP (f->icon_name))
1736 {
1737 icon = text;
1738 }
1739 else
1740 {
1741 /* See the comment "Note: Encoding strategy" in x_set_name. */
1742 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1743 &bytes, &stringp);
1744 icon.encoding = (stringp ? XA_STRING
1745 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1746 icon.format = 8;
1747 icon.nitems = bytes;
1748 }
1749
1750#ifdef USE_GTK
1751 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1752 SDATA (ENCODE_UTF_8 (name)));
1753#else /* not USE_GTK */
1754 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1755#endif /* not USE_GTK */
1756
1757 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1758 &icon);
1759
1760 if (!NILP (f->icon_name)
1761 && icon.value != (unsigned char *) SDATA (f->icon_name))
1762 xfree (icon.value);
1763 if (text.value != (unsigned char *) SDATA (name))
1764 xfree (text.value);
1765 }
1766#else /* not HAVE_X11R4 */
1767 XSetIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1768 SDATA (name));
1769 XStoreName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1770 SDATA (name));
1771#endif /* not HAVE_X11R4 */
1772 UNBLOCK_INPUT;
1773 }
1774} 1737}
1775 1738
1776void 1739void
diff --git a/src/xmenu.c b/src/xmenu.c
index 08bad9c2241..eddda3ef91b 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -1701,12 +1701,9 @@ digest_single_submenu (start, end, top_level_items)
1701 save_wv->next = wv; 1701 save_wv->next = wv;
1702 else 1702 else
1703 first_wv->contents = wv; 1703 first_wv->contents = wv;
1704 wv->name = pane_string; 1704 wv->lname = pane_name;
1705 /* Ignore the @ that means "separate pane". 1705 /* Set value to 1 so update_submenu_strings can handle '@' */
1706 This is a kludge, but this isn't worth more time. */ 1706 wv->value = (char *)1;
1707 if (!NILP (prefix) && wv->name[0] == '@')
1708 wv->name++;
1709 wv->value = 0;
1710 wv->enabled = 1; 1707 wv->enabled = 1;
1711 wv->button_type = BUTTON_TYPE_NONE; 1708 wv->button_type = BUTTON_TYPE_NONE;
1712 wv->help = Qnil; 1709 wv->help = Qnil;
@@ -1749,9 +1746,9 @@ digest_single_submenu (start, end, top_level_items)
1749 else 1746 else
1750 save_wv->contents = wv; 1747 save_wv->contents = wv;
1751 1748
1752 wv->name = (char *) SDATA (item_name); 1749 wv->lname = item_name;
1753 if (!NILP (descrip)) 1750 if (!NILP (descrip))
1754 wv->key = (char *) SDATA (descrip); 1751 wv->lkey = descrip;
1755 wv->value = 0; 1752 wv->value = 0;
1756 /* The EMACS_INT cast avoids a warning. There's no problem 1753 /* The EMACS_INT cast avoids a warning. There's no problem
1757 as long as pointers have enough bits to hold small integers. */ 1754 as long as pointers have enough bits to hold small integers. */
@@ -1790,6 +1787,42 @@ digest_single_submenu (start, end, top_level_items)
1790 1787
1791 return first_wv; 1788 return first_wv;
1792} 1789}
1790
1791/* Walk through the widget_value tree starting at FIRST_WV and update
1792 the char * pointers from the corresponding lisp values.
1793 We do this after building the whole tree, since GC may happen while the
1794 tree is constructed, and small strings are relocated. So we must wait
1795 until no GC can happen before storing pointers into lisp values. */
1796static void
1797update_submenu_strings (first_wv)
1798 widget_value *first_wv;
1799{
1800 widget_value *wv;
1801
1802 for (wv = first_wv; wv; wv = wv->next)
1803 {
1804 if (wv->lname && ! NILP (wv->lname))
1805 {
1806 wv->name = SDATA (wv->lname);
1807
1808 /* Ignore the @ that means "separate pane".
1809 This is a kludge, but this isn't worth more time. */
1810 if (wv->value == (char *)1)
1811 {
1812 if (wv->name[0] == '@')
1813 wv->name++;
1814 wv->value = 0;
1815 }
1816 }
1817
1818 if (wv->lkey && ! NILP (wv->lkey))
1819 wv->key = SDATA (wv->lkey);
1820
1821 if (wv->contents)
1822 update_submenu_strings (wv->contents);
1823 }
1824}
1825
1793 1826
1794/* Recompute all the widgets of frame F, when the menu bar has been 1827/* Recompute all the widgets of frame F, when the menu bar has been
1795 changed. Value is non-zero if widgets were updated. */ 1828 changed. Value is non-zero if widgets were updated. */
@@ -2022,9 +2055,10 @@ set_frame_menubar (f, first_time, deep_p)
2022 Lisp_Object string; 2055 Lisp_Object string;
2023 string = XVECTOR (items)->contents[i + 1]; 2056 string = XVECTOR (items)->contents[i + 1];
2024 if (NILP (string)) 2057 if (NILP (string))
2025 break; 2058 break;
2026 wv->name = (char *) SDATA (string); 2059 wv->name = (char *) SDATA (string);
2027 wv = wv->next; 2060 update_submenu_strings (wv->contents);
2061 wv = wv->next;
2028 } 2062 }
2029 2063
2030 f->menu_bar_vector = menu_items; 2064 f->menu_bar_vector = menu_items;