summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nv_driver.c123
-rw-r--r--src/nv_include.h4
-rw-r--r--src/nv_shadow.c15
-rw-r--r--src/nv_type.h1
4 files changed, 132 insertions, 11 deletions
diff --git a/src/nv_driver.c b/src/nv_driver.c
index b82c049..8e19c01 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -1,4 +1,4 @@
-/* $XdotOrg: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.13 2005/06/29 15:56:23 alanc Exp $ */
+/* $XdotOrg: driver/xf86-video-nv/src/nv_driver.c,v 1.18 2005/09/29 21:47:29 aplattner Exp $ */
/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
/*
* Copyright 1996-1997 David J. McKay
@@ -58,6 +58,10 @@ static Bool NVSaveScreen(ScreenPtr pScreen, int mode);
static void NVFreeScreen(int scrnIndex, int flags);
static ModeStatus NVValidMode(int scrnIndex, DisplayModePtr mode,
Bool verbose, int flags);
+#ifdef RANDR
+static Bool NVDriverFunc(ScrnInfoPtr pScrnInfo, xorgDriverFuncOp op,
+ pointer data);
+#endif
/* Internally used functions */
@@ -1236,6 +1240,7 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
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 +1257,29 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
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;
+ 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 +1861,7 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
int ret;
VisualPtr visual;
unsigned char *FBStart;
- int width, height, displayWidth, offscreenHeight;
+ int width, height, displayWidth, offscreenHeight, shadowHeight;
BoxRec AvailFBArea;
/*
@@ -1925,9 +1946,18 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
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 +2049,21 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
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 +2077,7 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pScrn->memPhysBase = pNv->FbAddress;
pScrn->fbOffset = 0;
- if(pNv->Rotate == 0)
+ if(pNv->Rotate == 0 && !pNv->RandRRotation)
NVInitVideo(pScreen);
pScreen->SaveScreen = NVSaveScreen;
@@ -2056,6 +2089,13 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pNv->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = NVBlockHandler;
+#ifdef RANDR
+ /* Install our DriverFunc. We have to do it this way instead of using the
+ * HaveDriverFuncs argument to xf86AddDriver, because InitOutput clobbers
+ * pScrn->DriverFunc */
+ pScrn->DriverFunc = NVDriverFunc;
+#endif
+
/* Report any unused options (only for the first generation) */
if (serverGeneration == 1) {
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
@@ -2087,3 +2127,64 @@ NVSave(ScrnInfoPtr pScrn)
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
diff --git a/src/nv_include.h b/src/nv_include.h
index bcdb481..23ad9b7 100644
--- a/src/nv_include.h
+++ b/src/nv_include.h
@@ -52,6 +52,10 @@
#include "region.h"
+#ifdef RANDR
+#include <X11/extensions/randr.h>
+#endif
+
#include "nv_local.h"
#include "nv_type.h"
#include "nv_proto.h"
diff --git a/src/nv_shadow.c b/src/nv_shadow.c
index 2278bb7..e695288 100644
--- a/src/nv_shadow.c
+++ b/src/nv_shadow.c
@@ -68,6 +68,11 @@ NVRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
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 @@ NVRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
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 @@ NVRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
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;
diff --git a/src/nv_type.h b/src/nv_type.h
index cdbe619..d704e2e 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -172,6 +172,7 @@ typedef struct {
CARD32 currentRop;
Bool WaitVSyncPossible;
Bool BlendingPossible;
+ Bool RandRRotation;
} NVRec, *NVPtr;
#define NVPTR(p) ((NVPtr)((p)->driverPrivate))