11ab64890Smrg/************************************************************
21ab64890SmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
31ab64890Smrg
41ab64890SmrgPermission to use, copy, modify, and distribute this
51ab64890Smrgsoftware and its documentation for any purpose and without
61ab64890Smrgfee is hereby granted, provided that the above copyright
71ab64890Smrgnotice appear in all copies and that both that copyright
81ab64890Smrgnotice and this permission notice appear in supporting
961b2299dSmrgdocumentation, and that the name of Silicon Graphics not be
1061b2299dSmrgused in advertising or publicity pertaining to distribution
111ab64890Smrgof the software without specific prior written permission.
1261b2299dSmrgSilicon Graphics makes no representation about the suitability
131ab64890Smrgof this software for any purpose. It is provided "as is"
141ab64890Smrgwithout any express or implied warranty.
151ab64890Smrg
1661b2299dSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
1761b2299dSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
181ab64890SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
1961b2299dSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
2061b2299dSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
2161b2299dSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
221ab64890SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
231ab64890SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE.
241ab64890Smrg
251ab64890Smrg********************************************************/
261ab64890Smrg
271ab64890Smrg#ifdef HAVE_CONFIG_H
281ab64890Smrg#include <config.h>
291ab64890Smrg#endif
301ab64890Smrg#include <stdio.h>
311ab64890Smrg#include "Xlibint.h"
321ab64890Smrg#include <X11/extensions/XKBproto.h>
331ab64890Smrg#include "XKBlibint.h"
341ab64890Smrg
351ab64890Smrgstatic int
36818534a1Smrg_XkbSizeKeyTypes(XkbDescPtr xkb, xkbSetMapReq *req)
371ab64890Smrg{
38818534a1Smrg    XkbKeyTypePtr map;
39818534a1Smrg    int i, len;
401ab64890Smrg
41818534a1Smrg    if (((req->present & XkbKeyTypesMask) == 0) || (req->nTypes == 0)) {
42818534a1Smrg        req->present &= ~XkbKeyTypesMask;
43818534a1Smrg        req->firstType = req->nTypes = 0;
44818534a1Smrg        return 0;
451ab64890Smrg    }
46818534a1Smrg    len = 0;
47818534a1Smrg    map = &xkb->map->types[req->firstType];
48818534a1Smrg    for (i = 0; i < req->nTypes; i++, map++) {
49818534a1Smrg        len += SIZEOF(xkbKeyTypeWireDesc);
50818534a1Smrg        len += map->map_count * SIZEOF(xkbKTSetMapEntryWireDesc);
51818534a1Smrg        if (map->preserve)
52818534a1Smrg            len += map->map_count * SIZEOF(xkbModsWireDesc);
531ab64890Smrg    }
541ab64890Smrg    return len;
551ab64890Smrg}
561ab64890Smrg
571ab64890Smrgstatic void
58818534a1Smrg_XkbWriteKeyTypes(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
591ab64890Smrg{
60818534a1Smrg    char *buf;
61818534a1Smrg    XkbKeyTypePtr type;
62818534a1Smrg    int i, n;
631ab64890Smrg    xkbKeyTypeWireDesc *desc;
641ab64890Smrg
65818534a1Smrg    if ((req->present & XkbKeyTypesMask) == 0)
66818534a1Smrg        return;
67818534a1Smrg    type = &xkb->map->types[req->firstType];
68818534a1Smrg    for (i = 0; i < req->nTypes; i++, type++) {
69818534a1Smrg        int sz = SIZEOF(xkbKeyTypeWireDesc);
70818534a1Smrg        sz += type->map_count * SIZEOF(xkbKTSetMapEntryWireDesc);
71818534a1Smrg        if (type->preserve)
72818534a1Smrg            sz += type->map_count * SIZEOF(xkbModsWireDesc);
73818534a1Smrg        BufAlloc(xkbKeyTypeWireDesc *, desc, sz);
74818534a1Smrg        desc->mask = type->mods.mask;
75818534a1Smrg        desc->realMods = type->mods.real_mods;
76818534a1Smrg        desc->virtualMods = type->mods.vmods;
77818534a1Smrg        desc->numLevels = type->num_levels;
78818534a1Smrg        desc->nMapEntries = type->map_count;
79818534a1Smrg        desc->preserve = (type->preserve != NULL);
80818534a1Smrg        buf = (char *) &desc[1];
81818534a1Smrg        if (desc->nMapEntries > 0) {
82818534a1Smrg            xkbKTSetMapEntryWireDesc *wire = (xkbKTSetMapEntryWireDesc *) buf;
83818534a1Smrg
84818534a1Smrg            for (n = 0; n < type->map_count; n++, wire++) {
85818534a1Smrg                wire->level = type->map[n].level;
86818534a1Smrg                wire->realMods = type->map[n].mods.real_mods;
87818534a1Smrg                wire->virtualMods = type->map[n].mods.vmods;
88818534a1Smrg            }
89818534a1Smrg            buf = (char *) wire;
90818534a1Smrg            if (type->preserve) {
91818534a1Smrg                xkbModsWireDesc *pwire = (xkbModsWireDesc *) buf;
92818534a1Smrg
93818534a1Smrg                for (n = 0; n < type->map_count; n++, pwire++) {
94818534a1Smrg                    pwire->realMods = type->preserve[n].real_mods;
95818534a1Smrg                    pwire->virtualMods = type->preserve[n].vmods;
96818534a1Smrg                }
97818534a1Smrg            }
98818534a1Smrg        }
991ab64890Smrg    }
1001ab64890Smrg    return;
1011ab64890Smrg}
1021ab64890Smrg
1031ab64890Smrgstatic int
104818534a1Smrg_XkbSizeKeySyms(XkbDescPtr xkb, xkbSetMapReq *req)
1051ab64890Smrg{
106818534a1Smrg    int i, len;
107818534a1Smrg    unsigned nSyms;
108818534a1Smrg
109818534a1Smrg    if (((req->present & XkbKeySymsMask) == 0) || (req->nKeySyms == 0)) {
110818534a1Smrg        req->present &= ~XkbKeySymsMask;
111818534a1Smrg        req->firstKeySym = req->nKeySyms = 0;
112818534a1Smrg        req->totalSyms = 0;
113818534a1Smrg        return 0;
1141ab64890Smrg    }
115818534a1Smrg    len = (int) (req->nKeySyms * sizeof(XkbSymMapRec));
116818534a1Smrg    for (i = nSyms = 0; i < req->nKeySyms; i++) {
117818534a1Smrg        nSyms += XkbKeyNumSyms(xkb, i + req->firstKeySym);
1181ab64890Smrg    }
119818534a1Smrg    len += nSyms * sizeof(CARD32);
120818534a1Smrg    req->totalSyms = nSyms;
1211ab64890Smrg    return len;
1221ab64890Smrg}
1231ab64890Smrg
1241ab64890Smrgstatic void
125818534a1Smrg_XkbWriteKeySyms(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
1261ab64890Smrg{
127818534a1Smrg    register KeySym *pSym;
128818534a1Smrg    CARD32 *outSym;
129818534a1Smrg    XkbSymMapPtr symMap;
130818534a1Smrg    xkbSymMapWireDesc *desc;
131818534a1Smrg    register int i;
132818534a1Smrg
133818534a1Smrg    if ((req->present & XkbKeySymsMask) == 0)
134818534a1Smrg        return;
1351ab64890Smrg    symMap = &xkb->map->key_sym_map[req->firstKeySym];
136818534a1Smrg    for (i = 0; i < req->nKeySyms; i++, symMap++) {
137818534a1Smrg        BufAlloc(xkbSymMapWireDesc *, desc,
138818534a1Smrg                 SIZEOF(xkbSymMapWireDesc) +
139818534a1Smrg                 (XkbKeyNumSyms(xkb, i + req->firstKeySym) * sizeof(CARD32)));
140818534a1Smrg        desc->ktIndex[0] = symMap->kt_index[0];
141818534a1Smrg        desc->ktIndex[1] = symMap->kt_index[1];
142818534a1Smrg        desc->ktIndex[2] = symMap->kt_index[2];
143818534a1Smrg        desc->ktIndex[3] = symMap->kt_index[3];
144818534a1Smrg        desc->groupInfo = symMap->group_info;
145818534a1Smrg        desc->width = symMap->width;
146818534a1Smrg        desc->nSyms = XkbKeyNumSyms(xkb, i + req->firstKeySym);
147818534a1Smrg        outSym = (CARD32 *) &desc[1];
148818534a1Smrg        if (desc->nSyms > 0) {
149818534a1Smrg            pSym = XkbKeySymsPtr(xkb, i + req->firstKeySym);
150818534a1Smrg            _XkbWriteCopyKeySyms(pSym, outSym, desc->nSyms);
151818534a1Smrg        }
1521ab64890Smrg    }
1531ab64890Smrg    return;
1541ab64890Smrg}
1551ab64890Smrg
1561ab64890Smrgstatic int
157818534a1Smrg_XkbSizeKeyActions(XkbDescPtr xkb, xkbSetMapReq *req)
1581ab64890Smrg{
159818534a1Smrg    int i, len, nActs;
1601ab64890Smrg
161818534a1Smrg    if (((req->present & XkbKeyActionsMask) == 0) || (req->nKeyActs == 0)) {
162818534a1Smrg        req->present &= ~XkbKeyActionsMask;
163818534a1Smrg        req->firstKeyAct = req->nKeyActs = 0;
164818534a1Smrg        req->totalActs = 0;
165818534a1Smrg        return 0;
1661ab64890Smrg    }
167818534a1Smrg    for (nActs = i = 0; i < req->nKeyActs; i++) {
168818534a1Smrg        if (xkb->server->key_acts[i + req->firstKeyAct] != 0)
169818534a1Smrg            nActs += XkbKeyNumActions(xkb, i + req->firstKeyAct);
1701ab64890Smrg    }
171818534a1Smrg    len = XkbPaddedSize(req->nKeyActs) + (nActs * SIZEOF(xkbActionWireDesc));
172818534a1Smrg    req->totalActs = nActs;
1731ab64890Smrg    return len;
1741ab64890Smrg}
1751ab64890Smrg
1761ab64890Smrgstatic void
177818534a1Smrg_XkbWriteKeyActions(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
1781ab64890Smrg{
179818534a1Smrg    register int i;
180818534a1Smrg    int n;
181818534a1Smrg    CARD8 *numDesc;
182818534a1Smrg    XkbAction *actDesc;
1831ab64890Smrg
184818534a1Smrg    if ((req->present & XkbKeyActionsMask) == 0)
185818534a1Smrg        return;
1861ab64890Smrg    n = XkbPaddedSize(req->nKeyActs);
187818534a1Smrg    n += (req->totalActs * SIZEOF(xkbActionWireDesc));
188818534a1Smrg
189818534a1Smrg    BufAlloc(CARD8 *, numDesc, n);
190818534a1Smrg    for (i = 0; i < req->nKeyActs; i++) {
191818534a1Smrg        if (xkb->server->key_acts[i + req->firstKeyAct] == 0)
192818534a1Smrg            numDesc[i] = 0;
193818534a1Smrg        else
194818534a1Smrg            numDesc[i] = XkbKeyNumActions(xkb, (i + req->firstKeyAct));
1951ab64890Smrg    }
196818534a1Smrg    actDesc = (XkbAction *) &numDesc[XkbPaddedSize(req->nKeyActs)];
197818534a1Smrg    for (i = 0; i < req->nKeyActs; i++) {
198818534a1Smrg        if (xkb->server->key_acts[i + req->firstKeyAct] != 0) {
199818534a1Smrg            n = XkbKeyNumActions(xkb, (i + req->firstKeyAct));
200818534a1Smrg            memcpy(actDesc, XkbKeyActionsPtr(xkb, (i + req->firstKeyAct)),
201818534a1Smrg                   n * SIZEOF(xkbActionWireDesc));
202818534a1Smrg            actDesc += n;
203818534a1Smrg        }
2041ab64890Smrg    }
2051ab64890Smrg    return;
2061ab64890Smrg}
2071ab64890Smrg
2081ab64890Smrgstatic int
209818534a1Smrg_XkbSizeKeyBehaviors(XkbDescPtr xkb, xkbSetMapReq *req)
2101ab64890Smrg{
211818534a1Smrg    register int i, first, last, nFound;
2121ab64890Smrg
213818534a1Smrg    if (((req->present & XkbKeyBehaviorsMask) == 0) || (req->nKeyBehaviors < 1)) {
214818534a1Smrg        req->present &= ~XkbKeyBehaviorsMask;
215818534a1Smrg        req->firstKeyBehavior = req->nKeyBehaviors = 0;
216818534a1Smrg        req->totalKeyBehaviors = 0;
217818534a1Smrg        return 0;
2181ab64890Smrg    }
219818534a1Smrg    first = req->firstKeyBehavior;
220818534a1Smrg    last = first + req->nKeyBehaviors - 1;
221818534a1Smrg    for (i = first, nFound = 0; i <= last; i++) {
222818534a1Smrg        if (xkb->server->behaviors[i].type != XkbKB_Default)
223818534a1Smrg            nFound++;
2241ab64890Smrg    }
225818534a1Smrg    req->totalKeyBehaviors = nFound;
226818534a1Smrg    return (nFound * SIZEOF(xkbBehaviorWireDesc));
2271ab64890Smrg}
2281ab64890Smrg
2291ab64890Smrgstatic void
230818534a1Smrg_XkbWriteKeyBehaviors(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
2311ab64890Smrg{
232818534a1Smrg    register int i, first, last;
233818534a1Smrg    xkbBehaviorWireDesc *wire;
234818534a1Smrg    char *buf;
235818534a1Smrg
236818534a1Smrg    if ((req->present & XkbKeyBehaviorsMask) == 0)
237818534a1Smrg        return;
238818534a1Smrg    first = req->firstKeyBehavior;
239818534a1Smrg    last = first + req->nKeyBehaviors - 1;
240818534a1Smrg
241818534a1Smrg    i = req->totalKeyBehaviors * SIZEOF(xkbBehaviorWireDesc);
242818534a1Smrg    BufAlloc(char *, buf, i);
243818534a1Smrg    wire = (xkbBehaviorWireDesc *) buf;
244818534a1Smrg    for (i = first; i <= last; i++) {
245818534a1Smrg        if (xkb->server->behaviors[i].type != XkbKB_Default) {
246818534a1Smrg            wire->key = i;
247818534a1Smrg            wire->type = xkb->server->behaviors[i].type;
248818534a1Smrg            wire->data = xkb->server->behaviors[i].data;
249818534a1Smrg            buf += SIZEOF(xkbBehaviorWireDesc);
250818534a1Smrg            wire = (xkbBehaviorWireDesc *) buf;
251818534a1Smrg        }
2521ab64890Smrg    }
2531ab64890Smrg    return;
2541ab64890Smrg}
2551ab64890Smrg
2561ab64890Smrgstatic unsigned
2571ab64890Smrg_XkbSizeVirtualMods(xkbSetMapReq *req)
2581ab64890Smrg{
259818534a1Smrg    register int i, bit, nMods;
260818534a1Smrg
261818534a1Smrg    if (((req->present & XkbVirtualModsMask) == 0) || (req->virtualMods == 0)) {
262818534a1Smrg        req->present &= ~XkbVirtualModsMask;
263818534a1Smrg        req->virtualMods = 0;
264818534a1Smrg        return 0;
265818534a1Smrg    }
266818534a1Smrg    for (i = nMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
267818534a1Smrg        if (req->virtualMods & bit)
268818534a1Smrg            nMods++;
269818534a1Smrg    }
270818534a1Smrg    return XkbPaddedSize(nMods);
2711ab64890Smrg}
2721ab64890Smrg
2731ab64890Smrgstatic void
274818534a1Smrg_XkbWriteVirtualMods(Display *dpy,
275818534a1Smrg                     XkbDescPtr xkb,
276818534a1Smrg                     xkbSetMapReq *req,
277818534a1Smrg                     unsigned size)
2781ab64890Smrg{
279818534a1Smrg    register int i, bit;
280818534a1Smrg    CARD8 *vmods;
2811ab64890Smrg
2821ab64890Smrg    /* This was req->present&XkbVirtualModsMask==0, and '==' beats '&' */
2831ab64890Smrg    if (((req->present & XkbVirtualModsMask) == 0) || (size < 1))
284818534a1Smrg        return;
285818534a1Smrg    BufAlloc(CARD8 *, vmods, size);
286818534a1Smrg    for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
287818534a1Smrg        if (req->virtualMods & bit)
288818534a1Smrg            *vmods++ = xkb->server->vmods[i];
2891ab64890Smrg    }
2901ab64890Smrg    return;
2911ab64890Smrg}
2921ab64890Smrg
2931ab64890Smrgstatic int
294818534a1Smrg_XkbSizeKeyExplicit(XkbDescPtr xkb, xkbSetMapReq *req)
2951ab64890Smrg{
296818534a1Smrg    register int i, first, last, nFound;
297818534a1Smrg
298818534a1Smrg    if (((req->present & XkbExplicitComponentsMask) == 0) ||
299818534a1Smrg        (req->nKeyExplicit == 0)) {
300818534a1Smrg        req->present &= ~XkbExplicitComponentsMask;
301818534a1Smrg        req->firstKeyExplicit = req->nKeyExplicit = 0;
302818534a1Smrg        req->totalKeyExplicit = 0;
303818534a1Smrg        return 0;
3041ab64890Smrg    }
305818534a1Smrg    first = req->firstKeyExplicit;
306818534a1Smrg    last = first + req->nKeyExplicit - 1;
3071ab64890Smrg
308818534a1Smrg    for (i = first, nFound = 0; i <= last; i++) {
309818534a1Smrg        if (xkb->server->explicit[i] != 0)
310818534a1Smrg            nFound++;
3111ab64890Smrg    }
312818534a1Smrg    req->totalKeyExplicit = nFound;
313818534a1Smrg    return XkbPaddedSize((nFound * 2));
3141ab64890Smrg}
3151ab64890Smrg
3161ab64890Smrgstatic void
317818534a1Smrg_XkbWriteKeyExplicit(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
3181ab64890Smrg{
319818534a1Smrg    register int i, first, last;
320818534a1Smrg    CARD8 *wire;
321818534a1Smrg
322818534a1Smrg    if ((req->present & XkbExplicitComponentsMask) == 0)
323818534a1Smrg        return;
324818534a1Smrg    first = req->firstKeyExplicit;
325818534a1Smrg    last = first + req->nKeyExplicit - 1;
326818534a1Smrg    i = XkbPaddedSize((req->totalKeyExplicit * 2));
327818534a1Smrg    BufAlloc(CARD8 *, wire, i);
328818534a1Smrg    for (i = first; i <= last; i++) {
329818534a1Smrg        if (xkb->server->explicit[i] != 0) {
330818534a1Smrg            wire[0] = i;
331818534a1Smrg            wire[1] = xkb->server->explicit[i];
332818534a1Smrg            wire += 2;
333818534a1Smrg        }
3341ab64890Smrg    }
3351ab64890Smrg    return;
3361ab64890Smrg}
3371ab64890Smrg
3381ab64890Smrgstatic int
339818534a1Smrg_XkbSizeModifierMap(XkbDescPtr xkb, xkbSetMapReq *req)
3401ab64890Smrg{
341818534a1Smrg    register int i, first, last, nFound;
3421ab64890Smrg
343818534a1Smrg    if (((req->present & XkbModifierMapMask) == 0) || (req->nModMapKeys == 0)) {
344818534a1Smrg        req->present &= ~XkbModifierMapMask;
345818534a1Smrg        req->firstModMapKey = req->nModMapKeys = 0;
346818534a1Smrg        req->totalModMapKeys = 0;
347818534a1Smrg        return 0;
3481ab64890Smrg    }
349818534a1Smrg    first = req->firstModMapKey;
350818534a1Smrg    last = first + req->nModMapKeys - 1;
3511ab64890Smrg
352818534a1Smrg    for (i = first, nFound = 0; i <= last; i++) {
353818534a1Smrg        if (xkb->map->modmap[i] != 0)
354818534a1Smrg            nFound++;
3551ab64890Smrg    }
356818534a1Smrg    req->totalModMapKeys = nFound;
357818534a1Smrg    return XkbPaddedSize((nFound * 2));
3581ab64890Smrg}
3591ab64890Smrg
3601ab64890Smrgstatic void
361818534a1Smrg_XkbWriteModifierMap(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
3621ab64890Smrg{
363818534a1Smrg    register int i, first, last;
364818534a1Smrg    CARD8 *wire;
365818534a1Smrg
366818534a1Smrg    if ((req->present & XkbModifierMapMask) == 0)
367818534a1Smrg        return;
368818534a1Smrg    first = req->firstModMapKey;
369818534a1Smrg    last = first + req->nModMapKeys - 1;
370818534a1Smrg    if (req->totalModMapKeys > 0) {
371818534a1Smrg        i = XkbPaddedSize((req->totalModMapKeys * 2));
372818534a1Smrg        BufAlloc(CARD8 *, wire, i);
373818534a1Smrg
374818534a1Smrg        for (i = first; i <= last; i++) {
375818534a1Smrg            if (xkb->map->modmap[i] != 0) {
376818534a1Smrg                wire[0] = i;
377818534a1Smrg                wire[1] = xkb->map->modmap[i];
378818534a1Smrg                wire += 2;
379818534a1Smrg            }
380818534a1Smrg        }
3811ab64890Smrg    }
3821ab64890Smrg    return;
3831ab64890Smrg}
3841ab64890Smrg
3851ab64890Smrgstatic int
386818534a1Smrg_XkbSizeVirtualModMap(XkbDescPtr xkb, xkbSetMapReq *req)
3871ab64890Smrg{
388818534a1Smrg    register int i, first, last, nFound;
389818534a1Smrg
390818534a1Smrg    if (((req->present & XkbVirtualModMapMask) == 0) ||
391818534a1Smrg        (req->nVModMapKeys == 0)) {
392818534a1Smrg        req->present &= ~XkbVirtualModMapMask;
393818534a1Smrg        req->firstVModMapKey = req->nVModMapKeys = 0;
394818534a1Smrg        req->totalVModMapKeys = 0;
395818534a1Smrg        return 0;
3961ab64890Smrg    }
397818534a1Smrg    first = req->firstVModMapKey;
398818534a1Smrg    last = first + req->nVModMapKeys - 1;
3991ab64890Smrg
400818534a1Smrg    for (i = first, nFound = 0; i <= last; i++) {
401818534a1Smrg        if (xkb->server->vmodmap[i] != 0)
402818534a1Smrg            nFound++;
4031ab64890Smrg    }
404818534a1Smrg    req->totalVModMapKeys = nFound;
405818534a1Smrg    return nFound * SIZEOF(xkbVModMapWireDesc);
4061ab64890Smrg}
4071ab64890Smrg
4081ab64890Smrgstatic void
409818534a1Smrg_XkbWriteVirtualModMap(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
4101ab64890Smrg{
411818534a1Smrg    register int i, first, last;
412818534a1Smrg    xkbVModMapWireDesc *wire;
413818534a1Smrg
414818534a1Smrg    if ((req->present & XkbVirtualModMapMask) == 0)
415818534a1Smrg        return;
416818534a1Smrg    first = req->firstVModMapKey;
417818534a1Smrg    last = first + req->nVModMapKeys - 1;
418818534a1Smrg    if (req->totalVModMapKeys > 0) {
419818534a1Smrg        i = req->totalVModMapKeys * SIZEOF(xkbVModMapWireDesc);
420818534a1Smrg        BufAlloc(xkbVModMapWireDesc *, wire, i);
421818534a1Smrg        for (i = first; i <= last; i++) {
422818534a1Smrg            if (xkb->server->vmodmap[i] != 0) {
423818534a1Smrg                wire->key = i;
424818534a1Smrg                wire->vmods = xkb->server->vmodmap[i];
425818534a1Smrg                wire++;
426818534a1Smrg            }
427818534a1Smrg        }
4281ab64890Smrg    }
4291ab64890Smrg    return;
4301ab64890Smrg}
4311ab64890Smrg
4321ab64890Smrgstatic void
433818534a1SmrgSendSetMap(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
4341ab64890Smrg{
435818534a1Smrg    xkbSetMapReq tmp;
436818534a1Smrg    unsigned szMods;
437818534a1Smrg
438818534a1Smrg    req->length += _XkbSizeKeyTypes(xkb, req) / 4;
439818534a1Smrg    req->length += _XkbSizeKeySyms(xkb, req) / 4;
440818534a1Smrg    req->length += _XkbSizeKeyActions(xkb, req) / 4;
441818534a1Smrg    req->length += _XkbSizeKeyBehaviors(xkb, req) / 4;
442818534a1Smrg    szMods = _XkbSizeVirtualMods(req);
443818534a1Smrg    req->length += szMods / 4;
444818534a1Smrg    req->length += _XkbSizeKeyExplicit(xkb, req) / 4;
445818534a1Smrg    req->length += _XkbSizeModifierMap(xkb, req) / 4;
446818534a1Smrg    req->length += _XkbSizeVirtualModMap(xkb, req) / 4;
447818534a1Smrg
448818534a1Smrg    tmp = *req;
449818534a1Smrg    if (tmp.nTypes > 0)
450818534a1Smrg        _XkbWriteKeyTypes(dpy, xkb, &tmp);
451818534a1Smrg    if (tmp.nKeySyms > 0)
452818534a1Smrg        _XkbWriteKeySyms(dpy, xkb, &tmp);
453818534a1Smrg    if (tmp.nKeyActs)
454818534a1Smrg        _XkbWriteKeyActions(dpy, xkb, &tmp);
455818534a1Smrg    if (tmp.totalKeyBehaviors > 0)
456818534a1Smrg        _XkbWriteKeyBehaviors(dpy, xkb, &tmp);
457818534a1Smrg    if (tmp.virtualMods)
458818534a1Smrg        _XkbWriteVirtualMods(dpy, xkb, &tmp, szMods);
459818534a1Smrg    if (tmp.totalKeyExplicit > 0)
460818534a1Smrg        _XkbWriteKeyExplicit(dpy, xkb, &tmp);
461818534a1Smrg    if (tmp.totalModMapKeys > 0)
462818534a1Smrg        _XkbWriteModifierMap(dpy, xkb, &tmp);
463818534a1Smrg    if (tmp.totalVModMapKeys > 0)
464818534a1Smrg        _XkbWriteVirtualModMap(dpy, xkb, &tmp);
4651ab64890Smrg    return;
4661ab64890Smrg}
4671ab64890Smrg
4681ab64890SmrgBool
469818534a1SmrgXkbSetMap(Display *dpy, unsigned which, XkbDescPtr xkb)
4701ab64890Smrg{
471818534a1Smrg    register xkbSetMapReq *req;
472818534a1Smrg    XkbInfoPtr xkbi;
473818534a1Smrg    XkbServerMapPtr srv;
474818534a1Smrg    XkbClientMapPtr map;
4751ab64890Smrg
4761ab64890Smrg    if ((dpy->flags & XlibDisplayNoXkb) ||
477818534a1Smrg        (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)) || (!xkb))
478818534a1Smrg        return False;
479818534a1Smrg    map = xkb->map;
480818534a1Smrg    srv = xkb->server;
481818534a1Smrg
482818534a1Smrg    if (((which & XkbKeyTypesMask) && ((!map) || (!map->types))) ||
483818534a1Smrg        ((which & XkbKeySymsMask) &&
484818534a1Smrg         ((!map) || (!map->syms) || (!map->key_sym_map))) ||
485818534a1Smrg        ((which & XkbKeyActionsMask) && ((!srv) || (!srv->key_acts))) ||
486818534a1Smrg        ((which & XkbKeyBehaviorsMask) && ((!srv) || (!srv->behaviors))) ||
487818534a1Smrg        ((which & XkbVirtualModsMask) && (!srv)) ||
488818534a1Smrg        ((which & XkbExplicitComponentsMask) && ((!srv) || (!srv->explicit))) ||
489818534a1Smrg        ((which & XkbModifierMapMask) && ((!map) || (!map->modmap))) ||
490818534a1Smrg        ((which & XkbVirtualModMapMask) && ((!srv) || (!srv->vmodmap))))
491818534a1Smrg        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;
501818534a1Smrg    req->minKeyCode = xkb->min_key_code;
502818534a1Smrg    req->maxKeyCode = xkb->max_key_code;
5031ab64890Smrg    req->firstType = 0;
504818534a1Smrg    if (which & XkbKeyTypesMask)
505818534a1Smrg        req->nTypes = map->num_types;
506818534a1Smrg    else
507818534a1Smrg        req->nTypes = 0;
508818534a1Smrg    if (which & XkbKeySymsMask) {
509818534a1Smrg        req->firstKeySym = xkb->min_key_code;
510818534a1Smrg        req->nKeySyms = XkbNumKeys(xkb);
5111ab64890Smrg    }
512818534a1Smrg    if (which & XkbKeyActionsMask) {
513818534a1Smrg        req->firstKeyAct = xkb->min_key_code;
514818534a1Smrg        req->nKeyActs = XkbNumKeys(xkb);
5151ab64890Smrg    }
516818534a1Smrg    if (which & XkbKeyBehaviorsMask) {
517818534a1Smrg        req->firstKeyBehavior = xkb->min_key_code;
518818534a1Smrg        req->nKeyBehaviors = XkbNumKeys(xkb);
5191ab64890Smrg    }
520818534a1Smrg    if (which & XkbVirtualModsMask)
521818534a1Smrg        req->virtualMods = ~0;
522818534a1Smrg    if (which & XkbExplicitComponentsMask) {
523818534a1Smrg        req->firstKeyExplicit = xkb->min_key_code;
524818534a1Smrg        req->nKeyExplicit = XkbNumKeys(xkb);
5251ab64890Smrg    }
526818534a1Smrg    if (which & XkbModifierMapMask) {
527818534a1Smrg        req->firstModMapKey = xkb->min_key_code;
528818534a1Smrg        req->nModMapKeys = XkbNumKeys(xkb);
5291ab64890Smrg    }
530818534a1Smrg    if (which & XkbVirtualModMapMask) {
531818534a1Smrg        req->firstVModMapKey = xkb->min_key_code;
532818534a1Smrg        req->nVModMapKeys = XkbNumKeys(xkb);
5331ab64890Smrg    }
534818534a1Smrg    SendSetMap(dpy, xkb, req);
5351ab64890Smrg    UnlockDisplay(dpy);
5361ab64890Smrg    SyncHandle();
5371ab64890Smrg    return True;
5381ab64890Smrg}
5391ab64890Smrg
5401ab64890SmrgBool
541818534a1SmrgXkbChangeMap(Display *dpy, XkbDescPtr xkb, XkbMapChangesPtr changes)
5421ab64890Smrg{
543818534a1Smrg    register xkbSetMapReq *req;
544818534a1Smrg    XkbInfoPtr xkbi;
545818534a1Smrg    XkbServerMapPtr srv;
546818534a1Smrg    XkbClientMapPtr map;
5471ab64890Smrg
5481ab64890Smrg    if ((dpy->flags & XlibDisplayNoXkb) ||
549818534a1Smrg        (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)) ||
550818534a1Smrg        (!xkb) || (!changes))
551818534a1Smrg        return False;
552818534a1Smrg    srv = xkb->server;
553818534a1Smrg    map = xkb->map;
554818534a1Smrg
555818534a1Smrg    if (((changes->changed & XkbKeyTypesMask) && ((!map) || (!map->types))) ||
556818534a1Smrg        ((changes->changed & XkbKeySymsMask) && ((!map) || (!map->syms) ||
557818534a1Smrg                                                 (!map->key_sym_map))) ||
558818534a1Smrg        ((changes->changed & XkbKeyActionsMask) && ((!srv) || (!srv->key_acts)))
559818534a1Smrg        || ((changes->changed & XkbKeyBehaviorsMask) &&
560818534a1Smrg            ((!srv) || (!srv->behaviors))) ||
561818534a1Smrg        ((changes->changed & XkbVirtualModsMask) && (!srv)) ||
562818534a1Smrg        ((changes->changed & XkbExplicitComponentsMask) &&
563818534a1Smrg         ((!srv) || (!srv->explicit))) ||
564818534a1Smrg        ((changes->changed & XkbModifierMapMask) && ((!map) || (!map->modmap)))
565818534a1Smrg        || ((changes->changed & XkbVirtualModMapMask) &&
566818534a1Smrg            ((!srv) || (!srv->vmodmap))))
567818534a1Smrg        return False;
5681ab64890Smrg
5691ab64890Smrg    LockDisplay(dpy);
5701ab64890Smrg    xkbi = dpy->xkb_info;
5711ab64890Smrg    GetReq(kbSetMap, req);
5721ab64890Smrg    req->reqType = xkbi->codes->major_opcode;
5731ab64890Smrg    req->xkbReqType = X_kbSetMap;
5741ab64890Smrg    req->deviceSpec = xkb->device_spec;
5751ab64890Smrg    req->present = changes->changed;
5761ab64890Smrg    req->flags = XkbSetMapRecomputeActions;
577818534a1Smrg    req->minKeyCode = xkb->min_key_code;
578818534a1Smrg    req->maxKeyCode = xkb->max_key_code;
5791ab64890Smrg    req->firstType = changes->first_type;
5801ab64890Smrg    req->nTypes = changes->num_types;
5811ab64890Smrg    req->firstKeySym = changes->first_key_sym;
5821ab64890Smrg    req->nKeySyms = changes->num_key_syms;
5831ab64890Smrg    req->firstKeyAct = changes->first_key_act;
5841ab64890Smrg    req->nKeyActs = changes->num_key_acts;
5851ab64890Smrg    req->firstKeyBehavior = changes->first_key_behavior;
5861ab64890Smrg    req->nKeyBehaviors = changes->num_key_behaviors;
5871ab64890Smrg    req->virtualMods = changes->vmods;
5881ab64890Smrg    req->firstKeyExplicit = changes->first_key_explicit;
5891ab64890Smrg    req->nKeyExplicit = changes->num_key_explicit;
5901ab64890Smrg    req->firstModMapKey = changes->first_modmap_key;
5911ab64890Smrg    req->nModMapKeys = changes->num_modmap_keys;
5921ab64890Smrg    req->firstVModMapKey = changes->first_vmodmap_key;
5931ab64890Smrg    req->nVModMapKeys = changes->num_vmodmap_keys;
594818534a1Smrg    SendSetMap(dpy, xkb, req);
5951ab64890Smrg    UnlockDisplay(dpy);
5961ab64890Smrg    SyncHandle();
5971ab64890Smrg    return True;
5981ab64890Smrg}
599