From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index f58bfe14ca2..ed75e1a2f00 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1569,6 +1569,13 @@ static void add_monitor( const struct gdi_monitor *gdi_monitor, void *param ) } }
+static UINT add_virtual_mode( DEVMODEW *modes, UINT count, const DEVMODEW *mode ) +{ + TRACE( "adding mode %s\n", debugstr_devmodew(mode) ); + modes[count] = *mode; + return 1; +} + static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *initial, const DEVMODEW *maximum, UINT32 *modes_count ) { @@ -1639,18 +1646,18 @@ static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *ini if (mode.dmPelsWidth > maximum->dmPelsWidth || mode.dmPelsHeight > maximum->dmPelsHeight) continue; if (mode.dmPelsWidth == maximum->dmPelsWidth && mode.dmPelsHeight == maximum->dmPelsHeight) continue; if (mode.dmPelsWidth == initial->dmPelsWidth && mode.dmPelsHeight == initial->dmPelsHeight) continue; - modes[count++] = mode; + count += add_virtual_mode( modes, count, &mode ); }
mode.dmPelsWidth = vertical ? initial->dmPelsHeight : initial->dmPelsWidth; mode.dmPelsHeight = vertical ? initial->dmPelsWidth : initial->dmPelsHeight; - modes[count++] = mode; + count += add_virtual_mode( modes, count, &mode );
if (maximum->dmPelsWidth != initial->dmPelsWidth || maximum->dmPelsHeight != initial->dmPelsHeight) { mode.dmPelsWidth = vertical ? maximum->dmPelsHeight : maximum->dmPelsWidth; mode.dmPelsHeight = vertical ? maximum->dmPelsWidth : maximum->dmPelsHeight; - modes[count++] = mode; + count += add_virtual_mode( modes, count, &mode ); } }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index ed75e1a2f00..5633cec839c 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1576,8 +1576,8 @@ static UINT add_virtual_mode( DEVMODEW *modes, UINT count, const DEVMODEW *mode return 1; }
-static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *initial, - const DEVMODEW *maximum, UINT32 *modes_count ) +static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *initial, const DEVMODEW *maximum, + const DEVMODEW *host_modes, UINT host_modes_count, UINT32 *modes_count ) { static struct screen_size { @@ -1665,14 +1665,16 @@ static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *ini return modes; }
-static void add_modes( const DEVMODEW *current, UINT modes_count, const DEVMODEW *modes, void *param ) +static void add_modes( const DEVMODEW *current, UINT host_modes_count, const DEVMODEW *host_modes, void *param ) { struct device_manager_ctx *ctx = param; DEVMODEW dummy, physical, detached = *current, virtual, *virtual_modes = NULL; + UINT virtual_count, modes_count = host_modes_count; + const DEVMODEW *modes = host_modes; struct source *source; - UINT virtual_count;
- TRACE( "current %s, modes_count %u, modes %p, param %p\n", debugstr_devmodew( current ), modes_count, modes, param ); + TRACE( "current %s, host_modes_count %u, host_modes %p, param %p\n", debugstr_devmodew( current ), + host_modes_count, host_modes, param );
assert( !list_empty( &sources ) ); source = LIST_ENTRY( list_tail( &sources ), struct source, entry ); @@ -1700,7 +1702,7 @@ static void add_modes( const DEVMODEW *current, UINT modes_count, const DEVMODEW if (!read_source_mode( source->key, ENUM_CURRENT_SETTINGS, &virtual )) virtual = physical;
- if ((virtual_modes = get_virtual_modes( &virtual, current, &physical, &virtual_count ))) + if ((virtual_modes = get_virtual_modes( &virtual, current, &physical, host_modes, host_modes_count, &virtual_count ))) { modes_count = virtual_count; modes = virtual_modes; @@ -2217,7 +2219,7 @@ static BOOL add_virtual_source( struct device_manager_ctx *ctx ) add_monitor( &monitor, ctx );
/* Expose the virtual source display modes as physical modes, to avoid DPI scaling */ - if (!(modes = get_virtual_modes( ¤t, &initial, &maximum, &modes_count ))) return STATUS_NO_MEMORY; + if (!(modes = get_virtual_modes( ¤t, &initial, &maximum, NULL, 0, &modes_count ))) return STATUS_NO_MEMORY; add_modes( ¤t, modes_count, modes, ctx ); free( modes );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 5633cec839c..0fe65397cb3 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1579,11 +1579,8 @@ static UINT add_virtual_mode( DEVMODEW *modes, UINT count, const DEVMODEW *mode static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *initial, const DEVMODEW *maximum, const DEVMODEW *host_modes, UINT host_modes_count, UINT32 *modes_count ) { - static struct screen_size + static SIZE screen_sizes[] = { - unsigned int width; - unsigned int height; - } screen_sizes[] = { /* 4:3 */ { 320, 240}, { 400, 300}, @@ -1616,7 +1613,7 @@ static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *ini {1920, 1200}, {2560, 1600} }; - UINT depths[] = {8, 16, initial->dmBitsPerPel}, i, j, count; + UINT depths[] = {8, 16, initial->dmBitsPerPel}, i, j, count = 0; BOOL vertical; DEVMODEW *modes;
@@ -1627,7 +1624,7 @@ static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *ini
modes = malloc( ARRAY_SIZE(depths) * (ARRAY_SIZE(screen_sizes) + 2) * sizeof(*modes) );
- for (count = i = 0; modes && i < ARRAY_SIZE(depths); ++i) + for (i = 0; modes && i < ARRAY_SIZE(depths); ++i) { DEVMODEW mode = { @@ -1640,8 +1637,8 @@ static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *ini
for (j = 0; j < ARRAY_SIZE(screen_sizes); ++j) { - mode.dmPelsWidth = vertical ? screen_sizes[j].height : screen_sizes[j].width; - mode.dmPelsHeight = vertical ? screen_sizes[j].width : screen_sizes[j].height; + mode.dmPelsWidth = vertical ? screen_sizes[j].cy : screen_sizes[j].cx; + mode.dmPelsHeight = vertical ? screen_sizes[j].cx : screen_sizes[j].cy;
if (mode.dmPelsWidth > maximum->dmPelsWidth || mode.dmPelsHeight > maximum->dmPelsHeight) continue; if (mode.dmPelsWidth == maximum->dmPelsWidth && mode.dmPelsHeight == maximum->dmPelsHeight) continue;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 0fe65397cb3..e4e519878eb 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1576,10 +1576,10 @@ static UINT add_virtual_mode( DEVMODEW *modes, UINT count, const DEVMODEW *mode return 1; }
-static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *initial, const DEVMODEW *maximum, - const DEVMODEW *host_modes, UINT host_modes_count, UINT32 *modes_count ) +static SIZE *get_screen_sizes( const DEVMODEW *maximum, const DEVMODEW *modes, UINT modes_count, + UINT *sizes_count ) { - static SIZE screen_sizes[] = + static SIZE default_sizes[] = { /* 4:3 */ { 320, 240}, @@ -1611,18 +1611,34 @@ static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *ini {1440, 900}, {1680, 1050}, {1920, 1200}, - {2560, 1600} + {2560, 1600}, }; - UINT depths[] = {8, 16, initial->dmBitsPerPel}, i, j, count = 0; + SIZE *sizes; + UINT count; + + count = ARRAY_SIZE(default_sizes); + if (!(sizes = malloc( count * sizeof(*sizes) ))) return NULL; + memcpy( sizes, default_sizes, count * sizeof(*sizes) ); + + *sizes_count = count; + return sizes; +} + +static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *initial, const DEVMODEW *maximum, + const DEVMODEW *host_modes, UINT host_modes_count, UINT32 *modes_count ) +{ + UINT depths[] = {8, 16, initial->dmBitsPerPel}, sizes_count, i, j, count = 0; + DEVMODEW *modes = NULL; + SIZE *screen_sizes; BOOL vertical; - DEVMODEW *modes;
/* Check the ratio of dmPelsWidth to dmPelsHeight to determine whether the initial display mode * is in horizontal or vertical orientation. DMDO_DEFAULT is the natural orientation of the * device, which isn't necessarily a horizontal mode */ vertical = initial->dmPelsHeight > initial->dmPelsWidth;
- modes = malloc( ARRAY_SIZE(depths) * (ARRAY_SIZE(screen_sizes) + 2) * sizeof(*modes) ); + if (!(screen_sizes = get_screen_sizes( maximum, host_modes, host_modes_count, &sizes_count ))) return NULL; + modes = malloc( ARRAY_SIZE(depths) * (sizes_count + 2) * sizeof(*modes) );
for (i = 0; modes && i < ARRAY_SIZE(depths); ++i) { @@ -1635,7 +1651,7 @@ static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *ini .dmDisplayOrientation = initial->dmDisplayOrientation, };
- for (j = 0; j < ARRAY_SIZE(screen_sizes); ++j) + for (j = 0; j < sizes_count; ++j) { mode.dmPelsWidth = vertical ? screen_sizes[j].cy : screen_sizes[j].cx; mode.dmPelsHeight = vertical ? screen_sizes[j].cx : screen_sizes[j].cy; @@ -1659,6 +1675,7 @@ static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *ini }
*modes_count = count; + free( screen_sizes ); return modes; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 42 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index e4e519878eb..c41e4507093 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -451,6 +451,21 @@ static const char *debugstr_devmodew( const DEVMODEW *devmode ) position ); }
+static UINT devmode_get( const DEVMODEW *mode, UINT field ) +{ + switch (field) + { + case DM_DISPLAYORIENTATION: return mode->dmFields & DM_DISPLAYORIENTATION ? mode->dmDisplayOrientation : 0; + case DM_BITSPERPEL: return mode->dmFields & DM_BITSPERPEL ? mode->dmBitsPerPel : 0; + case DM_PELSWIDTH: return mode->dmFields & DM_PELSWIDTH ? mode->dmPelsWidth : 0; + case DM_PELSHEIGHT: return mode->dmFields & DM_PELSHEIGHT ? mode->dmPelsHeight : 0; + case DM_DISPLAYFLAGS: return mode->dmFields & DM_DISPLAYFLAGS ? mode->dmDisplayFlags : 0; + case DM_DISPLAYFREQUENCY: return mode->dmFields & DM_DISPLAYFREQUENCY ? mode->dmDisplayFrequency : 0; + case DM_DISPLAYFIXEDOUTPUT: return mode->dmFields & DM_DISPLAYFIXEDOUTPUT ? mode->dmDisplayFixedOutput : 0; + } + return 0; +} + static BOOL write_source_mode( HKEY hkey, UINT index, const DEVMODEW *mode ) { WCHAR bufferW[MAX_PATH] = {0}; @@ -1569,6 +1584,18 @@ static void add_monitor( const struct gdi_monitor *gdi_monitor, void *param ) } }
+static UINT add_screen_size( SIZE *sizes, UINT count, SIZE size ) +{ + UINT i = 0; + + while (i < count && memcmp( sizes + i, &size, sizeof(size) )) i++; + if (i < count) return 0; + + TRACE( "adding size %s\n", wine_dbgstr_point((POINT *)&size) ); + sizes[i] = size; + return 1; +} + static UINT add_virtual_mode( DEVMODEW *modes, UINT count, const DEVMODEW *mode ) { TRACE( "adding mode %s\n", debugstr_devmodew(mode) ); @@ -1613,12 +1640,19 @@ static SIZE *get_screen_sizes( const DEVMODEW *maximum, const DEVMODEW *modes, U {1920, 1200}, {2560, 1600}, }; - SIZE *sizes; - UINT count; + UINT max_width = devmode_get( maximum, DM_PELSWIDTH ), max_height = devmode_get( maximum, DM_PELSHEIGHT ); + SIZE *sizes, max_size = {.cx = max( max_width, max_height ), .cy = min( max_width, max_height )}; + UINT i, count;
- count = ARRAY_SIZE(default_sizes); + count = 1 + ARRAY_SIZE(default_sizes) + modes_count; if (!(sizes = malloc( count * sizeof(*sizes) ))) return NULL; - memcpy( sizes, default_sizes, count * sizeof(*sizes) ); + + count = add_screen_size( sizes, 0, max_size ); + for (i = 0; i < ARRAY_SIZE(default_sizes); i++) + { + if (default_sizes[i].cx > max_size.cx || default_sizes[i].cy > max_size.cy) continue; + count += add_screen_size( sizes, count, default_sizes[i] ); + }
*sizes_count = count; return sizes;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index c41e4507093..560127ed00b 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1609,39 +1609,39 @@ static SIZE *get_screen_sizes( const DEVMODEW *maximum, const DEVMODEW *modes, U static SIZE default_sizes[] = { /* 4:3 */ - { 320, 240}, - { 400, 300}, - { 512, 384}, { 640, 480}, - { 768, 576}, { 800, 600}, {1024, 768}, - {1152, 864}, - {1280, 960}, - {1400, 1050}, {1600, 1200}, - {2048, 1536}, - /* 5:4 */ - {1280, 1024}, - {2560, 2048}, /* 16:9 */ + { 960, 540}, {1280, 720}, - {1366, 768}, {1600, 900}, {1920, 1080}, {2560, 1440}, - {3840, 2160}, + {2880, 1620}, + {3200, 1800}, /* 16:10 */ - { 320, 200}, - { 640, 400}, - {1280, 800}, {1440, 900}, {1680, 1050}, {1920, 1200}, {2560, 1600}, + /* 3:2 */ + {1440, 960}, + {1920, 1280}, + /* 21:9 ultra-wide */ + {2560, 1080}, + /* 12:5 */ + {1920, 800}, + {3840, 1600}, + /* 5:4 */ + {1280, 1024}, + /* 5:3 */ + {1280, 768}, }; UINT max_width = devmode_get( maximum, DM_PELSWIDTH ), max_height = devmode_get( maximum, DM_PELSHEIGHT ); SIZE *sizes, max_size = {.cx = max( max_width, max_height ), .cy = min( max_width, max_height )}; + const DEVMODEW *mode; UINT i, count;
count = 1 + ARRAY_SIZE(default_sizes) + modes_count; @@ -1654,6 +1654,15 @@ static SIZE *get_screen_sizes( const DEVMODEW *maximum, const DEVMODEW *modes, U count += add_screen_size( sizes, count, default_sizes[i] ); }
+ for (mode = modes; mode && modes_count; mode = NEXT_DEVMODEW(mode), modes_count--) + { + UINT width = devmode_get( mode, DM_PELSWIDTH ), height = devmode_get( mode, DM_PELSHEIGHT ); + SIZE size = {.cx = max( width, height ), .cy = min( width, height )}; + if (!size.cx || size.cx > max_size.cx) continue; + if (!size.cy || size.cy > max_size.cy) continue; + count += add_screen_size( sizes, count, size ); + } + *sizes_count = count; return sizes; }
From: Rémi Bernon rbernon@codeweavers.com
In addition to 60Hz modes. --- dlls/win32u/sysparams.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 560127ed00b..10be29df62d 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1670,7 +1670,7 @@ static SIZE *get_screen_sizes( const DEVMODEW *maximum, const DEVMODEW *modes, U static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *initial, const DEVMODEW *maximum, const DEVMODEW *host_modes, UINT host_modes_count, UINT32 *modes_count ) { - UINT depths[] = {8, 16, initial->dmBitsPerPel}, sizes_count, i, j, count = 0; + UINT depths[] = {8, 16, initial->dmBitsPerPel}, freqs[] = {60, -1}, sizes_count, i, j, f, count = 0; DEVMODEW *modes = NULL; SIZE *screen_sizes; BOOL vertical; @@ -1680,19 +1680,24 @@ static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *ini * device, which isn't necessarily a horizontal mode */ vertical = initial->dmPelsHeight > initial->dmPelsWidth;
+ freqs[1] = devmode_get( initial, DM_DISPLAYFREQUENCY ); + if (freqs[1] <= 60) freqs[1] = 0; + if (!(screen_sizes = get_screen_sizes( maximum, host_modes, host_modes_count, &sizes_count ))) return NULL; - modes = malloc( ARRAY_SIZE(depths) * (sizes_count + 2) * sizeof(*modes) ); + modes = malloc( ARRAY_SIZE(freqs) * ARRAY_SIZE(depths) * (sizes_count + 2) * sizeof(*modes) );
for (i = 0; modes && i < ARRAY_SIZE(depths); ++i) + for (f = 0; f < ARRAY_SIZE(freqs); ++f) { DEVMODEW mode = { .dmSize = sizeof(mode), .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, - .dmDisplayFrequency = 60, + .dmDisplayFrequency = freqs[f], .dmBitsPerPel = depths[i], .dmDisplayOrientation = initial->dmDisplayOrientation, }; + if (!mode.dmDisplayFrequency) continue;
for (j = 0; j < sizes_count; ++j) {