123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865 |
- /*
- * Copyright © 2006 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
- #include "randrstr.h"
- #include "swaprep.h"
- RESTYPE RRCrtcType;
- /*
- * Notify the CRTC of some change
- */
- void
- RRCrtcChanged(RRCrtcPtr crtc, Bool layoutChanged)
- {
- ScreenPtr pScreen = crtc->pScreen;
- crtc->changed = TRUE;
- if (pScreen) {
- rrScrPriv(pScreen);
- pScrPriv->changed = TRUE;
- /*
- * Send ConfigureNotify on any layout change
- */
- if (layoutChanged)
- pScrPriv->layoutChanged = TRUE;
- }
- }
- /*
- * Create a CRTC
- */
- RRCrtcPtr
- RRCrtcCreate(void *devPrivate)
- {
- RRCrtcPtr crtc;
- if (!RRInit())
- return NULL;
- crtc = malloc(sizeof(RRCrtcRec));
- if (!crtc)
- return NULL;
- crtc->id = FakeClientID(0);
- crtc->pScreen = NULL;
- crtc->mode = NULL;
- crtc->x = 0;
- crtc->y = 0;
- crtc->rotation = RR_Rotate_0;
- crtc->rotations = RR_Rotate_0;
- crtc->outputs = NULL;
- crtc->numOutputs = 0;
- crtc->gammaSize = 0;
- crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL;
- crtc->changed = FALSE;
- crtc->devPrivate = devPrivate;
- if (!AddResource(crtc->id, RRCrtcType, (pointer) crtc))
- return NULL;
- return crtc;
- }
- /*
- * Set the allowed rotations on a CRTC
- */
- void
- RRCrtcSetRotations(RRCrtcPtr crtc, Rotation rotations)
- {
- crtc->rotations = rotations;
- }
- /*
- * Attach a Crtc to a screen. This is done as a separate step
- * so that an xf86-based driver can create CRTCs in PreInit
- * before the Screen has been created
- */
- Bool
- RRCrtcAttachScreen(RRCrtcPtr crtc, ScreenPtr pScreen)
- {
- rrScrPriv(pScreen);
- RRCrtcPtr *crtcs;
- /* make space for the crtc pointer */
- if (pScrPriv->numCrtcs)
- crtcs = realloc(pScrPriv->crtcs,
- (pScrPriv->numCrtcs + 1) * sizeof(RRCrtcPtr));
- else
- crtcs = malloc(sizeof(RRCrtcPtr));
- if (!crtcs)
- return FALSE;
- /* attach the screen and crtc together */
- crtc->pScreen = pScreen;
- pScrPriv->crtcs = crtcs;
- pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
- RRCrtcChanged(crtc, TRUE);
- return TRUE;
- }
- /*
- * Notify the extension that the Crtc has been reconfigured,
- * the driver calls this whenever it has updated the mode
- */
- Bool
- RRCrtcNotify(RRCrtcPtr crtc,
- RRModePtr mode,
- int x,
- int y, Rotation rotation, int numOutputs, RROutputPtr * outputs)
- {
- int i, j;
- /*
- * Check to see if any of the new outputs were
- * not in the old list and mark them as changed
- */
- for (i = 0; i < numOutputs; i++) {
- for (j = 0; j < crtc->numOutputs; j++)
- if (outputs[i] == crtc->outputs[j])
- break;
- if (j == crtc->numOutputs) {
- RROutputChanged(outputs[i], FALSE);
- RRCrtcChanged(crtc, FALSE);
- }
- }
- /*
- * Check to see if any of the old outputs are
- * not in the new list and mark them as changed
- */
- for (j = 0; j < crtc->numOutputs; j++) {
- for (i = 0; i < numOutputs; i++)
- if (outputs[i] == crtc->outputs[j])
- break;
- if (i == numOutputs) {
- RROutputChanged(crtc->outputs[j], FALSE);
- RRCrtcChanged(crtc, FALSE);
- }
- }
- /*
- * Reallocate the crtc output array if necessary
- */
- if (numOutputs != crtc->numOutputs) {
- RROutputPtr *newoutputs;
- if (numOutputs) {
- if (crtc->numOutputs)
- newoutputs = realloc(crtc->outputs,
- numOutputs * sizeof(RROutputPtr));
- else
- newoutputs = malloc(numOutputs * sizeof(RROutputPtr));
- if (!newoutputs)
- return FALSE;
- }
- else {
- if (crtc->outputs)
- free(crtc->outputs);
- newoutputs = NULL;
- }
- crtc->outputs = newoutputs;
- crtc->numOutputs = numOutputs;
- }
- /*
- * Copy the new list of outputs into the crtc
- */
- memcpy(crtc->outputs, outputs, numOutputs * sizeof(RROutputPtr));
- /*
- * Update remaining crtc fields
- */
- if (mode != crtc->mode) {
- if (crtc->mode)
- RRModeDestroy(crtc->mode);
- crtc->mode = mode;
- if (mode != NULL)
- mode->refcnt++;
- RRCrtcChanged(crtc, TRUE);
- }
- if (x != crtc->x) {
- crtc->x = x;
- RRCrtcChanged(crtc, TRUE);
- }
- if (y != crtc->y) {
- crtc->y = y;
- RRCrtcChanged(crtc, TRUE);
- }
- if (rotation != crtc->rotation) {
- crtc->rotation = rotation;
- RRCrtcChanged(crtc, TRUE);
- }
- return TRUE;
- }
- void
- RRDeliverCrtcEvent(ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
- {
- ScreenPtr pScreen = pWin->drawable.pScreen;
- rrScrPriv(pScreen);
- xRRCrtcChangeNotifyEvent ce;
- RRModePtr mode = crtc->mode;
- ce.type = RRNotify + RREventBase;
- ce.subCode = RRNotify_CrtcChange;
- ce.timestamp = pScrPriv->lastSetTime.milliseconds;
- ce.window = pWin->drawable.id;
- ce.crtc = crtc->id;
- ce.rotation = crtc->rotation;
- if (mode) {
- ce.mode = mode->mode.id;
- ce.x = crtc->x;
- ce.y = crtc->y;
- ce.width = mode->mode.width;
- ce.height = mode->mode.height;
- }
- else {
- ce.mode = None;
- ce.x = 0;
- ce.y = 0;
- ce.width = 0;
- ce.height = 0;
- }
- WriteEventsToClient(client, 1, (xEvent *) &ce);
- }
- /*
- * Request that the Crtc be reconfigured
- */
- Bool
- RRCrtcSet(RRCrtcPtr crtc,
- RRModePtr mode,
- int x,
- int y, Rotation rotation, int numOutputs, RROutputPtr * outputs)
- {
- ScreenPtr pScreen = crtc->pScreen;
- /* See if nothing changed */
- if (crtc->mode == mode &&
- crtc->x == x &&
- crtc->y == y &&
- crtc->rotation == rotation &&
- crtc->numOutputs == numOutputs &&
- !memcmp(crtc->outputs, outputs, numOutputs * sizeof(RROutputPtr))) {
- return TRUE;
- }
- if (pScreen) {
- #if RANDR_12_INTERFACE
- rrScrPriv(pScreen);
- if (pScrPriv->rrCrtcSet) {
- return (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
- rotation, numOutputs, outputs);
- }
- #endif
- #if RANDR_10_INTERFACE
- if (pScrPriv->rrSetConfig) {
- RRScreenSize size;
- RRScreenRate rate;
- if (!mode) {
- RRCrtcNotify(crtc, NULL, x, y, rotation, 0, NULL);
- return TRUE;
- }
- Bool ret;
- size.width = mode->mode.width;
- size.height = mode->mode.height;
- if (outputs[0]->mmWidth && outputs[0]->mmHeight) {
- size.mmWidth = outputs[0]->mmWidth;
- size.mmHeight = outputs[0]->mmHeight;
- }
- else {
- size.mmWidth = pScreen->mmWidth;
- size.mmHeight = pScreen->mmHeight;
- }
- size.nRates = 1;
- rate.rate = RRVerticalRefresh(&mode->mode);
- size.pRates = &rate;
- ret =
- (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size);
- /*
- * Old 1.0 interface tied screen size to mode size
- */
- if (ret) {
- RRCrtcNotify(crtc, mode, x, y, rotation, 1, outputs);
- RRScreenSizeNotify(pScreen);
- }
- return ret;
- }
- #endif
- RRTellChanged(pScreen);
- }
- return FALSE;
- }
- /*
- * Destroy a Crtc at shutdown
- */
- void
- RRCrtcDestroy(RRCrtcPtr crtc)
- {
- FreeResource(crtc->id, 0);
- }
- static int
- RRCrtcDestroyResource(pointer value, XID pid)
- {
- RRCrtcPtr crtc = (RRCrtcPtr) value;
- ScreenPtr pScreen = crtc->pScreen;
- if (pScreen) {
- rrScrPriv(pScreen);
- int i;
- for (i = 0; i < pScrPriv->numCrtcs; i++) {
- if (pScrPriv->crtcs[i] == crtc) {
- memmove(pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1,
- (pScrPriv->numCrtcs - (i + 1)) * sizeof(RRCrtcPtr));
- --pScrPriv->numCrtcs;
- break;
- }
- }
- }
- if (crtc->gammaRed)
- free(crtc->gammaRed);
- free(crtc);
- return 1;
- }
- /*
- * Request that the Crtc gamma be changed
- */
- Bool
- RRCrtcGammaSet(RRCrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue)
- {
- Bool ret = TRUE;
- #if RANDR_12_INTERFACE
- ScreenPtr pScreen = crtc->pScreen;
- #endif
- memcpy(crtc->gammaRed, red, crtc->gammaSize * sizeof(CARD16));
- memcpy(crtc->gammaGreen, green, crtc->gammaSize * sizeof(CARD16));
- memcpy(crtc->gammaBlue, blue, crtc->gammaSize * sizeof(CARD16));
- #if RANDR_12_INTERFACE
- if (pScreen) {
- rrScrPriv(pScreen);
- if (pScrPriv->rrCrtcSetGamma)
- ret = (*pScrPriv->rrCrtcSetGamma) (pScreen, crtc);
- }
- #endif
- return ret;
- }
- /*
- * Notify the extension that the Crtc gamma has been changed
- * The driver calls this whenever it has changed the gamma values
- * in the RRCrtcRec
- */
- Bool
- RRCrtcGammaNotify(RRCrtcPtr crtc)
- {
- return TRUE; /* not much going on here */
- }
- /**
- * Returns the width/height that the crtc scans out from the framebuffer
- */
- void
- RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height)
- {
- if (crtc->mode == NULL) {
- *width = 0;
- *height = 0;
- return;
- }
- switch (crtc->rotation & 0xf) {
- case RR_Rotate_0:
- case RR_Rotate_180:
- *width = crtc->mode->mode.width;
- *height = crtc->mode->mode.height;
- break;
- case RR_Rotate_90:
- case RR_Rotate_270:
- *width = crtc->mode->mode.height;
- *height = crtc->mode->mode.width;
- break;
- }
- }
- /*
- * Set the size of the gamma table at server startup time
- */
- Bool
- RRCrtcGammaSetSize(RRCrtcPtr crtc, int size)
- {
- CARD16 *gamma;
- if (size == crtc->gammaSize)
- return TRUE;
- if (size) {
- gamma = malloc(size * 3 * sizeof(CARD16));
- if (!gamma)
- return FALSE;
- }
- else
- gamma = NULL;
- if (crtc->gammaRed)
- free(crtc->gammaRed);
- crtc->gammaRed = gamma;
- crtc->gammaGreen = gamma + size;
- crtc->gammaBlue = gamma + size * 2;
- crtc->gammaSize = size;
- return TRUE;
- }
- /*
- * Initialize crtc type
- */
- Bool
- RRCrtcInit(void)
- {
- RRCrtcType = CreateNewResourceType(RRCrtcDestroyResource);
- if (!RRCrtcType)
- return FALSE;
- #ifdef XResExtension
- RegisterResourceName(RRCrtcType, "CRTC");
- #endif
- return TRUE;
- }
- int
- ProcRRGetCrtcInfo(ClientPtr client)
- {
- REQUEST(xRRGetCrtcInfoReq);;
- xRRGetCrtcInfoReply rep;
- RRCrtcPtr crtc;
- CARD8 *extra;
- unsigned long extraLen;
- ScreenPtr pScreen;
- rrScrPrivPtr pScrPriv;
- RRModePtr mode;
- RROutput *outputs;
- RROutput *possible;
- int i, j, k;
- REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
- crtc = LookupCrtc(client, stuff->crtc, SecurityReadAccess);
- if (!crtc)
- return RRErrorBase + BadRRCrtc;
- /* All crtcs must be associated with screens before client
- * requests are processed
- */
- pScreen = crtc->pScreen;
- pScrPriv = rrGetScrPriv(pScreen);
- mode = crtc->mode;
- rep.type = X_Reply;
- rep.status = RRSetConfigSuccess;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.timestamp = pScrPriv->lastSetTime.milliseconds;
- rep.x = crtc->x;
- rep.y = crtc->y;
- rep.width = mode ? mode->mode.width : 0;
- rep.height = mode ? mode->mode.height : 0;
- 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 (client->swapped) {
- swaps(&rep.sequenceNumber);
- swapl(&rep.length);
- swapl(&rep.timestamp);
- swaps(&rep.x);
- swaps(&rep.y);
- swaps(&rep.width);
- swaps(&rep.height);
- swapl(&rep.mode);
- swaps(&rep.rotation);
- swaps(&rep.rotations);
- swaps(&rep.nOutput);
- swaps(&rep.nPossibleOutput);
- }
- WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *) &rep);
- if (extraLen) {
- WriteToClient(client, extraLen, (char *) extra);
- free(extra);
- }
- return client->noClientException;
- }
- int
- ProcRRSetCrtcConfig(ClientPtr client)
- {
- REQUEST(xRRSetCrtcConfigReq);
- xRRSetCrtcConfigReply rep;
- ScreenPtr pScreen;
- rrScrPrivPtr pScrPriv;
- RRCrtcPtr crtc;
- RRModePtr mode;
- int numOutputs;
- RROutputPtr *outputs = NULL;
- RROutput *outputIds;
- TimeStamp configTime;
- TimeStamp time;
- Rotation rotation;
- int i, j;
- REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
- numOutputs = (stuff->length - (SIZEOF(xRRSetCrtcConfigReq) >> 2));
- crtc = LookupIDByType(stuff->crtc, RRCrtcType);
- if (!crtc) {
- client->errorValue = stuff->crtc;
- return RRErrorBase + BadRRCrtc;
- }
- if (stuff->mode == None) {
- mode = NULL;
- if (numOutputs > 0)
- return BadMatch;
- }
- else {
- mode = LookupIDByType(stuff->mode, RRModeType);
- if (!mode) {
- client->errorValue = stuff->mode;
- return RRErrorBase + BadRRMode;
- }
- if (numOutputs == 0)
- return BadMatch;
- }
- if (numOutputs) {
- outputs = malloc(numOutputs * sizeof(RROutputPtr));
- if (!outputs)
- return BadAlloc;
- }
- else
- outputs = NULL;
- outputIds = (RROutput *) (stuff + 1);
- for (i = 0; i < numOutputs; i++) {
- outputs[i] = (RROutputPtr) LookupIDByType(outputIds[i], RROutputType);
- if (!outputs[i]) {
- client->errorValue = outputIds[i];
- if (outputs)
- free(outputs);
- return RRErrorBase + BadRROutput;
- }
- /* validate crtc for this output */
- for (j = 0; j < outputs[i]->numCrtcs; j++)
- if (outputs[i]->crtcs[j] == crtc)
- break;
- if (j == outputs[i]->numCrtcs) {
- if (outputs)
- free(outputs);
- return BadMatch;
- }
- /* validate mode for this output */
- for (j = 0; j < outputs[i]->numModes; j++)
- if (outputs[i]->modes[j] == mode)
- break;
- if (j == outputs[i]->numModes) {
- if (outputs)
- free(outputs);
- return BadMatch;
- }
- }
- pScreen = crtc->pScreen;
- pScrPriv = rrGetScrPriv(pScreen);
- time = ClientTimeToServerTime(stuff->timestamp);
- configTime = ClientTimeToServerTime(stuff->configTimestamp);
- if (!pScrPriv) {
- rep.status = RRSetConfigFailed;
- goto sendReply;
- }
- /*
- * 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;
- }
- /*
- * Validate requested rotation
- */
- rotation = (Rotation) stuff->rotation;
- /* test the rotation bits only! */
- switch (rotation & 0xf) {
- case RR_Rotate_0:
- case RR_Rotate_90:
- case RR_Rotate_180:
- case RR_Rotate_270:
- break;
- default:
- /*
- * Invalid rotation
- */
- client->errorValue = stuff->rotation;
- if (outputs)
- free(outputs);
- return BadValue;
- }
- if (mode) {
- if ((~crtc->rotations) & rotation) {
- /*
- * requested rotation or reflection not supported by screen
- */
- client->errorValue = stuff->rotation;
- if (outputs)
- free(outputs);
- return BadMatch;
- }
- #ifdef RANDR_12_INTERFACE
- /*
- * Check screen size bounds if the DDX provides a 1.2 interface
- * for setting screen size. Else, assume the CrtcSet sets
- * the size along with the mode
- */
- if (pScrPriv->rrScreenSetSize) {
- int source_width = mode->mode.width;
- int source_height = mode->mode.height;
- if (rotation == RR_Rotate_90 || rotation == RR_Rotate_270) {
- source_width = mode->mode.height;
- source_height = mode->mode.width;
- }
- if (stuff->x + source_width > pScreen->width) {
- client->errorValue = stuff->x;
- if (outputs)
- free(outputs);
- return BadValue;
- }
- if (stuff->y + source_height > pScreen->height) {
- client->errorValue = stuff->y;
- if (outputs)
- free(outputs);
- return BadValue;
- }
- }
- #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 (!RRCrtcSet(crtc, mode, stuff->x, stuff->y,
- rotation, numOutputs, outputs)) {
- rep.status = RRSetConfigFailed;
- goto sendReply;
- }
- rep.status = RRSetConfigSuccess;
- sendReply:
- if (outputs)
- free(outputs);
- rep.type = X_Reply;
- /* rep.status has already been filled in */
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.newTimestamp = pScrPriv->lastConfigTime.milliseconds;
- if (client->swapped) {
- swaps(&rep.sequenceNumber);
- swapl(&rep.length);
- swapl(&rep.newTimestamp);
- }
- WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *) &rep);
- return client->noClientException;
- }
- int
- ProcRRGetCrtcGammaSize(ClientPtr client)
- {
- REQUEST(xRRGetCrtcGammaSizeReq);
- xRRGetCrtcGammaSizeReply reply;
- RRCrtcPtr crtc;
- REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq);
- crtc = LookupCrtc(client, stuff->crtc, SecurityReadAccess);
- if (!crtc)
- return RRErrorBase + BadRRCrtc;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = 0;
- reply.size = crtc->gammaSize;
- if (client->swapped) {
- swaps(&reply.sequenceNumber);
- swapl(&reply.length);
- swaps(&reply.size);
- }
- WriteToClient(client, sizeof(xRRGetCrtcGammaSizeReply), (char *) &reply);
- return client->noClientException;
- }
- int
- ProcRRGetCrtcGamma(ClientPtr client)
- {
- REQUEST(xRRGetCrtcGammaReq);
- xRRGetCrtcGammaReply reply;
- RRCrtcPtr crtc;
- unsigned long len;
- REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq);
- crtc = LookupCrtc(client, stuff->crtc, SecurityReadAccess);
- if (!crtc)
- return RRErrorBase + BadRRCrtc;
- len = crtc->gammaSize * 3 * 2;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = (len + 3) >> 2;
- reply.size = crtc->gammaSize;
- if (client->swapped) {
- swaps(&reply.sequenceNumber);
- swapl(&reply.length);
- swaps(&reply.size);
- }
- WriteToClient(client, sizeof(xRRGetCrtcGammaReply), (char *) &reply);
- if (crtc->gammaSize) {
- client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
- WriteSwappedDataToClient(client, len, (char *) crtc->gammaRed);
- }
- return client->noClientException;
- }
- int
- ProcRRSetCrtcGamma(ClientPtr client)
- {
- REQUEST(xRRSetCrtcGammaReq);
- RRCrtcPtr crtc;
- unsigned long len;
- CARD16 *red, *green, *blue;
- REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq);
- crtc = LookupCrtc(client, stuff->crtc, SecurityWriteAccess);
- if (!crtc)
- return RRErrorBase + BadRRCrtc;
- len = client->req_len - (sizeof(xRRSetCrtcGammaReq) >> 2);
- if (len < (stuff->size * 3 + 1) >> 1)
- return BadLength;
- if (stuff->size != crtc->gammaSize)
- return BadMatch;
- red = (CARD16 *) (stuff + 1);
- green = red + crtc->gammaSize;
- blue = green + crtc->gammaSize;
- RRCrtcGammaSet(crtc, red, green, blue);
- return Success;
- }
|