X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/3da64ce8fc7efe6c8ae5b135a3d5215176662df6..0924e3f6e1b5749019ac7f69765af355623c9db8:/src/macfns.c diff --git a/src/macfns.c b/src/macfns.c index 3c92499701..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, 2002, 2003, 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. @@ -50,6 +51,14 @@ Boston, MA 02110-1301, USA. */ extern void free_frame_menubar (); +#if TARGET_API_MAC_CARBON + +/* Carbon version info */ + +static Lisp_Object Vmac_carbon_version_string; + +#endif /* TARGET_API_MAC_CARBON */ + /* Non-zero means we're allowed to display an hourglass cursor. */ int display_hourglass_p; @@ -209,15 +218,6 @@ 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 *)); @@ -251,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" }, @@ -1009,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; @@ -1032,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; @@ -1099,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; @@ -1135,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') @@ -1154,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; @@ -1176,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') @@ -1367,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)); @@ -1447,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; @@ -1600,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; @@ -1645,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); } @@ -1745,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)) @@ -1917,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 */ @@ -1931,6 +1909,156 @@ x_set_scroll_bar_default_width (f) #endif /* not MAC_OSX */ } +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 void +mac_set_font (f, arg, oldval) + struct frame *f; + Lisp_Object arg, oldval; +{ + 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; + + err = GetWindowProxyAlias (w, &alias); + if (err == errWindowDoesNotHaveProxy && !STRINGP (file_name)) + goto out; + + if (STRINGP (file_name)) + { + AEDesc desc; +#ifdef MAC_OSX + FSRef fref; +#else + FSSpec fss; +#endif + Boolean changed; + Lisp_Object encoded_file_name = ENCODE_FILE (file_name); + +#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); + } + + 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. */ @@ -2131,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); @@ -2398,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; @@ -2439,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)) @@ -2452,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. */ @@ -2473,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 @@ -2532,11 +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-mac"); + font = x_new_fontset (f, "fontset-standard"); if (! STRINGP (font)) font = x_new_font (f, "-*-monaco-*-12-*-mac-roman"); if (! STRINGP (font)) @@ -2545,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), @@ -2602,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, @@ -2670,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 @@ -2690,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; @@ -2705,6 +2846,35 @@ 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. */) @@ -2733,14 +2903,9 @@ 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; } @@ -2871,24 +3036,39 @@ If omitted or nil, that stands for the selected frame's display. */) (display) Lisp_Object display; { - int mac_major_version; - SInt32 response; + UInt32 response, major, minor, bugfix; OSErr err; 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; if (err != noErr) error ("Cannot get Mac OS version"); - mac_major_version = (response >> 8) & 0xff; - /* convert BCD to int */ - mac_major_version -= (mac_major_version >> 4) * 6; - - 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))); } @@ -2911,11 +3091,20 @@ If omitted or nil, that stands for the selected frame's 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, @@ -2926,11 +3115,20 @@ If omitted or nil, that stands for the selected frame's 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, @@ -3164,6 +3362,14 @@ DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0, return Qnil; } +/* x_sync is a no-op on Mac. */ + +void +x_sync (f) + FRAME_PTR f; +{ +} + /*********************************************************************** Window properties @@ -3340,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) @@ -3412,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); @@ -3456,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; @@ -3541,6 +3759,7 @@ x_create_tip_frame (dpyinfo, parms, text) check_mac (); + parms = Fcopy_alist (parms); #ifdef MULTI_KBOARD kb = dpyinfo->kboard; @@ -3585,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 */ @@ -3630,11 +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-mac"); + font = x_new_fontset (f, "fontset-standard"); if (! STRINGP (font)) font = x_new_font (f, "-*-monaco-*-12-*-mac-roman"); if (! STRINGP (font)) @@ -3823,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); @@ -4035,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); @@ -4118,14 +4350,14 @@ If ONLY-DIR-P is non-nil, the user can only select directories. */) (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); @@ -4200,21 +4432,13 @@ If ONLY-DIR-P is non-nil, the user can only select directories. */) /* 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 + + 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); } @@ -4236,41 +4460,36 @@ 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)); -#else - AECoerceDesc (&reply.selection, typeFSS, &aed); - AEGetDescData (&aed, (void *) &fs, sizeof (FSSpec)); - fsspec_to_posix_pathname (&fs, filename, sizeof (filename) - 1); -#endif - AEDisposeDesc(&aed); - if (reply.saveFileName) + 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) { - /* 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, + 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 + kCFStringEncodingUTF8 #else - CFStringGetSystemEncoding () + CFStringGetSystemEncoding () #endif - ); + ); + } + file = DECODE_FILE (make_unibyte_string (filename, + strlen (filename))); } - file = DECODE_FILE (make_unibyte_string (filename, - strlen (filename))); NavDisposeReply(&reply); } break; @@ -4308,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 ***********************************************************************/ @@ -4324,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, */ @@ -4332,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, @@ -4460,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); @@ -4487,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; @@ -4499,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; @@ -4517,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 }