diff options
Diffstat (limited to 'src/macfns.c')
| -rw-r--r-- | src/macfns.c | 427 |
1 files changed, 35 insertions, 392 deletions
diff --git a/src/macfns.c b/src/macfns.c index 9e471c6c588..21866876155 100644 --- a/src/macfns.c +++ b/src/macfns.c | |||
| @@ -1346,7 +1346,7 @@ x_set_background_color (f, arg, oldval) | |||
| 1346 | BLOCK_INPUT; | 1346 | BLOCK_INPUT; |
| 1347 | XSetBackground (dpy, mac->normal_gc, bg); | 1347 | XSetBackground (dpy, mac->normal_gc, bg); |
| 1348 | XSetForeground (dpy, mac->reverse_gc, bg); | 1348 | XSetForeground (dpy, mac->reverse_gc, bg); |
| 1349 | XSetWindowBackground (dpy, FRAME_MAC_WINDOW (f), bg); | 1349 | mac_set_frame_window_background (f, bg); |
| 1350 | XSetForeground (dpy, mac->cursor_gc, bg); | 1350 | XSetForeground (dpy, mac->cursor_gc, bg); |
| 1351 | 1351 | ||
| 1352 | UNBLOCK_INPUT; | 1352 | UNBLOCK_INPUT; |
| @@ -1686,7 +1686,8 @@ x_set_tool_bar_lines (f, value, oldval) | |||
| 1686 | if (nlines) | 1686 | if (nlines) |
| 1687 | { | 1687 | { |
| 1688 | FRAME_EXTERNAL_TOOL_BAR (f) = 1; | 1688 | FRAME_EXTERNAL_TOOL_BAR (f) = 1; |
| 1689 | if (FRAME_MAC_P (f) && !IsWindowToolbarVisible (FRAME_MAC_WINDOW (f))) | 1689 | if (FRAME_MAC_P (f) |
| 1690 | && !mac_is_window_toolbar_visible (FRAME_MAC_WINDOW (f))) | ||
| 1690 | /* Make sure next redisplay shows the tool bar. */ | 1691 | /* Make sure next redisplay shows the tool bar. */ |
| 1691 | XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt; | 1692 | XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt; |
| 1692 | } | 1693 | } |
| @@ -1770,7 +1771,7 @@ x_set_name_internal (f, name) | |||
| 1770 | CFStringRef windowTitle = | 1771 | CFStringRef windowTitle = |
| 1771 | cfstring_create_with_utf8_cstring (SDATA (name)); | 1772 | cfstring_create_with_utf8_cstring (SDATA (name)); |
| 1772 | 1773 | ||
| 1773 | SetWindowTitleWithCFString (FRAME_MAC_WINDOW (f), windowTitle); | 1774 | mac_set_window_title (FRAME_MAC_WINDOW (f), windowTitle); |
| 1774 | CFRelease (windowTitle); | 1775 | CFRelease (windowTitle); |
| 1775 | #else | 1776 | #else |
| 1776 | Str255 windowTitle; | 1777 | Str255 windowTitle; |
| @@ -1935,98 +1936,6 @@ mac_set_font (f, arg, oldval) | |||
| 1935 | #endif | 1936 | #endif |
| 1936 | } | 1937 | } |
| 1937 | 1938 | ||
| 1938 | #if TARGET_API_MAC_CARBON | ||
| 1939 | static void | ||
| 1940 | mac_update_proxy_icon (f) | ||
| 1941 | struct frame *f; | ||
| 1942 | { | ||
| 1943 | OSStatus err; | ||
| 1944 | Lisp_Object file_name = | ||
| 1945 | XBUFFER (XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer)->filename; | ||
| 1946 | Window w = FRAME_MAC_WINDOW (f); | ||
| 1947 | AliasHandle alias = NULL; | ||
| 1948 | |||
| 1949 | BLOCK_INPUT; | ||
| 1950 | |||
| 1951 | err = GetWindowProxyAlias (w, &alias); | ||
| 1952 | if (err == errWindowDoesNotHaveProxy && !STRINGP (file_name)) | ||
| 1953 | goto out; | ||
| 1954 | |||
| 1955 | if (STRINGP (file_name)) | ||
| 1956 | { | ||
| 1957 | AEDesc desc; | ||
| 1958 | #ifdef MAC_OSX | ||
| 1959 | FSRef fref, fref_proxy; | ||
| 1960 | #else | ||
| 1961 | FSSpec fss, fss_proxy; | ||
| 1962 | #endif | ||
| 1963 | Boolean changed; | ||
| 1964 | Lisp_Object encoded_file_name = ENCODE_FILE (file_name); | ||
| 1965 | |||
| 1966 | #ifdef MAC_OSX | ||
| 1967 | err = AECoercePtr (TYPE_FILE_NAME, SDATA (encoded_file_name), | ||
| 1968 | SBYTES (encoded_file_name), typeFSRef, &desc); | ||
| 1969 | #else | ||
| 1970 | SetPortWindowPort (w); | ||
| 1971 | err = AECoercePtr (TYPE_FILE_NAME, SDATA (encoded_file_name), | ||
| 1972 | SBYTES (encoded_file_name), typeFSS, &desc); | ||
| 1973 | #endif | ||
| 1974 | if (err == noErr) | ||
| 1975 | { | ||
| 1976 | #ifdef MAC_OSX | ||
| 1977 | err = AEGetDescData (&desc, &fref, sizeof (FSRef)); | ||
| 1978 | #else | ||
| 1979 | err = AEGetDescData (&desc, &fss, sizeof (FSSpec)); | ||
| 1980 | #endif | ||
| 1981 | AEDisposeDesc (&desc); | ||
| 1982 | } | ||
| 1983 | if (err == noErr) | ||
| 1984 | { | ||
| 1985 | if (alias) | ||
| 1986 | { | ||
| 1987 | /* (FS)ResolveAlias never sets `changed' to true if | ||
| 1988 | `alias' is minimal. */ | ||
| 1989 | #ifdef MAC_OSX | ||
| 1990 | err = FSResolveAlias (NULL, alias, &fref_proxy, &changed); | ||
| 1991 | if (err == noErr) | ||
| 1992 | err = FSCompareFSRefs (&fref, &fref_proxy); | ||
| 1993 | #else | ||
| 1994 | err = ResolveAlias (NULL, alias, &fss_proxy, &changed); | ||
| 1995 | if (err == noErr) | ||
| 1996 | err = !(fss.vRefNum == fss_proxy.vRefNum | ||
| 1997 | && fss.parID == fss_proxy.parID | ||
| 1998 | && EqualString (fss.name, fss_proxy.name, | ||
| 1999 | false, true)); | ||
| 2000 | #endif | ||
| 2001 | } | ||
| 2002 | if (err != noErr || alias == NULL) | ||
| 2003 | { | ||
| 2004 | if (alias) | ||
| 2005 | DisposeHandle ((Handle) alias); | ||
| 2006 | #ifdef MAC_OSX | ||
| 2007 | err = FSNewAliasMinimal (&fref, &alias); | ||
| 2008 | #else | ||
| 2009 | err = NewAliasMinimal (&fss, &alias); | ||
| 2010 | #endif | ||
| 2011 | changed = true; | ||
| 2012 | } | ||
| 2013 | } | ||
| 2014 | if (err == noErr) | ||
| 2015 | if (changed) | ||
| 2016 | err = SetWindowProxyAlias (w, alias); | ||
| 2017 | } | ||
| 2018 | |||
| 2019 | if (alias) | ||
| 2020 | DisposeHandle ((Handle) alias); | ||
| 2021 | |||
| 2022 | if (err != noErr || !STRINGP (file_name)) | ||
| 2023 | RemoveWindowProxy (w); | ||
| 2024 | |||
| 2025 | out: | ||
| 2026 | UNBLOCK_INPUT; | ||
| 2027 | } | ||
| 2028 | #endif | ||
| 2029 | |||
| 2030 | void | 1939 | void |
| 2031 | mac_update_title_bar (f, save_match_data) | 1940 | mac_update_title_bar (f, save_match_data) |
| 2032 | struct frame *f; | 1941 | struct frame *f; |
| @@ -2048,9 +1957,11 @@ mac_update_title_bar (f, save_match_data) | |||
| 2048 | || (!MINI_WINDOW_P (w) | 1957 | || (!MINI_WINDOW_P (w) |
| 2049 | && (modified_p != !NILP (w->last_had_star)))) | 1958 | && (modified_p != !NILP (w->last_had_star)))) |
| 2050 | { | 1959 | { |
| 2051 | SetWindowModified (FRAME_MAC_WINDOW (f), | 1960 | BLOCK_INPUT; |
| 2052 | !MINI_WINDOW_P (w) && modified_p); | 1961 | mac_set_window_modified (FRAME_MAC_WINDOW (f), |
| 1962 | !MINI_WINDOW_P (w) && modified_p); | ||
| 2053 | mac_update_proxy_icon (f); | 1963 | mac_update_proxy_icon (f); |
| 1964 | UNBLOCK_INPUT; | ||
| 2054 | } | 1965 | } |
| 2055 | #endif | 1966 | #endif |
| 2056 | } | 1967 | } |
| @@ -2247,52 +2158,12 @@ mac_window (f, window_prompting, minibuffer_only) | |||
| 2247 | long window_prompting; | 2158 | long window_prompting; |
| 2248 | int minibuffer_only; | 2159 | int minibuffer_only; |
| 2249 | { | 2160 | { |
| 2250 | Rect r; | ||
| 2251 | |||
| 2252 | BLOCK_INPUT; | 2161 | BLOCK_INPUT; |
| 2253 | 2162 | ||
| 2254 | SetRect (&r, f->left_pos, f->top_pos, | 2163 | mac_create_frame_window (f, 0); |
| 2255 | f->left_pos + FRAME_PIXEL_WIDTH (f), | ||
| 2256 | f->top_pos + FRAME_PIXEL_HEIGHT (f)); | ||
| 2257 | #if TARGET_API_MAC_CARBON | ||
| 2258 | CreateNewWindow (kDocumentWindowClass, | ||
| 2259 | kWindowStandardDocumentAttributes | ||
| 2260 | #ifdef MAC_OSX | ||
| 2261 | | kWindowToolbarButtonAttribute | ||
| 2262 | #endif | ||
| 2263 | , &r, &FRAME_MAC_WINDOW (f)); | ||
| 2264 | if (FRAME_MAC_WINDOW (f)) | ||
| 2265 | { | ||
| 2266 | SetWRefCon (FRAME_MAC_WINDOW (f), (long) f->output_data.mac); | ||
| 2267 | if (install_window_handler (FRAME_MAC_WINDOW (f)) != noErr) | ||
| 2268 | { | ||
| 2269 | DisposeWindow (FRAME_MAC_WINDOW (f)); | ||
| 2270 | FRAME_MAC_WINDOW (f) = NULL; | ||
| 2271 | } | ||
| 2272 | } | ||
| 2273 | #else /* !TARGET_API_MAC_CARBON */ | ||
| 2274 | FRAME_MAC_WINDOW (f) | ||
| 2275 | = NewCWindow (NULL, &r, "\p", false, zoomDocProc, | ||
| 2276 | (WindowRef) -1, 1, (long) f->output_data.mac); | ||
| 2277 | #endif /* !TARGET_API_MAC_CARBON */ | ||
| 2278 | /* so that update events can find this mac_output struct */ | ||
| 2279 | f->output_data.mac->mFP = f; /* point back to emacs frame */ | ||
| 2280 | |||
| 2281 | #ifndef MAC_OSX | ||
| 2282 | if (FRAME_MAC_WINDOW (f)) | ||
| 2283 | { | ||
| 2284 | ControlRef root_control; | ||
| 2285 | 2164 | ||
| 2286 | if (CreateRootControl (FRAME_MAC_WINDOW (f), &root_control) != noErr) | ||
| 2287 | { | ||
| 2288 | DisposeWindow (FRAME_MAC_WINDOW (f)); | ||
| 2289 | FRAME_MAC_WINDOW (f) = NULL; | ||
| 2290 | } | ||
| 2291 | } | ||
| 2292 | #endif | ||
| 2293 | if (FRAME_MAC_WINDOW (f)) | 2165 | if (FRAME_MAC_WINDOW (f)) |
| 2294 | XSetWindowBackground (FRAME_MAC_DISPLAY(f), FRAME_MAC_WINDOW (f), | 2166 | mac_set_frame_window_background (f, FRAME_BACKGROUND_PIXEL (f)); |
| 2295 | FRAME_BACKGROUND_PIXEL (f)); | ||
| 2296 | 2167 | ||
| 2297 | #if USE_MAC_TOOLBAR | 2168 | #if USE_MAC_TOOLBAR |
| 2298 | /* At the moment, the size of the tool bar is not yet known. We | 2169 | /* At the moment, the size of the tool bar is not yet known. We |
| @@ -2875,7 +2746,7 @@ FRAME nil means use the selected frame. */) | |||
| 2875 | if (!front_p) | 2746 | if (!front_p) |
| 2876 | { | 2747 | { |
| 2877 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 | 2748 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 |
| 2878 | if (FrontNonFloatingWindow () == FRAME_MAC_WINDOW (f)) | 2749 | if (mac_front_non_floating_window () == FRAME_MAC_WINDOW (f)) |
| 2879 | SetFrontProcessWithOptions (¤t_psn, | 2750 | SetFrontProcessWithOptions (¤t_psn, |
| 2880 | kSetFrontProcessFrontWindowOnly); | 2751 | kSetFrontProcessFrontWindowOnly); |
| 2881 | else | 2752 | else |
| @@ -2884,8 +2755,8 @@ FRAME nil means use the selected frame. */) | |||
| 2884 | } | 2755 | } |
| 2885 | 2756 | ||
| 2886 | #ifdef MAC_OSX | 2757 | #ifdef MAC_OSX |
| 2887 | ActivateWindow (ActiveNonFloatingWindow (), false); | 2758 | mac_activate_window (mac_active_non_floating_window (), false); |
| 2888 | ActivateWindow (FRAME_MAC_WINDOW (f), true); | 2759 | mac_activate_window (FRAME_MAC_WINDOW (f), true); |
| 2889 | #else | 2760 | #else |
| 2890 | #if !TARGET_API_MAC_CARBON | 2761 | #if !TARGET_API_MAC_CARBON |
| 2891 | /* SelectWindow (Non-Carbon) does not issue deactivate events if the | 2762 | /* SelectWindow (Non-Carbon) does not issue deactivate events if the |
| @@ -3663,26 +3534,7 @@ show_hourglass (timer) | |||
| 3663 | 3534 | ||
| 3664 | if (FRAME_LIVE_P (f) && FRAME_MAC_P (f) | 3535 | if (FRAME_LIVE_P (f) && FRAME_MAC_P (f) |
| 3665 | && FRAME_MAC_WINDOW (f) != tip_window) | 3536 | && FRAME_MAC_WINDOW (f) != tip_window) |
| 3666 | { | 3537 | mac_show_hourglass (f); |
| 3667 | #if USE_CG_DRAWING | ||
| 3668 | mac_prepare_for_quickdraw (f); | ||
| 3669 | #endif | ||
| 3670 | if (!f->output_data.mac->hourglass_control) | ||
| 3671 | { | ||
| 3672 | Window w = FRAME_MAC_WINDOW (f); | ||
| 3673 | Rect r; | ||
| 3674 | ControlRef c; | ||
| 3675 | |||
| 3676 | GetWindowPortBounds (w, &r); | ||
| 3677 | r.left = r.right - HOURGLASS_WIDTH; | ||
| 3678 | r.bottom = r.top + HOURGLASS_HEIGHT; | ||
| 3679 | if (CreateChasingArrowsControl (w, &r, &c) == noErr) | ||
| 3680 | f->output_data.mac->hourglass_control = c; | ||
| 3681 | } | ||
| 3682 | |||
| 3683 | if (f->output_data.mac->hourglass_control) | ||
| 3684 | ShowControl (f->output_data.mac->hourglass_control); | ||
| 3685 | } | ||
| 3686 | } | 3538 | } |
| 3687 | 3539 | ||
| 3688 | hourglass_shown_p = 1; | 3540 | hourglass_shown_p = 1; |
| @@ -3708,15 +3560,8 @@ hide_hourglass () | |||
| 3708 | { | 3560 | { |
| 3709 | struct frame *f = XFRAME (frame); | 3561 | struct frame *f = XFRAME (frame); |
| 3710 | 3562 | ||
| 3711 | if (FRAME_MAC_P (f) | 3563 | if (FRAME_MAC_P (f)) |
| 3712 | /* Watch out for newly created frames. */ | 3564 | mac_hide_hourglass (f); |
| 3713 | && f->output_data.mac->hourglass_control) | ||
| 3714 | { | ||
| 3715 | #if USE_CG_DRAWING | ||
| 3716 | mac_prepare_for_quickdraw (f); | ||
| 3717 | #endif | ||
| 3718 | HideControl (f->output_data.mac->hourglass_control); | ||
| 3719 | } | ||
| 3720 | } | 3565 | } |
| 3721 | 3566 | ||
| 3722 | hourglass_shown_p = 0; | 3567 | hourglass_shown_p = 0; |
| @@ -3953,33 +3798,17 @@ x_create_tip_frame (dpyinfo, parms, text) | |||
| 3953 | 3798 | ||
| 3954 | window_prompting = x_figure_window_size (f, parms, 0); | 3799 | window_prompting = x_figure_window_size (f, parms, 0); |
| 3955 | 3800 | ||
| 3956 | { | 3801 | BLOCK_INPUT; |
| 3957 | Rect r; | ||
| 3958 | 3802 | ||
| 3959 | BLOCK_INPUT; | 3803 | mac_create_frame_window (f, 1); |
| 3960 | SetRect (&r, 0, 0, 1, 1); | 3804 | |
| 3961 | #if TARGET_API_MAC_CARBON | 3805 | if (FRAME_MAC_WINDOW (f)) |
| 3962 | if (CreateNewWindow (kHelpWindowClass, | 3806 | { |
| 3963 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 | 3807 | mac_set_frame_window_background (f, FRAME_BACKGROUND_PIXEL (f)); |
| 3964 | kWindowIgnoreClicksAttribute | | 3808 | tip_window = FRAME_MAC_WINDOW (f); |
| 3965 | #endif | 3809 | } |
| 3966 | kWindowNoUpdatesAttribute | | 3810 | |
| 3967 | kWindowNoActivatesAttribute, | 3811 | UNBLOCK_INPUT; |
| 3968 | &r, &tip_window) == noErr) | ||
| 3969 | #else | ||
| 3970 | if (tip_window = NewCWindow (NULL, &r, "\p", false, plainDBox, | ||
| 3971 | NULL, false, 0L)) | ||
| 3972 | #endif | ||
| 3973 | { | ||
| 3974 | FRAME_MAC_WINDOW (f) = tip_window; | ||
| 3975 | XSetWindowBackground (FRAME_MAC_DISPLAY(f), tip_window, | ||
| 3976 | FRAME_BACKGROUND_PIXEL (f)); | ||
| 3977 | SetWRefCon (tip_window, (long) f->output_data.mac); | ||
| 3978 | /* so that update events can find this mac_output struct */ | ||
| 3979 | f->output_data.mac->mFP = f; | ||
| 3980 | } | ||
| 3981 | UNBLOCK_INPUT; | ||
| 3982 | } | ||
| 3983 | 3812 | ||
| 3984 | x_make_gc (f); | 3813 | x_make_gc (f); |
| 3985 | 3814 | ||
| @@ -4076,7 +3905,7 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y) | |||
| 4076 | 3905 | ||
| 4077 | BLOCK_INPUT; | 3906 | BLOCK_INPUT; |
| 4078 | #if TARGET_API_MAC_CARBON | 3907 | #if TARGET_API_MAC_CARBON |
| 4079 | GetGlobalMouse (&mouse_pos); | 3908 | mac_get_global_mouse (&mouse_pos); |
| 4080 | #else | 3909 | #else |
| 4081 | GetMouse (&mouse_pos); | 3910 | GetMouse (&mouse_pos); |
| 4082 | LocalToGlobal (&mouse_pos); | 3911 | LocalToGlobal (&mouse_pos); |
| @@ -4200,7 +4029,7 @@ Text larger than the specified size is clipped. */) | |||
| 4200 | BLOCK_INPUT; | 4029 | BLOCK_INPUT; |
| 4201 | compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f), | 4030 | compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f), |
| 4202 | FRAME_PIXEL_HEIGHT (f), &root_x, &root_y); | 4031 | FRAME_PIXEL_HEIGHT (f), &root_x, &root_y); |
| 4203 | MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false); | 4032 | mac_move_window (FRAME_MAC_WINDOW (f), root_x, root_y, false); |
| 4204 | UNBLOCK_INPUT; | 4033 | UNBLOCK_INPUT; |
| 4205 | goto start_timer; | 4034 | goto start_timer; |
| 4206 | } | 4035 | } |
| @@ -4302,10 +4131,10 @@ Text larger than the specified size is clipped. */) | |||
| 4302 | compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y); | 4131 | compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y); |
| 4303 | 4132 | ||
| 4304 | BLOCK_INPUT; | 4133 | BLOCK_INPUT; |
| 4305 | MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false); | 4134 | mac_move_window (FRAME_MAC_WINDOW (f), root_x, root_y, false); |
| 4306 | SizeWindow (FRAME_MAC_WINDOW (f), width, height, true); | 4135 | mac_size_window (FRAME_MAC_WINDOW (f), width, height, true); |
| 4307 | ShowWindow (FRAME_MAC_WINDOW (f)); | 4136 | mac_show_window (FRAME_MAC_WINDOW (f)); |
| 4308 | BringToFront (FRAME_MAC_WINDOW (f)); | 4137 | mac_bring_window_to_front (FRAME_MAC_WINDOW (f)); |
| 4309 | UNBLOCK_INPUT; | 4138 | UNBLOCK_INPUT; |
| 4310 | 4139 | ||
| 4311 | FRAME_PIXEL_WIDTH (f) = width; | 4140 | FRAME_PIXEL_WIDTH (f) = width; |
| @@ -4366,25 +4195,11 @@ Value is t if tooltip was open, nil otherwise. */) | |||
| 4366 | 4195 | ||
| 4367 | 4196 | ||
| 4368 | 4197 | ||
| 4369 | #if TARGET_API_MAC_CARBON | ||
| 4370 | /*********************************************************************** | 4198 | /*********************************************************************** |
| 4371 | File selection dialog | 4199 | File selection dialog |
| 4372 | ***********************************************************************/ | 4200 | ***********************************************************************/ |
| 4373 | 4201 | ||
| 4374 | static pascal void mac_nav_event_callback P_ ((NavEventCallbackMessage, | 4202 | #if TARGET_API_MAC_CARBON |
| 4375 | NavCBRecPtr, void *)); | ||
| 4376 | |||
| 4377 | /** | ||
| 4378 | There is a relatively standard way to do this using applescript to run | ||
| 4379 | a (choose file) method. However, this doesn't do "the right thing" | ||
| 4380 | by working only if the find-file occurred during a menu or toolbar | ||
| 4381 | click. So we must do the file dialog by hand, using the navigation | ||
| 4382 | manager. This also has more flexibility in determining the default | ||
| 4383 | directory and whether or not we are going to choose a file. | ||
| 4384 | **/ | ||
| 4385 | |||
| 4386 | extern Lisp_Object Qfile_name_history; | ||
| 4387 | |||
| 4388 | DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, | 4203 | DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, |
| 4389 | doc: /* Read file name, prompting with PROMPT in directory DIR. | 4204 | doc: /* Read file name, prompting with PROMPT in directory DIR. |
| 4390 | Use a file selection dialog. | 4205 | Use a file selection dialog. |
| @@ -4394,182 +4209,10 @@ If ONLY-DIR-P is non-nil, the user can only select directories. */) | |||
| 4394 | (prompt, dir, default_filename, mustmatch, only_dir_p) | 4209 | (prompt, dir, default_filename, mustmatch, only_dir_p) |
| 4395 | Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p; | 4210 | Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p; |
| 4396 | { | 4211 | { |
| 4397 | Lisp_Object file = Qnil; | 4212 | return mac_file_dialog (prompt, dir, default_filename, mustmatch, only_dir_p); |
| 4398 | int count = SPECPDL_INDEX (); | ||
| 4399 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; | ||
| 4400 | char filename[MAXPATHLEN]; | ||
| 4401 | static NavEventUPP mac_nav_event_callbackUPP = NULL; | ||
| 4402 | |||
| 4403 | check_mac (); | ||
| 4404 | |||
| 4405 | GCPRO6 (prompt, dir, default_filename, mustmatch, file, only_dir_p); | ||
| 4406 | CHECK_STRING (prompt); | ||
| 4407 | CHECK_STRING (dir); | ||
| 4408 | |||
| 4409 | /* Create the dialog with PROMPT as title, using DIR as initial | ||
| 4410 | directory and using "*" as pattern. */ | ||
| 4411 | dir = Fexpand_file_name (dir, Qnil); | ||
| 4412 | |||
| 4413 | { | ||
| 4414 | OSStatus status; | ||
| 4415 | NavDialogCreationOptions options; | ||
| 4416 | NavDialogRef dialogRef; | ||
| 4417 | NavTypeListHandle fileTypes = NULL; | ||
| 4418 | NavUserAction userAction; | ||
| 4419 | CFStringRef message=NULL, saveName = NULL; | ||
| 4420 | |||
| 4421 | BLOCK_INPUT; | ||
| 4422 | /* No need for a callback function because we are modal */ | ||
| 4423 | NavGetDefaultDialogCreationOptions(&options); | ||
| 4424 | options.modality = kWindowModalityAppModal; | ||
| 4425 | options.location.h = options.location.v = -1; | ||
| 4426 | options.optionFlags = kNavDefaultNavDlogOptions; | ||
| 4427 | options.optionFlags |= kNavAllFilesInPopup; /* All files allowed */ | ||
| 4428 | options.optionFlags |= kNavSelectAllReadableItem; | ||
| 4429 | options.optionFlags &= ~kNavAllowMultipleFiles; | ||
| 4430 | if (!NILP(prompt)) | ||
| 4431 | { | ||
| 4432 | message = cfstring_create_with_string (prompt); | ||
| 4433 | options.message = message; | ||
| 4434 | } | ||
| 4435 | /* Don't set the application, let it use default. | ||
| 4436 | options.clientName = CFSTR ("Emacs"); | ||
| 4437 | */ | ||
| 4438 | |||
| 4439 | if (mac_nav_event_callbackUPP == NULL) | ||
| 4440 | mac_nav_event_callbackUPP = NewNavEventUPP (mac_nav_event_callback); | ||
| 4441 | |||
| 4442 | if (!NILP (only_dir_p)) | ||
| 4443 | status = NavCreateChooseFolderDialog(&options, mac_nav_event_callbackUPP, | ||
| 4444 | NULL, NULL, &dialogRef); | ||
| 4445 | else if (NILP (mustmatch)) | ||
| 4446 | { | ||
| 4447 | /* This is a save dialog */ | ||
| 4448 | options.optionFlags |= kNavDontConfirmReplacement; | ||
| 4449 | options.actionButtonLabel = CFSTR ("Ok"); | ||
| 4450 | options.windowTitle = CFSTR ("Enter name"); | ||
| 4451 | |||
| 4452 | if (STRINGP (default_filename)) | ||
| 4453 | { | ||
| 4454 | Lisp_Object utf8 = ENCODE_UTF_8 (default_filename); | ||
| 4455 | char *begPtr = SDATA(utf8); | ||
| 4456 | char *filePtr = begPtr + SBYTES(utf8); | ||
| 4457 | while (filePtr != begPtr && !IS_DIRECTORY_SEP(filePtr[-1])) | ||
| 4458 | filePtr--; | ||
| 4459 | saveName = cfstring_create_with_utf8_cstring (filePtr); | ||
| 4460 | options.saveFileName = saveName; | ||
| 4461 | options.optionFlags |= kNavSelectDefaultLocation; | ||
| 4462 | } | ||
| 4463 | status = NavCreatePutFileDialog(&options, | ||
| 4464 | 'TEXT', kNavGenericSignature, | ||
| 4465 | mac_nav_event_callbackUPP, NULL, | ||
| 4466 | &dialogRef); | ||
| 4467 | } | ||
| 4468 | else | ||
| 4469 | { | ||
| 4470 | /* This is an open dialog*/ | ||
| 4471 | status = NavCreateChooseFileDialog(&options, fileTypes, | ||
| 4472 | mac_nav_event_callbackUPP, NULL, | ||
| 4473 | NULL, NULL, &dialogRef); | ||
| 4474 | } | ||
| 4475 | |||
| 4476 | /* Set the default location and continue*/ | ||
| 4477 | if (status == noErr) | ||
| 4478 | { | ||
| 4479 | Lisp_Object encoded_dir = ENCODE_FILE (dir); | ||
| 4480 | AEDesc defLocAed; | ||
| 4481 | |||
| 4482 | status = AECreateDesc (TYPE_FILE_NAME, SDATA (encoded_dir), | ||
| 4483 | SBYTES (encoded_dir), &defLocAed); | ||
| 4484 | if (status == noErr) | ||
| 4485 | { | ||
| 4486 | NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed); | ||
| 4487 | AEDisposeDesc(&defLocAed); | ||
| 4488 | } | ||
| 4489 | status = NavDialogRun(dialogRef); | ||
| 4490 | } | ||
| 4491 | |||
| 4492 | if (saveName) CFRelease(saveName); | ||
| 4493 | if (message) CFRelease(message); | ||
| 4494 | |||
| 4495 | if (status == noErr) { | ||
| 4496 | userAction = NavDialogGetUserAction(dialogRef); | ||
| 4497 | switch (userAction) | ||
| 4498 | { | ||
| 4499 | case kNavUserActionNone: | ||
| 4500 | case kNavUserActionCancel: | ||
| 4501 | break; /* Treat cancel like C-g */ | ||
| 4502 | case kNavUserActionOpen: | ||
| 4503 | case kNavUserActionChoose: | ||
| 4504 | case kNavUserActionSaveAs: | ||
| 4505 | { | ||
| 4506 | NavReplyRecord reply; | ||
| 4507 | Size len; | ||
| 4508 | |||
| 4509 | status = NavDialogGetReply(dialogRef, &reply); | ||
| 4510 | if (status != noErr) | ||
| 4511 | break; | ||
| 4512 | status = AEGetNthPtr (&reply.selection, 1, TYPE_FILE_NAME, | ||
| 4513 | NULL, NULL, filename, | ||
| 4514 | sizeof (filename) - 1, &len); | ||
| 4515 | if (status == noErr) | ||
| 4516 | { | ||
| 4517 | len = min (len, sizeof (filename) - 1); | ||
| 4518 | filename[len] = '\0'; | ||
| 4519 | if (reply.saveFileName) | ||
| 4520 | { | ||
| 4521 | /* If it was a saved file, we need to add the file name */ | ||
| 4522 | if (len && len < sizeof (filename) - 1 | ||
| 4523 | && filename[len-1] != '/') | ||
| 4524 | filename[len++] = '/'; | ||
| 4525 | CFStringGetCString(reply.saveFileName, filename+len, | ||
| 4526 | sizeof (filename) - len, | ||
| 4527 | #ifdef MAC_OSX | ||
| 4528 | kCFStringEncodingUTF8 | ||
| 4529 | #else | ||
| 4530 | CFStringGetSystemEncoding () | ||
| 4531 | #endif | ||
| 4532 | ); | ||
| 4533 | } | ||
| 4534 | file = DECODE_FILE (make_unibyte_string (filename, | ||
| 4535 | strlen (filename))); | ||
| 4536 | } | ||
| 4537 | NavDisposeReply(&reply); | ||
| 4538 | } | ||
| 4539 | break; | ||
| 4540 | } | ||
| 4541 | NavDialogDispose(dialogRef); | ||
| 4542 | UNBLOCK_INPUT; | ||
| 4543 | } | ||
| 4544 | else { | ||
| 4545 | UNBLOCK_INPUT; | ||
| 4546 | /* Fall back on minibuffer if there was a problem */ | ||
| 4547 | file = Fcompleting_read (prompt, intern ("read-file-name-internal"), | ||
| 4548 | dir, mustmatch, dir, Qfile_name_history, | ||
| 4549 | default_filename, Qnil); | ||
| 4550 | } | ||
| 4551 | } | ||
| 4552 | |||
| 4553 | UNGCPRO; | ||
| 4554 | |||
| 4555 | /* Make "Cancel" equivalent to C-g. */ | ||
| 4556 | if (NILP (file)) | ||
| 4557 | Fsignal (Qquit, Qnil); | ||
| 4558 | |||
| 4559 | return unbind_to (count, file); | ||
| 4560 | } | ||
| 4561 | |||
| 4562 | |||
| 4563 | /* Need to register some event callback function for enabling drag and | ||
| 4564 | drop in Navigation Service dialogs. */ | ||
| 4565 | static pascal void | ||
| 4566 | mac_nav_event_callback (selector, parms, data) | ||
| 4567 | NavEventCallbackMessage selector; | ||
| 4568 | NavCBRecPtr parms; | ||
| 4569 | void *data ; | ||
| 4570 | { | ||
| 4571 | } | 4213 | } |
| 4572 | #endif | 4214 | #endif |
| 4215 | |||
| 4573 | 4216 | ||
| 4574 | /*********************************************************************** | 4217 | /*********************************************************************** |
| 4575 | Fonts | 4218 | Fonts |