X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/901a6b035e69b9b8630dd4b756201a8f96cce348..0924e3f6e1b5749019ac7f69765af355623c9db8:/src/macfns.c diff --git a/src/macfns.c b/src/macfns.c index dc4aa584f8..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,65 +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. */ @@ -110,48 +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; +/* 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 */ @@ -209,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; } @@ -244,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)); @@ -291,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. */ @@ -331,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" }, @@ -1089,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; @@ -1112,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; @@ -1179,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; @@ -1215,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') @@ -1234,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; @@ -1256,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') @@ -1447,7 +1367,6 @@ x_set_mouse_color (f, arg, oldval) Lisp_Object arg, oldval; { struct x_output *x = f->output_data.x; - Display *dpy = FRAME_MAC_DISPLAY (f); Cursor cursor, nontext_cursor, mode_cursor, hand_cursor; Cursor hourglass_cursor, horizontal_drag_cursor; unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); @@ -1527,7 +1446,8 @@ x_set_mouse_color (f, arg, oldval) BLOCK_INPUT; - rif->define_frame_cursor (f, cursor); + if (FRAME_MAC_WINDOW (f) != 0) + rif->define_frame_cursor (f, cursor); f->output_data.mac->text_cursor = cursor; f->output_data.mac->nontext_cursor = nontext_cursor; @@ -1571,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)) @@ -1679,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; @@ -1724,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); } @@ -1824,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)) @@ -1834,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 @@ -1865,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 @@ -1889,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 @@ -1970,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 @@ -2013,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 */ @@ -2027,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); - while (*value) + 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; + + 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. @@ -2252,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); @@ -2495,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, @@ -2504,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; @@ -2519,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; @@ -2560,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)) @@ -2573,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. */ @@ -2594,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 @@ -2653,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)) @@ -2664,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), @@ -2721,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, @@ -2789,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 @@ -2809,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; @@ -2824,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; @@ -2843,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; @@ -2852,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); @@ -2879,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); @@ -2897,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); @@ -2911,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); @@ -2925,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); @@ -2939,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); @@ -2955,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); @@ -2968,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'. @@ -2987,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"); @@ -3062,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); @@ -3093,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; @@ -3187,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; @@ -3232,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; @@ -3259,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; @@ -3271,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 @@ -3336,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 */ @@ -3364,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 */ @@ -3459,6 +3546,10 @@ start_hourglass () EMACS_TIME delay; int secs, usecs = 0; + /* Don't bother for ttys. */ + if (NILP (Vwindow_system)) + return; + cancel_hourglass (); if (INTEGERP (Vhourglass_delay) @@ -3531,6 +3622,9 @@ show_hourglass (timer) 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); @@ -3575,7 +3669,12 @@ hide_hourglass () if (FRAME_MAC_P (f) /* Watch out for newly created frames. */ && f->output_data.mac->hourglass_control) - HideControl (f->output_data.mac->hourglass_control); + { +#if USE_CG_DRAWING + mac_prepare_for_quickdraw (f); +#endif + HideControl (f->output_data.mac->hourglass_control); + } } hourglass_shown_p = 0; @@ -3660,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; @@ -3676,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); @@ -3708,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 */ @@ -3753,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)) @@ -3944,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); @@ -3968,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. @@ -3978,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 @@ -4109,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; @@ -4156,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); @@ -4236,17 +4347,17 @@ 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[MAXPATHLEN]; - int default_filter_index = 1; /* 1: All Files, 2: Directories only */ static NavEventUPP mac_nav_event_callbackUPP = NULL; + check_mac (); + GCPRO6 (prompt, dir, default_filename, mustmatch, file, only_dir_p); CHECK_STRING (prompt); CHECK_STRING (dir); @@ -4262,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); @@ -4271,10 +4382,10 @@ 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 (ENCODE_UTF_8 (prompt))); + message = cfstring_create_with_string (prompt); options.message = message; } /* Don't set the application, let it use default. @@ -4287,8 +4398,8 @@ If ONLY-DIR-P is non-nil, the user can only select directories. */) if (!NILP (only_dir_p)) status = NavCreateChooseFolderDialog(&options, mac_nav_event_callbackUPP, NULL, NULL, &dialogRef); - else if (NILP (mustmatch)) - { + else if (NILP (mustmatch)) + { /* This is a save dialog */ options.optionFlags |= kNavDontConfirmReplacement; options.actionButtonLabel = CFSTR ("Ok"); @@ -4305,7 +4416,7 @@ If ONLY-DIR-P is non-nil, the user can only select directories. */) options.saveFileName = saveName; options.optionFlags |= kNavSelectDefaultLocation; } - status = NavCreatePutFileDialog(&options, + status = NavCreatePutFileDialog(&options, 'TEXT', kNavGenericSignature, mac_nav_event_callbackUPP, NULL, &dialogRef); @@ -4317,25 +4428,17 @@ If ONLY-DIR-P is non-nil, the user can only select directories. */) mac_nav_event_callbackUPP, NULL, NULL, NULL, &dialogRef); } - + /* Set the default location and continue*/ if (status == noErr) { + Lisp_Object encoded_dir = ENCODE_FILE (dir); AEDesc defLocAed; -#ifdef MAC_OSX - FSRef defLoc; - status = FSPathMakeRef(SDATA(ENCODE_FILE(dir)), &defLoc, NULL); -#else - FSSpec defLoc; - status = posix_pathname_to_fsspec (SDATA (ENCODE_FILE (dir)), &defLoc); -#endif - if (status == noErr) + + status = AECreateDesc (TYPE_FILE_NAME, SDATA (encoded_dir), + SBYTES (encoded_dir), &defLocAed); + if (status == noErr) { -#ifdef MAC_OSX - AECreateDesc(typeFSRef, &defLoc, sizeof(FSRef), &defLocAed); -#else - AECreateDesc(typeFSS, &defLoc, sizeof(FSSpec), &defLocAed); -#endif NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed); AEDisposeDesc(&defLocAed); } @@ -4357,57 +4460,58 @@ If ONLY-DIR-P is non-nil, the user can only select directories. */) case kNavUserActionSaveAs: { NavReplyRecord reply; - AEDesc aed; -#ifdef MAC_OSX - FSRef fsRef; -#else - FSSpec fs; -#endif - status = NavDialogGetReply(dialogRef, &reply); + Size len; -#ifdef MAC_OSX - AECoerceDesc(&reply.selection, typeFSRef, &aed); - AEGetDescData(&aed, (void *) &fsRef, sizeof (FSRef)); - FSRefMakePath(&fsRef, (UInt8 *) filename, sizeof (filename)); + status = NavDialogGetReply(dialogRef, &reply); + if (status != noErr) + break; + status = AEGetNthPtr (&reply.selection, 1, TYPE_FILE_NAME, + NULL, NULL, filename, + sizeof (filename) - 1, &len); + if (status == noErr) + { + 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 - AECoerceDesc (&reply.selection, typeFSS, &aed); - AEGetDescData (&aed, (void *) &fs, sizeof (FSSpec)); - fsspec_to_posix_pathname (&fs, filename, sizeof (filename) - 1); + CFStringGetSystemEncoding () #endif - AEDisposeDesc(&aed); - if (reply.saveFileName) - { - /* 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, - sizeof (filename) - len, - kCFStringEncodingUTF8); + ); + } + file = DECODE_FILE (make_unibyte_string (filename, + strlen (filename))); } - file = DECODE_FILE (make_unibyte_string (filename, - strlen (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); } @@ -4423,6 +4527,53 @@ mac_nav_event_callback (selector, parms, 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 ***********************************************************************/ @@ -4439,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, */ @@ -4447,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, @@ -4575,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); @@ -4602,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; @@ -4614,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; @@ -4632,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 }