aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/src/xkb/XKBGetMap.c
diff options
context:
space:
mode:
authorMihai Moldovan <ionic@ionic.de>2017-08-25 12:44:49 +0200
committerMihai Moldovan <ionic@ionic.de>2017-08-25 12:44:49 +0200
commitae0a2bfdeb9ceacb80aa03375353039d425b14b9 (patch)
treedaec55145477bcec69273e03d5c9ff10c10a4137 /nx-X11/lib/src/xkb/XKBGetMap.c
parentcbe2c0e44f412d07024207f374c0f56684adb088 (diff)
parent3b7e5a42f5abecb903a9d730d163d704520efb07 (diff)
downloadnx-libs-ae0a2bfdeb9ceacb80aa03375353039d425b14b9.tar.gz
nx-libs-ae0a2bfdeb9ceacb80aa03375353039d425b14b9.tar.bz2
nx-libs-ae0a2bfdeb9ceacb80aa03375353039d425b14b9.zip
Merge branch 'sunweaver-pr/libnx-x11-autoreconf' into 3.6.x
Attributes GH PR #498: https://github.com/ArcticaProject/nx-libs/pull/498
Diffstat (limited to 'nx-X11/lib/src/xkb/XKBGetMap.c')
-rw-r--r--nx-X11/lib/src/xkb/XKBGetMap.c882
1 files changed, 882 insertions, 0 deletions
diff --git a/nx-X11/lib/src/xkb/XKBGetMap.c b/nx-X11/lib/src/xkb/XKBGetMap.c
new file mode 100644
index 000000000..6e3c74343
--- /dev/null
+++ b/nx-X11/lib/src/xkb/XKBGetMap.c
@@ -0,0 +1,882 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, 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 Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#define NEED_MAP_READERS
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include <nx-X11/extensions/XKBproto.h>
+#include "XKBlibint.h"
+
+static Status
+_XkbReadKeyTypes(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep)
+{
+ int i, n, lastMapCount;
+ XkbKeyTypePtr type;
+
+ if (rep->nTypes > 0) {
+ n = rep->firstType + rep->nTypes;
+ if (xkb->map->num_types >= n)
+ n = xkb->map->num_types;
+ else if (XkbAllocClientMap(xkb, XkbKeyTypesMask, n) != Success)
+ return BadAlloc;
+
+ type = &xkb->map->types[rep->firstType];
+ for (i = 0; i < (int) rep->nTypes; i++, type++) {
+ xkbKeyTypeWireDesc *desc;
+ register int ndx;
+
+ ndx = i + rep->firstType;
+ if (ndx >= xkb->map->num_types)
+ xkb->map->num_types = ndx + 1;
+
+ desc = (xkbKeyTypeWireDesc *)
+ _XkbGetReadBufferPtr(buf, SIZEOF(xkbKeyTypeWireDesc));
+ if (desc == NULL)
+ return BadLength;
+
+ lastMapCount = type->map_count;
+ if (desc->nMapEntries > 0) {
+ if ((type->map == NULL) ||
+ (desc->nMapEntries > type->map_count)) {
+ XkbKTMapEntryRec *prev_map = type->map;
+
+ type->map = _XkbTypedRealloc(type->map, desc->nMapEntries,
+ XkbKTMapEntryRec);
+ if (type->map == NULL) {
+ _XkbFree(prev_map);
+ return BadAlloc;
+ }
+ }
+ }
+ else if (type->map != NULL) {
+ Xfree(type->map);
+ type->map_count = 0;
+ type->map = NULL;
+ }
+
+ if (desc->preserve && (desc->nMapEntries > 0)) {
+ if ((!type->preserve) || (desc->nMapEntries > lastMapCount)) {
+ XkbModsRec *prev_preserve = type->preserve;
+
+ type->preserve = _XkbTypedRealloc(type->preserve,
+ desc->nMapEntries,
+ XkbModsRec);
+ if (type->preserve == NULL) {
+ _XkbFree(prev_preserve);
+ return BadAlloc;
+ }
+ }
+ }
+ else if (type->preserve != NULL) {
+ Xfree(type->preserve);
+ type->preserve = NULL;
+ }
+
+ type->mods.mask = desc->mask;
+ type->mods.real_mods = desc->realMods;
+ type->mods.vmods = desc->virtualMods;
+ type->num_levels = desc->numLevels;
+ type->map_count = desc->nMapEntries;
+ if (desc->nMapEntries > 0) {
+ register xkbKTMapEntryWireDesc *wire;
+ register XkbKTMapEntryPtr entry;
+ register int size;
+
+ size = type->map_count * SIZEOF(xkbKTMapEntryWireDesc);
+ wire =
+ (xkbKTMapEntryWireDesc *) _XkbGetReadBufferPtr(buf, size);
+ if (wire == NULL)
+ return BadLength;
+ entry = type->map;
+ for (n = 0; n < type->map_count; n++, wire++, entry++) {
+ entry->active = wire->active;
+ entry->level = wire->level;
+ entry->mods.mask = wire->mask;
+ entry->mods.real_mods = wire->realMods;
+ entry->mods.vmods = wire->virtualMods;
+ }
+
+ if (desc->preserve) {
+ register xkbModsWireDesc *pwire;
+ register XkbModsPtr preserve;
+ register int sz;
+
+ sz = desc->nMapEntries * SIZEOF(xkbModsWireDesc);
+ pwire = (xkbModsWireDesc *) _XkbGetReadBufferPtr(buf, sz);
+ if (pwire == NULL)
+ return BadLength;
+ preserve = type->preserve;
+ for (n = 0; n < desc->nMapEntries; n++, pwire++, preserve++) {
+ preserve->mask = pwire->mask;
+ preserve->vmods = pwire->virtualMods;
+ preserve->real_mods = pwire->realMods;
+ }
+ }
+ }
+ }
+ }
+ return Success;
+}
+
+static Status
+_XkbReadKeySyms(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep)
+{
+ register int i;
+ XkbClientMapPtr map;
+ int size = xkb->max_key_code + 1;
+
+ if (((unsigned short) rep->firstKeySym + rep->nKeySyms) > size)
+ return BadLength;
+
+ map = xkb->map;
+ if (map->key_sym_map == NULL) {
+ register int offset;
+ XkbSymMapPtr oldMap;
+ xkbSymMapWireDesc *newMap;
+
+ map->key_sym_map = _XkbTypedCalloc(size, XkbSymMapRec);
+ if (map->key_sym_map == NULL)
+ return BadAlloc;
+ if (map->syms == NULL) {
+ int sz;
+
+ sz = (rep->totalSyms * 12) / 10;
+ sz = ((sz + (unsigned) 128) / 128) * 128;
+ map->syms = _XkbTypedCalloc(sz, KeySym);
+ if (map->syms == NULL)
+ return BadAlloc;
+ map->size_syms = sz;
+ }
+ offset = 1;
+ oldMap = &map->key_sym_map[rep->firstKeySym];
+ for (i = 0; i < (int) rep->nKeySyms; i++, oldMap++) {
+ newMap = (xkbSymMapWireDesc *)
+ _XkbGetReadBufferPtr(buf, SIZEOF(xkbSymMapWireDesc));
+ if (newMap == NULL)
+ return BadLength;
+ oldMap->kt_index[0] = newMap->ktIndex[0];
+ oldMap->kt_index[1] = newMap->ktIndex[1];
+ oldMap->kt_index[2] = newMap->ktIndex[2];
+ oldMap->kt_index[3] = newMap->ktIndex[3];
+ oldMap->group_info = newMap->groupInfo;
+ oldMap->width = newMap->width;
+ oldMap->offset = offset;
+ if (offset + newMap->nSyms >= map->size_syms) {
+ register int sz;
+ KeySym *prev_syms = map->syms;
+
+ sz = map->size_syms + 128;
+ map->syms = _XkbTypedRealloc(map->syms, sz, KeySym);
+ if (map->syms == NULL) {
+ _XkbFree(prev_syms);
+ map->size_syms = 0;
+ return BadAlloc;
+ }
+ map->size_syms = sz;
+ }
+ if (newMap->nSyms > 0) {
+ _XkbReadBufferCopyKeySyms(buf, (KeySym *) &map->syms[offset],
+ newMap->nSyms);
+ offset += newMap->nSyms;
+ }
+ else {
+ map->syms[offset] = 0;
+ }
+ }
+ map->num_syms = offset;
+ }
+ else {
+ XkbSymMapPtr oldMap = &map->key_sym_map[rep->firstKeySym];
+
+ for (i = 0; i < (int) rep->nKeySyms; i++, oldMap++) {
+ xkbSymMapWireDesc *newMap;
+ KeySym *newSyms;
+ int tmp;
+
+ newMap = (xkbSymMapWireDesc *)
+ _XkbGetReadBufferPtr(buf, SIZEOF(xkbSymMapWireDesc));
+ if (newMap == NULL)
+ return BadLength;
+
+ if (newMap->nSyms > 0)
+ tmp = newMap->nSyms;
+ else
+ tmp = 0;
+
+ newSyms = XkbResizeKeySyms(xkb, i + rep->firstKeySym, tmp);
+ if (newSyms == NULL)
+ return BadAlloc;
+ if (newMap->nSyms > 0)
+ _XkbReadBufferCopyKeySyms(buf, newSyms, newMap->nSyms);
+ else
+ newSyms[0] = NoSymbol;
+ oldMap->kt_index[0] = newMap->ktIndex[0];
+ oldMap->kt_index[1] = newMap->ktIndex[1];
+ oldMap->kt_index[2] = newMap->ktIndex[2];
+ oldMap->kt_index[3] = newMap->ktIndex[3];
+ oldMap->group_info = newMap->groupInfo;
+ oldMap->width = newMap->width;
+ }
+ }
+ return Success;
+}
+
+static Status
+_XkbReadKeyActions(XkbReadBufferPtr buf, XkbDescPtr info, xkbGetMapReply *rep)
+{
+ int i;
+ CARD8 numDescBuf[248];
+ CARD8 *numDesc = NULL;
+ register int nKeyActs;
+ Status ret = Success;
+
+ if ((nKeyActs = rep->nKeyActs) > 0) {
+ XkbSymMapPtr symMap;
+
+ if (nKeyActs < sizeof numDescBuf)
+ numDesc = numDescBuf;
+ else
+ numDesc = Xmalloc(nKeyActs * sizeof(CARD8));
+
+ if (!_XkbCopyFromReadBuffer(buf, (char *) numDesc, nKeyActs)) {
+ ret = BadLength;
+ goto done;
+ }
+ i = XkbPaddedSize(nKeyActs) - nKeyActs;
+ if ((i > 0) && (!_XkbSkipReadBufferData(buf, i))) {
+ ret = BadLength;
+ goto done;
+ }
+ symMap = &info->map->key_sym_map[rep->firstKeyAct];
+ for (i = 0; i < (int) rep->nKeyActs; i++, symMap++) {
+ if (numDesc[i] == 0) {
+ if ((i + rep->firstKeyAct) > (info->max_key_code + 1)) {
+ ret = BadLength;
+ goto done;
+ }
+ info->server->key_acts[i + rep->firstKeyAct] = 0;
+ }
+ else {
+ XkbAction *newActs;
+
+ /* 8/16/93 (ef) -- XXX! Verify size here (numdesc must be */
+ /* either zero or XkbKeyNumSyms(info,key) */
+ newActs = XkbResizeKeyActions(info, i + rep->firstKeyAct,
+ numDesc[i]);
+ if (newActs == NULL) {
+ ret = BadAlloc;
+ goto done;
+ }
+ if (!_XkbCopyFromReadBuffer(buf, (char *) newActs,
+ (int) (numDesc[i] * sizeof(XkbAction)))) {
+ ret = BadLength;
+ goto done;
+ }
+ }
+ }
+ }
+ done:
+ if (numDesc != NULL && numDesc != numDescBuf)
+ Xfree(numDesc);
+ return ret;
+}
+
+static Status
+_XkbReadKeyBehaviors(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep)
+{
+ register int i;
+
+ if (rep->totalKeyBehaviors > 0) {
+ int size = xkb->max_key_code + 1;
+
+ if (((int) rep->firstKeyBehavior + rep->nKeyBehaviors) > size)
+ return BadLength;
+ if (xkb->server->behaviors == NULL) {
+ xkb->server->behaviors = _XkbTypedCalloc(size, XkbBehavior);
+ if (xkb->server->behaviors == NULL)
+ return BadAlloc;
+ }
+ else {
+ bzero(&xkb->server->behaviors[rep->firstKeyBehavior],
+ (rep->nKeyBehaviors * sizeof(XkbBehavior)));
+ }
+ for (i = 0; i < rep->totalKeyBehaviors; i++) {
+ xkbBehaviorWireDesc *wire;
+
+ wire = (xkbBehaviorWireDesc *) _XkbGetReadBufferPtr(buf,
+ SIZEOF(xkbBehaviorWireDesc));
+ if (wire == NULL || wire->key >= size)
+ return BadLength;
+ xkb->server->behaviors[wire->key].type = wire->type;
+ xkb->server->behaviors[wire->key].data = wire->data;
+ }
+ }
+ return Success;
+}
+
+static Status
+_XkbReadVirtualMods(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep)
+{
+ if (rep->virtualMods) {
+ register int i, bit, nVMods;
+ register char *data;
+
+ for (i = nVMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
+ if (rep->virtualMods & bit)
+ nVMods++;
+ }
+ data = _XkbGetReadBufferPtr(buf, XkbPaddedSize(nVMods));
+ if (data == NULL)
+ return BadLength;
+ for (i = 0, bit = 1; (i < XkbNumVirtualMods) && (nVMods > 0);
+ i++, bit <<= 1) {
+ if (rep->virtualMods & bit) {
+ xkb->server->vmods[i] = *data++;
+ nVMods--;
+ }
+ }
+ }
+ return Success;
+}
+
+static Status
+_XkbReadExplicitComponents(XkbReadBufferPtr buf,
+ XkbDescPtr xkb,
+ xkbGetMapReply *rep)
+{
+ register int i;
+ unsigned char *wire;
+
+ if (rep->totalKeyExplicit > 0) {
+ int size = xkb->max_key_code + 1;
+
+ if (((int) rep->firstKeyExplicit + rep->nKeyExplicit) > size)
+ return BadLength;
+ if (xkb->server->explicit == NULL) {
+ xkb->server->explicit = _XkbTypedCalloc(size, unsigned char);
+
+ if (xkb->server->explicit == NULL)
+ return BadAlloc;
+ }
+ else {
+ bzero(&xkb->server->explicit[rep->firstKeyExplicit],
+ rep->nKeyExplicit);
+ }
+ i = XkbPaddedSize(2 * rep->totalKeyExplicit);
+ wire = (unsigned char *) _XkbGetReadBufferPtr(buf, i);
+ if (!wire)
+ return BadLength;
+ for (i = 0; i < rep->totalKeyExplicit; i++, wire += 2) {
+ if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code)
+ return BadLength;
+ xkb->server->explicit[wire[0]] = wire[1];
+ }
+ }
+ return Success;
+}
+
+static Status
+_XkbReadModifierMap(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep)
+{
+ register int i;
+ unsigned char *wire;
+
+ if (rep->totalModMapKeys > 0) {
+ if (((int) rep->firstModMapKey + rep->nModMapKeys) >
+ (xkb->max_key_code + 1))
+ return BadLength;
+ if ((xkb->map->modmap == NULL) &&
+ (XkbAllocClientMap(xkb, XkbModifierMapMask, 0) != Success)) {
+ return BadAlloc;
+ }
+ else {
+ bzero(&xkb->map->modmap[rep->firstModMapKey], rep->nModMapKeys);
+ }
+ i = XkbPaddedSize(2 * rep->totalModMapKeys);
+ wire = (unsigned char *) _XkbGetReadBufferPtr(buf, i);
+ if (!wire)
+ return BadLength;
+ for (i = 0; i < rep->totalModMapKeys; i++, wire += 2) {
+ if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code)
+ return BadLength;
+ xkb->map->modmap[wire[0]] = wire[1];
+ }
+ }
+ return Success;
+}
+
+static Status
+_XkbReadVirtualModMap(XkbReadBufferPtr buf,
+ XkbDescPtr xkb,
+ xkbGetMapReply *rep)
+{
+ register int i;
+ xkbVModMapWireDesc *wire;
+ XkbServerMapPtr srv;
+
+ if (rep->totalVModMapKeys > 0) {
+ if (((int) rep->firstVModMapKey + rep->nVModMapKeys)
+ > xkb->max_key_code + 1)
+ return BadLength;
+ if (((xkb->server == NULL) || (xkb->server->vmodmap == NULL)) &&
+ (XkbAllocServerMap(xkb, XkbVirtualModMapMask, 0) != Success)) {
+ return BadAlloc;
+ }
+ else {
+ srv = xkb->server;
+ if (rep->nVModMapKeys > rep->firstVModMapKey)
+ bzero((char *) &srv->vmodmap[rep->firstVModMapKey],
+ (rep->nVModMapKeys - rep->firstVModMapKey) *
+ sizeof(unsigned short));
+ }
+ srv = xkb->server;
+ i = rep->totalVModMapKeys * SIZEOF(xkbVModMapWireDesc);
+ wire = (xkbVModMapWireDesc *) _XkbGetReadBufferPtr(buf, i);
+ if (!wire)
+ return BadLength;
+ for (i = 0; i < rep->totalVModMapKeys; i++, wire++) {
+ if ((wire->key >= xkb->min_key_code) &&
+ (wire->key <= xkb->max_key_code))
+ srv->vmodmap[wire->key] = wire->vmods;
+ }
+ }
+ return Success;
+}
+
+static xkbGetMapReq *
+_XkbGetGetMapReq(Display *dpy, XkbDescPtr xkb)
+{
+ xkbGetMapReq *req;
+
+ GetReq(kbGetMap, req);
+ req->reqType = dpy->xkb_info->codes->major_opcode;
+ req->xkbReqType = X_kbGetMap;
+ req->deviceSpec = xkb->device_spec;
+ req->full = req->partial = 0;
+ req->firstType = req->nTypes = 0;
+ req->firstKeySym = req->nKeySyms = 0;
+ req->firstKeyAct = req->nKeyActs = 0;
+ req->firstKeyBehavior = req->nKeyBehaviors = 0;
+ req->virtualMods = 0;
+ req->firstKeyExplicit = req->nKeyExplicit = 0;
+ req->firstModMapKey = req->nModMapKeys = 0;
+ req->firstVModMapKey = req->nVModMapKeys = 0;
+ return req;
+}
+
+Status
+_XkbReadGetMapReply(Display *dpy,
+ xkbGetMapReply *rep,
+ XkbDescPtr xkb,
+ int *nread_rtrn)
+{
+ int extraData;
+ unsigned mask;
+
+ if (xkb->device_spec == XkbUseCoreKbd)
+ xkb->device_spec = rep->deviceID;
+ if (rep->maxKeyCode < rep->minKeyCode)
+ return BadImplementation;
+ xkb->min_key_code = rep->minKeyCode;
+ xkb->max_key_code = rep->maxKeyCode;
+
+ if (!xkb->map) {
+ mask = rep->present & XkbAllClientInfoMask;
+ if (mask && (XkbAllocClientMap(xkb, mask, rep->nTypes) != Success))
+ return BadAlloc;
+ }
+ if (!xkb->server) {
+ mask = rep->present & XkbAllServerInfoMask;
+ if (mask && (XkbAllocServerMap(xkb, mask, rep->totalActs) != Success))
+ return BadAlloc;
+ }
+ extraData = (int) (rep->length * 4);
+ extraData -= (SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply));
+ if (rep->length) {
+ XkbReadBufferRec buf;
+ int left;
+
+ if (_XkbInitReadBuffer(dpy, &buf, extraData)) {
+ Status status = Success;
+
+ if (nread_rtrn != NULL)
+ *nread_rtrn = extraData;
+ if (status == Success)
+ status = _XkbReadKeyTypes(&buf, xkb, rep);
+ if (status == Success)
+ status = _XkbReadKeySyms(&buf, xkb, rep);
+ if (status == Success)
+ status = _XkbReadKeyActions(&buf, xkb, rep);
+ if (status == Success)
+ status = _XkbReadKeyBehaviors(&buf, xkb, rep);
+ if (status == Success)
+ status = _XkbReadVirtualMods(&buf, xkb, rep);
+ if (status == Success)
+ status = _XkbReadExplicitComponents(&buf, xkb, rep);
+ if (status == Success)
+ status = _XkbReadModifierMap(&buf, xkb, rep);
+ if (status == Success)
+ status = _XkbReadVirtualModMap(&buf, xkb, rep);
+ left = _XkbFreeReadBuffer(&buf);
+ if (status != Success)
+ return status;
+ else if (left || buf.error)
+ return BadLength;
+ }
+ else
+ return BadAlloc;
+ }
+ return Success;
+}
+
+static Status
+_XkbHandleGetMapReply(Display *dpy, XkbDescPtr xkb)
+{
+ xkbGetMapReply rep;
+
+ if (!_XReply(dpy, (xReply *) &rep,
+ ((SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)) >> 2),
+ xFalse)) {
+ return BadImplementation;
+ }
+ return _XkbReadGetMapReply(dpy, &rep, xkb, NULL);
+}
+
+Status
+XkbGetUpdatedMap(Display *dpy, unsigned which, XkbDescPtr xkb)
+{
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
+ return BadAccess;
+ if (which) {
+ register xkbGetMapReq *req;
+ Status status;
+
+ LockDisplay(dpy);
+
+ req = _XkbGetGetMapReq(dpy, xkb);
+ req->full = which;
+ status = _XkbHandleGetMapReply(dpy, xkb);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return status;
+ }
+ return Success;
+}
+
+XkbDescPtr
+XkbGetMap(Display *dpy, unsigned which, unsigned deviceSpec)
+{
+ XkbDescPtr xkb;
+
+ xkb = _XkbTypedCalloc(1, XkbDescRec);
+ if (xkb) {
+ xkb->device_spec = deviceSpec;
+ xkb->map = _XkbTypedCalloc(1, XkbClientMapRec);
+ if ((xkb->map == NULL) ||
+ ((which) && (XkbGetUpdatedMap(dpy, which, xkb) != Success))) {
+ if (xkb->map) {
+ Xfree(xkb->map);
+ xkb->map = NULL;
+ }
+ Xfree(xkb);
+ return NULL;
+ }
+ xkb->dpy = dpy;
+ }
+ return xkb;
+}
+
+Status
+XkbGetKeyTypes(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb)
+{
+ register xkbGetMapReq *req;
+ Status status;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
+ return BadAccess;
+ if ((num < 1) || (num > XkbMaxKeyTypes))
+ return BadValue;
+
+ LockDisplay(dpy);
+
+ req = _XkbGetGetMapReq(dpy, xkb);
+ req->firstType = first;
+ req->nTypes = num;
+ status = _XkbHandleGetMapReply(dpy, xkb);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return status;
+}
+
+Status
+XkbGetKeyActions(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb)
+{
+ register xkbGetMapReq *req;
+ Status status;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
+ return BadAccess;
+
+ if ((num < 1) || (num > XkbMaxKeyCount))
+ return BadValue;
+
+ LockDisplay(dpy);
+
+ req = _XkbGetGetMapReq(dpy, xkb);
+ req->firstKeyAct = first;
+ req->nKeyActs = num;
+ status = _XkbHandleGetMapReply(dpy, xkb);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return status;
+}
+
+Status
+XkbGetKeySyms(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb)
+{
+ register xkbGetMapReq *req;
+ Status status;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
+ return BadAccess;
+
+ if ((num < 1) || (num > XkbMaxKeyCount))
+ return BadValue;
+
+ LockDisplay(dpy);
+
+ req = _XkbGetGetMapReq(dpy, xkb);
+ req->firstKeySym = first;
+ req->nKeySyms = num;
+ status = _XkbHandleGetMapReply(dpy, xkb);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return status;
+}
+
+Status
+XkbGetKeyBehaviors(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb)
+{
+ register xkbGetMapReq *req;
+ Status status;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
+ return BadAccess;
+
+ if ((num < 1) || (num > XkbMaxKeyCount))
+ return BadValue;
+
+ LockDisplay(dpy);
+
+ req = _XkbGetGetMapReq(dpy, xkb);
+ req->firstKeyBehavior = first;
+ req->nKeyBehaviors = num;
+ status = _XkbHandleGetMapReply(dpy, xkb);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return status;
+}
+
+Status
+XkbGetVirtualMods(Display *dpy, unsigned which, XkbDescPtr xkb)
+{
+ register xkbGetMapReq *req;
+ Status status;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
+ return BadAccess;
+
+ LockDisplay(dpy);
+
+ req = _XkbGetGetMapReq(dpy, xkb);
+ req->virtualMods = which;
+ status = _XkbHandleGetMapReply(dpy, xkb);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return status;
+}
+
+Status
+XkbGetKeyExplicitComponents(Display *dpy,
+ unsigned first,
+ unsigned num,
+ XkbDescPtr xkb)
+{
+ register xkbGetMapReq *req;
+ Status status;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
+ return BadAccess;
+
+ if ((num < 1) || (num > XkbMaxKeyCount))
+ return BadValue;
+
+ LockDisplay(dpy);
+
+ req = _XkbGetGetMapReq(dpy, xkb);
+ req->firstKeyExplicit = first;
+ req->nKeyExplicit = num;
+ if ((xkb != NULL) && (xkb->server != NULL) &&
+ (xkb->server->explicit != NULL)) {
+ if ((num > 0) && (first >= xkb->min_key_code) &&
+ (first + num <= xkb->max_key_code))
+ bzero(&xkb->server->explicit[first], num);
+ }
+ if (xkb)
+ status = _XkbHandleGetMapReply(dpy, xkb);
+ else
+ status = BadMatch;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return status;
+}
+
+Status
+XkbGetKeyModifierMap(Display *dpy,
+ unsigned first,
+ unsigned num,
+ XkbDescPtr xkb)
+{
+ register xkbGetMapReq *req;
+ Status status;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
+ return BadAccess;
+
+ if ((num < 1) || (num > XkbMaxKeyCount))
+ return BadValue;
+
+ LockDisplay(dpy);
+
+ req = _XkbGetGetMapReq(dpy, xkb);
+ req->firstModMapKey = first;
+ req->nModMapKeys = num;
+ if ((xkb != NULL) && (xkb->map != NULL) && (xkb->map->modmap != NULL)) {
+ if ((num > 0) && (first >= xkb->min_key_code) &&
+ (first + num <= xkb->max_key_code))
+ bzero(&xkb->map->modmap[first], num);
+ }
+ if (xkb)
+ status = _XkbHandleGetMapReply(dpy, xkb);
+ else
+ status = BadMatch;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return status;
+}
+
+Status
+XkbGetKeyVirtualModMap(Display *dpy, unsigned first, unsigned num,
+ XkbDescPtr xkb)
+{
+ register xkbGetMapReq *req;
+ Status status;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
+ return BadAccess;
+
+ if ((num < 1) || (num > XkbMaxKeyCount))
+ return BadValue;
+
+ LockDisplay(dpy);
+
+ req = _XkbGetGetMapReq(dpy, xkb);
+ req->firstVModMapKey = first;
+ req->nVModMapKeys = num;
+ if ((xkb != NULL) && (xkb->map != NULL) && (xkb->map->modmap != NULL)) {
+ if ((num > 0) && (first >= xkb->min_key_code) &&
+ (first + num <= xkb->max_key_code))
+ bzero(&xkb->server->vmodmap[first], num * sizeof(unsigned short));
+ }
+
+ if (xkb)
+ status = _XkbHandleGetMapReply(dpy, xkb);
+ else
+ status = BadMatch;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return status;
+}
+
+Status
+XkbGetMapChanges(Display *dpy, XkbDescPtr xkb, XkbMapChangesPtr changes)
+{
+ xkbGetMapReq *req;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
+ return BadAccess;
+ LockDisplay(dpy);
+ if (changes->changed) {
+ Status status = Success;
+
+ req = _XkbGetGetMapReq(dpy, xkb);
+ req->full = 0;
+ req->partial = changes->changed;
+ req->firstType = changes->first_type;
+ req->nTypes = changes->num_types;
+ req->firstKeySym = changes->first_key_sym;
+ req->nKeySyms = changes->num_key_syms;
+ req->firstKeyAct = changes->first_key_act;
+ req->nKeyActs = changes->num_key_acts;
+ req->firstKeyBehavior = changes->first_key_behavior;
+ req->nKeyBehaviors = changes->num_key_behaviors;
+ req->virtualMods = changes->vmods;
+ req->firstKeyExplicit = changes->first_key_explicit;
+ req->nKeyExplicit = changes->num_key_explicit;
+ req->firstModMapKey = changes->first_modmap_key;
+ req->nModMapKeys = changes->num_modmap_keys;
+ req->firstVModMapKey = changes->first_vmodmap_key;
+ req->nVModMapKeys = changes->num_vmodmap_keys;
+ status = _XkbHandleGetMapReply(dpy, xkb);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return status;
+ }
+ UnlockDisplay(dpy);
+ return Success;
+}