xserver: Branch 'server-1.6-branch' - 10 commits
Keith Packard
keithp at kemper.freedesktop.org
Tue Dec 9 21:59:12 PST 2008
hw/xfree86/modes/xf86Crtc.c | 25 ++++
hw/xfree86/modes/xf86Crtc.h | 36 ++++++
hw/xfree86/modes/xf86RandR12.c | 233 +++++++++++++++++++++++++++++++++++++++++
randr/randrstr.h | 19 +++
randr/rrcrtc.c | 152 ++++++++++++++++++++++++++
randr/rrdispatch.c | 2
randr/rrsdispatch.c | 39 ++++++
7 files changed, 503 insertions(+), 3 deletions(-)
New commits:
commit 4810226dfc52ef798b507d284030b4b3aec020a6
Author: Matthias Hopf <mhopf at suse.de>
Date: Fri Dec 5 15:37:15 2008 +0100
randr: Update SProcRandrVector for panning
(cherry picked from commit 44bef8b850c5a78a3d3eca5f0d92b71bdd0a87e2)
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/randr/rrsdispatch.c b/randr/rrsdispatch.c
index d356ab0..3ff9f3f 100644
--- a/randr/rrsdispatch.c
+++ b/randr/rrsdispatch.c
@@ -399,6 +399,43 @@ SProcRRGetCrtcTransform (ClientPtr client)
return (*ProcRandrVector[stuff->randrReqType]) (client);
}
+static int
+SProcRRGetPanning (ClientPtr client)
+{
+ int n;
+ REQUEST(xRRGetPanningReq);
+
+ REQUEST_SIZE_MATCH(xRRGetPanningReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->crtc, n);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetPanning (ClientPtr client)
+{
+ int n;
+ REQUEST(xRRSetPanningReq);
+
+ REQUEST_SIZE_MATCH(xRRSetPanningReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->crtc, n);
+ swapl(&stuff->timestamp, n);
+ swaps(&stuff->left, n);
+ swaps(&stuff->top, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ swaps(&stuff->track_left, n);
+ swaps(&stuff->track_top, n);
+ swaps(&stuff->track_width, n);
+ swaps(&stuff->track_height, n);
+ swaps(&stuff->border_left, n);
+ swaps(&stuff->border_top, n);
+ swaps(&stuff->border_right, n);
+ swaps(&stuff->border_bottom, n);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
SProcRRQueryVersion, /* 0 */
/* we skip 1 to make old clients fail pretty immediately */
@@ -433,5 +470,7 @@ int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
SProcRRGetScreenResources, /* 25 GetScreenResourcesCurrent */
SProcRRSetCrtcTransform, /* 26 */
SProcRRGetCrtcTransform, /* 27 */
+ SProcRRGetPanning, /* 28 */
+ SProcRRSetPanning, /* 29 */
};
commit 798a4878a4ffb03024e77ea6ddbd9b170b9c3fe4
Author: Matthias Hopf <mhopf at suse.de>
Date: Thu Dec 4 18:13:40 2008 +0100
randr: Allow panning to be disabled per axis
(cherry picked from commit e5ab9e66628cde081757cf2a1013a78e927a622e)
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 879f4a2..362229c 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -182,8 +182,8 @@ xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
return;
if (! crtc->enabled ||
- crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 ||
- crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1)
+ (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 &&
+ crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1))
return;
newX = crtc->x;
@@ -191,26 +191,36 @@ xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
width = crtc->mode.HDisplay;
height = crtc->mode.VDisplay;
- if (x >= crtc->panningTrackingArea.x1 && x < crtc->panningTrackingArea.x2 &&
- y >= crtc->panningTrackingArea.y1 && y < crtc->panningTrackingArea.y2) {
- if (x < crtc->x + crtc->panningBorder[0])
- newX = x - crtc->panningBorder[0];
- if (x >= crtc->x + width - crtc->panningBorder[2])
- newX = x - width + crtc->panningBorder[2] + 1;
- if (y < crtc->y + crtc->panningBorder[1])
- newY = y - crtc->panningBorder[1];
- if (y >= crtc->y + height - crtc->panningBorder[3])
- newY = y - height + crtc->panningBorder[3] + 1;
+ if ((crtc->panningTrackingArea.x2 <= crtc->panningTrackingArea.x1 ||
+ (x >= crtc->panningTrackingArea.x1 && x < crtc->panningTrackingArea.x2)) &&
+ (crtc->panningTrackingArea.y2 <= crtc->panningTrackingArea.y1 ||
+ (y >= crtc->panningTrackingArea.y1 && y < crtc->panningTrackingArea.y2))) {
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
+ if (x < crtc->x + crtc->panningBorder[0])
+ newX = x - crtc->panningBorder[0];
+ if (x >= crtc->x + width - crtc->panningBorder[2])
+ newX = x - width + crtc->panningBorder[2] + 1;
+ }
+ if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+ if (y < crtc->y + crtc->panningBorder[1])
+ newY = y - crtc->panningBorder[1];
+ if (y >= crtc->y + height - crtc->panningBorder[3])
+ newY = y - height + crtc->panningBorder[3] + 1;
+ }
}
/* Validate against [xy]1 after [xy]2, to be sure that results are > 0 for [xy]1 > 0 */
- if (newX >= crtc->panningTotalArea.x2 - width)
- newX = crtc->panningTotalArea.x2 - width - 1;
- if (newX < crtc->panningTotalArea.x1)
- newX = crtc->panningTotalArea.x1;
- if (newY >= crtc->panningTotalArea.y2 - height)
- newY = crtc->panningTotalArea.y2 - height - 1;
- if (newY < crtc->panningTotalArea.y1)
- newY = crtc->panningTotalArea.y1;
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
+ if (newX >= crtc->panningTotalArea.x2 - width)
+ newX = crtc->panningTotalArea.x2 - width - 1;
+ if (newX < crtc->panningTotalArea.x1)
+ newX = crtc->panningTotalArea.x1;
+ }
+ if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+ if (newY >= crtc->panningTotalArea.y2 - height)
+ newY = crtc->panningTotalArea.y2 - height - 1;
+ if (newY < crtc->panningTotalArea.y1)
+ newY = crtc->panningTotalArea.y1;
+ }
if (newX != crtc->x || newY != crtc->y)
xf86CrtcSetOrigin (crtc, newX, newY);
}
@@ -485,12 +495,16 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
/* Update panning information */
for (c = 0; c < config->num_crtc; c++) {
xf86CrtcPtr crtc = config->crtc[c];
- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 &&
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 ||
crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
- crtc->panningTotalArea.x2 += width - pScreen->width;
- crtc->panningTotalArea.y2 += height - pScreen->height;
- crtc->panningTrackingArea.x2 += width - pScreen->width;
- crtc->panningTrackingArea.y2 += height - pScreen->height;
+ if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1)
+ crtc->panningTotalArea.x2 += width - pScreen->width;
+ if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1)
+ crtc->panningTotalArea.y2 += height - pScreen->height;
+ if (crtc->panningTrackingArea.x2 > crtc->panningTrackingArea.x1)
+ crtc->panningTrackingArea.x2 += width - pScreen->width;
+ if (crtc->panningTrackingArea.y2 > crtc->panningTrackingArea.y1)
+ crtc->panningTrackingArea.y2 += height - pScreen->height;
xf86RandR13VerifyPanningArea (crtc, width, height);
xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
}
commit 5fa2cce83cc2df560ce62ec4bbf88233ee70e64a
Author: Matthias Hopf <mhopf at suse.de>
Date: Thu Dec 4 16:55:14 2008 +0100
randr: Rework panning area verification
(cherry picked from commit bad118ace6c5bae5a5ed8a35129c90c38f1c1932)
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 0b1dcb5..879f4a2 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -88,40 +88,88 @@ xf86RandR12ModeRefresh (DisplayModePtr mode)
return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
}
+/* Adapt panning area; return TRUE if panning area was valid without adaption */
static int
xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeight)
{
+ int ret = TRUE;
+
if (crtc->version < 2)
return FALSE;
- if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 ||
- crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) {
- memset (&crtc->panningTotalArea, 0, sizeof(BoxRec));
- memset (&crtc->panningTrackingArea, 0, sizeof(BoxRec));
- memset (&crtc->panningBorder, 0, 4*sizeof(INT16));
- return TRUE;
+ if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1) {
+ /* Panning in X is disabled */
+ if (crtc->panningTotalArea.x1 || crtc->panningTotalArea.x2)
+ /* Illegal configuration -> fail/disable */
+ ret = FALSE;
+ crtc->panningTotalArea.x1 = crtc->panningTotalArea.x2 = 0;
+ crtc->panningTrackingArea.x1 = crtc->panningTrackingArea.x2 = 0;
+ crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
+ } else {
+ /* Panning in X is enabled */
+ if (crtc->panningTotalArea.x1 < 0) {
+ /* Panning region outside screen -> move inside */
+ crtc->panningTotalArea.x2 -= crtc->panningTotalArea.x1;
+ crtc->panningTotalArea.x1 = 0;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay) {
+ /* Panning region smaller than displayed area -> crop to displayed area */
+ crtc->panningTotalArea.x2 = crtc->panningTotalArea.x1 + crtc->mode.HDisplay;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.x2 > screenWidth) {
+ /* Panning region larger than screen -> move inside, then crop to screen */
+ crtc->panningTotalArea.x1 -= crtc->panningTotalArea.x2 - screenWidth;
+ crtc->panningTotalArea.x2 = screenWidth;
+ ret = FALSE;
+ if (crtc->panningTotalArea.x1 < 0)
+ crtc->panningTotalArea.x1 = 0;
+ }
+ if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay) {
+ /* Borders too large -> set to 0 */
+ crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
+ ret = FALSE;
+ }
}
- if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 ||
- crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1 ||
- crtc->panningTotalArea.x1 < 0 ||
- crtc->panningTotalArea.y1 < 0 ||
- crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay ||
- crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay ||
- crtc->panningTotalArea.x2 > screenWidth ||
- crtc->panningTotalArea.y2 > screenHeight)
- {
- memset (&crtc->panningTotalArea, 0, sizeof(BoxRec));
- memset (&crtc->panningTrackingArea, 0, sizeof(BoxRec));
- memset (&crtc->panningBorder, 0, 4*sizeof(INT16));
- return FALSE;
- }
- if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay ||
- crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) {
- memset (&crtc->panningBorder, 0, 4*sizeof(INT16));
- return FALSE;
+ if (crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) {
+ /* Panning in Y is disabled */
+ if (crtc->panningTotalArea.y1 || crtc->panningTotalArea.y2)
+ /* Illegal configuration -> fail/disable */
+ ret = FALSE;
+ crtc->panningTotalArea.y1 = crtc->panningTotalArea.y2 = 0;
+ crtc->panningTrackingArea.y1 = crtc->panningTrackingArea.y2 = 0;
+ crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
+ } else {
+ /* Panning in Y is enabled */
+ if (crtc->panningTotalArea.y1 < 0) {
+ /* Panning region outside screen -> move inside */
+ crtc->panningTotalArea.y2 -= crtc->panningTotalArea.y1;
+ crtc->panningTotalArea.y1 = 0;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay) {
+ /* Panning region smaller than displayed area -> crop to displayed area */
+ crtc->panningTotalArea.y2 = crtc->panningTotalArea.y1 + crtc->mode.VDisplay;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.y2 > screenHeight) {
+ /* Panning region larger than screen -> move inside, then crop to screen */
+ crtc->panningTotalArea.y1 -= crtc->panningTotalArea.y2 - screenHeight;
+ crtc->panningTotalArea.y2 = screenHeight;
+ ret = FALSE;
+ if (crtc->panningTotalArea.y1 < 0)
+ crtc->panningTotalArea.y1 = 0;
+ }
+ if (crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) {
+ /* Borders too large -> set to 0 */
+ crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
+ ret = FALSE;
+ }
}
- return TRUE;
+
+ return ret;
}
static void
commit 97e8a75ce3c70e7a83028b256b6884084f5e196b
Author: Matthias Hopf <mhopf at suse.de>
Date: Thu Dec 4 16:28:40 2008 +0100
randr: Don't change panning parameters if verification fails.
(cherry picked from commit 219c26ce0c65625d55cfd943ec66fe94a1a0ddfd)
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 0e7a5ec..0b1dcb5 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1327,20 +1327,35 @@ xf86RandR13SetPanning (ScreenPtr pScreen,
{
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
xf86CrtcPtr crtc = randr_crtc->devPrivate;
- int ret;
+ BoxRec oldTotalArea;
+ BoxRec oldTrackingArea;
+ INT16 oldBorder[4];
+
if (crtc->version < 2)
return FALSE;
+
+ memcpy (&oldTotalArea, &crtc->panningTotalArea, sizeof(BoxRec));
+ memcpy (&oldTrackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
+ memcpy (oldBorder, crtc->panningBorder, 4*sizeof(INT16));
+
if (totalArea)
memcpy (&crtc->panningTotalArea, totalArea, sizeof(BoxRec));
if (trackingArea)
memcpy (&crtc->panningTrackingArea, trackingArea, sizeof(BoxRec));
if (border)
memcpy (crtc->panningBorder, border, 4*sizeof(INT16));
- ret = xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height);
- xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
- return ret;
+ if (xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height)) {
+ xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+ return TRUE;
+ } else {
+ /* Restore old settings */
+ memcpy (&crtc->panningTotalArea, &oldTotalArea, sizeof(BoxRec));
+ memcpy (&crtc->panningTrackingArea, &oldTrackingArea, sizeof(BoxRec));
+ memcpy (crtc->panningBorder, oldBorder, 4*sizeof(INT16));
+ return FALSE;
+ }
}
static Bool
commit 6189f0832ecd6930608f5b253e534bb104174694
Author: Matthias Hopf <mhopf at suse.de>
Date: Thu Dec 4 16:30:38 2008 +0100
randr: Rename pan() to set_origin(), and xf86CrtcPan() to xf86CrtcSetOrigin()
(cherry picked from commit 18a8bac1a1567b6215928f96870554ea63f39aab)
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 051916d..9717620 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -324,10 +324,10 @@ xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotati
crtc->x, crtc->y);
}
- if (crtc->funcs->pan &&
+ if (crtc->funcs->set_origin &&
memcmp (mode, &saved_mode, sizeof(saved_mode)) == 0 &&
saved_rotation == rotation) {
- crtc->funcs->pan (crtc, crtc->x, crtc->y);
+ crtc->funcs->set_origin (crtc, crtc->x, crtc->y);
ret = TRUE;
goto done;
}
@@ -424,12 +424,12 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
* Pans the screen, does not change the mode
*/
_X_EXPORT void
-xf86CrtcPan (xf86CrtcPtr crtc, int x, int y)
+xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y)
{
crtc->x = x;
crtc->y = y;
- if (crtc->funcs->pan)
- crtc->funcs->pan (crtc, x, y);
+ if (crtc->funcs->set_origin)
+ crtc->funcs->set_origin (crtc, x, y);
else
xf86CrtcSetMode (crtc, &crtc->mode, crtc->rotation, x, y);
}
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index f085bf7..5e47e6f 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -218,7 +218,7 @@ typedef struct _xf86CrtcFuncs {
* Callback for panning. Doesn't change the mode.
*/
void
- (*pan)(xf86CrtcPtr crtc, int x, int y);
+ (*set_origin)(xf86CrtcPtr crtc, int x, int y);
} xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
@@ -695,7 +695,7 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
int x, int y);
void
-xf86CrtcPan (xf86CrtcPtr crtc, int x, int y);
+xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y);
/*
* Assign crtc rotation during mode set
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index caf6429..0e7a5ec 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -164,7 +164,7 @@ xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
if (newY < crtc->panningTotalArea.y1)
newY = crtc->panningTotalArea.y1;
if (newX != crtc->x || newY != crtc->y)
- xf86CrtcPan (crtc, newX, newY);
+ xf86CrtcSetOrigin (crtc, newX, newY);
}
static Bool
commit 68858b202a0c32e8cc3fb22ca4714c1baa05b44c
Author: Matthias Hopf <mhopf at suse.de>
Date: Thu Dec 4 16:11:21 2008 +0100
randr: Nuke config-timestamp for panning
(cherry picked from commit 825b2c2f4a59ac4852f90bbbddf18ab832297fdd)
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index b8e4d11..99f7d1e 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -1056,7 +1056,6 @@ ProcRRSetPanning (ClientPtr client)
RRCrtcPtr crtc;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
- TimeStamp configTime;
TimeStamp time;
BoxRec total;
BoxRec tracking;
@@ -1083,21 +1082,7 @@ ProcRRSetPanning (ClientPtr client)
}
time = ClientTimeToServerTime(stuff->timestamp);
- configTime = ClientTimeToServerTime(stuff->configTimestamp);
-#if 0
- /*
- * if the client's config timestamp is not the same as the last config
- * timestamp, then the config information isn't up-to-date and
- * can't even be validated
- */
- if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0)
- {
- rep.status = RRSetConfigInvalidConfigTime;
- goto sendReply;
- }
-#endif
-
/*
* Make sure the requested set-time is not older than
* the last set-time
commit 7cbded550d3bebc35e2322a89d0afbb57b37b3da
Author: Matthias Hopf <mhopf at suse.de>
Date: Fri Nov 28 17:51:20 2008 +0100
randr: Protocol bits for panning support
(cherry picked from commit eeeb98d1df59baaaec954b6318d788a37e388d11)
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 64206e8..f6aa5c7 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -190,6 +190,17 @@ typedef void (*RRModeDestroyProcPtr) (ScreenPtr pScreen,
typedef Bool (*RROutputGetPropertyProcPtr) (ScreenPtr pScreen,
RROutputPtr output,
Atom property);
+typedef Bool (*RRGetPanningProcPtr) (ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border);
+typedef Bool (*RRSetPanningProcPtr) (ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border);
+
#endif /* RANDR_13_INTERFACE */
typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations);
@@ -239,6 +250,8 @@ typedef struct _rrScrPriv {
#endif
#if RANDR_13_INTERFACE
RROutputGetPropertyProcPtr rrOutputGetProperty;
+ RRGetPanningProcPtr rrGetPanning;
+ RRSetPanningProcPtr rrSetPanning;
#endif
/*
@@ -686,6 +699,12 @@ ProcRRSetCrtcTransform (ClientPtr client);
int
ProcRRGetCrtcTransform (ClientPtr client);
+int
+ProcRRGetPanning (ClientPtr client);
+
+int
+ProcRRSetPanning (ClientPtr client);
+
/* rrdispatch.c */
Bool
RRClientKnowsRates (ClientPtr pClient);
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 90d93b5..b8e4d11 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -978,6 +978,173 @@ sendReply:
}
int
+ProcRRGetPanning (ClientPtr client)
+{
+ REQUEST(xRRGetPanningReq);
+ xRRGetPanningReply rep;
+ RRCrtcPtr crtc;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ BoxRec total;
+ BoxRec tracking;
+ INT16 border[4];
+ int n;
+
+ REQUEST_SIZE_MATCH(xRRGetPanningReq);
+ crtc = LookupCrtc(client, stuff->crtc, DixReadAccess);
+
+ if (!crtc)
+ return RRErrorBase + BadRRCrtc;
+
+ /* All crtcs must be associated with screens before client
+ * requests are processed
+ */
+ pScreen = crtc->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (!pScrPriv || !pScrPriv->rrGetPanning)
+ return RRErrorBase + BadRRCrtc;
+
+ rep.type = X_Reply;
+ rep.status = RRSetConfigSuccess;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 1;
+ rep.timestamp = pScrPriv->lastSetTime.milliseconds;
+
+ if (! pScrPriv->rrGetPanning (pScreen, crtc, &total, &tracking, border))
+ return RRErrorBase + BadRRCrtc;
+
+ rep.left = total.x1;
+ rep.top = total.y1;
+ rep.width = total.x2 - total.x1;
+ rep.height = total.y2 - total.y1;
+ rep.track_left = tracking.x1;
+ rep.track_top = tracking.y1;
+ rep.track_width = tracking.x2 - tracking.x1;
+ rep.track_height = tracking.y2 - tracking.y1;
+ rep.border_left = border[0];
+ rep.border_top = border[1];
+ rep.border_right = border[2];
+ rep.border_bottom = border[3];
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.timestamp, n);
+ swaps(&rep.left, n);
+ swaps(&rep.top, n);
+ swaps(&rep.width, n);
+ swaps(&rep.height, n);
+ swaps(&rep.track_left, n);
+ swaps(&rep.track_top, n);
+ swaps(&rep.track_width, n);
+ swaps(&rep.track_height, n);
+ swaps(&rep.border_left, n);
+ swaps(&rep.border_top, n);
+ swaps(&rep.border_right, n);
+ swaps(&rep.border_bottom, n);
+ }
+ WriteToClient(client, sizeof(xRRGetPanningReply), (char *)&rep);
+ return client->noClientException;
+}
+
+int
+ProcRRSetPanning (ClientPtr client)
+{
+ REQUEST(xRRSetPanningReq);
+ xRRSetPanningReply rep;
+ RRCrtcPtr crtc;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ TimeStamp configTime;
+ TimeStamp time;
+ BoxRec total;
+ BoxRec tracking;
+ INT16 border[4];
+ int n;
+
+ REQUEST_SIZE_MATCH(xRRSetPanningReq);
+ crtc = LookupCrtc(client, stuff->crtc, DixReadAccess);
+
+ if (!crtc)
+ return RRErrorBase + BadRRCrtc;
+
+
+ /* All crtcs must be associated with screens before client
+ * requests are processed
+ */
+ pScreen = crtc->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (!pScrPriv) {
+ time = currentTime;
+ rep.status = RRSetConfigFailed;
+ goto sendReply;
+ }
+
+ time = ClientTimeToServerTime(stuff->timestamp);
+ configTime = ClientTimeToServerTime(stuff->configTimestamp);
+
+#if 0
+ /*
+ * if the client's config timestamp is not the same as the last config
+ * timestamp, then the config information isn't up-to-date and
+ * can't even be validated
+ */
+ if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0)
+ {
+ rep.status = RRSetConfigInvalidConfigTime;
+ goto sendReply;
+ }
+#endif
+
+ /*
+ * Make sure the requested set-time is not older than
+ * the last set-time
+ */
+ if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0)
+ {
+ rep.status = RRSetConfigInvalidTime;
+ goto sendReply;
+ }
+
+ if (!pScrPriv->rrGetPanning)
+ return RRErrorBase + BadRRCrtc;
+
+ total.x1 = stuff->left;
+ total.y1 = stuff->top;
+ total.x2 = stuff->width - total.x1;
+ total.y2 = stuff->height - total.y1;
+ tracking.x1 = stuff->track_left;
+ tracking.y1 = stuff->track_top;
+ tracking.x2 = stuff->track_width - tracking.x1;
+ tracking.y2 = stuff->track_height - tracking.y1;
+ border[0] = stuff->border_left;
+ border[1] = stuff->border_top;
+ border[2] = stuff->border_right;
+ border[3] = stuff->border_bottom;
+
+ if (! pScrPriv->rrSetPanning (pScreen, crtc, &total, &tracking, border))
+ return BadMatch;
+
+ rep.status = RRSetConfigSuccess;
+
+sendReply:
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.newTimestamp, n);
+ }
+ WriteToClient(client, sizeof(xRRSetPanningReply), (char *)&rep);
+ return client->noClientException;
+}
+
+int
ProcRRGetCrtcGammaSize (ClientPtr client)
{
REQUEST(xRRGetCrtcGammaSizeReq);
diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c
index 64af6ce..0cc0bca 100644
--- a/randr/rrdispatch.c
+++ b/randr/rrdispatch.c
@@ -215,5 +215,7 @@ int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = {
ProcRRGetScreenResourcesCurrent, /* 25 */
ProcRRSetCrtcTransform, /* 26 */
ProcRRGetCrtcTransform, /* 27 */
+ ProcRRGetPanning, /* 28 */
+ ProcRRSetPanning, /* 29 */
};
commit bc05471d1184ebf72b793b1dceff9856eba616d2
Author: Matthias Hopf <mhopf at suse.de>
Date: Fri Nov 28 17:49:31 2008 +0100
randr: Panning support
(cherry picked from commit b929d721efdb17bcc94b9984c4f34d0df3d267d5)
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index a2583b8..051916d 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -324,8 +324,14 @@ xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotati
crtc->x, crtc->y);
}
- /* XXX short-circuit changes to base location only */
-
+ if (crtc->funcs->pan &&
+ memcmp (mode, &saved_mode, sizeof(saved_mode)) == 0 &&
+ saved_rotation == rotation) {
+ crtc->funcs->pan (crtc, crtc->x, crtc->y);
+ ret = TRUE;
+ goto done;
+ }
+
/* Pass our mode to the outputs and the CRTC to give them a chance to
* adjust it according to limitations or output properties, and also
* a chance to reject the mode entirely.
@@ -414,6 +420,20 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
return xf86CrtcSetModeTransform (crtc, mode, rotation, NULL, x, y);
}
+/**
+ * Pans the screen, does not change the mode
+ */
+_X_EXPORT void
+xf86CrtcPan (xf86CrtcPtr crtc, int x, int y)
+{
+ crtc->x = x;
+ crtc->y = y;
+ if (crtc->funcs->pan)
+ crtc->funcs->pan (crtc, x, y);
+ else
+ xf86CrtcSetMode (crtc, &crtc->mode, crtc->rotation, x, y);
+}
+
/*
* Output functions
*/
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 9d7750f..caf6429 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -51,6 +51,8 @@ typedef struct _xf86RandR12Info {
int mmHeight;
int maxX;
int maxY;
+ int pointerX;
+ int pointerY;
Rotation rotation; /* current mode */
Rotation supported_rotations; /* driver supported */
} XF86RandRInfoRec, *XF86RandRInfoPtr;
@@ -86,6 +88,85 @@ xf86RandR12ModeRefresh (DisplayModePtr mode)
return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
}
+static int
+xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeight)
+{
+ if (crtc->version < 2)
+ return FALSE;
+
+ if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 ||
+ crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) {
+ memset (&crtc->panningTotalArea, 0, sizeof(BoxRec));
+ memset (&crtc->panningTrackingArea, 0, sizeof(BoxRec));
+ memset (&crtc->panningBorder, 0, 4*sizeof(INT16));
+ return TRUE;
+ }
+
+ if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 ||
+ crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1 ||
+ crtc->panningTotalArea.x1 < 0 ||
+ crtc->panningTotalArea.y1 < 0 ||
+ crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay ||
+ crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay ||
+ crtc->panningTotalArea.x2 > screenWidth ||
+ crtc->panningTotalArea.y2 > screenHeight)
+ {
+ memset (&crtc->panningTotalArea, 0, sizeof(BoxRec));
+ memset (&crtc->panningTrackingArea, 0, sizeof(BoxRec));
+ memset (&crtc->panningBorder, 0, 4*sizeof(INT16));
+ return FALSE;
+ }
+ if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay ||
+ crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) {
+ memset (&crtc->panningBorder, 0, 4*sizeof(INT16));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
+{
+ int newX, newY;
+ int width, height;
+
+ if (crtc->version < 2)
+ return;
+
+ if (! crtc->enabled ||
+ crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 ||
+ crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1)
+ return;
+
+ newX = crtc->x;
+ newY = crtc->y;
+ width = crtc->mode.HDisplay;
+ height = crtc->mode.VDisplay;
+
+ if (x >= crtc->panningTrackingArea.x1 && x < crtc->panningTrackingArea.x2 &&
+ y >= crtc->panningTrackingArea.y1 && y < crtc->panningTrackingArea.y2) {
+ if (x < crtc->x + crtc->panningBorder[0])
+ newX = x - crtc->panningBorder[0];
+ if (x >= crtc->x + width - crtc->panningBorder[2])
+ newX = x - width + crtc->panningBorder[2] + 1;
+ if (y < crtc->y + crtc->panningBorder[1])
+ newY = y - crtc->panningBorder[1];
+ if (y >= crtc->y + height - crtc->panningBorder[3])
+ newY = y - height + crtc->panningBorder[3] + 1;
+ }
+ /* Validate against [xy]1 after [xy]2, to be sure that results are > 0 for [xy]1 > 0 */
+ if (newX >= crtc->panningTotalArea.x2 - width)
+ newX = crtc->panningTotalArea.x2 - width - 1;
+ if (newX < crtc->panningTotalArea.x1)
+ newX = crtc->panningTotalArea.x1;
+ if (newY >= crtc->panningTotalArea.y2 - height)
+ newY = crtc->panningTotalArea.y2 - height - 1;
+ if (newY < crtc->panningTotalArea.y1)
+ newY = crtc->panningTotalArea.y1;
+ if (newX != crtc->x || newY != crtc->y)
+ xf86CrtcPan (crtc, newX, newY);
+}
+
static Bool
xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
{
@@ -332,6 +413,7 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
WindowPtr pRoot = WindowTable[pScreen->myNum];
PixmapPtr pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
Bool ret = FALSE;
+ int c;
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
if (xf86RandR12Key) {
@@ -352,6 +434,19 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
goto finish;
ret = TRUE;
+ /* Update panning information */
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 &&
+ crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+ crtc->panningTotalArea.x2 += width - pScreen->width;
+ crtc->panningTotalArea.y2 += height - pScreen->height;
+ crtc->panningTrackingArea.x2 += width - pScreen->width;
+ crtc->panningTrackingArea.y2 += height - pScreen->height;
+ xf86RandR13VerifyPanningArea (crtc, width, height);
+ xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+ }
+ }
pScreen->width = pScrnPix->drawable.width = width;
pScreen->height = pScrnPix->drawable.height = height;
@@ -762,6 +857,7 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
int num_randr_outputs,
RROutputPtr *randr_outputs)
{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
xf86CrtcPtr crtc = randr_crtc->devPrivate;
@@ -841,6 +937,8 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
xfree(save_crtcs);
return FALSE;
}
+ xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height);
+ xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
/*
* Save the last successful setting for EnterVT
*/
@@ -1187,6 +1285,62 @@ xf86RandR12TellChanged (ScreenPtr pScreen)
static void
xf86RandR12PointerMoved (int scrnIndex, int x, int y)
{
+ ScreenPtr pScreen = screenInfo.screens[scrnIndex];
+ ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ int c;
+
+ randrp->pointerX = x;
+ randrp->pointerY = y;
+ for (c = 0; c < config->num_crtc; c++)
+ xf86RandR13Pan (config->crtc[c], x, y);
+}
+
+static Bool
+xf86RandR13GetPanning (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border)
+{
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+
+ if (crtc->version < 2)
+ return FALSE;
+ if (totalArea)
+ memcpy (totalArea, &crtc->panningTotalArea, sizeof(BoxRec));
+ if (trackingArea)
+ memcpy (trackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
+ if (border)
+ memcpy (border, crtc->panningBorder, 4*sizeof(INT16));
+
+ return TRUE;
+}
+
+static Bool
+xf86RandR13SetPanning (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+ int ret;
+
+ if (crtc->version < 2)
+ return FALSE;
+ if (totalArea)
+ memcpy (&crtc->panningTotalArea, totalArea, sizeof(BoxRec));
+ if (trackingArea)
+ memcpy (&crtc->panningTrackingArea, trackingArea, sizeof(BoxRec));
+ if (border)
+ memcpy (crtc->panningBorder, border, 4*sizeof(INT16));
+ ret = xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height);
+ xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+
+ return ret;
}
static Bool
@@ -1203,6 +1357,8 @@ xf86RandR12Init12 (ScreenPtr pScreen)
rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
#if RANDR_13_INTERFACE
rp->rrOutputGetProperty = xf86RandR13OutputGetProperty;
+ rp->rrGetPanning = xf86RandR13GetPanning;
+ rp->rrSetPanning = xf86RandR13SetPanning;
#endif
rp->rrModeDestroy = xf86RandR12ModeDestroy;
rp->rrSetConfig = NULL;
commit f7e2fee8fe9b47f1e898feb8419aacd9a32c1f01
Author: Matthias Hopf <mhopf at suse.de>
Date: Fri Nov 28 17:39:23 2008 +0100
randr: Crtc interface update for panning support.
(cherry picked from commit 834cbc16f3eb539704faade7bff347b161ce69d9)
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 4b6f7d2..f085bf7 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -213,9 +213,16 @@ typedef struct _xf86CrtcFuncs {
Bool
(*set_mode_major)(xf86CrtcPtr crtc, DisplayModePtr mode,
Rotation rotation, int x, int y);
+
+ /**
+ * Callback for panning. Doesn't change the mode.
+ */
+ void
+ (*pan)(xf86CrtcPtr crtc, int x, int y);
+
} xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
-#define XF86_CRTC_VERSION 1
+#define XF86_CRTC_VERSION 2
struct _xf86Crtc {
/**
@@ -321,6 +328,15 @@ struct _xf86Crtc {
* Bounding box in screen space
*/
BoxRec bounds;
+ /**
+ * Panning:
+ * TotalArea: total panning area, larger than CRTC's size
+ * TrackingArea: Area of the pointer for which the CRTC is panned
+ * border: Borders of the displayed CRTC area which induces panning if the pointer reaches them
+ */
+ BoxRec panningTotalArea;
+ BoxRec panningTrackingArea;
+ INT16 panningBorder[4];
};
typedef struct _xf86OutputFuncs {
@@ -678,6 +694,9 @@ Bool
xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
int x, int y);
+void
+xf86CrtcPan (xf86CrtcPtr crtc, int x, int y);
+
/*
* Assign crtc rotation during mode set
*/
@@ -867,4 +886,19 @@ xf86_unwrap_crtc_notify(ScreenPtr pScreen, xf86_crtc_notify_proc_ptr old);
void
xf86_crtc_notify(ScreenPtr pScreen);
+/**
+ * Panning
+ */
+Bool
+xf86_crtc_get_panning(ScrnInfoPtr pScrn,
+ BoxPtr totalArea,
+ BoxPtr TrackingArea,
+ INT16 *border);
+
+Bool
+xf86_crtc_set_panning(ScrnInfoPtr pScrn,
+ BoxPtr totalArea,
+ BoxPtr TrackingArea,
+ INT16 *border);
+
#endif /* _XF86CRTC_H_ */
commit 27ca32eb05101e0e5624422dd25e1aa95b129d77
Author: Matthias Hopf <mhopf at suse.de>
Date: Fri Nov 28 17:38:52 2008 +0100
randr: Weird enough, crtc->version was never set upon creation. Fix that.
(cherry picked from commit a475eb9feec75e9ce1e316da0f1679acd7dd3aa8)
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 9ae173c..a2583b8 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -96,6 +96,7 @@ xf86CrtcCreate (ScrnInfoPtr scrn,
crtc = xcalloc (sizeof (xf86CrtcRec), 1);
if (!crtc)
return NULL;
+ crtc->version = XF86_CRTC_VERSION;
crtc->scrn = scrn;
crtc->funcs = funcs;
#ifdef RANDR_12_INTERFACE
More information about the xorg-commit
mailing list