diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 29042a0ee..ebc0f8fc7 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -52,13 +52,17 @@ int xf86CrtcConfigPrivateIndex = -1; void -xf86CrtcConfigInit (ScrnInfoPtr scrn) +xf86CrtcConfigInit (ScrnInfoPtr scrn, + const xf86CrtcConfigFuncsRec *funcs) { xf86CrtcConfigPtr config; if (xf86CrtcConfigPrivateIndex == -1) xf86CrtcConfigPrivateIndex = xf86AllocateScrnInfoPrivateIndex(); config = xnfcalloc (1, sizeof (xf86CrtcConfigRec)); + + config->funcs = funcs; + scrn->privates[xf86CrtcConfigPrivateIndex].ptr = config; } diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h index 756730e7b..345332b5d 100644 --- a/hw/xfree86/modes/xf86Crtc.h +++ b/hw/xfree86/modes/xf86Crtc.h @@ -407,6 +407,25 @@ struct _xf86Output { #endif }; +typedef struct _xf86CrtcConfigFuncs { + /** + * Requests that the driver resize the screen. + * + * The driver is responsible for updating scrn->virtualX and scrn->virtualY. + * If the requested size cannot be set, the driver should leave those values + * alone and return FALSE. + * + * A naive driver that cannot reallocate the screen may simply change + * virtual[XY]. A more advanced driver will want to also change the + * devPrivate.ptr and devKind of the screen pixmap, update any offscreen + * pixmaps it may have moved, and change pScrn->displayWidth. + */ + Bool + (*resize)(ScrnInfoPtr scrn, + int width, + int height); +} xf86CrtcConfigFuncsRec, *xf86CrtcConfigFuncsPtr; + typedef struct _xf86CrtcConfig { int num_output; xf86OutputPtr *output; @@ -435,6 +454,8 @@ typedef struct _xf86CrtcConfig { int dga_width, dga_height, dga_stride; DisplayModePtr dga_save_mode; + const xf86CrtcConfigFuncsRec *funcs; + } xf86CrtcConfigRec, *xf86CrtcConfigPtr; extern int xf86CrtcConfigPrivateIndex; @@ -446,7 +467,8 @@ extern int xf86CrtcConfigPrivateIndex; */ void -xf86CrtcConfigInit (ScrnInfoPtr scrn); +xf86CrtcConfigInit (ScrnInfoPtr scrn, + const xf86CrtcConfigFuncsRec *funcs); void xf86CrtcSetSizeRange (ScrnInfoPtr scrn, diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index abdf92e78..052d12aa3 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -335,8 +335,9 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen, { XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); WindowPtr pRoot = WindowTable[pScreen->myNum]; - Bool ret = TRUE; + Bool ret = FALSE; if (randrp->virtualX == -1 || randrp->virtualY == -1) { @@ -345,20 +346,26 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen, } if (pRoot) (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE); - pScrn->virtualX = width; - pScrn->virtualY = height; - pScreen->width = pScrn->virtualX; - pScreen->height = pScrn->virtualY; + /* Let the driver update virtualX and virtualY */ + if (!(*config->funcs->resize)(pScrn, width, height)) + goto finish; + + ret = TRUE; + + pScreen->width = width; + pScreen->height = height; pScreen->mmWidth = mmWidth; pScreen->mmHeight = mmHeight; xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1); xf86SetViewport (pScreen, 0, 0); + +finish: if (pRoot) (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE); #if RANDR_12_INTERFACE - if (WindowTable[pScreen->myNum]) + if (WindowTable[pScreen->myNum] && ret) RRScreenSizeNotify (pScreen); #endif return ret; @@ -904,15 +911,14 @@ xf86RandR12CreateScreenResources12 (ScreenPtr pScreen) { int c; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); for (c = 0; c < config->num_crtc; c++) xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc); - RRScreenSetSizeRange (pScreen, 320, 240, - randrp->virtualX, randrp->virtualY); + RRScreenSetSizeRange (pScreen, config->minWidth, config->minHeight, + config->maxWidth, config->maxHeight); return TRUE; }