diff options
-rw-r--r-- | randr/mirandr.c | 6 | ||||
-rw-r--r-- | randr/randrstr.h | 28 | ||||
-rw-r--r-- | randr/rrcrtc.c | 52 | ||||
-rw-r--r-- | randr/rrinfo.c | 1 | ||||
-rw-r--r-- | randr/rrmode.c | 68 | ||||
-rw-r--r-- | randr/rroutput.c | 43 | ||||
-rw-r--r-- | randr/rrscreen.c | 17 |
7 files changed, 171 insertions, 44 deletions
diff --git a/randr/mirandr.c b/randr/mirandr.c index bcc8e0fcd..7300cfebe 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -52,7 +52,7 @@ miRRCrtcSet (ScreenPtr pScreen, int y, Rotation rotation, int numOutput, - RROutputPtr *outputs) + RROutputConfigPtr outputs) { return TRUE; } @@ -114,6 +114,10 @@ miRandRInit (ScreenPtr pScreen) return FALSE; if (!RROutputSetCrtcs (output, &crtc, 1)) return FALSE; + if (!RROutputSetPossibleOptions (output, 0)) + return FALSE; + if (!RROutputSetCurrentOptions (output, 0)) + return FALSE; if (!RROutputSetConnection (output, RR_Connected)) return FALSE; RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output); diff --git a/randr/randrstr.h b/randr/randrstr.h index 0b8c61e1f..a4e55890f 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -72,12 +72,14 @@ extern int (*SProcRandrVector[RRNumberRequests])(ClientPtr); typedef struct _rrMode RRModeRec, *RRModePtr; typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; typedef struct _rrOutput RROutputRec, *RROutputPtr; +typedef struct _rrOutputConfig RROutputConfigRec, *RROutputConfigPtr; struct _rrMode { int refcnt; xRRModeInfo mode; char *name; void *devPrivate; + ScreenPtr screen; }; struct _rrCrtc { @@ -105,6 +107,8 @@ struct _rrOutput { CARD8 connection; CARD8 subpixelOrder; RRCrtcPtr crtc; + CARD32 currentOptions; + CARD32 possibleOptions; int numCrtcs; RRCrtcPtr *crtcs; int numClones; @@ -116,6 +120,11 @@ struct _rrOutput { void *devPrivate; }; +struct _rrOutputConfig { + RROutputPtr output; + CARD32 options; +}; + #if RANDR_12_INTERFACE typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen, CARD16 width, @@ -130,7 +139,7 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen, int y, Rotation rotation, int numOutputs, - RROutputPtr *outputs); + RROutputConfigPtr outputs); typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc); @@ -352,7 +361,7 @@ miRRCrtcSet (ScreenPtr pScreen, int y, Rotation rotation, int numOutput, - RROutputPtr *outputs); + RROutputConfigPtr outputs); /* randr.c */ /* @@ -440,7 +449,7 @@ RRCrtcNotify (RRCrtcPtr crtc, int x, int y, Rotation rotation, - int numOutput, + int numOutputs, RROutputPtr *outputs); void @@ -456,7 +465,7 @@ RRCrtcSet (RRCrtcPtr crtc, int y, Rotation rotation, int numOutput, - RROutputPtr *outputs); + RROutputConfigPtr outputs); /* * Request that the Crtc gamma be changed @@ -530,6 +539,9 @@ RRModeGet (ScreenPtr pScreen, xRRModeInfo *modeInfo, const char *name); +void +RRModePruneUnused (ScreenPtr pScreen); + /* * Destroy a mode. */ @@ -584,6 +596,10 @@ RROutputSetCrtcs (RROutputPtr output, RRCrtcPtr *crtcs, int numCrtcs); +Bool +RROutputSetPossibleOptions (RROutputPtr output, + CARD32 possibleOptions); + void RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc); @@ -595,6 +611,10 @@ Bool RROutputSetSubpixelOrder (RROutputPtr output, int subpixelOrder); +Bool +RROutputSetCurrentOptions (RROutputPtr output, + CARD32 currentOptions); + void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output); diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index 77cba29fa..3108f1452 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -92,25 +92,25 @@ RRCrtcNotify (RRCrtcPtr crtc, if (numOutputs != prevNumOutputs) { - RROutputPtr *outputs; + RROutputPtr *newoutputs; if (numOutputs) { if (crtc->numOutputs) - outputs = xrealloc (crtc->outputs, + newoutputs = xrealloc (crtc->outputs, numOutputs * sizeof (RROutputPtr)); else - outputs = xalloc (numOutputs * sizeof (RROutputPtr)); - if (!outputs) + newoutputs = xalloc (numOutputs * sizeof (RROutputPtr)); + if (!newoutputs) return FALSE; } else { if (crtc->outputs) xfree (crtc->outputs); - outputs = NULL; + newoutputs = NULL; } - crtc->outputs = outputs; + crtc->outputs = newoutputs; crtc->numOutputs = numOutputs; } for (i = 0; i < numOutputs; i++) @@ -183,7 +183,7 @@ RRCrtcSet (RRCrtcPtr crtc, int y, Rotation rotation, int numOutputs, - RROutputPtr *outputs) + RROutputConfigPtr outputs) { ScreenPtr pScreen = crtc->pScreen; rrScrPriv(pScreen); @@ -252,7 +252,7 @@ RRCrtcDestroyResource (pointer value, XID pid) { if (pScrPriv->crtcs[i] == crtc) { - memmove (pScrPriv->crtcs, pScrPriv->crtcs + 1, + memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1, (pScrPriv->numCrtcs - (i - 1)) * sizeof (RRCrtcPtr)); --pScrPriv->numCrtcs; break; @@ -458,15 +458,15 @@ ProcRRSetCrtcConfig (ClientPtr client) RRCrtcPtr crtc; RRModePtr mode; int numOutputs; - RROutputPtr *outputs = NULL; - RROutput *outputIds; + RROutputConfigPtr outputs = NULL; + xRROutputConfig *outputConfigs; TimeStamp configTime; TimeStamp time; Rotation rotation; int i, j; REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); - numOutputs = stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2); + numOutputs = (stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2)) >> 1; crtc = LookupIDByType (stuff->crtc, RRCrtcType); if (!crtc) @@ -493,39 +493,47 @@ ProcRRSetCrtcConfig (ClientPtr client) } if (numOutputs) { - outputs = xalloc (numOutputs * sizeof (RROutputPtr)); + outputs = xalloc (numOutputs * sizeof (RROutputConfigRec)); if (!outputs) return BadAlloc; } else outputs = NULL; - outputIds = (RROutput *) (stuff + 1); + outputConfigs = (xRROutputConfig *) (stuff + 1); for (i = 0; i < numOutputs; i++) { - outputs[i] = LookupIDByType (outputIds[i], RROutputType); - if (!outputs[i]) + outputs[i].output = LookupIDByType (outputConfigs[i].output, RROutputType); + if (!outputs[i].output) { - client->errorValue = outputIds[i]; + client->errorValue = outputConfigs[i].output; if (outputs) xfree (outputs); return RRErrorBase + BadRROutput; } + outputs[i].options = outputConfigs[i].options; + if (outputs[i].options & ~outputs[i].output->possibleOptions) + { + client->errorValue = outputConfigs[i].options; + if (outputs) + xfree (outputs); + return BadMatch; + } /* validate crtc for this output */ - for (j = 0; j < outputs[i]->numCrtcs; j++) - if (outputs[i]->crtcs[j] == crtc) + for (j = 0; j < outputs[i].output->numCrtcs; j++) + if (outputs[i].output->crtcs[j] == crtc) break; - if (j == outputs[j]->numCrtcs) + if (j == outputs[j].output->numCrtcs) { if (outputs) xfree (outputs); return BadMatch; } /* validate mode for this output */ - for (j = 0; j < outputs[i]->numModes; j++) - if (outputs[i]->modes[j] == mode) + for (j = 0; j < outputs[i].output->numModes; j++) + if (outputs[i].output->modes[j] == mode) break; - if (j == outputs[i]->numModes) + if (j == outputs[i].output->numModes) { if (outputs) xfree (outputs); diff --git a/randr/rrinfo.c b/randr/rrinfo.c index 491ac218d..6fd4ee581 100644 --- a/randr/rrinfo.c +++ b/randr/rrinfo.c @@ -208,6 +208,7 @@ RRGetInfo (ScreenPtr pScreen) if (pScrPriv->nSizes) RRScanOldConfig (pScreen, rotations); #endif + RRModePruneUnused (pScreen); RRTellChanged (pScreen); return TRUE; } diff --git a/randr/rrmode.c b/randr/rrmode.c index 23ac5305c..3a6748691 100644 --- a/randr/rrmode.c +++ b/randr/rrmode.c @@ -24,6 +24,27 @@ RESTYPE RRModeType; +static Bool +RRModeEqual (xRRModeInfo *a, xRRModeInfo *b) +{ + if (a->width != b->width) return FALSE; + if (a->height != b->height) return FALSE; + if (a->mmWidth != b->mmWidth) return FALSE; + if (a->mmHeight != b->mmHeight) return FALSE; + if (a->dotClock != b->dotClock) return FALSE; + if (a->hSyncStart != b->hSyncStart) return FALSE; + if (a->hSyncEnd != b->hSyncEnd) return FALSE; + if (a->hTotal != b->hTotal) return FALSE; + if (a->hSkew != b->hSkew) return FALSE; + if (a->vSyncStart != b->vSyncStart) return FALSE; + if (a->vSyncEnd != b->vSyncEnd) return FALSE; + if (a->vTotal != b->vTotal) return FALSE; + if (a->nameLength != b->nameLength) return FALSE; + if (a->modeFlags != b->modeFlags) return FALSE; + if (a->origin != b->origin) return FALSE; + return TRUE; +} + RRModePtr RRModeGet (ScreenPtr pScreen, xRRModeInfo *modeInfo, @@ -37,8 +58,7 @@ RRModeGet (ScreenPtr pScreen, for (i = 0; i < pScrPriv->numModes; i++) { mode = pScrPriv->modes[i]; - modeInfo->id = mode->mode.id; - if (!memcmp (modeInfo, &mode->mode, sizeof (xRRModeInfo)) && + if (RRModeEqual (&mode->mode, modeInfo) && !memcmp (name, mode->name, modeInfo->nameLength)) { ++mode->refcnt; @@ -54,6 +74,7 @@ RRModeGet (ScreenPtr pScreen, mode->name = (char *) (mode + 1); memcpy (mode->name, name, modeInfo->nameLength); mode->name[modeInfo->nameLength] = '\0'; + mode->screen = pScreen; if (pScrPriv->numModes) modes = xrealloc (pScrPriv->modes, @@ -80,8 +101,31 @@ RRModeGet (ScreenPtr pScreen, void RRModeDestroy (RRModePtr mode) { + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + int m; + if (--mode->refcnt > 0) return; + pScreen = mode->screen; + pScrPriv = rrGetScrPriv (pScreen); + for (m = 0; m < pScrPriv->numModes; m++) + { + if (pScrPriv->modes[m] == mode) + { + memmove (pScrPriv->modes + m, pScrPriv->modes + m + 1, + (pScrPriv->numModes - m - 1) * sizeof (RRModePtr)); + pScrPriv->numModes--; + if (!pScrPriv->numModes) + { + xfree (pScrPriv->modes); + pScrPriv->modes = NULL; + } + pScrPriv->changed = TRUE; + break; + } + } + xfree (mode); } @@ -104,6 +148,26 @@ RRModeInit (void) return TRUE; } +void +RRModePruneUnused (ScreenPtr pScreen) +{ + rrScrPriv (pScreen); + RRModePtr *unused, mode; + int m; + int num = pScrPriv->numModes; + + unused = xalloc (num * sizeof (RRModePtr)); + if (!unused) + return; + memcpy (unused, pScrPriv->modes, num * sizeof (RRModePtr)); + for (m = 0; m < num; m++) { + mode = unused[m]; + if (mode->refcnt == 1 && mode->mode.origin != RRModeOriginUser) + FreeResource (mode->mode.id, 0); + } + xfree (unused); +} + int ProcRRCreateMode (ClientPtr client) { diff --git a/randr/rroutput.c b/randr/rroutput.c index 90b2b9856..b252d7dec 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -60,6 +60,8 @@ RROutputCreate (ScreenPtr pScreen, output->connection = RR_UnknownConnection; output->subpixelOrder = SubPixelUnknown; output->crtc = NULL; + output->currentOptions = 0; + output->possibleOptions = 0; output->numCrtcs = 0; output->crtcs = NULL; output->numClones = 0; @@ -190,6 +192,17 @@ RROutputSetCrtcs (RROutputPtr output, return TRUE; } +Bool +RROutputSetPossibleOptions (RROutputPtr output, + CARD32 possibleOptions) +{ + if (output->possibleOptions == possibleOptions) + return TRUE; + output->possibleOptions = possibleOptions; + output->changed = TRUE; + return TRUE; +} + void RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc) { @@ -222,6 +235,17 @@ RROutputSetSubpixelOrder (RROutputPtr output, return TRUE; } +Bool +RROutputSetCurrentOptions (RROutputPtr output, + CARD32 currentOptions) +{ + if (output->currentOptions == currentOptions) + return TRUE; + output->currentOptions = currentOptions; + output->changed = TRUE; + return TRUE; +} + void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) { @@ -248,7 +272,7 @@ RROutputDestroyResource (pointer value, XID pid) { if (pScrPriv->outputs[i] == output) { - memmove (pScrPriv->outputs, pScrPriv->outputs + 1, + memmove (pScrPriv->outputs + i, pScrPriv->outputs + i + 1, (pScrPriv->numOutputs - (i - 1)) * sizeof (RROutputPtr)); --pScrPriv->numOutputs; break; @@ -280,6 +304,8 @@ RROutputInit (void) return TRUE; } +#define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32) + int ProcRRGetOutputInfo (ClientPtr client) { @@ -307,24 +333,27 @@ ProcRRGetOutputInfo (ClientPtr client) rep.type = X_Reply; rep.sequenceNumber = client->sequence; - rep.length = 0; + rep.length = OutputInfoExtra >> 2; rep.timestamp = pScrPriv->lastSetTime.milliseconds; rep.crtc = output->crtc ? output->crtc->id : None; + rep.currentOptions = output->currentOptions; rep.connection = output->connection; rep.subpixelOrder = output->subpixelOrder; rep.nCrtcs = output->numCrtcs; rep.nModes = output->numModes; rep.nClones = output->numClones; rep.nameLength = output->nameLength; + rep.possibleOptions = output->possibleOptions; + rep.pad1 = 42; - rep.length = (output->numCrtcs + - output->numModes + - output->numClones + - ((rep.nameLength + 3) >> 2)); + extraLen = ((output->numCrtcs + + output->numModes + + output->numClones + + ((rep.nameLength + 3) >> 2)) << 2); - extraLen = rep.length << 2; if (extraLen) { + rep.length += extraLen >> 2; extra = xalloc (extraLen); if (!extra) return BadAlloc; diff --git a/randr/rrscreen.c b/randr/rrscreen.c index e382540b7..7b53f0468 100644 --- a/randr/rrscreen.c +++ b/randr/rrscreen.c @@ -372,7 +372,7 @@ ProcRRGetScreenResources (ClientPtr client) rep.length = (pScrPriv->numCrtcs + pScrPriv->numOutputs + - pScrPriv->numModes * 10 + + pScrPriv->numModes * (SIZEOF(xRRModeInfo) >> 2) + ((rep.nbytesNames + 3) >> 2)); extraLen = rep.length << 2; @@ -429,7 +429,7 @@ ProcRRGetScreenResources (ClientPtr client) pScrPriv->modes[i]->mode.nameLength); names += pScrPriv->modes[i]->mode.nameLength; } - assert ((names + 3 >> 3) == rep.length); + assert (((((char *) names - (char *) extra) + 3) >> 2) == rep.length); } if (client->swapped) { @@ -694,7 +694,7 @@ ProcRRSetScreenConfig (ClientPtr client) Rotation rotation; int rate; Bool has_rate; - RROutputPtr output; + RROutputConfigRec output; RRModePtr mode; RR10DataPtr pData = NULL; RRScreenSizePtr pSize; @@ -731,13 +731,14 @@ ProcRRSetScreenConfig (ClientPtr client) if (!RRGetInfo (pScreen)) return BadAlloc; - output = RRFirstOutput (pScreen); - if (!output) + output.output = RRFirstOutput (pScreen); + if (!output.output) { time = currentTime; rep.status = RRSetConfigFailed; goto sendReply; } + output.options = output.output->currentOptions; /* * if the client's config timestamp is not the same as the last config @@ -750,7 +751,7 @@ ProcRRSetScreenConfig (ClientPtr client) goto sendReply; } - pData = RR10GetData (pScreen, output); + pData = RR10GetData (pScreen, output.output); if (!pData) return BadAlloc; @@ -786,7 +787,7 @@ ProcRRSetScreenConfig (ClientPtr client) return BadValue; } - if ((~output->crtc->rotations) & rotation) + if ((~output.output->crtc->rotations) & rotation) { /* * requested rotation or reflection not supported by screen @@ -835,7 +836,7 @@ ProcRRSetScreenConfig (ClientPtr client) goto sendReply; } - rep.status = RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation, + rep.status = RRCrtcSet (output.output->crtc, mode, 0, 0, stuff->rotation, 1, &output); sendReply: |