Commit 70d842b1 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

winex11: Resize the screen when changing CRTC modes.

Based on a patch by Gabriel Corona. According to the RandR spec for RRSetCrtcConfig: "The entire area of the CRTC must fit within the screen size, else a Match error results. As an example, rotating the screen so that a single CRTC fills the entire screen before and after may necessitate disabling the CRTC, resizing the screen, then re-enabling the CRTC at the new configuration to avoid an invalid intermediate configuration." This patch involves resizing the screen also when shrinking a CRTC, not just when expanding it past the current screen size. This is partially because we have no way to reliably determine the current display width (DisplayWidth() is never updated past opening the connection, and RandR exposes no way to retrieve the screen dimensions), and partially because it's probably what the user wants anyway (e.g. it's what the `xrandr` configuration app does when the screen size is not expliticly specified). This patch fixes TestBot failures on the Debian machines for ddraw, d3d8, and d3d9 device tests. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=33290Signed-off-by: 's avatarZebediah Figura <z.figura12@gmail.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 7aa9a04f
...@@ -58,6 +58,7 @@ MAKE_FUNCPTR(XRRGetCrtcInfo) ...@@ -58,6 +58,7 @@ MAKE_FUNCPTR(XRRGetCrtcInfo)
MAKE_FUNCPTR(XRRGetOutputInfo) MAKE_FUNCPTR(XRRGetOutputInfo)
MAKE_FUNCPTR(XRRGetScreenResources) MAKE_FUNCPTR(XRRGetScreenResources)
MAKE_FUNCPTR(XRRSetCrtcConfig) MAKE_FUNCPTR(XRRSetCrtcConfig)
MAKE_FUNCPTR(XRRSetScreenSize)
static typeof(XRRGetScreenResources) *pXRRGetScreenResourcesCurrent; static typeof(XRRGetScreenResources) *pXRRGetScreenResourcesCurrent;
static RRMode *xrandr12_modes; static RRMode *xrandr12_modes;
static int primary_crtc; static int primary_crtc;
...@@ -102,6 +103,7 @@ static int load_xrandr(void) ...@@ -102,6 +103,7 @@ static int load_xrandr(void)
LOAD_FUNCPTR(XRRGetOutputInfo) LOAD_FUNCPTR(XRRGetOutputInfo)
LOAD_FUNCPTR(XRRGetScreenResources) LOAD_FUNCPTR(XRRGetScreenResources)
LOAD_FUNCPTR(XRRSetCrtcConfig) LOAD_FUNCPTR(XRRSetCrtcConfig)
LOAD_FUNCPTR(XRRSetScreenSize)
r = 2; r = 2;
#endif #endif
#undef LOAD_FUNCPTR #undef LOAD_FUNCPTR
...@@ -320,8 +322,30 @@ static int xrandr12_get_current_mode(void) ...@@ -320,8 +322,30 @@ static int xrandr12_get_current_mode(void)
return ret; return ret;
} }
static void get_screen_size( XRRScreenResources *resources, unsigned int *width, unsigned int *height )
{
XRRCrtcInfo *crtc_info;
int i;
*width = *height = 0;
for (i = 0; i < resources->ncrtc; ++i)
{
if (!(crtc_info = pXRRGetCrtcInfo( gdi_display, resources, resources->crtcs[i] )))
continue;
if (crtc_info->mode != None)
{
*width = max(*width, crtc_info->x + crtc_info->width);
*height = max(*height, crtc_info->y + crtc_info->height);
}
pXRRFreeCrtcInfo( crtc_info );
}
}
static LONG xrandr12_set_current_mode( int mode ) static LONG xrandr12_set_current_mode( int mode )
{ {
unsigned int screen_width, screen_height;
Status status = RRSetConfigFailed; Status status = RRSetConfigFailed;
XRRScreenResources *resources; XRRScreenResources *resources;
XRRCrtcInfo *crtc_info; XRRCrtcInfo *crtc_info;
...@@ -345,10 +369,41 @@ static LONG xrandr12_set_current_mode( int mode ) ...@@ -345,10 +369,41 @@ static LONG xrandr12_set_current_mode( int mode )
TRACE("CRTC %d: mode %#lx, %ux%u+%d+%d.\n", primary_crtc, crtc_info->mode, TRACE("CRTC %d: mode %#lx, %ux%u+%d+%d.\n", primary_crtc, crtc_info->mode,
crtc_info->width, crtc_info->height, crtc_info->x, crtc_info->y); crtc_info->width, crtc_info->height, crtc_info->x, crtc_info->y);
/* According to the RandR spec, the entire CRTC must fit inside the screen.
* Since we use the union of all enabled CRTCs to determine the necessary
* screen size, this might involve shrinking the screen, so we must disable
* the CRTC in question first. */
XGrabServer( gdi_display );
status = pXRRSetCrtcConfig( gdi_display, resources, resources->crtcs[primary_crtc],
CurrentTime, crtc_info->x, crtc_info->y, None,
crtc_info->rotation, NULL, 0 );
if (status != RRSetConfigSuccess)
{
XUngrabServer( gdi_display );
ERR("Failed to disable CRTC.\n");
pXRRFreeCrtcInfo( crtc_info );
pXRRFreeScreenResources( resources );
return DISP_CHANGE_FAILED;
}
get_screen_size( resources, &screen_width, &screen_height );
screen_width = max( screen_width, crtc_info->x + dd_modes[mode].width );
screen_height = max( screen_height, crtc_info->y + dd_modes[mode].height );
pXRRSetScreenSize( gdi_display, root_window, screen_width, screen_height,
screen_width * DisplayWidthMM( gdi_display, default_visual.screen )
/ DisplayWidth( gdi_display, default_visual.screen ),
screen_height * DisplayHeightMM( gdi_display, default_visual.screen )
/ DisplayHeight( gdi_display, default_visual.screen ));
status = pXRRSetCrtcConfig( gdi_display, resources, resources->crtcs[primary_crtc], status = pXRRSetCrtcConfig( gdi_display, resources, resources->crtcs[primary_crtc],
CurrentTime, crtc_info->x, crtc_info->y, xrandr12_modes[mode], CurrentTime, crtc_info->x, crtc_info->y, xrandr12_modes[mode],
crtc_info->rotation, crtc_info->outputs, crtc_info->noutput ); crtc_info->rotation, crtc_info->outputs, crtc_info->noutput );
XUngrabServer( gdi_display );
pXRRFreeCrtcInfo( crtc_info ); pXRRFreeCrtcInfo( crtc_info );
pXRRFreeScreenResources( resources ); pXRRFreeScreenResources( resources );
......
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