aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKaroly Lorentey2005-12-29 04:41:02 +0000
committerKaroly Lorentey2005-12-29 04:41:02 +0000
commite583523a108624f7fd0c28294010b19daae5ab97 (patch)
tree6bbb60c1f603809ca8980a459e0c4ed6d2c02378 /src
parentda8e8fc14f3166ec596e34f43fbfea866d1176df (diff)
parentd52c26e925297a2d1663e2293d46ce95e91c4689 (diff)
downloademacs-e583523a108624f7fd0c28294010b19daae5ab97.tar.gz
emacs-e583523a108624f7fd0c28294010b19daae5ab97.zip
Merged from miles@gnu.org--gnu-2005 (patch 678-680)
Patches applied: * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-678 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-679 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-680 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-468
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog138
-rw-r--r--src/gtkutil.c24
-rw-r--r--src/gtkutil.h2
-rw-r--r--src/image.c16
-rw-r--r--src/insdel.c30
-rw-r--r--src/m/amdx86-64.h27
-rw-r--r--src/mac.c355
-rw-r--r--src/macfns.c69
-rw-r--r--src/macgui.h21
-rw-r--r--src/macmenu.c445
-rw-r--r--src/macterm.c612
-rw-r--r--src/macterm.h7
-rw-r--r--src/minibuf.c22
-rw-r--r--src/xfns.c22
-rw-r--r--src/xmenu.c5
15 files changed, 1167 insertions, 628 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 969f9f6c46d..f14f216f1d3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,118 @@
12005-12-25 Giorgos Keramidas <keramida@ceid.upatras.gr>
2
3 * m/amdx86-64.h [__FreeBSD__] (START_FILES, LIB_STANDARD):
4 define for FreeBSD on this platform.
5
62005-12-24 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
7
8 * macterm.h (TYPE_FILE_NAME): New define.
9 (posix_pathname_to_fsspec, fsspec_to_posix_pathname): Remove externs.
10
11 * mac.c (posix_pathname_to_fsspec, fsspec_to_posix_pathname): Add
12 prototypes. Make static.
13 (mac_aedesc_to_lisp): Initialize err to noErr.
14 (mac_coerce_file_name_ptr, mac_coerce_file_name_desc)
15 (init_coercion_handler): New functions.
16 (Fmac_coerce_ae_data): Use coercion of Apple event data for
17 translation from/to file names.
18
19 * macterm.c: Don't include sys/param.h.
20 (init_coercion_handler): Add extern.
21 [MAC_OS8] (main): Call init_coercion_handler.
22 (mac_initialize) [MAC_OSX]: Likewise.
23 [TARGET_API_MAC_CARBON] (mac_do_receive_drag): Use coercion of
24 Apple event data for translation from/to file names.
25
26 * macfns.c [TARGET_API_MAC_CARBON] (Fx_file_dialog): Likewise.
27
28 * image.c [MAC_OS] (find_image_fsspec): Likewise.
29
302005-12-23 Martin Rudalics <rudalics@gmx.at> (tiny change)
31
32 * insdel.c (insert, insert_and_inherit, insert_before_markers)
33 (insert_before_markers_and_inherit): Make sure FROM is correct
34 when `after-change-functions' are called.
35
362005-12-23 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
37
38 * xfns.c (Fx_uses_old_gtk_dialog): New function.
39
40 * gtkutil.c (xg_uses_old_file_dialog): New function.
41 (xg_get_file_name): Use xg_uses_old_file_dialog.
42
43 * gtkutil.h: Declare xg_uses_old_file_dialog.
44
452005-12-22 Richard M. Stallman <rms@gnu.org>
46
47 * xmenu.c (xmenu_show): Call inhibit_garbage_collection.
48
492005-12-22 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
50
51 * mac.c (Fmac_coerce_ae_data) [MAC_OSX]: Fix memory leak.
52
53 * macgui.h (XCharStruct): Remove member `valid_p'.
54 (STORE_XCHARSTRUCT): Don't set member `valid_p'.
55 (XCharStructRow): New typedef.
56 (XCHARSTRUCTROW_CHAR_VALID_P, XCHARSTRUCTROW_SET_CHAR_VALID): New
57 macros.
58 (struct MacFontStruct): Add member `bounds'. Remove member
59 `per_char'. All uses for QuichDraw Text fonts are changed to
60 `bounds.per_char'. ATSUI font bounds are represented as an array
61 `bounds.rows' of XCharStructRow's, each of which consists of a
62 bitmap of valid entries and an array of char bounds.
63
64 * macterm.c (mac_per_char_metric): Add prototype.
65 (x_per_char_metric) [USE_CG_TEXT_DRAWING]: Remove prototype.
66 (mac_query_char_extents): New function.
67 (x_per_char_metric): Use it.
68 (XLoadQueryFont): Likewise. Consolidate min/max_bounds calculations.
69 [USE_CG_TEXT_DRAWING] (mac_draw_string_cg): Use
70 mac_per_char_metric instead of x_per_char_metric.
71 (mac_text_extents_16): New function.
72 (mac_compute_glyph_string_overhangs): Use it.
73 (mac_unload_font): Free member `bounds' in struct MacFontStruct.
74
752005-12-21 Stefan Monnier <monnier@iro.umontreal.ca>
76
77 * minibuf.c (Fdisplay_completion_list): Use XCAR/XCDR.
78 (Fminibuffer_completion_help): Remove duplicates before display.
79
802005-12-21 L$,1 q(Brentey K,Aa(Broly <lorentey@elte.hu>
81
82 * print.c (print_preprocess): Don't lose print_depth levels while
83 iterating.
84
852005-12-21 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
86
87 * macmenu.c (Qmac_apple_event): Add extern.
88 (set_frame_menubar, mac_menu_show keymp_panes)
89 (single_keymap_panes, list_of_panes, list_of_item)
90 (single_menu_item): Add argument types to prototypes.
91 (mac_dialog_show) [HAVE_DIALOGS]: Likewise.
92 (struct skp): New struct (from xmenu.c).
93 (single_keymap_panes, single_menu_item, list_of_panes)
94 (list_of_item): Sync with xmenu.c.
95 (Fx_popup_menu, Fx_popup_dialog): Likewise. Don't get window from
96 POSITION if it is mac-apple-event event.
97 (menubar_selection_callback): Don't use menu_command_in_progress.
98 (set_frame_menubar): First parse all submenus, then make
99 widget_value trees from them. Don't allocate any widget_value
100 objects until we are done with the parsing.
101 (parse_single_submenu, digest_single_submenu): New functions.
102 (single_submenu): Function deleted, replaced by those two.
103 (install_menu_quit_handler) [HAVE_CANCELMENUTRACKING]: Don't
104 create or dispose of EventHandlerUPP. Install hander to all submenus.
105 (mac_menu_show) [!HAVE_MULTILINGUAL_MENU]: Use ENCODE_MENU_STRING
106 instead of ENCODE_SYSTEM.
107 (free_frame_menubar, fill_submenu, fill_menu): Don't use NULL for
108 integer values.
109 [HAVE_DIALOGS] (mac_dialog_show): Sync with xdialog_show (in xmenu.c).
110 (add_menu_item) [TARGET_API_MAC_CARBON]: Use CFString functions to
111 format menu item string. Don't use NULL for integer value.
112
113 * macterm.h (struct mac_output): Remove unused member
114 menu_command_in_progress.
115
12005-12-20 Juri Linkov <juri@jurta.org> 1162005-12-20 Juri Linkov <juri@jurta.org>
2 117
3 * xmenu.c (Fx_popup_menu): Set Vmenu_updating_frame to f if 118 * xmenu.c (Fx_popup_menu): Set Vmenu_updating_frame to f if
@@ -25,15 +140,15 @@
25 (x_use_underline_position_properties): Undo 2005-07-13 change. 140 (x_use_underline_position_properties): Undo 2005-07-13 change.
26 (syms_of_macterm) <x-use-underline-position-properties>: Likewise. 141 (syms_of_macterm) <x-use-underline-position-properties>: Likewise.
27 (mac_use_core_graphics, mac_wheel_button_is_mouse_2) 142 (mac_use_core_graphics, mac_wheel_button_is_mouse_2)
28 (mac_pass_command_to_system, mac_pass_control_to_system): New 143 (mac_pass_command_to_system, mac_pass_control_to_system):
29 boolean variables renamed from Lisp_Object ones 144 New boolean variables renamed from Lisp_Object ones
30 Vmac_use_core_graphics, Vmac_wheel_button_is_mouse_2, 145 Vmac_use_core_graphics, Vmac_wheel_button_is_mouse_2,
31 Vmac_pass_command_to_system, and Vmac_pass_control_to_system. All 146 Vmac_pass_command_to_system, and Vmac_pass_control_to_system.
32 uses changed. 147 All uses changed.
33 (syms_of_macterm): DEFVAR_BOOL them. Remove previous DEFVAR_LISPs. 148 (syms_of_macterm): DEFVAR_BOOL them. Remove previous DEFVAR_LISPs.
34 Make them user options. 149 Make them user options.
35 (mac_handle_command_event, mac_store_services_event): Call 150 (mac_handle_command_event, mac_store_services_event):
36 create_apple_event_from_event_ref without 5th argument. 151 Call create_apple_event_from_event_ref without 5th argument.
37 (backtranslate_modified_keycode): Mask off modifier keys that are 152 (backtranslate_modified_keycode): Mask off modifier keys that are
38 mapped to some Emacs modifiers before passing it to KeyTranslate. 153 mapped to some Emacs modifiers before passing it to KeyTranslate.
39 (syms_of_macterm): Make variables `mac-emulate-three-button-mouse', 154 (syms_of_macterm): Make variables `mac-emulate-three-button-mouse',
@@ -41,8 +156,8 @@
41 Fix docstrings of `mac-*-modifier'. 156 Fix docstrings of `mac-*-modifier'.
42 157
43 * mac.c (create_apple_event_from_event_ref): Remove arg `types'. 158 * mac.c (create_apple_event_from_event_ref): Remove arg `types'.
44 (do_applescript): Change argument types to Lisp_Object. All uses 159 (do_applescript): Change argument types to Lisp_Object.
45 changed. 160 All uses changed.
46 161
47 * macterm.h (create_apple_event_from_event_ref): Remove 5th 162 * macterm.h (create_apple_event_from_event_ref): Remove 5th
48 argument from extern. 163 argument from extern.
@@ -85,9 +200,9 @@
85 200
86 * xfns.c (compute_tip_xy): Handle negative dx and dy. 201 * xfns.c (compute_tip_xy): Handle negative dx and dy.
87 202
88 * w32fns.c (compute_tip_xy): Ditto 203 * w32fns.c (compute_tip_xy): Ditto.
89 204
90 * macfns.c (compute_tip_xy): Ditto 205 * macfns.c (compute_tip_xy): Ditto.
91 206
922005-12-14 Chong Yidong <cyd@stupidchicken.com> 2072005-12-14 Chong Yidong <cyd@stupidchicken.com>
93 208
@@ -165,8 +280,7 @@
165 * mac.c (Qundecoded_file_name): New variable. 280 * mac.c (Qundecoded_file_name): New variable.
166 (syms_of_mac): Initialize it. 281 (syms_of_mac): Initialize it.
167 (mac_aelist_to_lisp, mac_aedesc_to_lisp): New functions. 282 (mac_aelist_to_lisp, mac_aedesc_to_lisp): New functions.
168 [TARGET_API_MAC_CARBON] (create_apple_event_from_event_ref): New 283 [TARGET_API_MAC_CARBON] (create_apple_event_from_event_ref): New fun.
169 function.
170 (Fmac_coerce_ae_data): New defun. 284 (Fmac_coerce_ae_data): New defun.
171 (syms_of_mac): Defsubr it. 285 (syms_of_mac): Defsubr it.
172 286
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 54cb43b8398..9da3c5bf457 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1155,6 +1155,27 @@ create_dialog (wv, select_cb, deactivate_cb)
1155/*********************************************************************** 1155/***********************************************************************
1156 File dialog functions 1156 File dialog functions
1157 ***********************************************************************/ 1157 ***********************************************************************/
1158/* Return non-zero if the old file selection dialog is being used.
1159 Return zero if not. */
1160
1161int
1162xg_uses_old_file_dialog ()
1163{
1164#ifdef HAVE_GTK_FILE_BOTH
1165 extern int x_use_old_gtk_file_dialog;
1166 return x_use_old_gtk_file_dialog;
1167#else /* ! HAVE_GTK_FILE_BOTH */
1168
1169#ifdef HAVE_GTK_FILE_SELECTION_NEW
1170 return 1;
1171#else
1172 return 0;
1173#endif
1174
1175#endif /* ! HAVE_GTK_FILE_BOTH */
1176}
1177
1178
1158/* Function that is called when the file dialog pops down. 1179/* Function that is called when the file dialog pops down.
1159 W is the dialog widget, RESPONSE is the response code. 1180 W is the dialog widget, RESPONSE is the response code.
1160 USER_DATA is what we passed in to g_signal_connect (pointer to int). */ 1181 USER_DATA is what we passed in to g_signal_connect (pointer to int). */
@@ -1343,7 +1364,6 @@ xg_get_file_name (f, prompt, default_filename, mustmatch_p, only_dir_p)
1343 char *fn = 0; 1364 char *fn = 0;
1344 int filesel_done = 0; 1365 int filesel_done = 0;
1345 xg_get_file_func func; 1366 xg_get_file_func func;
1346 extern int x_use_old_gtk_file_dialog;
1347 1367
1348#if defined (HAVE_GTK_AND_PTHREAD) && defined (__SIGRTMIN) 1368#if defined (HAVE_GTK_AND_PTHREAD) && defined (__SIGRTMIN)
1349 /* I really don't know why this is needed, but without this the GLIBC add on 1369 /* I really don't know why this is needed, but without this the GLIBC add on
@@ -1354,7 +1374,7 @@ xg_get_file_name (f, prompt, default_filename, mustmatch_p, only_dir_p)
1354 1374
1355#ifdef HAVE_GTK_FILE_BOTH 1375#ifdef HAVE_GTK_FILE_BOTH
1356 1376
1357 if (x_use_old_gtk_file_dialog) 1377 if (xg_uses_old_file_dialog ())
1358 w = xg_get_file_with_selection (f, prompt, default_filename, 1378 w = xg_get_file_with_selection (f, prompt, default_filename,
1359 mustmatch_p, only_dir_p, &func); 1379 mustmatch_p, only_dir_p, &func);
1360 else 1380 else
diff --git a/src/gtkutil.h b/src/gtkutil.h
index aea4ee9e7cf..6b9fd179ec5 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -132,6 +132,8 @@ extern int use_old_gtk_file_dialog;
132extern widget_value *malloc_widget_value P_ ((void)); 132extern widget_value *malloc_widget_value P_ ((void));
133extern void free_widget_value P_ ((widget_value *)); 133extern void free_widget_value P_ ((widget_value *));
134 134
135extern int xg_uses_old_file_dialog P_ ((void));
136
135extern char *xg_get_file_name P_ ((FRAME_PTR f, 137extern char *xg_get_file_name P_ ((FRAME_PTR f,
136 char *prompt, 138 char *prompt,
137 char *default_filename, 139 char *default_filename,
diff --git a/src/image.c b/src/image.c
index 8a6d40ae34f..579c04e6f46 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2259,23 +2259,25 @@ find_image_fsspec (specified_file, file, fss)
2259 Lisp_Object specified_file, *file; 2259 Lisp_Object specified_file, *file;
2260 FSSpec *fss; 2260 FSSpec *fss;
2261{ 2261{
2262#if MAC_OSX
2263 FSRef fsr;
2264#endif
2265 OSErr err; 2262 OSErr err;
2263 AEDesc desc;
2266 2264
2267 *file = x_find_image_file (specified_file); 2265 *file = x_find_image_file (specified_file);
2268 if (!STRINGP (*file)) 2266 if (!STRINGP (*file))
2269 return fnfErr; /* file or directory not found; 2267 return fnfErr; /* file or directory not found;
2270 incomplete pathname */ 2268 incomplete pathname */
2271 /* Try to open the image file. */ 2269 /* Try to open the image file. */
2272#if MAC_OSX 2270 err = AECoercePtr (TYPE_FILE_NAME, SDATA (*file),
2273 err = FSPathMakeRef (SDATA (*file), &fsr, NULL); 2271 SBYTES (*file), typeFSS, &desc);
2274 if (err == noErr) 2272 if (err == noErr)
2275 err = FSGetCatalogInfo (&fsr, kFSCatInfoNone, NULL, NULL, fss, NULL); 2273 {
2274#if TARGET_API_MAC_CARBON
2275 err = AEGetDescData (&desc, fss, sizeof (FSSpec));
2276#else 2276#else
2277 err = posix_pathname_to_fsspec (SDATA (*file), fss); 2277 *fss = *(FSSpec *)(*(desc.dataHandle));
2278#endif 2278#endif
2279 AEDisposeDesc (&desc);
2280 }
2279 return err; 2281 return err;
2280} 2282}
2281 2283
diff --git a/src/insdel.c b/src/insdel.c
index fd416037241..a63dce14928 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -749,9 +749,10 @@ insert (string, nbytes)
749{ 749{
750 if (nbytes > 0) 750 if (nbytes > 0)
751 { 751 {
752 int opoint = PT; 752 int len = chars_in_text (string, nbytes), opoint;
753 insert_1 (string, nbytes, 0, 1, 0); 753 insert_1_both (string, len, nbytes, 0, 1, 0);
754 signal_after_change (opoint, 0, PT - opoint); 754 opoint = PT - len;
755 signal_after_change (opoint, 0, len);
755 update_compositions (opoint, PT, CHECK_BORDER); 756 update_compositions (opoint, PT, CHECK_BORDER);
756 } 757 }
757} 758}
@@ -765,9 +766,10 @@ insert_and_inherit (string, nbytes)
765{ 766{
766 if (nbytes > 0) 767 if (nbytes > 0)
767 { 768 {
768 int opoint = PT; 769 int len = chars_in_text (string, nbytes), opoint;
769 insert_1 (string, nbytes, 1, 1, 0); 770 insert_1_both (string, len, nbytes, 1, 1, 0);
770 signal_after_change (opoint, 0, PT - opoint); 771 opoint = PT - len;
772 signal_after_change (opoint, 0, len);
771 update_compositions (opoint, PT, CHECK_BORDER); 773 update_compositions (opoint, PT, CHECK_BORDER);
772 } 774 }
773} 775}
@@ -813,10 +815,10 @@ insert_before_markers (string, nbytes)
813{ 815{
814 if (nbytes > 0) 816 if (nbytes > 0)
815 { 817 {
816 int opoint = PT; 818 int len = chars_in_text (string, nbytes), opoint;
817 819 insert_1_both (string, len, nbytes, 0, 1, 1);
818 insert_1 (string, nbytes, 0, 1, 1); 820 opoint = PT - len;
819 signal_after_change (opoint, 0, PT - opoint); 821 signal_after_change (opoint, 0, len);
820 update_compositions (opoint, PT, CHECK_BORDER); 822 update_compositions (opoint, PT, CHECK_BORDER);
821 } 823 }
822} 824}
@@ -830,10 +832,10 @@ insert_before_markers_and_inherit (string, nbytes)
830{ 832{
831 if (nbytes > 0) 833 if (nbytes > 0)
832 { 834 {
833 int opoint = PT; 835 int len = chars_in_text (string, nbytes), opoint;
834 836 insert_1_both (string, len, nbytes, 1, 1, 1);
835 insert_1 (string, nbytes, 1, 1, 1); 837 opoint = PT - len;
836 signal_after_change (opoint, 0, PT - opoint); 838 signal_after_change (opoint, 0, len);
837 update_compositions (opoint, PT, CHECK_BORDER); 839 update_compositions (opoint, PT, CHECK_BORDER);
838 } 840 }
839} 841}
diff --git a/src/m/amdx86-64.h b/src/m/amdx86-64.h
index 2d7d86ce7c3..14ddd16406e 100644
--- a/src/m/amdx86-64.h
+++ b/src/m/amdx86-64.h
@@ -100,11 +100,38 @@ Boston, MA 02110-1301, USA. */
100/* Define XPNTR to avoid or'ing with DATA_SEG_BITS */ 100/* Define XPNTR to avoid or'ing with DATA_SEG_BITS */
101#undef DATA_SEG_BITS 101#undef DATA_SEG_BITS
102 102
103#ifdef __FreeBSD__
104
105/* The libraries for binaries native to the build host's architecture are
106 installed under /usr/lib in FreeBSD, and the ones that need special paths
107 are 32-bit compatibility libraries (installed under /usr/lib32). To build
108 a native binary of Emacs on FreeBSD/amd64 we can just point to /usr/lib. */
109
110#undef START_FILES
111#define START_FILES pre-crt0.o /usr/lib/crt1.o /usr/lib/crti.o
112
113/* The duplicate -lgcc is intentional in the definition of LIB_STANDARD.
114 The reason is that some functions in libgcc.a call functions from libc.a,
115 and some libc.a functions need functions from libgcc.a. Since most
116 versions of ld are one-pass linkers, we need to mention -lgcc twice,
117 or else we risk getting unresolved externals. */
118#undef LIB_STANDARD
119#define LIB_STANDARD -lgcc -lc -lgcc /usr/lib/crtn.o
120
121#else /* !__FreeBSD__ */
122
103#undef START_FILES 123#undef START_FILES
104#define START_FILES pre-crt0.o /usr/lib64/crt1.o /usr/lib64/crti.o 124#define START_FILES pre-crt0.o /usr/lib64/crt1.o /usr/lib64/crti.o
105 125
126/* The duplicate -lgcc is intentional in the definition of LIB_STANDARD.
127 The reason is that some functions in libgcc.a call functions from libc.a,
128 and some libc.a functions need functions from libgcc.a. Since most
129 versions of ld are one-pass linkers, we need to mention -lgcc twice,
130 or else we risk getting unresolved externals. */
106#undef LIB_STANDARD 131#undef LIB_STANDARD
107#define LIB_STANDARD -lgcc -lc -lgcc /usr/lib64/crtn.o 132#define LIB_STANDARD -lgcc -lc -lgcc /usr/lib64/crtn.o
108 133
134#endif /* __FreeBSD__ */
135
109/* arch-tag: 8a5e001d-e12e-4692-a3a6-0b15ba271c6e 136/* arch-tag: 8a5e001d-e12e-4692-a3a6-0b15ba271c6e
110 (do not change this comment) */ 137 (do not change this comment) */
diff --git a/src/mac.c b/src/mac.c
index d81c6d6a0ae..7c3e495f3a9 100644
--- a/src/mac.c
+++ b/src/mac.c
@@ -79,6 +79,8 @@ static ComponentInstance as_scripting_component;
79/* The single script context used for all script executions. */ 79/* The single script context used for all script executions. */
80static OSAID as_script_context; 80static OSAID as_script_context;
81 81
82static OSErr posix_pathname_to_fsspec P_ ((const char *, FSSpec *));
83static OSErr fsspec_to_posix_pathname P_ ((const FSSpec *, char *, int));
82 84
83/* When converting from Mac to Unix pathnames, /'s in folder names are 85/* When converting from Mac to Unix pathnames, /'s in folder names are
84 converted to :'s. This function, used in copying folder names, 86 converted to :'s. This function, used in copying folder names,
@@ -333,7 +335,7 @@ Lisp_Object
333mac_aedesc_to_lisp (desc) 335mac_aedesc_to_lisp (desc)
334 AEDesc *desc; 336 AEDesc *desc;
335{ 337{
336 OSErr err; 338 OSErr err = noErr;
337 DescType desc_type = desc->descriptorType; 339 DescType desc_type = desc->descriptorType;
338 Lisp_Object result; 340 Lisp_Object result;
339 341
@@ -397,6 +399,277 @@ mac_aedesc_to_lisp (desc)
397 return Fcons (make_unibyte_string ((char *) &desc_type, 4), result); 399 return Fcons (make_unibyte_string ((char *) &desc_type, 4), result);
398} 400}
399 401
402static pascal OSErr
403mac_coerce_file_name_ptr (type_code, data_ptr, data_size,
404 to_type, handler_refcon, result)
405 DescType type_code;
406 const void *data_ptr;
407 Size data_size;
408 DescType to_type;
409 long handler_refcon;
410 AEDesc *result;
411{
412 OSErr err;
413
414 if (type_code == TYPE_FILE_NAME)
415 /* Coercion from undecoded file name. */
416 switch (to_type)
417 {
418 case typeAlias:
419 case typeFSS:
420 case typeFSRef:
421#ifdef MAC_OSX
422 case typeFileURL:
423#endif
424 {
425#ifdef MAC_OSX
426 CFStringRef str;
427 CFURLRef url = NULL;
428 CFDataRef data = NULL;
429
430 str = CFStringCreateWithBytes (NULL, data_ptr, data_size,
431 kCFStringEncodingUTF8, false);
432 if (str)
433 {
434 url = CFURLCreateWithFileSystemPath (NULL, str,
435 kCFURLPOSIXPathStyle, false);
436 CFRelease (str);
437 }
438 if (url)
439 {
440 data = CFURLCreateData (NULL, url, kCFStringEncodingUTF8, true);
441 CFRelease (url);
442 }
443 if (data)
444 {
445 err = AECoercePtr (typeFileURL, CFDataGetBytePtr (data),
446 CFDataGetLength (data), to_type, result);
447 CFRelease (data);
448 }
449 else
450 err = memFullErr;
451#else
452 FSSpec fs;
453 char *buf;
454
455 buf = xmalloc (data_size + 1);
456 if (buf)
457 {
458 memcpy (buf, data_ptr, data_size);
459 buf[data_size] = '\0';
460 err = posix_pathname_to_fsspec (buf, &fs);
461 xfree (buf);
462 }
463 else
464 err = memFullErr;
465 if (err == noErr)
466 err = AECoercePtr (typeFSS, &fs, sizeof (FSSpec),
467 to_type, result);
468#endif
469 }
470 break;
471
472 case TYPE_FILE_NAME:
473 case typeWildCard:
474 err = AECreateDesc (TYPE_FILE_NAME, data_ptr, data_size, result);
475 break;
476
477 default:
478 err = errAECoercionFail;
479 break;
480 }
481 else if (to_type == TYPE_FILE_NAME)
482 /* Coercion to undecoded file name. */
483 switch (type_code)
484 {
485 case typeAlias:
486 case typeFSS:
487 case typeFSRef:
488#ifdef MAC_OSX
489 case typeFileURL:
490#endif
491 {
492 AEDesc desc;
493#ifdef MAC_OSX
494 Size size;
495 char *buf;
496 CFURLRef url = NULL;
497 CFStringRef str = NULL;
498 CFDataRef data = NULL;
499
500 err = AECoercePtr (type_code, data_ptr, data_size,
501 typeFileURL, &desc);
502 if (err == noErr)
503 {
504 size = AEGetDescDataSize (&desc);
505 buf = xmalloc (size);
506 if (buf)
507 {
508 err = AEGetDescData (&desc, buf, size);
509 if (err == noErr)
510 url = CFURLCreateWithBytes (NULL, buf, size,
511 kCFStringEncodingUTF8, NULL);
512 xfree (buf);
513 }
514 AEDisposeDesc (&desc);
515 }
516 if (url)
517 {
518 str = CFURLCopyFileSystemPath (url, kCFURLPOSIXPathStyle);
519 CFRelease (url);
520 }
521 if (str)
522 {
523 data =
524 CFStringCreateExternalRepresentation (NULL, str,
525 kCFStringEncodingUTF8,
526 '\0');
527 CFRelease (str);
528 }
529 if (data)
530 {
531 err = AECreateDesc (TYPE_FILE_NAME, CFDataGetBytePtr (data),
532 CFDataGetLength (data), result);
533 CFRelease (data);
534 }
535 else
536 err = memFullErr;
537#else
538 FSSpec fs;
539 char file_name[MAXPATHLEN];
540
541 err = AECoercePtr (type_code, data_ptr, data_size,
542 typeFSS, &desc);
543 if (err == noErr)
544 {
545#if TARGET_API_MAC_CARBON
546 err = AEGetDescData (&desc, &fs, sizeof (FSSpec));
547#else
548 fs = *(FSSpec *)(*(desc.dataHandle));
549#endif
550 if (err == noErr)
551 err = fsspec_to_posix_pathname (&fs, file_name,
552 sizeof (file_name) - 1);
553 if (err == noErr)
554 err = AECreateDesc (TYPE_FILE_NAME, file_name,
555 strlen (file_name), result);
556 AEDisposeDesc (&desc);
557 }
558#endif
559 }
560 break;
561
562 default:
563 err = errAECoercionFail;
564 break;
565 }
566 else
567 abort ();
568
569 if (err != noErr)
570 return errAECoercionFail;
571 return noErr;
572}
573
574static pascal OSErr
575mac_coerce_file_name_desc (from_desc, to_type, handler_refcon, result)
576 const AEDesc *from_desc;
577 DescType to_type;
578 long handler_refcon;
579 AEDesc *result;
580{
581 OSErr err = noErr;
582 DescType from_type = from_desc->descriptorType;
583
584 if (from_type == TYPE_FILE_NAME)
585 {
586 if (to_type != TYPE_FILE_NAME && to_type != typeWildCard
587 && to_type != typeAlias && to_type != typeFSS
588 && to_type != typeFSRef
589#ifdef MAC_OSX
590 && to_type != typeFileURL
591#endif
592 )
593 return errAECoercionFail;
594 }
595 else if (to_type == TYPE_FILE_NAME)
596 {
597 if (from_type != typeAlias && from_type != typeFSS
598 && from_type != typeFSRef
599#ifdef MAC_OSX
600 && from_type != typeFileURL
601#endif
602 )
603 return errAECoercionFail;
604 }
605 else
606 abort ();
607
608 if (from_type == to_type || to_type == typeWildCard)
609 err = AEDuplicateDesc (from_desc, result);
610 else
611 {
612 char *data_ptr;
613 Size data_size;
614
615#if TARGET_API_MAC_CARBON
616 data_size = AEGetDescDataSize (from_desc);
617#else
618 data_size = GetHandleSize (from_desc->dataHandle);
619#endif
620 data_ptr = xmalloc (data_size);
621 if (data_ptr)
622 {
623#if TARGET_API_MAC_CARBON
624 err = AEGetDescData (from_desc, data_ptr, data_size);
625#else
626 memcpy (data_ptr, *(from_desc->dataHandle), data_size);
627#endif
628 if (err == noErr)
629 err = mac_coerce_file_name_ptr (from_type, data_ptr,
630 data_size, to_type,
631 handler_refcon, result);
632 xfree (data_ptr);
633 }
634 else
635 err = memFullErr;
636 }
637
638 if (err != noErr)
639 return errAECoercionFail;
640 return noErr;
641}
642
643OSErr
644init_coercion_handler ()
645{
646 OSErr err;
647
648 static AECoercePtrUPP coerce_file_name_ptrUPP = NULL;
649 static AECoerceDescUPP coerce_file_name_descUPP = NULL;
650
651 if (coerce_file_name_ptrUPP == NULL)
652 {
653 coerce_file_name_ptrUPP = NewAECoercePtrUPP (mac_coerce_file_name_ptr);
654 coerce_file_name_descUPP = NewAECoerceDescUPP (mac_coerce_file_name_desc);
655 }
656
657 err = AEInstallCoercionHandler (TYPE_FILE_NAME, typeWildCard,
658 (AECoercionHandlerUPP)
659 coerce_file_name_ptrUPP, 0, false, false);
660 if (err == noErr)
661 err = AEInstallCoercionHandler (typeWildCard, TYPE_FILE_NAME,
662 (AECoercionHandlerUPP)
663 coerce_file_name_ptrUPP, 0, false, false);
664 if (err == noErr)
665 err = AEInstallCoercionHandler (TYPE_FILE_NAME, typeWildCard,
666 coerce_file_name_descUPP, 0, true, false);
667 if (err == noErr)
668 err = AEInstallCoercionHandler (typeWildCard, TYPE_FILE_NAME,
669 coerce_file_name_descUPP, 0, true, false);
670 return err;
671}
672
400#if TARGET_API_MAC_CARBON 673#if TARGET_API_MAC_CARBON
401OSErr 674OSErr
402create_apple_event_from_event_ref (event, num_params, names, types, result) 675create_apple_event_from_event_ref (event, num_params, names, types, result)
@@ -2602,7 +2875,7 @@ path_from_vol_dir_name (char *path, int man_path_len, short vol_ref_num,
2602} 2875}
2603 2876
2604 2877
2605OSErr 2878static OSErr
2606posix_pathname_to_fsspec (ufn, fs) 2879posix_pathname_to_fsspec (ufn, fs)
2607 const char *ufn; 2880 const char *ufn;
2608 FSSpec *fs; 2881 FSSpec *fs;
@@ -2618,7 +2891,7 @@ posix_pathname_to_fsspec (ufn, fs)
2618 } 2891 }
2619} 2892}
2620 2893
2621OSErr 2894static OSErr
2622fsspec_to_posix_pathname (fs, ufn, ufnbuflen) 2895fsspec_to_posix_pathname (fs, ufn, ufnbuflen)
2623 const FSSpec *fs; 2896 const FSSpec *fs;
2624 char *ufn; 2897 char *ufn;
@@ -4072,89 +4345,21 @@ Each type should be a string of length 4 or the symbol
4072 4345
4073 CHECK_STRING (src_data); 4346 CHECK_STRING (src_data);
4074 if (EQ (src_type, Qundecoded_file_name)) 4347 if (EQ (src_type, Qundecoded_file_name))
4075 { 4348 src_desc_type = TYPE_FILE_NAME;
4076#ifdef MAC_OSX
4077 src_desc_type = typeFileURL;
4078#else
4079 src_desc_type = typeFSS;
4080#endif
4081 }
4082 else 4349 else
4083 src_desc_type = mac_get_code_from_arg (src_type, 0); 4350 src_desc_type = mac_get_code_from_arg (src_type, 0);
4084 4351
4085 if (EQ (dst_type, Qundecoded_file_name)) 4352 if (EQ (dst_type, Qundecoded_file_name))
4086 { 4353 dst_desc_type = TYPE_FILE_NAME;
4087#ifdef MAC_OSX
4088 dst_desc_type = typeFSRef;
4089#else
4090 dst_desc_type = typeFSS;
4091#endif
4092 }
4093 else 4354 else
4094 dst_desc_type = mac_get_code_from_arg (dst_type, 0); 4355 dst_desc_type = mac_get_code_from_arg (dst_type, 0);
4095 4356
4096 BLOCK_INPUT; 4357 BLOCK_INPUT;
4097 if (EQ (src_type, Qundecoded_file_name)) 4358 err = AECoercePtr (src_desc_type, SDATA (src_data), SBYTES (src_data),
4098 {
4099#ifdef MAC_OSX
4100 CFStringRef str;
4101 CFURLRef url = NULL;
4102 CFDataRef data = NULL;
4103
4104 str = cfstring_create_with_utf8_cstring (SDATA (src_data));
4105 if (str)
4106 {
4107 url = CFURLCreateWithFileSystemPath (NULL, str,
4108 kCFURLPOSIXPathStyle, false);
4109 CFRelease (str);
4110 }
4111 if (url)
4112 {
4113 data = CFURLCreateData (NULL, url, kCFStringEncodingUTF8, true);
4114 CFRelease (url);
4115 }
4116 if (data)
4117 err = AECoercePtr (src_desc_type, CFDataGetBytePtr (data),
4118 CFDataGetLength (data),
4119 dst_desc_type, &dst_desc);
4120 else
4121 err = memFullErr;
4122#else
4123 err = posix_pathname_to_fsspec (SDATA (src_data), &fs);
4124 if (err == noErr)
4125 AECoercePtr (src_desc_type, &fs, sizeof (FSSpec),
4126 dst_desc_type, &dst_desc); 4359 dst_desc_type, &dst_desc);
4127#endif
4128 }
4129 else
4130 err = AECoercePtr (src_desc_type, SDATA (src_data), SBYTES (src_data),
4131 dst_desc_type, &dst_desc);
4132
4133 if (err == noErr) 4360 if (err == noErr)
4134 { 4361 {
4135 if (EQ (dst_type, Qundecoded_file_name)) 4362 result = Fcdr (mac_aedesc_to_lisp (&dst_desc));
4136 {
4137 char file_name[MAXPATHLEN];
4138
4139#ifdef MAC_OSX
4140 err = AEGetDescData (&dst_desc, &fref, sizeof (FSRef));
4141 if (err == noErr)
4142 err = FSRefMakePath (&fref, file_name, sizeof (file_name));
4143#else
4144#if TARGET_API_MAC_CARBON
4145 err = AEGetDescData (&dst_desc, &fs, sizeof (FSSpec));
4146#else
4147 memcpy (&fs, *(dst_desc.dataHandle), sizeof (FSSpec));
4148#endif
4149 if (err == noErr)
4150 err = fsspec_to_posix_pathname (&fs, file_name,
4151 sizeof (file_name) - 1);
4152#endif
4153 if (err == noErr)
4154 result = make_unibyte_string (file_name, strlen (file_name));
4155 }
4156 else
4157 result = Fcdr (mac_aedesc_to_lisp (&dst_desc));
4158 AEDisposeDesc (&dst_desc); 4363 AEDisposeDesc (&dst_desc);
4159 } 4364 }
4160 UNBLOCK_INPUT; 4365 UNBLOCK_INPUT;
diff --git a/src/macfns.c b/src/macfns.c
index 99abc643043..4ede8b7971b 100644
--- a/src/macfns.c
+++ b/src/macfns.c
@@ -4226,21 +4226,13 @@ If ONLY-DIR-P is non-nil, the user can only select directories. */)
4226 /* Set the default location and continue*/ 4226 /* Set the default location and continue*/
4227 if (status == noErr) 4227 if (status == noErr)
4228 { 4228 {
4229 Lisp_Object encoded_dir = ENCODE_FILE (dir);
4229 AEDesc defLocAed; 4230 AEDesc defLocAed;
4230#ifdef MAC_OSX 4231
4231 FSRef defLoc; 4232 status = AECreateDesc (TYPE_FILE_NAME, SDATA (encoded_dir),
4232 status = FSPathMakeRef(SDATA(ENCODE_FILE(dir)), &defLoc, NULL); 4233 SBYTES (encoded_dir), &defLocAed);
4233#else
4234 FSSpec defLoc;
4235 status = posix_pathname_to_fsspec (SDATA (ENCODE_FILE (dir)), &defLoc);
4236#endif
4237 if (status == noErr) 4234 if (status == noErr)
4238 { 4235 {
4239#ifdef MAC_OSX
4240 AECreateDesc(typeFSRef, &defLoc, sizeof(FSRef), &defLocAed);
4241#else
4242 AECreateDesc(typeFSS, &defLoc, sizeof(FSSpec), &defLocAed);
4243#endif
4244 NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed); 4236 NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed);
4245 AEDisposeDesc(&defLocAed); 4237 AEDisposeDesc(&defLocAed);
4246 } 4238 }
@@ -4262,41 +4254,36 @@ If ONLY-DIR-P is non-nil, the user can only select directories. */)
4262 case kNavUserActionSaveAs: 4254 case kNavUserActionSaveAs:
4263 { 4255 {
4264 NavReplyRecord reply; 4256 NavReplyRecord reply;
4265 AEDesc aed; 4257 Size len;
4266#ifdef MAC_OSX
4267 FSRef fsRef;
4268#else
4269 FSSpec fs;
4270#endif
4271 status = NavDialogGetReply(dialogRef, &reply);
4272 4258
4273#ifdef MAC_OSX 4259 status = NavDialogGetReply(dialogRef, &reply);
4274 AECoerceDesc(&reply.selection, typeFSRef, &aed); 4260 if (status != noErr)
4275 AEGetDescData(&aed, (void *) &fsRef, sizeof (FSRef)); 4261 break;
4276 FSRefMakePath(&fsRef, (UInt8 *) filename, sizeof (filename)); 4262 status = AEGetNthPtr (&reply.selection, 1, TYPE_FILE_NAME,
4277#else 4263 NULL, NULL, filename,
4278 AECoerceDesc (&reply.selection, typeFSS, &aed); 4264 sizeof (filename) - 1, &len);
4279 AEGetDescData (&aed, (void *) &fs, sizeof (FSSpec)); 4265 if (status == noErr)
4280 fsspec_to_posix_pathname (&fs, filename, sizeof (filename) - 1);
4281#endif
4282 AEDisposeDesc(&aed);
4283 if (reply.saveFileName)
4284 { 4266 {
4285 /* If it was a saved file, we need to add the file name */ 4267 len = min (len, sizeof (filename) - 1);
4286 int len = strlen(filename); 4268 filename[len] = '\0';
4287 if (len && filename[len-1] != '/') 4269 if (reply.saveFileName)
4288 filename[len++] = '/'; 4270 {
4289 CFStringGetCString(reply.saveFileName, filename+len, 4271 /* If it was a saved file, we need to add the file name */
4290 sizeof (filename) - len, 4272 if (len && len < sizeof (filename) - 1
4273 && filename[len-1] != '/')
4274 filename[len++] = '/';
4275 CFStringGetCString(reply.saveFileName, filename+len,
4276 sizeof (filename) - len,
4291#if MAC_OSX 4277#if MAC_OSX
4292 kCFStringEncodingUTF8 4278 kCFStringEncodingUTF8
4293#else 4279#else
4294 CFStringGetSystemEncoding () 4280 CFStringGetSystemEncoding ()
4295#endif 4281#endif
4296 ); 4282 );
4283 }
4284 file = DECODE_FILE (make_unibyte_string (filename,
4285 strlen (filename)));
4297 } 4286 }
4298 file = DECODE_FILE (make_unibyte_string (filename,
4299 strlen (filename)));
4300 NavDisposeReply(&reply); 4287 NavDisposeReply(&reply);
4301 } 4288 }
4302 break; 4289 break;
diff --git a/src/macgui.h b/src/macgui.h
index 40244dbc7c6..74c64bfb41d 100644
--- a/src/macgui.h
+++ b/src/macgui.h
@@ -109,7 +109,6 @@ typedef struct _XCharStruct
109#if 0 109#if 0
110 unsigned short attributes; /* per char flags (not predefined) */ 110 unsigned short attributes; /* per char flags (not predefined) */
111#endif 111#endif
112 unsigned valid_p : 1;
113} XCharStruct; 112} XCharStruct;
114 113
115#define STORE_XCHARSTRUCT(xcs, w, bds) \ 114#define STORE_XCHARSTRUCT(xcs, w, bds) \
@@ -117,8 +116,19 @@ typedef struct _XCharStruct
117 (xcs).lbearing = (bds).left, \ 116 (xcs).lbearing = (bds).left, \
118 (xcs).rbearing = (bds).right, \ 117 (xcs).rbearing = (bds).right, \
119 (xcs).ascent = -(bds).top, \ 118 (xcs).ascent = -(bds).top, \
120 (xcs).descent = (bds).bottom, \ 119 (xcs).descent = (bds).bottom)
121 (xcs).valid_p = 1) 120
121typedef struct
122{
123 char valid_bits[0x100 / 8];
124 XCharStruct per_char[0x100];
125} XCharStructRow;
126
127#define XCHARSTRUCTROW_CHAR_VALID_P(row, byte2) \
128 ((row)->valid_bits[(byte2) / 8] & (1 << (byte2) % 8))
129
130#define XCHARSTRUCTROW_SET_CHAR_VALID(row, byte2) \
131 ((row)->valid_bits[(byte2) / 8] |= (1 << (byte2) % 8))
122 132
123struct MacFontStruct { 133struct MacFontStruct {
124 char *full_name; 134 char *full_name;
@@ -157,7 +167,10 @@ struct MacFontStruct {
157#endif /* 0 */ 167#endif /* 0 */
158 XCharStruct min_bounds; /* minimum bounds over all existing char */ 168 XCharStruct min_bounds; /* minimum bounds over all existing char */
159 XCharStruct max_bounds; /* maximum bounds over all existing char */ 169 XCharStruct max_bounds; /* maximum bounds over all existing char */
160 XCharStruct *per_char; /* first_char to last_char information */ 170 union {
171 XCharStruct *per_char; /* first_char to last_char information */
172 XCharStructRow **rows; /* first row to last row information */
173 } bounds;
161 int ascent; /* logical extent above baseline for spacing */ 174 int ascent; /* logical extent above baseline for spacing */
162 int descent; /* logical decent below baseline for spacing */ 175 int descent; /* logical decent below baseline for spacing */
163}; 176};
diff --git a/src/macmenu.c b/src/macmenu.c
index 064cec57486..1b132407df7 100644
--- a/src/macmenu.c
+++ b/src/macmenu.c
@@ -1,4 +1,4 @@
1/* Menu support for GNU Emacs on the for Mac OS. 1/* Menu support for GNU Emacs on Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2 Copyright (C) 2000, 2001, 2002, 2003, 2004,
3 2005 Free Software Foundation, Inc. 3 2005 Free Software Foundation, Inc.
4 4
@@ -24,6 +24,7 @@ Boston, MA 02110-1301, USA. */
24#include <config.h> 24#include <config.h>
25 25
26#include <stdio.h> 26#include <stdio.h>
27
27#include "lisp.h" 28#include "lisp.h"
28#include "termhooks.h" 29#include "termhooks.h"
29#include "keyboard.h" 30#include "keyboard.h"
@@ -154,7 +155,7 @@ Lisp_Object Vmenu_updating_frame;
154 155
155Lisp_Object Qdebug_on_next_call; 156Lisp_Object Qdebug_on_next_call;
156 157
157extern Lisp_Object Qmenu_bar; 158extern Lisp_Object Qmenu_bar, Qmac_apple_event;
158 159
159extern Lisp_Object QCtoggle, QCradio; 160extern Lisp_Object QCtoggle, QCradio;
160 161
@@ -165,27 +166,28 @@ extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
165 166
166extern Lisp_Object Qmenu_bar_update_hook; 167extern Lisp_Object Qmenu_bar_update_hook;
167 168
169void set_frame_menubar P_ ((FRAME_PTR, int, int));
170
168#if TARGET_API_MAC_CARBON 171#if TARGET_API_MAC_CARBON
169#define ENCODE_MENU_STRING(str) ENCODE_UTF_8 (str) 172#define ENCODE_MENU_STRING(str) ENCODE_UTF_8 (str)
170#else 173#else
171#define ENCODE_MENU_STRING(str) ENCODE_SYSTEM (str) 174#define ENCODE_MENU_STRING(str) ENCODE_SYSTEM (str)
172#endif 175#endif
173 176
174void set_frame_menubar ();
175
176static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, 177static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
177 Lisp_Object, Lisp_Object, Lisp_Object, 178 Lisp_Object, Lisp_Object, Lisp_Object,
178 Lisp_Object, Lisp_Object)); 179 Lisp_Object, Lisp_Object));
179#ifdef HAVE_DIALOGS 180#ifdef HAVE_DIALOGS
180static Lisp_Object mac_dialog_show (); 181static Lisp_Object mac_dialog_show P_ ((FRAME_PTR, int, Lisp_Object,
182 Lisp_Object, char **));
181#endif 183#endif
182static Lisp_Object mac_menu_show (); 184static Lisp_Object mac_menu_show P_ ((struct frame *, int, int, int, int,
183 185 Lisp_Object, char **));
184static void keymap_panes (); 186static void keymap_panes P_ ((Lisp_Object *, int, int));
185static void single_keymap_panes (); 187static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
186static void single_menu_item (); 188 int, int));
187static void list_of_panes (); 189static void list_of_panes P_ ((Lisp_Object));
188static void list_of_items (); 190static void list_of_items P_ ((Lisp_Object));
189 191
190static void fill_submenu (MenuHandle, widget_value *); 192static void fill_submenu (MenuHandle, widget_value *);
191static void fill_menubar (widget_value *); 193static void fill_menubar (widget_value *);
@@ -280,8 +282,7 @@ init_menu_items ()
280 menu_items_submenu_depth = 0; 282 menu_items_submenu_depth = 0;
281} 283}
282 284
283/* Call at the end of generating the data in menu_items. 285/* Call at the end of generating the data in menu_items. */
284 This fills in the number of items in the last pane. */
285 286
286static void 287static void
287finish_menu_items () 288finish_menu_items ()
@@ -415,11 +416,21 @@ keymap_panes (keymaps, nmaps, notreal)
415 P is the number of panes we have made so far. */ 416 P is the number of panes we have made so far. */
416 for (mapno = 0; mapno < nmaps; mapno++) 417 for (mapno = 0; mapno < nmaps; mapno++)
417 single_keymap_panes (keymaps[mapno], 418 single_keymap_panes (keymaps[mapno],
418 Fkeymap_prompt (keymaps[mapno]), Qnil, notreal, 10); 419 Fkeymap_prompt (keymaps[mapno]), Qnil, notreal, 10);
419 420
420 finish_menu_items (); 421 finish_menu_items ();
421} 422}
422 423
424/* Args passed between single_keymap_panes and single_menu_item. */
425struct skp
426 {
427 Lisp_Object pending_maps;
428 int maxdepth, notreal;
429 };
430
431static void single_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
432 void *));
433
423/* This is a recursive subroutine of keymap_panes. 434/* This is a recursive subroutine of keymap_panes.
424 It handles one keymap, KEYMAP. 435 It handles one keymap, KEYMAP.
425 The other arguments are passed along 436 The other arguments are passed along
@@ -437,89 +448,71 @@ single_keymap_panes (keymap, pane_name, prefix, notreal, maxdepth)
437 int notreal; 448 int notreal;
438 int maxdepth; 449 int maxdepth;
439{ 450{
440 Lisp_Object pending_maps = Qnil; 451 struct skp skp;
441 Lisp_Object tail, item; 452 struct gcpro gcpro1;
442 struct gcpro gcpro1, gcpro2; 453
454 skp.pending_maps = Qnil;
455 skp.maxdepth = maxdepth;
456 skp.notreal = notreal;
443 457
444 if (maxdepth <= 0) 458 if (maxdepth <= 0)
445 return; 459 return;
446 460
447 push_menu_pane (pane_name, prefix); 461 push_menu_pane (pane_name, prefix);
448 462
449 for (tail = keymap; CONSP (tail); tail = XCDR (tail)) 463 GCPRO1 (skp.pending_maps);
450 { 464 map_keymap (keymap, single_menu_item, Qnil, &skp, 1);
451 GCPRO2 (keymap, pending_maps); 465 UNGCPRO;
452 /* Look at each key binding, and if it is a menu item add it
453 to this menu. */
454 item = XCAR (tail);
455 if (CONSP (item))
456 single_menu_item (XCAR (item), XCDR (item),
457 &pending_maps, notreal, maxdepth);
458 else if (VECTORP (item))
459 {
460 /* Loop over the char values represented in the vector. */
461 int len = XVECTOR (item)->size;
462 int c;
463 for (c = 0; c < len; c++)
464 {
465 Lisp_Object character;
466 XSETFASTINT (character, c);
467 single_menu_item (character, XVECTOR (item)->contents[c],
468 &pending_maps, notreal, maxdepth);
469 }
470 }
471 UNGCPRO;
472 }
473 466
474 /* Process now any submenus which want to be panes at this level. */ 467 /* Process now any submenus which want to be panes at this level. */
475 while (!NILP (pending_maps)) 468 while (CONSP (skp.pending_maps))
476 { 469 {
477 Lisp_Object elt, eltcdr, string; 470 Lisp_Object elt, eltcdr, string;
478 elt = Fcar (pending_maps); 471 elt = XCAR (skp.pending_maps);
479 eltcdr = XCDR (elt); 472 eltcdr = XCDR (elt);
480 string = XCAR (eltcdr); 473 string = XCAR (eltcdr);
481 /* We no longer discard the @ from the beginning of the string here. 474 /* We no longer discard the @ from the beginning of the string here.
482 Instead, we do this in mac_menu_show. */ 475 Instead, we do this in mac_menu_show. */
483 single_keymap_panes (Fcar (elt), string, 476 single_keymap_panes (Fcar (elt), string,
484 XCDR (eltcdr), notreal, maxdepth - 1); 477 XCDR (eltcdr), notreal, maxdepth - 1);
485 pending_maps = Fcdr (pending_maps); 478 skp.pending_maps = XCDR (skp.pending_maps);
486 } 479 }
487} 480}
488 481
489/* This is a subroutine of single_keymap_panes that handles one 482/* This is a subroutine of single_keymap_panes that handles one
490 keymap entry. 483 keymap entry.
491 KEY is a key in a keymap and ITEM is its binding. 484 KEY is a key in a keymap and ITEM is its binding.
492 PENDING_MAPS_PTR points to a list of keymaps waiting to be made into 485 SKP->PENDING_MAPS_PTR is a list of keymaps waiting to be made into
493 separate panes. 486 separate panes.
494 If NOTREAL is nonzero, only check for equivalent key bindings, don't 487 If SKP->NOTREAL is nonzero, only check for equivalent key bindings, don't
495 evaluate expressions in menu items and don't make any menu. 488 evaluate expressions in menu items and don't make any menu.
496 If we encounter submenus deeper than MAXDEPTH levels, ignore them. */ 489 If we encounter submenus deeper than SKP->MAXDEPTH levels, ignore them. */
497 490
498static void 491static void
499single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth) 492single_menu_item (key, item, dummy, skp_v)
500 Lisp_Object key, item; 493 Lisp_Object key, item, dummy;
501 Lisp_Object *pending_maps_ptr; 494 void *skp_v;
502 int maxdepth, notreal;
503{ 495{
504 Lisp_Object map, item_string, enabled; 496 Lisp_Object map, item_string, enabled;
505 struct gcpro gcpro1, gcpro2; 497 struct gcpro gcpro1, gcpro2;
506 int res; 498 int res;
499 struct skp *skp = skp_v;
507 500
508 /* Parse the menu item and leave the result in item_properties. */ 501 /* Parse the menu item and leave the result in item_properties. */
509 GCPRO2 (key, item); 502 GCPRO2 (key, item);
510 res = parse_menu_item (item, notreal, 0); 503 res = parse_menu_item (item, skp->notreal, 0);
511 UNGCPRO; 504 UNGCPRO;
512 if (!res) 505 if (!res)
513 return; /* Not a menu item. */ 506 return; /* Not a menu item. */
514 507
515 map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP]; 508 map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP];
516 509
517 if (notreal) 510 if (skp->notreal)
518 { 511 {
519 /* We don't want to make a menu, just traverse the keymaps to 512 /* We don't want to make a menu, just traverse the keymaps to
520 precompute equivalent key bindings. */ 513 precompute equivalent key bindings. */
521 if (!NILP (map)) 514 if (!NILP (map))
522 single_keymap_panes (map, Qnil, key, 1, maxdepth - 1); 515 single_keymap_panes (map, Qnil, key, 1, skp->maxdepth - 1);
523 return; 516 return;
524 } 517 }
525 518
@@ -530,8 +523,8 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth)
530 { 523 {
531 if (!NILP (enabled)) 524 if (!NILP (enabled))
532 /* An enabled separate pane. Remember this to handle it later. */ 525 /* An enabled separate pane. Remember this to handle it later. */
533 *pending_maps_ptr = Fcons (Fcons (map, Fcons (item_string, key)), 526 skp->pending_maps = Fcons (Fcons (map, Fcons (item_string, key)),
534 *pending_maps_ptr); 527 skp->pending_maps);
535 return; 528 return;
536 } 529 }
537 530
@@ -539,14 +532,14 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth)
539 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF], 532 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF],
540 XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ], 533 XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ],
541 XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE], 534 XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE],
542 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED], 535 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED],
543 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]); 536 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]);
544 537
545 /* Display a submenu using the toolkit. */ 538 /* Display a submenu using the toolkit. */
546 if (! (NILP (map) || NILP (enabled))) 539 if (! (NILP (map) || NILP (enabled)))
547 { 540 {
548 push_submenu_start (); 541 push_submenu_start ();
549 single_keymap_panes (map, Qnil, key, 0, maxdepth - 1); 542 single_keymap_panes (map, Qnil, key, 0, skp->maxdepth - 1);
550 push_submenu_end (); 543 push_submenu_end ();
551 } 544 }
552} 545}
@@ -563,13 +556,13 @@ list_of_panes (menu)
563 556
564 init_menu_items (); 557 init_menu_items ();
565 558
566 for (tail = menu; !NILP (tail); tail = Fcdr (tail)) 559 for (tail = menu; CONSP (tail); tail = XCDR (tail))
567 { 560 {
568 Lisp_Object elt, pane_name, pane_data; 561 Lisp_Object elt, pane_name, pane_data;
569 elt = Fcar (tail); 562 elt = XCAR (tail);
570 pane_name = Fcar (elt); 563 pane_name = Fcar (elt);
571 CHECK_STRING (pane_name); 564 CHECK_STRING (pane_name);
572 push_menu_pane (pane_name, Qnil); 565 push_menu_pane (ENCODE_MENU_STRING (pane_name), Qnil);
573 pane_data = Fcdr (elt); 566 pane_data = Fcdr (elt);
574 CHECK_CONS (pane_data); 567 CHECK_CONS (pane_data);
575 list_of_items (pane_data); 568 list_of_items (pane_data);
@@ -586,20 +579,22 @@ list_of_items (pane)
586{ 579{
587 Lisp_Object tail, item, item1; 580 Lisp_Object tail, item, item1;
588 581
589 for (tail = pane; !NILP (tail); tail = Fcdr (tail)) 582 for (tail = pane; CONSP (tail); tail = XCDR (tail))
590 { 583 {
591 item = Fcar (tail); 584 item = XCAR (tail);
592 if (STRINGP (item)) 585 if (STRINGP (item))
593 push_menu_item (item, Qnil, Qnil, Qt, Qnil, Qnil, Qnil, Qnil); 586 push_menu_item (ENCODE_MENU_STRING (item), Qnil, Qnil, Qt,
594 else if (NILP (item)) 587 Qnil, Qnil, Qnil, Qnil);
595 push_left_right_boundary (); 588 else if (CONSP (item))
596 else
597 { 589 {
598 CHECK_CONS (item); 590 item1 = XCAR (item);
599 item1 = Fcar (item);
600 CHECK_STRING (item1); 591 CHECK_STRING (item1);
601 push_menu_item (item1, Qt, Fcdr (item), Qt, Qnil, Qnil, Qnil, Qnil); 592 push_menu_item (ENCODE_MENU_STRING (item1), Qt, XCDR (item),
593 Qt, Qnil, Qnil, Qnil, Qnil);
602 } 594 }
595 else
596 push_left_right_boundary ();
597
603 } 598 }
604} 599}
605 600
@@ -659,15 +654,14 @@ no quit occurs and `x-popup-menu' returns nil. */)
659 Lisp_Object keymap, tem; 654 Lisp_Object keymap, tem;
660 int xpos = 0, ypos = 0; 655 int xpos = 0, ypos = 0;
661 Lisp_Object title; 656 Lisp_Object title;
662 char *error_name; 657 char *error_name = NULL;
663 Lisp_Object selection; 658 Lisp_Object selection;
664 FRAME_PTR f = NULL; 659 FRAME_PTR f = NULL;
665 Lisp_Object x, y, window; 660 Lisp_Object x, y, window;
666 int keymaps = 0; 661 int keymaps = 0;
667 int for_click = 0; 662 int for_click = 0;
668 struct gcpro gcpro1;
669 int specpdl_count = SPECPDL_INDEX (); 663 int specpdl_count = SPECPDL_INDEX ();
670 664 struct gcpro gcpro1;
671 665
672#ifdef HAVE_MENUS 666#ifdef HAVE_MENUS
673 if (! NILP (position)) 667 if (! NILP (position))
@@ -677,7 +671,8 @@ no quit occurs and `x-popup-menu' returns nil. */)
677 /* Decode the first argument: find the window and the coordinates. */ 671 /* Decode the first argument: find the window and the coordinates. */
678 if (EQ (position, Qt) 672 if (EQ (position, Qt)
679 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) 673 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
680 || EQ (XCAR (position), Qtool_bar)))) 674 || EQ (XCAR (position), Qtool_bar)
675 || EQ (XCAR (position), Qmac_apple_event))))
681 { 676 {
682 /* Use the mouse's current position. */ 677 /* Use the mouse's current position. */
683 FRAME_PTR new_f = SELECTED_FRAME (); 678 FRAME_PTR new_f = SELECTED_FRAME ();
@@ -703,8 +698,8 @@ no quit occurs and `x-popup-menu' returns nil. */)
703 if (CONSP (tem)) 698 if (CONSP (tem))
704 { 699 {
705 window = Fcar (Fcdr (position)); 700 window = Fcar (Fcdr (position));
706 x = Fcar (tem); 701 x = XCAR (tem);
707 y = Fcar (Fcdr (tem)); 702 y = Fcar (XCDR (tem));
708 } 703 }
709 else 704 else
710 { 705 {
@@ -788,11 +783,11 @@ no quit occurs and `x-popup-menu' returns nil. */)
788 783
789 /* The first keymap that has a prompt string 784 /* The first keymap that has a prompt string
790 supplies the menu title. */ 785 supplies the menu title. */
791 for (tem = menu, i = 0; CONSP (tem); tem = Fcdr (tem)) 786 for (tem = menu, i = 0; CONSP (tem); tem = XCDR (tem))
792 { 787 {
793 Lisp_Object prompt; 788 Lisp_Object prompt;
794 789
795 maps[i++] = keymap = get_keymap (Fcar (tem), 1, 0); 790 maps[i++] = keymap = get_keymap (XCAR (tem), 1, 0);
796 791
797 prompt = Fkeymap_prompt (keymap); 792 prompt = Fkeymap_prompt (keymap);
798 if (NILP (title) && !NILP (prompt)) 793 if (NILP (title) && !NILP (prompt))
@@ -879,7 +874,8 @@ for instance using the window manager, then this produces a quit and
879 /* Decode the first argument: find the window or frame to use. */ 874 /* Decode the first argument: find the window or frame to use. */
880 if (EQ (position, Qt) 875 if (EQ (position, Qt)
881 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) 876 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
882 || EQ (XCAR (position), Qtool_bar)))) 877 || EQ (XCAR (position), Qtool_bar)
878 || EQ (XCAR (position), Qmac_apple_event))))
883 { 879 {
884#if 0 /* Using the frame the mouse is on may not be right. */ 880#if 0 /* Using the frame the mouse is on may not be right. */
885 /* Use the mouse's current position. */ 881 /* Use the mouse's current position. */
@@ -947,6 +943,7 @@ for instance using the window manager, then this produces a quit and
947 Lisp_Object title; 943 Lisp_Object title;
948 char *error_name; 944 char *error_name;
949 Lisp_Object selection; 945 Lisp_Object selection;
946 int specpdl_count = SPECPDL_INDEX ();
950 947
951 /* Decode the dialog items from what was specified. */ 948 /* Decode the dialog items from what was specified. */
952 title = Fcar (contents); 949 title = Fcar (contents);
@@ -955,11 +952,11 @@ for instance using the window manager, then this produces a quit and
955 list_of_panes (Fcons (contents, Qnil)); 952 list_of_panes (Fcons (contents, Qnil));
956 953
957 /* Display them in a dialog box. */ 954 /* Display them in a dialog box. */
955 record_unwind_protect (cleanup_popup_menu, Qnil);
958 BLOCK_INPUT; 956 BLOCK_INPUT;
959 selection = mac_dialog_show (f, 0, title, header, &error_name); 957 selection = mac_dialog_show (f, 0, title, header, &error_name);
960 UNBLOCK_INPUT; 958 UNBLOCK_INPUT;
961 959 unbind_to (specpdl_count, Qnil);
962 discard_menu_items ();
963 960
964 if (error_name) error (error_name); 961 if (error_name) error (error_name);
965 return selection; 962 return selection;
@@ -971,13 +968,14 @@ for instance using the window manager, then this produces a quit and
971 This is called from keyboard.c when it gets the 968 This is called from keyboard.c when it gets the
972 MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue. 969 MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue.
973 970
974 To activate the menu bar, we signal to the input thread that it can 971 To activate the menu bar, we use the button-press event location
975 return from the WM_INITMENU message, allowing the normal Windows 972 that was saved in saved_menu_event_location.
976 processing of the menus.
977 973
978 But first we recompute the menu bar contents (the whole tree). 974 But first we recompute the menu bar contents (the whole tree).
979 975
980 This way we can safely execute Lisp code. */ 976 The reason for saving the button event until here, instead of
977 passing it to the toolkit right away, is that we can safely
978 execute Lisp code. */
981 979
982void 980void
983x_activate_menubar (f) 981x_activate_menubar (f)
@@ -1074,14 +1072,12 @@ menubar_selection_callback (FRAME_PTR f, int client_data)
1074 buf.arg = entry; 1072 buf.arg = entry;
1075 kbd_buffer_store_event (&buf); 1073 kbd_buffer_store_event (&buf);
1076 1074
1077 f->output_data.mac->menu_command_in_progress = 0;
1078 f->output_data.mac->menubar_active = 0; 1075 f->output_data.mac->menubar_active = 0;
1079 return; 1076 return;
1080 } 1077 }
1081 i += MENU_ITEMS_ITEM_LENGTH; 1078 i += MENU_ITEMS_ITEM_LENGTH;
1082 } 1079 }
1083 } 1080 }
1084 f->output_data.mac->menu_command_in_progress = 0;
1085 f->output_data.mac->menubar_active = 0; 1081 f->output_data.mac->menubar_active = 0;
1086} 1082}
1087 1083
@@ -1127,22 +1123,18 @@ free_menubar_widget_value_tree (wv)
1127 UNBLOCK_INPUT; 1123 UNBLOCK_INPUT;
1128} 1124}
1129 1125
1130/* Return a tree of widget_value structures for a menu bar item 1126/* Set up data in menu_items for a menu bar item
1131 whose event type is ITEM_KEY (with string ITEM_NAME) 1127 whose event type is ITEM_KEY (with string ITEM_NAME)
1132 and whose contents come from the list of keymaps MAPS. */ 1128 and whose contents come from the list of keymaps MAPS. */
1133 1129
1134static widget_value * 1130static int
1135single_submenu (item_key, item_name, maps) 1131parse_single_submenu (item_key, item_name, maps)
1136 Lisp_Object item_key, item_name, maps; 1132 Lisp_Object item_key, item_name, maps;
1137{ 1133{
1138 widget_value *wv, *prev_wv, *save_wv, *first_wv;
1139 int i;
1140 int submenu_depth = 0;
1141 Lisp_Object length; 1134 Lisp_Object length;
1142 int len; 1135 int len;
1143 Lisp_Object *mapvec; 1136 Lisp_Object *mapvec;
1144 widget_value **submenu_stack; 1137 int i;
1145 int previous_items = menu_items_used;
1146 int top_level_items = 0; 1138 int top_level_items = 0;
1147 1139
1148 length = Flength (maps); 1140 length = Flength (maps);
@@ -1156,28 +1148,44 @@ single_submenu (item_key, item_name, maps)
1156 maps = Fcdr (maps); 1148 maps = Fcdr (maps);
1157 } 1149 }
1158 1150
1159 menu_items_n_panes = 0;
1160
1161 /* Loop over the given keymaps, making a pane for each map. 1151 /* Loop over the given keymaps, making a pane for each map.
1162 But don't make a pane that is empty--ignore that map instead. */ 1152 But don't make a pane that is empty--ignore that map instead. */
1163 for (i = 0; i < len; i++) 1153 for (i = 0; i < len; i++)
1164 { 1154 {
1165 if (SYMBOLP (mapvec[i]) 1155 if (!KEYMAPP (mapvec[i]))
1166 || (CONSP (mapvec[i]) && !KEYMAPP (mapvec[i])))
1167 { 1156 {
1168 /* Here we have a command at top level in the menu bar 1157 /* Here we have a command at top level in the menu bar
1169 as opposed to a submenu. */ 1158 as opposed to a submenu. */
1170 top_level_items = 1; 1159 top_level_items = 1;
1171 push_menu_pane (Qnil, Qnil); 1160 push_menu_pane (Qnil, Qnil);
1172 push_menu_item (item_name, Qt, item_key, mapvec[i], 1161 push_menu_item (item_name, Qt, item_key, mapvec[i],
1173 Qnil, Qnil, Qnil, Qnil); 1162 Qnil, Qnil, Qnil, Qnil);
1174 } 1163 }
1175 else 1164 else
1176 single_keymap_panes (mapvec[i], item_name, item_key, 0, 10); 1165 {
1166 Lisp_Object prompt;
1167 prompt = Fkeymap_prompt (mapvec[i]);
1168 single_keymap_panes (mapvec[i],
1169 !NILP (prompt) ? prompt : item_name,
1170 item_key, 0, 10);
1171 }
1177 } 1172 }
1178 1173
1179 /* Create a tree of widget_value objects 1174 return top_level_items;
1180 representing the panes and their items. */ 1175}
1176
1177/* Create a tree of widget_value objects
1178 representing the panes and items
1179 in menu_items starting at index START, up to index END. */
1180
1181static widget_value *
1182digest_single_submenu (start, end, top_level_items)
1183 int start, end, top_level_items;
1184{
1185 widget_value *wv, *prev_wv, *save_wv, *first_wv;
1186 int i;
1187 int submenu_depth = 0;
1188 widget_value **submenu_stack;
1181 1189
1182 submenu_stack 1190 submenu_stack
1183 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); 1191 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
@@ -1191,12 +1199,12 @@ single_submenu (item_key, item_name, maps)
1191 save_wv = 0; 1199 save_wv = 0;
1192 prev_wv = 0; 1200 prev_wv = 0;
1193 1201
1194 /* Loop over all panes and items made during this call 1202 /* Loop over all panes and items made by the preceding call
1195 and construct a tree of widget_value objects. 1203 to parse_single_submenu and construct a tree of widget_value objects.
1196 Ignore the panes and items made by previous calls to 1204 Ignore the panes and items used by previous calls to
1197 single_submenu, even though those are also in menu_items. */ 1205 digest_single_submenu, even though those are also in menu_items. */
1198 i = previous_items; 1206 i = start;
1199 while (i < menu_items_used) 1207 while (i < end)
1200 { 1208 {
1201 if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) 1209 if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
1202 { 1210 {
@@ -1230,7 +1238,7 @@ single_submenu (item_key, item_name, maps)
1230#ifndef HAVE_MULTILINGUAL_MENU 1238#ifndef HAVE_MULTILINGUAL_MENU
1231 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) 1239 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
1232 { 1240 {
1233 pane_name = ENCODE_SYSTEM (pane_name); 1241 pane_name = ENCODE_MENU_STRING (pane_name);
1234 AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name; 1242 AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name;
1235 } 1243 }
1236#endif 1244#endif
@@ -1266,7 +1274,7 @@ single_submenu (item_key, item_name, maps)
1266 { 1274 {
1267 /* Create a new item within current pane. */ 1275 /* Create a new item within current pane. */
1268 Lisp_Object item_name, enable, descrip, def, type, selected; 1276 Lisp_Object item_name, enable, descrip, def, type, selected;
1269 Lisp_Object help; 1277 Lisp_Object help;
1270 1278
1271 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); 1279 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
1272 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); 1280 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
@@ -1277,13 +1285,13 @@ single_submenu (item_key, item_name, maps)
1277 help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP); 1285 help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
1278 1286
1279#ifndef HAVE_MULTILINGUAL_MENU 1287#ifndef HAVE_MULTILINGUAL_MENU
1280 if (STRING_MULTIBYTE (item_name)) 1288 if (STRING_MULTIBYTE (item_name))
1281 { 1289 {
1282 item_name = ENCODE_MENU_STRING (item_name); 1290 item_name = ENCODE_MENU_STRING (item_name);
1283 AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; 1291 AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name;
1284 } 1292 }
1285 1293
1286 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) 1294 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
1287 { 1295 {
1288 descrip = ENCODE_MENU_STRING (descrip); 1296 descrip = ENCODE_MENU_STRING (descrip);
1289 AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; 1297 AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip;
@@ -1315,7 +1323,7 @@ single_submenu (item_key, item_name, maps)
1315 abort (); 1323 abort ();
1316 1324
1317 wv->selected = !NILP (selected); 1325 wv->selected = !NILP (selected);
1318 if (!STRINGP (help)) 1326 if (! STRINGP (help))
1319 help = Qnil; 1327 help = Qnil;
1320 1328
1321 wv->help = help; 1329 wv->help = help;
@@ -1337,6 +1345,7 @@ single_submenu (item_key, item_name, maps)
1337 1345
1338 return first_wv; 1346 return first_wv;
1339} 1347}
1348
1340/* Walk through the widget_value tree starting at FIRST_WV and update 1349/* Walk through the widget_value tree starting at FIRST_WV and update
1341 the char * pointers from the corresponding lisp values. 1350 the char * pointers from the corresponding lisp values.
1342 We do this after building the whole tree, since GC may happen while the 1351 We do this after building the whole tree, since GC may happen while the
@@ -1418,20 +1427,28 @@ static void
1418install_menu_quit_handler (MenuHandle menu_handle) 1427install_menu_quit_handler (MenuHandle menu_handle)
1419{ 1428{
1420#ifdef HAVE_CANCELMENUTRACKING 1429#ifdef HAVE_CANCELMENUTRACKING
1421 EventHandlerUPP handler = NewEventHandlerUPP(menu_quit_handler);
1422 UInt32 numTypes = 1;
1423 EventTypeSpec typesList[] = { { kEventClassKeyboard, kEventRawKeyDown } }; 1430 EventTypeSpec typesList[] = { { kEventClassKeyboard, kEventRawKeyDown } };
1424 int i = MIN_MENU_ID; 1431 int i = MIN_MENU_ID;
1425 MenuHandle menu = menu_handle ? menu_handle : GetMenuHandle (i); 1432 MenuHandle menu = menu_handle ? menu_handle : GetMenuHandle (i);
1426 1433
1427 while (menu != NULL) 1434 while (menu != NULL)
1428 { 1435 {
1429 InstallMenuEventHandler (menu, handler, GetEventTypeCount (typesList), 1436 InstallMenuEventHandler (menu, menu_quit_handler,
1437 GetEventTypeCount (typesList),
1430 typesList, menu_handle, NULL); 1438 typesList, menu_handle, NULL);
1431 if (menu_handle) break; 1439 if (menu_handle) break;
1432 menu = GetMenuHandle (++i); 1440 menu = GetMenuHandle (++i);
1433 } 1441 }
1434 DisposeEventHandlerUPP (handler); 1442
1443 i = menu_handle ? MIN_POPUP_SUBMENU_ID : MIN_SUBMENU_ID;
1444 menu = GetMenuHandle (i);
1445 while (menu != NULL)
1446 {
1447 InstallMenuEventHandler (menu, menu_quit_handler,
1448 GetEventTypeCount (typesList),
1449 typesList, menu_handle, NULL);
1450 menu = GetMenuHandle (++i);
1451 }
1435#endif /* HAVE_CANCELMENUTRACKING */ 1452#endif /* HAVE_CANCELMENUTRACKING */
1436} 1453}
1437 1454
@@ -1448,7 +1465,9 @@ set_frame_menubar (f, first_time, deep_p)
1448 int menubar_widget = f->output_data.mac->menubar_widget; 1465 int menubar_widget = f->output_data.mac->menubar_widget;
1449 Lisp_Object items; 1466 Lisp_Object items;
1450 widget_value *wv, *first_wv, *prev_wv = 0; 1467 widget_value *wv, *first_wv, *prev_wv = 0;
1451 int i; 1468 int i, last_i = 0;
1469 int *submenu_start, *submenu_end;
1470 int *submenu_top_level_items, *submenu_n_panes;
1452 1471
1453 /* We must not change the menubar when actually in use. */ 1472 /* We must not change the menubar when actually in use. */
1454 if (f->output_data.mac->menubar_active) 1473 if (f->output_data.mac->menubar_active)
@@ -1461,14 +1480,6 @@ set_frame_menubar (f, first_time, deep_p)
1461 else if (pending_menu_activation && !deep_p) 1480 else if (pending_menu_activation && !deep_p)
1462 deep_p = 1; 1481 deep_p = 1;
1463 1482
1464 wv = xmalloc_widget_value ();
1465 wv->name = "menubar";
1466 wv->value = 0;
1467 wv->enabled = 1;
1468 wv->button_type = BUTTON_TYPE_NONE;
1469 wv->help = Qnil;
1470 first_wv = wv;
1471
1472 if (deep_p) 1483 if (deep_p)
1473 { 1484 {
1474 /* Make a widget-value tree representing the entire menu trees. */ 1485 /* Make a widget-value tree representing the entire menu trees. */
@@ -1503,6 +1514,7 @@ set_frame_menubar (f, first_time, deep_p)
1503 1514
1504 /* Run the Lucid hook. */ 1515 /* Run the Lucid hook. */
1505 safe_run_hooks (Qactivate_menubar_hook); 1516 safe_run_hooks (Qactivate_menubar_hook);
1517
1506 /* If it has changed current-menubar from previous value, 1518 /* If it has changed current-menubar from previous value,
1507 really recompute the menubar from the value. */ 1519 really recompute the menubar from the value. */
1508 if (! NILP (Vlucid_menu_bar_dirty_flag)) 1520 if (! NILP (Vlucid_menu_bar_dirty_flag))
@@ -1517,21 +1529,56 @@ set_frame_menubar (f, first_time, deep_p)
1517 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, 1529 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
1518 previous_menu_items_used * sizeof (Lisp_Object)); 1530 previous_menu_items_used * sizeof (Lisp_Object));
1519 1531
1520 /* Fill in the current menu bar contents. */ 1532 /* Fill in menu_items with the current menu bar contents.
1533 This can evaluate Lisp code. */
1521 menu_items = f->menu_bar_vector; 1534 menu_items = f->menu_bar_vector;
1522 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; 1535 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
1536 submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1537 submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1538 submenu_n_panes = (int *) alloca (XVECTOR (items)->size * sizeof (int));
1539 submenu_top_level_items
1540 = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1523 init_menu_items (); 1541 init_menu_items ();
1524 for (i = 0; i < XVECTOR (items)->size; i += 4) 1542 for (i = 0; i < XVECTOR (items)->size; i += 4)
1525 { 1543 {
1526 Lisp_Object key, string, maps; 1544 Lisp_Object key, string, maps;
1527 1545
1546 last_i = i;
1547
1528 key = XVECTOR (items)->contents[i]; 1548 key = XVECTOR (items)->contents[i];
1529 string = XVECTOR (items)->contents[i + 1]; 1549 string = XVECTOR (items)->contents[i + 1];
1530 maps = XVECTOR (items)->contents[i + 2]; 1550 maps = XVECTOR (items)->contents[i + 2];
1531 if (NILP (string)) 1551 if (NILP (string))
1532 break; 1552 break;
1533 1553
1534 wv = single_submenu (key, string, maps); 1554 submenu_start[i] = menu_items_used;
1555
1556 menu_items_n_panes = 0;
1557 submenu_top_level_items[i]
1558 = parse_single_submenu (key, string, maps);
1559 submenu_n_panes[i] = menu_items_n_panes;
1560
1561 submenu_end[i] = menu_items_used;
1562 }
1563
1564 finish_menu_items ();
1565
1566 /* Convert menu_items into widget_value trees
1567 to display the menu. This cannot evaluate Lisp code. */
1568
1569 wv = xmalloc_widget_value ();
1570 wv->name = "menubar";
1571 wv->value = 0;
1572 wv->enabled = 1;
1573 wv->button_type = BUTTON_TYPE_NONE;
1574 wv->help = Qnil;
1575 first_wv = wv;
1576
1577 for (i = 0; i < last_i; i += 4)
1578 {
1579 menu_items_n_panes = submenu_n_panes[i];
1580 wv = digest_single_submenu (submenu_start[i], submenu_end[i],
1581 submenu_top_level_items[i]);
1535 if (prev_wv) 1582 if (prev_wv)
1536 prev_wv->next = wv; 1583 prev_wv->next = wv;
1537 else 1584 else
@@ -1542,8 +1589,6 @@ set_frame_menubar (f, first_time, deep_p)
1542 prev_wv = wv; 1589 prev_wv = wv;
1543 } 1590 }
1544 1591
1545 finish_menu_items ();
1546
1547 set_buffer_internal_1 (prev); 1592 set_buffer_internal_1 (prev);
1548 unbind_to (specpdl_count, Qnil); 1593 unbind_to (specpdl_count, Qnil);
1549 1594
@@ -1552,22 +1597,18 @@ set_frame_menubar (f, first_time, deep_p)
1552 1597
1553 for (i = 0; i < previous_menu_items_used; i++) 1598 for (i = 0; i < previous_menu_items_used; i++)
1554 if (menu_items_used == i 1599 if (menu_items_used == i
1555 || (NILP (Fequal (previous_items[i], 1600 || (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i])))
1556 XVECTOR (menu_items)->contents[i]))))
1557 break; 1601 break;
1558 if (i == menu_items_used && i == previous_menu_items_used && i != 0) 1602 if (i == menu_items_used && i == previous_menu_items_used && i != 0)
1559 { 1603 {
1560 free_menubar_widget_value_tree (first_wv); 1604 free_menubar_widget_value_tree (first_wv);
1561 menu_items = Qnil; 1605 discard_menu_items ();
1562 1606
1563 return; 1607 return;
1564 } 1608 }
1565 1609
1566 /* Now GC cannot happen during the lifetime of the widget_value, 1610 /* Now GC cannot happen during the lifetime of the widget_value,
1567 so it's safe to store data from a Lisp_String, as long as 1611 so it's safe to store data from a Lisp_String. */
1568 local copies are made when the actual menu is created.
1569 Windows takes care of this for normal string items, but
1570 not for owner-drawn items or additional item-info. */
1571 wv = first_wv->contents; 1612 wv = first_wv->contents;
1572 for (i = 0; i < XVECTOR (items)->size; i += 4) 1613 for (i = 0; i < XVECTOR (items)->size; i += 4)
1573 { 1614 {
@@ -1582,13 +1623,21 @@ set_frame_menubar (f, first_time, deep_p)
1582 1623
1583 f->menu_bar_vector = menu_items; 1624 f->menu_bar_vector = menu_items;
1584 f->menu_bar_items_used = menu_items_used; 1625 f->menu_bar_items_used = menu_items_used;
1585 menu_items = Qnil; 1626 discard_menu_items ();
1586 } 1627 }
1587 else 1628 else
1588 { 1629 {
1589 /* Make a widget-value tree containing 1630 /* Make a widget-value tree containing
1590 just the top level menu bar strings. */ 1631 just the top level menu bar strings. */
1591 1632
1633 wv = xmalloc_widget_value ();
1634 wv->name = "menubar";
1635 wv->value = 0;
1636 wv->enabled = 1;
1637 wv->button_type = BUTTON_TYPE_NONE;
1638 wv->help = Qnil;
1639 first_wv = wv;
1640
1592 items = FRAME_MENU_BAR_ITEMS (f); 1641 items = FRAME_MENU_BAR_ITEMS (f);
1593 for (i = 0; i < XVECTOR (items)->size; i += 4) 1642 for (i = 0; i < XVECTOR (items)->size; i += 4)
1594 { 1643 {
@@ -1676,6 +1725,7 @@ initialize_frame_menubar (f)
1676 set_frame_menubar (f, 1, 1); 1725 set_frame_menubar (f, 1, 1);
1677} 1726}
1678 1727
1728
1679/* Get rid of the menu bar of frame F, and free its storage. 1729/* Get rid of the menu bar of frame F, and free its storage.
1680 This is used when deleting a frame, and when turning off the menu bar. */ 1730 This is used when deleting a frame, and when turning off the menu bar. */
1681 1731
@@ -1683,7 +1733,7 @@ void
1683free_frame_menubar (f) 1733free_frame_menubar (f)
1684 FRAME_PTR f; 1734 FRAME_PTR f;
1685{ 1735{
1686 f->output_data.mac->menubar_widget = NULL; 1736 f->output_data.mac->menubar_widget = 0;
1687} 1737}
1688 1738
1689 1739
@@ -1760,6 +1810,7 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1760 Lisp_Object *subprefix_stack 1810 Lisp_Object *subprefix_stack
1761 = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object)); 1811 = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object));
1762 int submenu_depth = 0; 1812 int submenu_depth = 0;
1813
1763 int first_pane; 1814 int first_pane;
1764 int specpdl_count = SPECPDL_INDEX (); 1815 int specpdl_count = SPECPDL_INDEX ();
1765 1816
@@ -1813,12 +1864,14 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1813 /* Create a new pane. */ 1864 /* Create a new pane. */
1814 Lisp_Object pane_name, prefix; 1865 Lisp_Object pane_name, prefix;
1815 char *pane_string; 1866 char *pane_string;
1867
1816 pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME); 1868 pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
1817 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); 1869 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
1870
1818#ifndef HAVE_MULTILINGUAL_MENU 1871#ifndef HAVE_MULTILINGUAL_MENU
1819 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) 1872 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
1820 { 1873 {
1821 pane_name = ENCODE_SYSTEM (pane_name); 1874 pane_name = ENCODE_MENU_STRING (pane_name);
1822 AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name; 1875 AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name;
1823 } 1876 }
1824#endif 1877#endif
@@ -1861,14 +1914,13 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1861 { 1914 {
1862 /* Create a new item within current pane. */ 1915 /* Create a new item within current pane. */
1863 Lisp_Object item_name, enable, descrip, def, type, selected, help; 1916 Lisp_Object item_name, enable, descrip, def, type, selected, help;
1864
1865 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); 1917 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
1866 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); 1918 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
1867 descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY); 1919 descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
1868 def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION); 1920 def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION);
1869 type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE); 1921 type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE);
1870 selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED); 1922 selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
1871 help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP); 1923 help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
1872 1924
1873#ifndef HAVE_MULTILINGUAL_MENU 1925#ifndef HAVE_MULTILINGUAL_MENU
1874 if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) 1926 if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
@@ -1876,8 +1928,9 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1876 item_name = ENCODE_MENU_STRING (item_name); 1928 item_name = ENCODE_MENU_STRING (item_name);
1877 AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; 1929 AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name;
1878 } 1930 }
1931
1879 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) 1932 if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
1880 { 1933 {
1881 descrip = ENCODE_MENU_STRING (descrip); 1934 descrip = ENCODE_MENU_STRING (descrip);
1882 AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; 1935 AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip;
1883 } 1936 }
@@ -1907,7 +1960,8 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1907 abort (); 1960 abort ();
1908 1961
1909 wv->selected = !NILP (selected); 1962 wv->selected = !NILP (selected);
1910 if (!STRINGP (help)) 1963
1964 if (! STRINGP (help))
1911 help = Qnil; 1965 help = Qnil;
1912 1966
1913 wv->help = help; 1967 wv->help = help;
@@ -1934,6 +1988,7 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1934 if (STRING_MULTIBYTE (title)) 1988 if (STRING_MULTIBYTE (title))
1935 title = ENCODE_MENU_STRING (title); 1989 title = ENCODE_MENU_STRING (title);
1936#endif 1990#endif
1991
1937 wv_title->name = (char *) SDATA (title); 1992 wv_title->name = (char *) SDATA (title);
1938 wv_title->enabled = FALSE; 1993 wv_title->enabled = FALSE;
1939 wv_title->title = TRUE; 1994 wv_title->title = TRUE;
@@ -1957,7 +2012,6 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
1957 pos.v = y; 2012 pos.v = y;
1958 2013
1959 SetPortWindowPort (FRAME_MAC_WINDOW (f)); 2014 SetPortWindowPort (FRAME_MAC_WINDOW (f));
1960
1961 LocalToGlobal (&pos); 2015 LocalToGlobal (&pos);
1962 2016
1963 /* No selection has been chosen yet. */ 2017 /* No selection has been chosen yet. */
@@ -2167,11 +2221,11 @@ static char * button_names [] = {
2167 "button6", "button7", "button8", "button9", "button10" }; 2221 "button6", "button7", "button8", "button9", "button10" };
2168 2222
2169static Lisp_Object 2223static Lisp_Object
2170mac_dialog_show (f, keymaps, title, header, error) 2224mac_dialog_show (f, keymaps, title, header, error_name)
2171 FRAME_PTR f; 2225 FRAME_PTR f;
2172 int keymaps; 2226 int keymaps;
2173 Lisp_Object title, header; 2227 Lisp_Object title, header;
2174 char **error; 2228 char **error_name;
2175{ 2229{
2176 int i, nb_buttons=0; 2230 int i, nb_buttons=0;
2177 char dialog_name[6]; 2231 char dialog_name[6];
@@ -2184,11 +2238,11 @@ mac_dialog_show (f, keymaps, title, header, error)
2184 /* 1 means we've seen the boundary between left-hand elts and right-hand. */ 2238 /* 1 means we've seen the boundary between left-hand elts and right-hand. */
2185 int boundary_seen = 0; 2239 int boundary_seen = 0;
2186 2240
2187 *error = NULL; 2241 *error_name = NULL;
2188 2242
2189 if (menu_items_n_panes > 1) 2243 if (menu_items_n_panes > 1)
2190 { 2244 {
2191 *error = "Multiple panes in dialog box"; 2245 *error_name = "Multiple panes in dialog box";
2192 return Qnil; 2246 return Qnil;
2193 } 2247 }
2194 2248
@@ -2216,18 +2270,16 @@ mac_dialog_show (f, keymaps, title, header, error)
2216 { 2270 {
2217 2271
2218 /* Create a new item within current pane. */ 2272 /* Create a new item within current pane. */
2219 Lisp_Object item_name, enable, descrip, help; 2273 Lisp_Object item_name, enable, descrip;
2220
2221 item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME]; 2274 item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME];
2222 enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; 2275 enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];
2223 descrip 2276 descrip
2224 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; 2277 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];
2225 help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP];
2226 2278
2227 if (NILP (item_name)) 2279 if (NILP (item_name))
2228 { 2280 {
2229 free_menubar_widget_value_tree (first_wv); 2281 free_menubar_widget_value_tree (first_wv);
2230 *error = "Submenu in dialog items"; 2282 *error_name = "Submenu in dialog items";
2231 return Qnil; 2283 return Qnil;
2232 } 2284 }
2233 if (EQ (item_name, Qquote)) 2285 if (EQ (item_name, Qquote))
@@ -2241,7 +2293,7 @@ mac_dialog_show (f, keymaps, title, header, error)
2241 if (nb_buttons >= 9) 2293 if (nb_buttons >= 9)
2242 { 2294 {
2243 free_menubar_widget_value_tree (first_wv); 2295 free_menubar_widget_value_tree (first_wv);
2244 *error = "Too many dialog items"; 2296 *error_name = "Too many dialog items";
2245 return Qnil; 2297 return Qnil;
2246 } 2298 }
2247 2299
@@ -2304,8 +2356,8 @@ mac_dialog_show (f, keymaps, title, header, error)
2304 /* Free the widget_value objects we used to specify the contents. */ 2356 /* Free the widget_value objects we used to specify the contents. */
2305 free_menubar_widget_value_tree (first_wv); 2357 free_menubar_widget_value_tree (first_wv);
2306 2358
2307 /* Find the selected item, and its pane, to return the proper 2359 /* Find the selected item, and its pane, to return
2308 value. */ 2360 the proper value. */
2309 if (menu_item_selection != 0) 2361 if (menu_item_selection != 0)
2310 { 2362 {
2311 Lisp_Object prefix; 2363 Lisp_Object prefix;
@@ -2322,6 +2374,12 @@ mac_dialog_show (f, keymaps, title, header, error)
2322 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; 2374 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
2323 i += MENU_ITEMS_PANE_LENGTH; 2375 i += MENU_ITEMS_PANE_LENGTH;
2324 } 2376 }
2377 else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
2378 {
2379 /* This is the boundary between left-side elts and
2380 right-side elts. */
2381 ++i;
2382 }
2325 else 2383 else
2326 { 2384 {
2327 entry 2385 entry
@@ -2340,6 +2398,9 @@ mac_dialog_show (f, keymaps, title, header, error)
2340 } 2398 }
2341 } 2399 }
2342 } 2400 }
2401 else
2402 /* Make "Cancel" equivalent to C-g. */
2403 Fsignal (Qquit, Qnil);
2343 2404
2344 return Qnil; 2405 return Qnil;
2345} 2406}
@@ -2365,7 +2426,11 @@ static void
2365add_menu_item (MenuHandle menu, widget_value *wv, int submenu, 2426add_menu_item (MenuHandle menu, widget_value *wv, int submenu,
2366 int force_disable) 2427 int force_disable)
2367{ 2428{
2429#if TARGET_API_MAC_CARBON
2430 CFStringRef item_name;
2431#else
2368 Str255 item_name; 2432 Str255 item_name;
2433#endif
2369 int pos; 2434 int pos;
2370 2435
2371 if (name_is_separator (wv->name)) 2436 if (name_is_separator (wv->name))
@@ -2376,42 +2441,49 @@ add_menu_item (MenuHandle menu, widget_value *wv, int submenu,
2376 2441
2377#if TARGET_API_MAC_CARBON 2442#if TARGET_API_MAC_CARBON
2378 pos = CountMenuItems (menu); 2443 pos = CountMenuItems (menu);
2379#else
2380 pos = CountMItems (menu);
2381#endif
2382 2444
2383 strcpy (item_name, ""); 2445 item_name = cfstring_create_with_utf8_cstring (wv->name);
2384 strncat (item_name, wv->name, 255); 2446
2385 if (wv->key != NULL) 2447 if (wv->key != NULL)
2386 { 2448 {
2387 strncat (item_name, " ", 255); 2449 CFStringRef name, key;
2388 strncat (item_name, wv->key, 255); 2450
2451 name = item_name;
2452 key = cfstring_create_with_utf8_cstring (wv->key);
2453 item_name = CFStringCreateWithFormat (NULL, NULL, CFSTR ("%@ %@"),
2454 name, key);
2455 CFRelease (name);
2456 CFRelease (key);
2389 } 2457 }
2390 item_name[255] = 0;
2391#if TARGET_API_MAC_CARBON
2392 {
2393 CFStringRef string = cfstring_create_with_utf8_cstring (item_name);
2394 2458
2395 SetMenuItemTextWithCFString (menu, pos, string); 2459 SetMenuItemTextWithCFString (menu, pos, item_name);
2396 CFRelease (string); 2460 CFRelease (item_name);
2397 } 2461
2398#else 2462 if (wv->enabled && !force_disable)
2463 EnableMenuItem (menu, pos);
2464 else
2465 DisableMenuItem (menu, pos);
2466#else /* ! TARGET_API_MAC_CARBON */
2467 pos = CountMItems (menu);
2468
2469 item_name[sizeof (item_name) - 1] = '\0';
2470 strncpy (item_name, wv->name, sizeof (item_name) - 1);
2471 if (wv->key != NULL)
2472 {
2473 int len = strlen (item_name);
2474
2475 strncpy (item_name + len, " ", sizeof (item_name) - 1 - len);
2476 len = strlen (item_name);
2477 strncpy (item_name + len, wv->key, sizeof (item_name) - 1 - len);
2478 }
2399 c2pstr (item_name); 2479 c2pstr (item_name);
2400 SetMenuItemText (menu, pos, item_name); 2480 SetMenuItemText (menu, pos, item_name);
2401#endif
2402 2481
2403 if (wv->enabled && !force_disable) 2482 if (wv->enabled && !force_disable)
2404#if TARGET_API_MAC_CARBON
2405 EnableMenuItem (menu, pos);
2406#else
2407 EnableItem (menu, pos); 2483 EnableItem (menu, pos);
2408#endif
2409 else 2484 else
2410#if TARGET_API_MAC_CARBON
2411 DisableMenuItem (menu, pos);
2412#else
2413 DisableItem (menu, pos); 2485 DisableItem (menu, pos);
2414#endif 2486#endif /* ! TARGET_API_MAC_CARBON */
2415 2487
2416 /* Draw radio buttons and tickboxes. */ 2488 /* Draw radio buttons and tickboxes. */
2417 { 2489 {
@@ -2425,7 +2497,7 @@ add_menu_item (MenuHandle menu, widget_value *wv, int submenu,
2425 SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data); 2497 SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data);
2426 } 2498 }
2427 2499
2428 if (submenu != NULL) 2500 if (submenu != 0)
2429 SetMenuItemHierarchicalID (menu, pos, submenu); 2501 SetMenuItemHierarchicalID (menu, pos, submenu);
2430} 2502}
2431 2503
@@ -2444,7 +2516,7 @@ fill_submenu (MenuHandle menu, widget_value *wv)
2444 add_menu_item (menu, wv, cur_submenu, 0); 2516 add_menu_item (menu, wv, cur_submenu, 0);
2445 } 2517 }
2446 else 2518 else
2447 add_menu_item (menu, wv, NULL, 0); 2519 add_menu_item (menu, wv, 0, 0);
2448} 2520}
2449 2521
2450 2522
@@ -2463,7 +2535,7 @@ fill_menu (MenuHandle menu, widget_value *wv)
2463 add_menu_item (menu, wv, cur_submenu, 0); 2535 add_menu_item (menu, wv, cur_submenu, 0);
2464 } 2536 }
2465 else 2537 else
2466 add_menu_item (menu, wv, NULL, 0); 2538 add_menu_item (menu, wv, 0, 0);
2467} 2539}
2468 2540
2469/* Construct native Mac OS menubar based on widget_value tree. */ 2541/* Construct native Mac OS menubar based on widget_value tree. */
@@ -2493,7 +2565,6 @@ fill_menubar (widget_value *wv)
2493} 2565}
2494 2566
2495#endif /* HAVE_MENUS */ 2567#endif /* HAVE_MENUS */
2496
2497 2568
2498void 2569void
2499syms_of_macmenu () 2570syms_of_macmenu ()
diff --git a/src/macterm.c b/src/macterm.c
index cbf7078cb25..614525440ec 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -68,7 +68,6 @@ Boston, MA 02110-1301, USA. */
68#include <errno.h> 68#include <errno.h>
69#include <setjmp.h> 69#include <setjmp.h>
70#include <sys/stat.h> 70#include <sys/stat.h>
71#include <sys/param.h>
72 71
73#include "charset.h" 72#include "charset.h"
74#include "coding.h" 73#include "coding.h"
@@ -259,7 +258,7 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
259 unsigned long *)); 258 unsigned long *));
260 259
261static int is_emacs_window P_ ((WindowPtr)); 260static int is_emacs_window P_ ((WindowPtr));
262 261static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
263static void XSetFont P_ ((Display *, GC, XFontStruct *)); 262static void XSetFont P_ ((Display *, GC, XFontStruct *));
264 263
265/* Defined in macmenu.h. */ 264/* Defined in macmenu.h. */
@@ -868,9 +867,159 @@ mac_draw_image_string_16 (f, gc, x, y, buf, nchars)
868} 867}
869 868
870 869
870/* Mac replacement for XQueryTextExtents, but takes a character. If
871 STYLE is NULL, measurement is done by QuickDraw Text routines for
872 the font of the current graphics port. If CG_GLYPH is not NULL,
873 *CG_GLYPH is set to the glyph ID or 0 if it cannot be obtained. */
874
875static OSErr
876mac_query_char_extents (style, c,
877 font_ascent_return, font_descent_return,
878 overall_return, cg_glyph)
879#if USE_ATSUI
880 ATSUStyle style;
881#else
882 void *style;
883#endif
884 int c;
885 int *font_ascent_return, *font_descent_return;
886 XCharStruct *overall_return;
871#if USE_CG_TEXT_DRAWING 887#if USE_CG_TEXT_DRAWING
872static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *)); 888 CGGlyph *cg_glyph;
889#else
890 void *cg_glyph;
891#endif
892{
893 OSErr err = noErr;
894 int width;
895 Rect char_bounds;
896
897#if USE_ATSUI
898 if (style)
899 {
900 ATSUTextLayout text_layout;
901 UniChar ch = c;
902
903 err = atsu_get_text_layout_with_text_ptr (&ch, 1, style, &text_layout);
904 if (err == noErr)
905 {
906 ATSTrapezoid glyph_bounds;
907
908 err = ATSUGetGlyphBounds (text_layout, 0, 0,
909 kATSUFromTextBeginning, kATSUToTextEnd,
910#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
911 kATSUseFractionalOrigins,
912#else
913 kATSUseDeviceOrigins,
914#endif
915 1, &glyph_bounds, NULL);
916 if (err == noErr)
917 {
918 xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x
919 == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x);
920
921 width = Fix2Long (glyph_bounds.upperRight.x
922 - glyph_bounds.upperLeft.x);
923 if (font_ascent_return)
924 *font_ascent_return = -Fix2Long (glyph_bounds.upperLeft.y);
925 if (font_descent_return)
926 *font_descent_return = Fix2Long (glyph_bounds.lowerLeft.y);
927 }
928 }
929 if (err == noErr && overall_return)
930 {
931 err = ATSUMeasureTextImage (text_layout,
932 kATSUFromTextBeginning, kATSUToTextEnd,
933 0, 0, &char_bounds);
934 if (err == noErr)
935 STORE_XCHARSTRUCT (*overall_return, width, char_bounds);
936#if USE_CG_TEXT_DRAWING
937 if (err == noErr && cg_glyph)
938 {
939 OSErr err1;
940 ATSUGlyphInfoArray glyph_info_array;
941 ByteCount count = sizeof (ATSUGlyphInfoArray);
942
943 err1 = ATSUMatchFontsToText (text_layout, kATSUFromTextBeginning,
944 kATSUToTextEnd, NULL, NULL, NULL);
945 if (err1 == noErr)
946 err1 = ATSUGetGlyphInfo (text_layout, kATSUFromTextBeginning,
947 kATSUToTextEnd, &count,
948 &glyph_info_array);
949 if (err1 == noErr)
950 {
951 xassert (glyph_info_array.glyphs[0].glyphID);
952 *cg_glyph = glyph_info_array.glyphs[0].glyphID;
953 }
954 else
955 *cg_glyph = 0;
956 }
957#endif
958 }
959 }
960 else
961#endif
962 {
963 if (font_ascent_return || font_descent_return)
964 {
965 FontInfo font_info;
966
967 GetFontInfo (&font_info);
968 if (font_ascent_return)
969 *font_ascent_return = font_info.ascent;
970 if (font_descent_return)
971 *font_descent_return = font_info.descent;
972 }
973 if (overall_return)
974 {
975 char ch = c;
976
977 width = CharWidth (ch);
978 QDTextBounds (1, &ch, &char_bounds);
979 STORE_XCHARSTRUCT (*overall_return, width, char_bounds);
980 }
981 }
982
983 return err;
984}
985
986
987/* Mac replacement for XTextExtents16. Only sets horizontal metrics. */
988
989static int
990mac_text_extents_16 (font_struct, string, nchars, overall_return)
991 XFontStruct *font_struct;
992 XChar2b *string;
993 int nchars;
994 XCharStruct *overall_return;
995{
996 int i;
997 short width = 0, lbearing = 0, rbearing = 0;
998 XCharStruct *pcm;
999
1000 for (i = 0; i < nchars; i++)
1001 {
1002 pcm = mac_per_char_metric (font_struct, string, 0);
1003 if (pcm == NULL)
1004 width += FONT_WIDTH (font_struct);
1005 else
1006 {
1007 lbearing = min (lbearing, width + pcm->lbearing);
1008 rbearing = max (rbearing, width + pcm->rbearing);
1009 width += pcm->width;
1010 }
1011 string++;
1012 }
1013
1014 overall_return->lbearing = lbearing;
1015 overall_return->rbearing = rbearing;
1016 overall_return->width = width;
1017
1018 /* What's the meaning of the return value of XTextExtents16? */
1019}
873 1020
1021
1022#if USE_CG_TEXT_DRAWING
874static int cg_text_anti_aliasing_threshold = 8; 1023static int cg_text_anti_aliasing_threshold = 8;
875 1024
876static void 1025static void
@@ -910,7 +1059,9 @@ mac_draw_string_cg (f, gc, x, y, buf, nchars)
910 advances = xmalloc (sizeof (CGSize) * nchars); 1059 advances = xmalloc (sizeof (CGSize) * nchars);
911 for (i = 0; i < nchars; i++) 1060 for (i = 0; i < nchars; i++)
912 { 1061 {
913 advances[i].width = x_per_char_metric (GC_FONT (gc), buf)->width; 1062 XCharStruct *pcm = mac_per_char_metric (GC_FONT (gc), buf, 0);
1063
1064 advances[i].width = pcm->width;
914 advances[i].height = 0; 1065 advances[i].height = 0;
915 glyphs[i] = GC_FONT (gc)->cg_glyphs[buf->byte2]; 1066 glyphs[i] = GC_FONT (gc)->cg_glyphs[buf->byte2];
916 buf++; 1067 buf++;
@@ -1724,63 +1875,32 @@ x_per_char_metric (font, char2b)
1724#if USE_ATSUI 1875#if USE_ATSUI
1725 if (font->mac_style) 1876 if (font->mac_style)
1726 { 1877 {
1727 if (char2b->byte1 >= font->min_byte1 1878 XCharStructRow **row = font->bounds.rows + char2b->byte1;
1728 && char2b->byte1 <= font->max_byte1 1879
1729 && char2b->byte2 >= font->min_char_or_byte2 1880 if (*row == NULL)
1730 && char2b->byte2 <= font->max_char_or_byte2)
1731 { 1881 {
1732 pcm = (font->per_char 1882 *row = xmalloc (sizeof (XCharStructRow));
1733 + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1) 1883 if (*row)
1734 * (char2b->byte1 - font->min_byte1)) 1884 bzero (*row, sizeof (XCharStructRow));
1735 + (char2b->byte2 - font->min_char_or_byte2));
1736 } 1885 }
1737 1886 if (*row)
1738 if (pcm && !pcm->valid_p)
1739 { 1887 {
1740 OSErr err; 1888 pcm = (*row)->per_char + char2b->byte2;
1741 ATSUTextLayout text_layout; 1889 if (!XCHARSTRUCTROW_CHAR_VALID_P (*row, char2b->byte2))
1742 UniChar c;
1743 int char_width;
1744 ATSTrapezoid glyph_bounds;
1745 Rect char_bounds;
1746
1747 c = (char2b->byte1 << 8) + char2b->byte2;
1748 BLOCK_INPUT;
1749 err = atsu_get_text_layout_with_text_ptr (&c, 1,
1750 font->mac_style,
1751 &text_layout);
1752 if (err == noErr)
1753 err = ATSUMeasureTextImage (text_layout,
1754 kATSUFromTextBeginning, kATSUToTextEnd,
1755 0, 0, &char_bounds);
1756
1757 if (err == noErr)
1758 err = ATSUGetGlyphBounds (text_layout, 0, 0,
1759 kATSUFromTextBeginning, kATSUToTextEnd,
1760#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
1761 kATSUseFractionalOrigins,
1762#else
1763 kATSUseDeviceOrigins,
1764#endif
1765 1, &glyph_bounds, NULL);
1766 UNBLOCK_INPUT;
1767 if (err != noErr)
1768 pcm = NULL;
1769 else
1770 { 1890 {
1771 xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x 1891 BLOCK_INPUT;
1772 == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x); 1892 mac_query_char_extents (font->mac_style,
1773 1893 (char2b->byte1 << 8) + char2b->byte2,
1774 char_width = Fix2Long (glyph_bounds.upperRight.x 1894 NULL, NULL, pcm, NULL);
1775 - glyph_bounds.upperLeft.x); 1895 UNBLOCK_INPUT;
1776 STORE_XCHARSTRUCT (*pcm, char_width, char_bounds); 1896 XCHARSTRUCTROW_SET_CHAR_VALID (*row, char2b->byte2);
1777 } 1897 }
1778 } 1898 }
1779 } 1899 }
1780 else 1900 else
1781 { 1901 {
1782#endif 1902#endif
1783 if (font->per_char != NULL) 1903 if (font->bounds.per_char != NULL)
1784 { 1904 {
1785 if (font->min_byte1 == 0 && font->max_byte1 == 0) 1905 if (font->min_byte1 == 0 && font->max_byte1 == 0)
1786 { 1906 {
@@ -1793,7 +1913,8 @@ x_per_char_metric (font, char2b)
1793 if (char2b->byte1 == 0 1913 if (char2b->byte1 == 0
1794 && char2b->byte2 >= font->min_char_or_byte2 1914 && char2b->byte2 >= font->min_char_or_byte2
1795 && char2b->byte2 <= font->max_char_or_byte2) 1915 && char2b->byte2 <= font->max_char_or_byte2)
1796 pcm = font->per_char + char2b->byte2 - font->min_char_or_byte2; 1916 pcm = font->bounds.per_char
1917 + (char2b->byte2 - font->min_char_or_byte2);
1797 } 1918 }
1798 else 1919 else
1799 { 1920 {
@@ -1815,7 +1936,7 @@ x_per_char_metric (font, char2b)
1815 && char2b->byte2 >= font->min_char_or_byte2 1936 && char2b->byte2 >= font->min_char_or_byte2
1816 && char2b->byte2 <= font->max_char_or_byte2) 1937 && char2b->byte2 <= font->max_char_or_byte2)
1817 { 1938 {
1818 pcm = (font->per_char 1939 pcm = (font->bounds.per_char
1819 + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1) 1940 + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1)
1820 * (char2b->byte1 - font->min_byte1)) 1941 * (char2b->byte1 - font->min_byte1))
1821 + (char2b->byte2 - font->min_char_or_byte2)); 1942 + (char2b->byte2 - font->min_char_or_byte2));
@@ -2157,67 +2278,32 @@ mac_compute_glyph_string_overhangs (s)
2157{ 2278{
2158 if (s->cmp == NULL 2279 if (s->cmp == NULL
2159 && s->first_glyph->type == CHAR_GLYPH) 2280 && s->first_glyph->type == CHAR_GLYPH)
2160 { 2281 if (!s->two_byte_p
2161 Rect r;
2162 MacFontStruct *font = s->font;
2163
2164#if USE_ATSUI 2282#if USE_ATSUI
2165 if (font->mac_style) 2283 || s->font->mac_style
2166 { 2284#endif
2167 OSErr err; 2285 )
2168 ATSUTextLayout text_layout; 2286 {
2169 UniChar *buf; 2287 XCharStruct cs;
2170 int i;
2171 2288
2172 SetRect (&r, 0, 0, 0, 0); 2289 mac_text_extents_16 (s->font, s->char2b, s->nchars, &cs);
2173 buf = xmalloc (sizeof (UniChar) * s->nchars); 2290 s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
2174 if (buf) 2291 s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
2175 { 2292 }
2176 for (i = 0; i < s->nchars; i++) 2293 else
2177 buf[i] = (s->char2b[i].byte1 << 8) + s->char2b[i].byte2; 2294 {
2295 Rect r;
2296 MacFontStruct *font = s->font;
2178 2297
2179 err = atsu_get_text_layout_with_text_ptr (buf, s->nchars, 2298 TextFont (font->mac_fontnum);
2180 font->mac_style, 2299 TextSize (font->mac_fontsize);
2181 &text_layout); 2300 TextFace (font->mac_fontface);
2182 if (err == noErr)
2183 err = ATSUMeasureTextImage (text_layout,
2184 kATSUFromTextBeginning,
2185 kATSUToTextEnd,
2186 0, 0, &r);
2187 xfree (buf);
2188 }
2189 }
2190 else
2191 {
2192#endif
2193 TextFont (font->mac_fontnum);
2194 TextSize (font->mac_fontsize);
2195 TextFace (font->mac_fontface);
2196 2301
2197 if (s->two_byte_p)
2198 QDTextBounds (s->nchars * 2, (char *)s->char2b, &r); 2302 QDTextBounds (s->nchars * 2, (char *)s->char2b, &r);
2199 else
2200 {
2201 int i;
2202 char *buf = xmalloc (s->nchars);
2203 2303
2204 if (buf == NULL) 2304 s->right_overhang = r.right > s->width ? r.right - s->width : 0;
2205 SetRect (&r, 0, 0, 0, 0); 2305 s->left_overhang = r.left < 0 ? -r.left : 0;
2206 else 2306 }
2207 {
2208 for (i = 0; i < s->nchars; ++i)
2209 buf[i] = s->char2b[i].byte2;
2210 QDTextBounds (s->nchars, buf, &r);
2211 xfree (buf);
2212 }
2213 }
2214#if USE_ATSUI
2215 }
2216#endif
2217
2218 s->right_overhang = r.right > s->width ? r.right - s->width : 0;
2219 s->left_overhang = r.left < 0 ? -r.left : 0;
2220 }
2221} 2307}
2222 2308
2223 2309
@@ -7375,7 +7461,7 @@ is_fully_specified_xlfd (char *p)
7375static MacFontStruct * 7461static MacFontStruct *
7376XLoadQueryFont (Display *dpy, char *fontname) 7462XLoadQueryFont (Display *dpy, char *fontname)
7377{ 7463{
7378 int i, size, char_width; 7464 int size;
7379 char *name; 7465 char *name;
7380 Str255 family; 7466 Str255 family;
7381 Str31 charset; 7467 Str31 charset;
@@ -7392,6 +7478,7 @@ XLoadQueryFont (Display *dpy, char *fontname)
7392 short scriptcode; 7478 short scriptcode;
7393#endif 7479#endif
7394 MacFontStruct *font; 7480 MacFontStruct *font;
7481 XCharStruct *space_bounds = NULL, *pcm;
7395 7482
7396 if (is_fully_specified_xlfd (fontname)) 7483 if (is_fully_specified_xlfd (fontname))
7397 name = fontname; 7484 name = fontname;
@@ -7488,19 +7575,27 @@ XLoadQueryFont (Display *dpy, char *fontname)
7488 if (font->mac_style) 7575 if (font->mac_style)
7489 { 7576 {
7490 OSErr err; 7577 OSErr err;
7491 ATSUTextLayout text_layout; 7578 UniChar c;
7492 UniChar c = 0x20;
7493 Rect char_bounds, min_bounds, max_bounds;
7494 int min_width, max_width;
7495 ATSTrapezoid glyph_bounds;
7496 7579
7497 font->per_char = xmalloc (sizeof (XCharStruct) * 0x10000); 7580 font->min_byte1 = 0;
7498 if (font->per_char == NULL) 7581 font->max_byte1 = 0xff;
7582 font->min_char_or_byte2 = 0;
7583 font->max_char_or_byte2 = 0xff;
7584
7585 font->bounds.rows = xmalloc (sizeof (XCharStructRow *) * 0x100);
7586 if (font->bounds.rows == NULL)
7499 { 7587 {
7500 mac_unload_font (&one_mac_display_info, font); 7588 mac_unload_font (&one_mac_display_info, font);
7501 return NULL; 7589 return NULL;
7502 } 7590 }
7503 bzero (font->per_char, sizeof (XCharStruct) * 0x10000); 7591 bzero (font->bounds.rows, sizeof (XCharStructRow *) * 0x100);
7592 font->bounds.rows[0] = xmalloc (sizeof (XCharStructRow));
7593 if (font->bounds.rows[0] == NULL)
7594 {
7595 mac_unload_font (&one_mac_display_info, font);
7596 return NULL;
7597 }
7598 bzero (font->bounds.rows[0], sizeof (XCharStructRow));
7504 7599
7505#if USE_CG_TEXT_DRAWING 7600#if USE_CG_TEXT_DRAWING
7506 { 7601 {
@@ -7525,108 +7620,58 @@ XLoadQueryFont (Display *dpy, char *fontname)
7525 if (font->cg_glyphs) 7620 if (font->cg_glyphs)
7526 bzero (font->cg_glyphs, sizeof (CGGlyph) * 0x100); 7621 bzero (font->cg_glyphs, sizeof (CGGlyph) * 0x100);
7527#endif 7622#endif
7528 7623 space_bounds = font->bounds.rows[0]->per_char + 0x20;
7529 err = atsu_get_text_layout_with_text_ptr (&c, 1, 7624 err = mac_query_char_extents (font->mac_style, 0x20,
7530 font->mac_style, 7625 &font->ascent, &font->descent,
7531 &text_layout); 7626 space_bounds,
7627#if USE_CG_TEXT_DRAWING
7628 (font->cg_glyphs ? font->cg_glyphs + 0x20
7629 : NULL)
7630#else
7631 NULL
7632#endif
7633 );
7532 if (err != noErr) 7634 if (err != noErr)
7533 { 7635 {
7534 mac_unload_font (&one_mac_display_info, font); 7636 mac_unload_font (&one_mac_display_info, font);
7535 return NULL; 7637 return NULL;
7536 } 7638 }
7639 XCHARSTRUCTROW_SET_CHAR_VALID (font->bounds.rows[0], 0x20);
7537 7640
7538 for (c = 0x20; c <= 0xff; c++) 7641 pcm = font->bounds.rows[0]->per_char;
7642 for (c = 0x21; c <= 0xff; c++)
7539 { 7643 {
7540 if (c == 0xad) 7644 if (c == 0xad)
7541 /* Soft hyphen is not supported in ATSUI. */ 7645 /* Soft hyphen is not supported in ATSUI. */
7542 continue; 7646 continue;
7543 else if (c == 0x7f) 7647 else if (c == 0x7f)
7544 { 7648 {
7545 STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
7546 STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
7547 c = 0x9f; 7649 c = 0x9f;
7548 continue; 7650 continue;
7549 } 7651 }
7550 7652
7551 err = ATSUClearLayoutCache (text_layout, kATSUFromTextBeginning); 7653 mac_query_char_extents (font->mac_style, c, NULL, NULL, pcm + c,
7552 if (err == noErr) 7654#if USE_CG_TEXT_DRAWING
7553 err = ATSUMeasureTextImage (text_layout, 7655 (font->cg_glyphs ? font->cg_glyphs + c
7554 kATSUFromTextBeginning, kATSUToTextEnd, 7656 : NULL)
7555 0, 0, &char_bounds);
7556 if (err == noErr)
7557 err = ATSUGetGlyphBounds (text_layout, 0, 0,
7558 kATSUFromTextBeginning, kATSUToTextEnd,
7559#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
7560 kATSUseFractionalOrigins,
7561#else 7657#else
7562 kATSUseDeviceOrigins, 7658 NULL
7563#endif 7659#endif
7564 1, &glyph_bounds, NULL); 7660 );
7565 if (err == noErr) 7661 XCHARSTRUCTROW_SET_CHAR_VALID (font->bounds.rows[0], c);
7566 {
7567 xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x
7568 == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x);
7569 7662
7570 char_width = Fix2Long (glyph_bounds.upperRight.x
7571 - glyph_bounds.upperLeft.x);
7572 STORE_XCHARSTRUCT (font->per_char[c],
7573 char_width, char_bounds);
7574 if (c == 0x20)
7575 {
7576 min_width = max_width = char_width;
7577 min_bounds = max_bounds = char_bounds;
7578 font->ascent = -Fix2Long (glyph_bounds.upperLeft.y);
7579 font->descent = Fix2Long (glyph_bounds.lowerLeft.y);
7580 }
7581 else
7582 {
7583 if (char_width > 0)
7584 {
7585 min_width = min (min_width, char_width);
7586 max_width = max (max_width, char_width);
7587 }
7588 if (!EmptyRect (&char_bounds))
7589 {
7590 SetRect (&min_bounds,
7591 max (min_bounds.left, char_bounds.left),
7592 max (min_bounds.top, char_bounds.top),
7593 min (min_bounds.right, char_bounds.right),
7594 min (min_bounds.bottom, char_bounds.bottom));
7595 UnionRect (&max_bounds, &char_bounds, &max_bounds);
7596 }
7597 }
7598 }
7599#if USE_CG_TEXT_DRAWING 7663#if USE_CG_TEXT_DRAWING
7600 if (err == noErr && char_width > 0 && font->cg_font) 7664 if (font->cg_glyphs && font->cg_glyphs[c] == 0)
7601 { 7665 {
7602 ATSUGlyphInfoArray glyph_info_array; 7666 /* Don't use CG text drawing if font substitution occurs in
7603 ByteCount count = sizeof (ATSUGlyphInfoArray); 7667 ASCII or Latin-1 characters. */
7604 7668 CGFontRelease (font->cg_font);
7605 err = ATSUMatchFontsToText (text_layout, kATSUFromTextBeginning, 7669 font->cg_font = NULL;
7606 kATSUToTextEnd, NULL, NULL, NULL); 7670 xfree (font->cg_glyphs);
7607 if (err == noErr) 7671 font->cg_glyphs = NULL;
7608 err = ATSUGetGlyphInfo (text_layout, kATSUFromTextBeginning,
7609 kATSUToTextEnd, &count,
7610 &glyph_info_array);
7611 if (err == noErr)
7612 font->cg_glyphs[c] = glyph_info_array.glyphs[0].glyphID;
7613 else
7614 {
7615 /* Don't use CG text drawing if font substitution
7616 occurs in ASCII or Latin-1 characters. */
7617 CGFontRelease (font->cg_font);
7618 font->cg_font = NULL;
7619 xfree (font->cg_glyphs);
7620 font->cg_glyphs = NULL;
7621 }
7622 } 7672 }
7623#endif 7673#endif
7624 } 7674 }
7625
7626 font->min_byte1 = 0;
7627 font->max_byte1 = 0xff;
7628 font->min_char_or_byte2 = 0;
7629 font->max_char_or_byte2 = 0xff;
7630 } 7675 }
7631 else 7676 else
7632#endif 7677#endif
@@ -7665,6 +7710,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
7665 7710
7666 if (is_two_byte_font) 7711 if (is_two_byte_font)
7667 { 7712 {
7713 int char_width;
7714
7668 font->min_byte1 = 0xa1; 7715 font->min_byte1 = 0xa1;
7669 font->max_byte1 = 0xfe; 7716 font->max_byte1 = 0xfe;
7670 font->min_char_or_byte2 = 0xa1; 7717 font->min_char_or_byte2 = 0xa1;
@@ -7693,21 +7740,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
7693 char_width = StringWidth("\p\xa1\xa1"); 7740 char_width = StringWidth("\p\xa1\xa1");
7694 break; 7741 break;
7695 } 7742 }
7696 }
7697 else
7698 {
7699 font->min_byte1 = font->max_byte1 = 0;
7700 font->min_char_or_byte2 = 0x20;
7701 font->max_char_or_byte2 = 0xff;
7702 7743
7703 /* Do this instead of use the_fontinfo.widMax, which 7744 font->bounds.per_char = NULL;
7704 incorrectly returns 15 for 12-point Monaco! */
7705 char_width = CharWidth ('m');
7706 }
7707
7708 if (is_two_byte_font)
7709 {
7710 font->per_char = NULL;
7711 7745
7712 if (fontface & italic) 7746 if (fontface & italic)
7713 font->max_bounds.rbearing = char_width + 1; 7747 font->max_bounds.rbearing = char_width + 1;
@@ -7722,54 +7756,28 @@ XLoadQueryFont (Display *dpy, char *fontname)
7722 } 7756 }
7723 else 7757 else
7724 { 7758 {
7725 int c, min_width, max_width; 7759 int c;
7726 Rect char_bounds, min_bounds, max_bounds;
7727 char ch;
7728
7729 font->per_char = xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
7730 bzero (font->per_char, sizeof (XCharStruct) * (0xff - 0x20 + 1));
7731 7760
7732 min_width = max_width = char_width; 7761 font->min_byte1 = font->max_byte1 = 0;
7733 SetRect (&min_bounds, -32767, -32767, 32767, 32767); 7762 font->min_char_or_byte2 = 0x20;
7734 SetRect (&max_bounds, 0, 0, 0, 0); 7763 font->max_char_or_byte2 = 0xff;
7735 for (c = 0x20; c <= 0xff; c++)
7736 {
7737 if (c == 0x7f)
7738 {
7739 STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
7740 STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
7741 continue;
7742 }
7743 7764
7744 ch = c; 7765 font->bounds.per_char =
7745 char_width = CharWidth (ch); 7766 xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
7746 QDTextBounds (1, &ch, &char_bounds); 7767 if (font->bounds.per_char == NULL)
7747 STORE_XCHARSTRUCT (font->per_char[c - 0x20],
7748 char_width, char_bounds);
7749 /* Some Japanese fonts (in SJIS encoding) return 0 as
7750 the character width of 0x7f. */
7751 if (char_width > 0)
7752 {
7753 min_width = min (min_width, char_width);
7754 max_width = max (max_width, char_width);
7755 }
7756 if (!EmptyRect (&char_bounds))
7757 {
7758 SetRect (&min_bounds,
7759 max (min_bounds.left, char_bounds.left),
7760 max (min_bounds.top, char_bounds.top),
7761 min (min_bounds.right, char_bounds.right),
7762 min (min_bounds.bottom, char_bounds.bottom));
7763 UnionRect (&max_bounds, &char_bounds, &max_bounds);
7764 }
7765 }
7766 if (min_width == max_width
7767 && max_bounds.left >= 0 && max_bounds.right <= max_width)
7768 { 7768 {
7769 /* Fixed width and no overhangs. */ 7769 mac_unload_font (&one_mac_display_info, font);
7770 xfree (font->per_char); 7770 return NULL;
7771 font->per_char = NULL;
7772 } 7771 }
7772 bzero (font->bounds.per_char,
7773 sizeof (XCharStruct) * (0xff - 0x20 + 1));
7774
7775 space_bounds = font->bounds.per_char;
7776 mac_query_char_extents (NULL, 0x20, &font->ascent, &font->descent,
7777 space_bounds, NULL);
7778
7779 for (c = 0x21, pcm = space_bounds + 1; c <= 0xff; c++, pcm++)
7780 mac_query_char_extents (NULL, c, NULL, NULL, pcm, NULL);
7773 } 7781 }
7774 7782
7775 /* Restore previous font number, size and face. */ 7783 /* Restore previous font number, size and face. */
@@ -7778,6 +7786,46 @@ XLoadQueryFont (Display *dpy, char *fontname)
7778 TextFace (old_fontface); 7786 TextFace (old_fontface);
7779 } 7787 }
7780 7788
7789 if (space_bounds)
7790 {
7791 int c;
7792
7793 font->min_bounds = font->max_bounds = *space_bounds;
7794 for (c = 0x21, pcm = space_bounds + 1; c <= 0x7f; c++, pcm++)
7795 if (pcm->width > 0)
7796 {
7797 font->min_bounds.lbearing = min (font->min_bounds.lbearing,
7798 pcm->lbearing);
7799 font->min_bounds.rbearing = min (font->min_bounds.rbearing,
7800 pcm->rbearing);
7801 font->min_bounds.width = min (font->min_bounds.width,
7802 pcm->width);
7803 font->min_bounds.ascent = min (font->min_bounds.ascent,
7804 pcm->ascent);
7805
7806 font->max_bounds.lbearing = max (font->max_bounds.lbearing,
7807 pcm->lbearing);
7808 font->max_bounds.rbearing = max (font->max_bounds.rbearing,
7809 pcm->rbearing);
7810 font->max_bounds.width = max (font->max_bounds.width,
7811 pcm->width);
7812 font->max_bounds.ascent = max (font->max_bounds.ascent,
7813 pcm->ascent);
7814 }
7815 if (
7816#if USE_ATSUI
7817 font->mac_style == NULL &&
7818#endif
7819 font->max_bounds.width == font->min_bounds.width
7820 && font->min_bounds.lbearing >= 0
7821 && font->max_bounds.rbearing <= font->max_bounds.width)
7822 {
7823 /* Fixed width and no overhangs. */
7824 xfree (font->bounds.per_char);
7825 font->bounds.per_char = NULL;
7826 }
7827 }
7828
7781#if !defined (MAC_OS8) || USE_ATSUI 7829#if !defined (MAC_OS8) || USE_ATSUI
7782 /* AppKit and WebKit do some adjustment to the heights of Courier, 7830 /* AppKit and WebKit do some adjustment to the heights of Courier,
7783 Helvetica, and Times. This only works on the environments where 7831 Helvetica, and Times. This only works on the environments where
@@ -7797,18 +7845,27 @@ mac_unload_font (dpyinfo, font)
7797 XFontStruct *font; 7845 XFontStruct *font;
7798{ 7846{
7799 xfree (font->full_name); 7847 xfree (font->full_name);
7800 if (font->per_char)
7801 xfree (font->per_char);
7802#if USE_ATSUI 7848#if USE_ATSUI
7803 if (font->mac_style) 7849 if (font->mac_style)
7804 ATSUDisposeStyle (font->mac_style); 7850 {
7851 int i;
7852
7853 for (i = font->min_byte1; i <= font->max_byte1; i++)
7854 if (font->bounds.rows[i])
7855 xfree (font->bounds.rows[i]);
7856 xfree (font->bounds.rows);
7857 ATSUDisposeStyle (font->mac_style);
7858 }
7859 else
7860#endif
7861 if (font->bounds.per_char)
7862 xfree (font->bounds.per_char);
7805#if USE_CG_TEXT_DRAWING 7863#if USE_CG_TEXT_DRAWING
7806 if (font->cg_font) 7864 if (font->cg_font)
7807 CGFontRelease (font->cg_font); 7865 CGFontRelease (font->cg_font);
7808 if (font->cg_glyphs) 7866 if (font->cg_glyphs)
7809 xfree (font->cg_glyphs); 7867 xfree (font->cg_glyphs);
7810#endif 7868#endif
7811#endif
7812 xfree (font); 7869 xfree (font);
7813} 7870}
7814 7871
@@ -8143,6 +8200,7 @@ extern void init_apple_event_handler P_ ((void));
8143extern void mac_find_apple_event_spec P_ ((AEEventClass, AEEventID, 8200extern void mac_find_apple_event_spec P_ ((AEEventClass, AEEventID,
8144 Lisp_Object *, Lisp_Object *, 8201 Lisp_Object *, Lisp_Object *,
8145 Lisp_Object *)); 8202 Lisp_Object *));
8203extern OSErr init_coercion_handler P_ ((void));
8146 8204
8147#if TARGET_API_MAC_CARBON 8205#if TARGET_API_MAC_CARBON
8148/* Drag and Drop */ 8206/* Drag and Drop */
@@ -9149,25 +9207,25 @@ mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
9149 result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags); 9207 result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags);
9150 if (result == noErr) 9208 if (result == noErr)
9151 { 9209 {
9152#ifdef MAC_OSX 9210 OSErr err;
9153 FSRef fref; 9211 AEDesc desc;
9154#endif
9155 char unix_path_name[MAXPATHLEN];
9156 9212
9157 GetFlavorData (theDrag, theItem, flavorTypeHFS, &data, &size, 0L); 9213 err = GetFlavorData (theDrag, theItem, flavorTypeHFS,
9158#ifdef MAC_OSX 9214 &data, &size, 0L);
9159 /* Use Carbon routines, otherwise it converts the file name 9215 if (err == noErr)
9160 to /Macintosh HD/..., which is not correct. */ 9216 err = AECoercePtr (typeFSS, &data.fileSpec, sizeof (FSSpec),
9161 FSpMakeFSRef (&data.fileSpec, &fref); 9217 TYPE_FILE_NAME, &desc);
9162 if (! FSRefMakePath (&fref, unix_path_name, sizeof (unix_path_name))); 9218 if (err == noErr)
9163#else 9219 {
9164 if (fsspec_to_posix_pathname (&data.fileSpec, unix_path_name, 9220 Lisp_Object file;
9165 sizeof (unix_path_name) - 1) == noErr) 9221
9166#endif 9222 /* x-dnd functions expect undecoded filenames. */
9167 /* x-dnd functions expect undecoded filenames. */ 9223 file = make_uninit_string (AEGetDescDataSize (&desc));
9168 file_list = Fcons (make_unibyte_string (unix_path_name, 9224 err = AEGetDescData (&desc, SDATA (file), SBYTES (file));
9169 strlen (unix_path_name)), 9225 if (err == noErr)
9170 file_list); 9226 file_list = Fcons (file, file_list);
9227 AEDisposeDesc (&desc);
9228 }
9171 } 9229 }
9172 } 9230 }
9173 /* If there are items in the list, construct an event and post it to 9231 /* If there are items in the list, construct an event and post it to
@@ -9259,6 +9317,8 @@ main (void)
9259 9317
9260 init_environ (); 9318 init_environ ();
9261 9319
9320 init_coercion_handler ();
9321
9262 initialize_applescript (); 9322 initialize_applescript ();
9263 9323
9264 init_apple_event_handler (); 9324 init_apple_event_handler ();
@@ -10648,6 +10708,8 @@ mac_initialize ()
10648#endif /* USE_CARBON_EVENTS */ 10708#endif /* USE_CARBON_EVENTS */
10649 10709
10650#ifdef MAC_OSX 10710#ifdef MAC_OSX
10711 init_coercion_handler ();
10712
10651 init_apple_event_handler (); 10713 init_apple_event_handler ();
10652 10714
10653 if (!inhibit_window_system) 10715 if (!inhibit_window_system)
diff --git a/src/macterm.h b/src/macterm.h
index 08c2f058cde..2f2ae26b3b3 100644
--- a/src/macterm.h
+++ b/src/macterm.h
@@ -322,9 +322,6 @@ struct mac_output {
322 /* Nonzero means menubar is currently active. */ 322 /* Nonzero means menubar is currently active. */
323 char menubar_active; 323 char menubar_active;
324 324
325 /* Nonzero means a menu command is being processed. */
326 char menu_command_in_progress;
327
328 /* Relief GCs, colors etc. */ 325 /* Relief GCs, colors etc. */
329 struct relief 326 struct relief
330 { 327 {
@@ -569,14 +566,14 @@ extern Lisp_Object mac_make_lispy_event_code P_ ((int));
569#define FONT_TYPE_FOR_UNIBYTE(font, ch) 0 566#define FONT_TYPE_FOR_UNIBYTE(font, ch) 0
570#define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0 567#define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0
571 568
569#define TYPE_FILE_NAME 'fNam'
570
572/* Defined in macselect.c */ 571/* Defined in macselect.c */
573 572
574extern void x_clear_frame_selections P_ ((struct frame *)); 573extern void x_clear_frame_selections P_ ((struct frame *));
575 574
576/* Defined in mac.c. */ 575/* Defined in mac.c. */
577 576
578extern OSErr posix_pathname_to_fsspec P_ ((const char *, FSSpec *));
579extern OSErr fsspec_to_posix_pathname P_ ((const FSSpec *, char *, int));
580extern void mac_clear_font_name_table P_ ((void)); 577extern void mac_clear_font_name_table P_ ((void));
581extern Lisp_Object mac_aedesc_to_lisp P_ ((AEDesc *)); 578extern Lisp_Object mac_aedesc_to_lisp P_ ((AEDesc *));
582#if TARGET_API_MAC_CARBON 579#if TARGET_API_MAC_CARBON
diff --git a/src/minibuf.c b/src/minibuf.c
index 8cc014f84ee..af7fa60aba4 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -2410,7 +2410,7 @@ during running `completion-setup-hook'. */)
2410 else 2410 else
2411 { 2411 {
2412 write_string ("Possible completions are:", -1); 2412 write_string ("Possible completions are:", -1);
2413 for (tail = completions, i = 0; !NILP (tail); tail = Fcdr (tail), i++) 2413 for (tail = completions, i = 0; CONSP (tail); tail = XCDR (tail), i++)
2414 { 2414 {
2415 Lisp_Object tem, string; 2415 Lisp_Object tem, string;
2416 int length; 2416 int length;
@@ -2418,7 +2418,7 @@ during running `completion-setup-hook'. */)
2418 2418
2419 startpos = Qnil; 2419 startpos = Qnil;
2420 2420
2421 elt = Fcar (tail); 2421 elt = XCAR (tail);
2422 if (SYMBOLP (elt)) 2422 if (SYMBOLP (elt))
2423 elt = SYMBOL_NAME (elt); 2423 elt = SYMBOL_NAME (elt);
2424 /* Compute the length of this element. */ 2424 /* Compute the length of this element. */
@@ -2594,9 +2594,21 @@ DEFUN ("minibuffer-completion-help", Fminibuffer_completion_help, Sminibuffer_co
2594 temp_echo_area_glyphs (build_string (" [No completions]")); 2594 temp_echo_area_glyphs (build_string (" [No completions]"));
2595 } 2595 }
2596 else 2596 else
2597 internal_with_output_to_temp_buffer ("*Completions*", 2597 {
2598 display_completion_list_1, 2598 /* Sort and remove duplicates. */
2599 Fsort (completions, Qstring_lessp)); 2599 Lisp_Object tmp = completions = Fsort (completions, Qstring_lessp);
2600 while (CONSP (tmp))
2601 {
2602 if (CONSP (XCDR (tmp))
2603 && !NILP (Fequal (XCAR (tmp), XCAR (XCDR (tmp)))))
2604 XSETCDR (tmp, XCDR (XCDR (tmp)));
2605 else
2606 tmp = XCDR (tmp);
2607 }
2608 internal_with_output_to_temp_buffer ("*Completions*",
2609 display_completion_list_1,
2610 completions);
2611 }
2600 return Qnil; 2612 return Qnil;
2601} 2613}
2602 2614
diff --git a/src/xfns.c b/src/xfns.c
index acd63125e87..2aa237ec549 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -5238,8 +5238,27 @@ Value is t if tooltip was open, nil otherwise. */)
5238 File selection dialog 5238 File selection dialog
5239 ***********************************************************************/ 5239 ***********************************************************************/
5240 5240
5241#ifdef USE_MOTIF 5241DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5242 Sx_uses_old_gtk_dialog,
5243 0, 0, 0,
5244 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5245 ()
5246{
5247#ifdef USE_GTK
5248 extern int use_dialog_box;
5249 extern int use_file_dialog;
5242 5250
5251 if (use_dialog_box
5252 && use_file_dialog
5253 && have_menus_p ()
5254 && xg_uses_old_file_dialog ())
5255 return Qt;
5256#endif
5257 return Qnil;
5258}
5259
5260
5261#ifdef USE_MOTIF
5243/* Callback for "OK" and "Cancel" on file selection dialog. */ 5262/* Callback for "OK" and "Cancel" on file selection dialog. */
5244 5263
5245static void 5264static void
@@ -5859,6 +5878,7 @@ variable `use-file-dialog'. */);
5859 last_show_tip_args = Qnil; 5878 last_show_tip_args = Qnil;
5860 staticpro (&last_show_tip_args); 5879 staticpro (&last_show_tip_args);
5861 5880
5881 defsubr (&Sx_uses_old_gtk_dialog);
5862#if defined (USE_MOTIF) || defined (USE_GTK) 5882#if defined (USE_MOTIF) || defined (USE_GTK)
5863 defsubr (&Sx_file_dialog); 5883 defsubr (&Sx_file_dialog);
5864#endif 5884#endif
diff --git a/src/xmenu.c b/src/xmenu.c
index 36f95d911f0..70c07702cae 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -3388,6 +3388,11 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
3388 return Qnil; 3388 return Qnil;
3389 } 3389 }
3390 3390
3391 /* Don't GC while we prepare and show the menu,
3392 because we give the oldxmenu library pointers to the
3393 contents of strings. */
3394 inhibit_garbage_collection ();
3395
3391#ifdef HAVE_X_WINDOWS 3396#ifdef HAVE_X_WINDOWS
3392 /* Adjust coordinates to relative to the outer (window manager) window. */ 3397 /* Adjust coordinates to relative to the outer (window manager) window. */
3393 x += FRAME_OUTER_TO_INNER_DIFF_X (f); 3398 x += FRAME_OUTER_TO_INNER_DIFF_X (f);