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 #define NEED_MAP_READERS
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include "Xlibint.h"
32 #include <X11/extensions/XKBproto.h>
33 #include "XKBlibint.h"
34
35
36 static Status
_XkbReadAtoms(XkbReadBufferPtr buf,Atom * atoms,int maxAtoms,CARD32 present)37 _XkbReadAtoms(XkbReadBufferPtr buf,
38 Atom *atoms,
39 int maxAtoms,
40 CARD32 present)
41 {
42 register int i, bit;
43
44 for (i = 0, bit = 1; (i < maxAtoms) && (present); i++, bit <<= 1) {
45 if (present & bit) {
46 if (!_XkbReadBufferCopy32(buf, (long *) &atoms[i], 1))
47 return BadLength;
48 present &= ~bit;
49 }
50 }
51 return Success;
52 }
53
54 Status
_XkbReadGetNamesReply(Display * dpy,xkbGetNamesReply * rep,XkbDescPtr xkb,int * nread_rtrn)55 _XkbReadGetNamesReply(Display *dpy,
56 xkbGetNamesReply *rep,
57 XkbDescPtr xkb,
58 int *nread_rtrn)
59 {
60 int i, len;
61 XkbReadBufferRec buf;
62 register XkbNamesPtr names;
63
64 if (xkb->device_spec == XkbUseCoreKbd)
65 xkb->device_spec = rep->deviceID;
66
67 if ((xkb->names == NULL) &&
68 (XkbAllocNames(xkb, rep->which,
69 rep->nRadioGroups, rep->nKeyAliases) != Success)) {
70 return BadAlloc;
71 }
72 names = xkb->names;
73 if (rep->length == 0)
74 return Success;
75
76 if (!_XkbInitReadBuffer(dpy, &buf, (int) rep->length * 4))
77 return BadAlloc;
78 if (nread_rtrn)
79 *nread_rtrn = (int) rep->length * 4;
80
81 if ((rep->which & XkbKeycodesNameMask) &&
82 (!_XkbReadBufferCopy32(&buf, (long *) &names->keycodes, 1)))
83 goto BAILOUT;
84 if ((rep->which & XkbGeometryNameMask) &&
85 (!_XkbReadBufferCopy32(&buf, (long *) &names->geometry, 1)))
86 goto BAILOUT;
87 if ((rep->which & XkbSymbolsNameMask) &&
88 (!_XkbReadBufferCopy32(&buf, (long *) &names->symbols, 1)))
89 goto BAILOUT;
90 if ((rep->which & XkbPhysSymbolsNameMask) &&
91 (!_XkbReadBufferCopy32(&buf, (long *) &names->phys_symbols, 1)))
92 goto BAILOUT;
93 if ((rep->which & XkbTypesNameMask) &&
94 (!_XkbReadBufferCopy32(&buf, (long *) &names->types, 1)))
95 goto BAILOUT;
96 if ((rep->which & XkbCompatNameMask) &&
97 (!_XkbReadBufferCopy32(&buf, (long *) &names->compat, 1)))
98 goto BAILOUT;
99
100 if (rep->which & XkbKeyTypeNamesMask) {
101 XkbClientMapPtr map = xkb->map;
102 XkbKeyTypePtr type;
103
104 len = rep->nTypes * 4;
105 if (map != NULL) {
106 type = map->types;
107 for (i = 0; (i < map->num_types) && (i < rep->nTypes); i++, type++) {
108 if (!_XkbReadBufferCopy32(&buf, (long *) &type->name, 1))
109 goto BAILOUT;
110 len -= 4;
111 }
112 }
113 if ((len > 0) && (!_XkbSkipReadBufferData(&buf, len)))
114 goto BAILOUT;
115 }
116 if (rep->which & XkbKTLevelNamesMask) {
117 CARD8 *nLevels;
118 XkbClientMapPtr map = xkb->map;
119
120 nLevels =
121 (CARD8 *) _XkbGetReadBufferPtr(&buf, XkbPaddedSize(rep->nTypes));
122 if (nLevels == NULL)
123 goto BAILOUT;
124 if (map != NULL) {
125 XkbKeyTypePtr type = map->types;
126
127 for (i = 0; i < (int) rep->nTypes; i++, type++) {
128 if (i >= map->num_types) {
129 if (!_XkbSkipReadBufferData(&buf, nLevels[i] * 4))
130 goto BAILOUT;
131 continue;
132 }
133 if ((nLevels[i] > 0) && (nLevels[i] != type->num_levels)) {
134 goto BAILOUT;
135 }
136
137 Xfree(type->level_names);
138 if (nLevels[i] == 0) {
139 type->level_names = NULL;
140 continue;
141 }
142 type->level_names = _XkbTypedCalloc(nLevels[i], Atom);
143 if (type->level_names != NULL) {
144 if (!_XkbReadBufferCopy32(&buf, (long *) type->level_names,
145 nLevels[i]))
146 goto BAILOUT;
147 }
148 else {
149 _XkbSkipReadBufferData(&buf, nLevels[i] * 4);
150 }
151 }
152 }
153 else {
154 for (i = 0; i < (int) rep->nTypes; i++) {
155 _XkbSkipReadBufferData(&buf, nLevels[i] * 4);
156 }
157 }
158 }
159 if (rep->which & XkbIndicatorNamesMask) {
160 if (_XkbReadAtoms(&buf, names->indicators, XkbNumIndicators,
161 rep->indicators) != Success)
162 goto BAILOUT;
163 }
164 if (rep->which & XkbVirtualModNamesMask) {
165 if (_XkbReadAtoms(&buf, names->vmods, XkbNumVirtualMods,
166 (CARD32) rep->virtualMods) != Success)
167 goto BAILOUT;
168 }
169 if (rep->which & XkbGroupNamesMask) {
170 if (_XkbReadAtoms(&buf, names->groups, XkbNumKbdGroups,
171 (CARD32) rep->groupNames) != Success)
172 goto BAILOUT;
173 }
174 if (rep->which & XkbKeyNamesMask) {
175 if (names->keys == NULL) {
176 int nKeys;
177
178 if (xkb->max_key_code == 0) {
179 xkb->min_key_code = rep->minKeyCode;
180 xkb->max_key_code = rep->maxKeyCode;
181 }
182 nKeys = xkb->max_key_code + 1;
183 names->keys = _XkbTypedCalloc(nKeys, XkbKeyNameRec);
184 }
185 if (((int) rep->firstKey + rep->nKeys) > xkb->max_key_code + 1)
186 goto BAILOUT;
187 if (names->keys != NULL) {
188 if (!_XkbCopyFromReadBuffer(&buf,
189 (char *) &names->keys[rep->firstKey],
190 rep->nKeys * XkbKeyNameLength))
191 goto BAILOUT;
192 }
193 else
194 _XkbSkipReadBufferData(&buf, rep->nKeys * XkbKeyNameLength);
195 }
196 if (rep->which & XkbKeyAliasesMask && (rep->nKeyAliases > 0)) {
197 if (XkbAllocNames(xkb, XkbKeyAliasesMask, 0, rep->nKeyAliases) !=
198 Success)
199 goto BAILOUT;
200 if (!_XkbCopyFromReadBuffer(&buf, (char *) names->key_aliases,
201 rep->nKeyAliases * XkbKeyNameLength * 2))
202 goto BAILOUT;
203 }
204 if (rep->which & XkbRGNamesMask) {
205 if (rep->nRadioGroups > 0) {
206 Atom *rgNames;
207
208 if ((names->radio_groups == NULL) ||
209 (names->num_rg < rep->nRadioGroups)) {
210 _XkbResizeArray(names->radio_groups, names->num_rg,
211 rep->nRadioGroups, Atom);
212 }
213 rgNames = names->radio_groups;
214 if (!rgNames) {
215 names->num_rg = 0;
216 goto BAILOUT;
217 }
218 if (!_XkbReadBufferCopy32
219 (&buf, (long *) rgNames, rep->nRadioGroups))
220 goto BAILOUT;
221 names->num_rg = rep->nRadioGroups;
222 }
223 else if (names->num_rg > 0) {
224 names->num_rg = 0;
225 Xfree(names->radio_groups);
226 }
227 }
228 len = _XkbFreeReadBuffer(&buf);
229 if (len != 0)
230 return BadLength;
231 else
232 return Success;
233 BAILOUT:
234 _XkbFreeReadBuffer(&buf);
235 return BadLength;
236 }
237
238 Status
XkbGetNames(Display * dpy,unsigned which,XkbDescPtr xkb)239 XkbGetNames(Display *dpy, unsigned which, XkbDescPtr xkb)
240 {
241 register xkbGetNamesReq *req;
242 xkbGetNamesReply rep;
243 Status status;
244 XkbInfoPtr xkbi;
245
246 if ((dpy->flags & XlibDisplayNoXkb) ||
247 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
248 return BadAccess;
249 LockDisplay(dpy);
250 xkbi = dpy->xkb_info;
251 if (!xkb->names) {
252 xkb->names = _XkbTypedCalloc(1, XkbNamesRec);
253 if (!xkb->names) {
254 UnlockDisplay(dpy);
255 SyncHandle();
256 return BadAlloc;
257 }
258 }
259 GetReq(kbGetNames, req);
260 req->reqType = xkbi->codes->major_opcode;
261 req->xkbReqType = X_kbGetNames;
262 req->deviceSpec = xkb->device_spec;
263 req->which = which;
264 if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
265 UnlockDisplay(dpy);
266 SyncHandle();
267 return BadImplementation;
268 }
269
270 status = _XkbReadGetNamesReply(dpy, &rep, xkb, NULL);
271 UnlockDisplay(dpy);
272 SyncHandle();
273 return status;
274 }
275
276 /***====================================================================***/
277
278 static int
_XkbCountBits(int nBitsMax,unsigned long mask)279 _XkbCountBits(int nBitsMax, unsigned long mask)
280 {
281 register unsigned long y, nBits;
282
283 y = (mask >> 1) & 033333333333;
284 y = mask - y - ((y >> 1) & 033333333333);
285 nBits = ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077));
286
287 /* nBitsMax really means max+1 */
288 return (nBits < nBitsMax) ? nBits : (nBitsMax - 1);
289 }
290
291 static CARD32
_XkbCountAtoms(Atom * atoms,int maxAtoms,int * count)292 _XkbCountAtoms(Atom *atoms, int maxAtoms, int *count)
293 {
294 register unsigned int i, bit, nAtoms;
295 register CARD32 atomsPresent;
296
297 for (i = nAtoms = atomsPresent = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) {
298 if (atoms[i] != None) {
299 atomsPresent |= bit;
300 nAtoms++;
301 }
302 }
303 if (count)
304 *count = nAtoms;
305 return atomsPresent;
306 }
307
308 static void
_XkbCopyAtoms(Display * dpy,Atom * atoms,CARD32 mask,int maxAtoms)309 _XkbCopyAtoms(Display *dpy, Atom *atoms, CARD32 mask, int maxAtoms)
310 {
311 register unsigned int i, bit;
312
313 for (i = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) {
314 if (mask & bit)
315 Data32(dpy, &atoms[i], 4);
316 }
317 return;
318 }
319
320 Bool
XkbSetNames(Display * dpy,unsigned int which,unsigned int firstType,unsigned int nTypes,XkbDescPtr xkb)321 XkbSetNames(Display *dpy,
322 unsigned int which,
323 unsigned int firstType,
324 unsigned int nTypes,
325 XkbDescPtr xkb)
326 {
327 register xkbSetNamesReq *req;
328 int nLvlNames = 0;
329 XkbInfoPtr xkbi;
330 XkbNamesPtr names;
331 unsigned firstLvlType, nLvlTypes;
332 int nVMods, nLEDs, nRG, nKA, nGroups;
333 int nKeys = 0, firstKey = 0, nAtoms;
334 CARD32 leds, vmods, groups;
335
336 if ((dpy->flags & XlibDisplayNoXkb) ||
337 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
338 return False;
339 if ((!xkb) || (!xkb->names))
340 return False;
341 firstLvlType = firstType;
342 nLvlTypes = nTypes;
343 if (nTypes < 1)
344 which &= ~(XkbKTLevelNamesMask | XkbKeyTypeNamesMask);
345 else if (firstType <= XkbLastRequiredType) {
346 int adjust;
347
348 adjust = XkbLastRequiredType - firstType + 1;
349 firstType += adjust;
350 nTypes -= adjust;
351 if (nTypes < 1)
352 which &= ~XkbKeyTypeNamesMask;
353 }
354 names = xkb->names;
355 if (which & (XkbKTLevelNamesMask | XkbKeyTypeNamesMask)) {
356 register int i;
357 XkbKeyTypePtr type;
358
359 if ((xkb->map == NULL) || (xkb->map->types == NULL) || (nTypes == 0) ||
360 (firstType + nTypes > xkb->map->num_types) ||
361 (firstLvlType + nLvlTypes > xkb->map->num_types))
362 return False;
363 if (which & XkbKTLevelNamesMask) {
364 type = &xkb->map->types[firstLvlType];
365 for (i = nLvlNames = 0; i < nLvlTypes; i++, type++) {
366 if (type->level_names != NULL)
367 nLvlNames += type->num_levels;
368 }
369 }
370 }
371
372 nVMods = nLEDs = nRG = nKA = nAtoms = nGroups = 0;
373 LockDisplay(dpy);
374 xkbi = dpy->xkb_info;
375 GetReq(kbSetNames, req);
376 req->reqType = xkbi->codes->major_opcode;
377 req->xkbReqType = X_kbSetNames;
378 req->deviceSpec = xkb->device_spec;
379 req->firstType = firstType;
380 req->nTypes = nTypes;
381 req->firstKey = xkb->min_key_code;
382 req->nKeys = xkb->max_key_code - xkb->min_key_code + 1;
383
384 if (which & XkbKeycodesNameMask)
385 nAtoms++;
386 if (which & XkbGeometryNameMask)
387 nAtoms++;
388 if (which & XkbSymbolsNameMask)
389 nAtoms++;
390 if (which & XkbPhysSymbolsNameMask)
391 nAtoms++;
392 if (which & XkbTypesNameMask)
393 nAtoms++;
394 if (which & XkbCompatNameMask)
395 nAtoms++;
396 if (which & XkbKeyTypeNamesMask)
397 nAtoms += nTypes;
398 if (which & XkbKTLevelNamesMask) {
399 req->firstKTLevel = firstLvlType;
400 req->nKTLevels = nLvlTypes;
401 req->length += XkbPaddedSize(nLvlTypes) / 4; /* room for group widths */
402 nAtoms += nLvlNames;
403 }
404 else
405 req->firstKTLevel = req->nKTLevels = 0;
406
407 if (which & XkbIndicatorNamesMask) {
408 req->indicators = leds =
409 _XkbCountAtoms(names->indicators, XkbNumIndicators, &nLEDs);
410 if (nLEDs > 0)
411 nAtoms += nLEDs;
412 else
413 which &= ~XkbIndicatorNamesMask;
414 }
415 else
416 req->indicators = leds = 0;
417
418 if (which & XkbVirtualModNamesMask) {
419 vmods = req->virtualMods = (CARD16)
420 _XkbCountAtoms(names->vmods, XkbNumVirtualMods, &nVMods);
421 if (nVMods > 0)
422 nAtoms += nVMods;
423 else
424 which &= ~XkbVirtualModNamesMask;
425 }
426 else
427 vmods = req->virtualMods = 0;
428
429 if (which & XkbGroupNamesMask) {
430 groups = req->groupNames = (CARD8)
431 _XkbCountAtoms(names->groups, XkbNumKbdGroups, &nGroups);
432 if (nGroups > 0)
433 nAtoms += nGroups;
434 else
435 which &= ~XkbGroupNamesMask;
436 }
437 else
438 groups = req->groupNames = 0;
439
440 if ((which & XkbKeyNamesMask) && (names->keys != NULL)) {
441 firstKey = req->firstKey;
442 nKeys = req->nKeys;
443 nAtoms += nKeys; /* technically not atoms, but 4 bytes wide */
444 }
445 else
446 which &= ~XkbKeyNamesMask;
447
448 if (which & XkbKeyAliasesMask) {
449 nKA = ((names->key_aliases != NULL) ? names->num_key_aliases : 0);
450 if (nKA > 0) {
451 req->nKeyAliases = nKA;
452 nAtoms += nKA * 2; /* not atoms, but 8 bytes on the wire */
453 }
454 else {
455 which &= ~XkbKeyAliasesMask;
456 req->nKeyAliases = 0;
457 }
458 }
459 else
460 req->nKeyAliases = 0;
461
462 if (which & XkbRGNamesMask) {
463 nRG = names->num_rg;
464 if (nRG > 0)
465 nAtoms += nRG;
466 else
467 which &= ~XkbRGNamesMask;
468 }
469
470 req->which = which;
471 req->nRadioGroups = nRG;
472 req->length += (nAtoms * 4) / 4;
473
474 if (which & XkbKeycodesNameMask)
475 Data32(dpy, (long *) &names->keycodes, 4);
476 if (which & XkbGeometryNameMask)
477 Data32(dpy, (long *) &names->geometry, 4);
478 if (which & XkbSymbolsNameMask)
479 Data32(dpy, (long *) &names->symbols, 4);
480 if (which & XkbPhysSymbolsNameMask)
481 Data32(dpy, (long *) &names->phys_symbols, 4);
482 if (which & XkbTypesNameMask)
483 Data32(dpy, (long *) &names->types, 4);
484 if (which & XkbCompatNameMask)
485 Data32(dpy, (long *) &names->compat, 4);
486 if (which & XkbKeyTypeNamesMask) {
487 register int i;
488 register XkbKeyTypePtr type;
489
490 type = &xkb->map->types[firstType];
491 for (i = 0; i < nTypes; i++, type++) {
492 Data32(dpy, (long *) &type->name, 4);
493 }
494 }
495 if (which & XkbKTLevelNamesMask) {
496 XkbKeyTypePtr type;
497 int i;
498 char *tmp;
499
500 BufAlloc(char *, tmp, XkbPaddedSize(nLvlTypes));
501 type = &xkb->map->types[firstLvlType];
502 for (i = 0; i < nLvlTypes; i++, type++) {
503 *tmp++ = type->num_levels;
504 }
505 type = &xkb->map->types[firstLvlType];
506 for (i = 0; i < nLvlTypes; i++, type++) {
507 if (type->level_names != NULL)
508 Data32(dpy, (long *) type->level_names, type->num_levels * 4);
509 }
510 }
511 if (which & XkbIndicatorNamesMask)
512 _XkbCopyAtoms(dpy, names->indicators, leds, XkbNumIndicators);
513 if (which & XkbVirtualModNamesMask)
514 _XkbCopyAtoms(dpy, names->vmods, vmods, XkbNumVirtualMods);
515 if (which & XkbGroupNamesMask)
516 _XkbCopyAtoms(dpy, names->groups, groups, XkbNumKbdGroups);
517 if (which & XkbKeyNamesMask) {
518 Data(dpy, (char *) &names->keys[firstKey], nKeys * XkbKeyNameLength);
519 }
520 if (which & XkbKeyAliasesMask) {
521 Data(dpy, (char *) names->key_aliases, nKA * XkbKeyNameLength * 2);
522 }
523 if (which & XkbRGNamesMask) {
524 Data32(dpy, (long *) names->radio_groups, nRG * 4);
525 }
526 UnlockDisplay(dpy);
527 SyncHandle();
528 return True;
529 }
530
531 Bool
XkbChangeNames(Display * dpy,XkbDescPtr xkb,XkbNameChangesPtr changes)532 XkbChangeNames(Display *dpy, XkbDescPtr xkb, XkbNameChangesPtr changes)
533 {
534 register xkbSetNamesReq *req;
535 int nLvlNames = 0;
536 XkbInfoPtr xkbi;
537 XkbNamesPtr names;
538 unsigned which, firstType, nTypes;
539 unsigned firstLvlType, nLvlTypes;
540 int nVMods, nLEDs, nRG, nKA, nGroups;
541 int nKeys = 0, firstKey = 0, nAtoms;
542 CARD32 leds = 0, vmods = 0, groups = 0;
543
544 if ((dpy->flags & XlibDisplayNoXkb) ||
545 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
546 return False;
547 if ((!xkb) || (!xkb->names) || (!changes))
548 return False;
549 which = changes->changed;
550 firstType = changes->first_type;
551 nTypes = changes->num_types;
552 firstLvlType = changes->first_lvl;
553 nLvlTypes = changes->num_lvls;
554 if (which & XkbKeyTypeNamesMask) {
555 if (nTypes < 1)
556 which &= ~XkbKeyTypeNamesMask;
557 else if (firstType <= XkbLastRequiredType) {
558 int adjust;
559
560 adjust = XkbLastRequiredType - firstType + 1;
561 firstType += adjust;
562 nTypes -= adjust;
563 if (nTypes < 1)
564 which &= ~XkbKeyTypeNamesMask;
565 }
566 }
567 else
568 firstType = nTypes = 0;
569
570 if (which & XkbKTLevelNamesMask) {
571 if (nLvlTypes < 1)
572 which &= ~XkbKTLevelNamesMask;
573 }
574 else
575 firstLvlType = nLvlTypes = 0;
576
577 names = xkb->names;
578 if (which & (XkbKTLevelNamesMask | XkbKeyTypeNamesMask)) {
579 register int i;
580
581 if ((xkb->map == NULL) || (xkb->map->types == NULL) || (nTypes == 0) ||
582 (firstType + nTypes > xkb->map->num_types) ||
583 (firstLvlType + nLvlTypes > xkb->map->num_types))
584 return False;
585 if (which & XkbKTLevelNamesMask) {
586 XkbKeyTypePtr type = &xkb->map->types[firstLvlType];
587
588 for (i = nLvlNames = 0; i < nLvlTypes; i++, type++) {
589 if (type->level_names != NULL)
590 nLvlNames += type->num_levels;
591 }
592 }
593 }
594
595 if (changes->num_keys < 1)
596 which &= ~XkbKeyNamesMask;
597 if ((which & XkbKeyNamesMask) == 0)
598 changes->first_key = changes->num_keys = 0;
599 else if ((changes->first_key < xkb->min_key_code) ||
600 (changes->first_key + changes->num_keys > xkb->max_key_code)) {
601 return False;
602 }
603
604 if ((which & XkbVirtualModNamesMask) == 0)
605 changes->changed_vmods = 0;
606 else if (changes->changed_vmods == 0)
607 which &= ~XkbVirtualModNamesMask;
608
609 if ((which & XkbIndicatorNamesMask) == 0)
610 changes->changed_indicators = 0;
611 else if (changes->changed_indicators == 0)
612 which &= ~XkbIndicatorNamesMask;
613
614 if ((which & XkbGroupNamesMask) == 0)
615 changes->changed_groups = 0;
616 else if (changes->changed_groups == 0)
617 which &= ~XkbGroupNamesMask;
618
619 nVMods = nLEDs = nRG = nKA = nAtoms = nGroups = 0;
620 LockDisplay(dpy);
621 xkbi = dpy->xkb_info;
622 GetReq(kbSetNames, req);
623 req->reqType = xkbi->codes->major_opcode;
624 req->xkbReqType = X_kbSetNames;
625 req->deviceSpec = xkb->device_spec;
626 req->firstType = firstType;
627 req->nTypes = nTypes;
628 req->firstKey = changes->first_key;
629 req->nKeys = changes->num_keys;
630
631 if (which & XkbKeycodesNameMask)
632 nAtoms++;
633 if (which & XkbGeometryNameMask)
634 nAtoms++;
635 if (which & XkbSymbolsNameMask)
636 nAtoms++;
637 if (which & XkbPhysSymbolsNameMask)
638 nAtoms++;
639 if (which & XkbTypesNameMask)
640 nAtoms++;
641 if (which & XkbCompatNameMask)
642 nAtoms++;
643 if (which & XkbKeyTypeNamesMask)
644 nAtoms += nTypes;
645 if (which & XkbKTLevelNamesMask) {
646 req->firstKTLevel = firstLvlType;
647 req->nKTLevels = nLvlTypes;
648 req->length += XkbPaddedSize(nLvlTypes) / 4; /* room for group widths */
649 nAtoms += nLvlNames;
650 }
651 else
652 req->firstKTLevel = req->nKTLevels = 0;
653
654 if (which & XkbIndicatorNamesMask) {
655 leds = req->indicators = (CARD32) changes->changed_indicators;
656 nLEDs = _XkbCountBits(XkbNumIndicators, changes->changed_indicators);
657 if (nLEDs > 0)
658 nAtoms += nLEDs;
659 else
660 which &= ~XkbIndicatorNamesMask;
661 }
662 else
663 req->indicators = 0;
664
665 if (which & XkbVirtualModNamesMask) {
666 vmods = req->virtualMods = changes->changed_vmods;
667 nVMods = _XkbCountBits(XkbNumVirtualMods,
668 (unsigned long) changes->changed_vmods);
669 if (nVMods > 0)
670 nAtoms += nVMods;
671 else
672 which &= ~XkbVirtualModNamesMask;
673 }
674 else
675 req->virtualMods = 0;
676
677 if (which & XkbGroupNamesMask) {
678 groups = req->groupNames = changes->changed_groups;
679 nGroups = _XkbCountBits(XkbNumKbdGroups,
680 (unsigned long) changes->changed_groups);
681 if (nGroups > 0)
682 nAtoms += nGroups;
683 else
684 which &= ~XkbGroupNamesMask;
685 }
686 else
687 req->groupNames = 0;
688
689 if ((which & XkbKeyNamesMask) && (names->keys != NULL)) {
690 firstKey = req->firstKey;
691 nKeys = req->nKeys;
692 nAtoms += nKeys; /* technically not atoms, but 4 bytes wide */
693 }
694 else
695 which &= ~XkbKeyNamesMask;
696
697 if (which & XkbKeyAliasesMask) {
698 nKA = ((names->key_aliases != NULL) ? names->num_key_aliases : 0);
699 if (nKA > 0)
700 nAtoms += nKA * 2; /* not atoms, but 8 bytes on the wire */
701 else
702 which &= ~XkbKeyAliasesMask;
703 }
704
705 if (which & XkbRGNamesMask) {
706 nRG = names->num_rg;
707 if (nRG > 0)
708 nAtoms += nRG;
709 else
710 which &= ~XkbRGNamesMask;
711 }
712
713 req->which = which;
714 req->nRadioGroups = nRG;
715 req->length += (nAtoms * 4) / 4;
716
717 if (which & XkbKeycodesNameMask)
718 Data32(dpy, (long *) &names->keycodes, 4);
719 if (which & XkbGeometryNameMask)
720 Data32(dpy, (long *) &names->geometry, 4);
721 if (which & XkbSymbolsNameMask)
722 Data32(dpy, (long *) &names->symbols, 4);
723 if (which & XkbPhysSymbolsNameMask)
724 Data32(dpy, (long *) &names->phys_symbols, 4);
725 if (which & XkbTypesNameMask)
726 Data32(dpy, (long *) &names->types, 4);
727 if (which & XkbCompatNameMask)
728 Data32(dpy, (long *) &names->compat, 4);
729 if (which & XkbKeyTypeNamesMask) {
730 register int i;
731 register XkbKeyTypePtr type;
732
733 type = &xkb->map->types[firstType];
734 for (i = 0; i < nTypes; i++, type++) {
735 Data32(dpy, (long *) &type->name, 4);
736 }
737 }
738 if (which & XkbKTLevelNamesMask) {
739 XkbKeyTypePtr type;
740 int i;
741 char *tmp;
742
743 BufAlloc(char *, tmp, XkbPaddedSize(nLvlTypes));
744 type = &xkb->map->types[firstLvlType];
745 for (i = 0; i < nLvlTypes; i++, type++) {
746 *tmp++ = type->num_levels;
747 }
748 type = &xkb->map->types[firstLvlType];
749 for (i = 0; i < nLvlTypes; i++, type++) {
750 if (type->level_names != NULL)
751 Data32(dpy, (long *) type->level_names, type->num_levels * 4);
752 }
753 }
754 if (which & XkbIndicatorNamesMask)
755 _XkbCopyAtoms(dpy, names->indicators, leds, XkbNumIndicators);
756 if (which & XkbVirtualModNamesMask)
757 _XkbCopyAtoms(dpy, names->vmods, vmods, XkbNumVirtualMods);
758 if (which & XkbGroupNamesMask)
759 _XkbCopyAtoms(dpy, names->groups, groups, XkbNumKbdGroups);
760 if (which & XkbKeyNamesMask) {
761 Data(dpy, (char *) &names->keys[firstKey], nKeys * XkbKeyNameLength);
762 }
763 if (which & XkbKeyAliasesMask) {
764 Data(dpy, (char *) names->key_aliases, nKA * XkbKeyNameLength * 2);
765 }
766 if (which & XkbRGNamesMask) {
767 Data32(dpy, (long *) names->radio_groups, nRG * 4);
768 }
769 UnlockDisplay(dpy);
770 SyncHandle();
771 return True;
772 }
773
774 void
XkbNoteNameChanges(XkbNameChangesPtr old,XkbNamesNotifyEvent * new,unsigned int wanted)775 XkbNoteNameChanges(XkbNameChangesPtr old,
776 XkbNamesNotifyEvent *new,
777 unsigned int wanted)
778 {
779 int first, last, old_last, new_last;
780
781 if ((old == NULL) || (new == NULL))
782 return;
783
784 wanted &= new->changed;
785
786 if (wanted == 0)
787 return;
788
789 if (wanted & XkbKeyTypeNamesMask) {
790 if (old->changed & XkbKeyTypeNamesMask) {
791 new_last = (new->first_type + new->num_types - 1);
792 old_last = (old->first_type + old->num_types - 1);
793
794 if (new->first_type < old->first_type)
795 first = new->first_type;
796 else
797 first = old->first_type;
798
799 if (old_last > new_last)
800 last = old_last;
801 else
802 last = new_last;
803
804 old->first_type = first;
805 old->num_types = (last - first) + 1;
806 }
807 else {
808 old->first_type = new->first_type;
809 old->num_types = new->num_types;
810 }
811 }
812 if (wanted & XkbKTLevelNamesMask) {
813 if (old->changed & XkbKTLevelNamesMask) {
814 new_last = (new->first_lvl + new->num_lvls - 1);
815 old_last = (old->first_lvl + old->num_lvls - 1);
816
817 if (new->first_lvl < old->first_lvl)
818 first = new->first_lvl;
819 else
820 first = old->first_lvl;
821
822 if (old_last > new_last)
823 last = old_last;
824 else
825 last = new_last;
826
827 old->first_lvl = first;
828 old->num_lvls = (last - first) + 1;
829 }
830 else {
831 old->first_lvl = new->first_lvl;
832 old->num_lvls = new->num_lvls;
833 }
834 }
835 if (wanted & XkbIndicatorNamesMask) {
836 if (old->changed & XkbIndicatorNamesMask)
837 old->changed_indicators |= new->changed_indicators;
838 else
839 old->changed_indicators = new->changed_indicators;
840 }
841 if (wanted & XkbKeyNamesMask) {
842 if (old->changed & XkbKeyNamesMask) {
843 new_last = (new->first_key + new->num_keys - 1);
844 old_last = (old->first_key + old->num_keys - 1);
845
846 first = old->first_key;
847
848 if (new->first_key < old->first_key)
849 first = new->first_key;
850 if (old_last > new_last)
851 new_last = old_last;
852
853 old->first_key = first;
854 old->num_keys = (new_last - first) + 1;
855 }
856 else {
857 old->first_key = new->first_key;
858 old->num_keys = new->num_keys;
859 }
860 }
861 if (wanted & XkbVirtualModNamesMask) {
862 if (old->changed & XkbVirtualModNamesMask)
863 old->changed_vmods |= new->changed_vmods;
864 else
865 old->changed_vmods = new->changed_vmods;
866 }
867 if (wanted & XkbGroupNamesMask) {
868 if (old->changed & XkbGroupNamesMask)
869 old->changed_groups |= new->changed_groups;
870 else
871 old->changed_groups = new->changed_groups;
872 }
873 if (wanted & XkbRGNamesMask)
874 old->num_rg = new->num_radio_groups;
875 if (wanted & XkbKeyAliasesMask)
876 old->num_aliases = new->num_aliases;
877 old->changed |= wanted;
878 return;
879 }
880