mirror of
https://github.com/X11Libre/xserver.git
synced 2026-09-11 18:42:23 +00:00
xkb: pass x_rpcbuf_t into XkbAssembleMap()
The keymap assembly machinery is a horribly complicated machinery, because often whole replies with variable sized payloads can be nested into each other. It's time to use x_rpcbuf_t for that, but's is not an easy thing to do and really a huge change - therefore doing this in small and easy to digest step. At first, let XkbAssembleMap() operate on a x_rpcbuf_t. But for now just let it use the x_rpcbuf_t's raw buffer directly (because it's callees cant work on this yet) - thus XkbAssembleMap() yet need to make enough room in the buffer before calling in. For the time being we're allocating far too much (because calculating the actually need amount would be too complicated here) and having an extra memcpy(). But it's just an intermediate step anyways - subsequent commits will convert everything down the whole call chain into using x_rpcbuf_t operations, so that extra overhead can be dropped again later. Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
parent
b59b6226d7
commit
742443ea73
1 changed files with 51 additions and 37 deletions
90
xkb/xkb.c
90
xkb/xkb.c
|
|
@ -33,6 +33,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <X11/extensions/XKMformat.h>
|
||||
|
||||
#include "dix/dix_priv.h"
|
||||
#include "dix/rpcbuf_priv.h"
|
||||
#include "miext/extinit_priv.h"
|
||||
#include "os/osdep.h"
|
||||
#include "xkb/xkbfmisc_priv.h"
|
||||
|
|
@ -1014,19 +1015,12 @@ XkbSizeKeyTypes(XkbDescPtr xkb, xkbGetMapReply * rep)
|
|||
return len;
|
||||
}
|
||||
|
||||
static char *
|
||||
XkbWriteKeyTypes(XkbDescPtr xkb, CARD8 firstType, CARD8 nTypes,
|
||||
char *buf, ClientPtr client)
|
||||
static void XkbWriteKeyTypes(XkbDescPtr xkb, CARD8 firstType, CARD8 nTypes,
|
||||
x_rpcbuf_t *rpcbuf, ClientPtr client)
|
||||
{
|
||||
XkbKeyTypePtr type;
|
||||
unsigned i;
|
||||
xkbKeyTypeWireDesc *wire;
|
||||
|
||||
type = &xkb->map->types[firstType];
|
||||
for (i = 0; i < nTypes; i++, type++) {
|
||||
register unsigned n;
|
||||
|
||||
wire = (xkbKeyTypeWireDesc *) buf;
|
||||
XkbKeyTypePtr type = &xkb->map->types[firstType];
|
||||
for (int i = 0; i < nTypes; i++, type++) {
|
||||
xkbKeyTypeWireDesc *wire = x_rpcbuf_reserve(rpcbuf, sizeof(xkbKeyTypeWireDesc));
|
||||
wire->mask = type->mods.mask;
|
||||
wire->realMods = type->mods.real_mods;
|
||||
wire->virtualMods = type->mods.vmods;
|
||||
|
|
@ -1037,13 +1031,14 @@ XkbWriteKeyTypes(XkbDescPtr xkb, CARD8 firstType, CARD8 nTypes,
|
|||
swaps(&wire->virtualMods);
|
||||
}
|
||||
|
||||
buf = (char *) &wire[1];
|
||||
if (wire->nMapEntries > 0) {
|
||||
xkbKTMapEntryWireDesc *ewire;
|
||||
XkbKTMapEntryPtr entry;
|
||||
if (type->map_count > 0) {
|
||||
void *space = x_rpcbuf_reserve(
|
||||
rpcbuf, sizeof(xkbKTMapEntryWireDesc) * type->map_count);
|
||||
xkbKTMapEntryWireDesc *ewire = space;
|
||||
XkbKTMapEntryPtr entry = type->map;
|
||||
|
||||
size_t n;
|
||||
|
||||
ewire = (xkbKTMapEntryWireDesc *) buf;
|
||||
entry = type->map;
|
||||
for (n = 0; n < type->map_count; n++, ewire++, entry++) {
|
||||
ewire->active = entry->active;
|
||||
ewire->mask = entry->mods.mask;
|
||||
|
|
@ -1054,13 +1049,12 @@ XkbWriteKeyTypes(XkbDescPtr xkb, CARD8 firstType, CARD8 nTypes,
|
|||
swaps(&ewire->virtualMods);
|
||||
}
|
||||
}
|
||||
buf = (char *) ewire;
|
||||
if (type->preserve != NULL) {
|
||||
xkbModsWireDesc *pwire;
|
||||
XkbModsPtr preserve;
|
||||
|
||||
pwire = (xkbModsWireDesc *) buf;
|
||||
preserve = type->preserve;
|
||||
if (type->preserve != NULL) {
|
||||
xkbModsWireDesc *pwire = x_rpcbuf_reserve(
|
||||
rpcbuf, sizeof(xkbModsWireDesc) * type->map_count);
|
||||
XkbModsPtr preserve = type->preserve;
|
||||
|
||||
for (n = 0; n < type->map_count; n++, pwire++, preserve++) {
|
||||
pwire->mask = preserve->mask;
|
||||
pwire->realMods = preserve->real_mods;
|
||||
|
|
@ -1069,11 +1063,9 @@ XkbWriteKeyTypes(XkbDescPtr xkb, CARD8 firstType, CARD8 nTypes,
|
|||
swaps(&pwire->virtualMods);
|
||||
}
|
||||
}
|
||||
buf = (char *) pwire;
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -1403,11 +1395,13 @@ XkbComputeGetMapReplySize(XkbDescPtr xkb, xkbGetMapReply * rep)
|
|||
return Success;
|
||||
}
|
||||
|
||||
static void
|
||||
XkbAssembleMap(ClientPtr client, XkbDescPtr xkb, xkbGetMapReply rep, char *desc)
|
||||
static void XkbAssembleMap(ClientPtr client, XkbDescPtr xkb,
|
||||
xkbGetMapReply rep, x_rpcbuf_t *rpcbuf)
|
||||
{
|
||||
if (rep.nTypes > 0)
|
||||
desc = XkbWriteKeyTypes(xkb, rep.firstType, rep.nTypes, desc, client);
|
||||
XkbWriteKeyTypes(xkb, rep.firstType, rep.nTypes, rpcbuf, client);
|
||||
|
||||
char *desc = rpcbuf->buffer + rpcbuf->wpos;
|
||||
|
||||
if (rep.nKeySyms > 0)
|
||||
desc = XkbWriteKeySyms(xkb, rep.firstKeySym, rep.nKeySyms, desc, client);
|
||||
if (rep.nKeyActs > 0)
|
||||
|
|
@ -1546,11 +1540,12 @@ ProcXkbGetMap(ClientPtr client)
|
|||
return status;
|
||||
|
||||
int payload_len = (rep.length * sizeof(CARD32)) - (sizeof(xkbGetMapReply) - sizeof(xGenericReply));
|
||||
char *payload_buf = calloc(1, payload_len);
|
||||
if (!payload_buf)
|
||||
|
||||
x_rpcbuf_t rpcbuf = { .swapped = client->swapped, .err_clear = TRUE };
|
||||
if (!x_rpcbuf_makeroom(&rpcbuf, payload_len))
|
||||
return BadAlloc;
|
||||
|
||||
XkbAssembleMap(client, xkb, rep, payload_buf);
|
||||
XkbAssembleMap(client, xkb, rep, &rpcbuf);
|
||||
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
|
|
@ -1560,9 +1555,11 @@ ProcXkbGetMap(ClientPtr client)
|
|||
swaps(&rep.totalActs);
|
||||
}
|
||||
|
||||
if (rpcbuf.error)
|
||||
return BadAlloc;
|
||||
|
||||
WriteToClient(client, sizeof(xkbGetMapReply), &rep);
|
||||
WriteToClient(client, payload_len, payload_buf);
|
||||
free(payload_buf);
|
||||
WriteToClient(client, payload_len, rpcbuf.buffer);
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
|
@ -6053,8 +6050,19 @@ ProcXkbGetKbdByName(ClientPtr client)
|
|||
}
|
||||
|
||||
if (reported & (XkbGBN_SymbolsMask | XkbGBN_TypesMask)) {
|
||||
char *buf = payload_walk + sizeof(mrep);
|
||||
XkbAssembleMap(client, new, mrep, buf);
|
||||
x_rpcbuf_t rpcbuf = { .swapped = client->swapped, .err_clear = TRUE };
|
||||
/* allocating far too much, but it's just temporary */
|
||||
if (!x_rpcbuf_makeroom(&rpcbuf, payload_length * 4)) {
|
||||
free(payload_buffer);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
XkbAssembleMap(client, new, mrep, &rpcbuf);
|
||||
|
||||
if (rpcbuf.error) {
|
||||
free(payload_buffer);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
if (client->swapped) {
|
||||
swaps(&mrep.sequenceNumber);
|
||||
|
|
@ -6064,8 +6072,14 @@ ProcXkbGetKbdByName(ClientPtr client)
|
|||
swaps(&mrep.totalActs);
|
||||
}
|
||||
|
||||
// struct is 8 bytes (2 units) longer than generic reply, so need to
|
||||
// compute the payload length carefully
|
||||
const size_t payloadBytes = (mrep.length * 4) - (sizeof(mrep) - sizeof(xGenericReply));
|
||||
memcpy(payload_walk, &mrep, sizeof(mrep));
|
||||
payload_walk = buf + (mrep.length * 4) - (sizeof(mrep) - sizeof(xGenericReply));
|
||||
payload_walk += sizeof(mrep);
|
||||
memcpy(payload_walk, rpcbuf.buffer, payloadBytes);
|
||||
payload_walk += payloadBytes;
|
||||
x_rpcbuf_clear(&rpcbuf);
|
||||
}
|
||||
|
||||
if (reported & XkbGBN_CompatMapMask) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue