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 static Status
_XkbReadKeyTypes(XkbReadBufferPtr buf,XkbDescPtr xkb,xkbGetMapReply * rep)36 _XkbReadKeyTypes(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep)
37 {
38 int i, n, lastMapCount;
39 XkbKeyTypePtr type;
40
41 if (rep->nTypes > 0) {
42 n = rep->firstType + rep->nTypes;
43 if (xkb->map->num_types >= n)
44 n = xkb->map->num_types;
45 else if (XkbAllocClientMap(xkb, XkbKeyTypesMask, n) != Success)
46 return BadAlloc;
47
48 type = &xkb->map->types[rep->firstType];
49 for (i = 0; i < (int) rep->nTypes; i++, type++) {
50 xkbKeyTypeWireDesc *desc;
51 register int ndx;
52
53 ndx = i + rep->firstType;
54 if (ndx >= xkb->map->num_types)
55 xkb->map->num_types = ndx + 1;
56
57 desc = (xkbKeyTypeWireDesc *)
58 _XkbGetReadBufferPtr(buf, SIZEOF(xkbKeyTypeWireDesc));
59 if (desc == NULL)
60 return BadLength;
61
62 lastMapCount = type->map_count;
63 if (desc->nMapEntries > 0) {
64 if ((type->map == NULL) ||
65 (desc->nMapEntries > type->map_count)) {
66 _XkbResizeArray(type->map, type->map_count,
67 desc->nMapEntries, XkbKTMapEntryRec);
68 if (type->map == NULL) {
69 return BadAlloc;
70 }
71 }
72 }
73 else if (type->map != NULL) {
74 Xfree(type->map);
75 type->map_count = 0;
76 type->map = NULL;
77 }
78
79 if (desc->preserve && (desc->nMapEntries > 0)) {
80 if ((!type->preserve) || (desc->nMapEntries > lastMapCount)) {
81 _XkbResizeArray(type->preserve, lastMapCount,
82 desc->nMapEntries, XkbModsRec);
83 if (type->preserve == NULL) {
84 return BadAlloc;
85 }
86 }
87 }
88 else if (type->preserve != NULL) {
89 Xfree(type->preserve);
90 type->preserve = NULL;
91 }
92
93 type->mods.mask = desc->mask;
94 type->mods.real_mods = desc->realMods;
95 type->mods.vmods = desc->virtualMods;
96 type->num_levels = desc->numLevels;
97 type->map_count = desc->nMapEntries;
98 if (desc->nMapEntries > 0) {
99 register xkbKTMapEntryWireDesc *wire;
100 register XkbKTMapEntryPtr entry;
101 register int size;
102
103 size = type->map_count * SIZEOF(xkbKTMapEntryWireDesc);
104 wire =
105 (xkbKTMapEntryWireDesc *) _XkbGetReadBufferPtr(buf, size);
106 if (wire == NULL)
107 return BadLength;
108 entry = type->map;
109 for (n = 0; n < type->map_count; n++, wire++, entry++) {
110 entry->active = wire->active;
111 entry->level = wire->level;
112 entry->mods.mask = wire->mask;
113 entry->mods.real_mods = wire->realMods;
114 entry->mods.vmods = wire->virtualMods;
115 }
116
117 if (desc->preserve) {
118 register xkbModsWireDesc *pwire;
119 register XkbModsPtr preserve;
120 register int sz;
121
122 sz = desc->nMapEntries * SIZEOF(xkbModsWireDesc);
123 pwire = (xkbModsWireDesc *) _XkbGetReadBufferPtr(buf, sz);
124 if (pwire == NULL)
125 return BadLength;
126 preserve = type->preserve;
127 for (n = 0; n < desc->nMapEntries; n++, pwire++, preserve++) {
128 preserve->mask = pwire->mask;
129 preserve->vmods = pwire->virtualMods;
130 preserve->real_mods = pwire->realMods;
131 }
132 }
133 }
134 }
135 }
136 return Success;
137 }
138
139 static Status
_XkbReadKeySyms(XkbReadBufferPtr buf,XkbDescPtr xkb,xkbGetMapReply * rep)140 _XkbReadKeySyms(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep)
141 {
142 register int i;
143 XkbClientMapPtr map;
144 int size = xkb->max_key_code + 1;
145
146 if (((unsigned short) rep->firstKeySym + rep->nKeySyms) > size)
147 return BadLength;
148
149 map = xkb->map;
150 if (map->key_sym_map == NULL) {
151 register int offset;
152 XkbSymMapPtr oldMap;
153 xkbSymMapWireDesc *newMap;
154
155 map->key_sym_map = _XkbTypedCalloc(size, XkbSymMapRec);
156 if (map->key_sym_map == NULL)
157 return BadAlloc;
158 if (map->syms == NULL) {
159 int sz;
160
161 sz = (rep->totalSyms * 12) / 10;
162 sz = ((sz + (unsigned) 128) / 128) * 128;
163 map->syms = _XkbTypedCalloc(sz, KeySym);
164 if (map->syms == NULL)
165 return BadAlloc;
166 map->size_syms = sz;
167 }
168 offset = 1;
169 oldMap = &map->key_sym_map[rep->firstKeySym];
170 for (i = 0; i < (int) rep->nKeySyms; i++, oldMap++) {
171 newMap = (xkbSymMapWireDesc *)
172 _XkbGetReadBufferPtr(buf, SIZEOF(xkbSymMapWireDesc));
173 if (newMap == NULL)
174 return BadLength;
175 oldMap->kt_index[0] = newMap->ktIndex[0];
176 oldMap->kt_index[1] = newMap->ktIndex[1];
177 oldMap->kt_index[2] = newMap->ktIndex[2];
178 oldMap->kt_index[3] = newMap->ktIndex[3];
179 oldMap->group_info = newMap->groupInfo;
180 oldMap->width = newMap->width;
181 oldMap->offset = offset;
182 if (offset + newMap->nSyms >= map->size_syms) {
183 register int sz;
184
185 sz = map->size_syms + 128;
186 _XkbResizeArray(map->syms, map->size_syms, sz, KeySym);
187 if (map->syms == NULL) {
188 map->size_syms = 0;
189 return BadAlloc;
190 }
191 map->size_syms = sz;
192 }
193 if (newMap->nSyms > 0) {
194 _XkbReadBufferCopyKeySyms(buf, (KeySym *) &map->syms[offset],
195 newMap->nSyms);
196 offset += newMap->nSyms;
197 }
198 else {
199 map->syms[offset] = 0;
200 }
201 }
202 map->num_syms = offset;
203 }
204 else {
205 XkbSymMapPtr oldMap = &map->key_sym_map[rep->firstKeySym];
206
207 for (i = 0; i < (int) rep->nKeySyms; i++, oldMap++) {
208 xkbSymMapWireDesc *newMap;
209 KeySym *newSyms;
210 int tmp;
211
212 newMap = (xkbSymMapWireDesc *)
213 _XkbGetReadBufferPtr(buf, SIZEOF(xkbSymMapWireDesc));
214 if (newMap == NULL)
215 return BadLength;
216
217 if (newMap->nSyms > 0)
218 tmp = newMap->nSyms;
219 else
220 tmp = 0;
221
222 newSyms = XkbResizeKeySyms(xkb, i + rep->firstKeySym, tmp);
223 if (newSyms == NULL)
224 return BadAlloc;
225 if (newMap->nSyms > 0)
226 _XkbReadBufferCopyKeySyms(buf, newSyms, newMap->nSyms);
227 else
228 newSyms[0] = NoSymbol;
229 oldMap->kt_index[0] = newMap->ktIndex[0];
230 oldMap->kt_index[1] = newMap->ktIndex[1];
231 oldMap->kt_index[2] = newMap->ktIndex[2];
232 oldMap->kt_index[3] = newMap->ktIndex[3];
233 oldMap->group_info = newMap->groupInfo;
234 oldMap->width = newMap->width;
235 }
236 }
237 return Success;
238 }
239
240 static Status
_XkbReadKeyActions(XkbReadBufferPtr buf,XkbDescPtr info,xkbGetMapReply * rep)241 _XkbReadKeyActions(XkbReadBufferPtr buf, XkbDescPtr info, xkbGetMapReply *rep)
242 {
243 int i;
244 CARD8 numDescBuf[248];
245 CARD8 *numDesc = NULL;
246 register int nKeyActs;
247 Status ret = Success;
248
249 if ((nKeyActs = rep->nKeyActs) > 0) {
250 XkbSymMapPtr symMap;
251
252 if (nKeyActs < sizeof numDescBuf)
253 numDesc = numDescBuf;
254 else
255 numDesc = Xmallocarray(nKeyActs, sizeof(CARD8));
256
257 if (!_XkbCopyFromReadBuffer(buf, (char *) numDesc, nKeyActs)) {
258 ret = BadLength;
259 goto done;
260 }
261 i = XkbPaddedSize(nKeyActs) - nKeyActs;
262 if ((i > 0) && (!_XkbSkipReadBufferData(buf, i))) {
263 ret = BadLength;
264 goto done;
265 }
266 symMap = &info->map->key_sym_map[rep->firstKeyAct];
267 for (i = 0; i < (int) rep->nKeyActs; i++, symMap++) {
268 if (numDesc[i] == 0) {
269 if ((i + rep->firstKeyAct) > (info->max_key_code + 1)) {
270 ret = BadLength;
271 goto done;
272 }
273 info->server->key_acts[i + rep->firstKeyAct] = 0;
274 }
275 else {
276 XkbAction *newActs;
277
278 /* 8/16/93 (ef) -- XXX! Verify size here (numdesc must be */
279 /* either zero or XkbKeyNumSyms(info,key) */
280 newActs = XkbResizeKeyActions(info, i + rep->firstKeyAct,
281 numDesc[i]);
282 if (newActs == NULL) {
283 ret = BadAlloc;
284 goto done;
285 }
286 if (!_XkbCopyFromReadBuffer(buf, (char *) newActs,
287 (int) (numDesc[i] * sizeof(XkbAction)))) {
288 ret = BadLength;
289 goto done;
290 }
291 }
292 }
293 }
294 done:
295 if (numDesc != NULL && numDesc != numDescBuf)
296 Xfree(numDesc);
297 return ret;
298 }
299
300 static Status
_XkbReadKeyBehaviors(XkbReadBufferPtr buf,XkbDescPtr xkb,xkbGetMapReply * rep)301 _XkbReadKeyBehaviors(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep)
302 {
303 register int i;
304
305 if (rep->totalKeyBehaviors > 0) {
306 int size = xkb->max_key_code + 1;
307
308 if (((int) rep->firstKeyBehavior + rep->nKeyBehaviors) > size)
309 return BadLength;
310 if (xkb->server->behaviors == NULL) {
311 xkb->server->behaviors = _XkbTypedCalloc(size, XkbBehavior);
312 if (xkb->server->behaviors == NULL)
313 return BadAlloc;
314 }
315 else {
316 bzero(&xkb->server->behaviors[rep->firstKeyBehavior],
317 (rep->nKeyBehaviors * sizeof(XkbBehavior)));
318 }
319 for (i = 0; i < rep->totalKeyBehaviors; i++) {
320 xkbBehaviorWireDesc *wire;
321
322 wire = (xkbBehaviorWireDesc *) _XkbGetReadBufferPtr(buf,
323 SIZEOF(xkbBehaviorWireDesc));
324 if (wire == NULL || wire->key >= size)
325 return BadLength;
326 xkb->server->behaviors[wire->key].type = wire->type;
327 xkb->server->behaviors[wire->key].data = wire->data;
328 }
329 }
330 return Success;
331 }
332
333 static Status
_XkbReadVirtualMods(XkbReadBufferPtr buf,XkbDescPtr xkb,xkbGetMapReply * rep)334 _XkbReadVirtualMods(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep)
335 {
336 if (rep->virtualMods) {
337 register int i, bit, nVMods;
338 register char *data;
339
340 for (i = nVMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
341 if (rep->virtualMods & bit)
342 nVMods++;
343 }
344 data = _XkbGetReadBufferPtr(buf, XkbPaddedSize(nVMods));
345 if (data == NULL)
346 return BadLength;
347 for (i = 0, bit = 1; (i < XkbNumVirtualMods) && (nVMods > 0);
348 i++, bit <<= 1) {
349 if (rep->virtualMods & bit) {
350 xkb->server->vmods[i] = *data++;
351 nVMods--;
352 }
353 }
354 }
355 return Success;
356 }
357
358 static Status
_XkbReadExplicitComponents(XkbReadBufferPtr buf,XkbDescPtr xkb,xkbGetMapReply * rep)359 _XkbReadExplicitComponents(XkbReadBufferPtr buf,
360 XkbDescPtr xkb,
361 xkbGetMapReply *rep)
362 {
363 register int i;
364 unsigned char *wire;
365
366 if (rep->totalKeyExplicit > 0) {
367 int size = xkb->max_key_code + 1;
368
369 if (((int) rep->firstKeyExplicit + rep->nKeyExplicit) > size)
370 return BadLength;
371 if (xkb->server->explicit == NULL) {
372 xkb->server->explicit = _XkbTypedCalloc(size, unsigned char);
373
374 if (xkb->server->explicit == NULL)
375 return BadAlloc;
376 }
377 else {
378 bzero(&xkb->server->explicit[rep->firstKeyExplicit],
379 rep->nKeyExplicit);
380 }
381 i = XkbPaddedSize(2 * rep->totalKeyExplicit);
382 wire = (unsigned char *) _XkbGetReadBufferPtr(buf, i);
383 if (!wire)
384 return BadLength;
385 for (i = 0; i < rep->totalKeyExplicit; i++, wire += 2) {
386 if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code)
387 return BadLength;
388 xkb->server->explicit[wire[0]] = wire[1];
389 }
390 }
391 return Success;
392 }
393
394 static Status
_XkbReadModifierMap(XkbReadBufferPtr buf,XkbDescPtr xkb,xkbGetMapReply * rep)395 _XkbReadModifierMap(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep)
396 {
397 register int i;
398 unsigned char *wire;
399
400 if (rep->totalModMapKeys > 0) {
401 if (((int) rep->firstModMapKey + rep->nModMapKeys) >
402 (xkb->max_key_code + 1))
403 return BadLength;
404 if ((xkb->map->modmap == NULL) &&
405 (XkbAllocClientMap(xkb, XkbModifierMapMask, 0) != Success)) {
406 return BadAlloc;
407 }
408 else {
409 bzero(&xkb->map->modmap[rep->firstModMapKey], rep->nModMapKeys);
410 }
411 i = XkbPaddedSize(2 * rep->totalModMapKeys);
412 wire = (unsigned char *) _XkbGetReadBufferPtr(buf, i);
413 if (!wire)
414 return BadLength;
415 for (i = 0; i < rep->totalModMapKeys; i++, wire += 2) {
416 if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code)
417 return BadLength;
418 xkb->map->modmap[wire[0]] = wire[1];
419 }
420 }
421 return Success;
422 }
423
424 static Status
_XkbReadVirtualModMap(XkbReadBufferPtr buf,XkbDescPtr xkb,xkbGetMapReply * rep)425 _XkbReadVirtualModMap(XkbReadBufferPtr buf,
426 XkbDescPtr xkb,
427 xkbGetMapReply *rep)
428 {
429 register int i;
430 xkbVModMapWireDesc *wire;
431 XkbServerMapPtr srv;
432
433 if (rep->totalVModMapKeys > 0) {
434 if (((int) rep->firstVModMapKey + rep->nVModMapKeys)
435 > xkb->max_key_code + 1)
436 return BadLength;
437 if (((xkb->server == NULL) || (xkb->server->vmodmap == NULL)) &&
438 (XkbAllocServerMap(xkb, XkbVirtualModMapMask, 0) != Success)) {
439 return BadAlloc;
440 }
441 else {
442 srv = xkb->server;
443 if (rep->nVModMapKeys > rep->firstVModMapKey)
444 bzero((char *) &srv->vmodmap[rep->firstVModMapKey],
445 (rep->nVModMapKeys - rep->firstVModMapKey) *
446 sizeof(unsigned short));
447 }
448 srv = xkb->server;
449 i = rep->totalVModMapKeys * SIZEOF(xkbVModMapWireDesc);
450 wire = (xkbVModMapWireDesc *) _XkbGetReadBufferPtr(buf, i);
451 if (!wire)
452 return BadLength;
453 for (i = 0; i < rep->totalVModMapKeys; i++, wire++) {
454 if ((wire->key >= xkb->min_key_code) &&
455 (wire->key <= xkb->max_key_code))
456 srv->vmodmap[wire->key] = wire->vmods;
457 }
458 }
459 return Success;
460 }
461
462 static xkbGetMapReq *
_XkbGetGetMapReq(Display * dpy,XkbDescPtr xkb)463 _XkbGetGetMapReq(Display *dpy, XkbDescPtr xkb)
464 {
465 xkbGetMapReq *req;
466
467 GetReq(kbGetMap, req);
468 req->reqType = dpy->xkb_info->codes->major_opcode;
469 req->xkbReqType = X_kbGetMap;
470 req->deviceSpec = xkb->device_spec;
471 req->full = req->partial = 0;
472 req->firstType = req->nTypes = 0;
473 req->firstKeySym = req->nKeySyms = 0;
474 req->firstKeyAct = req->nKeyActs = 0;
475 req->firstKeyBehavior = req->nKeyBehaviors = 0;
476 req->virtualMods = 0;
477 req->firstKeyExplicit = req->nKeyExplicit = 0;
478 req->firstModMapKey = req->nModMapKeys = 0;
479 req->firstVModMapKey = req->nVModMapKeys = 0;
480 return req;
481 }
482
483 Status
_XkbReadGetMapReply(Display * dpy,xkbGetMapReply * rep,XkbDescPtr xkb,int * nread_rtrn)484 _XkbReadGetMapReply(Display *dpy,
485 xkbGetMapReply *rep,
486 XkbDescPtr xkb,
487 int *nread_rtrn)
488 {
489 int extraData;
490 unsigned mask;
491
492 if (xkb->device_spec == XkbUseCoreKbd)
493 xkb->device_spec = rep->deviceID;
494 if (rep->maxKeyCode < rep->minKeyCode)
495 return BadImplementation;
496 xkb->min_key_code = rep->minKeyCode;
497 xkb->max_key_code = rep->maxKeyCode;
498
499 if (!xkb->map) {
500 mask = rep->present & XkbAllClientInfoMask;
501 if (mask && (XkbAllocClientMap(xkb, mask, rep->nTypes) != Success))
502 return BadAlloc;
503 }
504 if (!xkb->server) {
505 mask = rep->present & XkbAllServerInfoMask;
506 if (mask && (XkbAllocServerMap(xkb, mask, rep->totalActs) != Success))
507 return BadAlloc;
508 }
509 extraData = (int) (rep->length * 4);
510 extraData -= (SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply));
511 if (rep->length) {
512 XkbReadBufferRec buf;
513 int left;
514
515 if (_XkbInitReadBuffer(dpy, &buf, extraData)) {
516 Status status = Success;
517
518 if (nread_rtrn != NULL)
519 *nread_rtrn = extraData;
520 if (status == Success)
521 status = _XkbReadKeyTypes(&buf, xkb, rep);
522 if (status == Success)
523 status = _XkbReadKeySyms(&buf, xkb, rep);
524 if (status == Success)
525 status = _XkbReadKeyActions(&buf, xkb, rep);
526 if (status == Success)
527 status = _XkbReadKeyBehaviors(&buf, xkb, rep);
528 if (status == Success)
529 status = _XkbReadVirtualMods(&buf, xkb, rep);
530 if (status == Success)
531 status = _XkbReadExplicitComponents(&buf, xkb, rep);
532 if (status == Success)
533 status = _XkbReadModifierMap(&buf, xkb, rep);
534 if (status == Success)
535 status = _XkbReadVirtualModMap(&buf, xkb, rep);
536 left = _XkbFreeReadBuffer(&buf);
537 if (status != Success)
538 return status;
539 else if (left || buf.error)
540 return BadLength;
541 }
542 else
543 return BadAlloc;
544 }
545 return Success;
546 }
547
548 static Status
_XkbHandleGetMapReply(Display * dpy,XkbDescPtr xkb)549 _XkbHandleGetMapReply(Display *dpy, XkbDescPtr xkb)
550 {
551 xkbGetMapReply rep;
552
553 if (!_XReply(dpy, (xReply *) &rep,
554 ((SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)) >> 2),
555 xFalse)) {
556 return BadImplementation;
557 }
558 return _XkbReadGetMapReply(dpy, &rep, xkb, NULL);
559 }
560
561 Status
XkbGetUpdatedMap(Display * dpy,unsigned which,XkbDescPtr xkb)562 XkbGetUpdatedMap(Display *dpy, unsigned which, XkbDescPtr xkb)
563 {
564 if ((dpy->flags & XlibDisplayNoXkb) ||
565 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
566 return BadAccess;
567 if (which) {
568 register xkbGetMapReq *req;
569 Status status;
570
571 LockDisplay(dpy);
572
573 req = _XkbGetGetMapReq(dpy, xkb);
574 req->full = which;
575 status = _XkbHandleGetMapReply(dpy, xkb);
576
577 UnlockDisplay(dpy);
578 SyncHandle();
579 return status;
580 }
581 return Success;
582 }
583
584 XkbDescPtr
XkbGetMap(Display * dpy,unsigned which,unsigned deviceSpec)585 XkbGetMap(Display *dpy, unsigned which, unsigned deviceSpec)
586 {
587 XkbDescPtr xkb;
588
589 xkb = _XkbTypedCalloc(1, XkbDescRec);
590 if (xkb) {
591 xkb->device_spec = deviceSpec;
592 xkb->map = _XkbTypedCalloc(1, XkbClientMapRec);
593 if ((xkb->map == NULL) ||
594 ((which) && (XkbGetUpdatedMap(dpy, which, xkb) != Success))) {
595 if (xkb->map) {
596 Xfree(xkb->map);
597 xkb->map = NULL;
598 }
599 Xfree(xkb);
600 return NULL;
601 }
602 xkb->dpy = dpy;
603 }
604 return xkb;
605 }
606
607 Status
XkbGetKeyTypes(Display * dpy,unsigned first,unsigned num,XkbDescPtr xkb)608 XkbGetKeyTypes(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb)
609 {
610 register xkbGetMapReq *req;
611 Status status;
612
613 if ((dpy->flags & XlibDisplayNoXkb) ||
614 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
615 return BadAccess;
616 if ((num < 1) || (num > XkbMaxKeyTypes))
617 return BadValue;
618
619 LockDisplay(dpy);
620
621 req = _XkbGetGetMapReq(dpy, xkb);
622 req->firstType = first;
623 req->nTypes = num;
624 status = _XkbHandleGetMapReply(dpy, xkb);
625
626 UnlockDisplay(dpy);
627 SyncHandle();
628 return status;
629 }
630
631 Status
XkbGetKeyActions(Display * dpy,unsigned first,unsigned num,XkbDescPtr xkb)632 XkbGetKeyActions(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb)
633 {
634 register xkbGetMapReq *req;
635 Status status;
636
637 if ((dpy->flags & XlibDisplayNoXkb) ||
638 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
639 return BadAccess;
640
641 if ((num < 1) || (num > XkbMaxKeyCount))
642 return BadValue;
643
644 LockDisplay(dpy);
645
646 req = _XkbGetGetMapReq(dpy, xkb);
647 req->firstKeyAct = first;
648 req->nKeyActs = num;
649 status = _XkbHandleGetMapReply(dpy, xkb);
650
651 UnlockDisplay(dpy);
652 SyncHandle();
653 return status;
654 }
655
656 Status
XkbGetKeySyms(Display * dpy,unsigned first,unsigned num,XkbDescPtr xkb)657 XkbGetKeySyms(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb)
658 {
659 register xkbGetMapReq *req;
660 Status status;
661
662 if ((dpy->flags & XlibDisplayNoXkb) ||
663 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
664 return BadAccess;
665
666 if ((num < 1) || (num > XkbMaxKeyCount))
667 return BadValue;
668
669 LockDisplay(dpy);
670
671 req = _XkbGetGetMapReq(dpy, xkb);
672 req->firstKeySym = first;
673 req->nKeySyms = num;
674 status = _XkbHandleGetMapReply(dpy, xkb);
675
676 UnlockDisplay(dpy);
677 SyncHandle();
678
679 return status;
680 }
681
682 Status
XkbGetKeyBehaviors(Display * dpy,unsigned first,unsigned num,XkbDescPtr xkb)683 XkbGetKeyBehaviors(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb)
684 {
685 register xkbGetMapReq *req;
686 Status status;
687
688 if ((dpy->flags & XlibDisplayNoXkb) ||
689 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
690 return BadAccess;
691
692 if ((num < 1) || (num > XkbMaxKeyCount))
693 return BadValue;
694
695 LockDisplay(dpy);
696
697 req = _XkbGetGetMapReq(dpy, xkb);
698 req->firstKeyBehavior = first;
699 req->nKeyBehaviors = num;
700 status = _XkbHandleGetMapReply(dpy, xkb);
701
702 UnlockDisplay(dpy);
703 SyncHandle();
704 return status;
705 }
706
707 Status
XkbGetVirtualMods(Display * dpy,unsigned which,XkbDescPtr xkb)708 XkbGetVirtualMods(Display *dpy, unsigned which, XkbDescPtr xkb)
709 {
710 register xkbGetMapReq *req;
711 Status status;
712
713 if ((dpy->flags & XlibDisplayNoXkb) ||
714 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
715 return BadAccess;
716
717 LockDisplay(dpy);
718
719 req = _XkbGetGetMapReq(dpy, xkb);
720 req->virtualMods = which;
721 status = _XkbHandleGetMapReply(dpy, xkb);
722
723 UnlockDisplay(dpy);
724 SyncHandle();
725 return status;
726 }
727
728 Status
XkbGetKeyExplicitComponents(Display * dpy,unsigned first,unsigned num,XkbDescPtr xkb)729 XkbGetKeyExplicitComponents(Display *dpy,
730 unsigned first,
731 unsigned num,
732 XkbDescPtr xkb)
733 {
734 register xkbGetMapReq *req;
735 Status status;
736
737 if ((dpy->flags & XlibDisplayNoXkb) ||
738 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
739 return BadAccess;
740
741 if ((num < 1) || (num > XkbMaxKeyCount))
742 return BadValue;
743
744 LockDisplay(dpy);
745
746 req = _XkbGetGetMapReq(dpy, xkb);
747 req->firstKeyExplicit = first;
748 req->nKeyExplicit = num;
749 if ((xkb != NULL) && (xkb->server != NULL) &&
750 (xkb->server->explicit != NULL)) {
751 if ((num > 0) && (first >= xkb->min_key_code) &&
752 (first + num <= xkb->max_key_code))
753 bzero(&xkb->server->explicit[first], num);
754 }
755 if (xkb)
756 status = _XkbHandleGetMapReply(dpy, xkb);
757 else
758 status = BadMatch;
759
760 UnlockDisplay(dpy);
761 SyncHandle();
762 return status;
763 }
764
765 Status
XkbGetKeyModifierMap(Display * dpy,unsigned first,unsigned num,XkbDescPtr xkb)766 XkbGetKeyModifierMap(Display *dpy,
767 unsigned first,
768 unsigned num,
769 XkbDescPtr xkb)
770 {
771 register xkbGetMapReq *req;
772 Status status;
773
774 if ((dpy->flags & XlibDisplayNoXkb) ||
775 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
776 return BadAccess;
777
778 if ((num < 1) || (num > XkbMaxKeyCount))
779 return BadValue;
780
781 LockDisplay(dpy);
782
783 req = _XkbGetGetMapReq(dpy, xkb);
784 req->firstModMapKey = first;
785 req->nModMapKeys = num;
786 if ((xkb != NULL) && (xkb->map != NULL) && (xkb->map->modmap != NULL)) {
787 if ((num > 0) && (first >= xkb->min_key_code) &&
788 (first + num <= xkb->max_key_code))
789 bzero(&xkb->map->modmap[first], num);
790 }
791 if (xkb)
792 status = _XkbHandleGetMapReply(dpy, xkb);
793 else
794 status = BadMatch;
795
796 UnlockDisplay(dpy);
797 SyncHandle();
798 return status;
799 }
800
801 Status
XkbGetKeyVirtualModMap(Display * dpy,unsigned first,unsigned num,XkbDescPtr xkb)802 XkbGetKeyVirtualModMap(Display *dpy, unsigned first, unsigned num,
803 XkbDescPtr xkb)
804 {
805 register xkbGetMapReq *req;
806 Status status;
807
808 if ((dpy->flags & XlibDisplayNoXkb) ||
809 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
810 return BadAccess;
811
812 if ((num < 1) || (num > XkbMaxKeyCount))
813 return BadValue;
814
815 LockDisplay(dpy);
816
817 req = _XkbGetGetMapReq(dpy, xkb);
818 req->firstVModMapKey = first;
819 req->nVModMapKeys = num;
820 if ((xkb != NULL) && (xkb->map != NULL) && (xkb->map->modmap != NULL)) {
821 if ((num > 0) && (first >= xkb->min_key_code) &&
822 (first + num <= xkb->max_key_code))
823 bzero(&xkb->server->vmodmap[first], num * sizeof(unsigned short));
824 }
825
826 if (xkb)
827 status = _XkbHandleGetMapReply(dpy, xkb);
828 else
829 status = BadMatch;
830
831 UnlockDisplay(dpy);
832 SyncHandle();
833 return status;
834 }
835
836 Status
XkbGetMapChanges(Display * dpy,XkbDescPtr xkb,XkbMapChangesPtr changes)837 XkbGetMapChanges(Display *dpy, XkbDescPtr xkb, XkbMapChangesPtr changes)
838 {
839 xkbGetMapReq *req;
840
841 if ((dpy->flags & XlibDisplayNoXkb) ||
842 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
843 return BadAccess;
844 LockDisplay(dpy);
845 if (changes->changed) {
846 Status status = Success;
847
848 req = _XkbGetGetMapReq(dpy, xkb);
849 req->full = 0;
850 req->partial = changes->changed;
851 req->firstType = changes->first_type;
852 req->nTypes = changes->num_types;
853 req->firstKeySym = changes->first_key_sym;
854 req->nKeySyms = changes->num_key_syms;
855 req->firstKeyAct = changes->first_key_act;
856 req->nKeyActs = changes->num_key_acts;
857 req->firstKeyBehavior = changes->first_key_behavior;
858 req->nKeyBehaviors = changes->num_key_behaviors;
859 req->virtualMods = changes->vmods;
860 req->firstKeyExplicit = changes->first_key_explicit;
861 req->nKeyExplicit = changes->num_key_explicit;
862 req->firstModMapKey = changes->first_modmap_key;
863 req->nModMapKeys = changes->num_modmap_keys;
864 req->firstVModMapKey = changes->first_vmodmap_key;
865 req->nVModMapKeys = changes->num_vmodmap_keys;
866 status = _XkbHandleGetMapReply(dpy, xkb);
867 UnlockDisplay(dpy);
868 SyncHandle();
869 return status;
870 }
871 UnlockDisplay(dpy);
872 return Success;
873 }
874