X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/30c92fab793df102666fff234d59377003a79462..0924e3f6e1b5749019ac7f69765af355623c9db8:/src/macfns.c diff --git a/src/macfns.c b/src/macfns.c index f40e8354f3..9cb9e3e049 100644 --- a/src/macfns.c +++ b/src/macfns.c @@ -1,5 +1,6 @@ /* Graphical user interface functions for Mac OS. - Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2003, 2004, + 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -15,64 +16,48 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ /* Contributed by Andrew Choi (akochoi@mac.com). */ #include - -#include #include #include -#include -#include #include "lisp.h" -#include "charset.h" #include "macterm.h" #include "frame.h" #include "window.h" #include "buffer.h" -#include "dispextern.h" -#include "fontset.h" #include "intervals.h" +#include "dispextern.h" #include "keyboard.h" #include "blockinput.h" -#include "epaths.h" -#include "termhooks.h" +#include +#include "charset.h" #include "coding.h" +#include "fontset.h" #include "systime.h" +#include "termhooks.h" +#include "atimer.h" -/* #include "bitmaps/gray.xbm" */ -#define gray_width 2 -#define gray_height 2 -static unsigned char gray_bits[] = { - 0x01, 0x02}; - -/*#include -#include */ #include #include #include +#include +#include +#include -#include -#include +extern void free_frame_menubar (); -/*extern void free_frame_menubar (); -extern double atof (); -extern int w32_console_toggle_lock_key (int vk_code, Lisp_Object new_state); -extern int quit_char;*/ +#if TARGET_API_MAC_CARBON -extern char *lispy_function_keys[]; +/* Carbon version info */ -/* The gray bitmap `bitmaps/gray'. This is done because macterm.c uses - it, and including `bitmaps/gray' more than once is a problem when - config.h defines `static' as an empty replacement string. */ +static Lisp_Object Vmac_carbon_version_string; -int gray_bitmap_width = gray_width; -int gray_bitmap_height = gray_height; -unsigned char *gray_bitmap_bits = gray_bits; +#endif /* TARGET_API_MAC_CARBON */ /* Non-zero means we're allowed to display an hourglass cursor. */ @@ -109,55 +94,20 @@ Lisp_Object Vx_no_window_manager; Lisp_Object Vx_pixel_size_width_font_regexp; -/* Evaluate this expression to rebuild the section of syms_of_macfns - that initializes and staticpros the symbols declared below. Note - that Emacs 18 has a bug that keeps C-x C-e from being able to - evaluate this expression. - -(progn - ;; Accumulate a list of the symbols we want to initialize from the - ;; declarations at the top of the file. - (goto-char (point-min)) - (search-forward "/\*&&& symbols declared here &&&*\/\n") - (let (symbol-list) - (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)") - (setq symbol-list - (cons (buffer-substring (match-beginning 1) (match-end 1)) - symbol-list)) - (forward-line 1)) - (setq symbol-list (nreverse symbol-list)) - ;; Delete the section of syms_of_... where we initialize the symbols. - (search-forward "\n /\*&&& init symbols here &&&*\/\n") - (let ((start (point))) - (while (looking-at "^ Q") - (forward-line 2)) - (kill-region start (point))) - ;; Write a new symbol initialization section. - (while symbol-list - (insert (format " %s = intern (\"" (car symbol-list))) - (let ((start (point))) - (insert (substring (car symbol-list) 1)) - (subst-char-in-region start (point) ?_ ?-)) - (insert (format "\");\n staticpro (&%s);\n" (car symbol-list))) - (setq symbol-list (cdr symbol-list))))) - - */ - -/*&&& symbols declared here &&&*/ Lisp_Object Qnone; Lisp_Object Qsuppress_icon; Lisp_Object Qundefined_color; Lisp_Object Qcancel_timer; -Lisp_Object Qhyper; -Lisp_Object Qsuper; -Lisp_Object Qmeta; -Lisp_Object Qalt; -Lisp_Object Qctrl; -Lisp_Object Qcontrol; -Lisp_Object Qshift; + +/* In dispnew.c */ extern Lisp_Object Vwindow_system_version; +#if GLYPH_DEBUG +int image_cache_refcount, dpyinfo_refcount; +#endif + + #if 0 /* Use xstricmp instead. */ /* compare two strings ignoring case */ @@ -215,7 +165,7 @@ check_x_frame (frame) CHECK_LIVE_FRAME (frame); f = XFRAME (frame); if (! FRAME_MAC_P (f)) - error ("non-mac frame used"); + error ("Non-Mac frame used"); return f; } @@ -250,40 +200,11 @@ check_x_display_info (frame) return dpyinfo; } - -/* Return the Emacs frame-object corresponding to a mac window. - It could be the frame's main window or an icon window. */ - -/* This function can be called during GC, so use GC_xxx type test macros. */ - -struct frame * -x_window_to_frame (dpyinfo, wdesc) - struct mac_display_info *dpyinfo; - WindowPtr wdesc; -{ - Lisp_Object tail, frame; - struct frame *f; - - for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail)) - { - frame = XCAR (tail); - if (!GC_FRAMEP (frame)) - continue; - f = XFRAME (frame); - if (!FRAME_W32_P (f) || FRAME_MAC_DISPLAY_INFO (f) != dpyinfo) - continue; - /*if (f->output_data.w32->hourglass_window == wdesc) - return f;*/ - - /* MAC_TODO: Check tooltips when supported. */ - if (FRAME_MAC_WINDOW (f) == wdesc) - return f; - } - return 0; -} + static Lisp_Object unwind_create_frame P_ ((Lisp_Object)); +static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object)); void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); @@ -297,18 +218,11 @@ void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object)); void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object)); void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object)); void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object)); -void x_set_scroll_bar_foreground P_ ((struct frame *, Lisp_Object, - Lisp_Object)); -void x_set_scroll_bar_background P_ ((struct frame *, Lisp_Object, - Lisp_Object)); -static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *, - Lisp_Object, - Lisp_Object, - char *, char *, - int)); extern void mac_get_window_bounds P_ ((struct frame *, Rect *, Rect *)); + + /* Store the screen positions of frame F into XPTR and YPTR. These are the positions of the containing window manager window, not Emacs's own window. */ @@ -337,7 +251,7 @@ typedef struct colormap_t char *name; } colormap_t; -colormap_t mac_color_map[] = +static const colormap_t mac_color_map[] = { { RGB_TO_ULONG(255, 250, 250), "snow" }, { RGB_TO_ULONG(248, 248, 255), "ghost white" }, @@ -1095,7 +1009,7 @@ colormap_t mac_color_map[] = Lisp_Object mac_color_map_lookup (colorname) - char *colorname; + const char *colorname; { Lisp_Object ret = Qnil; int i; @@ -1118,7 +1032,7 @@ Lisp_Object x_to_mac_color (colorname) char * colorname; { - register Lisp_Object tail, ret = Qnil; + register Lisp_Object ret = Qnil; BLOCK_INPUT; @@ -1185,7 +1099,7 @@ x_to_mac_color (colorname) char *color; unsigned long colorval; int i, pos; - pos = 0; + pos = 16; colorval = 0; color = colorname + 4; @@ -1221,7 +1135,7 @@ x_to_mac_color (colorname) if (value == ULONG_MAX) break; colorval |= (value << pos); - pos += 0x8; + pos -= 0x8; if (i == 2) { if (*end != '\0') @@ -1240,7 +1154,7 @@ x_to_mac_color (colorname) char *color; unsigned long colorval; int i, pos; - pos = 0; + pos = 16; colorval = 0; color = colorname + 5; @@ -1262,7 +1176,7 @@ x_to_mac_color (colorname) if (val == 0x100) val = 0xFF; colorval |= (val << pos); - pos += 0x8; + pos -= 0x8; if (i == 2) { if (*end != '\0') @@ -1384,6 +1298,7 @@ x_set_foreground_color (f, arg, oldval) struct frame *f; Lisp_Object arg, oldval; { + struct mac_output *mac = f->output_data.mac; unsigned long fg, old_fg; fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); @@ -1392,10 +1307,28 @@ x_set_foreground_color (f, arg, oldval) if (FRAME_MAC_WINDOW (f) != 0) { + Display *dpy = FRAME_MAC_DISPLAY (f); + + BLOCK_INPUT; + XSetForeground (dpy, mac->normal_gc, fg); + XSetBackground (dpy, mac->reverse_gc, fg); + + if (mac->cursor_pixel == old_fg) + { + unload_color (f, mac->cursor_pixel); + mac->cursor_pixel = fg; + XSetBackground (dpy, mac->cursor_gc, mac->cursor_pixel); + } + + UNBLOCK_INPUT; + update_face_from_frame_parameter (f, Qforeground_color, arg); + if (FRAME_VISIBLE_P (f)) redraw_frame (f); } + + unload_color (f, old_fg); } void @@ -1403,11 +1336,24 @@ x_set_background_color (f, arg, oldval) struct frame *f; Lisp_Object arg, oldval; { - FRAME_BACKGROUND_PIXEL (f) - = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f)); + struct mac_output *mac = f->output_data.mac; + unsigned long bg; + + bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f)); + unload_color (f, FRAME_BACKGROUND_PIXEL (f)); + FRAME_BACKGROUND_PIXEL (f) = bg; if (FRAME_MAC_WINDOW (f) != 0) { + Display *dpy = FRAME_MAC_DISPLAY (f); + + BLOCK_INPUT; + XSetBackground (dpy, mac->normal_gc, bg); + XSetForeground (dpy, mac->reverse_gc, bg); + XSetWindowBackground (dpy, FRAME_MAC_WINDOW (f), bg); + XSetForeground (dpy, mac->cursor_gc, bg); + + UNBLOCK_INPUT; update_face_from_frame_parameter (f, Qbackground_color, arg); if (FRAME_VISIBLE_P (f)) @@ -1420,148 +1366,99 @@ x_set_mouse_color (f, arg, oldval) struct frame *f; Lisp_Object arg, oldval; { + struct x_output *x = f->output_data.x; Cursor cursor, nontext_cursor, mode_cursor, hand_cursor; - int count; - int mask_color; - - if (!EQ (Qnil, arg)) - f->output_data.mac->mouse_pixel - = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); - mask_color = FRAME_BACKGROUND_PIXEL (f); + Cursor hourglass_cursor, horizontal_drag_cursor; + unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); + unsigned long mask_color = x->background_pixel; /* Don't let pointers be invisible. */ - if (mask_color == f->output_data.mac->mouse_pixel - && mask_color == FRAME_BACKGROUND_PIXEL (f)) - f->output_data.mac->mouse_pixel = FRAME_FOREGROUND_PIXEL (f); - -#if 0 /* MAC_TODO : cursor changes */ - BLOCK_INPUT; + if (mask_color == pixel) + pixel = x->foreground_pixel; - /* It's not okay to crash if the user selects a screwy cursor. */ - count = x_catch_errors (FRAME_W32_DISPLAY (f)); + f->output_data.mac->mouse_pixel = pixel; - if (!EQ (Qnil, Vx_pointer_shape)) + if (!NILP (Vx_pointer_shape)) { CHECK_NUMBER (Vx_pointer_shape); - cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XINT (Vx_pointer_shape)); + cursor = XINT (Vx_pointer_shape); } else - cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_xterm); - x_check_errors (FRAME_W32_DISPLAY (f), "bad text pointer cursor: %s"); + cursor = kThemeIBeamCursor; - if (!EQ (Qnil, Vx_nontext_pointer_shape)) + if (!NILP (Vx_nontext_pointer_shape)) { CHECK_NUMBER (Vx_nontext_pointer_shape); - nontext_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), - XINT (Vx_nontext_pointer_shape)); + nontext_cursor = XINT (Vx_nontext_pointer_shape); } else - nontext_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_left_ptr); - x_check_errors (FRAME_W32_DISPLAY (f), "bad nontext pointer cursor: %s"); + nontext_cursor = kThemeArrowCursor; - if (!EQ (Qnil, Vx_hourglass_pointer_shape)) + if (!NILP (Vx_hourglass_pointer_shape)) { CHECK_NUMBER (Vx_hourglass_pointer_shape); - hourglass_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), - XINT (Vx_hourglass_pointer_shape)); + hourglass_cursor = XINT (Vx_hourglass_pointer_shape); } else - hourglass_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_watch); - x_check_errors (FRAME_W32_DISPLAY (f), "bad busy pointer cursor: %s"); + hourglass_cursor = kThemeWatchCursor; - x_check_errors (FRAME_W32_DISPLAY (f), "bad nontext pointer cursor: %s"); - if (!EQ (Qnil, Vx_mode_pointer_shape)) + if (!NILP (Vx_mode_pointer_shape)) { CHECK_NUMBER (Vx_mode_pointer_shape); - mode_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), - XINT (Vx_mode_pointer_shape)); + mode_cursor = XINT (Vx_mode_pointer_shape); } else - mode_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_xterm); - x_check_errors (FRAME_W32_DISPLAY (f), "bad modeline pointer cursor: %s"); + mode_cursor = kThemeArrowCursor; - if (!EQ (Qnil, Vx_sensitive_text_pointer_shape)) + if (!NILP (Vx_sensitive_text_pointer_shape)) { CHECK_NUMBER (Vx_sensitive_text_pointer_shape); - hand_cursor - = XCreateFontCursor (FRAME_W32_DISPLAY (f), - XINT (Vx_sensitive_text_pointer_shape)); + hand_cursor = XINT (Vx_sensitive_text_pointer_shape); } else - hand_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_crosshair); + hand_cursor = kThemePointingHandCursor; if (!NILP (Vx_window_horizontal_drag_shape)) { CHECK_NUMBER (Vx_window_horizontal_drag_shape); - horizontal_drag_cursor - = XCreateFontCursor (FRAME_W32_DISPLAY (f), - XINT (Vx_window_horizontal_drag_shape)); + horizontal_drag_cursor = XINT (Vx_window_horizontal_drag_shape); } else - horizontal_drag_cursor - = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_sb_h_double_arrow); - - /* Check and report errors with the above calls. */ - x_check_errors (FRAME_W32_DISPLAY (f), "can't set cursor shape: %s"); - x_uncatch_errors (FRAME_W32_DISPLAY (f), count); + horizontal_drag_cursor = kThemeResizeLeftRightCursor; +#if 0 /* MAC_TODO: cursor color changes */ { XColor fore_color, back_color; - fore_color.pixel = f->output_data.w32->mouse_pixel; + fore_color.pixel = f->output_data.mac->mouse_pixel; + x_query_color (f, &fore_color); back_color.pixel = mask_color; - XQueryColor (FRAME_W32_DISPLAY (f), - DefaultColormap (FRAME_W32_DISPLAY (f), - DefaultScreen (FRAME_W32_DISPLAY (f))), - &fore_color); - XQueryColor (FRAME_W32_DISPLAY (f), - DefaultColormap (FRAME_W32_DISPLAY (f), - DefaultScreen (FRAME_W32_DISPLAY (f))), - &back_color); - XRecolorCursor (FRAME_W32_DISPLAY (f), cursor, - &fore_color, &back_color); - XRecolorCursor (FRAME_W32_DISPLAY (f), nontext_cursor, - &fore_color, &back_color); - XRecolorCursor (FRAME_W32_DISPLAY (f), mode_cursor, - &fore_color, &back_color); - XRecolorCursor (FRAME_W32_DISPLAY (f), hand_cursor, - &fore_color, &back_color); - XRecolorCursor (FRAME_W32_DISPLAY (f), hourglass_cursor, - &fore_color, &back_color); + x_query_color (f, &back_color); + + XRecolorCursor (dpy, cursor, &fore_color, &back_color); + XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color); + XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color); + XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color); + XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color); + XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color); } +#endif - if (FRAME_W32_WINDOW (f) != 0) - XDefineCursor (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), cursor); - - if (cursor != f->output_data.w32->text_cursor && f->output_data.w32->text_cursor != 0) - XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->text_cursor); - f->output_data.w32->text_cursor = cursor; - - if (nontext_cursor != f->output_data.w32->nontext_cursor - && f->output_data.w32->nontext_cursor != 0) - XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->nontext_cursor); - f->output_data.w32->nontext_cursor = nontext_cursor; - - if (hourglass_cursor != f->output_data.w32->hourglass_cursor - && f->output_data.w32->hourglass_cursor != 0) - XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->hourglass_cursor); - f->output_data.w32->hourglass_cursor = hourglass_cursor; + BLOCK_INPUT; - if (mode_cursor != f->output_data.w32->modeline_cursor - && f->output_data.w32->modeline_cursor != 0) - XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->modeline_cursor); - f->output_data.w32->modeline_cursor = mode_cursor; + if (FRAME_MAC_WINDOW (f) != 0) + rif->define_frame_cursor (f, cursor); - if (hand_cursor != f->output_data.w32->hand_cursor - && f->output_data.w32->hand_cursor != 0) - XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->hand_cursor); - f->output_data.w32->hand_cursor = hand_cursor; + f->output_data.mac->text_cursor = cursor; + f->output_data.mac->nontext_cursor = nontext_cursor; + f->output_data.mac->hourglass_cursor = hourglass_cursor; + f->output_data.mac->modeline_cursor = mode_cursor; + f->output_data.mac->hand_cursor = hand_cursor; + f->output_data.mac->horizontal_drag_cursor = horizontal_drag_cursor; - XFlush (FRAME_W32_DISPLAY (f)); UNBLOCK_INPUT; update_face_from_frame_parameter (f, Qmouse_color, arg); -#endif /* MAC_TODO */ } void @@ -1594,9 +1491,10 @@ x_set_cursor_color (f, arg, oldval) { BLOCK_INPUT; /* Update frame's cursor_gc. */ - f->output_data.mac->cursor_gc->foreground = fore_pixel; - f->output_data.mac->cursor_gc->background = pixel; - + XSetBackground (FRAME_MAC_DISPLAY (f), + f->output_data.mac->cursor_gc, pixel); + XSetForeground (FRAME_MAC_DISPLAY (f), + f->output_data.mac->cursor_gc, fore_pixel); UNBLOCK_INPUT; if (FRAME_VISIBLE_P (f)) @@ -1702,7 +1600,7 @@ x_set_icon_name (f, arg, oldval) if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt)) return; } - else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil)) + else if (!NILP (arg) || NILP (oldval)) return; f->icon_name = arg; @@ -1747,36 +1645,15 @@ x_set_menu_bar_lines (f, value, oldval) struct frame *f; Lisp_Object value, oldval; { - int nlines; - int olines = FRAME_MENU_BAR_LINES (f); - - /* Right now, menu bars don't work properly in minibuf-only frames; - most of the commands try to apply themselves to the minibuffer - frame itself, and get an error because you can't switch buffers - in or split the minibuffer window. */ - if (FRAME_MINIBUF_ONLY_P (f)) - return; - - if (INTEGERP (value)) - nlines = XINT (value); - else - nlines = 0; + /* Make sure we redisplay all windows in this frame. */ + windows_or_buffers_changed++; FRAME_MENU_BAR_LINES (f) = 0; - if (nlines) - FRAME_EXTERNAL_MENU_BAR (f) = 1; - else - { - if (FRAME_EXTERNAL_MENU_BAR (f) == 1) - free_frame_menubar (f); - FRAME_EXTERNAL_MENU_BAR (f) = 0; - - /* Adjust the frame size so that the client (text) dimensions - remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being - set correctly. */ - x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); - do_pending_window_change (0); - } + /* The menu bar is always shown. */ + FRAME_EXTERNAL_MENU_BAR (f) = 1; + if (FRAME_MAC_P (f) && f->output_data.mac->menubar_widget == 0) + /* Make sure next redisplay shows the menu bar. */ + XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt; adjust_glyphs (f); } @@ -1847,8 +1724,7 @@ x_set_tool_bar_lines (f, value, oldval) int y = nlines * FRAME_LINE_HEIGHT (f); BLOCK_INPUT; - XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), - 0, y, width, height, 0); + mac_clear_area (f, 0, y, width, height); UNBLOCK_INPUT; if (WINDOWP (f->tool_bar_window)) @@ -1857,8 +1733,49 @@ x_set_tool_bar_lines (f, value, oldval) } + +/* Set the Mac window title to NAME for frame F. */ + +static void +x_set_name_internal (f, name) + FRAME_PTR f; + Lisp_Object name; +{ + if (FRAME_MAC_WINDOW (f)) + { + if (STRING_MULTIBYTE (name)) +#if TARGET_API_MAC_CARBON + name = ENCODE_UTF_8 (name); +#else + name = ENCODE_SYSTEM (name); +#endif + + BLOCK_INPUT; + + { +#if TARGET_API_MAC_CARBON + CFStringRef windowTitle = + cfstring_create_with_utf8_cstring (SDATA (name)); + + SetWindowTitleWithCFString (FRAME_MAC_WINDOW (f), windowTitle); + CFRelease (windowTitle); +#else + Str255 windowTitle; + if (strlen (SDATA (name)) < 255) + { + strcpy (windowTitle, SDATA (name)); + c2pstr (windowTitle); + SetWTitle (FRAME_MAC_WINDOW (f), windowTitle); + } +#endif + } + + UNBLOCK_INPUT; + } +} + /* Change the name of frame F to NAME. If NAME is nil, set F's name to - w32_id_name. + mac_id_name. If EXPLICIT is non-zero, that indicates that lisp code is setting the name; if NAME is a string, set F's name to NAME and set @@ -1888,7 +1805,7 @@ x_set_name (f, name, explicit) else if (f->explicit_name) return; - /* If NAME is nil, set the name to the w32_id_name. */ + /* If NAME is nil, set the name to the mac_id_name. */ if (NILP (name)) { /* Check for no change needed in this very common case @@ -1912,37 +1829,7 @@ x_set_name (f, name, explicit) if (! NILP (f->title)) name = f->title; - if (FRAME_MAC_WINDOW (f)) - { - if (STRING_MULTIBYTE (name)) -#if TARGET_API_MAC_CARBON - name = ENCODE_UTF_8 (name); -#else - return; -#endif - - BLOCK_INPUT; - - { -#if TARGET_API_MAC_CARBON - CFStringRef windowTitle = - cfstring_create_with_utf8_cstring (SDATA (name)); - - SetWindowTitleWithCFString (FRAME_MAC_WINDOW (f), windowTitle); - CFRelease (windowTitle); -#else - Str255 windowTitle; - if (strlen (SDATA (name)) < 255) - { - strcpy (windowTitle, SDATA (name)); - c2pstr (windowTitle); - SetWTitle (FRAME_MAC_WINDOW (f), windowTitle); - } -#endif - } - - UNBLOCK_INPUT; - } + x_set_name_internal (f, name); } /* This function should be called when the user's lisp code has @@ -1993,38 +1880,10 @@ x_set_title (f, name, old_name) if (NILP (name)) name = f->name; + else + CHECK_STRING (name); - if (FRAME_MAC_WINDOW (f)) - { - if (STRING_MULTIBYTE (name)) -#if TARGET_API_MAC_CARBON - name = ENCODE_UTF_8 (name); -#else - return; -#endif - - BLOCK_INPUT; - - { -#if TARGET_API_MAC_CARBON - CFStringRef windowTitle = - cfstring_create_with_utf8_cstring (SDATA (name)); - - SetWindowTitleWithCFString (FRAME_MAC_WINDOW (f), windowTitle); - CFRelease (windowTitle); -#else - Str255 windowTitle; - if (strlen (SDATA (name)) < 255) - { - strcpy (windowTitle, SDATA (name)); - c2pstr (windowTitle); - SetWTitle (FRAME_MAC_WINDOW (f), windowTitle); - } -#endif - } - - UNBLOCK_INPUT; - } + x_set_name_internal (f, name); } void @@ -2036,7 +1895,7 @@ x_set_scroll_bar_default_width (f) int wid = FRAME_COLUMN_WIDTH (f); #ifdef MAC_OSX - FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 16; /* Aqua scroll bars. */ + FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = MAC_AQUA_VERTICAL_SCROLL_BAR_WIDTH; FRAME_CONFIG_SCROLL_BAR_COLS (f) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid - 1) / wid; #else /* not MAC_OSX */ @@ -2050,52 +1909,177 @@ x_set_scroll_bar_default_width (f) #endif /* not MAC_OSX */ } - -/* Subroutines of creating a frame. */ +void +mac_set_scroll_bar_width (f, arg, oldval) + struct frame *f; + Lisp_Object arg, oldval; +{ +#ifdef MAC_OSX + if (INTEGERP (arg) && XINT (arg) > 0) + { + if (XINT (arg) < (MAC_AQUA_SMALL_VERTICAL_SCROLL_BAR_WIDTH + + MAC_AQUA_VERTICAL_SCROLL_BAR_WIDTH) / 2) + XSETINT (arg, MAC_AQUA_SMALL_VERTICAL_SCROLL_BAR_WIDTH); + else + XSETINT (arg, MAC_AQUA_VERTICAL_SCROLL_BAR_WIDTH); + } +#endif + x_set_scroll_bar_width (f, arg, oldval); +} -static char * -mac_get_rdb_resource (rdb, resource) - char *rdb; - char *resource; +static void +mac_set_font (f, arg, oldval) + struct frame *f; + Lisp_Object arg, oldval; { - char *value = rdb; - int len = strlen (resource); + x_set_font (f, arg, oldval); +#if USE_MAC_FONT_PANEL + { + Lisp_Object focus_frame = x_get_focus_frame (f); + + if ((NILP (focus_frame) && f == SELECTED_FRAME ()) + || XFRAME (focus_frame) == f) + { + BLOCK_INPUT; + mac_set_font_info_for_selection (f, DEFAULT_FACE_ID, 0); + UNBLOCK_INPUT; + } + } +#endif +} + +#if TARGET_API_MAC_CARBON +static void +mac_update_proxy_icon (f) + struct frame *f; +{ + OSStatus err; + Lisp_Object file_name = + XBUFFER (XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer)->filename; + Window w = FRAME_MAC_WINDOW (f); + AliasHandle alias = NULL; + + BLOCK_INPUT; - while (*value) + err = GetWindowProxyAlias (w, &alias); + if (err == errWindowDoesNotHaveProxy && !STRINGP (file_name)) + goto out; + + if (STRINGP (file_name)) { - if ((strncmp (value, resource, len) == 0) && (value[len] == ':')) - return xstrdup (&value[len + 1]); + AEDesc desc; +#ifdef MAC_OSX + FSRef fref; +#else + FSSpec fss; +#endif + Boolean changed; + Lisp_Object encoded_file_name = ENCODE_FILE (file_name); - value = strchr (value, '\0') + 1; +#ifdef MAC_OSX + err = AECoercePtr (TYPE_FILE_NAME, SDATA (encoded_file_name), + SBYTES (encoded_file_name), typeFSRef, &desc); +#else + SetPortWindowPort (w); + err = AECoercePtr (TYPE_FILE_NAME, SDATA (encoded_file_name), + SBYTES (encoded_file_name), typeFSS, &desc); +#endif + if (err == noErr) + { +#ifdef MAC_OSX + err = AEGetDescData (&desc, &fref, sizeof (FSRef)); +#else + err = AEGetDescData (&desc, &fss, sizeof (FSSpec)); +#endif + AEDisposeDesc (&desc); + } + if (err == noErr) + { + if (alias) + { +#ifdef MAC_OSX + err = FSUpdateAlias (NULL, &fref, alias, &changed); +#else + err = UpdateAlias (NULL, &fss, alias, &changed); +#endif + } + if (err != noErr || alias == NULL) + { + if (alias) + DisposeHandle ((Handle) alias); +#ifdef MAC_OSX + err = FSNewAliasMinimal (&fref, &alias); +#else + err = NewAliasMinimal (&fss, &alias); +#endif + changed = true; + } + } + if (err == noErr) + if (changed) + err = SetWindowProxyAlias (w, alias); } - return NULL; + if (alias) + DisposeHandle ((Handle) alias); + + if (err != noErr || !STRINGP (file_name)) + RemoveWindowProxy (w); + + out: + UNBLOCK_INPUT; } +#endif + +void +mac_update_title_bar (f, save_match_data) + struct frame *f; + int save_match_data; +{ +#if TARGET_API_MAC_CARBON + struct window *w; + int modified_p; + + if (!FRAME_MAC_P (f)) + return; + + w = XWINDOW (FRAME_SELECTED_WINDOW (f)); + modified_p = (BUF_SAVE_MODIFF (XBUFFER (w->buffer)) + < BUF_MODIFF (XBUFFER (w->buffer))); + if (windows_or_buffers_changed + /* Minibuffer modification status shown in the close button is + confusing. */ + || (!MINI_WINDOW_P (w) + && (modified_p != !NILP (w->last_had_star)))) + SetWindowModified (FRAME_MAC_WINDOW (f), + !MINI_WINDOW_P (w) && modified_p); + + if (windows_or_buffers_changed) + mac_update_proxy_icon (f); +#endif +} + + +/* Subroutines of creating a frame. */ /* Retrieve the string resource specified by NAME with CLASS from - database RDB. */ + database RDB. + + The return value points to the contents of a Lisp string. So it + will not be valid after the next GC where string compaction will + occur. */ char * x_get_string_resource (rdb, name, class) XrmDatabase rdb; char *name, *class; { - if (rdb) - { - char *resource; - - if (resource = mac_get_rdb_resource (rdb, name)) - return resource; - if (resource = mac_get_rdb_resource (rdb, class)) - return resource; - } + Lisp_Object value = xrm_get_resource (rdb, name, class); - /* MAC_TODO: implement resource strings. (Maybe Property Lists?) */ -#if 0 - return mac_get_string_resource (name, class); -#else - return (char *)0; -#endif + if (STRINGP (value)) + return SDATA (value); + else + return NULL; } /* Return the value of parameter PARAM. @@ -2261,8 +2245,6 @@ XParseGeometry (string, x, y, width, height) /* Create and set up the Mac window for frame F. */ -extern OSErr install_window_handler (WindowPtr); - static void mac_window (f) struct frame *f; @@ -2277,8 +2259,10 @@ mac_window (f) #if TARGET_API_MAC_CARBON CreateNewWindow (kDocumentWindowClass, kWindowStandardDocumentAttributes - /* | kWindowToolbarButtonAttribute */, - &r, &FRAME_MAC_WINDOW (f)); +#ifdef MAC_OSX + | kWindowToolbarButtonAttribute +#endif + , &r, &FRAME_MAC_WINDOW (f)); if (FRAME_MAC_WINDOW (f)) { SetWRefCon (FRAME_MAC_WINDOW (f), (long) f->output_data.mac); @@ -2296,6 +2280,22 @@ mac_window (f) /* so that update events can find this mac_output struct */ f->output_data.mac->mFP = f; /* point back to emacs frame */ +#ifndef MAC_OSX + if (FRAME_MAC_WINDOW (f)) + { + ControlRef root_control; + + if (CreateRootControl (FRAME_MAC_WINDOW (f), &root_control) != noErr) + { + DisposeWindow (FRAME_MAC_WINDOW (f)); + FRAME_MAC_WINDOW (f) = NULL; + } + } +#endif + if (FRAME_MAC_WINDOW (f)) + XSetWindowBackground (FRAME_MAC_DISPLAY(f), FRAME_MAC_WINDOW (f), + FRAME_BACKGROUND_PIXEL (f)); + validate_x_resource_name (); /* x_set_name normally ignores requests to set the name if the @@ -2490,9 +2490,11 @@ unwind_create_frame (frame) x_free_frame_resources (f); +#if GLYPH_DEBUG /* Check that reference counts are indeed correct. */ xassert (dpyinfo->reference_count == dpyinfo_refcount); xassert (dpyinfo->image_cache->refcount == image_cache_refcount); +#endif return Qt; } @@ -2502,7 +2504,7 @@ unwind_create_frame (frame) DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 1, 1, 0, - doc: /* Make a new window, which is called a \"frame\" in Emacs terms. + doc: /* Make a new window, which is called a "frame" in Emacs terms. Returns an Emacs frame object. ALIST is an alist of frame parameters. If the parameters specify that the frame should not have a minibuffer, @@ -2511,7 +2513,7 @@ then `default-minibuffer-frame' must be a frame whose minibuffer can be shared by the new frame. This function is an internal primitive--use `make-frame' instead. */) - (parms) + (parms) Lisp_Object parms; { struct frame *f; @@ -2526,11 +2528,11 @@ This function is an internal primitive--use `make-frame' instead. */) struct mac_display_info *dpyinfo = NULL; Lisp_Object parent; struct kboard *kb; - char x_frame_name[10]; - static int x_frame_count = 2; /* begins at 2 because terminal frame is F1 */ check_mac (); + parms = Fcopy_alist (parms); + /* Use this general default value to start with until we know if this frame has a specified name. */ Vx_resource_name = Vinvocation_name; @@ -2567,7 +2569,7 @@ This function is an internal primitive--use `make-frame' instead. */) frame = Qnil; GCPRO4 (parms, parent, name, frame); tem = mac_get_arg (parms, Qminibuffer, "minibuffer", "Minibuffer", - RES_TYPE_SYMBOL); + RES_TYPE_SYMBOL); if (EQ (tem, Qnone) || NILP (tem)) f = make_frame_without_minibuffer (Qnil, kb, display); else if (EQ (tem, Qonly)) @@ -2580,18 +2582,6 @@ This function is an internal primitive--use `make-frame' instead. */) else f = make_frame (1); - if (EQ (name, Qunbound) || NILP (name)) - { - sprintf (x_frame_name, "F%d", x_frame_count++); - f->name = build_string (x_frame_name); - f->explicit_name = 0; - } - else - { - f->name = name; - f->explicit_name = 1; - } - XSETFRAME (frame, f); /* Note that X Windows does support scroll bars. */ @@ -2601,14 +2591,20 @@ This function is an internal primitive--use `make-frame' instead. */) f->output_data.mac = (struct mac_output *) xmalloc (sizeof (struct mac_output)); bzero (f->output_data.mac, sizeof (struct mac_output)); FRAME_FONTSET (f) = -1; - record_unwind_protect (unwind_create_frame, frame); f->icon_name = mac_get_arg (parms, Qicon_name, "iconName", "Title", RES_TYPE_STRING); if (! STRINGP (f->icon_name)) f->icon_name = Qnil; -/* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */ +/* FRAME_MAC_DISPLAY_INFO (f) = dpyinfo; */ + + /* With FRAME_MAC_DISPLAY_INFO set up, this unwind-protect is safe. */ + record_unwind_protect (unwind_create_frame, frame); +#if GLYPH_DEBUG + image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount; + dpyinfo_refcount = dpyinfo->reference_count; +#endif /* GLYPH_DEBUG */ #ifdef MULTI_KBOARD FRAME_KBOARD (f) = kb; #endif @@ -2660,9 +2656,15 @@ This function is an internal primitive--use `make-frame' instead. */) } /* Try out a font which we hope has bold and italic variations. */ +#if USE_ATSUI + if (! STRINGP (font)) + font = x_new_font (f, "-*-monaco-medium-r-normal--12-*-*-*-*-*-iso10646-1"); +#endif if (! STRINGP (font)) font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1"); /* If those didn't work, look for something which will at least work. */ + if (! STRINGP (font)) + font = x_new_fontset (f, "fontset-standard"); if (! STRINGP (font)) font = x_new_font (f, "-*-monaco-*-12-*-mac-roman"); if (! STRINGP (font)) @@ -2671,8 +2673,7 @@ This function is an internal primitive--use `make-frame' instead. */) error ("Cannot find any usable font"); UNBLOCK_INPUT; - x_default_parameter (f, parms, Qfont, font, - "font", "Font", RES_TYPE_STRING); + x_set_frame_parameters (f, Fcons (Fcons (Qfont, font), Qnil)); } x_default_parameter (f, parms, Qborder_width, make_number (0), @@ -2728,9 +2729,10 @@ This function is an internal primitive--use `make-frame' instead. */) x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1), "menuBar", "MenuBar", RES_TYPE_NUMBER); x_default_parameter (f, parms, Qtool_bar_lines, make_number (1), - "toolBar", "ToolBar", RES_TYPE_NUMBER); + "toolBar", "ToolBar", RES_TYPE_NUMBER); x_default_parameter (f, parms, Qbuffer_predicate, Qnil, - "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL); + "bufferPredicate", "BufferPredicate", + RES_TYPE_SYMBOL); x_default_parameter (f, parms, Qtitle, Qnil, "title", "Title", RES_TYPE_STRING); x_default_parameter (f, parms, Qfullscreen, Qnil, @@ -2738,22 +2740,6 @@ This function is an internal primitive--use `make-frame' instead. */) f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window; -#if TARGET_API_MAC_CARBON - f->output_data.mac->text_cursor = kThemeIBeamCursor; - f->output_data.mac->nontext_cursor = kThemeArrowCursor; - f->output_data.mac->modeline_cursor = kThemeArrowCursor; - f->output_data.mac->hand_cursor = kThemePointingHandCursor; - f->output_data.mac->hourglass_cursor = kThemeWatchCursor; - f->output_data.mac->horizontal_drag_cursor = kThemeResizeLeftRightCursor; -#else - f->output_data.mac->text_cursor = GetCursor (iBeamCursor); - f->output_data.mac->nontext_cursor = &arrow_cursor; - f->output_data.mac->modeline_cursor = &arrow_cursor; - f->output_data.mac->hand_cursor = &arrow_cursor; - f->output_data.mac->hourglass_cursor = GetCursor (watchCursor); - f->output_data.mac->horizontal_drag_cursor = &arrow_cursor; -#endif - /* Compute the size of the window. */ window_prompting = x_figure_window_size (f, parms, 1); @@ -2812,17 +2798,28 @@ This function is an internal primitive--use `make-frame' instead. */) if (EQ (visibility, Qunbound)) visibility = Qt; -#if 0 /* MAC_TODO: really no iconify on Mac */ if (EQ (visibility, Qicon)) x_iconify_frame (f); - else -#endif - if (! NILP (visibility)) + else if (! NILP (visibility)) x_make_frame_visible (f); else /* Must have been Qnil. */ ; } + + /* Initialize `default-minibuffer-frame' in case this is the first + frame on this display device. */ + if (FRAME_HAS_MINIBUF_P (f) + && (!FRAMEP (kb->Vdefault_minibuffer_frame) + || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))) + kb->Vdefault_minibuffer_frame = frame; + + /* All remaining specified parameters, which have not been "used" + by x_get_arg and friends, now go in the misc. alist of the frame. */ + for (tem = parms; !NILP (tem); tem = XCDR (tem)) + if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem)))) + f->param_alist = Fcons (XCAR (tem), f->param_alist); + UNGCPRO; /* Make sure windows on this frame appear in calls to next-window @@ -2832,9 +2829,11 @@ This function is an internal primitive--use `make-frame' instead. */) return unbind_to (count, frame); } + /* FRAME is used only to get a handle on the X display. We don't pass the display info directly because we're called from frame.c, which doesn't know about that structure. */ + Lisp_Object x_get_focus_frame (frame) struct frame *frame; @@ -2847,10 +2846,39 @@ x_get_focus_frame (frame) XSETFRAME (xfocus, dpyinfo->x_focus_frame); return xfocus; } + + +DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0, + doc: /* Set the input focus to FRAME. +FRAME nil means use the selected frame. */) + (frame) + Lisp_Object frame; +{ + struct frame *f = check_x_frame (frame); + + BLOCK_INPUT; +#ifdef MAC_OSX + ActivateWindow (ActiveNonFloatingWindow (), false); + ActivateWindow (FRAME_MAC_WINDOW (f), true); +#else +#if !TARGET_API_MAC_CARBON + /* SelectWindow (Non-Carbon) does not issue deactivate events if the + possibly inactive window that is to be selected is already the + frontmost one. */ + SendBehind (FRAME_MAC_WINDOW (f), NULL); +#endif + /* This brings the window to the front. */ + SelectWindow (FRAME_MAC_WINDOW (f)); +#endif + UNBLOCK_INPUT; + + return Qnil; +} + DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0, doc: /* Internal function called by `color-defined-p', which see. */) - (color, frame) + (color, frame) Lisp_Object color, frame; { XColor foo; @@ -2866,7 +2894,7 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0, DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0, doc: /* Internal function called by `color-values', which see. */) - (color, frame) + (color, frame) Lisp_Object color, frame; { XColor foo; @@ -2875,21 +2903,16 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0, CHECK_STRING (color); if (mac_defined_color (f, SDATA (color), &foo, 0)) - { - Lisp_Object rgb[3]; - - rgb[0] = make_number (foo.red); - rgb[1] = make_number (foo.green); - rgb[2] = make_number (foo.blue); - return Flist (3, rgb); - } + return list3 (make_number (foo.red), + make_number (foo.green), + make_number (foo.blue)); else return Qnil; } DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0, doc: /* Internal function called by `display-color-p', which see. */) - (display) + (display) Lisp_Object display; { struct mac_display_info *dpyinfo = check_x_display_info (display); @@ -2902,12 +2925,12 @@ DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0, DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p, 0, 1, 0, - doc: /* Return t if the X display supports shades of gray. + doc: /* Return t if DISPLAY supports shades of gray. Note that color displays do support shades of gray. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) + (display) Lisp_Object display; { struct mac_display_info *dpyinfo = check_x_display_info (display); @@ -2920,11 +2943,11 @@ If omitted or nil, that stands for the selected frame's display. */) DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width, 0, 1, 0, - doc: /* Returns the width in pixels of the X display DISPLAY. + doc: /* Returns the width in pixels of DISPLAY. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) + (display) Lisp_Object display; { struct mac_display_info *dpyinfo = check_x_display_info (display); @@ -2934,11 +2957,11 @@ If omitted or nil, that stands for the selected frame's display. */) DEFUN ("x-display-pixel-height", Fx_display_pixel_height, Sx_display_pixel_height, 0, 1, 0, - doc: /* Returns the height in pixels of the X display DISPLAY. + doc: /* Returns the height in pixels of DISPLAY. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) + (display) Lisp_Object display; { struct mac_display_info *dpyinfo = check_x_display_info (display); @@ -2948,11 +2971,11 @@ If omitted or nil, that stands for the selected frame's display. */) DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes, 0, 1, 0, - doc: /* Returns the number of bitplanes of the display DISPLAY. + doc: /* Returns the number of bitplanes of DISPLAY. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) + (display) Lisp_Object display; { struct mac_display_info *dpyinfo = check_x_display_info (display); @@ -2962,11 +2985,11 @@ If omitted or nil, that stands for the selected frame's display. */) DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells, 0, 1, 0, - doc: /* Returns the number of color cells of the display DISPLAY. + doc: /* Returns the number of color cells of DISPLAY. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) + (display) Lisp_Object display; { struct mac_display_info *dpyinfo = check_x_display_info (display); @@ -2978,11 +3001,11 @@ If omitted or nil, that stands for the selected frame's display. */) DEFUN ("x-server-max-request-size", Fx_server_max_request_size, Sx_server_max_request_size, 0, 1, 0, - doc: /* Returns the maximum request size of the server of display DISPLAY. + doc: /* Returns the maximum request size of the server of DISPLAY. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) + (display) Lisp_Object display; { struct mac_display_info *dpyinfo = check_x_display_info (display); @@ -2991,18 +3014,18 @@ If omitted or nil, that stands for the selected frame's display. */) } DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0, - doc: /* Returns the vendor ID string of the Mac OS system (Apple). + doc: /* Returns the "vendor ID" string of the Mac OS system (Apple). The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) + (display) Lisp_Object display; { return build_string ("Apple Computers"); } DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0, - doc: /* Returns the version numbers of the server of display DISPLAY. + doc: /* Returns the version numbers of the Mac OS system. The value is a list of three integers: the major and minor version numbers, and the vendor-specific release number. See also the function `x-server-vendor'. @@ -3010,74 +3033,112 @@ number. See also the function `x-server-vendor'. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) + (display) Lisp_Object display; { - int mac_major_version; - SInt32 response; + UInt32 response, major, minor, bugfix; + OSErr err; - if (Gestalt (gestaltSystemVersion, &response) != noErr) - error ("Cannot get Mac OS version"); + BLOCK_INPUT; + err = Gestalt (gestaltSystemVersion, &response); + if (err == noErr) + { + if (response >= 0x00001040) + { + err = Gestalt (gestaltSystemVersionMajor, &major); + if (err == noErr) + err = Gestalt (gestaltSystemVersionMinor, &minor); + if (err == noErr) + err = Gestalt (gestaltSystemVersionBugFix, &bugfix); + } + else + { + bugfix = response & 0xf; + response >>= 4; + minor = response & 0xf; + response >>= 4; + /* convert BCD to int */ + major = response - (response >> 4) * 6; + } + } + UNBLOCK_INPUT; - mac_major_version = (response >> 8) & 0xff; - /* convert BCD to int */ - mac_major_version -= (mac_major_version >> 4) * 6; + if (err != noErr) + error ("Cannot get Mac OS version"); - return Fcons (make_number (mac_major_version), - Fcons (make_number ((response >> 4) & 0xf), - Fcons (make_number (response & 0xf), + return Fcons (make_number (major), + Fcons (make_number (minor), + Fcons (make_number (bugfix), Qnil))); } DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0, - doc: /* Return the number of screens on the server of display DISPLAY. + doc: /* Return the number of screens on the server of DISPLAY. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) + (display) Lisp_Object display; { return make_number (1); } DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0, - doc: /* Return the height in millimeters of the X display DISPLAY. + doc: /* Return the height in millimeters of DISPLAY. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) + (display) Lisp_Object display; { - /* MAC_TODO: this is an approximation, and only of the main display */ - struct mac_display_info *dpyinfo = check_x_display_info (display); + /* Only of the main display. */ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 + CGSize size; + BLOCK_INPUT; + size = CGDisplayScreenSize (kCGDirectMainDisplay); + UNBLOCK_INPUT; + + return make_number ((int) (size.height + .5f)); +#else + /* This is an approximation. */ return make_number ((int) (dpyinfo->height * 25.4 / dpyinfo->resy)); +#endif } DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0, - doc: /* Return the width in millimeters of the X display DISPLAY. + doc: /* Return the width in millimeters of DISPLAY. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) + (display) Lisp_Object display; { - /* MAC_TODO: this is an approximation, and only of the main display */ - struct mac_display_info *dpyinfo = check_x_display_info (display); + /* Only of the main display. */ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 + CGSize size; + BLOCK_INPUT; + size = CGDisplayScreenSize (kCGDirectMainDisplay); + UNBLOCK_INPUT; + + return make_number ((int) (size.width + .5f)); +#else + /* This is an approximation. */ return make_number ((int) (dpyinfo->width * 25.4 / dpyinfo->resx)); +#endif } DEFUN ("x-display-backing-store", Fx_display_backing_store, Sx_display_backing_store, 0, 1, 0, - doc: /* Returns an indication of whether display DISPLAY does backing store. + doc: /* Returns an indication of whether DISPLAY does backing store. The value may be `always', `when-mapped', or `not-useful'. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) + (display) Lisp_Object display; { return intern ("not-useful"); @@ -3085,14 +3146,14 @@ If omitted or nil, that stands for the selected frame's display. */) DEFUN ("x-display-visual-class", Fx_display_visual_class, Sx_display_visual_class, 0, 1, 0, - doc: /* Returns the visual class of the display DISPLAY. + doc: /* Returns the visual class of DISPLAY. The value is one of the symbols `static-gray', `gray-scale', `static-color', `pseudo-color', `true-color', or `direct-color'. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) + (display) Lisp_Object display; { struct mac_display_info *dpyinfo = check_x_display_info (display); @@ -3116,11 +3177,11 @@ If omitted or nil, that stands for the selected frame's display. */) DEFUN ("x-display-save-under", Fx_display_save_under, Sx_display_save_under, 0, 1, 0, - doc: /* Returns t if the display DISPLAY supports the save-under feature. + doc: /* Returns t if DISPLAY supports the save-under feature. The optional argument DISPLAY specifies which display to ask about. DISPLAY should be either a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) + (display) Lisp_Object display; { return Qnil; @@ -3210,7 +3271,7 @@ DISPLAY is the name of the display to connect to. Optional second arg XRM-STRING is a string of resources in xrdb format. If the optional third arg MUST-SUCCEED is non-nil, terminate Emacs if we can't open the connection. */) - (display, xrm_string, must_succeed) + (display, xrm_string, must_succeed) Lisp_Object display, xrm_string, must_succeed; { unsigned char *xrm_option; @@ -3255,8 +3316,8 @@ DEFUN ("x-close-connection", Fx_close_connection, doc: /* Close the connection to DISPLAY's server. For DISPLAY, specify either a frame or a display name (a string). If DISPLAY is nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; + (display) + Lisp_Object display; { struct mac_display_info *dpyinfo = check_x_display_info (display); int i; @@ -3282,7 +3343,7 @@ If DISPLAY is nil, that stands for the selected frame's display. */) DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0, doc: /* Return the list of display names that Emacs has connections to. */) - () + () { Lisp_Object tail, result; @@ -3294,18 +3355,21 @@ DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0, } DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0, - doc: /* If ON is non-nil, report errors as soon as the erring request is made. -If ON is nil, allow buffering of requests. -This is a noop on Mac OS systems. -The optional second argument DISPLAY specifies which display to act on. -DISPLAY should be either a frame or a display name (a string). -If DISPLAY is omitted or nil, that stands for the selected frame's display. */) - (on, display) + doc: /* This is a noop on Mac OS systems. */) + (on, display) Lisp_Object display, on; { return Qnil; } +/* x_sync is a no-op on Mac. */ + +void +x_sync (f) + FRAME_PTR f; +{ +} + /*********************************************************************** Window properties @@ -3359,7 +3423,7 @@ DEFUN ("x-delete-window-property", Fx_delete_window_property, Sx_delete_window_property, 1, 2, 0, doc: /* Remove window property PROP from X window of FRAME. FRAME nil or omitted means use the selected frame. Value is PROP. */) - (prop, frame) + (prop, frame) Lisp_Object prop, frame; { #if 0 /* MAC_TODO : port window properties to Mac */ @@ -3387,7 +3451,7 @@ DEFUN ("x-window-property", Fx_window_property, Sx_window_property, If FRAME is nil or omitted, use the selected frame. Value is nil if FRAME hasn't a property with name PROP or if PROP has no string value. */) - (prop, frame) + (prop, frame) Lisp_Object prop, frame; { #if 0 /* MAC_TODO : port window properties to Mac */ @@ -3438,7 +3502,7 @@ value. */) /*********************************************************************** - Hourglass cursor + Busy cursor ***********************************************************************/ /* If non-null, an asynchronous timer that, when it expires, displays @@ -3464,16 +3528,28 @@ static Lisp_Object Vhourglass_delay; static void show_hourglass P_ ((struct atimer *)); static void hide_hourglass P_ ((void)); +/* Return non-zero if houglass timer has been started or hourglass is shown. */ + +int +hourglass_started () +{ + return hourglass_shown_p || hourglass_atimer != NULL; +} + /* Cancel a currently active hourglass timer, and start a new one. */ void start_hourglass () { -#if 0 /* MAC_TODO: cursor shape changes. */ +#ifdef MAC_OSX EMACS_TIME delay; int secs, usecs = 0; + /* Don't bother for ttys. */ + if (NILP (Vwindow_system)) + return; + cancel_hourglass (); if (INTEGERP (Vhourglass_delay) @@ -3493,16 +3569,17 @@ start_hourglass () EMACS_SET_SECS_USECS (delay, secs, usecs); hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay, show_hourglass, NULL); -#endif /* MAC_TODO */ +#endif /* MAC_OSX */ } -/* Cancel the hourglass cursor timer if active, hide an hourglass - cursor if shown. */ +/* Cancel the hourglass cursor timer if active, hide a busy cursor if + shown. */ void cancel_hourglass () { +#ifdef MAC_OSX if (hourglass_atimer) { cancel_atimer (hourglass_atimer); @@ -3511,22 +3588,22 @@ cancel_hourglass () if (hourglass_shown_p) hide_hourglass (); +#endif /* MAC_OSX */ } /* Timer function of hourglass_atimer. TIMER is equal to hourglass_atimer. - Display an hourglass cursor on all frames by mapping the frames' - hourglass_window. Set the hourglass_p flag in the frames' - output_data.x structure to indicate that an hourglass cursor is - shown on the frames. */ + On Mac, busy status is shown by the progress indicator (chasing + arrows) at the upper-right corner of each frame instead of the + hourglass pointer. */ static void show_hourglass (timer) struct atimer *timer; { -#if 0 /* MAC_TODO: cursor shape changes. */ +#if TARGET_API_MAC_CARBON /* The timer implementation will cancel this timer automatically after this function has run. Set hourglass_atimer to null so that we know the timer doesn't have to be canceled. */ @@ -3539,46 +3616,47 @@ show_hourglass (timer) BLOCK_INPUT; FOR_EACH_FRAME (rest, frame) - if (FRAME_W32_P (XFRAME (frame))) - { - struct frame *f = XFRAME (frame); - - f->output_data.w32->hourglass_p = 1; + { + struct frame *f = XFRAME (frame); - if (!f->output_data.w32->hourglass_window) - { - unsigned long mask = CWCursor; - XSetWindowAttributes attrs; - - attrs.cursor = f->output_data.w32->hourglass_cursor; - - f->output_data.w32->hourglass_window - = XCreateWindow (FRAME_X_DISPLAY (f), - FRAME_OUTER_WINDOW (f), - 0, 0, 32000, 32000, 0, 0, - InputOnly, - CopyFromParent, - mask, &attrs); - } + if (FRAME_LIVE_P (f) && FRAME_MAC_P (f) + && FRAME_MAC_WINDOW (f) != tip_window) + { +#if USE_CG_DRAWING + mac_prepare_for_quickdraw (f); +#endif + if (!f->output_data.mac->hourglass_control) + { + Window w = FRAME_MAC_WINDOW (f); + Rect r; + ControlRef c; + + GetWindowPortBounds (w, &r); + r.left = r.right - HOURGLASS_WIDTH; + r.bottom = r.top + HOURGLASS_HEIGHT; + if (CreateChasingArrowsControl (w, &r, &c) == noErr) + f->output_data.mac->hourglass_control = c; + } - XMapRaised (FRAME_X_DISPLAY (f), - f->output_data.w32->hourglass_window); - XFlush (FRAME_X_DISPLAY (f)); - } + if (f->output_data.mac->hourglass_control) + ShowControl (f->output_data.mac->hourglass_control); + } + } hourglass_shown_p = 1; UNBLOCK_INPUT; } -#endif /* MAC_TODO */ +#endif /* TARGET_API_MAC_CARBON */ } -/* Hide the hourglass cursor on all frames, if it is currently shown. */ +/* Hide the progress indicators on all frames, if it is currently + shown. */ static void hide_hourglass () { -#if 0 /* MAC_TODO: cursor shape changes. */ +#if TARGET_API_MAC_CARBON if (hourglass_shown_p) { Lisp_Object rest, frame; @@ -3588,23 +3666,21 @@ hide_hourglass () { struct frame *f = XFRAME (frame); - if (FRAME_W32_P (f) + if (FRAME_MAC_P (f) /* Watch out for newly created frames. */ - && f->output_data.x->hourglass_window) + && f->output_data.mac->hourglass_control) { - XUnmapWindow (FRAME_X_DISPLAY (f), - f->output_data.x->hourglass_window); - /* Sync here because XTread_socket looks at the - hourglass_p flag that is reset to zero below. */ - XSync (FRAME_X_DISPLAY (f), False); - f->output_data.x->hourglass_p = 0; +#if USE_CG_DRAWING + mac_prepare_for_quickdraw (f); +#endif + HideControl (f->output_data.mac->hourglass_control); } } hourglass_shown_p = 0; UNBLOCK_INPUT; } -#endif /* MAC_TODO */ +#endif /* TARGET_API_MAC_CARBON */ } @@ -3683,9 +3759,7 @@ x_create_tip_frame (dpyinfo, parms, text) check_mac (); - /* Use this general default value to start with until we know if - this frame has a specified name. */ - Vx_resource_name = Vinvocation_name; + parms = Fcopy_alist (parms); #ifdef MULTI_KBOARD kb = dpyinfo->kboard; @@ -3699,7 +3773,6 @@ x_create_tip_frame (dpyinfo, parms, text) && !EQ (name, Qunbound) && !NILP (name)) error ("Invalid frame name--not a string or nil"); - Vx_resource_name = name; frame = Qnil; GCPRO3 (parms, name, frame); @@ -3731,8 +3804,8 @@ x_create_tip_frame (dpyinfo, parms, text) FRAME_FONTSET (f) = -1; f->icon_name = Qnil; - -#if 0 /* GLYPH_DEBUG TODO: image support. */ +/* FRAME_X_DISPLAY_INFO (f) = dpyinfo; */ +#if GLYPH_DEBUG image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount; dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ @@ -3776,9 +3849,15 @@ x_create_tip_frame (dpyinfo, parms, text) } /* Try out a font which we hope has bold and italic variations. */ +#if USE_ATSUI + if (! STRINGP (font)) + font = x_new_font (f, "-*-monaco-medium-r-normal--12-*-*-*-*-*-iso10646-1"); +#endif if (! STRINGP (font)) font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1"); /* If those didn't work, look for something which will at least work. */ + if (! STRINGP (font)) + font = x_new_fontset (f, "fontset-standard"); if (! STRINGP (font)) font = x_new_font (f, "-*-monaco-*-12-*-mac-roman"); if (! STRINGP (font)) @@ -3843,7 +3922,7 @@ x_create_tip_frame (dpyinfo, parms, text) SetRect (&r, 0, 0, 1, 1); #if TARGET_API_MAC_CARBON if (CreateNewWindow (kHelpWindowClass, -#ifdef MAC_OS_X_VERSION_10_2 +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 kWindowIgnoreClicksAttribute | #endif kWindowNoUpdatesAttribute | @@ -3855,6 +3934,8 @@ x_create_tip_frame (dpyinfo, parms, text) #endif { FRAME_MAC_WINDOW (f) = tip_window; + XSetWindowBackground (FRAME_MAC_DISPLAY(f), tip_window, + FRAME_BACKGROUND_PIXEL (f)); SetWRefCon (tip_window, (long) f->output_data.mac); /* so that update events can find this mac_output struct */ f->output_data.mac->mFP = f; @@ -3965,16 +4046,22 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y) if (INTEGERP (top)) *root_y = XINT (top); - else if (*root_y + XINT (dy) - height < 0) - *root_y -= XINT (dy); + else if (*root_y + XINT (dy) <= 0) + *root_y = 0; /* Can happen for negative dy */ + else if (*root_y + XINT (dy) + height <= FRAME_MAC_DISPLAY_INFO (f)->height) + /* It fits below the pointer */ + *root_y += XINT (dy); + else if (height + XINT (dy) <= *root_y) + /* It fits above the pointer. */ + *root_y -= height + XINT (dy); else - { - *root_y -= height; - *root_y += XINT (dy); - } + /* Put it on the top. */ + *root_y = 0; if (INTEGERP (left)) *root_x = XINT (left); + else if (*root_x + XINT (dx) <= 0) + *root_x = 0; /* Can happen for negative dx */ else if (*root_x + XINT (dx) + width <= FRAME_MAC_DISPLAY_INFO (f)->width) /* It fits to the right of the pointer. */ *root_x += XINT (dx); @@ -3989,7 +4076,7 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y) DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, doc: /* Show STRING in a "tooltip" window on frame FRAME. -A tooltip window is a small X window displaying a string. +A tooltip window is a small window displaying a string. FRAME nil or omitted means use the selected frame. @@ -3999,7 +4086,7 @@ change the tooltip's appearance. Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil means use the default timeout of 5 seconds. -If the list of frame parameters PARAMS contains a `left' parameters, +If the list of frame parameters PARMS contains a `left' parameter, the tooltip is displayed at that x-position. Otherwise it is displayed at the mouse position, with offset DX added (default is 5 if DX isn't specified). Likewise for the y-position; if a `top' frame @@ -4130,7 +4217,7 @@ Text larger than the specified size is clipped. */) clear_glyph_matrix (w->desired_matrix); clear_glyph_matrix (w->current_matrix); SET_TEXT_POS (pos, BEGV, BEGV_BYTE); - try_window (FRAME_ROOT_WINDOW (f), pos); + try_window (FRAME_ROOT_WINDOW (f), pos, 0); /* Compute width and height of the tooltip. */ width = height = 0; @@ -4177,6 +4264,9 @@ Text larger than the specified size is clipped. */) BringToFront (FRAME_MAC_WINDOW (f)); UNBLOCK_INPUT; + FRAME_PIXEL_WIDTH (f) = width; + FRAME_PIXEL_HEIGHT (f) = height; + /* Draw into the window. */ w->must_be_updated_p = 1; update_single_window (w, 1); @@ -4237,6 +4327,9 @@ Value is t if tooltip was open, nil otherwise. */) File selection dialog ***********************************************************************/ +static pascal void mac_nav_event_callback P_ ((NavEventCallbackMessage, + NavCBRecPtr, void *)); + /** There is a relatively standard way to do this using applescript to run a (choose file) method. However, this doesn't do "the right thing" @@ -4254,15 +4347,16 @@ Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file selection box, if specified. Ensure that file exists if MUSTMATCH is non-nil. If ONLY-DIR-P is non-nil, the user can only select directories. */) - (prompt, dir, default_filename, mustmatch, only_dir_p) + (prompt, dir, default_filename, mustmatch, only_dir_p) Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p; { - struct frame *f = SELECTED_FRAME (); Lisp_Object file = Qnil; int count = SPECPDL_INDEX (); struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; - char filename[1001]; - int default_filter_index = 1; /* 1: All Files, 2: Directories only */ + char filename[MAXPATHLEN]; + static NavEventUPP mac_nav_event_callbackUPP = NULL; + + check_mac (); GCPRO6 (prompt, dir, default_filename, mustmatch, file, only_dir_p); CHECK_STRING (prompt); @@ -4279,7 +4373,7 @@ If ONLY-DIR-P is non-nil, the user can only select directories. */) NavTypeListHandle fileTypes = NULL; NavUserAction userAction; CFStringRef message=NULL, saveName = NULL; - + BLOCK_INPUT; /* No need for a callback function because we are modal */ NavGetDefaultDialogCreationOptions(&options); @@ -4288,61 +4382,69 @@ If ONLY-DIR-P is non-nil, the user can only select directories. */) options.optionFlags = kNavDefaultNavDlogOptions; options.optionFlags |= kNavAllFilesInPopup; /* All files allowed */ options.optionFlags |= kNavSelectAllReadableItem; + options.optionFlags &= ~kNavAllowMultipleFiles; if (!NILP(prompt)) { - message = cfstring_create_with_utf8_cstring (SDATA (prompt)); + message = cfstring_create_with_string (prompt); options.message = message; } /* Don't set the application, let it use default. options.clientName = CFSTR ("Emacs"); */ + if (mac_nav_event_callbackUPP == NULL) + mac_nav_event_callbackUPP = NewNavEventUPP (mac_nav_event_callback); + if (!NILP (only_dir_p)) - status = NavCreateChooseFolderDialog(&options, NULL, NULL, NULL, - &dialogRef); - else if (NILP (mustmatch)) - { + status = NavCreateChooseFolderDialog(&options, mac_nav_event_callbackUPP, + NULL, NULL, &dialogRef); + else if (NILP (mustmatch)) + { /* This is a save dialog */ options.optionFlags |= kNavDontConfirmReplacement; options.actionButtonLabel = CFSTR ("Ok"); options.windowTitle = CFSTR ("Enter name"); - if (!NILP(default_filename)) + if (STRINGP (default_filename)) { - saveName = - cfstring_create_with_utf8_cstring (SDATA (default_filename)); + Lisp_Object utf8 = ENCODE_UTF_8 (default_filename); + char *begPtr = SDATA(utf8); + char *filePtr = begPtr + SBYTES(utf8); + while (filePtr != begPtr && !IS_DIRECTORY_SEP(filePtr[-1])) + filePtr--; + saveName = cfstring_create_with_utf8_cstring (filePtr); options.saveFileName = saveName; options.optionFlags |= kNavSelectDefaultLocation; } - status = NavCreatePutFileDialog(&options, + status = NavCreatePutFileDialog(&options, 'TEXT', kNavGenericSignature, - NULL, NULL, &dialogRef); + mac_nav_event_callbackUPP, NULL, + &dialogRef); } else { /* This is an open dialog*/ status = NavCreateChooseFileDialog(&options, fileTypes, - NULL, NULL, NULL, NULL, - &dialogRef); + mac_nav_event_callbackUPP, NULL, + NULL, NULL, &dialogRef); } - + /* Set the default location and continue*/ - if (status == noErr) { - if (!NILP(dir)) { - FSRef defLoc; + if (status == noErr) + { + Lisp_Object encoded_dir = ENCODE_FILE (dir); AEDesc defLocAed; - status = FSPathMakeRef(SDATA(dir), &defLoc, NULL); - if (status == noErr) + + status = AECreateDesc (TYPE_FILE_NAME, SDATA (encoded_dir), + SBYTES (encoded_dir), &defLocAed); + if (status == noErr) { - AECreateDesc(typeFSRef, &defLoc, sizeof(FSRef), &defLocAed); NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed); + AEDisposeDesc(&defLocAed); } - AEDisposeDesc(&defLocAed); + status = NavDialogRun(dialogRef); } - status = NavDialogRun(dialogRef); - } - if (saveName) CFRelease(saveName); if (message) CFRelease(message); @@ -4358,55 +4460,125 @@ If ONLY-DIR-P is non-nil, the user can only select directories. */) case kNavUserActionSaveAs: { NavReplyRecord reply; - AEDesc aed; - FSRef fsRef; + Size len; + status = NavDialogGetReply(dialogRef, &reply); - AECoerceDesc(&reply.selection, typeFSRef, &aed); - AEGetDescData(&aed, (void *) &fsRef, sizeof (FSRef)); - FSRefMakePath(&fsRef, (UInt8 *) filename, 1000); - AEDisposeDesc(&aed); - if (reply.saveFileName) + if (status != noErr) + break; + status = AEGetNthPtr (&reply.selection, 1, TYPE_FILE_NAME, + NULL, NULL, filename, + sizeof (filename) - 1, &len); + if (status == noErr) { - /* If it was a saved file, we need to add the file name */ - int len = strlen(filename); - if (len && filename[len-1] != '/') - filename[len++] = '/'; - CFStringGetCString(reply.saveFileName, filename+len, - 1000-len, kCFStringEncodingUTF8); + len = min (len, sizeof (filename) - 1); + filename[len] = '\0'; + if (reply.saveFileName) + { + /* If it was a saved file, we need to add the file name */ + if (len && len < sizeof (filename) - 1 + && filename[len-1] != '/') + filename[len++] = '/'; + CFStringGetCString(reply.saveFileName, filename+len, + sizeof (filename) - len, +#if MAC_OSX + kCFStringEncodingUTF8 +#else + CFStringGetSystemEncoding () +#endif + ); + } + file = DECODE_FILE (make_unibyte_string (filename, + strlen (filename))); } - file = DECODE_FILE(build_string (filename)); NavDisposeReply(&reply); } break; } NavDialogDispose(dialogRef); + UNBLOCK_INPUT; } else { + UNBLOCK_INPUT; /* Fall back on minibuffer if there was a problem */ file = Fcompleting_read (prompt, intern ("read-file-name-internal"), dir, mustmatch, dir, Qfile_name_history, default_filename, Qnil); } - UNBLOCK_INPUT; } UNGCPRO; - + /* Make "Cancel" equivalent to C-g. */ if (NILP (file)) Fsignal (Qquit, Qnil); - + return unbind_to (count, file); } +/* Need to register some event callback function for enabling drag and + drop in Navigation Service dialogs. */ +static pascal void +mac_nav_event_callback (selector, parms, data) + NavEventCallbackMessage selector; + NavCBRecPtr parms; + void *data ; +{ +} +#endif + +/*********************************************************************** + Fonts + ***********************************************************************/ + +DEFUN ("mac-clear-font-name-table", Fmac_clear_font_name_table, + Smac_clear_font_name_table, 0, 0, 0, + doc: /* Clear the font name table. */) + () +{ + check_mac (); + mac_clear_font_name_table (); + return Qnil; +} + +#if USE_MAC_FONT_PANEL +DEFUN ("mac-set-font-panel-visibility", Fmac_set_font_panel_visibility, + Smac_set_font_panel_visibility, 1, 1, 0, + doc: /* Make the font panel visible if and only if VISIBLE is non-nil. +This is for internal use only. Use `mac-font-panel-mode' instead. */) + (visible) + Lisp_Object visible; +{ + OSStatus err = noErr; + + check_mac (); + + BLOCK_INPUT; + if (NILP (visible) != !mac_font_panel_visible_p ()) + { + err = mac_show_hide_font_panel (); + if (err == noErr && !NILP (visible)) + { + Lisp_Object focus_frame = x_get_focus_frame (SELECTED_FRAME ()); + struct frame *f = (NILP (focus_frame) ? SELECTED_FRAME () + : XFRAME (focus_frame)); + + mac_set_font_info_for_selection (f, DEFAULT_FACE_ID, 0); + } + } + UNBLOCK_INPUT; + + if (err != noErr) + error ("Cannot change visibility of the font panel"); + return Qnil; +} #endif /*********************************************************************** Initialization ***********************************************************************/ -/* Keep this list in the same order as frame_parms in frame.c. +/* Keep this list in the same order as frame_parms in frame.c. Use 0 for unsupported frame parameters. */ frame_parm_handler mac_frame_parm_handlers[] = @@ -4418,7 +4590,7 @@ frame_parm_handler mac_frame_parm_handlers[] = x_set_border_width, x_set_cursor_color, x_set_cursor_type, - x_set_font, + mac_set_font, x_set_foreground_color, x_set_icon_name, 0, /* MAC_TODO: x_set_icon_type, */ @@ -4426,7 +4598,7 @@ frame_parm_handler mac_frame_parm_handlers[] = x_set_menu_bar_lines, x_set_mouse_color, x_explicitly_set_name, - x_set_scroll_bar_width, + mac_set_scroll_bar_width, x_set_title, x_set_unsplittable, x_set_vertical_scroll_bars, @@ -4464,29 +4636,12 @@ syms_of_macfns () staticpro (&Qundefined_color); Qcancel_timer = intern ("cancel-timer"); staticpro (&Qcancel_timer); - - Qhyper = intern ("hyper"); - staticpro (&Qhyper); - Qsuper = intern ("super"); - staticpro (&Qsuper); - Qmeta = intern ("meta"); - staticpro (&Qmeta); - Qalt = intern ("alt"); - staticpro (&Qalt); - Qctrl = intern ("ctrl"); - staticpro (&Qctrl); - Qcontrol = intern ("control"); - staticpro (&Qcontrol); - Qshift = intern ("shift"); - staticpro (&Qshift); /* This is the end of symbol initialization. */ /* Text property `display' should be nonsticky by default. */ Vtext_property_default_nonsticky = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky); - Qface_set_after_frame_default = intern ("face-set-after-frame-default"); - staticpro (&Qface_set_after_frame_default); Fput (Qundefined_color, Qerror_conditions, Fcons (Qundefined_color, Fcons (Qerror, Qnil))); @@ -4494,39 +4649,58 @@ syms_of_macfns () build_string ("Undefined color")); DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape, - doc: /* The shape of the pointer when over text. + doc: /* The shape of the pointer when over text. Changing the value does not affect existing frames unless you set the mouse color. */); Vx_pointer_shape = Qnil; +#if 0 /* This doesn't really do anything. */ + DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape, + doc: /* The shape of the pointer when not over text. +This variable takes effect when you create a new frame +or when you set the mouse color. */); +#endif Vx_nontext_pointer_shape = Qnil; - Vx_mode_pointer_shape = Qnil; - DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape, - doc: /* The shape of the pointer when Emacs is hourglass. + doc: /* The shape of the pointer when Emacs is busy. This variable takes effect when you create a new frame or when you set the mouse color. */); Vx_hourglass_pointer_shape = Qnil; DEFVAR_BOOL ("display-hourglass", &display_hourglass_p, - doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */); + doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */); display_hourglass_p = 1; DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay, - doc: /* *Seconds to wait before displaying an hourglass pointer. + doc: /* *Seconds to wait before displaying an hourglass pointer. Value must be an integer or float. */); Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY); +#if 0 /* This doesn't really do anything. */ + DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape, + doc: /* The shape of the pointer when over the mode line. +This variable takes effect when you create a new frame +or when you set the mouse color. */); +#endif + Vx_mode_pointer_shape = Qnil; + DEFVAR_LISP ("x-sensitive-text-pointer-shape", - &Vx_sensitive_text_pointer_shape, + &Vx_sensitive_text_pointer_shape, doc: /* The shape of the pointer when over mouse-sensitive text. This variable takes effect when you create a new frame or when you set the mouse color. */); Vx_sensitive_text_pointer_shape = Qnil; + DEFVAR_LISP ("x-window-horizontal-drag-cursor", + &Vx_window_horizontal_drag_shape, + doc: /* Pointer shape to use for indicating a window can be dragged horizontally. +This variable takes effect when you create a new frame +or when you set the mouse color. */); + Vx_window_horizontal_drag_shape = Qnil; + DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel, - doc: /* A string indicating the foreground color of the cursor box. */); + doc: /* A string indicating the foreground color of the cursor box. */); Vx_cursor_fore_pixel = Qnil; DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size, @@ -4535,7 +4709,7 @@ Text larger than this is clipped. */); Vx_max_tooltip_size = Fcons (make_number (80), make_number (40)); DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager, - doc: /* Non-nil if no window manager is in use. + doc: /* Non-nil if no window manager is in use. Emacs doesn't try to figure this out; this is always nil unless you set it to something else. */); /* We don't have any way to find this out, so set it to nil @@ -4544,7 +4718,7 @@ unless you set it to something else. */); DEFVAR_LISP ("x-pixel-size-width-font-regexp", &Vx_pixel_size_width_font_regexp, - doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. + doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. Since Emacs gets width of a font matching with this regexp from PIXEL_SIZE field of the name, font finding mechanism gets faster for @@ -4552,6 +4726,22 @@ such a font. This is especially effective for such large fonts as Chinese, Japanese, and Korean. */); Vx_pixel_size_width_font_regexp = Qnil; +#if TARGET_API_MAC_CARBON + DEFVAR_LISP ("mac-carbon-version-string", &Vmac_carbon_version_string, + doc: /* Version info for Carbon API. */); + { + OSErr err; + UInt32 response; + char carbon_version[16] = "Unknown"; + + err = Gestalt (gestaltCarbonVersion, &response); + if (err == noErr) + sprintf (carbon_version, "%u.%u.%u", + (response >> 8) & 0xf, (response >> 4) & 0xf, response & 0xf); + Vmac_carbon_version_string = build_string (carbon_version); + } +#endif /* TARGET_API_MAC_CARBON */ + /* X window properties. */ defsubr (&Sx_change_window_property); defsubr (&Sx_delete_window_property); @@ -4579,6 +4769,7 @@ Chinese, Japanese, and Korean. */); defsubr (&Sx_close_connection); defsubr (&Sx_display_list); defsubr (&Sx_synchronize); + defsubr (&Sx_focus_frame); /* Setting callback functions for fontset handler. */ get_font_info_func = x_get_font_info; @@ -4591,7 +4782,7 @@ Chinese, Japanese, and Korean. */); load_font_func = x_load_font; find_ccl_program_func = x_find_ccl_program; query_font_func = x_query_font; - set_frame_fontset_func = x_set_font; + set_frame_fontset_func = mac_set_font; check_window_system_func = check_mac; hourglass_atimer = NULL; @@ -4609,6 +4800,10 @@ Chinese, Japanese, and Korean. */); #if TARGET_API_MAC_CARBON defsubr (&Sx_file_dialog); +#endif + defsubr (&Smac_clear_font_name_table); +#if USE_MAC_FONT_PANEL + defsubr (&Smac_set_font_panel_visibility); #endif }