diff options
| author | Karoly Lorentey | 2005-12-29 04:41:02 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2005-12-29 04:41:02 +0000 |
| commit | e583523a108624f7fd0c28294010b19daae5ab97 (patch) | |
| tree | 6bbb60c1f603809ca8980a459e0c4ed6d2c02378 /src | |
| parent | da8e8fc14f3166ec596e34f43fbfea866d1176df (diff) | |
| parent | d52c26e925297a2d1663e2293d46ce95e91c4689 (diff) | |
| download | emacs-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/ChangeLog | 138 | ||||
| -rw-r--r-- | src/gtkutil.c | 24 | ||||
| -rw-r--r-- | src/gtkutil.h | 2 | ||||
| -rw-r--r-- | src/image.c | 16 | ||||
| -rw-r--r-- | src/insdel.c | 30 | ||||
| -rw-r--r-- | src/m/amdx86-64.h | 27 | ||||
| -rw-r--r-- | src/mac.c | 355 | ||||
| -rw-r--r-- | src/macfns.c | 69 | ||||
| -rw-r--r-- | src/macgui.h | 21 | ||||
| -rw-r--r-- | src/macmenu.c | 445 | ||||
| -rw-r--r-- | src/macterm.c | 612 | ||||
| -rw-r--r-- | src/macterm.h | 7 | ||||
| -rw-r--r-- | src/minibuf.c | 22 | ||||
| -rw-r--r-- | src/xfns.c | 22 | ||||
| -rw-r--r-- | src/xmenu.c | 5 |
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 @@ | |||
| 1 | 2005-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 | |||
| 6 | 2005-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 | |||
| 30 | 2005-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 | |||
| 36 | 2005-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 | |||
| 45 | 2005-12-22 Richard M. Stallman <rms@gnu.org> | ||
| 46 | |||
| 47 | * xmenu.c (xmenu_show): Call inhibit_garbage_collection. | ||
| 48 | |||
| 49 | 2005-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 | |||
| 75 | 2005-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 | |||
| 80 | 2005-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 | |||
| 85 | 2005-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 | |||
| 1 | 2005-12-20 Juri Linkov <juri@jurta.org> | 116 | 2005-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 | ||
| 92 | 2005-12-14 Chong Yidong <cyd@stupidchicken.com> | 207 | 2005-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 | |||
| 1161 | int | ||
| 1162 | xg_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; | |||
| 132 | extern widget_value *malloc_widget_value P_ ((void)); | 132 | extern widget_value *malloc_widget_value P_ ((void)); |
| 133 | extern void free_widget_value P_ ((widget_value *)); | 133 | extern void free_widget_value P_ ((widget_value *)); |
| 134 | 134 | ||
| 135 | extern int xg_uses_old_file_dialog P_ ((void)); | ||
| 136 | |||
| 135 | extern char *xg_get_file_name P_ ((FRAME_PTR f, | 137 | extern 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) */ |
| @@ -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. */ |
| 80 | static OSAID as_script_context; | 80 | static OSAID as_script_context; |
| 81 | 81 | ||
| 82 | static OSErr posix_pathname_to_fsspec P_ ((const char *, FSSpec *)); | ||
| 83 | static 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 | |||
| 333 | mac_aedesc_to_lisp (desc) | 335 | mac_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 | ||
| 402 | static pascal OSErr | ||
| 403 | mac_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 | |||
| 574 | static pascal OSErr | ||
| 575 | mac_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 | |||
| 643 | OSErr | ||
| 644 | init_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 |
| 401 | OSErr | 674 | OSErr |
| 402 | create_apple_event_from_event_ref (event, num_params, names, types, result) | 675 | create_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 | ||
| 2605 | OSErr | 2878 | static OSErr |
| 2606 | posix_pathname_to_fsspec (ufn, fs) | 2879 | posix_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 | ||
| 2621 | OSErr | 2894 | static OSErr |
| 2622 | fsspec_to_posix_pathname (fs, ufn, ufnbuflen) | 2895 | fsspec_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 | |
| 121 | typedef 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 | ||
| 123 | struct MacFontStruct { | 133 | struct 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 | ||
| 155 | Lisp_Object Qdebug_on_next_call; | 156 | Lisp_Object Qdebug_on_next_call; |
| 156 | 157 | ||
| 157 | extern Lisp_Object Qmenu_bar; | 158 | extern Lisp_Object Qmenu_bar, Qmac_apple_event; |
| 158 | 159 | ||
| 159 | extern Lisp_Object QCtoggle, QCradio; | 160 | extern Lisp_Object QCtoggle, QCradio; |
| 160 | 161 | ||
| @@ -165,27 +166,28 @@ extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map; | |||
| 165 | 166 | ||
| 166 | extern Lisp_Object Qmenu_bar_update_hook; | 167 | extern Lisp_Object Qmenu_bar_update_hook; |
| 167 | 168 | ||
| 169 | void 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 | ||
| 174 | void set_frame_menubar (); | ||
| 175 | |||
| 176 | static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, | 177 | static 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 |
| 180 | static Lisp_Object mac_dialog_show (); | 181 | static Lisp_Object mac_dialog_show P_ ((FRAME_PTR, int, Lisp_Object, |
| 182 | Lisp_Object, char **)); | ||
| 181 | #endif | 183 | #endif |
| 182 | static Lisp_Object mac_menu_show (); | 184 | static Lisp_Object mac_menu_show P_ ((struct frame *, int, int, int, int, |
| 183 | 185 | Lisp_Object, char **)); | |
| 184 | static void keymap_panes (); | 186 | static void keymap_panes P_ ((Lisp_Object *, int, int)); |
| 185 | static void single_keymap_panes (); | 187 | static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object, |
| 186 | static void single_menu_item (); | 188 | int, int)); |
| 187 | static void list_of_panes (); | 189 | static void list_of_panes P_ ((Lisp_Object)); |
| 188 | static void list_of_items (); | 190 | static void list_of_items P_ ((Lisp_Object)); |
| 189 | 191 | ||
| 190 | static void fill_submenu (MenuHandle, widget_value *); | 192 | static void fill_submenu (MenuHandle, widget_value *); |
| 191 | static void fill_menubar (widget_value *); | 193 | static 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 | ||
| 286 | static void | 287 | static void |
| 287 | finish_menu_items () | 288 | finish_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. */ | ||
| 425 | struct skp | ||
| 426 | { | ||
| 427 | Lisp_Object pending_maps; | ||
| 428 | int maxdepth, notreal; | ||
| 429 | }; | ||
| 430 | |||
| 431 | static 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 | ||
| 498 | static void | 491 | static void |
| 499 | single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth) | 492 | single_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 | ||
| 982 | void | 980 | void |
| 983 | x_activate_menubar (f) | 981 | x_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 | ||
| 1134 | static widget_value * | 1130 | static int |
| 1135 | single_submenu (item_key, item_name, maps) | 1131 | parse_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 | |||
| 1181 | static widget_value * | ||
| 1182 | digest_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 | |||
| 1418 | install_menu_quit_handler (MenuHandle menu_handle) | 1427 | install_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 | |||
| 1683 | free_frame_menubar (f) | 1733 | free_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 | ||
| 2169 | static Lisp_Object | 2223 | static Lisp_Object |
| 2170 | mac_dialog_show (f, keymaps, title, header, error) | 2224 | mac_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 | |||
| 2365 | add_menu_item (MenuHandle menu, widget_value *wv, int submenu, | 2426 | add_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 | ||
| 2498 | void | 2569 | void |
| 2499 | syms_of_macmenu () | 2570 | syms_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 | ||
| 261 | static int is_emacs_window P_ ((WindowPtr)); | 260 | static int is_emacs_window P_ ((WindowPtr)); |
| 262 | 261 | static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int)); | |
| 263 | static void XSetFont P_ ((Display *, GC, XFontStruct *)); | 262 | static 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 | |||
| 875 | static OSErr | ||
| 876 | mac_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 |
| 872 | static 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 | |||
| 989 | static int | ||
| 990 | mac_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 | ||
| 874 | static int cg_text_anti_aliasing_threshold = 8; | 1023 | static int cg_text_anti_aliasing_threshold = 8; |
| 875 | 1024 | ||
| 876 | static void | 1025 | static 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) | |||
| 7375 | static MacFontStruct * | 7461 | static MacFontStruct * |
| 7376 | XLoadQueryFont (Display *dpy, char *fontname) | 7462 | XLoadQueryFont (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)); | |||
| 8143 | extern void mac_find_apple_event_spec P_ ((AEEventClass, AEEventID, | 8200 | extern 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 *)); |
| 8203 | extern 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 | ||
| 574 | extern void x_clear_frame_selections P_ ((struct frame *)); | 573 | extern void x_clear_frame_selections P_ ((struct frame *)); |
| 575 | 574 | ||
| 576 | /* Defined in mac.c. */ | 575 | /* Defined in mac.c. */ |
| 577 | 576 | ||
| 578 | extern OSErr posix_pathname_to_fsspec P_ ((const char *, FSSpec *)); | ||
| 579 | extern OSErr fsspec_to_posix_pathname P_ ((const FSSpec *, char *, int)); | ||
| 580 | extern void mac_clear_font_name_table P_ ((void)); | 577 | extern void mac_clear_font_name_table P_ ((void)); |
| 581 | extern Lisp_Object mac_aedesc_to_lisp P_ ((AEDesc *)); | 578 | extern 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 | 5241 | DEFUN ("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 | ||
| 5245 | static void | 5264 | static 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); |