1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
15
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25 ********************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30 #include <stdio.h>
31 #include "Xlibint.h"
32 #include <X11/extensions/XKBproto.h>
33 #include "XKBlibint.h"
34
35 static int
_XkbSizeKeyTypes(XkbDescPtr xkb,xkbSetMapReq * req)36 _XkbSizeKeyTypes(XkbDescPtr xkb, xkbSetMapReq *req)
37 {
38 XkbKeyTypePtr map;
39 int i, len;
40
41 if (((req->present & XkbKeyTypesMask) == 0) || (req->nTypes == 0)) {
42 req->present &= ~XkbKeyTypesMask;
43 req->firstType = req->nTypes = 0;
44 return 0;
45 }
46 len = 0;
47 map = &xkb->map->types[req->firstType];
48 for (i = 0; i < req->nTypes; i++, map++) {
49 len += SIZEOF(xkbKeyTypeWireDesc);
50 len += map->map_count * SIZEOF(xkbKTSetMapEntryWireDesc);
51 if (map->preserve)
52 len += map->map_count * SIZEOF(xkbModsWireDesc);
53 }
54 return len;
55 }
56
57 static void
_XkbWriteKeyTypes(Display * dpy,XkbDescPtr xkb,xkbSetMapReq * req)58 _XkbWriteKeyTypes(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
59 {
60 char *buf;
61 XkbKeyTypePtr type;
62 int i, n;
63 xkbKeyTypeWireDesc *desc;
64
65 if ((req->present & XkbKeyTypesMask) == 0)
66 return;
67 type = &xkb->map->types[req->firstType];
68 for (i = 0; i < req->nTypes; i++, type++) {
69 int sz = SIZEOF(xkbKeyTypeWireDesc);
70 sz += type->map_count * SIZEOF(xkbKTSetMapEntryWireDesc);
71 if (type->preserve)
72 sz += type->map_count * SIZEOF(xkbModsWireDesc);
73 BufAlloc(xkbKeyTypeWireDesc *, desc, sz);
74 desc->mask = type->mods.mask;
75 desc->realMods = type->mods.real_mods;
76 desc->virtualMods = type->mods.vmods;
77 desc->numLevels = type->num_levels;
78 desc->nMapEntries = type->map_count;
79 desc->preserve = (type->preserve != NULL);
80 buf = (char *) &desc[1];
81 if (desc->nMapEntries > 0) {
82 xkbKTSetMapEntryWireDesc *wire = (xkbKTSetMapEntryWireDesc *) buf;
83
84 for (n = 0; n < type->map_count; n++, wire++) {
85 wire->level = type->map[n].level;
86 wire->realMods = type->map[n].mods.real_mods;
87 wire->virtualMods = type->map[n].mods.vmods;
88 }
89 buf = (char *) wire;
90 if (type->preserve) {
91 xkbModsWireDesc *pwire = (xkbModsWireDesc *) buf;
92
93 for (n = 0; n < type->map_count; n++, pwire++) {
94 pwire->realMods = type->preserve[n].real_mods;
95 pwire->virtualMods = type->preserve[n].vmods;
96 }
97 }
98 }
99 }
100 return;
101 }
102
103 static int
_XkbSizeKeySyms(XkbDescPtr xkb,xkbSetMapReq * req)104 _XkbSizeKeySyms(XkbDescPtr xkb, xkbSetMapReq *req)
105 {
106 int i, len;
107 unsigned nSyms;
108
109 if (((req->present & XkbKeySymsMask) == 0) || (req->nKeySyms == 0)) {
110 req->present &= ~XkbKeySymsMask;
111 req->firstKeySym = req->nKeySyms = 0;
112 req->totalSyms = 0;
113 return 0;
114 }
115 len = (int) (req->nKeySyms * sizeof(XkbSymMapRec));
116 for (i = nSyms = 0; i < req->nKeySyms; i++) {
117 nSyms += XkbKeyNumSyms(xkb, i + req->firstKeySym);
118 }
119 len += nSyms * sizeof(CARD32);
120 req->totalSyms = nSyms;
121 return len;
122 }
123
124 static void
_XkbWriteKeySyms(Display * dpy,XkbDescPtr xkb,xkbSetMapReq * req)125 _XkbWriteKeySyms(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
126 {
127 register KeySym *pSym;
128 CARD32 *outSym;
129 XkbSymMapPtr symMap;
130 xkbSymMapWireDesc *desc;
131 register int i;
132
133 if ((req->present & XkbKeySymsMask) == 0)
134 return;
135 symMap = &xkb->map->key_sym_map[req->firstKeySym];
136 for (i = 0; i < req->nKeySyms; i++, symMap++) {
137 BufAlloc(xkbSymMapWireDesc *, desc,
138 SIZEOF(xkbSymMapWireDesc) +
139 (XkbKeyNumSyms(xkb, i + req->firstKeySym) * sizeof(CARD32)));
140 desc->ktIndex[0] = symMap->kt_index[0];
141 desc->ktIndex[1] = symMap->kt_index[1];
142 desc->ktIndex[2] = symMap->kt_index[2];
143 desc->ktIndex[3] = symMap->kt_index[3];
144 desc->groupInfo = symMap->group_info;
145 desc->width = symMap->width;
146 desc->nSyms = XkbKeyNumSyms(xkb, i + req->firstKeySym);
147 outSym = (CARD32 *) &desc[1];
148 if (desc->nSyms > 0) {
149 pSym = XkbKeySymsPtr(xkb, i + req->firstKeySym);
150 _XkbWriteCopyKeySyms(pSym, outSym, desc->nSyms);
151 }
152 }
153 return;
154 }
155
156 static int
_XkbSizeKeyActions(XkbDescPtr xkb,xkbSetMapReq * req)157 _XkbSizeKeyActions(XkbDescPtr xkb, xkbSetMapReq *req)
158 {
159 int i, len, nActs;
160
161 if (((req->present & XkbKeyActionsMask) == 0) || (req->nKeyActs == 0)) {
162 req->present &= ~XkbKeyActionsMask;
163 req->firstKeyAct = req->nKeyActs = 0;
164 req->totalActs = 0;
165 return 0;
166 }
167 for (nActs = i = 0; i < req->nKeyActs; i++) {
168 if (xkb->server->key_acts[i + req->firstKeyAct] != 0)
169 nActs += XkbKeyNumActions(xkb, i + req->firstKeyAct);
170 }
171 len = XkbPaddedSize(req->nKeyActs) + (nActs * SIZEOF(xkbActionWireDesc));
172 req->totalActs = nActs;
173 return len;
174 }
175
176 static void
_XkbWriteKeyActions(Display * dpy,XkbDescPtr xkb,xkbSetMapReq * req)177 _XkbWriteKeyActions(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
178 {
179 register int i;
180 int n;
181 CARD8 *numDesc;
182 XkbAction *actDesc;
183
184 if ((req->present & XkbKeyActionsMask) == 0)
185 return;
186 n = XkbPaddedSize(req->nKeyActs);
187 n += (req->totalActs * SIZEOF(xkbActionWireDesc));
188
189 BufAlloc(CARD8 *, numDesc, n);
190 for (i = 0; i < req->nKeyActs; i++) {
191 if (xkb->server->key_acts[i + req->firstKeyAct] == 0)
192 numDesc[i] = 0;
193 else
194 numDesc[i] = XkbKeyNumActions(xkb, (i + req->firstKeyAct));
195 }
196 actDesc = (XkbAction *) &numDesc[XkbPaddedSize(req->nKeyActs)];
197 for (i = 0; i < req->nKeyActs; i++) {
198 if (xkb->server->key_acts[i + req->firstKeyAct] != 0) {
199 n = XkbKeyNumActions(xkb, (i + req->firstKeyAct));
200 memcpy(actDesc, XkbKeyActionsPtr(xkb, (i + req->firstKeyAct)),
201 n * SIZEOF(xkbActionWireDesc));
202 actDesc += n;
203 }
204 }
205 return;
206 }
207
208 static int
_XkbSizeKeyBehaviors(XkbDescPtr xkb,xkbSetMapReq * req)209 _XkbSizeKeyBehaviors(XkbDescPtr xkb, xkbSetMapReq *req)
210 {
211 register int i, first, last, nFound;
212
213 if (((req->present & XkbKeyBehaviorsMask) == 0) || (req->nKeyBehaviors < 1)) {
214 req->present &= ~XkbKeyBehaviorsMask;
215 req->firstKeyBehavior = req->nKeyBehaviors = 0;
216 req->totalKeyBehaviors = 0;
217 return 0;
218 }
219 first = req->firstKeyBehavior;
220 last = first + req->nKeyBehaviors - 1;
221 for (i = first, nFound = 0; i <= last; i++) {
222 if (xkb->server->behaviors[i].type != XkbKB_Default)
223 nFound++;
224 }
225 req->totalKeyBehaviors = nFound;
226 return (nFound * SIZEOF(xkbBehaviorWireDesc));
227 }
228
229 static void
_XkbWriteKeyBehaviors(Display * dpy,XkbDescPtr xkb,xkbSetMapReq * req)230 _XkbWriteKeyBehaviors(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
231 {
232 register int i, first, last;
233 xkbBehaviorWireDesc *wire;
234 char *buf;
235
236 if ((req->present & XkbKeyBehaviorsMask) == 0)
237 return;
238 first = req->firstKeyBehavior;
239 last = first + req->nKeyBehaviors - 1;
240
241 i = req->totalKeyBehaviors * SIZEOF(xkbBehaviorWireDesc);
242 BufAlloc(char *, buf, i);
243 wire = (xkbBehaviorWireDesc *) buf;
244 for (i = first; i <= last; i++) {
245 if (xkb->server->behaviors[i].type != XkbKB_Default) {
246 wire->key = i;
247 wire->type = xkb->server->behaviors[i].type;
248 wire->data = xkb->server->behaviors[i].data;
249 buf += SIZEOF(xkbBehaviorWireDesc);
250 wire = (xkbBehaviorWireDesc *) buf;
251 }
252 }
253 return;
254 }
255
256 static unsigned
_XkbSizeVirtualMods(xkbSetMapReq * req)257 _XkbSizeVirtualMods(xkbSetMapReq *req)
258 {
259 register int i, bit, nMods;
260
261 if (((req->present & XkbVirtualModsMask) == 0) || (req->virtualMods == 0)) {
262 req->present &= ~XkbVirtualModsMask;
263 req->virtualMods = 0;
264 return 0;
265 }
266 for (i = nMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
267 if (req->virtualMods & bit)
268 nMods++;
269 }
270 return XkbPaddedSize(nMods);
271 }
272
273 static void
_XkbWriteVirtualMods(Display * dpy,XkbDescPtr xkb,xkbSetMapReq * req,unsigned size)274 _XkbWriteVirtualMods(Display *dpy,
275 XkbDescPtr xkb,
276 xkbSetMapReq *req,
277 unsigned size)
278 {
279 register int i, bit;
280 CARD8 *vmods;
281
282 /* This was req->present&XkbVirtualModsMask==0, and '==' beats '&' */
283 if (((req->present & XkbVirtualModsMask) == 0) || (size < 1))
284 return;
285 BufAlloc(CARD8 *, vmods, size);
286 for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
287 if (req->virtualMods & bit)
288 *vmods++ = xkb->server->vmods[i];
289 }
290 return;
291 }
292
293 static int
_XkbSizeKeyExplicit(XkbDescPtr xkb,xkbSetMapReq * req)294 _XkbSizeKeyExplicit(XkbDescPtr xkb, xkbSetMapReq *req)
295 {
296 register int i, first, last, nFound;
297
298 if (((req->present & XkbExplicitComponentsMask) == 0) ||
299 (req->nKeyExplicit == 0)) {
300 req->present &= ~XkbExplicitComponentsMask;
301 req->firstKeyExplicit = req->nKeyExplicit = 0;
302 req->totalKeyExplicit = 0;
303 return 0;
304 }
305 first = req->firstKeyExplicit;
306 last = first + req->nKeyExplicit - 1;
307
308 for (i = first, nFound = 0; i <= last; i++) {
309 if (xkb->server->explicit[i] != 0)
310 nFound++;
311 }
312 req->totalKeyExplicit = nFound;
313 return XkbPaddedSize((nFound * 2));
314 }
315
316 static void
_XkbWriteKeyExplicit(Display * dpy,XkbDescPtr xkb,xkbSetMapReq * req)317 _XkbWriteKeyExplicit(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
318 {
319 register int i, first, last;
320 CARD8 *wire;
321
322 if ((req->present & XkbExplicitComponentsMask) == 0)
323 return;
324 first = req->firstKeyExplicit;
325 last = first + req->nKeyExplicit - 1;
326 i = XkbPaddedSize((req->totalKeyExplicit * 2));
327 BufAlloc(CARD8 *, wire, i);
328 for (i = first; i <= last; i++) {
329 if (xkb->server->explicit[i] != 0) {
330 wire[0] = i;
331 wire[1] = xkb->server->explicit[i];
332 wire += 2;
333 }
334 }
335 return;
336 }
337
338 static int
_XkbSizeModifierMap(XkbDescPtr xkb,xkbSetMapReq * req)339 _XkbSizeModifierMap(XkbDescPtr xkb, xkbSetMapReq *req)
340 {
341 register int i, first, last, nFound;
342
343 if (((req->present & XkbModifierMapMask) == 0) || (req->nModMapKeys == 0)) {
344 req->present &= ~XkbModifierMapMask;
345 req->firstModMapKey = req->nModMapKeys = 0;
346 req->totalModMapKeys = 0;
347 return 0;
348 }
349 first = req->firstModMapKey;
350 last = first + req->nModMapKeys - 1;
351
352 for (i = first, nFound = 0; i <= last; i++) {
353 if (xkb->map->modmap[i] != 0)
354 nFound++;
355 }
356 req->totalModMapKeys = nFound;
357 return XkbPaddedSize((nFound * 2));
358 }
359
360 static void
_XkbWriteModifierMap(Display * dpy,XkbDescPtr xkb,xkbSetMapReq * req)361 _XkbWriteModifierMap(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
362 {
363 register int i, first, last;
364 CARD8 *wire;
365
366 if ((req->present & XkbModifierMapMask) == 0)
367 return;
368 first = req->firstModMapKey;
369 last = first + req->nModMapKeys - 1;
370 if (req->totalModMapKeys > 0) {
371 i = XkbPaddedSize((req->totalModMapKeys * 2));
372 BufAlloc(CARD8 *, wire, i);
373
374 for (i = first; i <= last; i++) {
375 if (xkb->map->modmap[i] != 0) {
376 wire[0] = i;
377 wire[1] = xkb->map->modmap[i];
378 wire += 2;
379 }
380 }
381 }
382 return;
383 }
384
385 static int
_XkbSizeVirtualModMap(XkbDescPtr xkb,xkbSetMapReq * req)386 _XkbSizeVirtualModMap(XkbDescPtr xkb, xkbSetMapReq *req)
387 {
388 register int i, first, last, nFound;
389
390 if (((req->present & XkbVirtualModMapMask) == 0) ||
391 (req->nVModMapKeys == 0)) {
392 req->present &= ~XkbVirtualModMapMask;
393 req->firstVModMapKey = req->nVModMapKeys = 0;
394 req->totalVModMapKeys = 0;
395 return 0;
396 }
397 first = req->firstVModMapKey;
398 last = first + req->nVModMapKeys - 1;
399
400 for (i = first, nFound = 0; i <= last; i++) {
401 if (xkb->server->vmodmap[i] != 0)
402 nFound++;
403 }
404 req->totalVModMapKeys = nFound;
405 return nFound * SIZEOF(xkbVModMapWireDesc);
406 }
407
408 static void
_XkbWriteVirtualModMap(Display * dpy,XkbDescPtr xkb,xkbSetMapReq * req)409 _XkbWriteVirtualModMap(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
410 {
411 register int i, first, last;
412 xkbVModMapWireDesc *wire;
413
414 if ((req->present & XkbVirtualModMapMask) == 0)
415 return;
416 first = req->firstVModMapKey;
417 last = first + req->nVModMapKeys - 1;
418 if (req->totalVModMapKeys > 0) {
419 i = req->totalVModMapKeys * SIZEOF(xkbVModMapWireDesc);
420 BufAlloc(xkbVModMapWireDesc *, wire, i);
421 for (i = first; i <= last; i++) {
422 if (xkb->server->vmodmap[i] != 0) {
423 wire->key = i;
424 wire->vmods = xkb->server->vmodmap[i];
425 wire++;
426 }
427 }
428 }
429 return;
430 }
431
432 static void
SendSetMap(Display * dpy,XkbDescPtr xkb,xkbSetMapReq * req)433 SendSetMap(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req)
434 {
435 xkbSetMapReq tmp;
436 unsigned szMods;
437
438 req->length += _XkbSizeKeyTypes(xkb, req) / 4;
439 req->length += _XkbSizeKeySyms(xkb, req) / 4;
440 req->length += _XkbSizeKeyActions(xkb, req) / 4;
441 req->length += _XkbSizeKeyBehaviors(xkb, req) / 4;
442 szMods = _XkbSizeVirtualMods(req);
443 req->length += szMods / 4;
444 req->length += _XkbSizeKeyExplicit(xkb, req) / 4;
445 req->length += _XkbSizeModifierMap(xkb, req) / 4;
446 req->length += _XkbSizeVirtualModMap(xkb, req) / 4;
447
448 tmp = *req;
449 if (tmp.nTypes > 0)
450 _XkbWriteKeyTypes(dpy, xkb, &tmp);
451 if (tmp.nKeySyms > 0)
452 _XkbWriteKeySyms(dpy, xkb, &tmp);
453 if (tmp.nKeyActs)
454 _XkbWriteKeyActions(dpy, xkb, &tmp);
455 if (tmp.totalKeyBehaviors > 0)
456 _XkbWriteKeyBehaviors(dpy, xkb, &tmp);
457 if (tmp.virtualMods)
458 _XkbWriteVirtualMods(dpy, xkb, &tmp, szMods);
459 if (tmp.totalKeyExplicit > 0)
460 _XkbWriteKeyExplicit(dpy, xkb, &tmp);
461 if (tmp.totalModMapKeys > 0)
462 _XkbWriteModifierMap(dpy, xkb, &tmp);
463 if (tmp.totalVModMapKeys > 0)
464 _XkbWriteVirtualModMap(dpy, xkb, &tmp);
465 return;
466 }
467
468 Bool
XkbSetMap(Display * dpy,unsigned which,XkbDescPtr xkb)469 XkbSetMap(Display *dpy, unsigned which, XkbDescPtr xkb)
470 {
471 register xkbSetMapReq *req;
472 XkbInfoPtr xkbi;
473 XkbServerMapPtr srv;
474 XkbClientMapPtr map;
475
476 if ((dpy->flags & XlibDisplayNoXkb) ||
477 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)) || (!xkb))
478 return False;
479 map = xkb->map;
480 srv = xkb->server;
481
482 if (((which & XkbKeyTypesMask) && ((!map) || (!map->types))) ||
483 ((which & XkbKeySymsMask) &&
484 ((!map) || (!map->syms) || (!map->key_sym_map))) ||
485 ((which & XkbKeyActionsMask) && ((!srv) || (!srv->key_acts))) ||
486 ((which & XkbKeyBehaviorsMask) && ((!srv) || (!srv->behaviors))) ||
487 ((which & XkbVirtualModsMask) && (!srv)) ||
488 ((which & XkbExplicitComponentsMask) && ((!srv) || (!srv->explicit))) ||
489 ((which & XkbModifierMapMask) && ((!map) || (!map->modmap))) ||
490 ((which & XkbVirtualModMapMask) && ((!srv) || (!srv->vmodmap))))
491 return False;
492
493 LockDisplay(dpy);
494 xkbi = dpy->xkb_info;
495 GetReq(kbSetMap, req);
496 req->reqType = xkbi->codes->major_opcode;
497 req->xkbReqType = X_kbSetMap;
498 req->deviceSpec = xkb->device_spec;
499 req->present = which;
500 req->flags = XkbSetMapAllFlags;
501 req->minKeyCode = xkb->min_key_code;
502 req->maxKeyCode = xkb->max_key_code;
503 req->firstType = 0;
504 if (which & XkbKeyTypesMask)
505 req->nTypes = map->num_types;
506 else
507 req->nTypes = 0;
508 if (which & XkbKeySymsMask) {
509 req->firstKeySym = xkb->min_key_code;
510 req->nKeySyms = XkbNumKeys(xkb);
511 }
512 if (which & XkbKeyActionsMask) {
513 req->firstKeyAct = xkb->min_key_code;
514 req->nKeyActs = XkbNumKeys(xkb);
515 }
516 if (which & XkbKeyBehaviorsMask) {
517 req->firstKeyBehavior = xkb->min_key_code;
518 req->nKeyBehaviors = XkbNumKeys(xkb);
519 }
520 if (which & XkbVirtualModsMask)
521 req->virtualMods = ~0;
522 if (which & XkbExplicitComponentsMask) {
523 req->firstKeyExplicit = xkb->min_key_code;
524 req->nKeyExplicit = XkbNumKeys(xkb);
525 }
526 if (which & XkbModifierMapMask) {
527 req->firstModMapKey = xkb->min_key_code;
528 req->nModMapKeys = XkbNumKeys(xkb);
529 }
530 if (which & XkbVirtualModMapMask) {
531 req->firstVModMapKey = xkb->min_key_code;
532 req->nVModMapKeys = XkbNumKeys(xkb);
533 }
534 SendSetMap(dpy, xkb, req);
535 UnlockDisplay(dpy);
536 SyncHandle();
537 return True;
538 }
539
540 Bool
XkbChangeMap(Display * dpy,XkbDescPtr xkb,XkbMapChangesPtr changes)541 XkbChangeMap(Display *dpy, XkbDescPtr xkb, XkbMapChangesPtr changes)
542 {
543 register xkbSetMapReq *req;
544 XkbInfoPtr xkbi;
545 XkbServerMapPtr srv;
546 XkbClientMapPtr map;
547
548 if ((dpy->flags & XlibDisplayNoXkb) ||
549 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)) ||
550 (!xkb) || (!changes))
551 return False;
552 srv = xkb->server;
553 map = xkb->map;
554
555 if (((changes->changed & XkbKeyTypesMask) && ((!map) || (!map->types))) ||
556 ((changes->changed & XkbKeySymsMask) && ((!map) || (!map->syms) ||
557 (!map->key_sym_map))) ||
558 ((changes->changed & XkbKeyActionsMask) && ((!srv) || (!srv->key_acts)))
559 || ((changes->changed & XkbKeyBehaviorsMask) &&
560 ((!srv) || (!srv->behaviors))) ||
561 ((changes->changed & XkbVirtualModsMask) && (!srv)) ||
562 ((changes->changed & XkbExplicitComponentsMask) &&
563 ((!srv) || (!srv->explicit))) ||
564 ((changes->changed & XkbModifierMapMask) && ((!map) || (!map->modmap)))
565 || ((changes->changed & XkbVirtualModMapMask) &&
566 ((!srv) || (!srv->vmodmap))))
567 return False;
568
569 LockDisplay(dpy);
570 xkbi = dpy->xkb_info;
571 GetReq(kbSetMap, req);
572 req->reqType = xkbi->codes->major_opcode;
573 req->xkbReqType = X_kbSetMap;
574 req->deviceSpec = xkb->device_spec;
575 req->present = changes->changed;
576 req->flags = XkbSetMapRecomputeActions;
577 req->minKeyCode = xkb->min_key_code;
578 req->maxKeyCode = xkb->max_key_code;
579 req->firstType = changes->first_type;
580 req->nTypes = changes->num_types;
581 req->firstKeySym = changes->first_key_sym;
582 req->nKeySyms = changes->num_key_syms;
583 req->firstKeyAct = changes->first_key_act;
584 req->nKeyActs = changes->num_key_acts;
585 req->firstKeyBehavior = changes->first_key_behavior;
586 req->nKeyBehaviors = changes->num_key_behaviors;
587 req->virtualMods = changes->vmods;
588 req->firstKeyExplicit = changes->first_key_explicit;
589 req->nKeyExplicit = changes->num_key_explicit;
590 req->firstModMapKey = changes->first_modmap_key;
591 req->nModMapKeys = changes->num_modmap_keys;
592 req->firstVModMapKey = changes->first_vmodmap_key;
593 req->nVModMapKeys = changes->num_vmodmap_keys;
594 SendSetMap(dpy, xkb, req);
595 UnlockDisplay(dpy);
596 SyncHandle();
597 return True;
598 }
599