1 /************************************************************
2 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
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.
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.
25 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
34 #include <X11/Xfuncs.h>
37 #include <X11/Xproto.h>
38 #include <X11/keysym.h>
39 #include <X11/extensions/XKMformat.h>
47 XkbInternAtom(char *str
, Bool only_if_exists
)
51 return MakeAtom(str
, strlen(str
), !only_if_exists
);
54 /***====================================================================***/
57 XkmInsureSize(void *oldPtr
, int oldCount
, int *newCountRtrn
, int elemSize
)
59 int newCount
= *newCountRtrn
;
64 oldPtr
= calloc(newCount
, elemSize
);
66 else if (oldCount
< newCount
) {
67 oldPtr
= realloc(oldPtr
, newCount
* elemSize
);
69 char *tmp
= (char *) oldPtr
;
71 memset(&tmp
[oldCount
* elemSize
], 0,
72 (newCount
- oldCount
) * elemSize
);
75 else if (newCount
< oldCount
) {
76 *newCountRtrn
= oldCount
;
81 #define XkmInsureTypedSize(p,o,n,t) ((p)=((t *)XkmInsureSize((char *)(p),(o),(n),sizeof(t))))
84 XkmGetCARD8(FILE * file
, int *pNRead
)
89 if (pNRead
&& (tmp
!= EOF
))
95 XkmGetCARD16(FILE * file
, int *pNRead
)
99 if ((fread(&val
, 2, 1, file
) == 1) && (pNRead
))
105 XkmGetCARD32(FILE * file
, int *pNRead
)
109 if ((fread(&val
, 4, 1, file
) == 1) && (pNRead
))
115 XkmSkipPadding(FILE * file
, unsigned pad
)
117 register int i
, nRead
= 0;
119 for (i
= 0; i
< pad
; i
++) {
120 if (getc(file
) != EOF
)
127 XkmGetCountedString(FILE * file
, char *str
, int max_len
)
129 int count
, nRead
= 0;
131 count
= XkmGetCARD16(file
, &nRead
);
135 if (count
> max_len
) {
136 tmp
= fread(str
, 1, max_len
, file
);
137 while (tmp
< count
) {
138 if ((getc(file
)) != EOF
)
145 tmp
= fread(str
, 1, count
, file
);
149 if (count
>= max_len
)
150 str
[max_len
- 1] = '\0';
153 count
= XkbPaddedSize(nRead
) - nRead
;
155 nRead
+= XkmSkipPadding(file
, count
);
159 /***====================================================================***/
162 ReadXkmVirtualMods(FILE * file
, XkbDescPtr xkb
, XkbChangesPtr changes
)
164 register unsigned int i
, bit
;
165 unsigned int bound
, named
, tmp
;
168 if (XkbAllocServerMap(xkb
, XkbVirtualModsMask
, 0) != Success
) {
169 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmVirtualMods", 0);
172 bound
= XkmGetCARD16(file
, &nRead
);
173 named
= XkmGetCARD16(file
, &nRead
);
174 for (i
= tmp
= 0, bit
= 1; i
< XkbNumVirtualMods
; i
++, bit
<<= 1) {
176 xkb
->server
->vmods
[i
] = XkmGetCARD8(file
, &nRead
);
178 changes
->map
.vmods
|= bit
;
182 if ((i
= XkbPaddedSize(tmp
) - tmp
) > 0)
183 nRead
+= XkmSkipPadding(file
, i
);
184 if (XkbAllocNames(xkb
, XkbVirtualModNamesMask
, 0, 0) != Success
) {
185 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmVirtualMods", 0);
188 for (i
= 0, bit
= 1; i
< XkbNumVirtualMods
; i
++, bit
<<= 1) {
192 if (nRead
+= XkmGetCountedString(file
, name
, 100)) {
193 xkb
->names
->vmods
[i
] = XkbInternAtom(name
, FALSE
);
195 changes
->names
.changed_vmods
|= bit
;
202 /***====================================================================***/
205 ReadXkmKeycodes(FILE * file
, XkbDescPtr xkb
, XkbChangesPtr changes
)
208 unsigned minKC
, maxKC
, nAl
;
214 nRead
+= XkmGetCountedString(file
, name
, 100);
215 minKC
= XkmGetCARD8(file
, &nRead
);
216 maxKC
= XkmGetCARD8(file
, &nRead
);
217 if (xkb
->min_key_code
== 0) {
218 xkb
->min_key_code
= minKC
;
219 xkb
->max_key_code
= maxKC
;
222 if (minKC
< xkb
->min_key_code
)
223 xkb
->min_key_code
= minKC
;
224 if (maxKC
> xkb
->max_key_code
) {
225 _XkbLibError(_XkbErrBadValue
, "ReadXkmKeycodes", maxKC
);
229 nAl
= XkmGetCARD8(file
, &nRead
);
230 nRead
+= XkmSkipPadding(file
, 1);
232 #define WANTED (XkbKeycodesNameMask|XkbKeyNamesMask|XkbKeyAliasesMask)
233 if (XkbAllocNames(xkb
, WANTED
, 0, nAl
) != Success
) {
234 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmKeycodes", 0);
237 if (name
[0] != '\0') {
238 xkb
->names
->keycodes
= XkbInternAtom(name
, FALSE
);
241 for (pN
= &xkb
->names
->keys
[minKC
], i
= minKC
; i
<= (int) maxKC
; i
++, pN
++) {
242 if (fread(pN
, 1, XkbKeyNameLength
, file
) != XkbKeyNameLength
) {
243 _XkbLibError(_XkbErrBadLength
, "ReadXkmKeycodes", 0);
246 nRead
+= XkbKeyNameLength
;
251 for (pAl
= xkb
->names
->key_aliases
, i
= 0; i
< nAl
; i
++, pAl
++) {
254 tmp
= fread(pAl
, 1, 2 * XkbKeyNameLength
, file
);
255 if (tmp
!= 2 * XkbKeyNameLength
) {
256 _XkbLibError(_XkbErrBadLength
, "ReadXkmKeycodes", 0);
259 nRead
+= 2 * XkbKeyNameLength
;
262 changes
->names
.changed
|= XkbKeyAliasesMask
;
265 changes
->names
.changed
|= XkbKeyNamesMask
;
269 /***====================================================================***/
272 ReadXkmKeyTypes(FILE * file
, XkbDescPtr xkb
, XkbChangesPtr changes
)
274 register unsigned i
, n
;
280 XkbKTMapEntryPtr entry
;
281 xkmKTMapEntryDesc wire_entry
;
284 if ((tmp
= XkmGetCountedString(file
, buf
, 100)) < 1) {
285 _XkbLibError(_XkbErrBadLength
, "ReadXkmKeyTypes", 0);
289 if (buf
[0] != '\0') {
290 if (XkbAllocNames(xkb
, XkbTypesNameMask
, 0, 0) != Success
) {
291 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmKeyTypes", 0);
294 xkb
->names
->types
= XkbInternAtom(buf
, FALSE
);
296 num_types
= XkmGetCARD16(file
, &nRead
);
297 nRead
+= XkmSkipPadding(file
, 2);
300 if (XkbAllocClientMap(xkb
, XkbKeyTypesMask
, num_types
) != Success
) {
301 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmKeyTypes", 0);
304 xkb
->map
->num_types
= num_types
;
305 if (num_types
< XkbNumRequiredTypes
) {
306 _XkbLibError(_XkbErrMissingReqTypes
, "ReadXkmKeyTypes", 0);
309 type
= xkb
->map
->types
;
310 for (i
= 0; i
< num_types
; i
++, type
++) {
311 if ((int) fread(&wire
, SIZEOF(xkmKeyTypeDesc
), 1, file
) < 1) {
312 _XkbLibError(_XkbErrBadLength
, "ReadXkmKeyTypes", 0);
315 nRead
+= SIZEOF(xkmKeyTypeDesc
);
316 if (((i
== XkbOneLevelIndex
) && (wire
.numLevels
!= 1)) ||
317 (((i
== XkbTwoLevelIndex
) || (i
== XkbAlphabeticIndex
) ||
318 ((i
) == XkbKeypadIndex
)) && (wire
.numLevels
!= 2))) {
319 _XkbLibError(_XkbErrBadTypeWidth
, "ReadXkmKeyTypes", i
);
322 tmp
= wire
.nMapEntries
;
323 XkmInsureTypedSize(type
->map
, type
->map_count
, &tmp
, XkbKTMapEntryRec
);
324 if ((wire
.nMapEntries
> 0) && (type
->map
== NULL
)) {
325 _XkbLibError(_XkbErrBadValue
, "ReadXkmKeyTypes", wire
.nMapEntries
);
328 for (n
= 0, entry
= type
->map
; n
< wire
.nMapEntries
; n
++, entry
++) {
329 if (fread(&wire_entry
, SIZEOF(xkmKTMapEntryDesc
), 1, file
) <
331 _XkbLibError(_XkbErrBadLength
, "ReadXkmKeyTypes", 0);
334 nRead
+= SIZEOF(xkmKTMapEntryDesc
);
335 entry
->active
= (wire_entry
.virtualMods
== 0);
336 entry
->level
= wire_entry
.level
;
337 entry
->mods
.mask
= wire_entry
.realMods
;
338 entry
->mods
.real_mods
= wire_entry
.realMods
;
339 entry
->mods
.vmods
= wire_entry
.virtualMods
;
341 nRead
+= XkmGetCountedString(file
, buf
, 100);
342 if (((i
== XkbOneLevelIndex
) && (strcmp(buf
, "ONE_LEVEL") != 0)) ||
343 ((i
== XkbTwoLevelIndex
) && (strcmp(buf
, "TWO_LEVEL") != 0)) ||
344 ((i
== XkbAlphabeticIndex
) && (strcmp(buf
, "ALPHABETIC") != 0)) ||
345 ((i
== XkbKeypadIndex
) && (strcmp(buf
, "KEYPAD") != 0))) {
346 _XkbLibError(_XkbErrBadTypeName
, "ReadXkmKeyTypes", 0);
349 if (buf
[0] != '\0') {
350 type
->name
= XkbInternAtom(buf
, FALSE
);
359 XkmInsureTypedSize(type
->preserve
, type
->map_count
, &tmp
,
361 if (type
->preserve
== NULL
) {
362 _XkbLibError(_XkbErrBadMatch
, "ReadXkmKeycodes", 0);
365 for (n
= 0, pre
= type
->preserve
; n
< wire
.nMapEntries
; n
++, pre
++) {
366 if (fread(&p_entry
, SIZEOF(xkmModsDesc
), 1, file
) < 1) {
367 _XkbLibError(_XkbErrBadLength
, "ReadXkmKeycodes", 0);
370 nRead
+= SIZEOF(xkmModsDesc
);
371 pre
->mask
= p_entry
.realMods
;
372 pre
->real_mods
= p_entry
.realMods
;
373 pre
->vmods
= p_entry
.virtualMods
;
376 if (wire
.nLevelNames
> 0) {
377 int width
= wire
.numLevels
;
379 if (wire
.nLevelNames
> (unsigned) width
) {
380 _XkbLibError(_XkbErrBadMatch
, "ReadXkmKeycodes", 0);
383 XkmInsureTypedSize(type
->level_names
, type
->num_levels
, &width
,
385 if (type
->level_names
!= NULL
) {
386 for (n
= 0; n
< wire
.nLevelNames
; n
++) {
387 if ((tmp
= XkmGetCountedString(file
, buf
, 100)) < 1)
390 if (strlen(buf
) == 0)
391 type
->level_names
[n
] = None
;
393 type
->level_names
[n
] = XkbInternAtom(buf
, 0);
397 type
->mods
.mask
= wire
.realMods
;
398 type
->mods
.real_mods
= wire
.realMods
;
399 type
->mods
.vmods
= wire
.virtualMods
;
400 type
->num_levels
= wire
.numLevels
;
401 type
->map_count
= wire
.nMapEntries
;
404 changes
->map
.changed
|= XkbKeyTypesMask
;
405 changes
->map
.first_type
= 0;
406 changes
->map
.num_types
= xkb
->map
->num_types
;
411 /***====================================================================***/
414 ReadXkmCompatMap(FILE * file
, XkbDescPtr xkb
, XkbChangesPtr changes
)
417 unsigned num_si
, groups
;
419 XkbSymInterpretPtr interp
;
420 xkmSymInterpretDesc wire
;
423 XkbCompatMapPtr compat
;
426 if ((tmp
= XkmGetCountedString(file
, name
, 100)) < 1) {
427 _XkbLibError(_XkbErrBadLength
, "ReadXkmCompatMap", 0);
431 if (name
[0] != '\0') {
432 if (XkbAllocNames(xkb
, XkbCompatNameMask
, 0, 0) != Success
) {
433 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmCompatMap", 0);
436 xkb
->names
->compat
= XkbInternAtom(name
, FALSE
);
438 num_si
= XkmGetCARD16(file
, &nRead
);
439 groups
= XkmGetCARD8(file
, &nRead
);
440 nRead
+= XkmSkipPadding(file
, 1);
441 if (XkbAllocCompatMap(xkb
, XkbAllCompatMask
, num_si
) != Success
)
443 compat
= xkb
->compat
;
445 interp
= compat
->sym_interpret
;
446 for (i
= 0; i
< num_si
; i
++) {
447 tmp
= fread(&wire
, SIZEOF(xkmSymInterpretDesc
), 1, file
);
448 nRead
+= tmp
* SIZEOF(xkmSymInterpretDesc
);
449 interp
->sym
= wire
.sym
;
450 interp
->mods
= wire
.mods
;
451 interp
->match
= wire
.match
;
452 interp
->virtual_mod
= wire
.virtualMod
;
453 interp
->flags
= wire
.flags
;
454 interp
->act
.type
= wire
.actionType
;
455 act
= (XkbAction
*) &interp
->act
;
457 switch (interp
->act
.type
) {
459 case XkbSA_LatchMods
:
461 act
->mods
.flags
= wire
.actionData
[0];
462 act
->mods
.mask
= wire
.actionData
[1];
463 act
->mods
.real_mods
= wire
.actionData
[2];
464 act
->mods
.vmods1
= wire
.actionData
[3];
465 act
->mods
.vmods2
= wire
.actionData
[4];
468 case XkbSA_LatchGroup
:
469 case XkbSA_LockGroup
:
470 act
->group
.flags
= wire
.actionData
[0];
471 act
->group
.group_XXX
= wire
.actionData
[1];
474 act
->ptr
.flags
= wire
.actionData
[0];
475 act
->ptr
.high_XXX
= wire
.actionData
[1];
476 act
->ptr
.low_XXX
= wire
.actionData
[2];
477 act
->ptr
.high_YYY
= wire
.actionData
[3];
478 act
->ptr
.low_YYY
= wire
.actionData
[4];
481 case XkbSA_LockPtrBtn
:
482 act
->btn
.flags
= wire
.actionData
[0];
483 act
->btn
.count
= wire
.actionData
[1];
484 act
->btn
.button
= wire
.actionData
[2];
486 case XkbSA_DeviceBtn
:
487 case XkbSA_LockDeviceBtn
:
488 act
->devbtn
.flags
= wire
.actionData
[0];
489 act
->devbtn
.count
= wire
.actionData
[1];
490 act
->devbtn
.button
= wire
.actionData
[2];
491 act
->devbtn
.device
= wire
.actionData
[3];
493 case XkbSA_SetPtrDflt
:
494 act
->dflt
.flags
= wire
.actionData
[0];
495 act
->dflt
.affect
= wire
.actionData
[1];
496 act
->dflt
.valueXXX
= wire
.actionData
[2];
499 act
->iso
.flags
= wire
.actionData
[0];
500 act
->iso
.mask
= wire
.actionData
[1];
501 act
->iso
.real_mods
= wire
.actionData
[2];
502 act
->iso
.group_XXX
= wire
.actionData
[3];
503 act
->iso
.affect
= wire
.actionData
[4];
504 act
->iso
.vmods1
= wire
.actionData
[5];
505 act
->iso
.vmods2
= wire
.actionData
[6];
507 case XkbSA_SwitchScreen
:
508 act
->screen
.flags
= wire
.actionData
[0];
509 act
->screen
.screenXXX
= wire
.actionData
[1];
511 case XkbSA_SetControls
:
512 case XkbSA_LockControls
:
513 act
->ctrls
.flags
= wire
.actionData
[0];
514 act
->ctrls
.ctrls3
= wire
.actionData
[1];
515 act
->ctrls
.ctrls2
= wire
.actionData
[2];
516 act
->ctrls
.ctrls1
= wire
.actionData
[3];
517 act
->ctrls
.ctrls0
= wire
.actionData
[4];
519 case XkbSA_RedirectKey
:
520 act
->redirect
.new_key
= wire
.actionData
[0];
521 act
->redirect
.mods_mask
= wire
.actionData
[1];
522 act
->redirect
.mods
= wire
.actionData
[2];
523 act
->redirect
.vmods_mask0
= wire
.actionData
[3];
524 act
->redirect
.vmods_mask1
= wire
.actionData
[4];
525 act
->redirect
.vmods0
= wire
.actionData
[4];
526 act
->redirect
.vmods1
= wire
.actionData
[5];
528 case XkbSA_DeviceValuator
:
529 act
->devval
.device
= wire
.actionData
[0];
530 act
->devval
.v1_what
= wire
.actionData
[1];
531 act
->devval
.v1_ndx
= wire
.actionData
[2];
532 act
->devval
.v1_value
= wire
.actionData
[3];
533 act
->devval
.v2_what
= wire
.actionData
[4];
534 act
->devval
.v2_ndx
= wire
.actionData
[5];
535 act
->devval
.v2_what
= wire
.actionData
[6];
538 case XkbSA_XFree86Private
:
540 * Bugfix for broken xkbcomp: if we encounter an XFree86Private
541 * action with Any+AnyOfOrNone(All), then we skip the interp as
542 * broken. Versions of xkbcomp below 1.2.2 had a bug where they
543 * would interpret a symbol that couldn't be found in an interpret
544 * as Any. So, an XF86LogWindowTree+AnyOfOrNone(All) interp that
545 * triggered the PrWins action would make every key without an
546 * action trigger PrWins if libX11 didn't yet know about the
547 * XF86LogWindowTree keysym. None too useful.
549 * We only do this for XFree86 actions, as the current XKB
550 * dataset relies on Any+AnyOfOrNone(All) -> SetMods for Ctrl in
553 * See xkbcomp commits 2a473b906943ffd807ad81960c47530ee7ae9a60 and
554 * 3caab5aa37decb7b5dc1642a0452efc3e1f5100e for more details.
556 if (interp
->sym
== NoSymbol
&& interp
->match
== XkbSI_AnyOfOrNone
&&
557 (interp
->mods
& 0xff) == 0xff) {
558 ErrorF("XKB: Skipping broken Any+AnyOfOrNone(All) -> Private "
559 "action from compiled keymap\n");
562 /* copy the kind of action */
563 memcpy(act
->any
.data
, wire
.actionData
, XkbAnyActionDataSize
);
566 case XkbSA_Terminate
:
567 /* no args, kinda (note: untrue for xfree86). */
569 case XkbSA_ActionMessage
:
576 if ((num_si
> 0) && (changes
)) {
577 changes
->compat
.first_si
= 0;
578 changes
->compat
.num_si
= compat
->num_si
;
581 register unsigned bit
;
583 for (i
= 0, bit
= 1; i
< XkbNumKbdGroups
; i
++, bit
<<= 1) {
587 tmp
= fread(&md
, SIZEOF(xkmModsDesc
), 1, file
);
588 nRead
+= tmp
* SIZEOF(xkmModsDesc
);
589 xkb
->compat
->groups
[i
].real_mods
= md
.realMods
;
590 xkb
->compat
->groups
[i
].vmods
= md
.virtualMods
;
591 if (md
.virtualMods
!= 0) {
594 if (XkbVirtualModsToReal(xkb
, md
.virtualMods
, &mask
))
595 xkb
->compat
->groups
[i
].mask
= md
.realMods
| mask
;
598 xkb
->compat
->groups
[i
].mask
= md
.realMods
;
602 changes
->compat
.changed_groups
|= groups
;
608 ReadXkmIndicators(FILE * file
, XkbDescPtr xkb
, XkbChangesPtr changes
)
610 register unsigned nLEDs
;
611 xkmIndicatorMapDesc wire
;
616 if ((xkb
->indicators
== NULL
) && (XkbAllocIndicatorMaps(xkb
) != Success
)) {
617 _XkbLibError(_XkbErrBadAlloc
, "indicator rec", 0);
620 if (XkbAllocNames(xkb
, XkbIndicatorNamesMask
, 0, 0) != Success
) {
621 _XkbLibError(_XkbErrBadAlloc
, "indicator names", 0);
624 nLEDs
= XkmGetCARD8(file
, &nRead
);
625 nRead
+= XkmSkipPadding(file
, 3);
626 xkb
->indicators
->phys_indicators
= XkmGetCARD32(file
, &nRead
);
627 while (nLEDs
-- > 0) {
629 XkbIndicatorMapPtr map
;
631 if ((tmp
= XkmGetCountedString(file
, buf
, 100)) < 1) {
632 _XkbLibError(_XkbErrBadLength
, "ReadXkmIndicators", 0);
637 name
= XkbInternAtom(buf
, FALSE
);
640 if ((tmp
= fread(&wire
, SIZEOF(xkmIndicatorMapDesc
), 1, file
)) < 1) {
641 _XkbLibError(_XkbErrBadLength
, "ReadXkmIndicators", 0);
644 nRead
+= tmp
* SIZEOF(xkmIndicatorMapDesc
);
646 xkb
->names
->indicators
[wire
.indicator
- 1] = name
;
648 changes
->names
.changed_indicators
|=
649 (1 << (wire
.indicator
- 1));
651 map
= &xkb
->indicators
->maps
[wire
.indicator
- 1];
652 map
->flags
= wire
.flags
;
653 map
->which_groups
= wire
.which_groups
;
654 map
->groups
= wire
.groups
;
655 map
->which_mods
= wire
.which_mods
;
656 map
->mods
.mask
= wire
.real_mods
;
657 map
->mods
.real_mods
= wire
.real_mods
;
658 map
->mods
.vmods
= wire
.vmods
;
659 map
->ctrls
= wire
.ctrls
;
665 FindTypeForKey(XkbDescPtr xkb
, Atom name
, unsigned width
, KeySym
* syms
)
667 if ((!xkb
) || (!xkb
->map
))
672 for (i
= 0; i
< xkb
->map
->num_types
; i
++) {
673 if (xkb
->map
->types
[i
].name
== name
) {
674 if (xkb
->map
->types
[i
].num_levels
!= width
)
675 DebugF("Group width mismatch between key and type\n");
676 return &xkb
->map
->types
[i
];
680 if ((width
< 2) || ((syms
!= NULL
) && (syms
[1] == NoSymbol
)))
681 return &xkb
->map
->types
[XkbOneLevelIndex
];
683 if (XkbKSIsLower(syms
[0]) && XkbKSIsUpper(syms
[1]))
684 return &xkb
->map
->types
[XkbAlphabeticIndex
];
685 else if (XkbKSIsKeypad(syms
[0]) || XkbKSIsKeypad(syms
[1]))
686 return &xkb
->map
->types
[XkbKeypadIndex
];
688 return &xkb
->map
->types
[XkbTwoLevelIndex
];
692 ReadXkmSymbols(FILE * file
, XkbDescPtr xkb
)
694 register int i
, g
, s
, totalVModMaps
;
695 xkmKeySymMapDesc wireMap
;
697 unsigned minKC
, maxKC
, groupNames
, tmp
;
700 if ((tmp
= XkmGetCountedString(file
, buf
, 100)) < 1)
703 minKC
= XkmGetCARD8(file
, &nRead
);
704 maxKC
= XkmGetCARD8(file
, &nRead
);
705 groupNames
= XkmGetCARD8(file
, &nRead
);
706 totalVModMaps
= XkmGetCARD8(file
, &nRead
);
707 if (XkbAllocNames(xkb
,
708 XkbSymbolsNameMask
| XkbPhysSymbolsNameMask
|
709 XkbGroupNamesMask
, 0, 0) != Success
) {
710 _XkbLibError(_XkbErrBadAlloc
, "physical names", 0);
713 if ((buf
[0] != '\0') && (xkb
->names
)) {
716 name
= XkbInternAtom(buf
, 0);
717 xkb
->names
->symbols
= name
;
718 xkb
->names
->phys_symbols
= name
;
720 for (i
= 0, g
= 1; i
< XkbNumKbdGroups
; i
++, g
<<= 1) {
721 if (groupNames
& g
) {
722 if ((tmp
= XkmGetCountedString(file
, buf
, 100)) < 1)
729 if (buf
[0] != '\0') {
732 name
= XkbInternAtom(buf
, 0);
733 xkb
->names
->groups
[i
] = name
;
736 xkb
->names
->groups
[i
] = None
;
739 if (XkbAllocServerMap(xkb
, XkbAllServerInfoMask
, 0) != Success
) {
740 _XkbLibError(_XkbErrBadAlloc
, "server map", 0);
743 if (XkbAllocClientMap(xkb
, XkbAllClientInfoMask
, 0) != Success
) {
744 _XkbLibError(_XkbErrBadAlloc
, "client map", 0);
747 if (XkbAllocControls(xkb
, XkbAllControlsMask
) != Success
) {
748 _XkbLibError(_XkbErrBadAlloc
, "controls", 0);
751 if ((xkb
->map
== NULL
) || (xkb
->server
== NULL
))
753 if (xkb
->min_key_code
< 8)
754 xkb
->min_key_code
= minKC
;
755 if (xkb
->max_key_code
< 8)
756 xkb
->max_key_code
= maxKC
;
757 if ((minKC
>= 8) && (minKC
< xkb
->min_key_code
))
758 xkb
->min_key_code
= minKC
;
759 if ((maxKC
>= 8) && (maxKC
> xkb
->max_key_code
)) {
760 _XkbLibError(_XkbErrBadValue
, "keys in symbol map", maxKC
);
763 for (i
= minKC
; i
<= (int) maxKC
; i
++) {
764 Atom typeName
[XkbNumKbdGroups
];
765 XkbKeyTypePtr type
[XkbNumKbdGroups
];
767 if ((tmp
= fread(&wireMap
, SIZEOF(xkmKeySymMapDesc
), 1, file
)) < 1) {
768 _XkbLibError(_XkbErrBadLength
, "ReadXkmSymbols", 0);
771 nRead
+= tmp
* SIZEOF(xkmKeySymMapDesc
);
772 memset((char *) typeName
, 0, XkbNumKbdGroups
* sizeof(Atom
));
773 memset((char *) type
, 0, XkbNumKbdGroups
* sizeof(XkbKeyTypePtr
));
774 if (wireMap
.flags
& XkmKeyHasTypes
) {
775 for (g
= 0; g
< XkbNumKbdGroups
; g
++) {
776 if ((wireMap
.flags
& (1 << g
)) &&
777 ((tmp
= XkmGetCountedString(file
, buf
, 100)) > 0)) {
778 typeName
[g
] = XkbInternAtom(buf
, 1);
781 type
[g
] = FindTypeForKey(xkb
, typeName
[g
], wireMap
.width
, NULL
);
782 if (type
[g
] == NULL
) {
783 _XkbLibError(_XkbErrMissingTypes
, "ReadXkmSymbols", 0);
786 if (typeName
[g
] == type
[g
]->name
)
787 xkb
->server
->explicit[i
] |= (1 << g
);
790 if (wireMap
.flags
& XkmRepeatingKey
) {
791 xkb
->ctrls
->per_key_repeat
[i
/ 8] |= (1 << (i
% 8));
792 xkb
->server
->explicit[i
] |= XkbExplicitAutoRepeatMask
;
794 else if (wireMap
.flags
& XkmNonRepeatingKey
) {
795 xkb
->ctrls
->per_key_repeat
[i
/ 8] &= ~(1 << (i
% 8));
796 xkb
->server
->explicit[i
] |= XkbExplicitAutoRepeatMask
;
798 xkb
->map
->modmap
[i
] = wireMap
.modifier_map
;
799 if (XkbNumGroups(wireMap
.num_groups
) > 0) {
803 if (XkbNumGroups(wireMap
.num_groups
) > xkb
->ctrls
->num_groups
)
804 xkb
->ctrls
->num_groups
= wireMap
.num_groups
;
805 nSyms
= XkbNumGroups(wireMap
.num_groups
) * wireMap
.width
;
806 sym
= XkbResizeKeySyms(xkb
, i
, nSyms
);
809 for (s
= 0; s
< nSyms
; s
++) {
810 *sym
++ = XkmGetCARD32(file
, &nRead
);
812 if (wireMap
.flags
& XkmKeyHasActions
) {
815 act
= XkbResizeKeyActions(xkb
, i
, nSyms
);
816 for (s
= 0; s
< nSyms
; s
++, act
++) {
817 tmp
= fread(act
, SIZEOF(xkmActionDesc
), 1, file
);
818 nRead
+= tmp
* SIZEOF(xkmActionDesc
);
820 xkb
->server
->explicit[i
] |= XkbExplicitInterpretMask
;
823 for (g
= 0; g
< XkbNumGroups(wireMap
.num_groups
); g
++) {
824 if (((xkb
->server
->explicit[i
] & (1 << g
)) == 0) ||
828 tmpSyms
= XkbKeySymsPtr(xkb
, i
) + (wireMap
.width
* g
);
829 type
[g
] = FindTypeForKey(xkb
, None
, wireMap
.width
, tmpSyms
);
831 xkb
->map
->key_sym_map
[i
].kt_index
[g
] =
832 type
[g
] - (&xkb
->map
->types
[0]);
834 xkb
->map
->key_sym_map
[i
].group_info
= wireMap
.num_groups
;
835 xkb
->map
->key_sym_map
[i
].width
= wireMap
.width
;
836 if (wireMap
.flags
& XkmKeyHasBehavior
) {
839 tmp
= fread(&b
, SIZEOF(xkmBehaviorDesc
), 1, file
);
840 nRead
+= tmp
* SIZEOF(xkmBehaviorDesc
);
841 xkb
->server
->behaviors
[i
].type
= b
.type
;
842 xkb
->server
->behaviors
[i
].data
= b
.data
;
843 xkb
->server
->explicit[i
] |= XkbExplicitBehaviorMask
;
846 if (totalVModMaps
> 0) {
849 for (i
= 0; i
< totalVModMaps
; i
++) {
850 tmp
= fread(&v
, SIZEOF(xkmVModMapDesc
), 1, file
);
851 nRead
+= tmp
* SIZEOF(xkmVModMapDesc
);
853 xkb
->server
->vmodmap
[v
.key
] = v
.vmods
;
860 ReadXkmGeomDoodad(FILE * file
, XkbGeometryPtr geom
, XkbSectionPtr section
)
863 xkmDoodadDesc doodadWire
;
868 nRead
+= XkmGetCountedString(file
, buf
, 100);
869 tmp
= fread(&doodadWire
, SIZEOF(xkmDoodadDesc
), 1, file
);
870 nRead
+= SIZEOF(xkmDoodadDesc
) * tmp
;
871 doodad
= XkbAddGeomDoodad(geom
, section
, XkbInternAtom(buf
, FALSE
));
874 doodad
->any
.type
= doodadWire
.any
.type
;
875 doodad
->any
.priority
= doodadWire
.any
.priority
;
876 doodad
->any
.top
= doodadWire
.any
.top
;
877 doodad
->any
.left
= doodadWire
.any
.left
;
878 switch (doodadWire
.any
.type
) {
879 case XkbOutlineDoodad
:
881 doodad
->shape
.angle
= doodadWire
.shape
.angle
;
882 doodad
->shape
.color_ndx
= doodadWire
.shape
.color_ndx
;
883 doodad
->shape
.shape_ndx
= doodadWire
.shape
.shape_ndx
;
886 doodad
->text
.angle
= doodadWire
.text
.angle
;
887 doodad
->text
.width
= doodadWire
.text
.width
;
888 doodad
->text
.height
= doodadWire
.text
.height
;
889 doodad
->text
.color_ndx
= doodadWire
.text
.color_ndx
;
890 nRead
+= XkmGetCountedString(file
, buf
, 100);
891 doodad
->text
.text
= Xstrdup(buf
);
892 nRead
+= XkmGetCountedString(file
, buf
, 100);
893 doodad
->text
.font
= Xstrdup(buf
);
895 case XkbIndicatorDoodad
:
896 doodad
->indicator
.shape_ndx
= doodadWire
.indicator
.shape_ndx
;
897 doodad
->indicator
.on_color_ndx
= doodadWire
.indicator
.on_color_ndx
;
898 doodad
->indicator
.off_color_ndx
= doodadWire
.indicator
.off_color_ndx
;
901 doodad
->logo
.angle
= doodadWire
.logo
.angle
;
902 doodad
->logo
.color_ndx
= doodadWire
.logo
.color_ndx
;
903 doodad
->logo
.shape_ndx
= doodadWire
.logo
.shape_ndx
;
904 nRead
+= XkmGetCountedString(file
, buf
, 100);
905 doodad
->logo
.logo_name
= Xstrdup(buf
);
915 ReadXkmGeomOverlay(FILE * file
, XkbGeometryPtr geom
, XkbSectionPtr section
)
921 XkbOverlayRowPtr row
;
922 xkmOverlayDesc olWire
;
923 xkmOverlayRowDesc rowWire
;
926 nRead
+= XkmGetCountedString(file
, buf
, 100);
927 tmp
= fread(&olWire
, SIZEOF(xkmOverlayDesc
), 1, file
);
928 nRead
+= tmp
* SIZEOF(xkmOverlayDesc
);
929 ol
= XkbAddGeomOverlay(section
, XkbInternAtom(buf
, FALSE
), olWire
.num_rows
);
932 for (r
= 0; r
< olWire
.num_rows
; r
++) {
934 xkmOverlayKeyDesc keyWire
;
936 tmp
= fread(&rowWire
, SIZEOF(xkmOverlayRowDesc
), 1, file
);
937 nRead
+= tmp
* SIZEOF(xkmOverlayRowDesc
);
938 row
= XkbAddGeomOverlayRow(ol
, rowWire
.row_under
, rowWire
.num_keys
);
940 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmGeomOverlay", 0);
943 for (k
= 0; k
< rowWire
.num_keys
; k
++) {
944 tmp
= fread(&keyWire
, SIZEOF(xkmOverlayKeyDesc
), 1, file
);
945 nRead
+= tmp
* SIZEOF(xkmOverlayKeyDesc
);
946 memcpy(row
->keys
[k
].over
.name
, keyWire
.over
, XkbKeyNameLength
);
947 memcpy(row
->keys
[k
].under
.name
, keyWire
.under
, XkbKeyNameLength
);
949 row
->num_keys
= rowWire
.num_keys
;
955 ReadXkmGeomSection(FILE * file
, XkbGeometryPtr geom
)
958 XkbSectionPtr section
;
959 xkmSectionDesc sectionWire
;
965 nRead
+= XkmGetCountedString(file
, buf
, 100);
966 nameAtom
= XkbInternAtom(buf
, FALSE
);
967 tmp
= fread(§ionWire
, SIZEOF(xkmSectionDesc
), 1, file
);
968 nRead
+= SIZEOF(xkmSectionDesc
) * tmp
;
969 section
= XkbAddGeomSection(geom
, nameAtom
, sectionWire
.num_rows
,
970 sectionWire
.num_doodads
,
971 sectionWire
.num_overlays
);
973 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmGeomSection", 0);
976 section
->top
= sectionWire
.top
;
977 section
->left
= sectionWire
.left
;
978 section
->width
= sectionWire
.width
;
979 section
->height
= sectionWire
.height
;
980 section
->angle
= sectionWire
.angle
;
981 section
->priority
= sectionWire
.priority
;
982 if (sectionWire
.num_rows
> 0) {
989 for (i
= 0; i
< sectionWire
.num_rows
; i
++) {
990 tmp
= fread(&rowWire
, SIZEOF(xkmRowDesc
), 1, file
);
991 nRead
+= SIZEOF(xkmRowDesc
) * tmp
;
992 row
= XkbAddGeomRow(section
, rowWire
.num_keys
);
994 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmKeycodes", 0);
997 row
->top
= rowWire
.top
;
998 row
->left
= rowWire
.left
;
999 row
->vertical
= rowWire
.vertical
;
1000 for (k
= 0; k
< rowWire
.num_keys
; k
++) {
1001 tmp
= fread(&keyWire
, SIZEOF(xkmKeyDesc
), 1, file
);
1002 nRead
+= SIZEOF(xkmKeyDesc
) * tmp
;
1003 key
= XkbAddGeomKey(row
);
1005 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmGeomSection", 0);
1008 memcpy(key
->name
.name
, keyWire
.name
, XkbKeyNameLength
);
1009 key
->gap
= keyWire
.gap
;
1010 key
->shape_ndx
= keyWire
.shape_ndx
;
1011 key
->color_ndx
= keyWire
.color_ndx
;
1015 if (sectionWire
.num_doodads
> 0) {
1016 for (i
= 0; i
< sectionWire
.num_doodads
; i
++) {
1017 tmp
= ReadXkmGeomDoodad(file
, geom
, section
);
1023 if (sectionWire
.num_overlays
> 0) {
1024 for (i
= 0; i
< sectionWire
.num_overlays
; i
++) {
1025 tmp
= ReadXkmGeomOverlay(file
, geom
, section
);
1035 ReadXkmGeometry(FILE * file
, XkbDescPtr xkb
)
1041 xkmGeometryDesc wireGeom
;
1042 XkbGeometryPtr geom
;
1043 XkbGeometrySizesRec sizes
;
1045 nRead
+= XkmGetCountedString(file
, buf
, 100);
1046 tmp
= fread(&wireGeom
, SIZEOF(xkmGeometryDesc
), 1, file
);
1047 nRead
+= tmp
* SIZEOF(xkmGeometryDesc
);
1048 sizes
.which
= XkbGeomAllMask
;
1049 sizes
.num_properties
= wireGeom
.num_properties
;
1050 sizes
.num_colors
= wireGeom
.num_colors
;
1051 sizes
.num_shapes
= wireGeom
.num_shapes
;
1052 sizes
.num_sections
= wireGeom
.num_sections
;
1053 sizes
.num_doodads
= wireGeom
.num_doodads
;
1054 sizes
.num_key_aliases
= wireGeom
.num_key_aliases
;
1055 if (XkbAllocGeometry(xkb
, &sizes
) != Success
) {
1056 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmGeometry", 0);
1060 geom
->name
= XkbInternAtom(buf
, FALSE
);
1061 geom
->width_mm
= wireGeom
.width_mm
;
1062 geom
->height_mm
= wireGeom
.height_mm
;
1063 nRead
+= XkmGetCountedString(file
, buf
, 100);
1064 geom
->label_font
= Xstrdup(buf
);
1065 if (wireGeom
.num_properties
> 0) {
1068 for (i
= 0; i
< wireGeom
.num_properties
; i
++) {
1069 nRead
+= XkmGetCountedString(file
, buf
, 100);
1070 nRead
+= XkmGetCountedString(file
, val
, 1024);
1071 if (XkbAddGeomProperty(geom
, buf
, val
) == NULL
) {
1072 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmGeometry", 0);
1077 if (wireGeom
.num_colors
> 0) {
1078 for (i
= 0; i
< wireGeom
.num_colors
; i
++) {
1079 nRead
+= XkmGetCountedString(file
, buf
, 100);
1080 if (XkbAddGeomColor(geom
, buf
, i
) == NULL
) {
1081 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmGeometry", 0);
1086 geom
->base_color
= &geom
->colors
[wireGeom
.base_color_ndx
];
1087 geom
->label_color
= &geom
->colors
[wireGeom
.label_color_ndx
];
1088 if (wireGeom
.num_shapes
> 0) {
1090 xkmShapeDesc shapeWire
;
1093 for (i
= 0; i
< wireGeom
.num_shapes
; i
++) {
1096 xkmOutlineDesc olWire
;
1098 nRead
+= XkmGetCountedString(file
, buf
, 100);
1099 nameAtom
= XkbInternAtom(buf
, FALSE
);
1100 tmp
= fread(&shapeWire
, SIZEOF(xkmShapeDesc
), 1, file
);
1101 nRead
+= tmp
* SIZEOF(xkmShapeDesc
);
1102 shape
= XkbAddGeomShape(geom
, nameAtom
, shapeWire
.num_outlines
);
1104 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmGeometry", 0);
1107 for (n
= 0; n
< shapeWire
.num_outlines
; n
++) {
1109 xkmPointDesc ptWire
;
1111 tmp
= fread(&olWire
, SIZEOF(xkmOutlineDesc
), 1, file
);
1112 nRead
+= tmp
* SIZEOF(xkmOutlineDesc
);
1113 ol
= XkbAddGeomOutline(shape
, olWire
.num_points
);
1115 _XkbLibError(_XkbErrBadAlloc
, "ReadXkmGeometry", 0);
1118 ol
->num_points
= olWire
.num_points
;
1119 ol
->corner_radius
= olWire
.corner_radius
;
1120 for (p
= 0; p
< olWire
.num_points
; p
++) {
1121 tmp
= fread(&ptWire
, SIZEOF(xkmPointDesc
), 1, file
);
1122 nRead
+= tmp
* SIZEOF(xkmPointDesc
);
1123 ol
->points
[p
].x
= ptWire
.x
;
1124 ol
->points
[p
].y
= ptWire
.y
;
1125 if (ptWire
.x
< shape
->bounds
.x1
)
1126 shape
->bounds
.x1
= ptWire
.x
;
1127 if (ptWire
.x
> shape
->bounds
.x2
)
1128 shape
->bounds
.x2
= ptWire
.x
;
1129 if (ptWire
.y
< shape
->bounds
.y1
)
1130 shape
->bounds
.y1
= ptWire
.y
;
1131 if (ptWire
.y
> shape
->bounds
.y2
)
1132 shape
->bounds
.y2
= ptWire
.y
;
1135 if (shapeWire
.primary_ndx
!= XkbNoShape
)
1136 shape
->primary
= &shape
->outlines
[shapeWire
.primary_ndx
];
1137 if (shapeWire
.approx_ndx
!= XkbNoShape
)
1138 shape
->approx
= &shape
->outlines
[shapeWire
.approx_ndx
];
1141 if (wireGeom
.num_sections
> 0) {
1142 for (i
= 0; i
< wireGeom
.num_sections
; i
++) {
1143 tmp
= ReadXkmGeomSection(file
, geom
);
1149 if (wireGeom
.num_doodads
> 0) {
1150 for (i
= 0; i
< wireGeom
.num_doodads
; i
++) {
1151 tmp
= ReadXkmGeomDoodad(file
, geom
, NULL
);
1157 if ((wireGeom
.num_key_aliases
> 0) && (geom
->key_aliases
)) {
1158 int sz
= XkbKeyNameLength
* 2;
1159 int num
= wireGeom
.num_key_aliases
;
1161 if (fread(geom
->key_aliases
, sz
, num
, file
) != num
) {
1162 _XkbLibError(_XkbErrBadLength
, "ReadXkmGeometry", 0);
1165 nRead
+= (num
* sz
);
1166 geom
->num_key_aliases
= num
;
1172 XkmProbe(FILE * file
)
1177 hdr
= (('x' << 24) | ('k' << 16) | ('m' << 8) | XkmFileVersion
);
1178 tmp
= XkmGetCARD32(file
, &nRead
);
1180 if ((tmp
& (~0xff)) == (hdr
& (~0xff))) {
1181 _XkbLibError(_XkbErrBadFileVersion
, "XkmProbe", tmp
& 0xff);
1189 XkmReadTOC(FILE * file
, xkmFileInfo
* file_info
, int max_toc
,
1190 xkmSectionInfo
* toc
)
1194 unsigned i
, size_toc
;
1196 hdr
= (('x' << 24) | ('k' << 16) | ('m' << 8) | XkmFileVersion
);
1197 tmp
= XkmGetCARD32(file
, &nRead
);
1199 if ((tmp
& (~0xff)) == (hdr
& (~0xff))) {
1200 _XkbLibError(_XkbErrBadFileVersion
, "XkmReadTOC", tmp
& 0xff);
1203 _XkbLibError(_XkbErrBadFileType
, "XkmReadTOC", tmp
);
1207 fread(file_info
, SIZEOF(xkmFileInfo
), 1, file
);
1208 size_toc
= file_info
->num_toc
;
1209 if (size_toc
> max_toc
) {
1210 DebugF("Warning! Too many TOC entries; last %d ignored\n",
1211 size_toc
- max_toc
);
1214 for (i
= 0; i
< size_toc
; i
++) {
1215 fread(&toc
[i
], SIZEOF(xkmSectionInfo
), 1, file
);
1220 /***====================================================================***/
1224 XkmReadFile(FILE * file
, unsigned need
, unsigned want
, XkbDescPtr
*xkb
)
1226 register unsigned i
;
1227 xkmSectionInfo toc
[MAX_TOC
], tmpTOC
;
1228 xkmFileInfo fileInfo
;
1229 unsigned tmp
, nRead
= 0;
1230 unsigned which
= need
| want
;
1232 if (!XkmReadTOC(file
, &fileInfo
, MAX_TOC
, toc
))
1234 if ((fileInfo
.present
& need
) != need
) {
1235 _XkbLibError(_XkbErrIllegalContents
, "XkmReadFile",
1236 need
& (~fileInfo
.present
));
1240 *xkb
= XkbAllocKeyboard();
1241 for (i
= 0; i
< fileInfo
.num_toc
; i
++) {
1242 fseek(file
, toc
[i
].offset
, SEEK_SET
);
1243 tmp
= fread(&tmpTOC
, SIZEOF(xkmSectionInfo
), 1, file
);
1244 nRead
= tmp
* SIZEOF(xkmSectionInfo
);
1245 if ((tmpTOC
.type
!= toc
[i
].type
) || (tmpTOC
.format
!= toc
[i
].format
) ||
1246 (tmpTOC
.size
!= toc
[i
].size
) || (tmpTOC
.offset
!= toc
[i
].offset
)) {
1249 if ((which
& (1 << tmpTOC
.type
)) == 0) {
1252 switch (tmpTOC
.type
) {
1253 case XkmVirtualModsIndex
:
1254 tmp
= ReadXkmVirtualMods(file
, *xkb
, NULL
);
1257 tmp
= ReadXkmKeyTypes(file
, *xkb
, NULL
);
1259 case XkmCompatMapIndex
:
1260 tmp
= ReadXkmCompatMap(file
, *xkb
, NULL
);
1262 case XkmKeyNamesIndex
:
1263 tmp
= ReadXkmKeycodes(file
, *xkb
, NULL
);
1265 case XkmIndicatorsIndex
:
1266 tmp
= ReadXkmIndicators(file
, *xkb
, NULL
);
1268 case XkmSymbolsIndex
:
1269 tmp
= ReadXkmSymbols(file
, *xkb
);
1271 case XkmGeometryIndex
:
1272 tmp
= ReadXkmGeometry(file
, *xkb
);
1275 _XkbLibError(_XkbErrBadImplementation
,
1276 XkbConfigText(tmpTOC
.type
, XkbMessage
), 0);
1282 which
&= ~(1 << toc
[i
].type
);
1283 (*xkb
)->defined
|= (1 << toc
[i
].type
);
1285 if (nRead
!= tmpTOC
.size
) {
1286 _XkbLibError(_XkbErrBadLength
,
1287 XkbConfigText(tmpTOC
.type
, XkbMessage
),
1288 nRead
- tmpTOC
.size
);