In preparation for with https://gitlab.winehq.org/wine/wine/-/merge_requests/576. I think support for changing non-primary display modes in winemac will be easier /after/ the display placement logic is moved to win32u. I also don't really know how to handle the display position on macOS.
-- v4: winemac.drv: Support enumerating non-primary adapters display modes. winemac.drv: Support getting non-primary adapter current display mode. winemac.drv: Check for non-primary adapter earlier in macdrv_ChangeDisplaySettingsEx. winemac.drv: Remove unnecessary macdrv_EnumDisplaySettingsEx declaration. winemac.drv: Invalidate mode cache when enum flags changes. winemac.drv: Rename display modes cache variables.
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/display.c | 58 +++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 2d7b9656103..76a9d67be20 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -53,10 +53,10 @@ static const WCHAR initial_mode_keyW[] = {'I','n','i','t','i','a','l',' ','D','i ' ','M','o','d','e'}; static const WCHAR pixelencodingW[] = {'P','i','x','e','l','E','n','c','o','d','i','n','g',0};
-static CFArrayRef modes; -static BOOL modes_has_8bpp, modes_has_16bpp; -static int default_mode_bpp; -static pthread_mutex_t modes_mutex = PTHREAD_MUTEX_INITIALIZER; +static CFArrayRef cached_modes; +static BOOL cached_modes_has_8bpp, cached_modes_has_16bpp; +static int cached_default_mode_bpp; +static pthread_mutex_t cached_modes_mutex = PTHREAD_MUTEX_INITIALIZER;
static BOOL inited_original_display_mode;
@@ -397,20 +397,20 @@ static int get_default_bpp(void) { int ret;
- if (!default_mode_bpp) + if (!cached_default_mode_bpp) { CGDisplayModeRef mode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay); if (mode) { - default_mode_bpp = display_mode_bits_per_pixel(mode); + cached_default_mode_bpp = display_mode_bits_per_pixel(mode); CFRelease(mode); }
- if (!default_mode_bpp) - default_mode_bpp = 32; + if (!cached_default_mode_bpp) + cached_default_mode_bpp = 32; }
- ret = default_mode_bpp; + ret = cached_default_mode_bpp;
TRACE(" -> %d\n", ret); return ret; @@ -859,9 +859,9 @@ LONG macdrv_ChangeDisplaySettingsEx(LPCWSTR devname, LPDEVMODEW devmode, return DISP_CHANGE_FAILED; }
- pthread_mutex_lock(&modes_mutex); + pthread_mutex_lock(&cached_modes_mutex); bpp = get_default_bpp(); - pthread_mutex_unlock(&modes_mutex); + pthread_mutex_unlock(&cached_modes_mutex); if ((devmode->dmFields & DM_BITSPERPEL) && devmode->dmBitsPerPel != bpp) TRACE("using default %d bpp instead of caller's request %d bpp\n", bpp, devmode->dmBitsPerPel);
@@ -1012,39 +1012,39 @@ BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW devmod if (macdrv_get_displays(&displays, &num_displays)) goto failed;
- pthread_mutex_lock(&modes_mutex); + pthread_mutex_lock(&cached_modes_mutex);
- if (mode == 0 || !modes) + if (mode == 0 || !cached_modes) { - if (modes) CFRelease(modes); - modes = copy_display_modes(displays[0].displayID, (flags & EDS_RAWMODE) != 0); - modes_has_8bpp = modes_has_16bpp = FALSE; + if (cached_modes) CFRelease(cached_modes); + cached_modes = copy_display_modes(displays[0].displayID, (flags & EDS_RAWMODE) != 0); + cached_modes_has_8bpp = cached_modes_has_16bpp = FALSE;
- if (modes) + if (cached_modes) { - count = CFArrayGetCount(modes); - for (i = 0; i < count && !(modes_has_8bpp && modes_has_16bpp); i++) + count = CFArrayGetCount(cached_modes); + for (i = 0; i < count && !(cached_modes_has_8bpp && cached_modes_has_16bpp); i++) { - CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i); + CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(cached_modes, i); int bpp = display_mode_bits_per_pixel(mode); if (bpp == 8) - modes_has_8bpp = TRUE; + cached_modes_has_8bpp = TRUE; else if (bpp == 16) - modes_has_16bpp = TRUE; + cached_modes_has_16bpp = TRUE; } } }
display_mode = NULL; - if (modes) + if (cached_modes) { int default_bpp; DWORD seen_modes = 0;
- count = CFArrayGetCount(modes); + count = CFArrayGetCount(cached_modes); for (i = 0; i < count; i++) { - CGDisplayModeRef candidate = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i); + CGDisplayModeRef candidate = (CGDisplayModeRef)CFArrayGetValueAtIndex(cached_modes, i);
seen_modes++; if (seen_modes > mode) @@ -1058,10 +1058,10 @@ BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW devmod default_bpp = get_default_bpp();
/* If all the real modes are exhausted, synthesize lower bpp modes. */ - if (!display_mode && (!modes_has_16bpp || !modes_has_8bpp)) + if (!display_mode && (!cached_modes_has_16bpp || !cached_modes_has_8bpp)) { /* We want to synthesize higher depths first. */ - int synth_bpps[] = { modes_has_16bpp ? 0 : 16, modes_has_8bpp ? 0 : 8 }; + int synth_bpps[] = { cached_modes_has_16bpp ? 0 : 16, cached_modes_has_8bpp ? 0 : 8 }; size_t synth_bpp_idx; for (synth_bpp_idx = 0; synth_bpp_idx < 2; synth_bpp_idx++) { @@ -1071,7 +1071,7 @@ BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW devmod
for (i = 0; i < count; i++) { - CGDisplayModeRef candidate = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i); + CGDisplayModeRef candidate = (CGDisplayModeRef)CFArrayGetValueAtIndex(cached_modes, i); /* We only synthesize modes from those having the default bpp. */ if (display_mode_bits_per_pixel(candidate) != default_bpp) continue; @@ -1092,7 +1092,7 @@ BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW devmod } }
- pthread_mutex_unlock(&modes_mutex); + pthread_mutex_unlock(&cached_modes_mutex);
if (!display_mode) goto failed;
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/display.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 76a9d67be20..1b88db427a2 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -54,7 +54,7 @@ static const WCHAR initial_mode_keyW[] = {'I','n','i','t','i','a','l',' ','D','i static const WCHAR pixelencodingW[] = {'P','i','x','e','l','E','n','c','o','d','i','n','g',0};
static CFArrayRef cached_modes; -static BOOL cached_modes_has_8bpp, cached_modes_has_16bpp; +static BOOL cached_modes_has_8bpp, cached_modes_has_16bpp, cached_modes_flags; static int cached_default_mode_bpp; static pthread_mutex_t cached_modes_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -1014,11 +1014,12 @@ BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW devmod
pthread_mutex_lock(&cached_modes_mutex);
- if (mode == 0 || !cached_modes) + if (mode == 0 || !cached_modes || flags != cached_modes_flags) { if (cached_modes) CFRelease(cached_modes); cached_modes = copy_display_modes(displays[0].displayID, (flags & EDS_RAWMODE) != 0); cached_modes_has_8bpp = cached_modes_has_16bpp = FALSE; + cached_modes_flags = flags;
if (cached_modes) {
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/display.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 1b88db427a2..2034c8b21b4 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -46,9 +46,6 @@ struct display_mode_descriptor CFStringRef pixel_encoding; };
- -BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW devmode, DWORD flags); - static const WCHAR initial_mode_keyW[] = {'I','n','i','t','i','a','l',' ','D','i','s','p','l','a','y', ' ','M','o','d','e'}; static const WCHAR pixelencodingW[] = {'P','i','x','e','l','E','n','c','o','d','i','n','g',0};
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/display.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 2034c8b21b4..3744943f5f4 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -839,6 +839,11 @@ LONG macdrv_ChangeDisplaySettingsEx(LPCWSTR devname, LPDEVMODEW devmode, devname = primary_adapter; devmode = &default_mode; } + else if (wcsicmp(primary_adapter, devname)) + { + FIXME("Changing non-primary adapter settings is currently unsupported.\n"); + return DISP_CHANGE_SUCCESSFUL; + }
if (is_detached_mode(devmode)) { @@ -879,11 +884,6 @@ LONG macdrv_ChangeDisplaySettingsEx(LPCWSTR devname, LPDEVMODEW devmode, if (best_display_mode) { if (flags & (CDS_TEST | CDS_NORESET)) ret = DISP_CHANGE_SUCCESSFUL; - else if (wcsicmp(primary_adapter, devname)) - { - FIXME("Changing non-primary adapter settings is currently unsupported.\n"); - ret = DISP_CHANGE_SUCCESSFUL; - } else if (macdrv_set_display_mode(&displays[0], best_display_mode)) { int mode_bpp = display_mode_bits_per_pixel(best_display_mode);
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/display.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 3744943f5f4..a2114981650 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -1142,8 +1142,10 @@ failed: BOOL macdrv_GetCurrentDisplaySettings(LPCWSTR devname, LPDEVMODEW devmode) { struct macdrv_display *displays = NULL; - int num_displays; + int num_displays, display_idx; CGDisplayModeRef display_mode; + CGDirectDisplayID display_id; + WCHAR *end;
TRACE("%s, %p + %hu\n", debugstr_w(devname), devmode, devmode->dmSize);
@@ -1152,17 +1154,24 @@ BOOL macdrv_GetCurrentDisplaySettings(LPCWSTR devname, LPDEVMODEW devmode) if (macdrv_get_displays(&displays, &num_displays)) return FALSE;
- display_mode = CGDisplayCopyDisplayMode(displays[0].displayID); + display_idx = wcstol(devname + 11, &end, 10) - 1; + if (display_idx >= num_displays) + { + macdrv_free_displays(displays); + return FALSE; + } + + display_id = displays[display_idx].displayID; + display_mode = CGDisplayCopyDisplayMode(display_id);
- /* We currently only report modes for the primary display, so it's at (0, 0). */ - devmode->dmPosition.x = 0; - devmode->dmPosition.y = 0; + devmode->dmPosition.x = CGRectGetMinX(displays[display_idx].frame); + devmode->dmPosition.y = CGRectGetMinY(displays[display_idx].frame); devmode->dmFields |= DM_POSITION;
- display_mode_to_devmode(displays[0].displayID, display_mode, devmode); + display_mode_to_devmode(display_id, display_mode, devmode); if (retina_enabled) { - struct display_mode_descriptor *desc = create_original_display_mode_descriptor(displays[0].displayID); + struct display_mode_descriptor *desc = create_original_display_mode_descriptor(display_id); if (display_mode_matches_descriptor(display_mode, desc)) { devmode->dmPelsWidth *= 2; @@ -1174,7 +1183,8 @@ BOOL macdrv_GetCurrentDisplaySettings(LPCWSTR devname, LPDEVMODEW devmode) CFRelease(display_mode); macdrv_free_displays(displays);
- TRACE("current mode -- %dx%dx%dbpp @%d Hz", + TRACE("current mode -- %dx%d-%dx%dx%dbpp @%d Hz", + devmode->dmPosition.x, devmode->dmPosition.y, devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmBitsPerPel, devmode->dmDisplayFrequency); if (devmode->dmDisplayOrientation)
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/display.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index a2114981650..d1626478a4c 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -51,6 +51,7 @@ static const WCHAR initial_mode_keyW[] = {'I','n','i','t','i','a','l',' ','D','i static const WCHAR pixelencodingW[] = {'P','i','x','e','l','E','n','c','o','d','i','n','g',0};
static CFArrayRef cached_modes; +static CGDirectDisplayID cached_modes_display_id; static BOOL cached_modes_has_8bpp, cached_modes_has_16bpp, cached_modes_flags; static int cached_default_mode_bpp; static pthread_mutex_t cached_modes_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -998,9 +999,11 @@ BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW devmod struct macdrv_display *displays = NULL; int num_displays; CGDisplayModeRef display_mode; - int display_mode_bpp; + int display_mode_bpp, display_idx; BOOL synthesized = FALSE; + CGDirectDisplayID display_id; DWORD count, i; + WCHAR *end;
TRACE("%s, %u, %p + %hu, %08x\n", debugstr_w(devname), mode, devmode, devmode->dmSize, flags);
@@ -1009,13 +1012,23 @@ BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW devmod if (macdrv_get_displays(&displays, &num_displays)) goto failed;
+ display_idx = wcstol(devname + 11, &end, 10) - 1; + if (display_idx >= num_displays) + { + macdrv_free_displays(displays); + return FALSE; + } + + display_id = displays[display_idx].displayID; + pthread_mutex_lock(&cached_modes_mutex);
- if (mode == 0 || !cached_modes || flags != cached_modes_flags) + if (mode == 0 || !cached_modes || flags != cached_modes_flags || display_id != cached_modes_display_id) { if (cached_modes) CFRelease(cached_modes); - cached_modes = copy_display_modes(displays[0].displayID, (flags & EDS_RAWMODE) != 0); + cached_modes = copy_display_modes(display_id, (flags & EDS_RAWMODE) != 0); cached_modes_has_8bpp = cached_modes_has_16bpp = FALSE; + cached_modes_display_id = display_id; cached_modes_flags = flags;
if (cached_modes) @@ -1095,13 +1108,13 @@ BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW devmod if (!display_mode) goto failed;
- display_mode_to_devmode(displays[0].displayID, display_mode, devmode); + display_mode_to_devmode(display_id, display_mode, devmode); devmode->dmBitsPerPel = display_mode_bpp; if (devmode->dmBitsPerPel) devmode->dmFields |= DM_BITSPERPEL; if (retina_enabled) { - struct display_mode_descriptor* desc = create_original_display_mode_descriptor(displays[0].displayID); + struct display_mode_descriptor* desc = create_original_display_mode_descriptor(display_id); if (display_mode_matches_descriptor(display_mode, desc)) { devmode->dmPelsWidth *= 2;
On Tue Aug 30 10:08:54 2022 +0000, R��mi Bernon wrote:
changed this line in [version 4 of the diff](/wine/wine/-/merge_requests/720/diffs?diff_id=9088&start_sha=9098926bd3f5e12519e15416806d6ae020ef4096#d1968e8c429ee8f293c300a3b265157c4161beb0_1158_1158)
Thanks for looking into it.
Zhiyi Zhang (@zhiyi) commented about dlls/winemac.drv/display.c:
static const WCHAR pixelencodingW[] = {'P','i','x','e','l','E','n','c','o','d','i','n','g',0};
static CFArrayRef cached_modes; -static BOOL cached_modes_has_8bpp, cached_modes_has_16bpp; +static BOOL cached_modes_has_8bpp, cached_modes_has_16bpp, cached_modes_flags;
cached_modes_flags should be of type DWORD.