diff --git a/randr/randr.c b/randr/randr.c index 926e32f1c..beddb50b0 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -442,7 +442,7 @@ RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh) if (!modes) { RRModeDestroy (mode); - FreeResource (mode->id, 0); + FreeResource (mode->mode.id, 0); return NULL; } modes[output->numModes++] = mode; @@ -479,6 +479,9 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) RROutputSetCrtcs (output, &crtc, 1); RROutputSetCrtc (output, crtc); RROutputSetConnection (output, RR_Connected); +#ifdef RENDER + RROutputSetSubpixelOrder (output, PictureGetSubpixelOrder (pScreen)); +#endif } output = RRFirstOutput (pScreen); diff --git a/randr/randrstr.h b/randr/randrstr.h index a7f91b79a..682ebbfed 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -74,7 +74,6 @@ typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; typedef struct _rrOutput RROutputRec, *RROutputPtr; struct _rrMode { - RRMode id; int refcnt; xRRModeInfo mode; char *name; @@ -489,6 +488,10 @@ Bool RROutputSetConnection (RROutputPtr output, CARD8 connection); +Bool +RROutputSetSubpixelOrder (RROutputPtr output, + int subpixelOrder); + void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output); diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c index 279acfdee..aca0e542a 100644 --- a/randr/rrdispatch.c +++ b/randr/rrdispatch.c @@ -694,20 +694,229 @@ static int ProcRRGetScreenResources (ClientPtr client) { REQUEST(xRRGetScreenResourcesReq); + xRRGetScreenResourcesReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + CARD8 *extra; + unsigned long extraLen; + int i; + RRCrtc *crtcs; + RROutput *outputs; + xRRModeInfo *modeinfos; + CARD8 *names; + int n; REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); - (void) stuff; - return BadImplementation; + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + rep.pad = 0; + + if (pScrPriv) + RRGetInfo (pScreen); + + if (!pScrPriv) + { + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.timestamp = currentTime.milliseconds; + rep.configTimestamp = currentTime.milliseconds; + rep.nCrtcs = 0; + rep.nOutputs = 0; + rep.nModes = 0; + rep.nbytesNames = 0; + extra = NULL; + extraLen = 0; + } + else + { + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.timestamp = currentTime.milliseconds; + rep.configTimestamp = currentTime.milliseconds; + rep.nCrtcs = pScrPriv->numCrtcs; + rep.nOutputs = pScrPriv->numOutputs; + rep.nModes = pScrPriv->numModes;; + rep.nbytesNames = 0; + + for (i = 0; i < pScrPriv->numModes; i++) + rep.nbytesNames += pScrPriv->modes[i]->mode.nameLength; + + rep.length = (pScrPriv->numCrtcs + + pScrPriv->numOutputs + + pScrPriv->numModes * 10 + + ((rep.nbytesNames + 3) >> 2)); + + extraLen = rep.length << 2; + extra = xalloc (extraLen); + if (!extra) + return BadAlloc; + + crtcs = (RRCrtc *) extra; + outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs); + modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs); + names = (CARD8 *) (modeinfos + pScrPriv->numModes); + + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + crtcs[i] = pScrPriv->crtcs[i]->id; + if (client->swapped) + swapl (&crtcs[i], n); + } + + for (i = 0; i < pScrPriv->numOutputs; i++) + { + outputs[i] = pScrPriv->outputs[i]->id; + if (client->swapped) + swapl (&outputs[i], n); + } + + for (i = 0; i < pScrPriv->numModes; i++) + { + modeinfos[i] = pScrPriv->modes[i]->mode; + if (client->swapped) + { + swapl (&modeinfos[i].id, n); + swaps (&modeinfos[i].width, n); + swaps (&modeinfos[i].height, n); + swapl (&modeinfos[i].mmWidth, n); + swapl (&modeinfos[i].mmHeight, n); + swapl (&modeinfos[i].dotClock, n); + swaps (&modeinfos[i].hSyncStart, n); + swaps (&modeinfos[i].hSyncEnd, n); + swaps (&modeinfos[i].hTotal, n); + swaps (&modeinfos[i].hSkew, n); + swaps (&modeinfos[i].vSyncStart, n); + swaps (&modeinfos[i].vSyncEnd, n); + swaps (&modeinfos[i].vTotal, n); + swaps (&modeinfos[i].nameLength, n); + swapl (&modeinfos[i].modeFlags, n); + } + memcpy (names, pScrPriv->modes[i]->name, + pScrPriv->modes[i]->mode.nameLength); + names += pScrPriv->modes[i]->mode.nameLength; + } + assert ((names + 3 >> 3) == rep.length); + } + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swapl(&rep.configTimestamp, n); + swaps(&rep.nCrtcs, n); + swaps(&rep.nOutputs, n); + swaps(&rep.nModes, n); + swaps(&rep.nbytesNames, n); + } + WriteToClient(client, sizeof(xRRGetScreenResourcesReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + return client->noClientException; } static int ProcRRGetOutputInfo (ClientPtr client) { REQUEST(xRRGetOutputInfoReq);; + xRRGetOutputInfoReply rep; + RROutputPtr output; + CARD8 *extra; + unsigned long extraLen; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRCrtc *crtcs; + RRMode *modes; + RROutput *clones; + char *name; + int i, n; REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); - (void) stuff; - return BadImplementation; + output = (RROutputPtr)SecurityLookupIDByType(client, stuff->output, + RROutputType, + SecurityReadAccess); + + if (!output) + return RRErrorBase + BadRROutput; + + pScreen = output->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.timestamp = pScrPriv->lastSetTime.milliseconds; + rep.crtc = output->crtc ? output->crtc->id : None; + 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.length = (output->numCrtcs + + output->numModes + + output->numClones + + ((rep.nameLength + 3) >> 2)); + + extraLen = rep.length << 2; + extra = xalloc (extraLen); + if (!extra) + return BadAlloc; + + crtcs = (RRCrtc *) extra; + modes = (RRMode *) (crtcs + output->numCrtcs); + clones = (RROutput *) (modes + output->numModes); + name = (char *) (clones + output->numClones); + + for (i = 0; i < output->numCrtcs; i++) + { + crtcs[i] = output->crtcs[i]->id; + if (client->swapped) + swapl (&crtcs[i], n); + } + for (i = 0; i < output->numModes; i++) + { + modes[i] = output->modes[i]->mode.id; + if (client->swapped) + swapl (&modes[i], n); + } + for (i = 0; i < output->numClones; i++) + { + clones[i] = output->clones[i]->id; + if (client->swapped) + swapl (&clones[i], n); + } + memcpy (name, output->name, output->nameLength); + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swapl(&rep.crtc, n); + swaps(&rep.nCrtcs, n); + swaps(&rep.nModes, n); + swaps(&rep.nClones, n); + swaps(&rep.nameLength, n); + } + WriteToClient(client, sizeof(xRRGetOutputInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + + return client->noClientException; } static int diff --git a/randr/rrmode.c b/randr/rrmode.c index 52585d967..4e44e7d82 100644 --- a/randr/rrmode.c +++ b/randr/rrmode.c @@ -37,6 +37,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)) && !memcmp (name, mode->name, modeInfo->nameLength)) { @@ -66,8 +67,8 @@ RRModeGet (ScreenPtr pScreen, return NULL; } - mode->id = FakeClientID(0); - if (!AddResource (mode->id, RRModeType, (pointer) mode)) + mode->mode.id = FakeClientID(0); + if (!AddResource (mode->mode.id, RRModeType, (pointer) mode)) return NULL; ++mode->refcnt; pScrPriv->modes = modes; diff --git a/randr/rroutput.c b/randr/rroutput.c index ba5bcb451..478002300 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -154,6 +154,15 @@ RROutputSetConnection (RROutputPtr output, return TRUE; } +Bool +RROutputSetSubpixelOrder (RROutputPtr output, + int subpixelOrder) +{ + output->subpixelOrder = subpixelOrder; + output->changed = TRUE; + return TRUE; +} + void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) {