X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/c0342369acfbad2f0ea86b949a2f116304186353..ad8a47b89fc3c5a3302255f318b1ed805838cf72:/src/nsfns.m diff --git a/src/nsfns.m b/src/nsfns.m index 9433918315..8f14915ea6 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -46,6 +46,9 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu) #ifdef NS_IMPL_COCOA #include +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +#include "macfont.h" +#endif #endif #if 0 @@ -89,9 +92,6 @@ extern Lisp_Object Qunsplittable, Qmenu_bar_lines, Qbuffer_predicate, Qtitle; Lisp_Object Qbuffered; Lisp_Object Qfontsize; -/* hack for OS X file panels */ -char panelOK = 0; - EmacsTooltip *ns_tooltip = nil; /* Need forward declaration here to preserve organizational integrity of file */ @@ -127,7 +127,7 @@ check_ns_display_info (Lisp_Object object) struct frame *sf = XFRAME (selected_frame); if (FRAME_NS_P (sf) && FRAME_LIVE_P (sf)) - dpyinfo = FRAME_NS_DISPLAY_INFO (sf); + dpyinfo = FRAME_DISPLAY_INFO (sf); else if (x_display_list != 0) dpyinfo = x_display_list; else @@ -146,8 +146,8 @@ check_ns_display_info (Lisp_Object object) dpyinfo = ns_display_info_for_name (object); else { - FRAME_PTR f = decode_window_system_frame (object); - dpyinfo = FRAME_NS_DISPLAY_INFO (f); + struct frame *f = decode_window_system_frame (object); + dpyinfo = FRAME_DISPLAY_INFO (f); } return dpyinfo; @@ -175,20 +175,13 @@ ns_get_window (Lisp_Object maybeFrame) struct ns_display_info * ns_display_info_for_name (Lisp_Object name) { - Lisp_Object names; struct ns_display_info *dpyinfo; CHECK_STRING (name); - for (dpyinfo = x_display_list, names = ns_display_name_list; - dpyinfo; - dpyinfo = dpyinfo->next, names = XCDR (names)) - { - Lisp_Object tem; - tem = Fstring_equal (XCAR (XCAR (names)), name); - if (!NILP (tem)) - return dpyinfo; - } + for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) + if (!NILP (Fstring_equal (XCAR (dpyinfo->name_list_element), name))) + return dpyinfo; error ("Emacs for OpenStep does not yet support multi-display."); @@ -410,23 +403,23 @@ x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) if (!NILP (f->title)) arg = f->title; else - /* explicit name and no icon-name -> explicit_name */ + /* Explicit name and no icon-name -> explicit_name. */ if (f->explicit_name) arg = f->name; else { - /* no explicit name and no icon-name -> - name has to be rebuild from icon_title_format */ - windows_or_buffers_changed++; + /* No explicit name and no icon-name -> + name has to be rebuild from icon_title_format. */ + windows_or_buffers_changed = 62; return; } } /* Don't change the name if it's already NAME. */ - if ([[view window] miniwindowTitle] && - ([[[view window] miniwindowTitle] + if ([[view window] miniwindowTitle] + && ([[[view window] miniwindowTitle] isEqualToString: [NSString stringWithUTF8String: - SSDATA (arg)]])) + SSDATA (arg)]])) return; [[view window] setMiniwindowTitle: @@ -434,7 +427,7 @@ x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) } static void -ns_set_name_internal (FRAME_PTR f, Lisp_Object name) +ns_set_name_internal (struct frame *f, Lisp_Object name) { struct gcpro gcpro1; Lisp_Object encoded_name, encoded_icon_name; @@ -458,8 +451,8 @@ ns_set_name_internal (FRAME_PTR f, Lisp_Object name) str = [NSString stringWithUTF8String: SSDATA (encoded_icon_name)]; - if ([[view window] miniwindowTitle] && - ! [[[view window] miniwindowTitle] isEqualToString: str]) + if ([[view window] miniwindowTitle] + && ! [[[view window] miniwindowTitle] isEqualToString: str]) [[view window] setMiniwindowTitle: str]; } @@ -476,7 +469,7 @@ ns_set_name (struct frame *f, Lisp_Object name, int explicit) /* If we're switching from explicit to implicit, we had better update the mode lines and thereby update the title. */ if (f->explicit_name && NILP (name)) - update_mode_lines = 1; + update_mode_lines = 21; f->explicit_name = ! NILP (name); } @@ -484,7 +477,7 @@ ns_set_name (struct frame *f, Lisp_Object name, int explicit) return; if (NILP (name)) - name = build_string([ns_app_name UTF8String]); + name = build_string ([ns_app_name UTF8String]); else CHECK_STRING (name); @@ -494,7 +487,7 @@ ns_set_name (struct frame *f, Lisp_Object name, int explicit) fset_name (f, name); - /* title overrides explicit name */ + /* Title overrides explicit name. */ if (! NILP (f->title)) name = f->title; @@ -506,7 +499,7 @@ ns_set_name (struct frame *f, Lisp_Object name, int explicit) specified a name for the frame; the name will override any set by the redisplay code. */ static void -x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { NSTRACE (x_explicitly_set_name); ns_set_name (f, arg, 1); @@ -517,7 +510,7 @@ x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) name; names set this way will never override names set by the user's lisp code. */ void -x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { NSTRACE (x_implicitly_set_name); @@ -541,7 +534,7 @@ x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name) if (EQ (name, f->title)) return; - update_mode_lines = 1; + update_mode_lines = 22; fset_title (f, name); @@ -710,7 +703,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) } } - x_set_window_size (f, 0, f->text_cols, f->text_lines); + x_set_window_size (f, 0, f->text_cols, f->text_lines, 0); } @@ -860,14 +853,10 @@ ns_cursor_type_to_lisp (int arg) /* This is the same as the xfns.c definition. */ static void -x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { set_frame_cursor_types (f, arg); - - /* Make sure the cursor gets redrawn. */ - cursor_type_changed = 1; } - /* called to set mouse pointer color, but all other terms use it to initialize pointer types (and don't set the color ;) */ @@ -888,7 +877,7 @@ ns_appkit_version_str (void) #ifdef NS_IMPL_GNUSTEP sprintf(tmp, "gnustep-gui-%s", Xstr(GNUSTEP_GUI_VERSION)); -#elif defined(NS_IMPL_COCOA) +#elif defined (NS_IMPL_COCOA) sprintf(tmp, "apple-appkit-%.2f", NSAppKitVersionNumber); #else tmp = "ns-unknown"; @@ -905,7 +894,7 @@ ns_appkit_version_int (void) { #ifdef NS_IMPL_GNUSTEP return GNUSTEP_GUI_MAJOR_VERSION * 100 + GNUSTEP_GUI_MINOR_VERSION; -#elif defined(NS_IMPL_COCOA) +#elif defined (NS_IMPL_COCOA) return (int)NSAppKitVersionNumber; #endif return 0; @@ -957,6 +946,8 @@ frame_parm_handler ns_frame_parm_handlers[] = x_set_icon_name, x_set_icon_type, x_set_internal_border_width, /* generic OK */ + 0, /* x_set_right_divider_width */ + 0, /* x_set_bottom_divider_width */ x_set_menu_bar_lines, x_set_mouse_color, x_explicitly_set_name, @@ -984,7 +975,7 @@ frame_parm_handler ns_frame_parm_handlers[] = /* Handler for signals raised during x_create_frame. FRAME is the frame which is partially constructed. */ -static Lisp_Object +static void unwind_create_frame (Lisp_Object frame) { struct frame *f = XFRAME (frame); @@ -993,13 +984,13 @@ unwind_create_frame (Lisp_Object frame) display is disconnected after the frame has become official, but before x_create_frame removes the unwind protect. */ if (!FRAME_LIVE_P (f)) - return Qnil; + return; /* If frame is ``official'', nothing to do. */ if (NILP (Fmemq (frame, Vframe_list))) { #if defined GLYPH_DEBUG && defined ENABLE_CHECKING - struct ns_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); #endif x_free_frame_resources (f); @@ -1009,10 +1000,7 @@ unwind_create_frame (Lisp_Object frame) /* Check that reference counts are indeed correct. */ eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount); #endif - return Qt; } - - return Qnil; } /* @@ -1074,7 +1062,7 @@ This function is an internal primitive--use `make-frame' instead. */) Lisp_Object frame, tem; Lisp_Object name; int minibuffer_only = 0; - int window_prompting = 0; + long window_prompting = 0; int width, height; ptrdiff_t count = specpdl_ptr - specpdl; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; @@ -1149,9 +1137,9 @@ This function is an internal primitive--use `make-frame' instead. */) if (! STRINGP (f->icon_name)) fset_icon_name (f, Qnil); - FRAME_NS_DISPLAY_INFO (f) = dpyinfo; + FRAME_DISPLAY_INFO (f) = dpyinfo; - /* With FRAME_NS_DISPLAY_INFO set up, this unwind-protect is safe. */ + /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */ record_unwind_protect (unwind_create_frame, frame); f->output_data.ns->window_desc = desc_ctr++; @@ -1162,7 +1150,7 @@ This function is an internal primitive--use `make-frame' instead. */) } else { - f->output_data.ns->parent_desc = FRAME_NS_DISPLAY_INFO (f)->root_window; + f->output_data.ns->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; f->output_data.ns->explicit_parent = 0; } @@ -1181,7 +1169,16 @@ This function is an internal primitive--use `make-frame' instead. */) } block_input (); + +#ifdef NS_IMPL_COCOA +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if (CTGetCoreTextVersion != NULL + && CTGetCoreTextVersion () >= kCTVersionNumber10_5) + mac_register_font_driver (f); +#endif +#endif register_font_driver (&nsfont_driver, f); + x_default_parameter (f, parms, Qfont_backend, Qnil, "fontBackend", "FontBackend", RES_TYPE_STRING); @@ -1191,9 +1188,15 @@ This function is an internal primitive--use `make-frame' instead. */) x_default_parameter (f, parms, Qfontsize, make_number (0 /*(int)[font pointSize]*/), "fontSize", "FontSize", RES_TYPE_NUMBER); + // Remove ' Regular', not handled by backends. + char *fontname = xstrdup ([[font displayName] UTF8String]); + int len = strlen (fontname); + if (len > 8 && strcmp (fontname + len - 8, " Regular") == 0) + fontname[len-8] = '\0'; x_default_parameter (f, parms, Qfont, - build_string ([[font fontName] UTF8String]), + build_string (fontname), "font", "Font", RES_TYPE_STRING); + xfree (fontname); } unblock_input (); @@ -1234,6 +1237,13 @@ This function is an internal primitive--use `make-frame' instead. */) init_frame_faces (f); + /* Read comment about this code in corresponding place in xfns.c. */ + width = FRAME_TEXT_WIDTH (f); + height = FRAME_TEXT_HEIGHT (f); + FRAME_TEXT_HEIGHT (f) = 0; + SET_FRAME_WIDTH (f, 0); + change_frame_size (f, width, height, 1, 0, 0, 1); + /* The resources controlling the menu-bar and tool-bar are processed specially at startup, and reflected in the mode variables; ignore them here. */ @@ -1265,7 +1275,8 @@ This function is an internal primitive--use `make-frame' instead. */) f->output_data.ns->hand_cursor = [NSCursor pointingHandCursor]; f->output_data.ns->hourglass_cursor = [NSCursor disappearingItemCursor]; f->output_data.ns->horizontal_drag_cursor = [NSCursor resizeLeftRightCursor]; - FRAME_NS_DISPLAY_INFO (f)->vertical_scroll_bar_cursor + f->output_data.ns->vertical_drag_cursor = [NSCursor resizeUpDownCursor]; + FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor = [NSCursor arrowCursor]; f->output_data.ns->current_pointer = f->output_data.ns->text_cursor; @@ -1297,12 +1308,11 @@ This function is an internal primitive--use `make-frame' instead. */) x_default_parameter (f, parms, Qfullscreen, Qnil, "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); - width = FRAME_COLS (f); - height = FRAME_LINES (f); - - SET_FRAME_COLS (f, 0); - FRAME_LINES (f) = 0; - change_frame_size (f, height, width, 1, 0, 0); + width = FRAME_TEXT_WIDTH (f); + height = FRAME_TEXT_HEIGHT (f); + FRAME_TEXT_HEIGHT (f) = 0; + SET_FRAME_WIDTH (f, 0); + change_frame_size (f, width, height, 1, 0, 0, 1); if (! f->output_data.ns->explicit_parent) { @@ -1349,14 +1359,10 @@ This function is an internal primitive--use `make-frame' instead. */) return unbind_to (count, frame); } - -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. */) - (Lisp_Object frame) +void +x_focus_frame (struct frame *f) { - struct frame *f = decode_window_system_frame (frame); - struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f); + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); if (dpyinfo->x_focus_frame != f) { @@ -1366,8 +1372,6 @@ FRAME nil means use the selected frame. */) [[view window] makeKeyAndOrderFront: view]; unblock_input (); } - - return Qnil; } @@ -1378,9 +1382,15 @@ DEFUN ("ns-popup-font-panel", Fns_popup_font_panel, Sns_popup_font_panel, { struct frame *f = decode_window_system_frame (frame); id fm = [NSFontManager sharedFontManager]; - - [fm setSelectedFont: ((struct nsfont_info *)f->output_data.ns->font)->nsfont - isMultiple: NO]; + struct font *font = f->output_data.ns->font; + NSFont *nsfont; + if (EQ (font->driver->type, Qns)) + nsfont = ((struct nsfont_info *)font)->nsfont; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + else + nsfont = (NSFont *) macfont_get_nsctfont (font); +#endif + [fm setSelectedFont: nsfont isMultiple: NO]; [fm orderFrontFontPanel: NSApp]; return Qnil; } @@ -1396,6 +1406,41 @@ DEFUN ("ns-popup-color-panel", Fns_popup_color_panel, Sns_popup_color_panel, return Qnil; } +static struct +{ + id panel; + BOOL ret; +#if ! defined (NS_IMPL_COCOA) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 + NSString *dirS, *initS; + BOOL no_types; +#endif +} ns_fd_data; + +void +ns_run_file_dialog (void) +{ + if (ns_fd_data.panel == nil) return; +#if defined (NS_IMPL_COCOA) && \ + MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + ns_fd_data.ret = [ns_fd_data.panel runModal]; +#else + if (ns_fd_data.no_types) + { + ns_fd_data.ret = [ns_fd_data.panel + runModalForDirectory: ns_fd_data.dirS + file: ns_fd_data.initS]; + } + else + { + ns_fd_data.ret = [ns_fd_data.panel + runModalForDirectory: ns_fd_data.dirS + file: ns_fd_data.initS + types: nil]; + } +#endif + ns_fd_data.panel = nil; +} DEFUN ("ns-read-file-name", Fns_read_file_name, Sns_read_file_name, 1, 5, 0, doc: /* Use a graphical panel to read a file name, using prompt PROMPT. @@ -1420,6 +1465,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */) [NSString stringWithUTF8String: SSDATA (dir)]; NSString *initS = NILP (init) || !STRINGP (init) ? nil : [NSString stringWithUTF8String: SSDATA (init)]; + NSEvent *nxev; check_window_system (NULL); @@ -1440,7 +1486,6 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */) [panel setTreatsFilePackagesAsDirectories: YES]; [panel setDelegate: fileDelegate]; - panelOK = 0; if (! NILP (dir_only_p)) { [panel setCanChooseDirectories: YES]; @@ -1454,7 +1499,9 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */) [panel setCanChooseFiles: YES]; } - block_input (); + block_input (); + ns_fd_data.panel = panel; + ns_fd_data.ret = NO; #if defined (NS_IMPL_COCOA) && \ MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 if (! NILP (mustmatch) || ! NILP (dir_only_p)) @@ -1465,19 +1512,32 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */) else [panel setNameFieldStringValue: @""]; - ret = [panel runModal]; #else - if (NILP (mustmatch) && NILP (dir_only_p)) - { - ret = [panel runModalForDirectory: dirS file: initS]; - } - else - { - ret = [panel runModalForDirectory: dirS file: initS types: nil]; - } + ns_fd_data.no_types = NILP (mustmatch) && NILP (dir_only_p); + ns_fd_data.dirS = dirS; + ns_fd_data.initS = initS; #endif - ret = (ret == NSOKButton) || panelOK; + /* runModalForDirectory/runModal restarts the main event loop when done, + so we must start an event loop and then pop up the file dialog. + The file dialog may pop up a confirm dialog after Ok has been pressed, + so we can not simply pop down on the Ok/Cancel press. + */ + nxev = [NSEvent otherEventWithType: NSApplicationDefined + location: NSMakePoint (0, 0) + modifierFlags: 0 + timestamp: 0 + windowNumber: [[NSApp mainWindow] windowNumber] + context: [NSApp context] + subtype: 0 + data1: 0 + data2: NSAPP_DATA2_RUNFILEDIALOG]; + + [NSApp postEvent: nxev atStart: NO]; + while (ns_fd_data.panel != nil) + [NSApp run]; + + ret = (ns_fd_data.ret == NSOKButton); if (ret) { @@ -1786,11 +1846,11 @@ 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. */) (void) { - Lisp_Object tail, result; + Lisp_Object result = Qnil; + struct ns_display_info *ndi; - result = Qnil; - for (tail = ns_display_name_list; CONSP (tail); tail = XCDR (tail)) - result = Fcons (XCAR (XCAR (tail)), result); + for (ndi = x_display_list; ndi; ndi = ndi->next) + result = Fcons (XCAR (ndi->name_list_element), result); return result; } @@ -1975,7 +2035,7 @@ there was no result. */) ns_string_to_pasteboard (pb, send); if (NSPerformService (svcName, pb) == NO) - Fsignal (Qquit, Fcons (build_string ("service not available"), Qnil)); + Fsignal (Qquit, list1 (build_string ("service not available"))); if ([[pb types] count] == 0) return build_string (""); @@ -1991,13 +2051,28 @@ DEFUN ("ns-convert-utf8-nfd-to-nfc", Fns_convert_utf8_nfd_to_nfc, /* TODO: If GNUstep ever implements precomposedStringWithCanonicalMapping, remove this. */ NSString *utfStr; + Lisp_Object ret = Qnil; + NSAutoreleasePool *pool; CHECK_STRING (str); + pool = [[NSAutoreleasePool alloc] init]; utfStr = [NSString stringWithUTF8String: SSDATA (str)]; #ifdef NS_IMPL_COCOA + if (utfStr) utfStr = [utfStr precomposedStringWithCanonicalMapping]; #endif - return build_string ([utfStr UTF8String]); + if (utfStr) + { + const char *cstr = [utfStr UTF8String]; + if (cstr) + ret = build_string (cstr); + } + + [pool release]; + if (NILP (ret)) + error ("Invalid UTF-8"); + + return ret; } @@ -2150,17 +2225,13 @@ x_set_scroll_bar_default_width (struct frame *f) wid - 1) / wid; } - -extern const char *x_get_string_resource (XrmDatabase, char *, char *); - - /* terms impl this instead of x-get-resource directly */ -const char * -x_get_string_resource (XrmDatabase rdb, char *name, char *class) +char * +x_get_string_resource (XrmDatabase rdb, const char *name, const char *class) { /* remove appname prefix; TODO: allow for !="Emacs" */ - char *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0); - const char *res; + const char *res, *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0); + check_window_system (NULL); if (inhibit_x_resources) @@ -2168,16 +2239,16 @@ x_get_string_resource (XrmDatabase rdb, char *name, char *class) return NULL; res = ns_get_defaults_value (toCheck); - return !res ? NULL : - (!c_strncasecmp (res, "YES", 3) ? "true" : - (!c_strncasecmp (res, "NO", 2) ? "false" : res)); + return (!res ? NULL : + (!c_strncasecmp (res, "YES", 3) ? "true" : + (!c_strncasecmp (res, "NO", 2) ? "false" : (char *) res))); } Lisp_Object x_get_focus_frame (struct frame *frame) { - struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (frame); + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame); Lisp_Object nsfocus; if (!dpyinfo->x_focus_frame) @@ -2187,30 +2258,6 @@ x_get_focus_frame (struct frame *frame) return nsfocus; } - -int -x_pixel_width (struct frame *f) -{ - return FRAME_PIXEL_WIDTH (f); -} - - -int -x_pixel_height (struct frame *f) -{ - return FRAME_PIXEL_HEIGHT (f); -} - - -void -x_sync (struct frame *f) -{ - /* XXX Not implemented XXX */ - return; -} - - - /* ========================================================================== Lisp definitions that, for whatever reason, we can't alias as 'ns-XXX'. @@ -2320,28 +2367,86 @@ each physical monitor, use `display-monitor-attributes-list'. */) } #ifdef NS_IMPL_COCOA -/* Returns the name for the screen that DICT came from, or NULL. + +/* Returns the name for the screen that OBJ represents, or NULL. Caller must free return value. */ static char * -ns_screen_name (CGDirectDisplayID did) +ns_get_name_from_ioreg (io_object_t obj) { char *name = NULL; + NSDictionary *info = (NSDictionary *) - IODisplayCreateInfoDictionary (CGDisplayIOServicePort (did), - kIODisplayOnlyPreferredName); - NSDictionary *names - = [info objectForKey: - [NSString stringWithUTF8String:kDisplayProductName]]; - - if ([names count] > 0) { - NSString *n = [names objectForKey: [[names allKeys] objectAtIndex:0]]; - if (n != nil) - name = xstrdup ([n UTF8String]); - } + IODisplayCreateInfoDictionary (obj, kIODisplayOnlyPreferredName); + NSDictionary *names = [info objectForKey: + [NSString stringWithUTF8String: + kDisplayProductName]]; + + if ([names count] > 0) + { + NSString *n = [names objectForKey: [[names allKeys] + objectAtIndex:0]]; + if (n != nil) name = xstrdup ([n UTF8String]); + } [info release]; + + return name; +} + +/* Returns the name for the screen that DID came from, or NULL. + Caller must free return value. +*/ + +static char * +ns_screen_name (CGDirectDisplayID did) +{ + char *name = NULL; + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9 + mach_port_t masterPort; + io_iterator_t it; + io_object_t obj; + + // CGDisplayIOServicePort is deprecated. Do it another (harder) way. + + if (IOMasterPort (MACH_PORT_NULL, &masterPort) != kIOReturnSuccess + || IOServiceGetMatchingServices (masterPort, + IOServiceMatching ("IONDRVDevice"), + &it) != kIOReturnSuccess) + return name; + + /* Must loop until we find a name. Many devices can have the same unit + number (represents different GPU parts), but only one has a name. */ + while (! name && (obj = IOIteratorNext (it))) + { + CFMutableDictionaryRef props; + const void *val; + + if (IORegistryEntryCreateCFProperties (obj, + &props, + kCFAllocatorDefault, + kNilOptions) == kIOReturnSuccess + && props != nil + && (val = CFDictionaryGetValue(props, @"IOFBDependentIndex"))) + { + unsigned nr = [(NSNumber *)val unsignedIntegerValue]; + if (nr == CGDisplayUnitNumber (did)) + name = ns_get_name_from_ioreg (obj); + } + + CFRelease (props); + IOObjectRelease (obj); + } + + IOObjectRelease (it); + +#else + + name = ns_get_name_from_ioreg (CGDisplayIOServicePort (did)); + +#endif return name; } #endif @@ -2418,7 +2523,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */) if (n_monitors == 0) return Qnil; - monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors)); + monitors = xzalloc (n_monitors * sizeof *monitors); for (i = 0; i < [screens count]; ++i) { @@ -2446,7 +2551,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */) vy = (short) (primary_display_height - vfr.size.height - vfr.origin.y); } - + m->geom.x = (short) fr.origin.x; m->geom.y = y; m->geom.width = (unsigned short) fr.size.width; @@ -2531,6 +2636,7 @@ compute_tip_xy (struct frame *f, { Lisp_Object left, top; EmacsView *view = FRAME_NS_VIEW (f); + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); NSPoint pt; /* Start with user-specified or mouse position. */ @@ -2539,7 +2645,8 @@ compute_tip_xy (struct frame *f, if (!INTEGERP (left) || !INTEGERP (top)) { - pt = last_mouse_motion_position; + pt.x = dpyinfo->last_mouse_motion_x; + pt.y = dpyinfo->last_mouse_motion_y; /* Convert to screen coordinates */ pt = [view convertPoint: pt toView: nil]; pt = [[view window] convertBaseToScreen: pt]; @@ -2548,7 +2655,7 @@ compute_tip_xy (struct frame *f, { /* Absolute coordinates. */ pt.x = XINT (left); - pt.y = x_display_pixel_height (FRAME_NS_DISPLAY_INFO (f)) - XINT (top) + pt.y = x_display_pixel_height (FRAME_DISPLAY_INFO (f)) - XINT (top) - height; } @@ -2558,7 +2665,7 @@ compute_tip_xy (struct frame *f, else if (pt.x + XINT (dx) <= 0) *root_x = 0; /* Can happen for negative dx */ else if (pt.x + XINT (dx) + width - <= x_display_pixel_width (FRAME_NS_DISPLAY_INFO (f))) + <= x_display_pixel_width (FRAME_DISPLAY_INFO (f))) /* It fits to the right of the pointer. */ *root_x = pt.x + XINT (dx); else if (width + XINT (dx) <= pt.x) @@ -2574,12 +2681,12 @@ compute_tip_xy (struct frame *f, /* It fits below the pointer. */ *root_y = pt.y - height - XINT (dy); else if (pt.y + XINT (dy) + height - <= x_display_pixel_height (FRAME_NS_DISPLAY_INFO (f))) + <= x_display_pixel_height (FRAME_DISPLAY_INFO (f))) /* It fits above the pointer */ *root_y = pt.y + XINT (dy); else /* Put it on the top. */ - *root_y = x_display_pixel_height (FRAME_NS_DISPLAY_INFO (f)) - height; + *root_y = x_display_pixel_height (FRAME_DISPLAY_INFO (f)) - height; } @@ -2705,8 +2812,14 @@ handlePanelKeys (NSSavePanel *panel, NSEvent *theEvent) case NSPageUpFunctionKey: case NSPageDownFunctionKey: case NSEndFunctionKey: - [panel sendEvent: theEvent]; - ret = YES; + /* Don't send command modified keys, as those are handled in the + performKeyEquivalent method of the super class. + */ + if (! ([theEvent modifierFlags] & NSCommandKeyMask)) + { + [panel sendEvent: theEvent]; + ret = YES; + } break; /* As we don't have the standard key commands for copy/paste/cut/select-all in our edit menu, we must handle @@ -2749,25 +2862,6 @@ handlePanelKeys (NSSavePanel *panel, NSEvent *theEvent) } @implementation EmacsSavePanel -#ifdef NS_IMPL_COCOA -/* -------------------------------------------------------------------------- - These are overridden to intercept on OS X: ending panel restarts NSApp - event loop if it is stopped. Not sure if this is correct behavior, - perhaps should check if running and if so send an appdefined. - -------------------------------------------------------------------------- */ -- (void) ok: (id)sender -{ - [super ok: sender]; - panelOK = 1; - [NSApp stop: self]; -} -- (void) cancel: (id)sender -{ - [super cancel: sender]; - [NSApp stop: self]; -} -#endif - - (BOOL)performKeyEquivalent:(NSEvent *)theEvent { BOOL ret = handlePanelKeys (self, theEvent); @@ -2779,31 +2873,6 @@ handlePanelKeys (NSSavePanel *panel, NSEvent *theEvent) @implementation EmacsOpenPanel -#ifdef NS_IMPL_COCOA -/* -------------------------------------------------------------------------- - These are overridden to intercept on OS X: ending panel restarts NSApp - event loop if it is stopped. Not sure if this is correct behavior, - perhaps should check if running and if so send an appdefined. - -------------------------------------------------------------------------- */ -- (void) ok: (id)sender -{ - [super ok: sender]; - - // If not choosing directories, and Open is pressed on a directory, return. - if (! [self canChooseDirectories] && ns_directory_from_panel (self) && - ! ns_filename_from_panel (self)) - return; - - panelOK = 1; - [NSApp stop: self]; -} -- (void) cancel: (id)sender -{ - [super cancel: sender]; - [NSApp stop: self]; -} - -#endif - (BOOL)performKeyEquivalent:(NSEvent *)theEvent { // NSOpenPanel inherits NSSavePanel, so passing self is OK. @@ -2869,7 +2938,7 @@ Example: Install an icon Gnus.tiff and execute the following code When you miniaturize a Group, Summary or Article frame, Gnus.tiff will be used as the image of the icon representing the frame. */); - Vns_icon_type_alist = Fcons (Qt, Qnil); + Vns_icon_type_alist = list1 (Qt); DEFVAR_LISP ("ns-version-string", Vns_version_string, doc: /* Toolkit version for NS Windowing. */); @@ -2912,7 +2981,6 @@ be used as the image of the icon representing the frame. */); defsubr (&Sns_list_services); defsubr (&Sns_perform_service); defsubr (&Sns_convert_utf8_nfd_to_nfc); - defsubr (&Sx_focus_frame); defsubr (&Sns_popup_font_panel); defsubr (&Sns_popup_color_panel);