aboutsummaryrefslogtreecommitdiff
path: root/libX11/src/xkb/XKBNames.c
diff options
context:
space:
mode:
Diffstat (limited to 'libX11/src/xkb/XKBNames.c')
-rw-r--r--libX11/src/xkb/XKBNames.c891
1 files changed, 891 insertions, 0 deletions
diff --git a/libX11/src/xkb/XKBNames.c b/libX11/src/xkb/XKBNames.c
new file mode 100644
index 000000000..a8eeb2adf
--- /dev/null
+++ b/libX11/src/xkb/XKBNames.c
@@ -0,0 +1,891 @@
+/* $Xorg: XKBNames.c,v 1.3 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/XKBNames.c,v 1.5 2003/04/13 19:22:18 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
+_XkbReadAtoms( XkbReadBufferPtr buf,
+ Atom * atoms,
+ int maxAtoms,
+ CARD32 present)
+{
+register int i,bit;
+
+ for (i=0,bit=1;(i<maxAtoms)&&(present);i++,bit<<=1) {
+ if (present&bit) {
+ if (!_XkbReadBufferCopy32(buf,(long *)&atoms[i],1))
+ return BadLength;
+ present&= ~bit;
+ }
+ }
+ return Success;
+}
+
+Status
+_XkbReadGetNamesReply( Display * dpy,
+ xkbGetNamesReply * rep,
+ XkbDescPtr xkb,
+ int * nread_rtrn)
+{
+ int i,len;
+ XkbReadBufferRec buf;
+ register XkbNamesPtr names;
+
+ if ( xkb->device_spec == XkbUseCoreKbd )
+ xkb->device_spec = rep->deviceID;
+
+ if ((xkb->names==NULL)&&
+ (XkbAllocNames(xkb,rep->which,
+ rep->nRadioGroups,rep->nKeyAliases)!=Success)) {
+ return BadAlloc;
+ }
+ names= xkb->names;
+ if (rep->length==0)
+ return Success;
+
+ if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4))
+ return BadAlloc;
+ if (nread_rtrn)
+ *nread_rtrn= (int)rep->length*4;
+
+ if ((rep->which&XkbKeycodesNameMask)&&
+ (!_XkbReadBufferCopy32(&buf,(long *)&names->keycodes,1)))
+ goto BAILOUT;
+ if ((rep->which&XkbGeometryNameMask)&&
+ (!_XkbReadBufferCopy32(&buf,(long *)&names->geometry,1)))
+ goto BAILOUT;
+ if ((rep->which&XkbSymbolsNameMask)&&
+ (!_XkbReadBufferCopy32(&buf,(long *)&names->symbols,1)))
+ goto BAILOUT;
+ if ((rep->which&XkbPhysSymbolsNameMask)&&
+ (!_XkbReadBufferCopy32(&buf,(long *)&names->phys_symbols,1)))
+ goto BAILOUT;
+ if ((rep->which&XkbTypesNameMask)&&
+ (!_XkbReadBufferCopy32(&buf,(long *)&names->types,1)))
+ goto BAILOUT;
+ if ((rep->which&XkbCompatNameMask)&&
+ (!_XkbReadBufferCopy32(&buf,(long *)&names->compat,1)))
+ goto BAILOUT;
+
+ if ( rep->which & XkbKeyTypeNamesMask ) {
+ XkbClientMapPtr map= xkb->map;
+ XkbKeyTypePtr type;
+
+ len= rep->nTypes*4;
+ if (map!=NULL) {
+ type= map->types;
+ for (i=0;(i<map->num_types)&&(i<rep->nTypes);i++,type++) {
+ if (!_XkbReadBufferCopy32(&buf,(long *)&type->name,1))
+ goto BAILOUT;
+ len-= 4;
+ }
+ }
+ if ((len>0)&&(!_XkbSkipReadBufferData(&buf,len)))
+ goto BAILOUT;
+ }
+ if ( rep->which&XkbKTLevelNamesMask ) {
+ CARD8 *nLevels;
+ XkbClientMapPtr map= xkb->map;
+ XkbKeyTypePtr type;
+
+ nLevels=(CARD8*)_XkbGetReadBufferPtr(&buf,XkbPaddedSize(rep->nTypes));
+ if (nLevels==NULL)
+ goto BAILOUT;
+ if (map!=NULL) {
+ type= map->types;
+ for (i=0;i<(int)rep->nTypes;i++,type++) {
+ if (i>=map->num_types) {
+ if (!_XkbSkipReadBufferData(&buf,nLevels[i]*4))
+ goto BAILOUT;
+ continue;
+ }
+ if ((nLevels[i]>0)&&(nLevels[i]!=type->num_levels)) {
+ goto BAILOUT;
+ }
+ if (type->level_names!=NULL)
+ Xfree(type->level_names);
+ if (nLevels[i]==0) {
+ type->level_names= NULL;
+ continue;
+ }
+ type->level_names= _XkbTypedCalloc(nLevels[i],Atom);
+ if (type->level_names!=NULL) {
+ if (!_XkbReadBufferCopy32(&buf,(long *)type->level_names,
+ nLevels[i]))
+ goto BAILOUT;
+ }
+ else {
+ _XkbSkipReadBufferData(&buf,nLevels[i]*4);
+ }
+ }
+ }
+ else {
+ for (i=0;i<(int)rep->nTypes;i++) {
+ _XkbSkipReadBufferData(&buf,nLevels[i]*4);
+ }
+ }
+ }
+ if (rep->which & XkbIndicatorNamesMask) {
+ if (_XkbReadAtoms(&buf,names->indicators,XkbNumIndicators,
+ rep->indicators)!=Success)
+ goto BAILOUT;
+ }
+ if ( rep->which&XkbVirtualModNamesMask ) {
+ if (_XkbReadAtoms(&buf,names->vmods,XkbNumVirtualMods,
+ (CARD32)rep->virtualMods)!=Success)
+ goto BAILOUT;
+ }
+ if ( rep->which&XkbGroupNamesMask ) {
+ if (_XkbReadAtoms(&buf,names->groups,XkbNumKbdGroups,
+ (CARD32)rep->groupNames)!=Success)
+ goto BAILOUT;
+ }
+ if ( rep->which&XkbKeyNamesMask ) {
+ if (names->keys==NULL) {
+ int nKeys;
+ if (xkb->max_key_code==0) {
+ xkb->min_key_code= rep->minKeyCode;
+ xkb->max_key_code= rep->maxKeyCode;
+ }
+ nKeys= xkb->max_key_code+1;
+ names->keys= _XkbTypedCalloc(nKeys,XkbKeyNameRec);
+ }
+ if (names->keys!=NULL) {
+ if (!_XkbCopyFromReadBuffer(&buf,
+ (char *)&names->keys[rep->firstKey],
+ rep->nKeys*XkbKeyNameLength))
+ goto BAILOUT;
+ }
+ else _XkbSkipReadBufferData(&buf,rep->nKeys*XkbKeyNameLength);
+ }
+ if ( rep->which&XkbKeyAliasesMask && (rep->nKeyAliases>0) ) {
+ if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,rep->nKeyAliases)!=Success)
+ goto BAILOUT;
+ if (!_XkbCopyFromReadBuffer(&buf,(char *)names->key_aliases,
+ rep->nKeyAliases*XkbKeyNameLength*2))
+ goto BAILOUT;
+ }
+ if ( rep->which&XkbRGNamesMask ) {
+ if (rep->nRadioGroups>0) {
+ Atom *rgNames;
+
+ if (names->radio_groups==NULL)
+ names->radio_groups = _XkbTypedCalloc(rep->nRadioGroups,Atom);
+ else if (names->num_rg<rep->nRadioGroups) {
+ names->radio_groups = _XkbTypedRealloc(names->radio_groups,
+ rep->nRadioGroups,
+ Atom);
+ }
+ rgNames= names->radio_groups;
+ if (!rgNames) {
+ goto BAILOUT;
+ }
+ if (!_XkbReadBufferCopy32(&buf,(long *)rgNames,rep->nRadioGroups))
+ goto BAILOUT;
+ names->num_rg= rep->nRadioGroups;
+ }
+ else if (names->num_rg>0) {
+ names->num_rg= 0;
+ Xfree(names->radio_groups);
+ }
+ }
+ len= _XkbFreeReadBuffer(&buf);
+ if (len!=0) return BadLength;
+ else return Success;
+BAILOUT:
+ _XkbFreeReadBuffer(&buf);
+ return BadLength;
+}
+
+Status
+XkbGetNames(Display *dpy,unsigned which,XkbDescPtr xkb)
+{
+ register xkbGetNamesReq *req;
+ xkbGetNamesReply rep;
+ Status status;
+ XkbInfoPtr xkbi;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return BadAccess;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ if (!xkb->names) {
+ xkb->names = _XkbTypedCalloc(1,XkbNamesRec);
+ if (!xkb->names) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return BadAlloc;
+ }
+ }
+ GetReq(kbGetNames, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbGetNames;
+ req->deviceSpec = xkb->device_spec;
+ req->which = which;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return BadImplementation;
+ }
+
+ status = _XkbReadGetNamesReply(dpy,&rep,xkb,NULL);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return status;
+}
+
+/***====================================================================***/
+
+static int
+_XkbCountBits(int nBitsMax,unsigned long mask)
+{
+register unsigned long y, nBits;
+
+ y = (mask >> 1) &033333333333;
+ y = mask - y - ((y >>1) & 033333333333);
+ nBits = ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077));
+
+ /* nBitsMax really means max+1 */
+ return (nBits < nBitsMax) ? nBits : (nBitsMax - 1);
+}
+
+static CARD32
+_XkbCountAtoms(Atom *atoms,int maxAtoms,int *count)
+{
+register unsigned int i,bit,nAtoms;
+register CARD32 atomsPresent;
+
+ for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) {
+ if (atoms[i]!=None) {
+ atomsPresent|= bit;
+ nAtoms++;
+ }
+ }
+ if (count)
+ *count= nAtoms;
+ return atomsPresent;
+}
+
+static void
+_XkbCopyAtoms(Display *dpy,Atom *atoms,CARD32 mask,int maxAtoms)
+{
+register unsigned int i,bit;
+
+ for (i=0,bit=1;i<maxAtoms;i++,bit<<=1) {
+ if (mask&bit)
+ Data32(dpy,&atoms[i],4);
+ }
+ return;
+}
+
+Bool
+XkbSetNames( Display * dpy,
+ unsigned int which,
+ unsigned int firstType,
+ unsigned int nTypes,
+ XkbDescPtr xkb)
+{
+ register xkbSetNamesReq *req;
+ int nLvlNames = 0;
+ XkbInfoPtr xkbi;
+ XkbNamesPtr names;
+ unsigned firstLvlType,nLvlTypes;
+ int nVMods,nLEDs,nRG,nKA,nGroups;
+ int nKeys=0,firstKey=0,nAtoms;
+ CARD32 leds,vmods,groups;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return False;
+ if ((!xkb)||(!xkb->names))
+ return False;
+ firstLvlType= firstType;
+ nLvlTypes= nTypes;
+ if (nTypes<1)
+ which&= ~(XkbKTLevelNamesMask|XkbKeyTypeNamesMask);
+ else if (firstType<=XkbLastRequiredType) {
+ int adjust;
+ adjust= XkbLastRequiredType-firstType+1;
+ firstType+= adjust;
+ nTypes-= adjust;
+ if (nTypes<1)
+ which&= ~XkbKeyTypeNamesMask;
+ }
+ names= xkb->names;
+ if (which&(XkbKTLevelNamesMask|XkbKeyTypeNamesMask)) {
+ register int i;
+ XkbKeyTypePtr type;
+ if((xkb->map==NULL)||(xkb->map->types==NULL)||(nTypes==0)||
+ (firstType+nTypes>xkb->map->num_types)||
+ (firstLvlType+nLvlTypes>xkb->map->num_types))
+ return False;
+ if (which&XkbKTLevelNamesMask) {
+ type= &xkb->map->types[firstLvlType];
+ for (i=nLvlNames=0;i<nLvlTypes;i++,type++) {
+ if (type->level_names!=NULL)
+ nLvlNames+= type->num_levels;
+ }
+ }
+ }
+
+ nVMods= nLEDs= nRG= nKA= nAtoms= nGroups= 0;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ GetReq(kbSetNames, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbSetNames;
+ req->deviceSpec = xkb->device_spec;
+ req->firstType = firstType;
+ req->nTypes = nTypes;
+ req->firstKey = xkb->min_key_code;
+ req->nKeys = xkb->max_key_code-xkb->min_key_code+1;
+
+ if (which&XkbKeycodesNameMask)
+ nAtoms++;
+ if (which&XkbGeometryNameMask)
+ nAtoms++;
+ if (which&XkbSymbolsNameMask)
+ nAtoms++;
+ if (which&XkbPhysSymbolsNameMask)
+ nAtoms++;
+ if (which&XkbTypesNameMask)
+ nAtoms++;
+ if (which&XkbCompatNameMask)
+ nAtoms++;
+ if (which&XkbKeyTypeNamesMask)
+ nAtoms+= nTypes;
+ if (which&XkbKTLevelNamesMask) {
+ req->firstKTLevel= firstLvlType;
+ req->nKTLevels= nLvlTypes;
+ req->length+= XkbPaddedSize(nLvlTypes)/4; /* room for group widths */
+ nAtoms+= nLvlNames;
+ }
+ else req->firstKTLevel= req->nKTLevels= 0;
+
+ if (which&XkbIndicatorNamesMask) {
+ req->indicators= leds=
+ _XkbCountAtoms(names->indicators,XkbNumIndicators,&nLEDs);
+ if (nLEDs>0)
+ nAtoms+= nLEDs;
+ else which&= ~XkbIndicatorNamesMask;
+ }
+ else req->indicators= leds= 0;
+
+ if (which&XkbVirtualModNamesMask) {
+ vmods= req->virtualMods= (CARD16)
+ _XkbCountAtoms(names->vmods,XkbNumVirtualMods,&nVMods);
+ if (nVMods>0)
+ nAtoms+= nVMods;
+ else which&= ~XkbVirtualModNamesMask;
+ }
+ else vmods= req->virtualMods= 0;
+
+ if (which&XkbGroupNamesMask) {
+ groups= req->groupNames= (CARD8)
+ _XkbCountAtoms(names->groups,XkbNumKbdGroups,&nGroups);
+ if (nGroups>0)
+ nAtoms+= nGroups;
+ else which&= ~XkbGroupNamesMask;
+ }
+ else groups= req->groupNames= 0;
+
+ if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) {
+ firstKey= req->firstKey;
+ nKeys= req->nKeys;
+ nAtoms+= nKeys; /* technically not atoms, but 4 bytes wide */
+ }
+ else which&= ~XkbKeyNamesMask;
+
+ if (which&XkbKeyAliasesMask) {
+ nKA= ((names->key_aliases!=NULL)?names->num_key_aliases:0);
+ if (nKA>0) {
+ req->nKeyAliases= nKA;
+ nAtoms+= nKA*2; /* not atoms, but 8 bytes on the wire */
+ }
+ else {
+ which&= ~XkbKeyAliasesMask;
+ req->nKeyAliases = 0;
+ }
+ }
+ else req->nKeyAliases= 0;
+
+ if (which&XkbRGNamesMask) {
+ nRG= names->num_rg;
+ if (nRG>0)
+ nAtoms+= nRG;
+ else which&= ~XkbRGNamesMask;
+ }
+
+ req->which= which;
+ req->nRadioGroups= nRG;
+ req->length+= (nAtoms*4)/4;
+
+ if (which&XkbKeycodesNameMask)
+ Data32(dpy,(long *)&names->keycodes,4);
+ if (which&XkbGeometryNameMask)
+ Data32(dpy,(long *)&names->geometry,4);
+ if (which&XkbSymbolsNameMask)
+ Data32(dpy,(long *)&names->symbols,4);
+ if (which&XkbPhysSymbolsNameMask)
+ Data32(dpy,(long *)&names->phys_symbols,4);
+ if (which&XkbTypesNameMask)
+ Data32(dpy,(long *)&names->types,4);
+ if (which&XkbCompatNameMask)
+ Data32(dpy,(long *)&names->compat,4);
+ if (which&XkbKeyTypeNamesMask) {
+ register int i;
+ register XkbKeyTypePtr type;
+ type= &xkb->map->types[firstType];
+ for (i=0;i<nTypes;i++,type++) {
+ Data32(dpy,(long *)&type->name,4);
+ }
+ }
+ if (which&XkbKTLevelNamesMask) {
+ XkbKeyTypePtr type;
+ int i;
+ char *tmp;
+
+ BufAlloc(char *,tmp,XkbPaddedSize(nLvlTypes));
+ type = &xkb->map->types[firstLvlType];
+ for (i=0;i<nLvlTypes;i++,type++) {
+ *tmp++ = type->num_levels;
+ }
+ type = &xkb->map->types[firstLvlType];
+ for (i=0;i<nLvlTypes;i++,type++) {
+ if (type->level_names!=NULL)
+ Data32(dpy,(long *)type->level_names,type->num_levels*4);
+ }
+ }
+ if (which&XkbIndicatorNamesMask)
+ _XkbCopyAtoms(dpy,names->indicators,leds,XkbNumIndicators);
+ if (which&XkbVirtualModNamesMask)
+ _XkbCopyAtoms(dpy,names->vmods,vmods,XkbNumVirtualMods);
+ if (which&XkbGroupNamesMask)
+ _XkbCopyAtoms(dpy,names->groups,groups,XkbNumKbdGroups);
+ if (which&XkbKeyNamesMask) {
+#ifdef WORD64
+ char *tmp;
+ register int i;
+ BufAlloc(char *,tmp,nKeys*XkbKeyNameLength);
+ for (i=0;i<nKeys;i++,tmp+= XkbKeyNameLength) {
+ tmp[0]= names->keys[firstKey+i].name[0];
+ tmp[1]= names->keys[firstKey+i].name[1];
+ tmp[2]= names->keys[firstKey+i].name[2];
+ tmp[3]= names->keys[firstKey+i].name[3];
+ }
+#else
+ Data(dpy,(char *)&names->keys[firstKey],nKeys*XkbKeyNameLength);
+#endif
+ }
+ if (which&XkbKeyAliasesMask) {
+#ifdef WORD64
+ char *tmp;
+ register int i;
+ BufAlloc(char *,tmp,nKA*XkbKeyNameLength*2);
+ for (i=0;i<nKeys;i++,tmp+= 2*XkbKeyNameLength) {
+ tmp[0]= names->key_aliases[i].real[0];
+ tmp[1]= names->key_aliases[i].real[1];
+ tmp[2]= names->key_aliases[i].real[2];
+ tmp[3]= names->key_aliases[i].real[3];
+ tmp[4]= names->key_aliases[i].alias[0];
+ tmp[5]= names->key_aliases[i].alias[1];
+ tmp[6]= names->key_aliases[i].alias[2];
+ tmp[7]= names->key_aliases[i].alias[3];
+ }
+#else
+ Data(dpy,(char *)names->key_aliases,nKA*XkbKeyNameLength*2);
+#endif
+ }
+ if (which&XkbRGNamesMask) {
+ Data32(dpy,(long *)names->radio_groups,nRG*4);
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+XkbChangeNames(Display *dpy,XkbDescPtr xkb,XkbNameChangesPtr changes)
+{
+ register xkbSetNamesReq *req;
+ int nLvlNames = 0;
+ XkbInfoPtr xkbi;
+ XkbNamesPtr names;
+ unsigned which,firstType,nTypes;
+ unsigned firstLvlType,nLvlTypes;
+ int nVMods,nLEDs,nRG,nKA,nGroups;
+ int nKeys=0,firstKey=0,nAtoms;
+ CARD32 leds=0,vmods=0,groups=0;
+
+ if ((dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return False;
+ if ((!xkb)||(!xkb->names)||(!changes))
+ return False;
+ which= changes->changed;
+ firstType= changes->first_type;
+ nTypes= changes->num_types;
+ firstLvlType= changes->first_lvl;;
+ nLvlTypes= changes->num_lvls;
+ if (which&XkbKeyTypeNamesMask) {
+ if (nTypes<1)
+ which&= ~XkbKeyTypeNamesMask;
+ else if (firstType<=XkbLastRequiredType) {
+ int adjust;
+ adjust= XkbLastRequiredType-firstType+1;
+ firstType+= adjust;
+ nTypes-= adjust;
+ if (nTypes<1)
+ which&= ~XkbKeyTypeNamesMask;
+ }
+ }
+ else firstType= nTypes= 0;
+
+ if (which&XkbKTLevelNamesMask) {
+ if (nLvlTypes<1)
+ which&= ~XkbKTLevelNamesMask;
+ }
+ else firstLvlType= nLvlTypes= 0;
+
+ names= xkb->names;
+ if (which&(XkbKTLevelNamesMask|XkbKeyTypeNamesMask)) {
+ register int i;
+ XkbKeyTypePtr type;
+ if((xkb->map==NULL)||(xkb->map->types==NULL)||(nTypes==0)||
+ (firstType+nTypes>xkb->map->num_types)||
+ (firstLvlType+nLvlTypes>xkb->map->num_types))
+ return False;
+ if (which&XkbKTLevelNamesMask) {
+ type= &xkb->map->types[firstLvlType];
+ for (i=nLvlNames=0;i<nLvlTypes;i++,type++) {
+ if (type->level_names!=NULL)
+ nLvlNames+= type->num_levels;
+ }
+ }
+ }
+
+ if (changes->num_keys<1)
+ which&= ~XkbKeyNamesMask;
+ if ((which&XkbKeyNamesMask)==0)
+ changes->first_key= changes->num_keys= 0;
+ else if ((changes->first_key<xkb->min_key_code)||
+ (changes->first_key+changes->num_keys>xkb->max_key_code)) {
+ return False;
+ }
+
+ if ((which&XkbVirtualModNamesMask)==0)
+ changes->changed_vmods= 0;
+ else if (changes->changed_vmods==0)
+ which&= ~XkbVirtualModNamesMask;
+
+ if ((which&XkbIndicatorNamesMask)==0)
+ changes->changed_indicators= 0;
+ else if (changes->changed_indicators==0)
+ which&= ~XkbIndicatorNamesMask;
+
+ if ((which&XkbGroupNamesMask)==0)
+ changes->changed_groups= 0;
+ else if (changes->changed_groups==0)
+ which&= ~XkbGroupNamesMask;
+
+ nVMods= nLEDs= nRG= nKA= nAtoms= nGroups= 0;
+ LockDisplay(dpy);
+ xkbi = dpy->xkb_info;
+ GetReq(kbSetNames, req);
+ req->reqType = xkbi->codes->major_opcode;
+ req->xkbReqType = X_kbSetNames;
+ req->deviceSpec = xkb->device_spec;
+ req->firstType = firstType;
+ req->nTypes = nTypes;
+ req->firstKey = changes->first_key;
+ req->nKeys = changes->num_keys;
+
+ if (which&XkbKeycodesNameMask)
+ nAtoms++;
+ if (which&XkbGeometryNameMask)
+ nAtoms++;
+ if (which&XkbSymbolsNameMask)
+ nAtoms++;
+ if (which&XkbPhysSymbolsNameMask)
+ nAtoms++;
+ if (which&XkbTypesNameMask)
+ nAtoms++;
+ if (which&XkbCompatNameMask)
+ nAtoms++;
+ if (which&XkbKeyTypeNamesMask)
+ nAtoms+= nTypes;
+ if (which&XkbKTLevelNamesMask) {
+ req->firstKTLevel= firstLvlType;
+ req->nKTLevels= nLvlTypes;
+ req->length+= XkbPaddedSize(nLvlTypes)/4; /* room for group widths */
+ nAtoms+= nLvlNames;
+ }
+ else req->firstKTLevel= req->nKTLevels= 0;
+
+ if (which&XkbIndicatorNamesMask) {
+ leds= req->indicators= (CARD32)changes->changed_indicators;
+ nLEDs= _XkbCountBits(XkbNumIndicators,changes->changed_indicators);
+ if (nLEDs>0)
+ nAtoms+= nLEDs;
+ else which&= ~XkbIndicatorNamesMask;
+ }
+ else req->indicators= 0;
+
+ if (which&XkbVirtualModNamesMask) {
+ vmods= req->virtualMods= changes->changed_vmods;
+ nVMods= _XkbCountBits(XkbNumVirtualMods,
+ (unsigned long)changes->changed_vmods);
+ if (nVMods>0)
+ nAtoms+= nVMods;
+ else which&= ~XkbVirtualModNamesMask;
+ }
+ else req->virtualMods= 0;
+
+ if (which&XkbGroupNamesMask) {
+ groups= req->groupNames= changes->changed_groups;
+ nGroups= _XkbCountBits(XkbNumKbdGroups,
+ (unsigned long)changes->changed_groups);
+ if (nGroups>0)
+ nAtoms+= nGroups;
+ else which&= ~XkbGroupNamesMask;
+ }
+ else req->groupNames= 0;
+
+ if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) {
+ firstKey= req->firstKey;
+ nKeys= req->nKeys;
+ nAtoms+= nKeys; /* technically not atoms, but 4 bytes wide */
+ }
+ else which&= ~XkbKeyNamesMask;
+
+ if (which&XkbKeyAliasesMask) {
+ nKA= ((names->key_aliases!=NULL)?names->num_key_aliases:0);
+ if (nKA>0)
+ nAtoms+= nKA*2; /* not atoms, but 8 bytes on the wire */
+ else which&= ~XkbKeyAliasesMask;
+ }
+
+ if (which&XkbRGNamesMask) {
+ nRG= names->num_rg;
+ if (nRG>0)
+ nAtoms+= nRG;
+ else which&= ~XkbRGNamesMask;
+ }
+
+ req->which= which;
+ req->nRadioGroups= nRG;
+ req->length+= (nAtoms*4)/4;
+
+ if (which&XkbKeycodesNameMask)
+ Data32(dpy,(long *)&names->keycodes,4);
+ if (which&XkbGeometryNameMask)
+ Data32(dpy,(long *)&names->geometry,4);
+ if (which&XkbSymbolsNameMask)
+ Data32(dpy,(long *)&names->symbols,4);
+ if (which&XkbPhysSymbolsNameMask)
+ Data32(dpy,(long *)&names->phys_symbols,4);
+ if (which&XkbTypesNameMask)
+ Data32(dpy,(long *)&names->types,4);
+ if (which&XkbCompatNameMask)
+ Data32(dpy,(long *)&names->compat,4);
+ if (which&XkbKeyTypeNamesMask) {
+ register int i;
+ register XkbKeyTypePtr type;
+ type= &xkb->map->types[firstType];
+ for (i=0;i<nTypes;i++,type++) {
+ Data32(dpy,(long *)&type->name,4);
+ }
+ }
+ if (which&XkbKTLevelNamesMask) {
+ XkbKeyTypePtr type;
+ int i;
+ char *tmp;
+
+ BufAlloc(char *,tmp,XkbPaddedSize(nLvlTypes));
+ type = &xkb->map->types[firstLvlType];
+ for (i=0;i<nLvlTypes;i++,type++) {
+ *tmp++ = type->num_levels;
+ }
+ type = &xkb->map->types[firstLvlType];
+ for (i=0;i<nLvlTypes;i++,type++) {
+ if (type->level_names!=NULL)
+ Data32(dpy,(long *)type->level_names,type->num_levels*4);
+ }
+ }
+ if (which&XkbIndicatorNamesMask)
+ _XkbCopyAtoms(dpy,names->indicators,leds,XkbNumIndicators);
+ if (which&XkbVirtualModNamesMask)
+ _XkbCopyAtoms(dpy,names->vmods,vmods,XkbNumVirtualMods);
+ if (which&XkbGroupNamesMask)
+ _XkbCopyAtoms(dpy,names->groups,groups,XkbNumKbdGroups);
+ if (which&XkbKeyNamesMask) {
+#ifdef WORD64
+ char *tmp;
+ register int i;
+ BufAlloc(char *,tmp,nKeys*4);
+ for (i=0;i<nKeys;i++,tmp+= 4) {
+ tmp[0]= names->keys[firstKey+i].name[0];
+ tmp[1]= names->keys[firstKey+i].name[1];
+ tmp[2]= names->keys[firstKey+i].name[2];
+ tmp[3]= names->keys[firstKey+i].name[3];
+ }
+#else
+ Data(dpy,(char *)&names->keys[firstKey],nKeys*XkbKeyNameLength);
+#endif
+ }
+ if (which&XkbKeyAliasesMask) {
+#ifdef WORD64
+ char *tmp;
+ register int i;
+ BufAlloc(char *,tmp,nKA*XkbKeyNameLength*2);
+ for (i=0;i<nKeys;i++,tmp+= 2*XkbKeyNameLength) {
+ tmp[0]= names->key_aliases[i].real[0];
+ tmp[1]= names->key_aliases[i].real[1];
+ tmp[2]= names->key_aliases[i].real[2];
+ tmp[3]= names->key_aliases[i].real[3];
+ tmp[4]= names->key_aliases[i].alias[0];
+ tmp[5]= names->key_aliases[i].alias[1];
+ tmp[6]= names->key_aliases[i].alias[2];
+ tmp[7]= names->key_aliases[i].alias[3];
+ }
+#else
+ Data(dpy,(char *)names->key_aliases,nKA*XkbKeyNameLength*2);
+#endif
+ }
+ if (which&XkbRGNamesMask) {
+ Data32(dpy,(long *)names->radio_groups,nRG*4);
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+void
+XkbNoteNameChanges( XkbNameChangesPtr old,
+ XkbNamesNotifyEvent * new,
+ unsigned int wanted)
+{
+int first,last,old_last,new_last;
+
+ wanted&= new->changed;
+ if ((old==NULL)||(new==NULL)||(wanted==0))
+ return;
+ if (wanted&XkbKeyTypeNamesMask) {
+ if (old->changed&XkbKeyTypeNamesMask) {
+ new_last= (new->first_type+new->num_types-1);
+ old_last= (old->first_type+old->num_types-1);
+
+ if (new->first_type<old->first_type)
+ first= new->first_type;
+ else first= old->first_type;
+
+ if (old_last>new_last)
+ last= old_last;
+ else last= new_last;
+
+ old->first_type= first;
+ old->num_types= (last-first)+1;
+ }
+ else {
+ old->first_type= new->first_type;
+ old->num_types= new->num_types;
+ }
+ }
+ if (wanted&XkbKTLevelNamesMask) {
+ if (old->changed&XkbKTLevelNamesMask) {
+ new_last= (new->first_lvl+new->num_lvls-1);
+ old_last= (old->first_lvl+old->num_lvls-1);
+
+ if (new->first_lvl<old->first_lvl)
+ first= new->first_lvl;
+ else first= old->first_lvl;
+
+ if (old_last>new_last)
+ last= old_last;
+ else last= new_last;
+
+ old->first_lvl= first;
+ old->num_lvls= (last-first)+1;
+ }
+ else {
+ old->first_lvl= new->first_lvl;
+ old->num_lvls= new->num_lvls;
+ }
+ }
+ if (wanted&XkbIndicatorNamesMask) {
+ if (old->changed&XkbIndicatorNamesMask)
+ old->changed_indicators|= new->changed_indicators;
+ else old->changed_indicators= new->changed_indicators;
+ }
+ if (wanted&XkbKeyNamesMask) {
+ if (old->changed&XkbKeyNamesMask) {
+ new_last= (new->first_key+new->num_keys-1);
+ old_last= (old->first_key+old->num_keys-1);
+
+ first= old->first_key;
+
+ if (new->first_key<old->first_key)
+ first= new->first_key;
+ if (old_last>new_last)
+ new_last= old_last;
+
+ old->first_key= first;
+ old->num_keys= (new_last-first)+1;
+ }
+ else {
+ old->first_key= new->first_key;
+ old->num_keys= new->num_keys;
+ }
+ }
+ if (wanted&XkbVirtualModNamesMask) {
+ if (old->changed&XkbVirtualModNamesMask)
+ old->changed_vmods|= new->changed_vmods;
+ else old->changed_vmods= new->changed_vmods;
+ }
+ if (wanted&XkbGroupNamesMask) {
+ if (old->changed&XkbGroupNamesMask)
+ old->changed_groups|= new->changed_groups;
+ else old->changed_groups= new->changed_groups;
+ }
+ if (wanted&XkbRGNamesMask)
+ old->num_rg= new->num_radio_groups;
+ if (wanted&XkbKeyAliasesMask)
+ old->num_aliases= new->num_aliases;
+ old->changed|= wanted;
+ return;
+}