Index: xfree86/common/xf86Init.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/common/xf86Init.c,v retrieving revision 1.26 diff -u -r1.26 xf86Init.c --- xfree86/common/xf86Init.c 5 Oct 2005 16:39:09 -0000 1.26 +++ xfree86/common/xf86Init.c 7 Oct 2005 04:26:32 -0000 @@ -932,7 +932,6 @@ xf86Screens[i]->DPMSSet = NULL; xf86Screens[i]->LoadPalette = NULL; xf86Screens[i]->SetOverscan = NULL; - xf86Screens[i]->DriverFunc = NULL; xf86Screens[i]->pScreen = NULL; scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv); if (scr_index == i) { Index: xfree86/common/xf86RandR.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v retrieving revision 1.13 diff -u -r1.13 xf86RandR.c --- xfree86/common/xf86RandR.c 30 Sep 2005 08:54:44 -0000 1.13 +++ xfree86/common/xf86RandR.c 7 Oct 2005 04:26:32 -0000 @@ -109,12 +109,8 @@ /* If there is driver support for randr, let it set our supported rotations */ if(scrp->DriverFunc) { - xorgRRRotation RRRotation; - - RRRotation.RRRotations = *rotations; - if (!(*scrp->DriverFunc)(scrp, RR_GET_INFO, &RRRotation)) + if (!(*scrp->DriverFunc)(scrp, RR_GET_INFO, rotations)) return TRUE; - *rotations = RRRotation.RRRotations; } return TRUE; @@ -223,16 +219,16 @@ /* Have the driver do its thing. */ if (scrp->DriverFunc) { - xorgRRRotation RRRotation; - RRRotation.RRConfig.rotation = rotation; - RRRotation.RRConfig.rate = rate; - RRRotation.RRConfig.width = pSize->width; - RRRotation.RRConfig.height = pSize->height; + xorgRRConfig RRConfig; + RRConfig.rotation = rotation; + RRConfig.rate = rate; + RRConfig.width = pSize->width; + RRConfig.height = pSize->height; /* * Currently we need to rely on HW support for rotation. */ - if (!(*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation)) + if (!(*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRConfig)) return FALSE; } else return FALSE; @@ -244,12 +240,12 @@ if(randrp->rotation != oldRotation) { /* Have the driver undo its thing. */ if (scrp->DriverFunc) { - xorgRRRotation RRRotation; - RRRotation.RRConfig.rotation = oldRotation; - RRRotation.RRConfig.rate = xf86RandRModeRefresh (scrp->currentMode); - RRRotation.RRConfig.width = pScreen->width; - RRRotation.RRConfig.height = pScreen->height; - (*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation); + xorgRRConfig RRConfig; + RRConfig.rotation = oldRotation; + RRConfig.rate = xf86RandRModeRefresh (scrp->currentMode); + RRConfig.width = pScreen->width; + RRConfig.height = pScreen->height; + (*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRConfig); } randrp->rotation = oldRotation; Index: xfree86/common/xf86str.h =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/common/xf86str.h,v retrieving revision 1.9 diff -u -r1.9 xf86str.h --- xfree86/common/xf86str.h 24 Aug 2005 11:18:32 -0000 1.9 +++ xfree86/common/xf86str.h 7 Oct 2005 04:26:35 -0000 @@ -261,11 +261,6 @@ int height; } xorgRRConfig; -typedef union { - short RRRotations; - xorgRRConfig RRConfig; -} xorgRRRotation, *xorgRRRotationPtr; - /* GET_REQUIRED_HW_INTERFACES */ #define HW_IO 1 #define HW_MMIO 2 Index: xfree86/drivers/nv/nv.man =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/nv/nv.man,v retrieving revision 1.4 diff -u -r1.4 nv.man --- xfree86/drivers/nv/nv.man 9 Jul 2005 16:51:58 -0000 1.4 +++ xfree86/drivers/nv/nv.man 7 Oct 2005 04:26:38 -0000 @@ -122,6 +122,11 @@ Note: The Resize and Rotate extension will be disabled if the Rotate option is used. .TP +.BI "Option \*qRotate\*q \*qRandR\*q" +Enable rotation of the screen using the Resize and Rotate extension. +This mode is unaccelerated. +Default: no rotation support. +.TP .BI "Option \*qShadowFB\*q \*q" boolean \*q Enable or disable use of the shadow framebuffer layer. Default: off. .SH "SEE ALSO" Index: xfree86/drivers/nv/nv_driver.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v retrieving revision 1.18 diff -u -r1.18 nv_driver.c --- xfree86/drivers/nv/nv_driver.c 29 Sep 2005 21:47:29 -0000 1.18 +++ xfree86/drivers/nv/nv_driver.c 7 Oct 2005 04:26:42 -0000 @@ -58,6 +58,8 @@ static void NVFreeScreen(int scrnIndex, int flags); static ModeStatus NVValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags); +static Bool NVDriverFunc(ScrnInfoPtr pScrnInfo, xorgDriverFuncOp op, + pointer data); /* Internally used functions */ @@ -84,9 +86,18 @@ NVProbe, NVAvailableOptions, NULL, - 0 + 0, +#ifdef RANDR + NVDriverFunc +#endif }; +#ifdef RANDR +#define NVHaveDriverFuncs HaveDriverFuncs +#else +#define NVHaveDriverFuncs 0 +#endif + /* Known cards as of 2005/09/21 */ static SymTabRec NVKnownChipsets[] = @@ -520,7 +531,7 @@ if (!setupDone) { setupDone = TRUE; - xf86AddDriver(&NV, module, 0); + xf86AddDriver(&NV, module, NVHaveDriverFuncs); /* * Modules that this driver always requires may be loaded here @@ -1236,6 +1247,7 @@ pScrn->ValidMode = fbdevHWValidModeWeak(); } pNv->Rotate = 0; + pNv->RandRRotation = FALSE; if ((s = xf86GetOptValString(pNv->Options, OPTION_ROTATE))) { if(!xf86NameCmp(s, "CW")) { pNv->ShadowFB = TRUE; @@ -1252,13 +1264,30 @@ pNv->Rotate = -1; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen counter clockwise - acceleration disabled\n"); + } else + if(!xf86NameCmp(s, "RandR")) { +#ifdef RANDR + pNv->ShadowFB = TRUE; + pNv->NoAccel = TRUE; + pNv->HWCursor = FALSE; + pNv->RandRRotation = TRUE; + pNv->Rotate = 0; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using RandR rotation - acceleration disabled\n"); +#else + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "This driver was not compiled with support for the Resize and " + "Rotate extension. Cannot honor 'Option \"Rotate\" " + "\"RandR\"'.\n"); +#endif } else { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid value for Option \"Rotate\"\n", s); xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Valid options are \"CW\" or \"CCW\"\n"); + "Valid options are \"CW\", \"CCW\", and \"RandR\"\n"); } } + if(xf86GetOptValInteger(pNv->Options, OPTION_VIDEO_KEY, &(pNv->videoKey))) { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", pNv->videoKey); @@ -1840,7 +1869,7 @@ int ret; VisualPtr visual; unsigned char *FBStart; - int width, height, displayWidth, offscreenHeight; + int width, height, displayWidth, offscreenHeight, shadowHeight; BoxRec AvailFBArea; /* @@ -1925,9 +1954,18 @@ width = pScrn->virtualY; } + /* If RandR rotation is enabled, leave enough space in the + * framebuffer for us to rotate the screen dimensions without + * changing the pitch. + */ + if(pNv->RandRRotation) + shadowHeight = max(width, height); + else + shadowHeight = height; + if(pNv->ShadowFB) { pNv->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); - pNv->ShadowPtr = xalloc(pNv->ShadowPitch * height); + pNv->ShadowPtr = xalloc(pNv->ShadowPitch * shadowHeight); displayWidth = pNv->ShadowPitch / (pScrn->bitsPerPixel >> 3); FBStart = pNv->ShadowPtr; } else { @@ -2019,18 +2057,21 @@ if(pNv->ShadowFB) { RefreshAreaFuncPtr refreshArea = NVRefreshArea; - if(pNv->Rotate) { - pNv->PointerMoved = pScrn->PointerMoved; - pScrn->PointerMoved = NVPointerMoved; + if(pNv->Rotate || pNv->RandRRotation) { + pNv->PointerMoved = pScrn->PointerMoved; + if(pNv->Rotate) + pScrn->PointerMoved = NVPointerMoved; switch(pScrn->bitsPerPixel) { case 8: refreshArea = NVRefreshArea8; break; case 16: refreshArea = NVRefreshArea16; break; case 32: refreshArea = NVRefreshArea32; break; } - xf86DisableRandR(); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Driver rotation enabled, RandR disabled\n"); + if(!pNv->RandRRotation) { + xf86DisableRandR(); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Driver rotation enabled, RandR disabled\n"); + } } ShadowFBInit(pScreen, refreshArea); @@ -2044,7 +2085,7 @@ pScrn->memPhysBase = pNv->FbAddress; pScrn->fbOffset = 0; - if(pNv->Rotate == 0) + if(pNv->Rotate == 0 && !pNv->RandRRotation) NVInitVideo(pScreen); pScreen->SaveScreen = NVSaveScreen; @@ -2087,3 +2128,64 @@ NVDACSave(pScrn, vgaReg, nvReg, pNv->Primary); } +#ifdef RANDR +static Bool +NVRandRGetInfo(ScrnInfoPtr pScrn, Rotation *rotations) +{ + NVPtr pNv = NVPTR(pScrn); + + if(pNv->RandRRotation) + *rotations = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_270; + else + *rotations = RR_Rotate_0; + + return TRUE; +} + +static Bool +NVRandRSetConfig(ScrnInfoPtr pScrn, xorgRRConfig *config) +{ + NVPtr pNv = NVPTR(pScrn); + + switch(config->rotation) { + case RR_Rotate_0: + pNv->Rotate = 0; + pScrn->PointerMoved = pNv->PointerMoved; + break; + + case RR_Rotate_90: + pNv->Rotate = -1; + pScrn->PointerMoved = NVPointerMoved; + break; + + case RR_Rotate_270: + pNv->Rotate = 1; + pScrn->PointerMoved = NVPointerMoved; + break; + + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Unexpected rotation in NVRandRSetConfig!\n"); + pNv->Rotate = 0; + pScrn->PointerMoved = pNv->PointerMoved; + return FALSE; + } + + return TRUE; +} + +static Bool +NVDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer data) +{ + switch(op) { + case RR_GET_INFO: + return NVRandRGetInfo(pScrn, (Rotation*)data); + case RR_SET_CONFIG: + return NVRandRSetConfig(pScrn, (xorgRRConfig*)data); + default: + return FALSE; + } + + return FALSE; +} +#endif Index: xfree86/drivers/nv/nv_include.h =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_include.h,v retrieving revision 1.3 diff -u -r1.3 nv_include.h --- xfree86/drivers/nv/nv_include.h 20 Apr 2005 12:25:29 -0000 1.3 +++ xfree86/drivers/nv/nv_include.h 7 Oct 2005 04:26:42 -0000 @@ -52,6 +52,10 @@ #include "region.h" +#ifdef RANDR +#include +#endif + #include "nv_local.h" #include "nv_type.h" #include "nv_proto.h" Index: xfree86/drivers/nv/nv_shadow.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_shadow.c,v retrieving revision 1.3 diff -u -r1.3 nv_shadow.c --- xfree86/drivers/nv/nv_shadow.c 11 Jul 2005 02:29:58 -0000 1.3 +++ xfree86/drivers/nv/nv_shadow.c 7 Oct 2005 04:26:42 -0000 @@ -68,6 +68,11 @@ CARD8 *dstPtr, *srcPtr, *src; CARD32 *dst; + if(!pNv->Rotate) { + NVRefreshArea(pScrn, num, pbox); + return; + } + dstPitch = pScrn->displayWidth; srcPitch = -pNv->Rotate * pNv->ShadowPitch; @@ -114,6 +119,11 @@ CARD16 *dstPtr, *srcPtr, *src; CARD32 *dst; + if(!pNv->Rotate) { + NVRefreshArea(pScrn, num, pbox); + return; + } + dstPitch = pScrn->displayWidth; srcPitch = -pNv->Rotate * pNv->ShadowPitch >> 1; @@ -159,6 +169,11 @@ int count, width, height, dstPitch, srcPitch; CARD32 *dstPtr, *srcPtr, *src, *dst; + if(!pNv->Rotate) { + NVRefreshArea(pScrn, num, pbox); + return; + } + dstPitch = pScrn->displayWidth; srcPitch = -pNv->Rotate * pNv->ShadowPitch >> 2; Index: xfree86/drivers/nv/nv_type.h =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_type.h,v retrieving revision 1.5 diff -u -r1.5 nv_type.h --- xfree86/drivers/nv/nv_type.h 21 Apr 2005 22:25:47 -0000 1.5 +++ xfree86/drivers/nv/nv_type.h 7 Oct 2005 04:26:42 -0000 @@ -172,6 +172,7 @@ CARD32 currentRop; Bool WaitVSyncPossible; Bool BlendingPossible; + Bool RandRRotation; } NVRec, *NVPtr; #define NVPTR(p) ((NVPtr)((p)->driverPrivate))