int ProcRRSetCrtcTransform (ClientPtr client) { REQUEST(xRRSetCrtcTransformReq); RRCrtcPtr crtc; PictTransform transform; struct pixman_f_transform f_transform, f_inverse; char *filter; int nbytes; xFixed *params; int nparams; REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); PictTransform_from_xRenderTransform (&transform, &stuff->transform); pixman_f_transform_from_pixman_transform (&f_transform, &transform); if (!pixman_f_transform_invert (&f_inverse, &f_transform)) return BadMatch; filter = (char *) (stuff + 1); nbytes = stuff->nbytesFilter; params = (xFixed *) (filter + pad_to_int32(nbytes)); nparams = ((xFixed *) stuff + client->req_len) - params; if (nparams < 0) return BadLength; return RRCrtcTransformSet (crtc, &transform, &f_transform, &f_inverse, filter, nbytes, params, nparams); }
int ProcRRSetCrtcGamma (ClientPtr client) { REQUEST(xRRSetCrtcGammaReq); RRCrtcPtr crtc; unsigned long len; CARD16 *red, *green, *blue; REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); len = client->req_len - bytes_to_int32(sizeof (xRRSetCrtcGammaReq)); 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; }
int ProcRRGetCrtcGammaSize (ClientPtr client) { REQUEST(xRRGetCrtcGammaSizeReq); xRRGetCrtcGammaSizeReply reply; RRCrtcPtr crtc; int n; REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); /* Gamma retrieval failed, any better error? */ if (!RRCrtcGammaGet(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, n); swapl (&reply.length, n); swaps (&reply.size, n); } WriteToClient (client, sizeof (xRRGetCrtcGammaSizeReply), (char *) &reply); return Success; }
static int proc_present_query_capabilities (ClientPtr client) { REQUEST(xPresentQueryCapabilitiesReq); xPresentQueryCapabilitiesReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, }; WindowPtr window; RRCrtcPtr crtc = NULL; int r; REQUEST_SIZE_MATCH(xPresentQueryCapabilitiesReq); r = dixLookupWindow(&window, stuff->target, client, DixGetAttrAccess); switch (r) { case Success: crtc = present_get_crtc(window); break; case BadWindow: VERIFY_RR_CRTC(stuff->target, crtc, DixGetAttrAccess); break; default: return r; } rep.capabilities = present_query_capabilities(crtc); if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.capabilities); } WriteToClient(client, sizeof(rep), &rep); return Success; } static int (*proc_present_vector[PresentNumberRequests]) (ClientPtr) = { proc_present_query_version, /* 0 */ proc_present_pixmap, /* 1 */ proc_present_notify_msc, /* 2 */ proc_present_select_input, /* 3 */ proc_present_query_capabilities, /* 4 */ }; int proc_present_dispatch(ClientPtr client) { REQUEST(xReq); if (stuff->data >= PresentNumberRequests || !proc_present_vector[stuff->data]) return BadRequest; return (*proc_present_vector[stuff->data]) (client); }
int ProcRRGetCrtcTransform (ClientPtr client) { REQUEST(xRRGetCrtcTransformReq); xRRGetCrtcTransformReply *reply; RRCrtcPtr crtc; int n, nextra; RRTransformPtr current, pending; char *extra; REQUEST_SIZE_MATCH (xRRGetCrtcTransformReq); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); pending = &crtc->client_pending_transform; current = &crtc->client_current_transform; nextra = (transform_filter_length (pending) + transform_filter_length (current)); reply = malloc(sizeof (xRRGetCrtcTransformReply) + nextra); if (!reply) return BadAlloc; extra = (char *) (reply + 1); reply->type = X_Reply; reply->sequenceNumber = client->sequence; reply->length = bytes_to_int32(CrtcTransformExtra + nextra); reply->hasTransforms = crtc->transforms; transform_encode (client, &reply->pendingTransform, &pending->transform); extra += transform_filter_encode (client, extra, &reply->pendingNbytesFilter, &reply->pendingNparamsFilter, pending); transform_encode (client, &reply->currentTransform, ¤t->transform); extra += transform_filter_encode (client, extra, &reply->currentNbytesFilter, &reply->currentNparamsFilter, current); if (client->swapped) { swaps (&reply->sequenceNumber, n); swapl (&reply->length, n); } WriteToClient (client, sizeof (xRRGetCrtcTransformReply) + nextra, (char *) reply); free(reply); return Success; }
int ProcRRGetCrtcGamma (ClientPtr client) { REQUEST(xRRGetCrtcGammaReq); xRRGetCrtcGammaReply reply; RRCrtcPtr crtc; int n; unsigned long len; char *extra = NULL; REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); /* Gamma retrieval failed, any better error? */ if (!RRCrtcGammaGet(crtc)) return RRErrorBase + BadRRCrtc; len = crtc->gammaSize * 3 * 2; if (crtc->gammaSize) { extra = malloc(len); if (!extra) return BadAlloc; } reply.type = X_Reply; reply.sequenceNumber = client->sequence; reply.length = bytes_to_int32(len); reply.size = crtc->gammaSize; if (client->swapped) { swaps (&reply.sequenceNumber, n); swapl (&reply.length, n); swaps (&reply.size, n); } WriteToClient (client, sizeof (xRRGetCrtcGammaReply), (char *) &reply); if (crtc->gammaSize) { memcpy(extra, crtc->gammaRed, len); client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; WriteSwappedDataToClient (client, len, extra); free(extra); } return Success; }
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); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); /* All crtcs must be associated with screens before client * requests are processed */ pScreen = crtc->pScreen; pScrPriv = rrGetScrPriv(pScreen); if (!pScrPriv) return RRErrorBase + BadRRCrtc; memset(&rep, 0, sizeof(rep)); rep.type = X_Reply; rep.status = RRSetConfigSuccess; rep.sequenceNumber = client->sequence; rep.length = 1; rep.timestamp = pScrPriv->lastSetTime.milliseconds; if (pScrPriv->rrGetPanning && pScrPriv->rrGetPanning (pScreen, crtc, &total, &tracking, border)) { 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 Success; }
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 rc, i, j; REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); numOutputs = (stuff->length - bytes_to_int32(SIZEOF (xRRSetCrtcConfigReq))); VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess); if (stuff->mode == None) { mode = NULL; if (numOutputs > 0) return BadMatch; } else { VERIFY_RR_MODE(stuff->mode, mode, DixSetAttrAccess); 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++) { rc = dixLookupResourceByType((pointer *)(outputs + i), outputIds[i], RROutputType, client, DixSetAttrAccess); if (rc != Success) { free(outputs); return rc; } /* 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) { free(outputs); return BadMatch; } /* validate mode for this output */ for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++) { RRModePtr m = (j < outputs[i]->numModes ? outputs[i]->modes[j] : outputs[i]->userModes[j - outputs[i]->numModes]); if (m == mode) break; } if (j == outputs[i]->numModes + outputs[i]->numUserModes) { free(outputs); return BadMatch; } } /* validate clones */ for (i = 0; i < numOutputs; i++) { for (j = 0; j < numOutputs; j++) { int k; if (i == j) continue; for (k = 0; k < outputs[i]->numClones; k++) { if (outputs[i]->clones[k] == outputs[j]) break; } if (k == outputs[i]->numClones) { free(outputs); return BadMatch; } } } pScreen = crtc->pScreen; pScrPriv = rrGetScrPriv(pScreen); time = ClientTimeToServerTime(stuff->timestamp); configTime = ClientTimeToServerTime(stuff->configTimestamp); if (!pScrPriv) { time = currentTime; rep.status = RRSetConfigFailed; 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; free(outputs); return BadValue; } if (mode) { if ((~crtc->rotations) & rotation) { /* * requested rotation or reflection not supported by screen */ client->errorValue = stuff->rotation; 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 the driver supports transforms, * then it must allow crtcs to display a subset of the screen, so * only do this check for drivers without transform support. */ if (pScrPriv->rrScreenSetSize && !crtc->transforms) { int source_width; int source_height; PictTransform transform; struct pixman_f_transform f_transform, f_inverse; RRTransformCompute (stuff->x, stuff->y, mode->mode.width, mode->mode.height, rotation, &crtc->client_pending_transform, &transform, &f_transform, &f_inverse); RRModeGetScanoutSize (mode, &transform, &source_width, &source_height); if (stuff->x + source_width > pScreen->width) { client->errorValue = stuff->x; free(outputs); return BadValue; } if (stuff->y + source_height > pScreen->height) { client->errorValue = stuff->y; free(outputs); return BadValue; } } #endif } if (!RRCrtcSet (crtc, mode, stuff->x, stuff->y, rotation, numOutputs, outputs)) { rep.status = RRSetConfigFailed; goto sendReply; } rep.status = RRSetConfigSuccess; pScrPriv->lastSetTime = time; sendReply: free(outputs); rep.type = X_Reply; /* rep.status has already been filled in */ rep.length = 0; rep.sequenceNumber = client->sequence; rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; if (client->swapped) { int n; swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swapl(&rep.newTimestamp, n); } WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *)&rep); return Success; }
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, n; int width, height; BoxRec panned_area; REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); /* 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; 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], n); } 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], n); k++; } if (client->swapped) { swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swapl(&rep.timestamp, n); swaps(&rep.x, n); swaps(&rep.y, n); swaps(&rep.width, n); swaps(&rep.height, n); swapl(&rep.mode, n); swaps(&rep.rotation, n); swaps(&rep.rotations, n); swaps(&rep.nOutput, n); swaps(&rep.nPossibleOutput, n); } WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *)&rep); if (extraLen) { WriteToClient (client, extraLen, (char *) extra); free(extra); } return Success; }
int ProcRRSetPanning (ClientPtr client) { REQUEST(xRRSetPanningReq); xRRSetPanningReply rep; RRCrtcPtr crtc; ScreenPtr pScreen; rrScrPrivPtr pScrPriv; TimeStamp time; BoxRec total; BoxRec tracking; INT16 border[4]; int n; REQUEST_SIZE_MATCH(xRRSetPanningReq); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); /* 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); if (!pScrPriv->rrGetPanning) return RRErrorBase + BadRRCrtc; total.x1 = stuff->left; total.y1 = stuff->top; total.x2 = total.x1 + stuff->width; total.y2 = total.y1 + stuff->height; tracking.x1 = stuff->track_left; tracking.y1 = stuff->track_top; tracking.x2 = tracking.x1 + stuff->track_width; tracking.y2 = tracking.y1 + stuff->track_height; 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; pScrPriv->lastSetTime = time; 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 Success; }