XKBNames.c revision 61b2299d
11ab64890Smrg/* $Xorg: XKBNames.c,v 1.3 2000/08/17 19:45:02 cpqbld Exp $ */
21ab64890Smrg/************************************************************
31ab64890SmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
41ab64890Smrg
51ab64890SmrgPermission to use, copy, modify, and distribute this
61ab64890Smrgsoftware and its documentation for any purpose and without
71ab64890Smrgfee is hereby granted, provided that the above copyright
81ab64890Smrgnotice appear in all copies and that both that copyright
91ab64890Smrgnotice and this permission notice appear in supporting
1061b2299dSmrgdocumentation, and that the name of Silicon Graphics not be
1161b2299dSmrgused in advertising or publicity pertaining to distribution
121ab64890Smrgof the software without specific prior written permission.
1361b2299dSmrgSilicon Graphics makes no representation about the suitability
141ab64890Smrgof this software for any purpose. It is provided "as is"
151ab64890Smrgwithout any express or implied warranty.
161ab64890Smrg
1761b2299dSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
1861b2299dSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
191ab64890SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
2061b2299dSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
2161b2299dSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
2261b2299dSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
231ab64890SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
241ab64890SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE.
251ab64890Smrg
261ab64890Smrg********************************************************/
271ab64890Smrg/* $XFree86: xc/lib/X11/XKBNames.c,v 1.5 2003/04/13 19:22:18 dawes Exp $ */
281ab64890Smrg
291ab64890Smrg#define NEED_REPLIES
301ab64890Smrg#define NEED_EVENTS
311ab64890Smrg#define NEED_MAP_READERS
321ab64890Smrg#ifdef HAVE_CONFIG_H
331ab64890Smrg#include <config.h>
341ab64890Smrg#endif
351ab64890Smrg#include "Xlibint.h"
361ab64890Smrg#include <X11/extensions/XKBproto.h>
371ab64890Smrg#include "XKBlibint.h"
381ab64890Smrg
391ab64890Smrg
401ab64890Smrgstatic Status
411ab64890Smrg_XkbReadAtoms(	XkbReadBufferPtr	buf,
421ab64890Smrg		Atom *			atoms,
431ab64890Smrg		int			maxAtoms,
441ab64890Smrg		CARD32		 	present)
451ab64890Smrg{
461ab64890Smrgregister int i,bit;
471ab64890Smrg
481ab64890Smrg    for (i=0,bit=1;(i<maxAtoms)&&(present);i++,bit<<=1) {
491ab64890Smrg	if (present&bit) {
501ab64890Smrg	    if (!_XkbReadBufferCopy32(buf,(long *)&atoms[i],1))
511ab64890Smrg		return BadLength;
521ab64890Smrg	    present&= ~bit;
531ab64890Smrg	}
541ab64890Smrg    }
551ab64890Smrg    return Success;
561ab64890Smrg}
571ab64890Smrg
581ab64890SmrgStatus
591ab64890Smrg_XkbReadGetNamesReply(	Display *		dpy,
601ab64890Smrg			xkbGetNamesReply *	rep,
611ab64890Smrg			XkbDescPtr 		xkb,
621ab64890Smrg			int *			nread_rtrn)
631ab64890Smrg{
641ab64890Smrg    int				 i,len;
651ab64890Smrg    XkbReadBufferRec		 buf;
661ab64890Smrg    register XkbNamesPtr	 names;
671ab64890Smrg
681ab64890Smrg    if ( xkb->device_spec == XkbUseCoreKbd )
691ab64890Smrg	xkb->device_spec = rep->deviceID;
701ab64890Smrg
711ab64890Smrg    if ((xkb->names==NULL)&&
721ab64890Smrg	(XkbAllocNames(xkb,rep->which,
731ab64890Smrg				rep->nRadioGroups,rep->nKeyAliases)!=Success)) {
741ab64890Smrg	return BadAlloc;
751ab64890Smrg    }
761ab64890Smrg    names= xkb->names;
771ab64890Smrg    if (rep->length==0)
781ab64890Smrg	return Success;
791ab64890Smrg
801ab64890Smrg    if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4))
811ab64890Smrg	return BadAlloc;
821ab64890Smrg    if (nread_rtrn)
831ab64890Smrg	*nread_rtrn= (int)rep->length*4;
841ab64890Smrg
851ab64890Smrg    if ((rep->which&XkbKeycodesNameMask)&&
861ab64890Smrg	(!_XkbReadBufferCopy32(&buf,(long *)&names->keycodes,1)))
871ab64890Smrg	    goto BAILOUT;
881ab64890Smrg    if ((rep->which&XkbGeometryNameMask)&&
891ab64890Smrg	(!_XkbReadBufferCopy32(&buf,(long *)&names->geometry,1)))
901ab64890Smrg	    goto BAILOUT;
911ab64890Smrg    if ((rep->which&XkbSymbolsNameMask)&&
921ab64890Smrg	(!_XkbReadBufferCopy32(&buf,(long *)&names->symbols,1)))
931ab64890Smrg	    goto BAILOUT;
941ab64890Smrg    if ((rep->which&XkbPhysSymbolsNameMask)&&
951ab64890Smrg	(!_XkbReadBufferCopy32(&buf,(long *)&names->phys_symbols,1)))
961ab64890Smrg	    goto BAILOUT;
971ab64890Smrg    if ((rep->which&XkbTypesNameMask)&&
981ab64890Smrg	(!_XkbReadBufferCopy32(&buf,(long *)&names->types,1)))
991ab64890Smrg	    goto BAILOUT;
1001ab64890Smrg    if ((rep->which&XkbCompatNameMask)&&
1011ab64890Smrg	(!_XkbReadBufferCopy32(&buf,(long *)&names->compat,1)))
1021ab64890Smrg	    goto BAILOUT;
1031ab64890Smrg
1041ab64890Smrg    if ( rep->which & XkbKeyTypeNamesMask ) {
1051ab64890Smrg	XkbClientMapPtr	map= xkb->map;
1061ab64890Smrg	XkbKeyTypePtr	type;
1071ab64890Smrg
1081ab64890Smrg	len= rep->nTypes*4;
1091ab64890Smrg	if (map!=NULL) {
1101ab64890Smrg	    type= map->types;
1111ab64890Smrg	    for (i=0;(i<map->num_types)&&(i<rep->nTypes);i++,type++) {
1121ab64890Smrg		if (!_XkbReadBufferCopy32(&buf,(long *)&type->name,1))
1131ab64890Smrg		    goto BAILOUT;
1141ab64890Smrg		len-= 4;
1151ab64890Smrg	    }
1161ab64890Smrg	}
1171ab64890Smrg	if ((len>0)&&(!_XkbSkipReadBufferData(&buf,len)))
1181ab64890Smrg	    goto BAILOUT;
1191ab64890Smrg    }
1201ab64890Smrg    if ( rep->which&XkbKTLevelNamesMask ) {
1211ab64890Smrg	CARD8 *nLevels;
1221ab64890Smrg	XkbClientMapPtr	map= xkb->map;
1231ab64890Smrg	XkbKeyTypePtr	type;
1241ab64890Smrg
1251ab64890Smrg	nLevels=(CARD8*)_XkbGetReadBufferPtr(&buf,XkbPaddedSize(rep->nTypes));
1261ab64890Smrg	if (nLevels==NULL)
1271ab64890Smrg	    goto BAILOUT;
1281ab64890Smrg	if (map!=NULL) {
1291ab64890Smrg	    type= map->types;
1301ab64890Smrg	    for (i=0;i<(int)rep->nTypes;i++,type++) {
1311ab64890Smrg		if (i>=map->num_types) {
1321ab64890Smrg		    if (!_XkbSkipReadBufferData(&buf,nLevels[i]*4))
1331ab64890Smrg			goto BAILOUT;
1341ab64890Smrg		    continue;
1351ab64890Smrg		}
1361ab64890Smrg		if ((nLevels[i]>0)&&(nLevels[i]!=type->num_levels)) {
1371ab64890Smrg		    goto BAILOUT;
1381ab64890Smrg		}
1391ab64890Smrg		if (type->level_names!=NULL)
1401ab64890Smrg		    Xfree(type->level_names);
1411ab64890Smrg		if (nLevels[i]==0) {
1421ab64890Smrg		    type->level_names= NULL;
1431ab64890Smrg		    continue;
1441ab64890Smrg		}
1451ab64890Smrg		type->level_names= _XkbTypedCalloc(nLevels[i],Atom);
1461ab64890Smrg		if (type->level_names!=NULL) {
1471ab64890Smrg		    if (!_XkbReadBufferCopy32(&buf,(long *)type->level_names,
1481ab64890Smrg								nLevels[i]))
1491ab64890Smrg			goto BAILOUT;
1501ab64890Smrg		}
1511ab64890Smrg		else {
1521ab64890Smrg		    _XkbSkipReadBufferData(&buf,nLevels[i]*4);
1531ab64890Smrg		}
1541ab64890Smrg	    }
1551ab64890Smrg	}
1561ab64890Smrg	else {
1571ab64890Smrg	    for (i=0;i<(int)rep->nTypes;i++) {
1581ab64890Smrg		_XkbSkipReadBufferData(&buf,nLevels[i]*4);
1591ab64890Smrg	    }
1601ab64890Smrg	}
1611ab64890Smrg    }
1621ab64890Smrg    if (rep->which & XkbIndicatorNamesMask) {
1631ab64890Smrg	if (_XkbReadAtoms(&buf,names->indicators,XkbNumIndicators,
1641ab64890Smrg						rep->indicators)!=Success)
1651ab64890Smrg	    goto BAILOUT;
1661ab64890Smrg    }
1671ab64890Smrg    if ( rep->which&XkbVirtualModNamesMask ) {
1681ab64890Smrg	if (_XkbReadAtoms(&buf,names->vmods,XkbNumVirtualMods,
1691ab64890Smrg					(CARD32)rep->virtualMods)!=Success)
1701ab64890Smrg	    goto BAILOUT;
1711ab64890Smrg    }
1721ab64890Smrg    if ( rep->which&XkbGroupNamesMask ) {
1731ab64890Smrg	if (_XkbReadAtoms(&buf,names->groups,XkbNumKbdGroups,
1741ab64890Smrg					(CARD32)rep->groupNames)!=Success)
1751ab64890Smrg	    goto BAILOUT;
1761ab64890Smrg    }
1771ab64890Smrg    if ( rep->which&XkbKeyNamesMask ) {
1781ab64890Smrg	if (names->keys==NULL) {
1791ab64890Smrg	    int nKeys;
1801ab64890Smrg	    if (xkb->max_key_code==0) {
1811ab64890Smrg		xkb->min_key_code= rep->minKeyCode;
1821ab64890Smrg		xkb->max_key_code= rep->maxKeyCode;
1831ab64890Smrg	    }
1841ab64890Smrg	    nKeys= xkb->max_key_code+1;
1851ab64890Smrg	    names->keys= _XkbTypedCalloc(nKeys,XkbKeyNameRec);
1861ab64890Smrg	}
1871ab64890Smrg	if (names->keys!=NULL) {
1881ab64890Smrg	    if (!_XkbCopyFromReadBuffer(&buf,
1891ab64890Smrg					(char *)&names->keys[rep->firstKey],
1901ab64890Smrg					rep->nKeys*XkbKeyNameLength))
1911ab64890Smrg		goto BAILOUT;
1921ab64890Smrg	}
1931ab64890Smrg	else _XkbSkipReadBufferData(&buf,rep->nKeys*XkbKeyNameLength);
1941ab64890Smrg    }
1951ab64890Smrg    if ( rep->which&XkbKeyAliasesMask && (rep->nKeyAliases>0) ) {
1961ab64890Smrg	if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,rep->nKeyAliases)!=Success)
1971ab64890Smrg	    goto BAILOUT;
1981ab64890Smrg	if (!_XkbCopyFromReadBuffer(&buf,(char *)names->key_aliases,
1991ab64890Smrg				rep->nKeyAliases*XkbKeyNameLength*2))
2001ab64890Smrg	    goto BAILOUT;
2011ab64890Smrg    }
2021ab64890Smrg    if ( rep->which&XkbRGNamesMask ) {
2031ab64890Smrg	if (rep->nRadioGroups>0) {
2041ab64890Smrg	    Atom *rgNames;
2051ab64890Smrg
2061ab64890Smrg	    if (names->radio_groups==NULL)
2071ab64890Smrg		names->radio_groups = _XkbTypedCalloc(rep->nRadioGroups,Atom);
2081ab64890Smrg	    else if (names->num_rg<rep->nRadioGroups) {
2091ab64890Smrg		names->radio_groups = _XkbTypedRealloc(names->radio_groups,
2101ab64890Smrg							rep->nRadioGroups,
2111ab64890Smrg							Atom);
2121ab64890Smrg	    }
2131ab64890Smrg	    rgNames= names->radio_groups;
2141ab64890Smrg	    if (!rgNames) {
2151ab64890Smrg		goto BAILOUT;
2161ab64890Smrg	    }
2171ab64890Smrg	    if (!_XkbReadBufferCopy32(&buf,(long *)rgNames,rep->nRadioGroups))
2181ab64890Smrg		goto BAILOUT;
2191ab64890Smrg	    names->num_rg= rep->nRadioGroups;
2201ab64890Smrg	}
2211ab64890Smrg	else if (names->num_rg>0) {
2221ab64890Smrg	    names->num_rg= 0;
2231ab64890Smrg	    Xfree(names->radio_groups);
2241ab64890Smrg	}
2251ab64890Smrg    }
2261ab64890Smrg    len= _XkbFreeReadBuffer(&buf);
2271ab64890Smrg    if (len!=0) 	return BadLength;
2281ab64890Smrg    else		return Success;
2291ab64890SmrgBAILOUT:
2301ab64890Smrg    _XkbFreeReadBuffer(&buf);
2311ab64890Smrg    return BadLength;
2321ab64890Smrg}
2331ab64890Smrg
2341ab64890SmrgStatus
2351ab64890SmrgXkbGetNames(Display *dpy,unsigned which,XkbDescPtr xkb)
2361ab64890Smrg{
2371ab64890Smrg    register xkbGetNamesReq *req;
2381ab64890Smrg    xkbGetNamesReply	     rep;
2391ab64890Smrg    Status		     status;
2401ab64890Smrg    XkbInfoPtr xkbi;
2411ab64890Smrg
2421ab64890Smrg    if ((dpy->flags & XlibDisplayNoXkb) ||
2431ab64890Smrg	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
2441ab64890Smrg	return BadAccess;
2451ab64890Smrg    LockDisplay(dpy);
2461ab64890Smrg    xkbi = dpy->xkb_info;
2471ab64890Smrg    if (!xkb->names) {
2481ab64890Smrg	xkb->names = _XkbTypedCalloc(1,XkbNamesRec);
2491ab64890Smrg	if (!xkb->names) {
2501ab64890Smrg	    UnlockDisplay(dpy);
2511ab64890Smrg	    SyncHandle();
2521ab64890Smrg	    return BadAlloc;
2531ab64890Smrg	}
2541ab64890Smrg    }
2551ab64890Smrg    GetReq(kbGetNames, req);
2561ab64890Smrg    req->reqType = xkbi->codes->major_opcode;
2571ab64890Smrg    req->xkbReqType = X_kbGetNames;
2581ab64890Smrg    req->deviceSpec = xkb->device_spec;
2591ab64890Smrg    req->which = which;
2601ab64890Smrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
2611ab64890Smrg	UnlockDisplay(dpy);
2621ab64890Smrg	SyncHandle();
2631ab64890Smrg	return BadImplementation;
2641ab64890Smrg    }
2651ab64890Smrg
2661ab64890Smrg    status = _XkbReadGetNamesReply(dpy,&rep,xkb,NULL);
2671ab64890Smrg    UnlockDisplay(dpy);
2681ab64890Smrg    SyncHandle();
2691ab64890Smrg    return status;
2701ab64890Smrg}
2711ab64890Smrg
2721ab64890Smrg/***====================================================================***/
2731ab64890Smrg
2741ab64890Smrgstatic int
2751ab64890Smrg_XkbCountBits(int nBitsMax,unsigned long mask)
2761ab64890Smrg{
2771ab64890Smrgregister unsigned long y, nBits;
2781ab64890Smrg
2791ab64890Smrg    y = (mask >> 1) &033333333333;
2801ab64890Smrg    y = mask - y - ((y >>1) & 033333333333);
2811ab64890Smrg    nBits = ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077));
2821ab64890Smrg
2831ab64890Smrg    /* nBitsMax really means max+1 */
2841ab64890Smrg    return (nBits < nBitsMax) ? nBits : (nBitsMax - 1);
2851ab64890Smrg}
2861ab64890Smrg
2871ab64890Smrgstatic CARD32
2881ab64890Smrg_XkbCountAtoms(Atom *atoms,int maxAtoms,int *count)
2891ab64890Smrg{
2901ab64890Smrgregister unsigned int i,bit,nAtoms;
2911ab64890Smrgregister CARD32 atomsPresent;
2921ab64890Smrg
2931ab64890Smrg    for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) {
2941ab64890Smrg        if (atoms[i]!=None) {
2951ab64890Smrg            atomsPresent|= bit;
2961ab64890Smrg            nAtoms++;
2971ab64890Smrg        }
2981ab64890Smrg    }
2991ab64890Smrg    if (count)
3001ab64890Smrg        *count= nAtoms;
3011ab64890Smrg    return atomsPresent;
3021ab64890Smrg}
3031ab64890Smrg
3041ab64890Smrgstatic void
3051ab64890Smrg_XkbCopyAtoms(Display *dpy,Atom *atoms,CARD32 mask,int maxAtoms)
3061ab64890Smrg{
3071ab64890Smrgregister unsigned int i,bit;
3081ab64890Smrg
3091ab64890Smrg    for (i=0,bit=1;i<maxAtoms;i++,bit<<=1) {
3101ab64890Smrg        if (mask&bit)
3111ab64890Smrg	    Data32(dpy,&atoms[i],4);
3121ab64890Smrg    }
3131ab64890Smrg    return;
3141ab64890Smrg}
3151ab64890Smrg
3161ab64890SmrgBool
3171ab64890SmrgXkbSetNames(	Display *	dpy,
3181ab64890Smrg		unsigned int 	which,
3191ab64890Smrg		unsigned int 	firstType,
3201ab64890Smrg		unsigned int 	nTypes,
3211ab64890Smrg		XkbDescPtr 	xkb)
3221ab64890Smrg{
3231ab64890Smrg    register xkbSetNamesReq *req;
3241ab64890Smrg    int  nLvlNames = 0;
3251ab64890Smrg    XkbInfoPtr xkbi;
3261ab64890Smrg    XkbNamesPtr names;
3271ab64890Smrg    unsigned firstLvlType,nLvlTypes;
3281ab64890Smrg    int	nVMods,nLEDs,nRG,nKA,nGroups;
3291ab64890Smrg    int nKeys=0,firstKey=0,nAtoms;
3301ab64890Smrg    CARD32 leds,vmods,groups;
3311ab64890Smrg
3321ab64890Smrg    if ((dpy->flags & XlibDisplayNoXkb) ||
3331ab64890Smrg	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
3341ab64890Smrg	return False;
3351ab64890Smrg    if ((!xkb)||(!xkb->names))
3361ab64890Smrg	return False;
3371ab64890Smrg    firstLvlType= firstType;
3381ab64890Smrg    nLvlTypes= nTypes;
3391ab64890Smrg    if (nTypes<1)
3401ab64890Smrg	which&= ~(XkbKTLevelNamesMask|XkbKeyTypeNamesMask);
3411ab64890Smrg    else if (firstType<=XkbLastRequiredType) {
3421ab64890Smrg	int	adjust;
3431ab64890Smrg	adjust= XkbLastRequiredType-firstType+1;
3441ab64890Smrg	firstType+= adjust;
3451ab64890Smrg	nTypes-= adjust;
3461ab64890Smrg	if (nTypes<1)
3471ab64890Smrg	    which&= ~XkbKeyTypeNamesMask;
3481ab64890Smrg    }
3491ab64890Smrg    names= xkb->names;
3501ab64890Smrg    if (which&(XkbKTLevelNamesMask|XkbKeyTypeNamesMask)) {
3511ab64890Smrg	register int	i;
3521ab64890Smrg	XkbKeyTypePtr	type;
3531ab64890Smrg	if((xkb->map==NULL)||(xkb->map->types==NULL)||(nTypes==0)||
3541ab64890Smrg				(firstType+nTypes>xkb->map->num_types)||
3551ab64890Smrg				(firstLvlType+nLvlTypes>xkb->map->num_types))
3561ab64890Smrg	    return False;
3571ab64890Smrg	if (which&XkbKTLevelNamesMask) {
3581ab64890Smrg	    type= &xkb->map->types[firstLvlType];
3591ab64890Smrg	    for (i=nLvlNames=0;i<nLvlTypes;i++,type++) {
3601ab64890Smrg		if (type->level_names!=NULL)
3611ab64890Smrg		    nLvlNames+= type->num_levels;
3621ab64890Smrg	    }
3631ab64890Smrg	}
3641ab64890Smrg    }
36561b2299dSmrg
3661ab64890Smrg    nVMods= nLEDs= nRG= nKA= nAtoms= nGroups= 0;
3671ab64890Smrg    LockDisplay(dpy);
3681ab64890Smrg    xkbi = dpy->xkb_info;
3691ab64890Smrg    GetReq(kbSetNames, req);
3701ab64890Smrg    req->reqType = xkbi->codes->major_opcode;
3711ab64890Smrg    req->xkbReqType = X_kbSetNames;
3721ab64890Smrg    req->deviceSpec = xkb->device_spec;
3731ab64890Smrg    req->firstType = firstType;
3741ab64890Smrg    req->nTypes = nTypes;
3751ab64890Smrg    req->firstKey = xkb->min_key_code;
3761ab64890Smrg    req->nKeys = xkb->max_key_code-xkb->min_key_code+1;
3771ab64890Smrg
3781ab64890Smrg    if (which&XkbKeycodesNameMask)
3791ab64890Smrg	nAtoms++;
3801ab64890Smrg    if (which&XkbGeometryNameMask)
3811ab64890Smrg	nAtoms++;
3821ab64890Smrg    if (which&XkbSymbolsNameMask)
3831ab64890Smrg	nAtoms++;
3841ab64890Smrg    if (which&XkbPhysSymbolsNameMask)
3851ab64890Smrg	nAtoms++;
3861ab64890Smrg    if (which&XkbTypesNameMask)
3871ab64890Smrg	nAtoms++;
3881ab64890Smrg    if (which&XkbCompatNameMask)
3891ab64890Smrg	nAtoms++;
3901ab64890Smrg    if (which&XkbKeyTypeNamesMask)
3911ab64890Smrg	nAtoms+= nTypes;
3921ab64890Smrg    if (which&XkbKTLevelNamesMask) {
3931ab64890Smrg	req->firstKTLevel= firstLvlType;
3941ab64890Smrg	req->nKTLevels= nLvlTypes;
3951ab64890Smrg	req->length+= XkbPaddedSize(nLvlTypes)/4; /* room for group widths */
3961ab64890Smrg	nAtoms+= nLvlNames;
3971ab64890Smrg    }
3981ab64890Smrg    else req->firstKTLevel= req->nKTLevels= 0;
3991ab64890Smrg
4001ab64890Smrg    if (which&XkbIndicatorNamesMask) {
4011ab64890Smrg	req->indicators= leds=
4021ab64890Smrg		_XkbCountAtoms(names->indicators,XkbNumIndicators,&nLEDs);
4031ab64890Smrg	if (nLEDs>0)
4041ab64890Smrg	     nAtoms+= nLEDs;
4051ab64890Smrg	else which&= ~XkbIndicatorNamesMask;
4061ab64890Smrg    }
4071ab64890Smrg    else req->indicators= leds= 0;
4081ab64890Smrg
4091ab64890Smrg    if (which&XkbVirtualModNamesMask) {
41061b2299dSmrg	vmods= req->virtualMods= (CARD16)
4111ab64890Smrg		_XkbCountAtoms(names->vmods,XkbNumVirtualMods,&nVMods);
4121ab64890Smrg	if (nVMods>0)
4131ab64890Smrg	     nAtoms+= nVMods;
4141ab64890Smrg	else which&= ~XkbVirtualModNamesMask;
4151ab64890Smrg    }
4161ab64890Smrg    else vmods= req->virtualMods= 0;
4171ab64890Smrg
4181ab64890Smrg    if (which&XkbGroupNamesMask) {
4191ab64890Smrg	groups= req->groupNames= (CARD8)
4201ab64890Smrg		_XkbCountAtoms(names->groups,XkbNumKbdGroups,&nGroups);
4211ab64890Smrg	if (nGroups>0)
4221ab64890Smrg	     nAtoms+= nGroups;
4231ab64890Smrg	else which&= ~XkbGroupNamesMask;
4241ab64890Smrg    }
4251ab64890Smrg    else groups= req->groupNames= 0;
4261ab64890Smrg
4271ab64890Smrg    if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) {
4281ab64890Smrg	firstKey= req->firstKey;
4291ab64890Smrg	nKeys= req->nKeys;
4301ab64890Smrg	nAtoms+= nKeys;	/* technically not atoms, but 4 bytes wide */
4311ab64890Smrg    }
4321ab64890Smrg    else which&= ~XkbKeyNamesMask;
4331ab64890Smrg
4341ab64890Smrg    if (which&XkbKeyAliasesMask) {
4351ab64890Smrg	nKA= ((names->key_aliases!=NULL)?names->num_key_aliases:0);
4361ab64890Smrg	if (nKA>0) {
4371ab64890Smrg	    req->nKeyAliases= nKA;
4381ab64890Smrg	    nAtoms+= nKA*2; /* not atoms, but 8 bytes on the wire */
4391ab64890Smrg	}
4401ab64890Smrg	else {
4411ab64890Smrg	    which&= ~XkbKeyAliasesMask;
4421ab64890Smrg	    req->nKeyAliases = 0;
4431ab64890Smrg	}
4441ab64890Smrg    }
4451ab64890Smrg    else req->nKeyAliases= 0;
4461ab64890Smrg
4471ab64890Smrg    if (which&XkbRGNamesMask) {
4481ab64890Smrg	nRG= names->num_rg;
4491ab64890Smrg	if (nRG>0)
4501ab64890Smrg	     nAtoms+= nRG;
4511ab64890Smrg	else which&= ~XkbRGNamesMask;
4521ab64890Smrg    }
4531ab64890Smrg
4541ab64890Smrg    req->which= which;
4551ab64890Smrg    req->nRadioGroups= nRG;
4561ab64890Smrg    req->length+= (nAtoms*4)/4;
4571ab64890Smrg
4581ab64890Smrg    if (which&XkbKeycodesNameMask)
4591ab64890Smrg	Data32(dpy,(long *)&names->keycodes,4);
4601ab64890Smrg    if (which&XkbGeometryNameMask)
4611ab64890Smrg	Data32(dpy,(long *)&names->geometry,4);
4621ab64890Smrg    if (which&XkbSymbolsNameMask)
4631ab64890Smrg	Data32(dpy,(long *)&names->symbols,4);
4641ab64890Smrg    if (which&XkbPhysSymbolsNameMask)
4651ab64890Smrg	Data32(dpy,(long *)&names->phys_symbols,4);
4661ab64890Smrg    if (which&XkbTypesNameMask)
4671ab64890Smrg	Data32(dpy,(long *)&names->types,4);
4681ab64890Smrg    if (which&XkbCompatNameMask)
4691ab64890Smrg	Data32(dpy,(long *)&names->compat,4);
4701ab64890Smrg    if (which&XkbKeyTypeNamesMask) {
4711ab64890Smrg	register int 		i;
4721ab64890Smrg	register XkbKeyTypePtr	type;
4731ab64890Smrg	type= &xkb->map->types[firstType];
4741ab64890Smrg	for (i=0;i<nTypes;i++,type++) {
4751ab64890Smrg	    Data32(dpy,(long *)&type->name,4);
4761ab64890Smrg	}
4771ab64890Smrg    }
4781ab64890Smrg    if (which&XkbKTLevelNamesMask) {
4791ab64890Smrg	XkbKeyTypePtr type;
4801ab64890Smrg	int i;
4811ab64890Smrg	char *tmp;
4821ab64890Smrg
4831ab64890Smrg	BufAlloc(char *,tmp,XkbPaddedSize(nLvlTypes));
4841ab64890Smrg	type = &xkb->map->types[firstLvlType];
4851ab64890Smrg	for (i=0;i<nLvlTypes;i++,type++) {
4861ab64890Smrg	    *tmp++ = type->num_levels;
4871ab64890Smrg	}
4881ab64890Smrg	type = &xkb->map->types[firstLvlType];
4891ab64890Smrg	for (i=0;i<nLvlTypes;i++,type++) {
4901ab64890Smrg	    if (type->level_names!=NULL)
4911ab64890Smrg		Data32(dpy,(long *)type->level_names,type->num_levels*4);
4921ab64890Smrg	}
4931ab64890Smrg    }
4941ab64890Smrg    if (which&XkbIndicatorNamesMask)
4951ab64890Smrg	_XkbCopyAtoms(dpy,names->indicators,leds,XkbNumIndicators);
4961ab64890Smrg    if (which&XkbVirtualModNamesMask)
4971ab64890Smrg	_XkbCopyAtoms(dpy,names->vmods,vmods,XkbNumVirtualMods);
4981ab64890Smrg    if (which&XkbGroupNamesMask)
4991ab64890Smrg	_XkbCopyAtoms(dpy,names->groups,groups,XkbNumKbdGroups);
5001ab64890Smrg    if (which&XkbKeyNamesMask) {
5011ab64890Smrg#ifdef WORD64
5021ab64890Smrg	char *tmp;
5031ab64890Smrg	register int i;
5041ab64890Smrg	BufAlloc(char *,tmp,nKeys*XkbKeyNameLength);
5051ab64890Smrg	for (i=0;i<nKeys;i++,tmp+= XkbKeyNameLength) {
5061ab64890Smrg	    tmp[0]= names->keys[firstKey+i].name[0];
5071ab64890Smrg	    tmp[1]= names->keys[firstKey+i].name[1];
5081ab64890Smrg	    tmp[2]= names->keys[firstKey+i].name[2];
5091ab64890Smrg	    tmp[3]= names->keys[firstKey+i].name[3];
5101ab64890Smrg	}
5111ab64890Smrg#else
5121ab64890Smrg	Data(dpy,(char *)&names->keys[firstKey],nKeys*XkbKeyNameLength);
5131ab64890Smrg#endif
5141ab64890Smrg    }
5151ab64890Smrg    if (which&XkbKeyAliasesMask) {
5161ab64890Smrg#ifdef WORD64
5171ab64890Smrg	char *tmp;
5181ab64890Smrg	register int i;
5191ab64890Smrg	BufAlloc(char *,tmp,nKA*XkbKeyNameLength*2);
5201ab64890Smrg	for (i=0;i<nKeys;i++,tmp+= 2*XkbKeyNameLength) {
5211ab64890Smrg	    tmp[0]= names->key_aliases[i].real[0];
5221ab64890Smrg	    tmp[1]= names->key_aliases[i].real[1];
5231ab64890Smrg	    tmp[2]= names->key_aliases[i].real[2];
5241ab64890Smrg	    tmp[3]= names->key_aliases[i].real[3];
5251ab64890Smrg	    tmp[4]= names->key_aliases[i].alias[0];
5261ab64890Smrg	    tmp[5]= names->key_aliases[i].alias[1];
5271ab64890Smrg	    tmp[6]= names->key_aliases[i].alias[2];
5281ab64890Smrg	    tmp[7]= names->key_aliases[i].alias[3];
5291ab64890Smrg	}
5301ab64890Smrg#else
5311ab64890Smrg	Data(dpy,(char *)names->key_aliases,nKA*XkbKeyNameLength*2);
5321ab64890Smrg#endif
5331ab64890Smrg    }
5341ab64890Smrg    if (which&XkbRGNamesMask) {
5351ab64890Smrg	Data32(dpy,(long *)names->radio_groups,nRG*4);
5361ab64890Smrg    }
5371ab64890Smrg    UnlockDisplay(dpy);
5381ab64890Smrg    SyncHandle();
5391ab64890Smrg    return True;
5401ab64890Smrg}
5411ab64890Smrg
5421ab64890SmrgBool
5431ab64890SmrgXkbChangeNames(Display *dpy,XkbDescPtr xkb,XkbNameChangesPtr changes)
5441ab64890Smrg{
5451ab64890Smrg    register xkbSetNamesReq *req;
5461ab64890Smrg    int  nLvlNames = 0;
5471ab64890Smrg    XkbInfoPtr xkbi;
5481ab64890Smrg    XkbNamesPtr names;
5491ab64890Smrg    unsigned which,firstType,nTypes;
5501ab64890Smrg    unsigned firstLvlType,nLvlTypes;
5511ab64890Smrg    int	nVMods,nLEDs,nRG,nKA,nGroups;
5521ab64890Smrg    int nKeys=0,firstKey=0,nAtoms;
5531ab64890Smrg    CARD32 leds=0,vmods=0,groups=0;
5541ab64890Smrg
5551ab64890Smrg    if ((dpy->flags & XlibDisplayNoXkb) ||
5561ab64890Smrg	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
5571ab64890Smrg	return False;
5581ab64890Smrg    if ((!xkb)||(!xkb->names)||(!changes))
5591ab64890Smrg	return False;
5601ab64890Smrg    which= changes->changed;
5611ab64890Smrg    firstType= changes->first_type;
5621ab64890Smrg    nTypes= changes->num_types;
5631ab64890Smrg    firstLvlType= changes->first_lvl;;
5641ab64890Smrg    nLvlTypes= changes->num_lvls;
5651ab64890Smrg    if (which&XkbKeyTypeNamesMask) {
56661b2299dSmrg	if (nTypes<1)
5671ab64890Smrg	    which&= ~XkbKeyTypeNamesMask;
5681ab64890Smrg	else if (firstType<=XkbLastRequiredType) {
5691ab64890Smrg	    int	adjust;
5701ab64890Smrg	    adjust= XkbLastRequiredType-firstType+1;
5711ab64890Smrg	    firstType+= adjust;
5721ab64890Smrg	    nTypes-= adjust;
5731ab64890Smrg	    if (nTypes<1)
5741ab64890Smrg		which&= ~XkbKeyTypeNamesMask;
5751ab64890Smrg	}
5761ab64890Smrg    }
5771ab64890Smrg    else firstType= nTypes= 0;
5781ab64890Smrg
5791ab64890Smrg    if (which&XkbKTLevelNamesMask) {
5801ab64890Smrg	if (nLvlTypes<1)
5811ab64890Smrg	    which&= ~XkbKTLevelNamesMask;
5821ab64890Smrg    }
5831ab64890Smrg    else firstLvlType= nLvlTypes= 0;
5841ab64890Smrg
5851ab64890Smrg    names= xkb->names;
5861ab64890Smrg    if (which&(XkbKTLevelNamesMask|XkbKeyTypeNamesMask)) {
5871ab64890Smrg	register int	i;
5881ab64890Smrg	XkbKeyTypePtr	type;
5891ab64890Smrg	if((xkb->map==NULL)||(xkb->map->types==NULL)||(nTypes==0)||
5901ab64890Smrg				(firstType+nTypes>xkb->map->num_types)||
5911ab64890Smrg				(firstLvlType+nLvlTypes>xkb->map->num_types))
5921ab64890Smrg	    return False;
5931ab64890Smrg	if (which&XkbKTLevelNamesMask) {
5941ab64890Smrg	    type= &xkb->map->types[firstLvlType];
5951ab64890Smrg	    for (i=nLvlNames=0;i<nLvlTypes;i++,type++) {
5961ab64890Smrg		if (type->level_names!=NULL)
5971ab64890Smrg		    nLvlNames+= type->num_levels;
5981ab64890Smrg	    }
5991ab64890Smrg	}
6001ab64890Smrg    }
6011ab64890Smrg
6021ab64890Smrg    if (changes->num_keys<1)
6031ab64890Smrg	which&= ~XkbKeyNamesMask;
6041ab64890Smrg    if ((which&XkbKeyNamesMask)==0)
6051ab64890Smrg	changes->first_key= changes->num_keys= 0;
6061ab64890Smrg    else if ((changes->first_key<xkb->min_key_code)||
6071ab64890Smrg	     (changes->first_key+changes->num_keys>xkb->max_key_code)) {
6081ab64890Smrg	return False;
6091ab64890Smrg    }
6101ab64890Smrg
6111ab64890Smrg    if ((which&XkbVirtualModNamesMask)==0)
6121ab64890Smrg	changes->changed_vmods= 0;
6131ab64890Smrg    else if (changes->changed_vmods==0)
6141ab64890Smrg	which&= ~XkbVirtualModNamesMask;
6151ab64890Smrg
6161ab64890Smrg    if ((which&XkbIndicatorNamesMask)==0)
6171ab64890Smrg	changes->changed_indicators= 0;
6181ab64890Smrg    else if (changes->changed_indicators==0)
6191ab64890Smrg	which&= ~XkbIndicatorNamesMask;
6201ab64890Smrg
6211ab64890Smrg    if ((which&XkbGroupNamesMask)==0)
6221ab64890Smrg	changes->changed_groups= 0;
6231ab64890Smrg    else if (changes->changed_groups==0)
6241ab64890Smrg	which&= ~XkbGroupNamesMask;
62561b2299dSmrg
6261ab64890Smrg    nVMods= nLEDs= nRG= nKA= nAtoms= nGroups= 0;
6271ab64890Smrg    LockDisplay(dpy);
6281ab64890Smrg    xkbi = dpy->xkb_info;
6291ab64890Smrg    GetReq(kbSetNames, req);
6301ab64890Smrg    req->reqType = xkbi->codes->major_opcode;
6311ab64890Smrg    req->xkbReqType = X_kbSetNames;
6321ab64890Smrg    req->deviceSpec = xkb->device_spec;
6331ab64890Smrg    req->firstType = firstType;
6341ab64890Smrg    req->nTypes = nTypes;
6351ab64890Smrg    req->firstKey = changes->first_key;
6361ab64890Smrg    req->nKeys = changes->num_keys;
6371ab64890Smrg
6381ab64890Smrg    if (which&XkbKeycodesNameMask)
6391ab64890Smrg	nAtoms++;
6401ab64890Smrg    if (which&XkbGeometryNameMask)
6411ab64890Smrg	nAtoms++;
6421ab64890Smrg    if (which&XkbSymbolsNameMask)
6431ab64890Smrg	nAtoms++;
6441ab64890Smrg    if (which&XkbPhysSymbolsNameMask)
6451ab64890Smrg	nAtoms++;
6461ab64890Smrg    if (which&XkbTypesNameMask)
6471ab64890Smrg	nAtoms++;
6481ab64890Smrg    if (which&XkbCompatNameMask)
6491ab64890Smrg	nAtoms++;
6501ab64890Smrg    if (which&XkbKeyTypeNamesMask)
6511ab64890Smrg	nAtoms+= nTypes;
6521ab64890Smrg    if (which&XkbKTLevelNamesMask) {
6531ab64890Smrg	req->firstKTLevel= firstLvlType;
6541ab64890Smrg	req->nKTLevels= nLvlTypes;
6551ab64890Smrg	req->length+= XkbPaddedSize(nLvlTypes)/4; /* room for group widths */
6561ab64890Smrg	nAtoms+= nLvlNames;
6571ab64890Smrg    }
6581ab64890Smrg    else req->firstKTLevel= req->nKTLevels= 0;
6591ab64890Smrg
6601ab64890Smrg    if (which&XkbIndicatorNamesMask) {
6611ab64890Smrg	leds= req->indicators= (CARD32)changes->changed_indicators;
6621ab64890Smrg	nLEDs= _XkbCountBits(XkbNumIndicators,changes->changed_indicators);
6631ab64890Smrg	if (nLEDs>0)
6641ab64890Smrg	     nAtoms+= nLEDs;
6651ab64890Smrg	else which&= ~XkbIndicatorNamesMask;
6661ab64890Smrg    }
6671ab64890Smrg    else req->indicators= 0;
6681ab64890Smrg
6691ab64890Smrg    if (which&XkbVirtualModNamesMask) {
6701ab64890Smrg	vmods= req->virtualMods= changes->changed_vmods;
6711ab64890Smrg	nVMods= _XkbCountBits(XkbNumVirtualMods,
6721ab64890Smrg					(unsigned long)changes->changed_vmods);
6731ab64890Smrg	if (nVMods>0)
6741ab64890Smrg	     nAtoms+= nVMods;
6751ab64890Smrg	else which&= ~XkbVirtualModNamesMask;
6761ab64890Smrg    }
6771ab64890Smrg    else req->virtualMods= 0;
6781ab64890Smrg
6791ab64890Smrg    if (which&XkbGroupNamesMask) {
6801ab64890Smrg	groups= req->groupNames= changes->changed_groups;
6811ab64890Smrg	nGroups= _XkbCountBits(XkbNumKbdGroups,
6821ab64890Smrg					(unsigned long)changes->changed_groups);
6831ab64890Smrg	if (nGroups>0)
6841ab64890Smrg	     nAtoms+= nGroups;
6851ab64890Smrg	else which&= ~XkbGroupNamesMask;
6861ab64890Smrg    }
6871ab64890Smrg    else req->groupNames= 0;
6881ab64890Smrg
6891ab64890Smrg    if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) {
6901ab64890Smrg	firstKey= req->firstKey;
6911ab64890Smrg	nKeys= req->nKeys;
6921ab64890Smrg	nAtoms+= nKeys;	/* technically not atoms, but 4 bytes wide */
6931ab64890Smrg    }
6941ab64890Smrg    else which&= ~XkbKeyNamesMask;
6951ab64890Smrg
6961ab64890Smrg    if (which&XkbKeyAliasesMask) {
6971ab64890Smrg	nKA= ((names->key_aliases!=NULL)?names->num_key_aliases:0);
6981ab64890Smrg	if (nKA>0)
6991ab64890Smrg	    nAtoms+= nKA*2; /* not atoms, but 8 bytes on the wire */
7001ab64890Smrg	else which&= ~XkbKeyAliasesMask;
7011ab64890Smrg    }
7021ab64890Smrg
7031ab64890Smrg    if (which&XkbRGNamesMask) {
7041ab64890Smrg	nRG= names->num_rg;
7051ab64890Smrg	if (nRG>0)
7061ab64890Smrg	     nAtoms+= nRG;
7071ab64890Smrg	else which&= ~XkbRGNamesMask;
7081ab64890Smrg    }
7091ab64890Smrg
7101ab64890Smrg    req->which= which;
7111ab64890Smrg    req->nRadioGroups= nRG;
7121ab64890Smrg    req->length+= (nAtoms*4)/4;
7131ab64890Smrg
7141ab64890Smrg    if (which&XkbKeycodesNameMask)
7151ab64890Smrg	Data32(dpy,(long *)&names->keycodes,4);
7161ab64890Smrg    if (which&XkbGeometryNameMask)
7171ab64890Smrg	Data32(dpy,(long *)&names->geometry,4);
7181ab64890Smrg    if (which&XkbSymbolsNameMask)
7191ab64890Smrg	Data32(dpy,(long *)&names->symbols,4);
7201ab64890Smrg    if (which&XkbPhysSymbolsNameMask)
7211ab64890Smrg	Data32(dpy,(long *)&names->phys_symbols,4);
7221ab64890Smrg    if (which&XkbTypesNameMask)
7231ab64890Smrg	Data32(dpy,(long *)&names->types,4);
7241ab64890Smrg    if (which&XkbCompatNameMask)
7251ab64890Smrg	Data32(dpy,(long *)&names->compat,4);
7261ab64890Smrg    if (which&XkbKeyTypeNamesMask) {
7271ab64890Smrg	register int 		i;
7281ab64890Smrg	register XkbKeyTypePtr	type;
7291ab64890Smrg	type= &xkb->map->types[firstType];
7301ab64890Smrg	for (i=0;i<nTypes;i++,type++) {
7311ab64890Smrg	    Data32(dpy,(long *)&type->name,4);
7321ab64890Smrg	}
7331ab64890Smrg    }
7341ab64890Smrg    if (which&XkbKTLevelNamesMask) {
7351ab64890Smrg	XkbKeyTypePtr type;
7361ab64890Smrg	int i;
7371ab64890Smrg	char *tmp;
7381ab64890Smrg
7391ab64890Smrg	BufAlloc(char *,tmp,XkbPaddedSize(nLvlTypes));
7401ab64890Smrg	type = &xkb->map->types[firstLvlType];
7411ab64890Smrg	for (i=0;i<nLvlTypes;i++,type++) {
7421ab64890Smrg	    *tmp++ = type->num_levels;
7431ab64890Smrg	}
7441ab64890Smrg	type = &xkb->map->types[firstLvlType];
7451ab64890Smrg	for (i=0;i<nLvlTypes;i++,type++) {
7461ab64890Smrg	    if (type->level_names!=NULL)
7471ab64890Smrg		Data32(dpy,(long *)type->level_names,type->num_levels*4);
7481ab64890Smrg	}
7491ab64890Smrg    }
7501ab64890Smrg    if (which&XkbIndicatorNamesMask)
7511ab64890Smrg	_XkbCopyAtoms(dpy,names->indicators,leds,XkbNumIndicators);
7521ab64890Smrg    if (which&XkbVirtualModNamesMask)
7531ab64890Smrg	_XkbCopyAtoms(dpy,names->vmods,vmods,XkbNumVirtualMods);
7541ab64890Smrg    if (which&XkbGroupNamesMask)
7551ab64890Smrg	_XkbCopyAtoms(dpy,names->groups,groups,XkbNumKbdGroups);
7561ab64890Smrg    if (which&XkbKeyNamesMask) {
7571ab64890Smrg#ifdef WORD64
7581ab64890Smrg	char *tmp;
7591ab64890Smrg	register int i;
7601ab64890Smrg	BufAlloc(char *,tmp,nKeys*4);
7611ab64890Smrg	for (i=0;i<nKeys;i++,tmp+= 4) {
7621ab64890Smrg	    tmp[0]= names->keys[firstKey+i].name[0];
7631ab64890Smrg	    tmp[1]= names->keys[firstKey+i].name[1];
7641ab64890Smrg	    tmp[2]= names->keys[firstKey+i].name[2];
7651ab64890Smrg	    tmp[3]= names->keys[firstKey+i].name[3];
7661ab64890Smrg	}
7671ab64890Smrg#else
7681ab64890Smrg	Data(dpy,(char *)&names->keys[firstKey],nKeys*XkbKeyNameLength);
7691ab64890Smrg#endif
7701ab64890Smrg    }
7711ab64890Smrg    if (which&XkbKeyAliasesMask) {
7721ab64890Smrg#ifdef WORD64
7731ab64890Smrg	char *tmp;
7741ab64890Smrg	register int i;
7751ab64890Smrg	BufAlloc(char *,tmp,nKA*XkbKeyNameLength*2);
7761ab64890Smrg	for (i=0;i<nKeys;i++,tmp+= 2*XkbKeyNameLength) {
7771ab64890Smrg	    tmp[0]= names->key_aliases[i].real[0];
7781ab64890Smrg	    tmp[1]= names->key_aliases[i].real[1];
7791ab64890Smrg	    tmp[2]= names->key_aliases[i].real[2];
7801ab64890Smrg	    tmp[3]= names->key_aliases[i].real[3];
7811ab64890Smrg	    tmp[4]= names->key_aliases[i].alias[0];
7821ab64890Smrg	    tmp[5]= names->key_aliases[i].alias[1];
7831ab64890Smrg	    tmp[6]= names->key_aliases[i].alias[2];
7841ab64890Smrg	    tmp[7]= names->key_aliases[i].alias[3];
7851ab64890Smrg	}
7861ab64890Smrg#else
7871ab64890Smrg	Data(dpy,(char *)names->key_aliases,nKA*XkbKeyNameLength*2);
7881ab64890Smrg#endif
7891ab64890Smrg    }
7901ab64890Smrg    if (which&XkbRGNamesMask) {
7911ab64890Smrg	Data32(dpy,(long *)names->radio_groups,nRG*4);
7921ab64890Smrg    }
7931ab64890Smrg    UnlockDisplay(dpy);
7941ab64890Smrg    SyncHandle();
7951ab64890Smrg    return True;
7961ab64890Smrg}
7971ab64890Smrg
7981ab64890Smrgvoid
7991ab64890SmrgXkbNoteNameChanges(	XkbNameChangesPtr	old,
8001ab64890Smrg			XkbNamesNotifyEvent *	new,
8011ab64890Smrg			unsigned int	 	wanted)
8021ab64890Smrg{
8031ab64890Smrgint	first,last,old_last,new_last;
8041ab64890Smrg
8051ab64890Smrg    wanted&= new->changed;
8061ab64890Smrg    if ((old==NULL)||(new==NULL)||(wanted==0))
8071ab64890Smrg	return;
8081ab64890Smrg    if (wanted&XkbKeyTypeNamesMask) {
8091ab64890Smrg	if (old->changed&XkbKeyTypeNamesMask) {
8101ab64890Smrg	    new_last= (new->first_type+new->num_types-1);
8111ab64890Smrg	    old_last= (old->first_type+old->num_types-1);
8121ab64890Smrg
8131ab64890Smrg	    if (new->first_type<old->first_type)
8141ab64890Smrg		 first= new->first_type;
8151ab64890Smrg	    else first= old->first_type;
8161ab64890Smrg
8171ab64890Smrg	    if (old_last>new_last)
8181ab64890Smrg		 last= old_last;
8191ab64890Smrg	    else last= new_last;
8201ab64890Smrg
8211ab64890Smrg	    old->first_type= first;
8221ab64890Smrg	    old->num_types= (last-first)+1;
8231ab64890Smrg	}
8241ab64890Smrg	else {
8251ab64890Smrg	    old->first_type= new->first_type;
8261ab64890Smrg	    old->num_types= new->num_types;
8271ab64890Smrg	}
8281ab64890Smrg    }
8291ab64890Smrg    if (wanted&XkbKTLevelNamesMask) {
8301ab64890Smrg	if (old->changed&XkbKTLevelNamesMask) {
8311ab64890Smrg	    new_last= (new->first_lvl+new->num_lvls-1);
8321ab64890Smrg	    old_last= (old->first_lvl+old->num_lvls-1);
8331ab64890Smrg
8341ab64890Smrg	    if (new->first_lvl<old->first_lvl)
8351ab64890Smrg		 first= new->first_lvl;
8361ab64890Smrg	    else first= old->first_lvl;
8371ab64890Smrg
8381ab64890Smrg	    if (old_last>new_last)
8391ab64890Smrg		 last= old_last;
8401ab64890Smrg	    else last= new_last;
8411ab64890Smrg
8421ab64890Smrg	    old->first_lvl= first;
8431ab64890Smrg	    old->num_lvls= (last-first)+1;
8441ab64890Smrg	}
8451ab64890Smrg	else {
8461ab64890Smrg	    old->first_lvl= new->first_lvl;
8471ab64890Smrg	    old->num_lvls= new->num_lvls;
8481ab64890Smrg	}
8491ab64890Smrg    }
8501ab64890Smrg    if (wanted&XkbIndicatorNamesMask) {
8511ab64890Smrg	if (old->changed&XkbIndicatorNamesMask)
8521ab64890Smrg	     old->changed_indicators|= new->changed_indicators;
8531ab64890Smrg	else old->changed_indicators=  new->changed_indicators;
8541ab64890Smrg    }
8551ab64890Smrg    if (wanted&XkbKeyNamesMask) {
8561ab64890Smrg	if (old->changed&XkbKeyNamesMask) {
8571ab64890Smrg	    new_last= (new->first_key+new->num_keys-1);
8581ab64890Smrg	    old_last= (old->first_key+old->num_keys-1);
8591ab64890Smrg
8601ab64890Smrg	    first= old->first_key;
8611ab64890Smrg
8621ab64890Smrg	    if (new->first_key<old->first_key)
8631ab64890Smrg		first= new->first_key;
8641ab64890Smrg	    if (old_last>new_last)
8651ab64890Smrg		new_last= old_last;
8661ab64890Smrg
8671ab64890Smrg	    old->first_key= first;
8681ab64890Smrg	    old->num_keys= (new_last-first)+1;
8691ab64890Smrg	}
8701ab64890Smrg	else {
8711ab64890Smrg	    old->first_key= new->first_key;
8721ab64890Smrg	    old->num_keys= new->num_keys;
8731ab64890Smrg	}
8741ab64890Smrg    }
8751ab64890Smrg    if (wanted&XkbVirtualModNamesMask) {
8761ab64890Smrg	if (old->changed&XkbVirtualModNamesMask)
8771ab64890Smrg	     old->changed_vmods|= new->changed_vmods;
8781ab64890Smrg	else old->changed_vmods=  new->changed_vmods;
8791ab64890Smrg    }
8801ab64890Smrg    if (wanted&XkbGroupNamesMask) {
8811ab64890Smrg	if (old->changed&XkbGroupNamesMask)
8821ab64890Smrg	     old->changed_groups|= new->changed_groups;
8831ab64890Smrg	else old->changed_groups=  new->changed_groups;
8841ab64890Smrg    }
88561b2299dSmrg    if (wanted&XkbRGNamesMask)
8861ab64890Smrg	old->num_rg= new->num_radio_groups;
88761b2299dSmrg    if (wanted&XkbKeyAliasesMask)
8881ab64890Smrg	old->num_aliases= new->num_aliases;
8891ab64890Smrg    old->changed|= wanted;
8901ab64890Smrg    return;
8911ab64890Smrg}
892