XKBSetMap.c revision 61b2299d
11ab64890Smrg/* $Xorg: XKBSetMap.c,v 1.4 2000/08/17 19:45:03 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/XKBSetMap.c,v 3.2 2001/01/17 19:41:49 dawes Exp $ */
281ab64890Smrg
291ab64890Smrg#ifdef HAVE_CONFIG_H
301ab64890Smrg#include <config.h>
311ab64890Smrg#endif
321ab64890Smrg#include <stdio.h>
331ab64890Smrg#define NEED_REPLIES
341ab64890Smrg#define NEED_EVENTS
351ab64890Smrg#include "Xlibint.h"
361ab64890Smrg#include <X11/extensions/XKBproto.h>
371ab64890Smrg#include "XKBlibint.h"
381ab64890Smrg
391ab64890Smrgstatic int
401ab64890Smrg_XkbSizeKeyTypes(XkbDescPtr xkb,xkbSetMapReq *req)
411ab64890Smrg{
421ab64890Smrg    XkbKeyTypePtr	map;
431ab64890Smrg    int			i,len;
441ab64890Smrg
451ab64890Smrg    if (((req->present&XkbKeyTypesMask)==0)||(req->nTypes==0)) {
461ab64890Smrg	req->present&= ~XkbKeyTypesMask;
471ab64890Smrg	req->firstType= req->nTypes= 0;
481ab64890Smrg	return 0;
491ab64890Smrg    }
501ab64890Smrg    len= 0;
511ab64890Smrg    map= &xkb->map->types[req->firstType];
521ab64890Smrg    for (i=0;i<req->nTypes;i++,map++){
531ab64890Smrg	len+= SIZEOF(xkbKeyTypeWireDesc);
541ab64890Smrg	len+= map->map_count*SIZEOF(xkbKTSetMapEntryWireDesc);
551ab64890Smrg	if (map->preserve)
561ab64890Smrg	    len+= map->map_count*SIZEOF(xkbModsWireDesc);
571ab64890Smrg    }
581ab64890Smrg    return len;
591ab64890Smrg}
601ab64890Smrg
611ab64890Smrgstatic void
621ab64890Smrg_XkbWriteKeyTypes(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
631ab64890Smrg{
641ab64890Smrg    char *		buf;
651ab64890Smrg    XkbKeyTypePtr 	type;
661ab64890Smrg    int			i,n,sz;
671ab64890Smrg    xkbKeyTypeWireDesc *desc;
681ab64890Smrg
691ab64890Smrg    if ((req->present&XkbKeyTypesMask)==0)
701ab64890Smrg	return;
711ab64890Smrg    type= &xkb->map->types[req->firstType];
721ab64890Smrg    for (i=0;i<req->nTypes;i++,type++) {
731ab64890Smrg	sz= SIZEOF(xkbKeyTypeWireDesc);
741ab64890Smrg	sz+= type->map_count*SIZEOF(xkbKTSetMapEntryWireDesc);
751ab64890Smrg	if (type->preserve)
761ab64890Smrg	    sz+= type->map_count*SIZEOF(xkbModsWireDesc);
771ab64890Smrg	BufAlloc(xkbKeyTypeWireDesc *,desc,sz);
781ab64890Smrg	desc->mask = type->mods.mask;
791ab64890Smrg	desc->realMods = type->mods.real_mods;
801ab64890Smrg	desc->virtualMods = type->mods.vmods;
811ab64890Smrg	desc->numLevels = type->num_levels;
821ab64890Smrg	desc->nMapEntries = type->map_count;
831ab64890Smrg	desc->preserve = (type->preserve!=NULL);
841ab64890Smrg	buf= (char *)&desc[1];
851ab64890Smrg	if (desc->nMapEntries>0) {
861ab64890Smrg	    xkbKTSetMapEntryWireDesc *wire;
871ab64890Smrg	    wire= (xkbKTSetMapEntryWireDesc *)buf;
881ab64890Smrg	    for (n=0;n<type->map_count;n++,wire++) {
891ab64890Smrg		wire->level= type->map[n].level;
901ab64890Smrg		wire->realMods= type->map[n].mods.real_mods;
911ab64890Smrg		wire->virtualMods= type->map[n].mods.vmods;
921ab64890Smrg	    }
931ab64890Smrg	    buf= (char *)wire;
941ab64890Smrg	    if (type->preserve) {
951ab64890Smrg		xkbModsWireDesc *pwire;
961ab64890Smrg		pwire= (xkbModsWireDesc *)buf;
971ab64890Smrg		for (n=0;n<type->map_count;n++,pwire++) {
981ab64890Smrg		    pwire->realMods= type->preserve[n].real_mods;
991ab64890Smrg		    pwire->virtualMods= type->preserve[n].vmods;
1001ab64890Smrg		}
1011ab64890Smrg	    }
1021ab64890Smrg	}
1031ab64890Smrg    }
1041ab64890Smrg    return;
1051ab64890Smrg}
1061ab64890Smrg
1071ab64890Smrgstatic int
1081ab64890Smrg_XkbSizeKeySyms(XkbDescPtr xkb,xkbSetMapReq *req)
1091ab64890Smrg{
1101ab64890Smrg    int			i,len;
1111ab64890Smrg    unsigned		nSyms;
1121ab64890Smrg
1131ab64890Smrg    if (((req->present&XkbKeySymsMask)==0)||(req->nKeySyms==0)) {
1141ab64890Smrg	req->present&= ~XkbKeySymsMask;
1151ab64890Smrg	req->firstKeySym= req->nKeySyms= 0;
1161ab64890Smrg	req->totalSyms= 0;
1171ab64890Smrg	return 0;
1181ab64890Smrg    }
1191ab64890Smrg    len= (int)(req->nKeySyms*sizeof(XkbSymMapRec));
1201ab64890Smrg    for (i=nSyms=0;i<req->nKeySyms;i++) {
1211ab64890Smrg	nSyms+= XkbKeyNumSyms(xkb,i+req->firstKeySym);
1221ab64890Smrg    }
1231ab64890Smrg    len+= nSyms*sizeof(CARD32);
1241ab64890Smrg    req->totalSyms= nSyms;
1251ab64890Smrg    return len;
1261ab64890Smrg}
1271ab64890Smrg
1281ab64890Smrgstatic void
1291ab64890Smrg_XkbWriteKeySyms(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
1301ab64890Smrg{
1311ab64890Smrgregister KeySym *	pSym;
1321ab64890SmrgCARD32 *		outSym;
1331ab64890SmrgXkbSymMapPtr		symMap;
1341ab64890SmrgxkbSymMapWireDesc *desc;
1351ab64890Smrgregister int	i;
1361ab64890Smrg
1371ab64890Smrg    if ((req->present&XkbKeySymsMask)==0)
1381ab64890Smrg	return;
1391ab64890Smrg    symMap = &xkb->map->key_sym_map[req->firstKeySym];
1401ab64890Smrg    for (i=0;i<req->nKeySyms;i++,symMap++) {
1411ab64890Smrg	BufAlloc(xkbSymMapWireDesc *,desc,
1421ab64890Smrg		 SIZEOF(xkbSymMapWireDesc)+
1431ab64890Smrg		 (XkbKeyNumSyms(xkb,i+req->firstKeySym)*sizeof(CARD32)));
1441ab64890Smrg	desc->ktIndex[0] = symMap->kt_index[0];
1451ab64890Smrg	desc->ktIndex[1] = symMap->kt_index[1];
1461ab64890Smrg	desc->ktIndex[2] = symMap->kt_index[2];
1471ab64890Smrg	desc->ktIndex[3] = symMap->kt_index[3];
1481ab64890Smrg	desc->groupInfo = symMap->group_info;
1491ab64890Smrg	desc->width = symMap->width;
1501ab64890Smrg	desc->nSyms = XkbKeyNumSyms(xkb,i+req->firstKeySym);
1511ab64890Smrg	outSym = (CARD32 *)&desc[1];
1521ab64890Smrg	if (desc->nSyms>0) {
1531ab64890Smrg	     pSym = XkbKeySymsPtr(xkb,i+req->firstKeySym);
1541ab64890Smrg	    _XkbWriteCopyKeySyms(pSym,outSym,desc->nSyms);
1551ab64890Smrg	}
1561ab64890Smrg    }
1571ab64890Smrg    return;
1581ab64890Smrg}
1591ab64890Smrg
1601ab64890Smrgstatic int
1611ab64890Smrg_XkbSizeKeyActions(XkbDescPtr xkb,xkbSetMapReq *req)
1621ab64890Smrg{
1631ab64890Smrg    int			i,len,nActs;
1641ab64890Smrg
1651ab64890Smrg    if (((req->present&XkbKeyActionsMask)==0)||(req->nKeyActs==0)) {
1661ab64890Smrg	req->present&= ~XkbKeyActionsMask;
1671ab64890Smrg	req->firstKeyAct= req->nKeyActs= 0;
1681ab64890Smrg	req->totalActs= 0;
1691ab64890Smrg	return 0;
1701ab64890Smrg    }
1711ab64890Smrg    for (nActs=i=0;i<req->nKeyActs;i++) {
1721ab64890Smrg	if (xkb->server->key_acts[i+req->firstKeyAct]!=0)
1731ab64890Smrg	    nActs+= XkbKeyNumActions(xkb,i+req->firstKeyAct);
1741ab64890Smrg    }
1751ab64890Smrg    len= XkbPaddedSize(req->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc));
1761ab64890Smrg    req->totalActs= nActs;
1771ab64890Smrg    return len;
1781ab64890Smrg}
1791ab64890Smrg
1801ab64890Smrgstatic void
1811ab64890Smrg_XkbWriteKeyActions(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
1821ab64890Smrg{
1831ab64890Smrg    register int	 i;
1841ab64890Smrg    int	 		 n;
1851ab64890Smrg    CARD8		*numDesc;
1861ab64890Smrg    XkbAction		*actDesc;
1871ab64890Smrg
1881ab64890Smrg    if ((req->present&XkbKeyActionsMask)==0)
1891ab64890Smrg	return;
1901ab64890Smrg    n = XkbPaddedSize(req->nKeyActs);
1911ab64890Smrg    n+= (req->totalActs*SIZEOF(xkbActionWireDesc));
1921ab64890Smrg
1931ab64890Smrg    BufAlloc(CARD8 *,numDesc,n);
1941ab64890Smrg    for (i=0;i<req->nKeyActs;i++) {
1951ab64890Smrg	if (xkb->server->key_acts[i+req->firstKeyAct]==0)
1961ab64890Smrg	     numDesc[i] = 0;
1971ab64890Smrg	else numDesc[i] = XkbKeyNumActions(xkb,(i+req->firstKeyAct));
1981ab64890Smrg    }
1991ab64890Smrg    actDesc = (XkbAction *)&numDesc[XkbPaddedSize(req->nKeyActs)];
2001ab64890Smrg    for (i=0;i<req->nKeyActs;i++) {
2011ab64890Smrg	if (xkb->server->key_acts[i+req->firstKeyAct]!=0) {
2021ab64890Smrg	    n = XkbKeyNumActions(xkb,(i+req->firstKeyAct));
2031ab64890Smrg	    memcpy(actDesc,XkbKeyActionsPtr(xkb,(i+req->firstKeyAct)),
2041ab64890Smrg                                                   n*SIZEOF(xkbActionWireDesc));
2051ab64890Smrg	    actDesc+= n;
2061ab64890Smrg	}
2071ab64890Smrg    }
2081ab64890Smrg    return;
2091ab64890Smrg}
2101ab64890Smrg
2111ab64890Smrgstatic int
2121ab64890Smrg_XkbSizeKeyBehaviors(XkbDescPtr	xkb,xkbSetMapReq *req)
2131ab64890Smrg{
2141ab64890Smrgregister int i,first,last,nFound;
2151ab64890Smrg
2161ab64890Smrg    if (((req->present&XkbKeyBehaviorsMask)==0)||(req->nKeyBehaviors<1)) {
2171ab64890Smrg	req->present&= ~XkbKeyBehaviorsMask;
2181ab64890Smrg	req->firstKeyBehavior= req->nKeyBehaviors= 0;
2191ab64890Smrg	req->totalKeyBehaviors= 0;
2201ab64890Smrg	return 0;
2211ab64890Smrg    }
2221ab64890Smrg    first= req->firstKeyBehavior;
2231ab64890Smrg    last= first+req->nKeyBehaviors-1;
2241ab64890Smrg    for (i=first,nFound=0;i<=last;i++) {
2251ab64890Smrg	if (xkb->server->behaviors[i].type!=XkbKB_Default)
2261ab64890Smrg	    nFound++;
2271ab64890Smrg    }
2281ab64890Smrg    req->totalKeyBehaviors= nFound;
2291ab64890Smrg    return (nFound*SIZEOF(xkbBehaviorWireDesc));
2301ab64890Smrg}
2311ab64890Smrg
2321ab64890Smrgstatic void
2331ab64890Smrg_XkbWriteKeyBehaviors(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
2341ab64890Smrg{
2351ab64890Smrgregister int 		i,first,last;
2361ab64890SmrgxkbBehaviorWireDesc *	wire;
2371ab64890Smrgchar *			buf;
2381ab64890Smrg
2391ab64890Smrg    if ((req->present&XkbKeyBehaviorsMask)==0)
2401ab64890Smrg	return;
2411ab64890Smrg    first= req->firstKeyBehavior;
2421ab64890Smrg    last= first+req->nKeyBehaviors-1;
2431ab64890Smrg
2441ab64890Smrg    i= req->totalKeyBehaviors*SIZEOF(xkbBehaviorWireDesc);
2451ab64890Smrg    BufAlloc(char *,buf,i);
2461ab64890Smrg    wire= (xkbBehaviorWireDesc *)buf;
2471ab64890Smrg    for (i=first;i<=last;i++) {
2481ab64890Smrg	if (xkb->server->behaviors[i].type!=XkbKB_Default) {
2491ab64890Smrg	    wire->key= i;
2501ab64890Smrg	    wire->type= xkb->server->behaviors[i].type;
2511ab64890Smrg	    wire->data= xkb->server->behaviors[i].data;
2521ab64890Smrg	    buf+= SIZEOF(xkbBehaviorWireDesc);
2531ab64890Smrg	    wire= (xkbBehaviorWireDesc *)buf;
2541ab64890Smrg	}
2551ab64890Smrg    }
2561ab64890Smrg    return;
2571ab64890Smrg}
2581ab64890Smrg
2591ab64890Smrgstatic unsigned
2601ab64890Smrg_XkbSizeVirtualMods(xkbSetMapReq *req)
2611ab64890Smrg{
2621ab64890Smrgregister int i,bit,nMods;
2631ab64890Smrg
2641ab64890Smrg   if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0)) {
2651ab64890Smrg	req->present&= ~XkbVirtualModsMask;
2661ab64890Smrg	req->virtualMods= 0;
2671ab64890Smrg	return 0;
2681ab64890Smrg   }
2691ab64890Smrg   for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
2701ab64890Smrg	if (req->virtualMods&bit)
2711ab64890Smrg	    nMods++;
2721ab64890Smrg   }
2731ab64890Smrg   return XkbPaddedSize(nMods);
2741ab64890Smrg}
2751ab64890Smrg
2761ab64890Smrgstatic void
2771ab64890Smrg_XkbWriteVirtualMods(	Display *	dpy,
2781ab64890Smrg			XkbDescPtr 	xkb,
2791ab64890Smrg			xkbSetMapReq *	req,
2801ab64890Smrg			unsigned 	size)
2811ab64890Smrg{
2821ab64890Smrg    register int	 i,bit;
2831ab64890Smrg    CARD8		*vmods;
2841ab64890Smrg
2851ab64890Smrg    /* This was req->present&XkbVirtualModsMask==0, and '==' beats '&' */
2861ab64890Smrg    if (((req->present & XkbVirtualModsMask) == 0) || (size < 1))
2871ab64890Smrg	return;
2881ab64890Smrg    BufAlloc(CARD8 *,vmods,size);
2891ab64890Smrg    for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
2901ab64890Smrg	if (req->virtualMods&bit)
2911ab64890Smrg	    *vmods++= xkb->server->vmods[i];
2921ab64890Smrg    }
2931ab64890Smrg    return;
2941ab64890Smrg}
2951ab64890Smrg
2961ab64890Smrgstatic int
2971ab64890Smrg_XkbSizeKeyExplicit(XkbDescPtr xkb,xkbSetMapReq *req)
2981ab64890Smrg{
2991ab64890Smrgregister int i,first,last,nFound;
3001ab64890Smrg
3011ab64890Smrg    if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit==0)) {
3021ab64890Smrg	req->present&= ~XkbExplicitComponentsMask;
3031ab64890Smrg	req->firstKeyExplicit= req->nKeyExplicit= 0;
3041ab64890Smrg	req->totalKeyExplicit= 0;
3051ab64890Smrg	return 0;
3061ab64890Smrg    }
3071ab64890Smrg    first= req->firstKeyExplicit;
3081ab64890Smrg    last= first+req->nKeyExplicit-1;
3091ab64890Smrg
3101ab64890Smrg    for (i=first,nFound=0;i<=last;i++) {
3111ab64890Smrg	if (xkb->server->explicit[i]!=0)
3121ab64890Smrg	    nFound++;
3131ab64890Smrg    }
3141ab64890Smrg    req->totalKeyExplicit= nFound;
3151ab64890Smrg    return XkbPaddedSize((nFound*2));
3161ab64890Smrg}
3171ab64890Smrg
3181ab64890Smrgstatic void
3191ab64890Smrg_XkbWriteKeyExplicit(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
3201ab64890Smrg{
3211ab64890Smrgregister int	i,first,last;
3221ab64890SmrgCARD8 *		wire;
3231ab64890Smrg
3241ab64890Smrg    if ((req->present&XkbExplicitComponentsMask)==0)
3251ab64890Smrg	return;
3261ab64890Smrg    first= req->firstKeyExplicit;
32761b2299dSmrg    last= first+req->nKeyExplicit - 1;
3281ab64890Smrg    i= XkbPaddedSize((req->totalKeyExplicit*2));
3291ab64890Smrg    BufAlloc(CARD8 *,wire,i);
3301ab64890Smrg    for (i=first;i<=last;i++) {
3311ab64890Smrg	if (xkb->server->explicit[i]!=0) {
3321ab64890Smrg	    wire[0]= i;
3331ab64890Smrg	    wire[1]= xkb->server->explicit[i];
3341ab64890Smrg	    wire+= 2;
3351ab64890Smrg	}
3361ab64890Smrg    }
3371ab64890Smrg    return;
3381ab64890Smrg}
3391ab64890Smrg
3401ab64890Smrgstatic int
3411ab64890Smrg_XkbSizeModifierMap(XkbDescPtr xkb,xkbSetMapReq *req)
3421ab64890Smrg{
3431ab64890Smrgregister int i,first,last,nFound;
3441ab64890Smrg
3451ab64890Smrg    if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys==0)) {
3461ab64890Smrg	req->present&= ~XkbModifierMapMask;
3471ab64890Smrg	req->firstModMapKey= req->nModMapKeys= 0;
3481ab64890Smrg	req->totalModMapKeys= 0;
3491ab64890Smrg	return 0;
3501ab64890Smrg    }
3511ab64890Smrg    first= req->firstModMapKey;
3521ab64890Smrg    last= first+req->nModMapKeys-1;
3531ab64890Smrg
3541ab64890Smrg    for (i=first,nFound=0;i<=last;i++) {
3551ab64890Smrg	if (xkb->map->modmap[i]!=0)
3561ab64890Smrg	    nFound++;
3571ab64890Smrg    }
3581ab64890Smrg    req->totalModMapKeys= nFound;
3591ab64890Smrg    return XkbPaddedSize((nFound*2));
3601ab64890Smrg}
3611ab64890Smrg
3621ab64890Smrgstatic void
3631ab64890Smrg_XkbWriteModifierMap(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
3641ab64890Smrg{
3651ab64890Smrgregister int	i,first,last;
3661ab64890SmrgCARD8 *		wire;
3671ab64890Smrg
3681ab64890Smrg    if ((req->present&XkbModifierMapMask)==0)
3691ab64890Smrg	return;
3701ab64890Smrg    first= req->firstModMapKey;
3711ab64890Smrg    last= first+req->nModMapKeys-1;
3721ab64890Smrg    if (req->totalModMapKeys>0) {
3731ab64890Smrg	i= XkbPaddedSize((req->totalModMapKeys*2));
3741ab64890Smrg	BufAlloc(CARD8 *,wire,i);
3751ab64890Smrg	for (i=first;i<=last;i++) {
3761ab64890Smrg	    if (xkb->map->modmap[i]!=0) {
3771ab64890Smrg		wire[0]= i;
3781ab64890Smrg		wire[1]= xkb->map->modmap[i];
3791ab64890Smrg		wire+= 2;
3801ab64890Smrg	    }
3811ab64890Smrg	}
3821ab64890Smrg    }
3831ab64890Smrg    return;
3841ab64890Smrg}
3851ab64890Smrg
3861ab64890Smrgstatic int
3871ab64890Smrg_XkbSizeVirtualModMap(XkbDescPtr xkb,xkbSetMapReq *req)
3881ab64890Smrg{
3891ab64890Smrgregister int i,first,last,nFound;
3901ab64890Smrg
3911ab64890Smrg    if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys==0)) {
3921ab64890Smrg	req->present&= ~XkbVirtualModMapMask;
3931ab64890Smrg	req->firstVModMapKey= req->nVModMapKeys= 0;
3941ab64890Smrg	req->totalVModMapKeys= 0;
3951ab64890Smrg	return 0;
3961ab64890Smrg    }
3971ab64890Smrg    first= req->firstVModMapKey;
3981ab64890Smrg    last= first+req->nVModMapKeys-1;
3991ab64890Smrg
4001ab64890Smrg    for (i=first,nFound=0;i<=last;i++) {
4011ab64890Smrg	if (xkb->server->vmodmap[i]!=0)
4021ab64890Smrg	    nFound++;
4031ab64890Smrg    }
4041ab64890Smrg    req->totalVModMapKeys= nFound;
4051ab64890Smrg    return nFound*SIZEOF(xkbVModMapWireDesc);
4061ab64890Smrg}
4071ab64890Smrg
4081ab64890Smrgstatic void
4091ab64890Smrg_XkbWriteVirtualModMap(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
4101ab64890Smrg{
4111ab64890Smrgregister int		i,first,last;
4121ab64890SmrgxkbVModMapWireDesc *	wire;
4131ab64890Smrg
4141ab64890Smrg    if ((req->present&XkbVirtualModMapMask)==0)
4151ab64890Smrg	return;
4161ab64890Smrg    first= req->firstVModMapKey;
4171ab64890Smrg    last= first+req->nVModMapKeys-1;
4181ab64890Smrg    if (req->totalVModMapKeys>0) {
4191ab64890Smrg	i= req->totalVModMapKeys*SIZEOF(xkbVModMapWireDesc);
4201ab64890Smrg	BufAlloc(xkbVModMapWireDesc *,wire,i);
4211ab64890Smrg	for (i=first;i<=last;i++) {
4221ab64890Smrg	    if (xkb->server->vmodmap[i]!=0) {
4231ab64890Smrg		wire->key= i;
4241ab64890Smrg		wire->vmods= xkb->server->vmodmap[i];
4251ab64890Smrg		wire++;
4261ab64890Smrg	    }
4271ab64890Smrg	}
4281ab64890Smrg    }
4291ab64890Smrg    return;
4301ab64890Smrg}
4311ab64890Smrg
4321ab64890Smrgstatic void
4331ab64890SmrgSendSetMap(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req)
4341ab64890Smrg{
4351ab64890SmrgxkbSetMapReq tmp;
4361ab64890Smrgunsigned szMods;
4371ab64890Smrg
4381ab64890Smrg    req->length+= _XkbSizeKeyTypes(xkb,req)/4;
4391ab64890Smrg    req->length+= _XkbSizeKeySyms(xkb,req)/4;
4401ab64890Smrg    req->length+= _XkbSizeKeyActions(xkb,req)/4;
4411ab64890Smrg    req->length+= _XkbSizeKeyBehaviors(xkb,req)/4;
4421ab64890Smrg    szMods= _XkbSizeVirtualMods(req);
4431ab64890Smrg    req->length+= szMods/4;
4441ab64890Smrg    req->length+= _XkbSizeKeyExplicit(xkb,req)/4;
4451ab64890Smrg    req->length+= _XkbSizeModifierMap(xkb,req)/4;
4461ab64890Smrg    req->length+= _XkbSizeVirtualModMap(xkb,req)/4;
4471ab64890Smrg
4481ab64890Smrg    tmp= *req;
4491ab64890Smrg    if ( tmp.nTypes>0 )
4501ab64890Smrg	_XkbWriteKeyTypes(dpy,xkb,&tmp);
4511ab64890Smrg    if ( tmp.nKeySyms>0 )
4521ab64890Smrg	_XkbWriteKeySyms(dpy,xkb,&tmp);
4531ab64890Smrg    if ( tmp.nKeyActs )
4541ab64890Smrg	_XkbWriteKeyActions(dpy,xkb,&tmp);
4551ab64890Smrg    if ( tmp.totalKeyBehaviors>0 )
4561ab64890Smrg	_XkbWriteKeyBehaviors(dpy,xkb,&tmp);
4571ab64890Smrg    if ( tmp.virtualMods )
4581ab64890Smrg	_XkbWriteVirtualMods(dpy,xkb,&tmp,szMods);
4591ab64890Smrg    if ( tmp.totalKeyExplicit>0)
4601ab64890Smrg	_XkbWriteKeyExplicit(dpy,xkb,&tmp);
4611ab64890Smrg    if ( tmp.totalModMapKeys>0)
4621ab64890Smrg	_XkbWriteModifierMap(dpy,xkb,&tmp);
4631ab64890Smrg    if ( tmp.totalVModMapKeys>0)
4641ab64890Smrg	_XkbWriteVirtualModMap(dpy,xkb,&tmp);
4651ab64890Smrg    return;
4661ab64890Smrg}
4671ab64890Smrg
4681ab64890SmrgBool
4691ab64890SmrgXkbSetMap(Display *dpy,unsigned which,XkbDescPtr xkb)
4701ab64890Smrg{
4711ab64890Smrgregister xkbSetMapReq *	req;
4721ab64890SmrgXkbInfoPtr 		xkbi;
4731ab64890SmrgXkbServerMapPtr		srv;
4741ab64890SmrgXkbClientMapPtr		map;
4751ab64890Smrg
4761ab64890Smrg    if ((dpy->flags & XlibDisplayNoXkb) ||
4771ab64890Smrg	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))||
4781ab64890Smrg	(!xkb))
4791ab64890Smrg	return False;
4801ab64890Smrg    map= xkb->map;
4811ab64890Smrg    srv= xkb->server;
4821ab64890Smrg
4831ab64890Smrg    if (((which&XkbKeyTypesMask)&&((!map)||(!map->types)))||
4841ab64890Smrg	((which&XkbKeySymsMask)&&((!map)||(!map->syms)||(!map->key_sym_map)))||
4851ab64890Smrg	((which&XkbKeyActionsMask)&&((!srv)||(!srv->key_acts)))||
4861ab64890Smrg	((which&XkbKeyBehaviorsMask)&&((!srv)||(!srv->behaviors)))||
4871ab64890Smrg	((which&XkbVirtualModsMask)&&(!srv))||
4881ab64890Smrg	((which&XkbExplicitComponentsMask)&&((!srv)||(!srv->explicit)))||
4891ab64890Smrg	((which&XkbModifierMapMask)&&((!map)||(!map->modmap)))||
4901ab64890Smrg	((which&XkbVirtualModMapMask)&&((!srv)||(!srv->vmodmap))))
4911ab64890Smrg	return False;
4921ab64890Smrg
4931ab64890Smrg    LockDisplay(dpy);
4941ab64890Smrg    xkbi = dpy->xkb_info;
4951ab64890Smrg    GetReq(kbSetMap, req);
4961ab64890Smrg    req->reqType = xkbi->codes->major_opcode;
4971ab64890Smrg    req->xkbReqType = X_kbSetMap;
4981ab64890Smrg    req->deviceSpec = xkb->device_spec;
4991ab64890Smrg    req->present = which;
5001ab64890Smrg    req->flags = XkbSetMapAllFlags;
5011ab64890Smrg    req->minKeyCode= xkb->min_key_code;
5021ab64890Smrg    req->maxKeyCode= xkb->max_key_code;
5031ab64890Smrg    req->firstType = 0;
5041ab64890Smrg    if (which&XkbKeyTypesMask)	req->nTypes = map->num_types;
5051ab64890Smrg    else			req->nTypes = 0;
5061ab64890Smrg    if (which&XkbKeySymsMask) {
5071ab64890Smrg	req->firstKeySym = xkb->min_key_code;
5081ab64890Smrg	req->nKeySyms = XkbNumKeys(xkb);
5091ab64890Smrg    }
5101ab64890Smrg    if (which&XkbKeyActionsMask) {
5111ab64890Smrg	req->firstKeyAct = xkb->min_key_code;
5121ab64890Smrg	req->nKeyActs = XkbNumKeys(xkb);
5131ab64890Smrg    }
5141ab64890Smrg    if (which&XkbKeyBehaviorsMask) {
5151ab64890Smrg	req->firstKeyBehavior = xkb->min_key_code;
5161ab64890Smrg	req->nKeyBehaviors = XkbNumKeys(xkb);
5171ab64890Smrg    }
5181ab64890Smrg    if (which&XkbVirtualModsMask)
5191ab64890Smrg	req->virtualMods= ~0;
5201ab64890Smrg    if (which&XkbExplicitComponentsMask) {
5211ab64890Smrg	req->firstKeyExplicit= xkb->min_key_code;
5221ab64890Smrg	req->nKeyExplicit = XkbNumKeys(xkb);
5231ab64890Smrg    }
5241ab64890Smrg    if (which&XkbModifierMapMask) {
5251ab64890Smrg	req->firstModMapKey= xkb->min_key_code;
5261ab64890Smrg	req->nModMapKeys = XkbNumKeys(xkb);
5271ab64890Smrg    }
5281ab64890Smrg    if (which&XkbVirtualModMapMask) {
5291ab64890Smrg	req->firstVModMapKey= xkb->min_key_code;
5301ab64890Smrg	req->nVModMapKeys = XkbNumKeys(xkb);
5311ab64890Smrg    }
5321ab64890Smrg    SendSetMap(dpy,xkb,req);
5331ab64890Smrg    UnlockDisplay(dpy);
5341ab64890Smrg    SyncHandle();
5351ab64890Smrg    return True;
5361ab64890Smrg}
5371ab64890Smrg
5381ab64890SmrgBool
5391ab64890SmrgXkbChangeMap(Display *dpy,XkbDescPtr xkb,XkbMapChangesPtr changes)
5401ab64890Smrg{
5411ab64890Smrgregister xkbSetMapReq *	req;
5421ab64890SmrgXkbInfoPtr 		xkbi;
5431ab64890SmrgXkbServerMapPtr		srv;
5441ab64890SmrgXkbClientMapPtr		map;
5451ab64890Smrg
5461ab64890Smrg    if ((dpy->flags & XlibDisplayNoXkb) ||
5471ab64890Smrg	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))||
5481ab64890Smrg	(!xkb)||(!changes))
5491ab64890Smrg	return False;
5501ab64890Smrg    srv= xkb->server;
5511ab64890Smrg    map= xkb->map;
5521ab64890Smrg
5531ab64890Smrg    if (((changes->changed&XkbKeyTypesMask)&&((!map)||(!map->types)))||
5541ab64890Smrg	((changes->changed&XkbKeySymsMask)&&((!map)||(!map->syms)||
5551ab64890Smrg				(!map->key_sym_map)))||
5561ab64890Smrg	((changes->changed&XkbKeyActionsMask)&&((!srv)||(!srv->key_acts)))||
5571ab64890Smrg	((changes->changed&XkbKeyBehaviorsMask)&&((!srv)||(!srv->behaviors)))||
5581ab64890Smrg	((changes->changed&XkbVirtualModsMask)&&(!srv))||
5591ab64890Smrg	((changes->changed&XkbExplicitComponentsMask)&&
5601ab64890Smrg				((!srv)||(!srv->explicit)))||
5611ab64890Smrg	((changes->changed&XkbModifierMapMask)&&((!map)||(!map->modmap)))||
5621ab64890Smrg	((changes->changed&XkbVirtualModMapMask)&&((!srv)||(!srv->vmodmap))))
5631ab64890Smrg	return False;
5641ab64890Smrg
5651ab64890Smrg    LockDisplay(dpy);
5661ab64890Smrg    xkbi = dpy->xkb_info;
5671ab64890Smrg    GetReq(kbSetMap, req);
5681ab64890Smrg    req->reqType = xkbi->codes->major_opcode;
5691ab64890Smrg    req->xkbReqType = X_kbSetMap;
5701ab64890Smrg    req->deviceSpec = xkb->device_spec;
5711ab64890Smrg    req->present = changes->changed;
5721ab64890Smrg    req->flags = XkbSetMapRecomputeActions;
5731ab64890Smrg    req->minKeyCode= xkb->min_key_code;
5741ab64890Smrg    req->maxKeyCode= xkb->max_key_code;
5751ab64890Smrg    req->firstType = changes->first_type;
5761ab64890Smrg    req->nTypes = changes->num_types;
5771ab64890Smrg    req->firstKeySym = changes->first_key_sym;
5781ab64890Smrg    req->nKeySyms = changes->num_key_syms;
5791ab64890Smrg    req->firstKeyAct = changes->first_key_act;
5801ab64890Smrg    req->nKeyActs = changes->num_key_acts;
5811ab64890Smrg    req->firstKeyBehavior = changes->first_key_behavior;
5821ab64890Smrg    req->nKeyBehaviors = changes->num_key_behaviors;
5831ab64890Smrg    req->virtualMods = changes->vmods;
5841ab64890Smrg    req->firstKeyExplicit = changes->first_key_explicit;
5851ab64890Smrg    req->nKeyExplicit = changes->num_key_explicit;
5861ab64890Smrg    req->firstModMapKey = changes->first_modmap_key;
5871ab64890Smrg    req->nModMapKeys = changes->num_modmap_keys;
5881ab64890Smrg    req->firstVModMapKey = changes->first_vmodmap_key;
5891ab64890Smrg    req->nVModMapKeys = changes->num_vmodmap_keys;
5901ab64890Smrg    SendSetMap(dpy,xkb,req);
5911ab64890Smrg    UnlockDisplay(dpy);
5921ab64890Smrg    SyncHandle();
5931ab64890Smrg    return True;
5941ab64890Smrg}
5951ab64890Smrg
596