dix: write out X_GetProperty reply directly

No need for using a complex callback machinery, if we just move the
little pieces of byte-swapping directly into the request handler.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult 2025-04-04 19:20:17 +02:00
parent fc13768c3e
commit 67c09e3bc6
4 changed files with 42 additions and 57 deletions

View File

@ -419,22 +419,6 @@ DeleteAllWindowProperties(WindowPtr pWin)
pWin->properties = NULL; pWin->properties = NULL;
} }
static int
NullPropertyReply(ClientPtr client, ATOM propertyType, int format)
{
xGetPropertyReply reply = {
.type = X_Reply,
.format = format,
.sequenceNumber = client->sequence,
.length = 0,
.propertyType = propertyType,
.bytesAfter = 0,
.nItems = 0
};
WriteReplyToClient(client, sizeof(xGenericReply), &reply);
return Success;
}
/***************** /*****************
* GetProperty * GetProperty
* If type Any is specified, returns the property from the specified * If type Any is specified, returns the property from the specified
@ -452,7 +436,6 @@ ProcGetProperty(ClientPtr client)
unsigned long n, len, ind; unsigned long n, len, ind;
int rc; int rc;
WindowPtr pWin; WindowPtr pWin;
xGetPropertyReply reply;
Mask win_mode = DixGetPropAccess, prop_mode = DixReadAccess; Mask win_mode = DixGetPropAccess, prop_mode = DixReadAccess;
REQUEST(xGetPropertyReq); REQUEST(xGetPropertyReq);
@ -481,8 +464,17 @@ ProcGetProperty(ClientPtr client)
} }
rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode); rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode);
if (rc == BadMatch) if (rc == BadMatch) {
return NullPropertyReply(client, None, 0); xGetPropertyReply rep = {
.type = X_Reply,
.sequenceNumber = client->sequence,
};
if (client->swapped) {
swaps(&rep.sequenceNumber);
}
WriteToClient(client, sizeof(rep), &rep);
return Success;
}
else if (rc != Success) else if (rc != Success)
return rc; return rc;
@ -491,16 +483,19 @@ ProcGetProperty(ClientPtr client)
if (((stuff->type != pProp->type) && (stuff->type != AnyPropertyType)) if (((stuff->type != pProp->type) && (stuff->type != AnyPropertyType))
) { ) {
reply = (xGetPropertyReply) { xGetPropertyReply rep = {
.type = X_Reply, .type = X_Reply,
.sequenceNumber = client->sequence, .sequenceNumber = client->sequence,
.bytesAfter = pProp->size, .bytesAfter = pProp->size,
.format = pProp->format, .format = pProp->format,
.length = 0,
.nItems = 0,
.propertyType = pProp->type .propertyType = pProp->type
}; };
WriteReplyToClient(client, sizeof(xGenericReply), &reply); if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.propertyType);
swapl(&rep.bytesAfter);
}
WriteToClient(client, sizeof(rep), &rep);
return Success; return Success;
} }
@ -520,7 +515,7 @@ ProcGetProperty(ClientPtr client)
len = min(n - ind, 4 * stuff->longLength); len = min(n - ind, 4 * stuff->longLength);
reply = (xGetPropertyReply) { xGetPropertyReply rep = {
.type = X_Reply, .type = X_Reply,
.sequenceNumber = client->sequence, .sequenceNumber = client->sequence,
.bytesAfter = n - (ind + len), .bytesAfter = n - (ind + len),
@ -530,26 +525,15 @@ ProcGetProperty(ClientPtr client)
.propertyType = pProp->type .propertyType = pProp->type
}; };
if (stuff->delete && (reply.bytesAfter == 0)) if (stuff->delete && (rep.bytesAfter == 0))
deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp); deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp);
WriteReplyToClient(client, sizeof(xGenericReply), &reply); void *payload = calloc(1, len);
if (len) { if (!payload)
switch (reply.format) { return BadAlloc;
case 32: memcpy(payload, (char*)(pProp->data) + ind, len);
client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
break;
case 16:
client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
break;
default:
client->pSwapReplyFunc = (ReplySwapPtr) WriteToClient;
break;
}
WriteSwappedDataToClient(client, len, (char *) pProp->data + ind);
}
if (stuff->delete && (reply.bytesAfter == 0)) { if (stuff->delete && (rep.bytesAfter == 0)) {
/* Delete the Property */ /* Delete the Property */
if (pWin->properties == pProp) { if (pWin->properties == pProp) {
/* Takes care of head */ /* Takes care of head */
@ -567,6 +551,22 @@ ProcGetProperty(ClientPtr client)
free(pProp->data); free(pProp->data);
dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
} }
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.propertyType);
swapl(&rep.bytesAfter);
swapl(&rep.nItems);
if (rep.format == 32)
SwapLongs(payload, len / 4);
else if (rep.format == 16)
SwapShorts(payload, len / 2);
}
WriteToClient(client, sizeof(rep), &rep);
WriteToClient(client, len, payload);
free(payload);
return Success; return Success;
} }

View File

@ -181,17 +181,6 @@ SGenericReply(ClientPtr pClient, int size, xGenericReply * pRep)
WriteToClient(pClient, size, pRep); WriteToClient(pClient, size, pRep);
} }
void _X_COLD
SGetPropertyReply(ClientPtr pClient, int size, xGetPropertyReply * pRep)
{
swaps(&pRep->sequenceNumber);
swapl(&pRep->length);
swapl(&pRep->propertyType);
swapl(&pRep->bytesAfter);
swapl(&pRep->nItems);
WriteToClient(pClient, size, pRep);
}
void _X_COLD void _X_COLD
SListPropertiesReply(ClientPtr pClient, int size, xListPropertiesReply * pRep) SListPropertiesReply(ClientPtr pClient, int size, xListPropertiesReply * pRep)
{ {

View File

@ -735,7 +735,7 @@ ReplySwapPtr ReplySwapVector[256] = {
ReplyNotSwappd, ReplyNotSwappd,
ReplyNotSwappd, ReplyNotSwappd,
ReplyNotSwappd, ReplyNotSwappd,
(ReplySwapPtr) SGetPropertyReply, /* 20 */ ReplyNotSwappd, /* 20 */
(ReplySwapPtr) SListPropertiesReply, (ReplySwapPtr) SListPropertiesReply,
ReplyNotSwappd, ReplyNotSwappd,
ReplyNotSwappd, ReplyNotSwappd,

View File

@ -44,10 +44,6 @@ extern void SGenericReply(ClientPtr /* pClient */ ,
int /* size */ , int /* size */ ,
xGenericReply * /* pRep */ ); xGenericReply * /* pRep */ );
extern void SGetPropertyReply(ClientPtr /* pClient */ ,
int /* size */ ,
xGetPropertyReply * /* pRep */ );
extern void SListPropertiesReply(ClientPtr /* pClient */ , extern void SListPropertiesReply(ClientPtr /* pClient */ ,
int /* size */ , int /* size */ ,
xListPropertiesReply * /* pRep */ ); xListPropertiesReply * /* pRep */ );