summaryrefslogtreecommitdiff
path: root/randr/rrcrtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'randr/rrcrtc.c')
-rw-r--r--randr/rrcrtc.c147
1 files changed, 92 insertions, 55 deletions
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 39af679b2..338064f9f 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -1075,7 +1075,7 @@ ProcRRGetCrtcInfo(ClientPtr client)
REQUEST(xRRGetCrtcInfoReq);
xRRGetCrtcInfoReply rep;
RRCrtcPtr crtc;
- CARD8 *extra;
+ CARD8 *extra = NULL;
unsigned long extraLen;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
@@ -1085,10 +1085,13 @@ ProcRRGetCrtcInfo(ClientPtr client)
int i, j, k;
int width, height;
BoxRec panned_area;
+ Bool leased;
REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+ leased = RRCrtcIsLeased(crtc);
+
/* All crtcs must be associated with screens before client
* requests are processed
*/
@@ -1104,61 +1107,77 @@ ProcRRGetCrtcInfo(ClientPtr client)
.length = 0,
.timestamp = pScrPriv->lastSetTime.milliseconds
};
- if (pScrPriv->rrGetPanning &&
- pScrPriv->rrGetPanning(pScreen, crtc, &panned_area, NULL, NULL) &&
- (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1))
- {
- rep.x = panned_area.x1;
- rep.y = panned_area.y1;
- rep.width = panned_area.x2 - panned_area.x1;
- rep.height = panned_area.y2 - panned_area.y1;
- }
- else {
- RRCrtcGetScanoutSize(crtc, &width, &height);
- rep.x = crtc->x;
- rep.y = crtc->y;
- rep.width = width;
- rep.height = height;
- }
- rep.mode = mode ? mode->mode.id : 0;
- rep.rotation = crtc->rotation;
- rep.rotations = crtc->rotations;
- rep.nOutput = crtc->numOutputs;
- k = 0;
- for (i = 0; i < pScrPriv->numOutputs; i++)
- for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
- if (pScrPriv->outputs[i]->crtcs[j] == crtc)
- k++;
- rep.nPossibleOutput = k;
-
- rep.length = rep.nOutput + rep.nPossibleOutput;
-
- extraLen = rep.length << 2;
- if (extraLen) {
- extra = malloc(extraLen);
- if (!extra)
- return BadAlloc;
- }
- else
- extra = NULL;
-
- outputs = (RROutput *) extra;
- possible = (RROutput *) (outputs + rep.nOutput);
-
- for (i = 0; i < crtc->numOutputs; i++) {
- outputs[i] = crtc->outputs[i]->id;
- if (client->swapped)
- swapl(&outputs[i]);
- }
- k = 0;
- for (i = 0; i < pScrPriv->numOutputs; i++)
- for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
- if (pScrPriv->outputs[i]->crtcs[j] == crtc) {
- possible[k] = pScrPriv->outputs[i]->id;
- if (client->swapped)
- swapl(&possible[k]);
- k++;
+ if (leased) {
+ rep.x = rep.y = rep.width = rep.height = 0;
+ rep.mode = 0;
+ rep.rotation = RR_Rotate_0;
+ rep.rotations = RR_Rotate_0;
+ rep.nOutput = 0;
+ rep.nPossibleOutput = 0;
+ rep.length = 0;
+ extraLen = 0;
+ } else {
+ if (pScrPriv->rrGetPanning &&
+ pScrPriv->rrGetPanning(pScreen, crtc, &panned_area, NULL, NULL) &&
+ (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1))
+ {
+ rep.x = panned_area.x1;
+ rep.y = panned_area.y1;
+ rep.width = panned_area.x2 - panned_area.x1;
+ rep.height = panned_area.y2 - panned_area.y1;
+ }
+ else {
+ RRCrtcGetScanoutSize(crtc, &width, &height);
+ rep.x = crtc->x;
+ rep.y = crtc->y;
+ rep.width = width;
+ rep.height = height;
+ }
+ rep.mode = mode ? mode->mode.id : 0;
+ rep.rotation = crtc->rotation;
+ rep.rotations = crtc->rotations;
+ rep.nOutput = crtc->numOutputs;
+ k = 0;
+ for (i = 0; i < pScrPriv->numOutputs; i++) {
+ if (!RROutputIsLeased(pScrPriv->outputs[i])) {
+ for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
+ if (pScrPriv->outputs[i]->crtcs[j] == crtc)
+ k++;
+ }
+ }
+
+ rep.nPossibleOutput = k;
+
+ rep.length = rep.nOutput + rep.nPossibleOutput;
+
+ extraLen = rep.length << 2;
+ if (extraLen) {
+ extra = malloc(extraLen);
+ if (!extra)
+ return BadAlloc;
+ }
+
+ outputs = (RROutput *) extra;
+ possible = (RROutput *) (outputs + rep.nOutput);
+
+ for (i = 0; i < crtc->numOutputs; i++) {
+ outputs[i] = crtc->outputs[i]->id;
+ if (client->swapped)
+ swapl(&outputs[i]);
+ }
+ k = 0;
+ for (i = 0; i < pScrPriv->numOutputs; i++) {
+ if (!RROutputIsLeased(pScrPriv->outputs[i])) {
+ for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
+ if (pScrPriv->outputs[i]->crtcs[j] == crtc) {
+ possible[k] = pScrPriv->outputs[i]->id;
+ if (client->swapped)
+ swapl(&possible[k]);
+ k++;
+ }
}
+ }
+ }
if (client->swapped) {
swaps(&rep.sequenceNumber);
@@ -1205,6 +1224,9 @@ ProcRRSetCrtcConfig(ClientPtr client)
VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess);
+ if (RRCrtcIsLeased(crtc))
+ return BadAccess;
+
if (stuff->mode == None) {
mode = NULL;
if (numOutputs > 0)
@@ -1231,6 +1253,12 @@ ProcRRSetCrtcConfig(ClientPtr client)
free(outputs);
return ret;
}
+
+ if (RROutputIsLeased(outputs[i])) {
+ free(outputs);
+ return BadAccess;
+ }
+
/* validate crtc for this output */
for (j = 0; j < outputs[i]->numCrtcs; j++)
if (outputs[i]->crtcs[j] == crtc)
@@ -1474,6 +1502,9 @@ ProcRRSetPanning(ClientPtr client)
REQUEST_SIZE_MATCH(xRRSetPanningReq);
VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+ if (RRCrtcIsLeased(crtc))
+ return BadAccess;
+
/* All crtcs must be associated with screens before client
* requests are processed
*/
@@ -1614,6 +1645,9 @@ ProcRRSetCrtcGamma(ClientPtr client)
REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq);
VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+ if (RRCrtcIsLeased(crtc))
+ return BadAccess;
+
len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcGammaReq));
if (len < (stuff->size * 3 + 1) >> 1)
return BadLength;
@@ -1647,6 +1681,9 @@ ProcRRSetCrtcTransform(ClientPtr client)
REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq);
VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+ if (RRCrtcIsLeased(crtc))
+ return BadAccess;
+
PictTransform_from_xRenderTransform(&transform, &stuff->transform);
pixman_f_transform_from_pixman_transform(&f_transform, &transform);
if (!pixman_f_transform_invert(&f_inverse, &f_transform))