diff options
-rw-r--r-- | randr/randrstr.h | 19 | ||||
-rw-r--r-- | randr/rrcrtc.c | 167 | ||||
-rw-r--r-- | randr/rrdispatch.c | 2 |
3 files changed, 188 insertions, 0 deletions
diff --git a/randr/randrstr.h b/randr/randrstr.h index e2338b7e3..0cc4ff7ee 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 /* @@ -678,6 +691,12 @@ ProcRRSetCrtcTransform (ClientPtr client); extern _X_EXPORT int ProcRRGetCrtcTransform (ClientPtr client); +int +ProcRRGetPanning (ClientPtr client); + +int +ProcRRSetPanning (ClientPtr client); + /* rrdispatch.c */ extern _X_EXPORT Bool RRClientKnowsRates (ClientPtr pClient); diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index 90d93b513..b8e4d1109 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 64af6ce2a..0cc0bca98 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 */ }; |