Commit 320442a4 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

win32u: Add all display device source modes at once.

parent ee0aad5c
...@@ -416,6 +416,18 @@ static void get_monitor_info_from_edid( struct edid_monitor_info *info, const un ...@@ -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 ) static BOOL write_source_mode( HKEY hkey, UINT index, const DEVMODEW *mode )
{ {
WCHAR bufferW[MAX_PATH] = {0}; WCHAR bufferW[MAX_PATH] = {0};
...@@ -1432,27 +1444,24 @@ static void add_monitor( const struct gdi_monitor *gdi_monitor, void *param ) ...@@ -1432,27 +1444,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; struct device_manager_ctx *ctx = param;
DEVMODEW nopos_mode; const DEVMODEW *mode;
DEVMODEW dummy;
nopos_mode = *mode; TRACE( "current %s, modes_count %u, modes %p, param %p\n", debugstr_devmodew( current ), modes_count, modes, param );
nopos_mode.dmPosition.x = 0;
nopos_mode.dmPosition.y = 0;
nopos_mode.dmFields &= ~DM_POSITION;
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++; TRACE( "mode: %s\n", debugstr_devmodew( mode ) );
set_reg_value( ctx->source_key, mode_countW, REG_DWORD, &ctx->source.mode_count, sizeof(ctx->source.mode_count) ); if (write_source_mode( ctx->source_key, ctx->source.mode_count, mode )) 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 );
}
} }
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 = static const struct gdi_device_manager device_manager =
...@@ -1460,7 +1469,7 @@ static const struct gdi_device_manager device_manager = ...@@ -1460,7 +1469,7 @@ static const struct gdi_device_manager device_manager =
add_gpu, add_gpu,
add_source, add_source,
add_monitor, add_monitor,
add_mode, add_modes,
}; };
static void reset_display_manager_ctx( struct device_manager_ctx *ctx ) static void reset_display_manager_ctx( struct device_manager_ctx *ctx )
...@@ -1711,15 +1720,6 @@ static BOOL update_display_cache_from_registry(void) ...@@ -1711,15 +1720,6 @@ static BOOL update_display_cache_from_registry(void)
return ret; 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 ) 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, /* default implementation: expose an adapter and a monitor with a few standard modes,
...@@ -1744,7 +1744,6 @@ static BOOL default_update_display_devices( const struct gdi_device_manager *man ...@@ -1744,7 +1744,6 @@ static BOOL default_update_display_devices( const struct gdi_device_manager *man
static const struct gdi_gpu gpu; static const struct gdi_gpu gpu;
struct gdi_monitor monitor = {0}; struct gdi_monitor monitor = {0};
DEVMODEW mode = {{0}}; DEVMODEW mode = {{0}};
UINT i;
if (!force) return TRUE; if (!force) return TRUE;
...@@ -1762,11 +1761,7 @@ static BOOL default_update_display_devices( const struct gdi_device_manager *man ...@@ -1762,11 +1761,7 @@ static BOOL default_update_display_devices( const struct gdi_device_manager *man
monitor.rc_work.bottom = mode.dmPelsHeight; monitor.rc_work.bottom = mode.dmPelsHeight;
manager->add_monitor( &monitor, ctx ); manager->add_monitor( &monitor, ctx );
for (i = 0; i < ARRAY_SIZE(modes); ++i) manager->add_modes( &mode, ARRAY_SIZE(modes), modes, ctx );
{
if (is_same_devmode( modes + i, &mode )) manager->add_mode( &mode, TRUE, ctx );
else manager->add_mode( modes + i, FALSE, ctx );
}
return TRUE; return TRUE;
} }
...@@ -1823,10 +1818,10 @@ static void desktop_add_monitor( const struct gdi_monitor *monitor, void *param ...@@ -1823,10 +1818,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; 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 = static const struct gdi_device_manager desktop_device_manager =
...@@ -1834,7 +1829,7 @@ static const struct gdi_device_manager desktop_device_manager = ...@@ -1834,7 +1829,7 @@ static const struct gdi_device_manager desktop_device_manager =
desktop_add_gpu, desktop_add_gpu,
desktop_add_source, desktop_add_source,
desktop_add_monitor, desktop_add_monitor,
desktop_add_mode, desktop_add_modes,
}; };
static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ctx *ctx ) static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ctx *ctx )
...@@ -1881,9 +1876,9 @@ static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ct ...@@ -1881,9 +1876,9 @@ static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ct
}; };
struct device_manager_ctx desktop_ctx = {0}; 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}; unsigned int depths[] = {8, 16, 0};
DEVMODEW current; DEVMODEW current, *modes;
UINT i, j; UINT i, j;
if (!force) return TRUE; if (!force) return TRUE;
...@@ -1915,7 +1910,9 @@ static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ct ...@@ -1915,7 +1910,9 @@ static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ct
monitor.rc_work.bottom = current.dmPelsHeight; monitor.rc_work.bottom = current.dmPelsHeight;
add_monitor( &monitor, ctx ); 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 = DEVMODEW mode =
{ {
...@@ -1932,25 +1929,24 @@ static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ct ...@@ -1932,25 +1929,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 == 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 (mode.dmPelsWidth == screen_width && mode.dmPelsHeight == screen_height) continue;
modes[modes_count++] = mode;
if (is_same_devmode( &mode, &current )) add_mode( &current, TRUE, ctx );
else add_mode( &mode, FALSE, ctx );
} }
mode.dmPelsWidth = screen_width; mode.dmPelsWidth = screen_width;
mode.dmPelsHeight = screen_height; mode.dmPelsHeight = screen_height;
if (is_same_devmode( &mode, &current )) add_mode( &current, TRUE, ctx ); modes[modes_count++] = mode;
else add_mode( &mode, FALSE, ctx );
if (max_width != screen_width || max_height != screen_height) if (max_width != screen_width || max_height != screen_height)
{ {
mode.dmPelsWidth = max_width; mode.dmPelsWidth = max_width;
mode.dmPelsHeight = max_height; mode.dmPelsHeight = max_height;
if (is_same_devmode( &mode, &current )) add_mode( &current, TRUE, ctx ); modes[modes_count++] = mode;
else add_mode( &mode, FALSE, ctx );
} }
} }
add_modes( &current, modes_count, modes, ctx );
free( modes );
return TRUE; return TRUE;
} }
......
...@@ -283,13 +283,17 @@ BOOL ANDROID_UpdateDisplayDevices( const struct gdi_device_manager *device_manag ...@@ -283,13 +283,17 @@ BOOL ANDROID_UpdateDisplayDevices( const struct gdi_device_manager *device_manag
const DEVMODEW mode = const DEVMODEW mode =
{ {
.dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | .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, .dmBitsPerPel = screen_bpp, .dmPelsWidth = screen_width, .dmPelsHeight = screen_height, .dmDisplayFrequency = 60,
}; };
DEVMODEW current = mode;
device_manager->add_gpu( &gpu, param ); device_manager->add_gpu( &gpu, param );
device_manager->add_source( "Default", source_flags, param ); device_manager->add_source( "Default", source_flags, param );
device_manager->add_monitor( &gdi_monitor, param ); device_manager->add_monitor( &gdi_monitor, param );
device_manager->add_mode( &mode, TRUE, param );
current.dmFields |= DM_POSITION;
device_manager->add_modes( &current, 1, &mode, param );
force_display_devices_refresh = FALSE; force_display_devices_refresh = FALSE;
} }
......
...@@ -1110,27 +1110,6 @@ static BOOL is_same_devmode(const DEVMODEW *a, const DEVMODEW *b) ...@@ -1110,27 +1110,6 @@ static BOOL is_same_devmode(const DEVMODEW *a, const DEVMODEW *b)
a->dmDisplayFrequency == b->dmDisplayFrequency; 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 ) BOOL macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, BOOL force, void *param )
{ {
struct macdrv_adapter *adapters, *adapter; struct macdrv_adapter *adapters, *adapter;
...@@ -1211,23 +1190,7 @@ BOOL macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manage ...@@ -1211,23 +1190,7 @@ BOOL macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manage
} }
if (!(modes = display_get_modes(adapter->id, &mode_count))) break; if (!(modes = display_get_modes(adapter->id, &mode_count))) break;
TRACE("adapter: %#x, mode count: %d\n", adapter->id, mode_count); device_manager->add_modes( &current_mode, mode_count, modes, param );
/* Initialize modes */
for (mode = modes; mode < modes + mode_count; mode++)
{
if (is_same_devmode(mode, &current_mode))
{
TRACE("current mode: %s\n", debugstr_devmodew(&current_mode));
device_manager->add_mode( &current_mode, TRUE, param );
}
else
{
TRACE("mode: %s\n", debugstr_devmodew(mode));
device_manager->add_mode( mode, FALSE, param );
}
}
free(modes); free(modes);
macdrv_free_monitors(monitors); macdrv_free_monitors(monitors);
} }
......
...@@ -251,22 +251,28 @@ static void populate_devmode(struct wayland_output_mode *output_mode, DEVMODEW * ...@@ -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, static void wayland_add_device_modes(const struct gdi_device_manager *device_manager,
void *param, struct output_info *output_info) void *param, struct output_info *output_info)
{ {
DEVMODEW *modes, current = {.dmSize = sizeof(current)};
struct wayland_output_mode *output_mode; 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, &current);
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, RB_FOR_EACH_ENTRY(output_mode, &output_info->output->modes,
struct wayland_output_mode, entry) struct wayland_output_mode, entry)
{ {
DEVMODEW mode = {.dmSize = sizeof(mode)}; DEVMODEW mode = {.dmSize = sizeof(mode)};
BOOL mode_is_current = output_mode == output_info->output->current_mode;
populate_devmode(output_mode, &mode); populate_devmode(output_mode, &mode);
if (mode_is_current) modes[modes_count++] = mode;
{
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);
} }
device_manager->add_modes(&current, modes_count, modes, param);
free(modes);
} }
/*********************************************************************** /***********************************************************************
......
...@@ -97,6 +97,7 @@ static void wayland_output_state_add_mode(struct wayland_output_state *state, ...@@ -97,6 +97,7 @@ static void wayland_output_state_add_mode(struct wayland_output_state *state,
mode->height = height; mode->height = height;
mode->refresh = refresh; mode->refresh = refresh;
rb_put(&state->modes, mode, &mode->entry); rb_put(&state->modes, mode, &mode->entry);
state->modes_count++;
} }
if (current) state->current_mode = mode; if (current) state->current_mode = mode;
...@@ -144,6 +145,7 @@ static void wayland_output_done(struct wayland_output *output) ...@@ -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_destroy(&output->pending.modes, wayland_output_mode_free_rb, NULL);
rb_init(&output->pending.modes, wayland_output_mode_cmp_rb); rb_init(&output->pending.modes, wayland_output_mode_cmp_rb);
output->pending.modes_count = 0;
} }
if (output->pending_flags & WAYLAND_OUTPUT_CHANGED_NAME) if (output->pending_flags & WAYLAND_OUTPUT_CHANGED_NAME)
...@@ -321,7 +323,9 @@ BOOL wayland_output_create(uint32_t id, uint32_t version) ...@@ -321,7 +323,9 @@ BOOL wayland_output_create(uint32_t id, uint32_t version)
wl_list_init(&output->link); wl_list_init(&output->link);
rb_init(&output->pending.modes, wayland_output_mode_cmp_rb); 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); 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. */ /* Have a fallback while we don't have compositor given name. */
name_len = snprintf(NULL, 0, "WaylandOutput%d", next_output_id); name_len = snprintf(NULL, 0, "WaylandOutput%d", next_output_id);
......
...@@ -142,6 +142,7 @@ struct wayland_output_mode ...@@ -142,6 +142,7 @@ struct wayland_output_mode
struct wayland_output_state struct wayland_output_state
{ {
int modes_count;
struct rb_tree modes; struct rb_tree modes;
struct wayland_output_mode *current_mode; struct wayland_output_mode *current_mode;
char *name; char *name;
......
...@@ -494,25 +494,6 @@ BOOL X11DRV_DisplayDevices_SupportEventHandlers(void) ...@@ -494,25 +494,6 @@ BOOL X11DRV_DisplayDevices_SupportEventHandlers(void)
static BOOL force_display_devices_refresh; 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 ) BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, BOOL force, void *param )
{ {
struct x11drv_adapter *adapters; struct x11drv_adapter *adapters;
...@@ -520,7 +501,7 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage ...@@ -520,7 +501,7 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage
struct gdi_gpu *gpus; struct gdi_gpu *gpus;
INT gpu_count, adapter_count, monitor_count; INT gpu_count, adapter_count, monitor_count;
INT gpu, adapter, monitor; INT gpu, adapter, monitor;
DEVMODEW *modes, *mode; DEVMODEW *modes;
UINT mode_count; UINT mode_count;
if (!force && !force_display_devices_refresh) return TRUE; if (!force && !force_display_devices_refresh) return TRUE;
...@@ -566,25 +547,11 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage ...@@ -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; if (!settings_handler.get_id( devname, is_primary, &settings_id )) break;
settings_handler.get_current_mode( settings_id, &current_mode ); settings_handler.get_current_mode( settings_id, &current_mode );
if (!settings_handler.get_modes( settings_id, EDS_ROTATEDMODE, &modes, &mode_count )) if (settings_handler.get_modes( settings_id, EDS_ROTATEDMODE, &modes, &mode_count ))
continue;
for (mode = modes; mode_count; mode_count--)
{ {
if (is_same_devmode( mode, &current_mode )) device_manager->add_modes( &current_mode, mode_count, modes, param );
{ settings_handler.free_modes( modes );
TRACE( "current mode: %s\n", debugstr_devmodew( &current_mode ) );
device_manager->add_mode( &current_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);
} }
settings_handler.free_modes( modes );
} }
host_handler.free_adapters( adapters ); host_handler.free_adapters( adapters );
......
...@@ -262,7 +262,7 @@ struct gdi_device_manager ...@@ -262,7 +262,7 @@ struct gdi_device_manager
void (*add_gpu)( const struct gdi_gpu *gpu, void *param ); void (*add_gpu)( const struct gdi_gpu *gpu, void *param );
void (*add_source)( const char *name, UINT state_flags, 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_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 #define WINE_DM_UNSUPPORTED 0x80000000
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment