X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/28a11ed69d786148a28808b208e520bbde51387b..0924e3f6e1b5749019ac7f69765af355623c9db8:/src/macfns.c diff --git a/src/macfns.c b/src/macfns.c index f9a5f051eb..9cb9e3e049 100644 --- a/src/macfns.c +++ b/src/macfns.c @@ -51,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; @@ -243,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" }, @@ -1001,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; @@ -1091,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; @@ -1127,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') @@ -1146,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; @@ -1168,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') @@ -1592,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; @@ -1919,6 +1927,138 @@ mac_set_scroll_bar_width (f, arg, oldval) 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. */ @@ -2119,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); @@ -2449,7 +2591,6 @@ 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); @@ -2457,6 +2598,9 @@ This function is an internal primitive--use `make-frame' instead. */) f->icon_name = Qnil; /* 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; @@ -2529,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), @@ -2712,26 +2855,22 @@ FRAME nil means use the selected frame. */) Lisp_Object frame; { struct frame *f = check_x_frame (frame); - struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f); - if (dpyinfo->x_focus_frame != f) - { - BLOCK_INPUT; + BLOCK_INPUT; #ifdef MAC_OSX - ActivateWindow (ActiveNonFloatingWindow (), false); - ActivateWindow (FRAME_MAC_WINDOW (f), true); + 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); + /* 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)); + /* This brings the window to the front. */ + SelectWindow (FRAME_MAC_WINDOW (f)); #endif - UNBLOCK_INPUT; - } + UNBLOCK_INPUT; return Qnil; } @@ -2764,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; } @@ -2911,11 +3045,11 @@ If omitted or nil, that stands for the selected frame's display. */) { if (response >= 0x00001040) { - err = Gestalt ('sys1', &major); /* gestaltSystemVersionMajor */ + err = Gestalt (gestaltSystemVersionMajor, &major); if (err == noErr) - err = Gestalt ('sys2', &minor); /* gestaltSystemVersionMinor */ + err = Gestalt (gestaltSystemVersionMinor, &minor); if (err == noErr) - err = Gestalt ('sys3', &bugfix); /* gestaltSystemVersionBugFix */ + err = Gestalt (gestaltSystemVersionBugFix, &bugfix); } else { @@ -2957,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, @@ -2972,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, @@ -3470,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); @@ -3514,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; @@ -4190,13 +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]; 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); @@ -4366,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 ***********************************************************************/ @@ -4382,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, */ @@ -4518,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); @@ -4558,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; @@ -4576,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 }