aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshipmints2025-03-04 09:56:56 -0500
committerAlan Third2025-06-02 18:34:10 +0100
commit9cc5f1c697c1a47470651ff4293f335eaa10ea9a (patch)
treebdd3a1c0facd1e92b5c00e16e28bd61294f4fa42
parent55691c61d4af972b999bb97bffb46cb8571c912c (diff)
downloademacs-9cc5f1c697c1a47470651ff4293f335eaa10ea9a.tar.gz
emacs-9cc5f1c697c1a47470651ff4293f335eaa10ea9a.zip
Fix ns_make_monitor_attribute_list (bug#76691)
This is the NS implementation for 'display-monitor-attributes-list'. Change implementation from IORegistry to direct introspection of NSScreen. * src/nsfns.m (ns_make_monitor_attribute_list): Use localizedName selector on NSScreen. For anonymous displays, synthesize names of the form ("%dx%d@%d,%d" width height x y). (ns_get_name_from_ioreg) (ns_screen_name): Removed.
-rw-r--r--src/nsfns.m114
1 files changed, 19 insertions, 95 deletions
diff --git a/src/nsfns.m b/src/nsfns.m
index b1ed0eff58a..b219064cdd1 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -2612,100 +2612,6 @@ DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
2612 return make_fixnum (ns_display_pixel_height (dpyinfo)); 2612 return make_fixnum (ns_display_pixel_height (dpyinfo));
2613} 2613}
2614 2614
2615#ifdef NS_IMPL_COCOA
2616
2617/* Returns the name for the screen that OBJ represents, or NULL.
2618 Caller must free return value.
2619*/
2620
2621static char *
2622ns_get_name_from_ioreg (io_object_t obj)
2623{
2624 char *name = NULL;
2625
2626 NSDictionary *info = (NSDictionary *)
2627 IODisplayCreateInfoDictionary (obj, kIODisplayOnlyPreferredName);
2628 NSDictionary *names = [info objectForKey:
2629 [NSString stringWithUTF8String:
2630 kDisplayProductName]];
2631
2632 if ([names count] > 0)
2633 {
2634 NSString *n = [names objectForKey: [[names allKeys]
2635 objectAtIndex:0]];
2636 if (n != nil) name = xstrdup ([n UTF8String]);
2637 }
2638
2639 [info release];
2640
2641 return name;
2642}
2643
2644/* Returns the name for the screen that DID came from, or NULL.
2645 Caller must free return value.
2646*/
2647
2648static char *
2649ns_screen_name (CGDirectDisplayID did)
2650{
2651 char *name = NULL;
2652
2653#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
2654#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
2655 if (CGDisplayIOServicePort == NULL)
2656#endif
2657 {
2658 mach_port_t masterPort;
2659 io_iterator_t it;
2660 io_object_t obj;
2661
2662 /* CGDisplayIOServicePort is deprecated. Do it another (harder) way.
2663
2664 Is this code OK for macOS < 10.9, and GNUstep? I suspect it is,
2665 in which case is it worth keeping the other method in here? */
2666
2667 if (IOMasterPort (MACH_PORT_NULL, &masterPort) != kIOReturnSuccess
2668 || IOServiceGetMatchingServices (masterPort,
2669 IOServiceMatching ("IONDRVDevice"),
2670 &it) != kIOReturnSuccess)
2671 return name;
2672
2673 /* Must loop until we find a name. Many devices can have the same unit
2674 number (represents different GPU parts), but only one has a name. */
2675 while (! name && (obj = IOIteratorNext (it)))
2676 {
2677 CFMutableDictionaryRef props;
2678 const void *val;
2679
2680 if (IORegistryEntryCreateCFProperties (obj,
2681 &props,
2682 kCFAllocatorDefault,
2683 kNilOptions) == kIOReturnSuccess
2684 && props != nil
2685 && (val = CFDictionaryGetValue(props, @"IOFBDependentIndex")))
2686 {
2687 unsigned nr = [(NSNumber *)val unsignedIntegerValue];
2688 if (nr == CGDisplayUnitNumber (did))
2689 name = ns_get_name_from_ioreg (obj);
2690 }
2691
2692 CFRelease (props);
2693 IOObjectRelease (obj);
2694 }
2695
2696 IOObjectRelease (it);
2697 }
2698#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
2699 else
2700#endif
2701#endif /* #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 */
2702#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
2703 name = ns_get_name_from_ioreg (CGDisplayIOServicePort (did));
2704#endif
2705 return name;
2706}
2707#endif /* NS_IMPL_COCOA */
2708
2709static Lisp_Object 2615static Lisp_Object
2710ns_make_monitor_attribute_list (struct MonitorInfo *monitors, 2616ns_make_monitor_attribute_list (struct MonitorInfo *monitors,
2711 int n_monitors, 2617 int n_monitors,
@@ -2825,7 +2731,25 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
2825 m->work.height = (unsigned short) vfr.size.height; 2731 m->work.height = (unsigned short) vfr.size.height;
2826 2732
2827#ifdef NS_IMPL_COCOA 2733#ifdef NS_IMPL_COCOA
2828 m->name = ns_screen_name (did); 2734 m->name = NULL;
2735 if ([s respondsToSelector:@selector(localizedName)])
2736 {
2737 NSString *name = [s valueForKey:@"localizedName"];
2738 if (name != NULL)
2739 {
2740 m->name = xmalloc ([name lengthOfBytesUsingEncoding: NSUTF8StringEncoding] + 1);
2741 strcpy(m->name, [name UTF8String]);
2742 }
2743 }
2744 /* If necessary, synthesize a name of the following form:
2745 %dx%d@%d,%d width height x y. */
2746 if (m->name == NULL)
2747 {
2748 char buf[25]; /* sufficient for 12345x78901@34567,90123 */
2749 snprintf (buf, sizeof(buf), "%ux%u@%d,%d",
2750 m->work.width, m->work.height, m->work.x, m->work.y);
2751 m->name = xstrdup (buf);
2752 }
2829 2753
2830 { 2754 {
2831 CGSize mms = CGDisplayScreenSize (did); 2755 CGSize mms = CGDisplayScreenSize (did);