From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 84 +++++++++++++-------------- dlls/wineandroid.drv/init.c | 8 ++- dlls/winemac.drv/display.c | 39 +------------ dlls/winewayland.drv/display.c | 22 ++++--- dlls/winewayland.drv/wayland_output.c | 4 ++ dlls/winewayland.drv/waylanddrv.h | 1 + dlls/winex11.drv/display.c | 41 ++----------- include/wine/gdi_driver.h | 2 +- 8 files changed, 71 insertions(+), 130 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 4bcc9109bf0..e88d775f6cb 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -416,6 +416,18 @@ static void get_monitor_info_from_edid( struct edid_monitor_info *info, const un } }
+static const char *debugstr_devmodew( const DEVMODEW *devmode ) +{ + char position[32] = {0}; + if (devmode->dmFields & DM_POSITION) snprintf( position, sizeof(position), " at %s", wine_dbgstr_point( (POINT *)&devmode->dmPosition ) ); + return wine_dbg_sprintf( "%ux%u %ubits %uHz rotated %u degrees %sstretched %sinterlaced%s", + (UINT)devmode->dmPelsWidth, (UINT)devmode->dmPelsHeight, (UINT)devmode->dmBitsPerPel, + (UINT)devmode->dmDisplayFrequency, (UINT)devmode->dmDisplayOrientation * 90, + devmode->dmDisplayFixedOutput == DMDFO_STRETCH ? "" : "un", + devmode->dmDisplayFlags & DM_INTERLACED ? "" : "non-", + position ); +} + static BOOL write_source_mode( HKEY hkey, UINT index, const DEVMODEW *mode ) { WCHAR bufferW[MAX_PATH] = {0}; @@ -1430,27 +1442,24 @@ static void add_monitor( const struct gdi_monitor *gdi_monitor, void *param ) } }
-static void add_mode( const DEVMODEW *mode, BOOL current, void *param ) +static void add_modes( const DEVMODEW *current, UINT modes_count, const DEVMODEW *modes, void *param ) { struct device_manager_ctx *ctx = param; - DEVMODEW nopos_mode; + const DEVMODEW *mode; + DEVMODEW dummy;
- nopos_mode = *mode; - nopos_mode.dmPosition.x = 0; - nopos_mode.dmPosition.y = 0; - nopos_mode.dmFields &= ~DM_POSITION; + TRACE( "current %s, modes_count %u, modes %p, param %p\n", debugstr_devmodew( current ), modes_count, modes, param );
- if (write_source_mode( ctx->source_key, ctx->source.mode_count, &nopos_mode )) + if (!read_source_mode( ctx->source_key, ENUM_REGISTRY_SETTINGS, &dummy )) + write_source_mode( ctx->source_key, ENUM_REGISTRY_SETTINGS, current ); + write_source_mode( ctx->source_key, ENUM_CURRENT_SETTINGS, current ); + + for (mode = modes; modes_count; mode = NEXT_DEVMODEW(mode), modes_count--) { - ctx->source.mode_count++; - set_reg_value( ctx->source_key, mode_countW, REG_DWORD, &ctx->source.mode_count, sizeof(ctx->source.mode_count) ); - if (current) - { - if (!read_source_mode( ctx->source_key, ENUM_REGISTRY_SETTINGS, &nopos_mode )) - write_source_mode( ctx->source_key, ENUM_REGISTRY_SETTINGS, mode ); - write_source_mode( ctx->source_key, ENUM_CURRENT_SETTINGS, mode ); - } + TRACE( "mode: %s\n", debugstr_devmodew( mode ) ); + if (write_source_mode( ctx->source_key, ctx->source.mode_count, mode )) ctx->source.mode_count++; } + set_reg_value( ctx->source_key, mode_countW, REG_DWORD, &ctx->source.mode_count, sizeof(ctx->source.mode_count) ); }
static const struct gdi_device_manager device_manager = @@ -1458,7 +1467,7 @@ static const struct gdi_device_manager device_manager = add_gpu, add_source, add_monitor, - add_mode, + add_modes, };
static void reset_display_manager_ctx( struct device_manager_ctx *ctx ) @@ -1709,15 +1718,6 @@ static BOOL update_display_cache_from_registry(void) return ret; }
-static BOOL is_same_devmode( const DEVMODEW *a, const DEVMODEW *b ) -{ - return a->dmDisplayOrientation == b->dmDisplayOrientation && - a->dmBitsPerPel == b->dmBitsPerPel && - a->dmPelsWidth == b->dmPelsWidth && - a->dmPelsHeight == b->dmPelsHeight && - a->dmDisplayFrequency == b->dmDisplayFrequency; -} - static BOOL default_update_display_devices( const struct gdi_device_manager *manager, BOOL force, struct device_manager_ctx *ctx ) { /* default implementation: expose an adapter and a monitor with a few standard modes, @@ -1742,7 +1742,6 @@ static BOOL default_update_display_devices( const struct gdi_device_manager *man static const struct gdi_gpu gpu; struct gdi_monitor monitor = {0}; DEVMODEW mode = {{0}}; - UINT i;
if (!force) return TRUE;
@@ -1760,11 +1759,7 @@ static BOOL default_update_display_devices( const struct gdi_device_manager *man monitor.rc_work.bottom = mode.dmPelsHeight;
manager->add_monitor( &monitor, ctx ); - for (i = 0; i < ARRAY_SIZE(modes); ++i) - { - if (is_same_devmode( modes + i, &mode )) manager->add_mode( &mode, TRUE, ctx ); - else manager->add_mode( modes + i, FALSE, ctx ); - } + manager->add_modes( &mode, ARRAY_SIZE(modes), modes, ctx );
return TRUE; } @@ -1821,10 +1816,10 @@ static void desktop_add_monitor( const struct gdi_monitor *monitor, void *param { }
-static void desktop_add_mode( const DEVMODEW *mode, BOOL current, void *param ) +static void desktop_add_modes( const DEVMODEW *current, UINT modes_count, const DEVMODEW *modes, void *param ) { struct device_manager_ctx *ctx = param; - if (ctx->is_primary && current) ctx->primary = *mode; + if (ctx->is_primary) ctx->primary = *current; }
static const struct gdi_device_manager desktop_device_manager = @@ -1832,7 +1827,7 @@ static const struct gdi_device_manager desktop_device_manager = desktop_add_gpu, desktop_add_source, desktop_add_monitor, - desktop_add_mode, + desktop_add_modes, };
static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ctx *ctx ) @@ -1879,9 +1874,9 @@ static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ct };
struct device_manager_ctx desktop_ctx = {0}; - UINT screen_width, screen_height, max_width, max_height; + UINT screen_width, screen_height, max_width, max_height, modes_count; unsigned int depths[] = {8, 16, 0}; - DEVMODEW current; + DEVMODEW current, *modes; UINT i, j;
if (!force) return TRUE; @@ -1913,7 +1908,9 @@ static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ct monitor.rc_work.bottom = current.dmPelsHeight; add_monitor( &monitor, ctx );
- for (i = 0; i < ARRAY_SIZE(depths); ++i) + if (!(modes = malloc( ARRAY_SIZE(depths) * (ARRAY_SIZE(screen_sizes) + 2) * sizeof(*modes) ))) return FALSE; + + for (modes_count = i = 0; i < ARRAY_SIZE(depths); ++i) { DEVMODEW mode = { @@ -1930,25 +1927,24 @@ static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ct if (mode.dmPelsWidth > max_width || mode.dmPelsHeight > max_height) continue; if (mode.dmPelsWidth == max_width && mode.dmPelsHeight == max_height) continue; if (mode.dmPelsWidth == screen_width && mode.dmPelsHeight == screen_height) continue; - - if (is_same_devmode( &mode, ¤t )) add_mode( ¤t, TRUE, ctx ); - else add_mode( &mode, FALSE, ctx ); + modes[modes_count++] = mode; }
mode.dmPelsWidth = screen_width; mode.dmPelsHeight = screen_height; - if (is_same_devmode( &mode, ¤t )) add_mode( ¤t, TRUE, ctx ); - else add_mode( &mode, FALSE, ctx ); + modes[modes_count++] = mode;
if (max_width != screen_width || max_height != screen_height) { mode.dmPelsWidth = max_width; mode.dmPelsHeight = max_height; - if (is_same_devmode( &mode, ¤t )) add_mode( ¤t, TRUE, ctx ); - else add_mode( &mode, FALSE, ctx ); + modes[modes_count++] = mode; } }
+ add_modes( ¤t, modes_count, modes, ctx ); + free( modes ); + return TRUE; }
diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index f8646378627..d1894535bfb 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -283,13 +283,17 @@ BOOL ANDROID_UpdateDisplayDevices( const struct gdi_device_manager *device_manag const DEVMODEW mode = { .dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | - DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY | DM_POSITION, + DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, .dmBitsPerPel = screen_bpp, .dmPelsWidth = screen_width, .dmPelsHeight = screen_height, .dmDisplayFrequency = 60, }; + DEVMODEW current = mode; + device_manager->add_gpu( &gpu, param ); device_manager->add_source( "Default", source_flags, param ); device_manager->add_monitor( &gdi_monitor, param ); - device_manager->add_mode( &mode, TRUE, param ); + + current.dmFields |= DM_POSITION; + device_manager->add_modes( ¤t, 1, &mode, param ); force_display_devices_refresh = FALSE; }
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index ea9b5771064..5221f4402fa 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -1110,27 +1110,6 @@ static BOOL is_same_devmode(const DEVMODEW *a, const DEVMODEW *b) a->dmDisplayFrequency == b->dmDisplayFrequency; }
-static const char *debugstr_devmodew(const DEVMODEW *devmode) -{ - char position[32] = {0}; - - if (devmode->dmFields & DM_POSITION) - { - snprintf(position, sizeof(position), " at (%d,%d)", - (int)devmode->dmPosition.x, (int)devmode->dmPosition.y); - } - - return wine_dbg_sprintf("%ux%u %ubits %uHz rotated %u degrees %sstretched %sinterlaced%s", - (unsigned int)devmode->dmPelsWidth, - (unsigned int)devmode->dmPelsHeight, - (unsigned int)devmode->dmBitsPerPel, - (unsigned int)devmode->dmDisplayFrequency, - (unsigned int)devmode->dmDisplayOrientation * 90, - devmode->dmDisplayFixedOutput == DMDFO_STRETCH ? "" : "un", - devmode->dmDisplayFlags & DM_INTERLACED ? "" : "non-", - position); -} - BOOL macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, BOOL force, void *param ) { struct macdrv_adapter *adapters, *adapter; @@ -1211,23 +1190,7 @@ BOOL macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manage }
if (!(modes = display_get_modes(adapter->id, &mode_count))) break; - TRACE("adapter: %#x, mode count: %d\n", adapter->id, mode_count); - - /* Initialize modes */ - for (mode = modes; mode < modes + mode_count; mode++) - { - if (is_same_devmode(mode, ¤t_mode)) - { - TRACE("current mode: %s\n", debugstr_devmodew(¤t_mode)); - device_manager->add_mode( ¤t_mode, TRUE, param ); - } - else - { - TRACE("mode: %s\n", debugstr_devmodew(mode)); - device_manager->add_mode( mode, FALSE, param ); - } - } - + device_manager->add_modes( ¤t_mode, mode_count, modes, param ); free(modes); macdrv_free_monitors(monitors); } diff --git a/dlls/winewayland.drv/display.c b/dlls/winewayland.drv/display.c index 37f2a97d3b4..535a3c80ce3 100644 --- a/dlls/winewayland.drv/display.c +++ b/dlls/winewayland.drv/display.c @@ -251,22 +251,28 @@ static void populate_devmode(struct wayland_output_mode *output_mode, DEVMODEW * static void wayland_add_device_modes(const struct gdi_device_manager *device_manager, void *param, struct output_info *output_info) { + DEVMODEW *modes, current = {.dmSize = sizeof(current)}; struct wayland_output_mode *output_mode; + int modes_count = 0; + + if (!(modes = malloc(output_info->output->modes_count * sizeof(*modes)))) + return; + + populate_devmode(output_info->output->current_mode, ¤t); + current.dmFields |= DM_POSITION; + current.dmPosition.x = output_info->x; + current.dmPosition.y = output_info->y;
RB_FOR_EACH_ENTRY(output_mode, &output_info->output->modes, struct wayland_output_mode, entry) { DEVMODEW mode = {.dmSize = sizeof(mode)}; - BOOL mode_is_current = output_mode == output_info->output->current_mode; populate_devmode(output_mode, &mode); - if (mode_is_current) - { - mode.dmFields |= DM_POSITION; - mode.dmPosition.x = output_info->x; - mode.dmPosition.y = output_info->y; - } - device_manager->add_mode(&mode, mode_is_current, param); + modes[modes_count++] = mode; } + + device_manager->add_modes(¤t, modes_count, modes, param); + free(modes); }
/*********************************************************************** diff --git a/dlls/winewayland.drv/wayland_output.c b/dlls/winewayland.drv/wayland_output.c index f5941c10f6f..f76881a1770 100644 --- a/dlls/winewayland.drv/wayland_output.c +++ b/dlls/winewayland.drv/wayland_output.c @@ -97,6 +97,7 @@ static void wayland_output_state_add_mode(struct wayland_output_state *state, mode->height = height; mode->refresh = refresh; rb_put(&state->modes, mode, &mode->entry); + state->modes_count++; }
if (current) state->current_mode = mode; @@ -144,6 +145,7 @@ static void wayland_output_done(struct wayland_output *output) } rb_destroy(&output->pending.modes, wayland_output_mode_free_rb, NULL); rb_init(&output->pending.modes, wayland_output_mode_cmp_rb); + output->pending.modes_count = 0; }
if (output->pending_flags & WAYLAND_OUTPUT_CHANGED_NAME) @@ -321,7 +323,9 @@ BOOL wayland_output_create(uint32_t id, uint32_t version)
wl_list_init(&output->link); rb_init(&output->pending.modes, wayland_output_mode_cmp_rb); + output->pending.modes_count = 0; rb_init(&output->current.modes, wayland_output_mode_cmp_rb); + output->current.modes_count = 0;
/* Have a fallback while we don't have compositor given name. */ name_len = snprintf(NULL, 0, "WaylandOutput%d", next_output_id); diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index d6359e57db3..6811b34ab1a 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -142,6 +142,7 @@ struct wayland_output_mode
struct wayland_output_state { + int modes_count; struct rb_tree modes; struct wayland_output_mode *current_mode; char *name; diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 5dfbd1b797d..b4a2e4b9487 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -494,25 +494,6 @@ BOOL X11DRV_DisplayDevices_SupportEventHandlers(void)
static BOOL force_display_devices_refresh;
-static const char *debugstr_devmodew( const DEVMODEW *devmode ) -{ - char position[32] = {0}; - - if (devmode->dmFields & DM_POSITION) - { - snprintf( position, sizeof(position), " at (%d,%d)", - (int)devmode->dmPosition.x, (int)devmode->dmPosition.y ); - } - - return wine_dbg_sprintf( "%ux%u %ubits %uHz rotated %u degrees%s", - (unsigned int)devmode->dmPelsWidth, - (unsigned int)devmode->dmPelsHeight, - (unsigned int)devmode->dmBitsPerPel, - (unsigned int)devmode->dmDisplayFrequency, - (unsigned int)devmode->dmDisplayOrientation * 90, - position ); -} - BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, BOOL force, void *param ) { struct x11drv_adapter *adapters; @@ -520,7 +501,7 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage struct gdi_gpu *gpus; INT gpu_count, adapter_count, monitor_count; INT gpu, adapter, monitor; - DEVMODEW *modes, *mode; + DEVMODEW *modes; UINT mode_count;
if (!force && !force_display_devices_refresh) return TRUE; @@ -566,25 +547,11 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage if (!settings_handler.get_id( devname, is_primary, &settings_id )) break;
settings_handler.get_current_mode( settings_id, ¤t_mode ); - if (!settings_handler.get_modes( settings_id, EDS_ROTATEDMODE, &modes, &mode_count )) - continue; - - for (mode = modes; mode_count; mode_count--) + if (settings_handler.get_modes( settings_id, EDS_ROTATEDMODE, &modes, &mode_count )) { - if (is_same_devmode( mode, ¤t_mode )) - { - TRACE( "current mode: %s\n", debugstr_devmodew( ¤t_mode ) ); - device_manager->add_mode( ¤t_mode, TRUE, param ); - } - else - { - TRACE( "mode: %s\n", debugstr_devmodew( mode ) ); - device_manager->add_mode( mode, FALSE, param ); - } - mode = (DEVMODEW *)((char *)mode + sizeof(*modes) + modes[0].dmDriverExtra); + device_manager->add_modes( ¤t_mode, mode_count, modes, param ); + settings_handler.free_modes( modes ); } - - settings_handler.free_modes( modes ); }
host_handler.free_adapters( adapters ); diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 7827cd3a605..3b85f03abed 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -262,7 +262,7 @@ struct gdi_device_manager void (*add_gpu)( const struct gdi_gpu *gpu, void *param ); void (*add_source)( const char *name, UINT state_flags, void *param ); void (*add_monitor)( const struct gdi_monitor *monitor, void *param ); - void (*add_mode)( const DEVMODEW *mode, BOOL current, void *param ); + void (*add_modes)( const DEVMODEW *current, UINT modes_count, const DEVMODEW *modes, void *param ); };
#define WINE_DM_UNSUPPORTED 0x80000000