Fixing up some issues seen with display modes reported from the Apple Studio Display:
- It has some pairs of modes that differ only in whether they are "usable for desktop." Switching to one of the modes that isn't results in an error. All other things being equal, we should prefer modes that are "usable for desktop" over those that aren't. - display_get_modes was returning multiple identical DEVMODEs. This is because we consider the kDisplayModeValidFlag and kDisplayModeSafeFlag values as making a display mode unique (and thus not comparable to other modes with the same resolution). Like above, the Studio Display has mode pairs that are identical except that one is "unsafe." We should compare modes with the same resolution, regardless of the safe and valid flags, and prefer safe and valid ones over the alternatives.
From: Tim Clem tclem@codeweavers.com
--- dlls/winemac.drv/display.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index edf740b260e..b1a5a4500d2 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -457,6 +457,17 @@ static CFDictionaryRef create_mode_dict(CGDisplayModeRef display_mode, BOOL is_o }
+/*********************************************************************** + * mode_is_preferred + * + * Returns whether new_mode ought to be preferred over old_mode - that is, + * whether new_mode is a better option to expose as a valid mode to switch to. + * old_mode may be NULL, in which case the function returns true if the mode + * should be considered at all. + * old_mode and new_mode are guaranteed to have identical return values from + * create_mode_dict. So, they will have the same point dimension and relevant + * IO flags, among other properties. + */ static BOOL mode_is_preferred(CGDisplayModeRef new_mode, CGDisplayModeRef old_mode, struct display_mode_descriptor *original_mode_desc, BOOL include_unsupported)
From: Tim Clem tclem@codeweavers.com
Some devices, like the Apple Studio Display, have modes that differ only in this flag, and switching to the ones that are not usable for desktop results in an error. --- dlls/winemac.drv/display.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index b1a5a4500d2..ed27390ac30 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -475,6 +475,7 @@ static BOOL mode_is_preferred(CGDisplayModeRef new_mode, CGDisplayModeRef old_mo BOOL new_is_supported; CFStringRef pixel_encoding; size_t width_points, height_points; + BOOL new_usable_for_desktop, old_usable_for_desktop; size_t old_width_pixels, old_height_pixels, new_width_pixels, new_height_pixels; BOOL old_size_same, new_size_same;
@@ -516,6 +517,12 @@ static BOOL mode_is_preferred(CGDisplayModeRef new_mode, CGDisplayModeRef old_mo if (!new_is_supported && display_mode_is_supported(old_mode)) return FALSE;
+ /* Prefer modes that are usable for desktop over ones that aren't. */ + new_usable_for_desktop = CGDisplayModeIsUsableForDesktopGUI(new_mode); + old_usable_for_desktop = CGDisplayModeIsUsableForDesktopGUI(old_mode); + if (new_usable_for_desktop && !old_usable_for_desktop) + return TRUE; + /* Otherwise, prefer a mode whose pixel size equals its point size over one which is scaled. */ width_points = CGDisplayModeGetWidth(new_mode);
From: Tim Clem tclem@codeweavers.com
In the case that unsafe/invalid modes aren't excluded entirely by the include_unsupported flag to copy_display_modes, we actually want to compare them to their counterparts with the same resolution, so that we can prefer the safe and valid alternatives. --- dlls/winemac.drv/display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index ed27390ac30..fe9e6dcb5bd 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -420,8 +420,7 @@ static CFDictionaryRef create_mode_dict(CGDisplayModeRef display_mode, BOOL is_o height *= 2; }
- io_flags &= kDisplayModeValidFlag | kDisplayModeSafeFlag | kDisplayModeInterlacedFlag | - kDisplayModeStretchedFlag | kDisplayModeTelevisionFlag; + io_flags &= kDisplayModeInterlacedFlag | kDisplayModeStretchedFlag | kDisplayModeTelevisionFlag; cf_io_flags = CFNumberCreate(NULL, kCFNumberSInt32Type, &io_flags); cf_width = CFNumberCreate(NULL, kCFNumberSInt64Type, &width); cf_height = CFNumberCreate(NULL, kCFNumberSInt64Type, &height);
This merge request was approved by Brendan Shanks.