From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/display.c | 14 ++++------- dlls/winex11.drv/x11drv.h | 3 --- dlls/winex11.drv/xrandr.c | 12 ---------- dlls/winex11.drv/xvidmode.c | 47 ++++++++++++++----------------------- 4 files changed, 21 insertions(+), 55 deletions(-)
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index f817c599383..5151a68f431 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -90,11 +90,6 @@ static BOOL nores_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_ return TRUE; }
-static void nores_free_modes(DEVMODEW *modes) -{ - free(modes); -} - static BOOL nores_get_current_mode(x11drv_settings_id id, DEVMODEW *mode) { RECT primary = get_host_primary_monitor_rect(); @@ -140,7 +135,6 @@ void X11DRV_Settings_Init(void) nores_handler.priority = 1; nores_handler.get_id = nores_get_id; nores_handler.get_modes = nores_get_modes; - nores_handler.free_modes = nores_free_modes; nores_handler.get_current_mode = nores_get_current_mode; nores_handler.set_current_mode = nores_set_current_mode; X11DRV_Settings_SetHandler(&nores_handler); @@ -184,18 +178,18 @@ static DEVMODEW *get_full_mode(x11drv_settings_id id, DEVMODEW *dev_mode)
if (!found_mode || mode_idx == mode_count) { - settings_handler.free_modes(modes); + free( modes ); return NULL; }
if (!(full_mode = malloc(sizeof(*found_mode) + found_mode->dmDriverExtra))) { - settings_handler.free_modes(modes); + free( modes ); return NULL; }
memcpy(full_mode, found_mode, sizeof(*found_mode) + found_mode->dmDriverExtra); - settings_handler.free_modes(modes); + free( modes );
full_mode->dmFields |= DM_POSITION; full_mode->dmPosition = dev_mode->dmPosition; @@ -456,7 +450,7 @@ UINT X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage if (settings_handler.get_modes( settings_id, EDS_ROTATEDMODE, &modes, &mode_count, FALSE )) { device_manager->add_modes( ¤t_mode, mode_count, modes, param ); - settings_handler.free_modes( modes ); + free( modes ); } }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index a71607e9e97..6513dca9468 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -783,9 +783,6 @@ struct x11drv_settings_handler * Return FALSE on failure with parameters unchanged and error code set. Return TRUE on success */ BOOL (*get_modes)(x11drv_settings_id id, DWORD flags, DEVMODEW **modes, UINT *mode_count, BOOL full);
- /* free_modes() will be called to free the mode list returned from get_modes() */ - void (*free_modes)(DEVMODEW *modes); - /* get_current_mode() will be called to get the current display mode of the device of id * * Following fields in DEVMODE must be valid: diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index 979cbc8645f..87bddd07cf5 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -317,11 +317,6 @@ static BOOL xrandr10_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **n return TRUE; }
-static void xrandr10_free_modes( DEVMODEW *modes ) -{ - free( modes ); -} - static BOOL xrandr10_get_current_mode( x11drv_settings_id id, DEVMODEW *mode ) { XRRScreenConfiguration *screen_config; @@ -1475,11 +1470,6 @@ done: return ret; }
-static void xrandr14_free_modes( DEVMODEW *modes ) -{ - free( modes ); -} - static BOOL xrandr14_get_current_mode( x11drv_settings_id id, DEVMODEW *mode ) { struct current_mode *mode_ptr = NULL; @@ -1724,7 +1714,6 @@ void X11DRV_XRandR_Init(void) settings_handler.priority = 200; settings_handler.get_id = xrandr10_get_id; settings_handler.get_modes = xrandr10_get_modes; - settings_handler.free_modes = xrandr10_free_modes; settings_handler.get_current_mode = xrandr10_get_current_mode; settings_handler.set_current_mode = xrandr10_set_current_mode; X11DRV_Settings_SetHandler( &settings_handler ); @@ -1782,7 +1771,6 @@ void X11DRV_XRandR_Init(void) settings_handler.priority = 300; settings_handler.get_id = xrandr14_get_id; settings_handler.get_modes = xrandr14_get_modes; - settings_handler.free_modes = xrandr14_free_modes; settings_handler.get_current_mode = xrandr14_get_current_mode; settings_handler.set_current_mode = xrandr14_set_current_mode; X11DRV_Settings_SetHandler( &settings_handler ); diff --git a/dlls/winex11.drv/xvidmode.c b/dlls/winex11.drv/xvidmode.c index f2313d88090..c333fa4dc7e 100644 --- a/dlls/winex11.drv/xvidmode.c +++ b/dlls/winex11.drv/xvidmode.c @@ -94,7 +94,7 @@ static BOOL xf86vm_get_id(const WCHAR *device_name, BOOL is_primary, x11drv_sett static void add_xf86vm_mode( DEVMODEW *mode, DWORD depth, const XF86VidModeModeInfo *mode_info, BOOL full ) { mode->dmSize = sizeof(*mode); - mode->dmDriverExtra = full ? sizeof(mode_info) : 0; + mode->dmDriverExtra = full ? sizeof(*mode_info) : 0; mode->dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS; if (mode_info->htotal && mode_info->vtotal) { @@ -106,7 +106,13 @@ static void add_xf86vm_mode( DEVMODEW *mode, DWORD depth, const XF86VidModeModeI mode->dmPelsWidth = mode_info->hdisplay; mode->dmPelsHeight = mode_info->vdisplay; mode->dmDisplayFlags = 0; - if (full) memcpy( mode + 1, &mode_info, sizeof(mode_info) ); + if (full) + { + XF86VidModeModeInfo extra = *mode_info; + extra.private = NULL; + extra.privsize = 0; + memcpy( mode + 1, &extra, sizeof(extra) ); + } }
static BOOL xf86vm_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_modes, UINT *mode_count, BOOL full ) @@ -115,8 +121,6 @@ static BOOL xf86vm_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new XF86VidModeModeInfo **xf86vm_modes; UINT depth_idx, mode_idx = 0; DEVMODEW *modes, *mode; - SIZE_T size; - BYTE *ptr; Bool ret;
X11DRV_expect_error(gdi_display, XVidModeErrorHandler, NULL); @@ -124,21 +128,15 @@ static BOOL xf86vm_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new if (X11DRV_check_error() || !ret || !xf86vm_mode_count) return FALSE;
- /* Put a XF86VidModeModeInfo ** at the start to store the XF86VidMode modes pointer */ - size = sizeof(XF86VidModeModeInfo **); /* Display modes in different color depth, with a XF86VidModeModeInfo * at the end of each * DEVMODEW as driver private data */ - size += (xf86vm_mode_count * DEPTH_COUNT) * (sizeof(DEVMODEW) + sizeof(XF86VidModeModeInfo *)); - ptr = calloc(1, size); - if (!ptr) + if (!(modes = calloc( 1, (xf86vm_mode_count * DEPTH_COUNT) * (sizeof(DEVMODEW) + sizeof(XF86VidModeModeInfo)) ))) { RtlSetLastWin32Error( ERROR_NOT_ENOUGH_MEMORY ); + XFree( xf86vm_modes ); return FALSE; }
- memcpy(ptr, &xf86vm_modes, sizeof(xf86vm_modes)); - modes = (DEVMODEW *)(ptr + sizeof(xf86vm_modes)); - for (depth_idx = 0, mode = modes; depth_idx < DEPTH_COUNT; ++depth_idx) { for (xf86vm_mode_idx = 0; xf86vm_mode_idx < xf86vm_mode_count; ++xf86vm_mode_idx) @@ -151,20 +149,9 @@ static BOOL xf86vm_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new
*new_modes = modes; *mode_count = mode_idx; - return TRUE; -} - -static void xf86vm_free_modes(DEVMODEW *modes) -{ - XF86VidModeModeInfo **xf86vm_modes;
- if (modes) - { - BYTE *ptr = (BYTE *)modes - sizeof(xf86vm_modes); - memcpy(&xf86vm_modes, ptr, sizeof(xf86vm_modes)); - XFree(xf86vm_modes); - free(ptr); - } + XFree( xf86vm_modes ); + return TRUE; }
static BOOL xf86vm_get_current_mode(x11drv_settings_id id, DEVMODEW *mode) @@ -210,7 +197,7 @@ static BOOL xf86vm_get_current_mode(x11drv_settings_id id, DEVMODEW *mode)
static LONG xf86vm_set_current_mode(x11drv_settings_id id, const DEVMODEW *mode) { - XF86VidModeModeInfo *xf86vm_mode; + XF86VidModeModeInfo xf86vm_mode; Bool ret;
if (id.id != 1) @@ -229,10 +216,11 @@ static LONG xf86vm_set_current_mode(x11drv_settings_id id, const DEVMODEW *mode) WARN("Cannot change screen bit depth from %dbits to %dbits!\n", screen_bpp, mode->dmBitsPerPel);
- assert(mode->dmDriverExtra == sizeof(XF86VidModeModeInfo *)); - memcpy(&xf86vm_mode, (BYTE *)mode + sizeof(*mode), sizeof(xf86vm_mode)); + assert( mode->dmDriverExtra == sizeof(XF86VidModeModeInfo) ); + memcpy( &xf86vm_mode, (BYTE *)mode + sizeof(*mode), sizeof(xf86vm_mode) ); + X11DRV_expect_error(gdi_display, XVidModeErrorHandler, NULL); - ret = pXF86VidModeSwitchToMode(gdi_display, DefaultScreen(gdi_display), xf86vm_mode); + ret = pXF86VidModeSwitchToMode( gdi_display, DefaultScreen(gdi_display), &xf86vm_mode ); if (X11DRV_check_error() || !ret) return DISP_CHANGE_FAILED; #if 0 /* it is said that SetViewPort causes problems with some X servers */ @@ -307,7 +295,6 @@ void X11DRV_XF86VM_Init(void) xf86vm_handler.priority = 100; xf86vm_handler.get_id = xf86vm_get_id; xf86vm_handler.get_modes = xf86vm_get_modes; - xf86vm_handler.free_modes = xf86vm_free_modes; xf86vm_handler.get_current_mode = xf86vm_get_current_mode; xf86vm_handler.set_current_mode = xf86vm_set_current_mode; X11DRV_Settings_SetHandler(&xf86vm_handler);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/display.c | 20 +++++++++++++++++--- dlls/winex11.drv/x11drv.h | 2 +- dlls/winex11.drv/xrandr.c | 22 +++++++++++----------- dlls/winex11.drv/xvidmode.c | 21 ++++++++++----------- 4 files changed, 39 insertions(+), 26 deletions(-)
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 5151a68f431..f063dabcbb5 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -62,7 +62,7 @@ static BOOL nores_get_id(const WCHAR *device_name, BOOL is_primary, x11drv_setti return TRUE; }
-static BOOL nores_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_modes, UINT *mode_count, BOOL full ) +static BOOL nores_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_modes, UINT *mode_count ) { RECT primary = get_host_primary_monitor_rect(); DEVMODEW *modes; @@ -140,6 +140,19 @@ void X11DRV_Settings_Init(void) X11DRV_Settings_SetHandler(&nores_handler); }
+static void strip_driver_extra( DEVMODEW *modes, UINT count ) +{ + DEVMODEW *mode, *next; + UINT i; + + for (i = 0, mode = modes; i < count; i++, mode = next) + { + next = NEXT_DEVMODEW(mode); + mode->dmDriverExtra = 0; + memcpy( modes + i, mode, sizeof(*mode) ); + } +} + BOOL is_detached_mode(const DEVMODEW *mode) { return mode->dmFields & DM_POSITION && @@ -168,7 +181,7 @@ static DEVMODEW *get_full_mode(x11drv_settings_id id, DEVMODEW *dev_mode) if (is_detached_mode(dev_mode)) return dev_mode;
- if (!settings_handler.get_modes( id, EDS_ROTATEDMODE, &modes, &mode_count, TRUE )) return NULL; + if (!settings_handler.get_modes( id, EDS_ROTATEDMODE, &modes, &mode_count )) return NULL;
for (mode_idx = 0; mode_idx < mode_count; ++mode_idx) { @@ -447,8 +460,9 @@ UINT 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, FALSE )) + if (settings_handler.get_modes( settings_id, EDS_ROTATEDMODE, &modes, &mode_count )) { + strip_driver_extra( modes, mode_count ); device_manager->add_modes( ¤t_mode, mode_count, modes, param ); free( modes ); } diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 6513dca9468..a92ffb6428e 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -781,7 +781,7 @@ struct x11drv_settings_handler * dmDisplayFlags and dmDisplayFrequency * * Return FALSE on failure with parameters unchanged and error code set. Return TRUE on success */ - BOOL (*get_modes)(x11drv_settings_id id, DWORD flags, DEVMODEW **modes, UINT *mode_count, BOOL full); + BOOL (*get_modes)(x11drv_settings_id id, DWORD flags, DEVMODEW **modes, UINT *mode_count);
/* get_current_mode() will be called to get the current display mode of the device of id * diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index 87bddd07cf5..8b675ec355b 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -239,10 +239,10 @@ static BOOL xrandr10_get_id( const WCHAR *device_name, BOOL is_primary, x11drv_s }
static void add_xrandr10_mode( DEVMODEW *mode, DWORD depth, DWORD width, DWORD height, - DWORD frequency, SizeID size_id, BOOL full ) + DWORD frequency, SizeID size_id ) { mode->dmSize = sizeof(*mode); - mode->dmDriverExtra = full ? sizeof(SizeID) : 0; + mode->dmDriverExtra = sizeof(SizeID); mode->dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS; if (frequency) @@ -255,10 +255,10 @@ static void add_xrandr10_mode( DEVMODEW *mode, DWORD depth, DWORD width, DWORD h mode->dmPelsWidth = width; mode->dmPelsHeight = height; mode->dmDisplayFlags = 0; - if (full) memcpy( mode + 1, &size_id, sizeof(size_id) ); + memcpy( mode + 1, &size_id, sizeof(size_id) ); }
-static BOOL xrandr10_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_modes, UINT *new_mode_count, BOOL full ) +static BOOL xrandr10_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_modes, UINT *new_mode_count ) { INT size_idx, depth_idx, rate_idx, mode_idx = 0; INT size_count, rate_count, mode_count = 0; @@ -296,7 +296,7 @@ static BOOL xrandr10_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **n if (!rate_count) { add_xrandr10_mode( mode, depths[depth_idx], sizes[size_idx].width, - sizes[size_idx].height, 0, size_idx, full ); + sizes[size_idx].height, 0, size_idx ); mode = NEXT_DEVMODEW( mode ); mode_idx++; continue; @@ -305,7 +305,7 @@ static BOOL xrandr10_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **n for (rate_idx = 0; rate_idx < rate_count; ++rate_idx) { add_xrandr10_mode( mode, depths[depth_idx], sizes[size_idx].width, - sizes[size_idx].height, rates[rate_idx], size_idx, full ); + sizes[size_idx].height, rates[rate_idx], size_idx ); mode = NEXT_DEVMODEW( mode ); mode_idx++; } @@ -1331,10 +1331,10 @@ static BOOL xrandr14_get_id( const WCHAR *device_name, BOOL is_primary, x11drv_s }
static void add_xrandr14_mode( DEVMODEW *mode, XRRModeInfo *info, DWORD depth, DWORD frequency, - DWORD orientation, BOOL full ) + DWORD orientation ) { mode->dmSize = sizeof(*mode); - mode->dmDriverExtra = full ? sizeof(RRMode) : 0; + mode->dmDriverExtra = sizeof(RRMode); mode->dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS; if (frequency) @@ -1355,10 +1355,10 @@ static void add_xrandr14_mode( DEVMODEW *mode, XRRModeInfo *info, DWORD depth, D mode->dmDisplayOrientation = orientation; mode->dmBitsPerPel = depth; mode->dmDisplayFlags = 0; - if (full) memcpy( mode + 1, &info->id, sizeof(info->id) ); + memcpy( mode + 1, &info->id, sizeof(info->id) ); }
-static BOOL xrandr14_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_modes, UINT *mode_count, BOOL full ) +static BOOL xrandr14_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_modes, UINT *mode_count ) { DWORD frequency, orientation, orientation_count; XRRScreenResources *screen_resources; @@ -1447,7 +1447,7 @@ static BOOL xrandr14_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **n if (!((1 << orientation) & rotations)) continue;
- add_xrandr14_mode( mode, mode_info, depths[depth_idx], frequency, orientation, full ); + add_xrandr14_mode( mode, mode_info, depths[depth_idx], frequency, orientation ); mode = NEXT_DEVMODEW( mode ); ++mode_idx; } diff --git a/dlls/winex11.drv/xvidmode.c b/dlls/winex11.drv/xvidmode.c index c333fa4dc7e..7af34689dda 100644 --- a/dlls/winex11.drv/xvidmode.c +++ b/dlls/winex11.drv/xvidmode.c @@ -91,10 +91,12 @@ static BOOL xf86vm_get_id(const WCHAR *device_name, BOOL is_primary, x11drv_sett return TRUE; }
-static void add_xf86vm_mode( DEVMODEW *mode, DWORD depth, const XF86VidModeModeInfo *mode_info, BOOL full ) +static void add_xf86vm_mode( DEVMODEW *mode, DWORD depth, const XF86VidModeModeInfo *mode_info ) { + XF86VidModeModeInfo extra = *mode_info; + mode->dmSize = sizeof(*mode); - mode->dmDriverExtra = full ? sizeof(*mode_info) : 0; + mode->dmDriverExtra = sizeof(*mode_info); mode->dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS; if (mode_info->htotal && mode_info->vtotal) { @@ -106,16 +108,13 @@ static void add_xf86vm_mode( DEVMODEW *mode, DWORD depth, const XF86VidModeModeI mode->dmPelsWidth = mode_info->hdisplay; mode->dmPelsHeight = mode_info->vdisplay; mode->dmDisplayFlags = 0; - if (full) - { - XF86VidModeModeInfo extra = *mode_info; - extra.private = NULL; - extra.privsize = 0; - memcpy( mode + 1, &extra, sizeof(extra) ); - } + + extra.private = NULL; + extra.privsize = 0; + memcpy( mode + 1, &extra, sizeof(extra) ); }
-static BOOL xf86vm_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_modes, UINT *mode_count, BOOL full ) +static BOOL xf86vm_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_modes, UINT *mode_count ) { INT xf86vm_mode_idx, xf86vm_mode_count; XF86VidModeModeInfo **xf86vm_modes; @@ -141,7 +140,7 @@ static BOOL xf86vm_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new { for (xf86vm_mode_idx = 0; xf86vm_mode_idx < xf86vm_mode_count; ++xf86vm_mode_idx) { - add_xf86vm_mode( mode, depths[depth_idx], xf86vm_modes[xf86vm_mode_idx], full ); + add_xf86vm_mode( mode, depths[depth_idx], xf86vm_modes[xf86vm_mode_idx] ); mode = NEXT_DEVMODEW( mode ); mode_idx++; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/display.c | 35 ++++++------- dlls/winex11.drv/x11drv.h | 31 ++++++++++-- dlls/winex11.drv/xrandr.c | 97 +++++++++++++++---------------------- dlls/winex11.drv/xvidmode.c | 45 ++++++++--------- 4 files changed, 104 insertions(+), 104 deletions(-)
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index f063dabcbb5..e4a0bef2f08 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -62,10 +62,10 @@ static BOOL nores_get_id(const WCHAR *device_name, BOOL is_primary, x11drv_setti return TRUE; }
-static BOOL nores_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_modes, UINT *mode_count ) +static BOOL nores_get_modes( x11drv_settings_id id, DWORD flags, struct x11drv_mode **new_modes, UINT *mode_count ) { RECT primary = get_host_primary_monitor_rect(); - DEVMODEW *modes; + struct x11drv_mode *modes;
modes = calloc(1, sizeof(*modes)); if (!modes) @@ -74,16 +74,16 @@ static BOOL nores_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_ return FALSE; }
- modes[0].dmSize = sizeof(*modes); - modes[0].dmDriverExtra = 0; - modes[0].dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | - DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY; - modes[0].dmDisplayOrientation = DMDO_DEFAULT; - modes[0].dmBitsPerPel = screen_bpp; - modes[0].dmPelsWidth = primary.right; - modes[0].dmPelsHeight = primary.bottom; - modes[0].dmDisplayFlags = 0; - modes[0].dmDisplayFrequency = 60; + modes[0].mode.dmSize = sizeof(*modes); + modes[0].mode.dmDriverExtra = 0; + modes[0].mode.dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | + DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY; + modes[0].mode.dmDisplayOrientation = DMDO_DEFAULT; + modes[0].mode.dmBitsPerPel = screen_bpp; + modes[0].mode.dmPelsWidth = primary.right; + modes[0].mode.dmPelsHeight = primary.bottom; + modes[0].mode.dmDisplayFlags = 0; + modes[0].mode.dmDisplayFrequency = 60;
*new_modes = modes; *mode_count = 1; @@ -175,8 +175,9 @@ static BOOL is_same_devmode( const DEVMODEW *a, const DEVMODEW *b ) * Return NULL on failure. Caller should call free_full_mode() to free the returned mode. */ static DEVMODEW *get_full_mode(x11drv_settings_id id, DEVMODEW *dev_mode) { - DEVMODEW *modes, *full_mode, *found_mode = NULL; + DEVMODEW *full_mode, *found_mode = NULL; UINT mode_count, mode_idx; + struct x11drv_mode *modes;
if (is_detached_mode(dev_mode)) return dev_mode; @@ -185,7 +186,7 @@ static DEVMODEW *get_full_mode(x11drv_settings_id id, DEVMODEW *dev_mode)
for (mode_idx = 0; mode_idx < mode_count; ++mode_idx) { - found_mode = (DEVMODEW *)((BYTE *)modes + (sizeof(*modes) + modes[0].dmDriverExtra) * mode_idx); + found_mode = &modes[mode_idx].mode; if (is_same_devmode( found_mode, dev_mode )) break; }
@@ -416,7 +417,7 @@ UINT X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage struct gdi_monitor *monitors; struct x11drv_gpu *gpus; INT gpu, adapter, monitor; - DEVMODEW *modes; + struct x11drv_mode *modes; UINT mode_count;
TRACE( "via %s\n", debugstr_a(host_handler.name) ); @@ -462,8 +463,8 @@ UINT X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage settings_handler.get_current_mode( settings_id, ¤t_mode ); if (settings_handler.get_modes( settings_id, EDS_ROTATEDMODE, &modes, &mode_count )) { - strip_driver_extra( modes, mode_count ); - device_manager->add_modes( ¤t_mode, mode_count, modes, param ); + strip_driver_extra( &modes->mode, mode_count ); + device_manager->add_modes( ¤t_mode, mode_count, &modes->mode, param ); free( modes ); } } diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index a92ffb6428e..f19995391e8 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -38,6 +38,9 @@ #include <X11/extensions/XInput2.h> #endif
+#undef Status /* avoid conflict with wintrnl.h */ +typedef int Status; + #define BOOL X_BOOL #define BYTE X_BYTE #define INT8 X_INT8 @@ -46,6 +49,12 @@ #define INT64 X_INT64 #include <X11/Xmd.h> #include <X11/Xproto.h> +#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H +#include <X11/extensions/xf86vmode.h> +#endif +#ifdef HAVE_X11_EXTENSIONS_XRANDR_H +#include <X11/extensions/Xrandr.h> +#endif #undef BOOL #undef BYTE #undef INT8 @@ -54,9 +63,6 @@ #undef INT64 #undef LONG64
-#undef Status /* avoid conflict with wintrnl.h */ -typedef int Status; - /* avoid conflict with processthreadsapi.h */ #undef ControlMask
@@ -757,6 +763,21 @@ extern const unsigned int *depths; /* Use a distinct type for the settings id, to avoid mixups other types of ids */ typedef struct { ULONG_PTR id; } x11drv_settings_id;
+struct x11drv_mode +{ + DEVMODEW mode; + union + { +#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H + XF86VidModeModeInfo xf86vm; +#endif +#ifdef HAVE_X11_EXTENSIONS_XRANDR_H + SizeID xrandr10; + RRMode xrandr14; +#endif + }; +}; + /* Required functions for changing and enumerating display settings */ struct x11drv_settings_handler { @@ -781,7 +802,7 @@ struct x11drv_settings_handler * dmDisplayFlags and dmDisplayFrequency * * Return FALSE on failure with parameters unchanged and error code set. Return TRUE on success */ - BOOL (*get_modes)(x11drv_settings_id id, DWORD flags, DEVMODEW **modes, UINT *mode_count); + BOOL (*get_modes)(x11drv_settings_id id, DWORD flags, struct x11drv_mode **modes, UINT *mode_count);
/* get_current_mode() will be called to get the current display mode of the device of id * @@ -796,7 +817,7 @@ struct x11drv_settings_handler * mode must be a valid mode from get_modes() with optional fields, such as dmPosition set. * * Return DISP_CHANGE_*, same as ChangeDisplaySettingsExW() return values */ - LONG (*set_current_mode)(x11drv_settings_id id, const DEVMODEW *mode); + LONG (*set_current_mode)(x11drv_settings_id id, const struct x11drv_mode *mode); };
#define NEXT_DEVMODEW(mode) ((DEVMODEW *)((char *)((mode) + 1) + (mode)->dmDriverExtra)) diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index 8b675ec355b..6555d07f4ca 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -238,31 +238,30 @@ static BOOL xrandr10_get_id( const WCHAR *device_name, BOOL is_primary, x11drv_s return TRUE; }
-static void add_xrandr10_mode( DEVMODEW *mode, DWORD depth, DWORD width, DWORD height, +static void add_xrandr10_mode( struct x11drv_mode *mode, DWORD depth, DWORD width, DWORD height, DWORD frequency, SizeID size_id ) { - mode->dmSize = sizeof(*mode); - mode->dmDriverExtra = sizeof(SizeID); - mode->dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | + mode->mode.dmSize = sizeof(*mode); + mode->mode.dmDriverExtra = sizeof(*mode) - sizeof(mode->mode); + mode->mode.dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS; if (frequency) { - mode->dmFields |= DM_DISPLAYFREQUENCY; - mode->dmDisplayFrequency = frequency; + mode->mode.dmFields |= DM_DISPLAYFREQUENCY; + mode->mode.dmDisplayFrequency = frequency; } - mode->dmDisplayOrientation = DMDO_DEFAULT; - mode->dmBitsPerPel = depth; - mode->dmPelsWidth = width; - mode->dmPelsHeight = height; - mode->dmDisplayFlags = 0; - memcpy( mode + 1, &size_id, sizeof(size_id) ); + mode->mode.dmDisplayOrientation = DMDO_DEFAULT; + mode->mode.dmBitsPerPel = depth; + mode->mode.dmPelsWidth = width; + mode->mode.dmPelsHeight = height; + mode->mode.dmDisplayFlags = 0; + mode->xrandr10 = size_id; }
-static BOOL xrandr10_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_modes, UINT *new_mode_count ) +static BOOL xrandr10_get_modes( x11drv_settings_id id, DWORD flags, struct x11drv_mode **new_modes, UINT *new_mode_count ) { - INT size_idx, depth_idx, rate_idx, mode_idx = 0; - INT size_count, rate_count, mode_count = 0; - DEVMODEW *modes, *mode; + INT size_idx, depth_idx, rate_idx, size_count, rate_count, mode_count = 0; + struct x11drv_mode *modes, *mode; XRRScreenSize *sizes; short *rates;
@@ -279,10 +278,7 @@ static BOOL xrandr10_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **n ++mode_count; }
- /* Allocate space for reported modes in three depths, and put an SizeID at the end of DEVMODEW as - * driver private data */ - modes = calloc( mode_count * DEPTH_COUNT, sizeof(*modes) + sizeof(SizeID) ); - if (!modes) + if (!(modes = calloc( mode_count * DEPTH_COUNT, sizeof(*modes) ))) { RtlSetLastWin32Error( ERROR_NOT_ENOUGH_MEMORY ); return FALSE; @@ -295,25 +291,21 @@ static BOOL xrandr10_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **n rates = pXRRRates( gdi_display, DefaultScreen( gdi_display ), size_idx, &rate_count ); if (!rate_count) { - add_xrandr10_mode( mode, depths[depth_idx], sizes[size_idx].width, + add_xrandr10_mode( mode++, depths[depth_idx], sizes[size_idx].width, sizes[size_idx].height, 0, size_idx ); - mode = NEXT_DEVMODEW( mode ); - mode_idx++; continue; }
for (rate_idx = 0; rate_idx < rate_count; ++rate_idx) { - add_xrandr10_mode( mode, depths[depth_idx], sizes[size_idx].width, + add_xrandr10_mode( mode++, depths[depth_idx], sizes[size_idx].width, sizes[size_idx].height, rates[rate_idx], size_idx ); - mode = NEXT_DEVMODEW( mode ); - mode_idx++; } } }
*new_modes = modes; - *new_mode_count = mode_idx; + *new_mode_count = mode - modes; return TRUE; }
@@ -1330,46 +1322,46 @@ static BOOL xrandr14_get_id( const WCHAR *device_name, BOOL is_primary, x11drv_s return TRUE; }
-static void add_xrandr14_mode( DEVMODEW *mode, XRRModeInfo *info, DWORD depth, DWORD frequency, +static void add_xrandr14_mode( struct x11drv_mode *mode, XRRModeInfo *info, DWORD depth, DWORD frequency, DWORD orientation ) { - mode->dmSize = sizeof(*mode); - mode->dmDriverExtra = sizeof(RRMode); - mode->dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | + mode->mode.dmSize = sizeof(*mode); + mode->mode.dmDriverExtra = sizeof(*mode) - sizeof(mode->mode); + mode->mode.dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS; if (frequency) { - mode->dmFields |= DM_DISPLAYFREQUENCY; - mode->dmDisplayFrequency = frequency; + mode->mode.dmFields |= DM_DISPLAYFREQUENCY; + mode->mode.dmDisplayFrequency = frequency; } if (orientation == DMDO_DEFAULT || orientation == DMDO_180) { - mode->dmPelsWidth = info->width; - mode->dmPelsHeight = info->height; + mode->mode.dmPelsWidth = info->width; + mode->mode.dmPelsHeight = info->height; } else { - mode->dmPelsWidth = info->height; - mode->dmPelsHeight = info->width; + mode->mode.dmPelsWidth = info->height; + mode->mode.dmPelsHeight = info->width; } - mode->dmDisplayOrientation = orientation; - mode->dmBitsPerPel = depth; - mode->dmDisplayFlags = 0; - memcpy( mode + 1, &info->id, sizeof(info->id) ); + mode->mode.dmDisplayOrientation = orientation; + mode->mode.dmBitsPerPel = depth; + mode->mode.dmDisplayFlags = 0; + mode->xrandr14 = info->id; }
-static BOOL xrandr14_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_modes, UINT *mode_count ) +static BOOL xrandr14_get_modes( x11drv_settings_id id, DWORD flags, struct x11drv_mode **new_modes, UINT *mode_count ) { DWORD frequency, orientation, orientation_count; XRRScreenResources *screen_resources; XRROutputInfo *output_info = NULL; RROutput output = (RROutput)id.id; + struct x11drv_mode *mode, *modes; XRRCrtcInfo *crtc_info = NULL; - UINT depth_idx, mode_idx = 0; XRRModeInfo *mode_info; - DEVMODEW *mode, *modes; Rotation rotations; BOOL ret = FALSE; + UINT depth_idx; RRCrtc crtc; INT i, j;
@@ -1423,12 +1415,7 @@ static BOOL xrandr14_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **n } orientation_count = get_orientation_count( rotations );
- /* Allocate space for display modes in different color depths and orientations. - * Store a RRMode at the end of each DEVMODEW as private driver data */ - modes = calloc( output_info->nmode * DEPTH_COUNT * orientation_count, - sizeof(*modes) + sizeof(RRMode) ); - if (!modes) - goto done; + if (!(modes = calloc( output_info->nmode * DEPTH_COUNT * orientation_count, sizeof(*modes) ))) goto done;
for (i = 0, mode = modes; i < output_info->nmode; ++i) { @@ -1444,12 +1431,8 @@ static BOOL xrandr14_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **n { for (orientation = DMDO_DEFAULT; orientation <= DMDO_270; ++orientation) { - if (!((1 << orientation) & rotations)) - continue; - - add_xrandr14_mode( mode, mode_info, depths[depth_idx], frequency, orientation ); - mode = NEXT_DEVMODEW( mode ); - ++mode_idx; + if (!((1 << orientation) & rotations)) continue; + add_xrandr14_mode( mode++, mode_info, depths[depth_idx], frequency, orientation ); } }
@@ -1459,7 +1442,7 @@ static BOOL xrandr14_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **n
ret = TRUE; *new_modes = modes; - *mode_count = mode_idx; + *mode_count = mode - modes; done: if (crtc_info) pXRRFreeCrtcInfo( crtc_info ); diff --git a/dlls/winex11.drv/xvidmode.c b/dlls/winex11.drv/xvidmode.c index 7af34689dda..a47fed8a2e1 100644 --- a/dlls/winex11.drv/xvidmode.c +++ b/dlls/winex11.drv/xvidmode.c @@ -91,35 +91,32 @@ static BOOL xf86vm_get_id(const WCHAR *device_name, BOOL is_primary, x11drv_sett return TRUE; }
-static void add_xf86vm_mode( DEVMODEW *mode, DWORD depth, const XF86VidModeModeInfo *mode_info ) +static void add_xf86vm_mode( struct x11drv_mode *mode, DWORD depth, const XF86VidModeModeInfo *mode_info ) { - XF86VidModeModeInfo extra = *mode_info; - - mode->dmSize = sizeof(*mode); - mode->dmDriverExtra = sizeof(*mode_info); - mode->dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS; + mode->mode.dmSize = sizeof(*mode); + mode->mode.dmDriverExtra = sizeof(*mode) - sizeof(mode->mode); + mode->mode.dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS; if (mode_info->htotal && mode_info->vtotal) { - mode->dmFields |= DM_DISPLAYFREQUENCY; - mode->dmDisplayFrequency = mode_info->dotclock * 1000 / (mode_info->htotal * mode_info->vtotal); + mode->mode.dmFields |= DM_DISPLAYFREQUENCY; + mode->mode.dmDisplayFrequency = mode_info->dotclock * 1000 / (mode_info->htotal * mode_info->vtotal); } - mode->dmDisplayOrientation = DMDO_DEFAULT; - mode->dmBitsPerPel = depth; - mode->dmPelsWidth = mode_info->hdisplay; - mode->dmPelsHeight = mode_info->vdisplay; - mode->dmDisplayFlags = 0; - - extra.private = NULL; - extra.privsize = 0; - memcpy( mode + 1, &extra, sizeof(extra) ); + mode->mode.dmDisplayOrientation = DMDO_DEFAULT; + mode->mode.dmBitsPerPel = depth; + mode->mode.dmPelsWidth = mode_info->hdisplay; + mode->mode.dmPelsHeight = mode_info->vdisplay; + mode->mode.dmDisplayFlags = 0; + mode->xf86vm = *mode_info; + mode->xf86vm.privsize = 0; + mode->xf86vm.private = NULL; }
-static BOOL xf86vm_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new_modes, UINT *mode_count ) +static BOOL xf86vm_get_modes( x11drv_settings_id id, DWORD flags, struct x11drv_mode **new_modes, UINT *mode_count ) { INT xf86vm_mode_idx, xf86vm_mode_count; XF86VidModeModeInfo **xf86vm_modes; - UINT depth_idx, mode_idx = 0; - DEVMODEW *modes, *mode; + struct x11drv_mode *modes, *mode; + UINT depth_idx; Bool ret;
X11DRV_expect_error(gdi_display, XVidModeErrorHandler, NULL); @@ -129,7 +126,7 @@ static BOOL xf86vm_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new
/* Display modes in different color depth, with a XF86VidModeModeInfo * at the end of each * DEVMODEW as driver private data */ - if (!(modes = calloc( 1, (xf86vm_mode_count * DEPTH_COUNT) * (sizeof(DEVMODEW) + sizeof(XF86VidModeModeInfo)) ))) + if (!(modes = calloc( xf86vm_mode_count * DEPTH_COUNT, sizeof(*modes) ))) { RtlSetLastWin32Error( ERROR_NOT_ENOUGH_MEMORY ); XFree( xf86vm_modes ); @@ -140,14 +137,12 @@ static BOOL xf86vm_get_modes( x11drv_settings_id id, DWORD flags, DEVMODEW **new { for (xf86vm_mode_idx = 0; xf86vm_mode_idx < xf86vm_mode_count; ++xf86vm_mode_idx) { - add_xf86vm_mode( mode, depths[depth_idx], xf86vm_modes[xf86vm_mode_idx] ); - mode = NEXT_DEVMODEW( mode ); - mode_idx++; + add_xf86vm_mode( mode++, depths[depth_idx], xf86vm_modes[xf86vm_mode_idx] ); } }
*new_modes = modes; - *mode_count = mode_idx; + *mode_count = mode - modes;
XFree( xf86vm_modes ); return TRUE;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/display.c | 123 ++++++++++++++---------------------- dlls/winex11.drv/xrandr.c | 18 ++---- dlls/winex11.drv/xvidmode.c | 8 +-- 3 files changed, 56 insertions(+), 93 deletions(-)
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index e4a0bef2f08..6cf0afcbd23 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -43,6 +43,18 @@ static const unsigned int depths_24[] = {8, 16, 24}; static const unsigned int depths_32[] = {8, 16, 32}; const unsigned int *depths;
+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", + devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmBitsPerPel, + devmode->dmDisplayFrequency, devmode->dmDisplayOrientation * 90, + devmode->dmDisplayFixedOutput == DMDFO_STRETCH ? "" : "un", + devmode->dmDisplayFlags & DM_INTERLACED ? "" : "non-", + position ); +} + void X11DRV_Settings_SetHandler(const struct x11drv_settings_handler *new_handler) { if (new_handler->priority > settings_handler.priority) @@ -118,7 +130,7 @@ static BOOL nores_get_current_mode(x11drv_settings_id id, DEVMODEW *mode) return TRUE; }
-static LONG nores_set_current_mode(x11drv_settings_id id, const DEVMODEW *mode) +static LONG nores_set_current_mode( x11drv_settings_id id, const struct x11drv_mode *mode ) { WARN("NoRes settings handler, ignoring mode change request.\n"); return DISP_CHANGE_SUCCESSFUL; @@ -171,85 +183,26 @@ static BOOL is_same_devmode( const DEVMODEW *a, const DEVMODEW *b ) a->dmDisplayFrequency == b->dmDisplayFrequency; }
-/* Get the full display mode with all the necessary fields set. - * Return NULL on failure. Caller should call free_full_mode() to free the returned mode. */ -static DEVMODEW *get_full_mode(x11drv_settings_id id, DEVMODEW *dev_mode) +static DWORD get_full_mode( x11drv_settings_id id, DEVMODEW *mode, struct x11drv_mode *full ) { - DEVMODEW *full_mode, *found_mode = NULL; - UINT mode_count, mode_idx; struct x11drv_mode *modes; + UINT count, i;
- if (is_detached_mode(dev_mode)) - return dev_mode; - - if (!settings_handler.get_modes( id, EDS_ROTATEDMODE, &modes, &mode_count )) return NULL; - - for (mode_idx = 0; mode_idx < mode_count; ++mode_idx) - { - found_mode = &modes[mode_idx].mode; - if (is_same_devmode( found_mode, dev_mode )) break; - } - - if (!found_mode || mode_idx == mode_count) - { - free( modes ); - return NULL; - } + full->mode = *mode; + if (is_detached_mode( mode )) return DISP_CHANGE_SUCCESSFUL;
- if (!(full_mode = malloc(sizeof(*found_mode) + found_mode->dmDriverExtra))) + if (!settings_handler.get_modes( id, EDS_ROTATEDMODE, &modes, &count )) return DISP_CHANGE_BADMODE; + for (i = 0; i < count; i++) if (is_same_devmode( &modes[i].mode, mode )) break; + if (i < count) { - free( modes ); - return NULL; + *full = modes[i]; + full->mode.dmFields |= DM_POSITION; + full->mode.dmPosition = mode->dmPosition; + memcpy( full->mode.dmDeviceName, mode->dmDeviceName, sizeof(mode->dmDeviceName) ); } - - memcpy(full_mode, found_mode, sizeof(*found_mode) + found_mode->dmDriverExtra); free( modes );
- full_mode->dmFields |= DM_POSITION; - full_mode->dmPosition = dev_mode->dmPosition; - return full_mode; -} - -static void free_full_mode(DEVMODEW *mode) -{ - if (!is_detached_mode(mode)) - free(mode); -} - -static LONG apply_display_settings( DEVMODEW *displays, x11drv_settings_id *ids, BOOL do_attach ) -{ - DEVMODEW *full_mode; - BOOL attached_mode; - LONG count, ret; - DEVMODEW *mode; - - for (count = 0, mode = displays; mode->dmSize; mode = NEXT_DEVMODEW(mode), count++) - { - x11drv_settings_id *id = ids + count; - - attached_mode = !is_detached_mode(mode); - if ((attached_mode && !do_attach) || (!attached_mode && do_attach)) - continue; - - /* FIXME: get a full mode again because X11 driver extra data isn't portable */ - full_mode = get_full_mode(*id, mode); - if (!full_mode) - return DISP_CHANGE_BADMODE; - - TRACE("handler:%s changing %s to position:(%d,%d) resolution:%ux%u frequency:%uHz " - "depth:%ubits orientation:%#x.\n", settings_handler.name, - wine_dbgstr_w(mode->dmDeviceName), - full_mode->dmPosition.x, full_mode->dmPosition.y, full_mode->dmPelsWidth, - full_mode->dmPelsHeight, full_mode->dmDisplayFrequency, - full_mode->dmBitsPerPel, full_mode->dmDisplayOrientation); - - ret = settings_handler.set_current_mode(*id, full_mode); - free_full_mode(full_mode); - if (ret != DISP_CHANGE_SUCCESSFUL) - return ret; - } - - return DISP_CHANGE_SUCCESSFUL; + return i < count ? DISP_CHANGE_SUCCESSFUL : DISP_CHANGE_BADMODE; }
/*********************************************************************** @@ -259,7 +212,8 @@ static LONG apply_display_settings( DEVMODEW *displays, x11drv_settings_id *ids, LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_name, HWND hwnd, DWORD flags, LPVOID lpvoid ) { INT left_most = INT_MAX, top_most = INT_MAX; - LONG count, ret = DISP_CHANGE_BADPARAM; + LONG count, ret = DISP_CHANGE_FAILED; + struct x11drv_mode *modes; x11drv_settings_id *ids; DEVMODEW *mode;
@@ -273,19 +227,34 @@ LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_name, HW }
if (!(ids = calloc( count, sizeof(*ids) ))) return DISP_CHANGE_FAILED; + if (!(modes = calloc( count, sizeof(*modes) ))) goto done; + for (count = 0, mode = displays; mode->dmSize; mode = NEXT_DEVMODEW(mode), count++) { - if (!settings_handler.get_id( mode->dmDeviceName, !wcsicmp( mode->dmDeviceName, primary_name ), ids + count )) goto done; + BOOL is_primary = !wcsicmp( mode->dmDeviceName, primary_name ); + if (!settings_handler.get_id( mode->dmDeviceName, is_primary, ids + count )) goto done; mode->dmPosition.x -= left_most; mode->dmPosition.y -= top_most; + if ((ret = get_full_mode( ids[count], mode, modes + count ))) goto done; }
/* Detach displays first to free up CRTCs */ - ret = apply_display_settings( displays, ids, FALSE ); - if (ret == DISP_CHANGE_SUCCESSFUL) - ret = apply_display_settings( displays, ids, TRUE ); + TRACE( "Using %s\n", settings_handler.name ); + for (UINT i = 0; !ret && i < count; i++) + { + if (!is_detached_mode( &modes[i].mode )) continue; + TRACE( " setting %s mode %s\n", debugstr_w(modes[i].mode.dmDeviceName), debugstr_devmodew(&modes[i].mode) ); + ret = settings_handler.set_current_mode( ids[i], modes + i ); + } + for (UINT i = 0; !ret && i < count; i++) + { + if (is_detached_mode( &modes[i].mode )) continue; + TRACE( " setting %s mode %s\n", debugstr_w(modes[i].mode.dmDeviceName), debugstr_devmodew(&modes[i].mode) ); + ret = settings_handler.set_current_mode( ids[i], modes + i ); + }
done: + free( modes ); free( ids ); return ret; } diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index 6555d07f4ca..8b560d1d0f5 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -351,11 +351,12 @@ static BOOL xrandr10_get_current_mode( x11drv_settings_id id, DEVMODEW *mode ) return TRUE; }
-static LONG xrandr10_set_current_mode( x11drv_settings_id id, const DEVMODEW *mode ) +static LONG xrandr10_set_current_mode( x11drv_settings_id id, const struct x11drv_mode *full_mode ) { + const DEVMODEW *mode = &full_mode->mode; XRRScreenConfiguration *screen_config; + SizeID size_id = full_mode->xrandr10; Rotation rotation; - SizeID size_id; Window root; Status stat;
@@ -365,7 +366,7 @@ static LONG xrandr10_set_current_mode( x11drv_settings_id id, const DEVMODEW *mo return DISP_CHANGE_SUCCESSFUL; }
- if (is_detached_mode(mode)) + if (is_detached_mode( mode )) { FIXME("Detaching adapters is unsupported.\n"); return DISP_CHANGE_SUCCESSFUL; @@ -379,9 +380,6 @@ static LONG xrandr10_set_current_mode( x11drv_settings_id id, const DEVMODEW *mo screen_config = pXRRGetScreenInfo( gdi_display, root ); pXRRConfigCurrentConfiguration( screen_config, &rotation );
- assert( mode->dmDriverExtra == sizeof(SizeID) ); - memcpy( &size_id, (BYTE *)mode + sizeof(*mode), sizeof(size_id) ); - if (mode->dmFields & DM_DISPLAYFREQUENCY && mode->dmDisplayFrequency) stat = pXRRSetScreenConfigAndRate( gdi_display, screen_config, root, size_id, rotation, mode->dmDisplayFrequency, CurrentTime ); @@ -1559,10 +1557,12 @@ done: return ret; }
-static LONG xrandr14_set_current_mode( x11drv_settings_id id, const DEVMODEW *mode ) +static LONG xrandr14_set_current_mode( x11drv_settings_id id, const struct x11drv_mode *full_mode ) { + const DEVMODEW *mode = &full_mode->mode; unsigned int screen_width, screen_height; RROutput output = (RROutput)id.id, *outputs; + RRMode rrmode = (RRMode)full_mode->xrandr14; XRRScreenResources *screen_resources; XRROutputInfo *output_info = NULL; XRRCrtcInfo *crtc_info = NULL; @@ -1571,7 +1571,6 @@ static LONG xrandr14_set_current_mode( x11drv_settings_id id, const DEVMODEW *mo INT output_count; RRCrtc crtc = 0; Status status; - RRMode rrmode;
if (mode->dmFields & DM_BITSPERPEL && mode->dmBitsPerPel != screen_bpp) WARN("Cannot change screen color depth from %ubits to %ubits!\n", @@ -1624,9 +1623,6 @@ static LONG xrandr14_set_current_mode( x11drv_settings_id id, const DEVMODEW *mo if (!crtc_info) goto done;
- assert( mode->dmDriverExtra == sizeof(RRMode) ); - memcpy( &rrmode, (BYTE *)mode + sizeof(*mode), sizeof(rrmode) ); - if (crtc_info->noutput) { outputs = crtc_info->outputs; diff --git a/dlls/winex11.drv/xvidmode.c b/dlls/winex11.drv/xvidmode.c index a47fed8a2e1..40f0a4d867d 100644 --- a/dlls/winex11.drv/xvidmode.c +++ b/dlls/winex11.drv/xvidmode.c @@ -189,9 +189,10 @@ static BOOL xf86vm_get_current_mode(x11drv_settings_id id, DEVMODEW *mode) return TRUE; }
-static LONG xf86vm_set_current_mode(x11drv_settings_id id, const DEVMODEW *mode) +static LONG xf86vm_set_current_mode( x11drv_settings_id id, const struct x11drv_mode *full_mode ) { - XF86VidModeModeInfo xf86vm_mode; + XF86VidModeModeInfo xf86vm_mode = full_mode->xf86vm; + const DEVMODEW *mode = &full_mode->mode; Bool ret;
if (id.id != 1) @@ -210,9 +211,6 @@ static LONG xf86vm_set_current_mode(x11drv_settings_id id, const DEVMODEW *mode) WARN("Cannot change screen bit depth from %dbits to %dbits!\n", screen_bpp, mode->dmBitsPerPel);
- assert( mode->dmDriverExtra == sizeof(XF86VidModeModeInfo) ); - memcpy( &xf86vm_mode, (BYTE *)mode + sizeof(*mode), sizeof(xf86vm_mode) ); - X11DRV_expect_error(gdi_display, XVidModeErrorHandler, NULL); ret = pXF86VidModeSwitchToMode( gdi_display, DefaultScreen(gdi_display), &xf86vm_mode ); if (X11DRV_check_error() || !ret)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/display.c | 5 +++++ dlls/winex11.drv/xrandr.c | 5 ----- dlls/winex11.drv/xvidmode.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 6cf0afcbd23..f891de4ba21 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -238,6 +238,8 @@ LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_name, HW if ((ret = get_full_mode( ids[count], mode, modes + count ))) goto done; }
+ XGrabServer( gdi_display ); + /* Detach displays first to free up CRTCs */ TRACE( "Using %s\n", settings_handler.name ); for (UINT i = 0; !ret && i < count; i++) @@ -253,6 +255,9 @@ LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_name, HW ret = settings_handler.set_current_mode( ids[i], modes + i ); }
+ XFlush( gdi_display ); + XUngrabServer( gdi_display ); + done: free( modes ); free( ids ); diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index 8b560d1d0f5..81932c3fc03 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -390,7 +390,6 @@ static LONG xrandr10_set_current_mode( x11drv_settings_id id, const struct x11dr if (stat != RRSetConfigSuccess) return DISP_CHANGE_FAILED;
- XFlush( gdi_display ); return DISP_CHANGE_SUCCESSFUL; }
@@ -1580,8 +1579,6 @@ static LONG xrandr14_set_current_mode( x11drv_settings_id id, const struct x11dr if (!screen_resources) return ret;
- XGrabServer( gdi_display ); - output_info = pXRRGetOutputInfo( gdi_display, screen_resources, output ); if (!output_info || output_info->connection != RR_Connected) goto done; @@ -1656,8 +1653,6 @@ static LONG xrandr14_set_current_mode( x11drv_settings_id id, const struct x11dr ret = DISP_CHANGE_SUCCESSFUL;
done: - XUngrabServer( gdi_display ); - XFlush( gdi_display ); if (crtc_info) pXRRFreeCrtcInfo( crtc_info ); if (output_info) diff --git a/dlls/winex11.drv/xvidmode.c b/dlls/winex11.drv/xvidmode.c index 40f0a4d867d..fab0c4f135f 100644 --- a/dlls/winex11.drv/xvidmode.c +++ b/dlls/winex11.drv/xvidmode.c @@ -220,7 +220,7 @@ static LONG xf86vm_set_current_mode( x11drv_settings_id id, const struct x11drv_ #else XWarpPointer(gdi_display, None, DefaultRootWindow(gdi_display), 0, 0, 0, 0, 0, 0); #endif - XFlush(gdi_display); + return DISP_CHANGE_SUCCESSFUL; }