randr: ProcRRGetCrtcTransform(): split reply header and payload

Using struct initializer for the reply header and only allocating the
payload on heap. This allows using generic macros for reply preparation
and send-out later.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1794>
This commit is contained in:
Enrico Weigelt, metux IT consult 2024-07-29 17:33:15 +02:00 committed by Marge Bot
parent 90abc95c85
commit c6f1b8a735

View File

@ -1752,8 +1752,6 @@ ProcRRSetCrtcTransform(ClientPtr client)
filter, nbytes, params, nparams); filter, nbytes, params, nparams);
} }
#define CrtcTransformExtra (SIZEOF(xRRGetCrtcTransformReply) - 32)
static int static int
transform_filter_length(RRTransformPtr transform) transform_filter_length(RRTransformPtr transform)
{ {
@ -1808,11 +1806,9 @@ int
ProcRRGetCrtcTransform(ClientPtr client) ProcRRGetCrtcTransform(ClientPtr client)
{ {
REQUEST(xRRGetCrtcTransformReq); REQUEST(xRRGetCrtcTransformReq);
xRRGetCrtcTransformReply *reply;
RRCrtcPtr crtc; RRCrtcPtr crtc;
int nextra; int nextra;
RRTransformPtr current, pending; RRTransformPtr current, pending;
char *extra;
REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq); REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq);
VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
@ -1823,33 +1819,36 @@ ProcRRGetCrtcTransform(ClientPtr client)
nextra = (transform_filter_length(pending) + nextra = (transform_filter_length(pending) +
transform_filter_length(current)); transform_filter_length(current));
reply = calloc(1, sizeof(xRRGetCrtcTransformReply) + nextra); char *extra_buf = calloc(1, nextra);
if (!reply) if (!extra_buf)
return BadAlloc; return BadAlloc;
extra = (char *) (reply + 1); char *extra = extra_buf;
reply->type = X_Reply;
reply->sequenceNumber = client->sequence;
reply->length = bytes_to_int32(CrtcTransformExtra + nextra);
reply->hasTransforms = crtc->transforms; xRRGetCrtcTransformReply rep = {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = bytes_to_int32(sizeof(xRRGetCrtcTransformReply) - sizeof(xReq)),
.hasTransforms = crtc->transforms,
};
transform_encode(client, &reply->pendingTransform, &pending->transform); transform_encode(client, &rep.pendingTransform, &pending->transform);
extra += transform_filter_encode(client, extra, extra += transform_filter_encode(client, extra,
&reply->pendingNbytesFilter, &rep.pendingNbytesFilter,
&reply->pendingNparamsFilter, pending); &rep.pendingNparamsFilter, pending);
transform_encode(client, &reply->currentTransform, &current->transform); transform_encode(client, &rep.currentTransform, &current->transform);
extra += transform_filter_encode(client, extra, extra += transform_filter_encode(client, extra,
&reply->currentNbytesFilter, &rep.currentNbytesFilter,
&reply->currentNparamsFilter, current); &rep.currentNparamsFilter, current);
if (client->swapped) { if (client->swapped) {
swaps(&reply->sequenceNumber); swaps(&rep.sequenceNumber);
swapl(&reply->length); swapl(&rep.length);
} }
WriteToClient(client, sizeof(xRRGetCrtcTransformReply) + nextra, reply); WriteToClient(client, sizeof(xRRGetCrtcTransformReply), &rep);
free(reply); WriteToClient(client, nextra, extra_buf);
free(extra_buf);
return Success; return Success;
} }