aboutsummaryrefslogtreecommitdiff
path: root/libX11/src/xkb/XKBGetMap.c
diff options
context:
space:
mode:
Diffstat (limited to 'libX11/src/xkb/XKBGetMap.c')
-rw-r--r--libX11/src/xkb/XKBGetMap.c833
1 files changed, 833 insertions, 0 deletions
diff --git a/libX11/src/xkb/XKBGetMap.c b/libX11/src/xkb/XKBGetMap.c
new file mode 100644
index 000000000..59e996216
--- /dev/null
+++ b/libX11/src/xkb/XKBGetMap.c
@@ -0,0 +1,833 @@
+/* $Xorg: XKBGetMap.c,v 1.4 2000/08/17 19:45:02 cpqbld Exp $ */
+/************************************************************
+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.
+
+********************************************************/
+
+/* $XFree86: xc/lib/X11/XKBGetMap.c,v 1.9 2003/04/17 02:06:31 dawes Exp $ */
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#define NEED_MAP_READERS
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include <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;
+
+ map= xkb->map;
+ if (map->key_sym_map==NULL) {
+ register int offset;
+ XkbSymMapPtr oldMap;
+ xkbSymMapWireDesc *newMap;
+ map->key_sym_map= _XkbTypedCalloc((xkb->max_key_code+1),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 {
+ xkbSymMapWireDesc * newMap;
+ XkbSymMapPtr oldMap;
+ KeySym * newSyms;
+ int tmp;
+
+ 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;
+
+ 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) {
+ 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;
+xkbBehaviorWireDesc *wire;
+
+ if ( rep->totalKeyBehaviors>0 ) {
+ if ( xkb->server->behaviors == NULL ) {
+ int size = xkb->max_key_code+1;
+ 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++) {
+ wire= (xkbBehaviorWireDesc *)_XkbGetReadBufferPtr(buf,
+ SIZEOF(xkbBehaviorWireDesc));
+ if (wire==NULL)
+ 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 ) {
+ if ( xkb->server->explicit == NULL ) {
+ int size = xkb->max_key_code+1;
+ 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) {
+ 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 ((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) {
+ 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 (((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;
+ 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;
+}
+