Commit | Line | Data |
---|---|---|
7217e0ca ML |
1 | XKM File Format Description |
2 | Version 15 | |
3 | ||
4 | 1. Introduction | |
5 | ||
6 | The XKM file format is the exchange format for XKB keyboard descriptions | |
7 | between the server and xkbcomp. Usually, the server forks off xkbcomp, | |
8 | xkbcomp compiles the XKM format from the given parameters. | |
9 | The resulting XKM file is put into a directory readable by the server and | |
10 | then parsed. | |
11 | ||
12 | The XKM format is little more than a binary dump of various XKB-specific | |
13 | structures and hence tied to the ABI of the server. | |
14 | ||
15 | ❧❧❧❧❧❧❧❧❧❧❧ | |
16 | ||
17 | 1.1 About this file format description | |
18 | ||
19 | This description was produced by analyzing the XKM parsing code. Parts of | |
20 | the file description present in the original format specification may be | |
21 | missing. This description thus cannot be a reference document for XKM | |
22 | implementations. | |
23 | ||
24 | No description of the meaning of the various fields is given here. Refer to | |
25 | the XKB protocol specification for more details. | |
26 | ❧❧❧❧❧❧❧❧❧❧❧ | |
27 | ||
28 | 2. Notations used in this document | |
29 | ||
30 | Notation for structures: | |
31 | ||
32 | ┌─── | |
33 | Name of struct | |
34 | name of field: type or fixed value of field | |
35 | name of field: type or fixed value of field | |
36 | └─── | |
37 | ||
38 | Data types are identical to those used in the X Protocol specification | |
39 | except where noted otherwise. Structs specific to XKM are prefixed with XKM, | |
40 | defines specific to the XKB protocol specification are prefixed with Xkb and | |
41 | their value is equivalent to that in the protocol specification. | |
42 | ||
43 | Multiple instances of a given type are denoted in the following form: | |
44 | name of field: LISTofFIELDTYPE | |
45 | ||
46 | Length specifiers for such fields are usually prefixed with num_. For | |
47 | example, a struct containing a num_foo of 8 and a 'foo' field contains 8 | |
48 | structures of type 'foo'. | |
49 | ||
50 | Variable length padding is specified as pad(x), where x is the length of the | |
51 | data to be padded out to a multiple of 4 bytes. For example, given an x of | |
52 | 10, pad(x) would be the remaining 2 bytes to pad the whole struct to 12 | |
53 | bytes. | |
54 | ||
55 | A special notation is a variable content struct. In this case, the contents | |
56 | of the struct depend on the value of one or more specific fields. | |
57 | ┌─── | |
58 | Name of struct | |
59 | field: type or fixed value of field | |
60 | field: type or fixed value of field | |
61 | ─── | |
62 | field ⇒ value 1 | |
63 | ⇒ | |
64 | specific field: type | |
65 | specific field: type | |
66 | ─── | |
67 | field ⇒ value 2 | |
68 | ⇒ | |
69 | specific field: type | |
70 | specific field: type | |
71 | └─── | |
72 | This notation denotes that if field is of value 1, this struct contains the | |
73 | specific fields listed underneath value 1. | |
74 | ||
75 | ❧❧❧❧❧❧❧❧❧❧❧ | |
76 | ||
77 | 3. XKM Format | |
78 | ||
79 | The XKM format is a binary format with structs usually being padded to a | |
80 | multiple of 4 bytes. No provisions for endianess are provided, the parser is | |
81 | left to guess the endianess of the XKM file. | |
82 | ||
83 | ❧❧❧❧❧❧❧❧❧❧❧ | |
84 | 3.1 Common data types | |
85 | ||
86 | ┌─── | |
87 | XKMCountedString | |
88 | count: CARD16 | |
89 | string: count * CHAR | |
90 | pad: pad(count + 2) | |
91 | └─── | |
92 | ||
93 | XKMCountedString is used for user-readable identifiers. Prime example are | |
94 | the level names and the section names ("complete", "evdev(inet)", etc.) | |
95 | ||
96 | ┌─── | |
97 | XKMGroupBits: CARD8 | |
98 | group1 0x1 | |
99 | group2 0x2 | |
100 | group3 0x4 | |
101 | group4 0x8 | |
102 | └─── | |
103 | ||
104 | ❧❧❧❧❧❧❧❧❧❧❧ | |
105 | ||
106 | 3.2 Header and Table of Contents | |
107 | ||
108 | ┌─── | |
109 | XKMHeader | |
110 | version: CARD8 | |
111 | identifier1: 'm' | |
112 | identifier2: 'k' | |
113 | idenfifier3: 'x' | |
114 | └─── | |
115 | ||
116 | The XKM file format has a 4 byte header identifying the file and the XKM | |
117 | version. The header is followed by the table of contents indicating the | |
118 | sections present in this file. | |
119 | ||
120 | ┌─── | |
121 | XKMFileInfo | |
122 | type: CARD8 | |
123 | min_keycode: CARD8 | |
124 | max_keycode: CARD8 | |
125 | num_sectioninfo: CARD8 | |
126 | present: CARD16 | |
127 | pad: CARD16 | |
128 | sectioninfo: LISTofXKMSectionInfo | |
129 | └─── | |
130 | ||
131 | min_keycode and max_keycode specify the keycode range for this keyboard | |
132 | descriptions. The core protocol requires min_keycode always be equal to or | |
133 | greater than 8. | |
134 | ||
135 | ┌─── | |
136 | XKMSectionInfo | |
137 | type: CARD16 | |
138 | XkmTypesIndex 0 | |
139 | XkmCompatMapIndex 1 | |
140 | XkmSymbolsIndex 2 | |
141 | XkmIndicatorsIndex 3 | |
142 | XkmKeyNamesIndex 4 | |
143 | XkmGeometryIndex 5 | |
144 | XkmVirtualModsIndex 6 | |
145 | format: CARD16 | |
146 | size: CARD16 | |
147 | offset: CARD16 | |
148 | └─── | |
149 | ||
150 | Describes the section found in a chunk of a file. This struct is found | |
151 | _twice_ in the file per section, once as part of the XKMFileInfo, once at | |
152 | the beginning of the actual section (see offset). | |
153 | The type specifies the type of the section, the section is to be parsed | |
154 | according to this type. | |
155 | Size and offset specify the size in bytes and the offset into the file in | |
156 | bytes, respectively. | |
157 | ||
158 | 3.3 Sections | |
159 | ||
160 | Each section resides at the offset specified in the XKMFileInfo sectioninfo. | |
161 | ||
162 | ❧❧❧❧❧❧❧❧❧❧❧ | |
163 | ||
164 | 3.3.1 XKMTypes | |
165 | ||
166 | An XKMTypes section describes the key types defined in a layout. Roughly | |
167 | speaking, a key type defines how many levels a given key has and which | |
168 | modifiers change to a particular level. | |
169 | ||
170 | ┌─── | |
171 | XKMTypesSection | |
172 | section_info: XKMSectionInfo | |
173 | name: XKMCountedString | |
174 | num_types: CARD16 | |
175 | pad: CARD16 | |
176 | types: LISTofXKMKeyType | |
177 | └─── | |
178 | ||
179 | ┌─── | |
180 | XKMKeyType | |
181 | real_mods: CARD8 | |
182 | num_levels: CARD8 | |
183 | virt_mods: CARD16 | |
184 | num_map_entries: CARD8 | |
185 | num_level_names: CARD8 | |
186 | perserve: CARD8 | |
187 | pad: CARD8 | |
188 | map_entries: LISTofXKMKTMapEntry | |
189 | name: XKMCountedString | |
190 | mods: LISTofXKMModsDesc | |
191 | level_names: LISXTofXKMCountedString | |
192 | └─── | |
193 | ||
194 | The num_map_entries specifies the number of structs in both map_entries and mods. mods is only present if preserve is TRUE. | |
195 | ||
196 | ┌─── | |
197 | XKMKTMapEntry | |
198 | level: CARD8 | |
199 | real_mods: CARD8 | |
200 | virt_mods: CARD16 | |
201 | └─── | |
202 | ||
203 | ┌─── | |
204 | XKMModsDesc | |
205 | real_mods: CARD8 | |
206 | pad: CARD8 | |
207 | virt_mods: CARD16 | |
208 | └─── | |
209 | ||
210 | ❧❧❧❧❧❧❧❧❧❧❧ | |
211 | 3.3.2 XKMCompatMap | |
212 | ||
213 | An XKMCompatMap section describes the actions a keyboard may trigger. This | |
214 | ranges from the TerminateServer action to simple modifier bits. | |
215 | ||
216 | ┌─── | |
217 | XKMCompatMap | |
218 | section_info: XKMSectionInfo | |
219 | name: XKMCountedString | |
220 | num_si: CARD16 | |
221 | group_mask: XKMGroupBits | |
222 | pad: CARD8 | |
223 | si: LISTofXKMSymInterpreterDesc | |
224 | groups: LISTofXKMModsDesc | |
225 | └─── | |
226 | ||
227 | One XKMModsDesc is present for each bit set in group_mask. | |
228 | ||
229 | ┌─── | |
230 | XKMSymInterpretDesc | |
231 | sym: CARD32 | |
232 | mods: CARD8 | |
233 | match: CARD8 | |
234 | virtual_mod: CARD8 | |
235 | flags: CARD8 | |
236 | action_type: CARD8 | |
237 | action_data: XKMActionData | |
238 | └─── | |
239 | ||
240 | Where the action is 7 bytes of CARD8 whose content is determined by | |
241 | action_type. | |
242 | ||
243 | ┌─── | |
244 | XKMActionData: | |
245 | pad0: CARD8 | |
246 | pad1: CARD16 | |
247 | pad2: CARD32 | |
248 | ─── | |
249 | action_type ⇒ XkbSA_SetMods || | |
250 | action_type ⇒ XkbSA_LatchMods || | |
251 | action_type ⇒ XkbSA_LockMods | |
252 | ⇒ | |
253 | flags: CARD8 | |
254 | mask: CARD8 | |
255 | real_mods: CARD8 | |
256 | vmods1: CARD8 | |
257 | vmods2: CARD8 | |
258 | pad: CARD16 | |
259 | ─── | |
260 | action_type ⇒ XkbSA_SetGroup || | |
261 | action_type ⇒ XkbSA_LatchGroup || | |
262 | action_type ⇒ XkbSA_LockGroup | |
263 | ⇒ | |
264 | flags: CARD8 | |
265 | group_XXX: CARD8 | |
266 | pad0: CARD8 | |
267 | pad1: CARD32 | |
268 | ─── | |
269 | action_type ⇒ XkbSA_MovePtr | |
270 | ⇒ | |
271 | flags: CARD8 | |
272 | high_XXX: CARD8 | |
273 | low_XXX: CARD8 | |
274 | high_YYY: CARD8 | |
275 | low_YYY: CARD8 | |
276 | pad: CARD16 | |
277 | ─── | |
278 | action_type ⇒ XkbSA_PtrBtn || | |
279 | action_type ⇒ XkbSA_LockPtrBtn | |
280 | ⇒ | |
281 | flags: CARD8 | |
282 | count: CARD8 | |
283 | button: CARD8 | |
284 | pad: CARD32 | |
285 | ─── | |
286 | action_type ⇒ XkbSA_DeviceBtn || | |
287 | action_type ⇒ XkbSA_LockLockPtrBtn | |
288 | ⇒ | |
289 | flags: CARD8 | |
290 | count: CARD8 | |
291 | button: CARD8 | |
292 | device: CARD8 | |
293 | pad0: CARD8 | |
294 | pad1: CARD16 | |
295 | ─── | |
296 | action_type ⇒ XkbSA_SetPtrDflt | |
297 | ⇒ | |
298 | flags: CARD8 | |
299 | affect: CARD8 | |
300 | valueXXX: CARD8 | |
301 | pad0: CARD32 | |
302 | ─── | |
303 | action_type ⇒ XkbSA_ISOLock | |
304 | ⇒ | |
305 | flags: CARD8 | |
306 | mask: CARD8 | |
307 | real_mods: CARD8 | |
308 | group_XXX: CARD8 | |
309 | affect: CARD8 | |
310 | vmods1: CARD8 | |
311 | vmods1: CARD8 | |
312 | ─── | |
313 | action_type ⇒ XkbSA_SwitchScreen | |
314 | ⇒ | |
315 | flags: CARD8 | |
316 | screenXXX: CARD8 | |
317 | pad0: CARD8 | |
318 | pad1: CARD32 | |
319 | ─── | |
320 | action_type ⇒ XkbSA_SetControls || | |
321 | action_type ⇒ XkbSA_LockControls | |
322 | ⇒ | |
323 | flags: CARD8 | |
324 | ctrls3: CARD8 | |
325 | ctrls2: CARD8 | |
326 | ctrls1: CARD8 | |
327 | ctrls0: CARD8 | |
328 | pad: CARD16 | |
329 | ─── | |
330 | action_type ⇒ XkbSA_RedirectKey | |
331 | ⇒ | |
332 | new_key: CARD8 | |
333 | mods_mask: CARD8 | |
334 | mods: CARD8 | |
335 | vmods_mask0: CARD8 | |
336 | vmods_mask1: CARD8 | |
337 | vmods0: CARD8 | |
338 | vmods1: CARD8 | |
339 | ─── | |
340 | action_type ⇒ XkbSA_DeviceValuator | |
341 | ⇒ | |
342 | device: CARD8 | |
343 | v1_what: CARD8 | |
344 | v1_idx: CARD8 | |
345 | v1_value: CARD8 | |
346 | v2_what: CARD8 | |
347 | v2_idx: CARD8 | |
348 | v2_value: CARD8 | |
349 | pad: CARD8 | |
350 | ─── | |
351 | action_type ⇒ XkbSA_XFree86Private || | |
352 | action_type ⇒ XkbSA_Terminate | |
353 | ⇒ | |
354 | pad0: CARD8 | |
355 | pad1: CARD16 | |
356 | pad2: CARD32 | |
357 | ─── | |
358 | action_type ⇒ XkbSA_ActionMessage | |
359 | ⇒ | |
360 | press_msg: BOOL | |
361 | release_msg: BOOL | |
362 | gen_event: BOOL | |
363 | message: 4 * CHAR | |
364 | └─── | |
365 | ||
366 | Note: XkbSA_ActionMessage is currently unsupported and the contents are | |
367 | ignored. | |
368 | ||
369 | ❧❧❧❧❧❧❧❧❧❧❧ | |
370 | 3.3.3 XkmSymbols | |
371 | ||
372 | The symbols in a keymap define the actual keysyms each key may produce. | |
373 | ||
374 | ┌─── | |
375 | XKMSymbols | |
376 | section_info: XKMSectionInfo | |
377 | name: XKMCountedString | |
378 | min_keycode: CARD8 | |
379 | max_keycode: CARD8 | |
380 | group_names_mask: XKMGroupBits | |
381 | num_vmod_maps: CARD8 | |
382 | group_names: LISTofXKMCountedString | |
383 | keysyms: XKMKeysymMapDesc | |
384 | vmod_maps: XKMVModMapDesc | |
385 | └─── | |
386 | One group_name is present for each bit set in group_names_mask. | |
387 | The number of keysyms present is max_keycode - min_keycode + 1. | |
388 | ||
389 | ┌─── | |
390 | XKMKeysymMapDesc | |
391 | width: CARD8 | |
392 | num_groups: CARD8 | |
393 | modifier_map: CARD8 | |
394 | flags: CARD8 | |
395 | names: LISTofXKMCountedString | |
396 | syms: LISTofCARD32 | |
397 | behavior: XKMBehaviorDesc | |
398 | └─── | |
399 | ||
400 | Presence of names is conditional on the XkmKeyHasTypes flag. The number of | |
401 | strings is equal to the number of group bits in group_names_mask in the | |
402 | preceeding XKMSymbols section. | |
403 | The number of elements in syms is equal to width * num_groups. | |
404 | Presence of behavior is conditional on the XkmKeyHasBehavior flag. | |
405 | ||
406 | ┌─── | |
407 | XKMKeyBehaviorDesc | |
408 | type: CARD8 | |
409 | data: CARD8 | |
410 | pad: CARD16 | |
411 | └─── | |
412 | ||
413 | ┌─── | |
414 | XKMVModMapDesc | |
415 | key: CARD8 | |
416 | pad: CARD8 | |
417 | vmods: CARD16 | |
418 | └─── | |
419 | ||
420 | ❧❧❧❧❧❧❧❧❧❧❧ | |
421 | ||
422 | 3.3.4 XKMIndicators | |
423 | ||
424 | ┌─── | |
425 | XKMIndicators | |
426 | section_info: XKMSectionInfo | |
427 | name: XKMCountedString | |
428 | num_indicators: CARD8 | |
429 | pad0: CARD8 | |
430 | pad1: CARD16 | |
431 | indicators: LISTofXKMIndicatorMapDesc | |
432 | └─── | |
433 | ||
434 | ┌─── | |
435 | XKMIndicatorMapDesc | |
436 | name: XKMCountedString | |
437 | indicator: CARD8 | |
438 | flags: CARD8 | |
439 | which_mods: CARD8 | |
440 | real_mods: CARD8 | |
441 | vmods: CARD16 | |
442 | which_groups: CARD8 | |
443 | groups: CARD8 | |
444 | ctrls: CARD32 | |
445 | └─── | |
446 | ❧❧❧❧❧❧❧❧❧❧❧ | |
447 | ||
448 | 3.3.5 XKMKeyNames | |
449 | ||
450 | ┌─── | |
451 | XKMKeyNames | |
452 | section_info: XKMSectionInfo | |
453 | name: XKMCountedString | |
454 | min_keycode: CARD8 | |
455 | max_keycode: CARD8 | |
456 | num_aliases: CARD8 | |
457 | pad: CARD8 | |
458 | keynames: LISTofXKMKeyname | |
459 | aliases: LISTofXKMKeyAlias | |
460 | └─── | |
461 | ||
462 | keynames contains max_keycode - min_keycode + 1 entries. | |
463 | ||
464 | ┌─── | |
465 | XkmKeyname | |
466 | name: 4 * CHAR8 | |
467 | └─── | |
468 | ||
469 | ┌─── | |
470 | XkmKeyAlias | |
471 | real: XkmKeyname | |
472 | alias: XkmKeyname | |
473 | └─── | |
474 | ||
475 | ❧❧❧❧❧❧❧❧❧❧❧ | |
476 | ||
477 | 3.3.5 XKMGeometry | |
478 | ||
479 | ┌─── | |
480 | XKMGeometry | |
481 | section_info: XKMSectionInfo | |
482 | name: XKMCountedString | |
483 | width_mm: CARD16 | |
484 | height_mm: CARD16 | |
485 | base_color_ndx: CARD8 | |
486 | label_color_ndx: CARD8 | |
487 | num_properties: CARD16 | |
488 | num_colors: CARD16 | |
489 | num_shapes: CARD16 | |
490 | num_sections: CARD16 | |
491 | num_doodads: CARD16 | |
492 | num_key_aliases: CARD16 | |
493 | pad: CARD16 | |
494 | label_font: XKMCountedString | |
495 | properties: LISTofXKMGeomProperty | |
496 | colors: LISTofXKMCountedString | |
497 | shapes: LISTofXKMGeomShape | |
498 | sections: LISTofXKMGeomSection | |
499 | doodads: LISTofXKMGeomDoodad | |
500 | key_aliases: LISTofXKMKeyAlias | |
501 | └─── | |
502 | ||
503 | ┌─── | |
504 | XKMGeomProperty | |
505 | name: XKMCountedString | |
506 | value: XKMCountedString | |
507 | ||
508 | └─── | |
509 | ||
510 | ┌─── | |
511 | XKMGeomShape | |
512 | name: XKMCountedString | |
513 | num_outlines: CARD8 | |
514 | primary_idx: CARD8 | |
515 | approx_idx: CARD8 | |
516 | pad: CARD8 | |
517 | outlines: LISTofXKMOutlineDesc | |
518 | └─── | |
519 | ||
520 | ┌─── | |
521 | XKMOutlineDesc | |
522 | num_points: CARD8 | |
523 | corner_radius: CARD8 | |
524 | pad: CARD16 | |
525 | points: LISTofXKMPointDesc | |
526 | └─── | |
527 | ||
528 | ┌─── | |
529 | XKMPointDesc | |
530 | x: INT16 | |
531 | y: INT16 | |
532 | └─── | |
533 | ||
534 | ┌─── | |
535 | XKMGeomSection | |
536 | name: XKMCountedString | |
537 | top: INT16 | |
538 | left: INT16 | |
539 | width: CARD16 | |
540 | height: CARD16 | |
541 | angle: INT16 | |
542 | priority: CARD8 | |
543 | num_rows: CARD8 | |
544 | num_doodads: CARD8 | |
545 | num_overlays: CARD8 | |
546 | pad: CARD16 | |
547 | rows: LISTofXKMRowDesc | |
548 | doodads: LISTofXKMGeomDoodad | |
549 | overlays: LISTofXKMGeomOverlay | |
550 | └─── | |
551 | ||
552 | ┌─── | |
553 | XKMRowDesc | |
554 | top: INT16 | |
555 | left: INT16 | |
556 | num_keys: CARD8 | |
557 | vertical: BOOL | |
558 | pad: CARD16 | |
559 | keys: XKMKeyDesc | |
560 | └─── | |
561 | ||
562 | ┌─── | |
563 | XKMKeyDesc | |
564 | name: XKMKeyname | |
565 | gap: INT16 | |
566 | shape_idx: CARD8 | |
567 | color_idx: CARD8 | |
568 | └─── | |
569 | ||
570 | ┌─── | |
571 | XKMGeomDoodad | |
572 | name: XKMCountedString | |
573 | type: CARD8 | |
574 | priority: CARD8 | |
575 | top: INT16 | |
576 | left: INT16 | |
577 | pad1: CARD16 | |
578 | pad2: CARD32 | |
579 | pad3: CARD32 | |
580 | ─── | |
581 | type ⇒ XkbOutlineDoodad || | |
582 | type ⇒ XkbSolideDoodad | |
583 | ⇒ | |
584 | type: CARD8 | |
585 | priority: CARD8 | |
586 | top: INT16 | |
587 | left: INT16 | |
588 | angle: INT16 | |
589 | color_idx: CARD8 | |
590 | shape_idx: CARD8 | |
591 | pad0: CARD16 | |
592 | pad1: CARD32 | |
593 | ─── | |
594 | type ⇒ XkbTextDoodad | |
595 | ⇒ | |
596 | type: CARD8 | |
597 | priority: CARD8 | |
598 | top: INT16 | |
599 | left: INT16 | |
600 | angle: INT16 | |
601 | width: CARD16 | |
602 | height: CARD16 | |
603 | color_idx: CARD8 | |
604 | pad0: CARD8 | |
605 | pad1: CARD16 | |
606 | text: XKMCountedString | |
607 | font: XKMCountedString | |
608 | ─── | |
609 | type ⇒ XkbIndicatorDoodad | |
610 | ⇒ | |
611 | type: CARD8 | |
612 | priority: CARD8 | |
613 | top: INT16 | |
614 | left: INT16 | |
615 | shape_idx: CARD8 | |
616 | on_color_idx: CARD8 | |
617 | off_color_idx: CARD8 | |
618 | pad0: CARD8 | |
619 | pad1: CARD16 | |
620 | pad2: CARD32 | |
621 | ─── | |
622 | type ⇒ XkbLogoDoodad | |
623 | ⇒ | |
624 | type: CARD8 | |
625 | priority: CARD8 | |
626 | top: INT16 | |
627 | left: INT16 | |
628 | angle: INT16 | |
629 | color_idx: CARD8 | |
630 | shape_idx: CARD8 | |
631 | pad0: CARD16 | |
632 | pad1: CARD32 | |
633 | logo_name: XKMCountedString | |
634 | └─── | |
635 | ||
636 | WARNING: XKMGeomDoodad has variable length depending on the type. | |
637 | NOTE: The current server implementation does not use all fields of all | |
638 | structures. | |
639 | ||
640 | ┌─── | |
641 | XKMOverlayDesc | |
642 | name: XKMCountedString | |
643 | num_rows: CARD8 | |
644 | pad0: CARD8 | |
645 | pad1: CARD16 | |
646 | rows: LISTofXKMOverlayRowDesc | |
647 | └─── | |
648 | ||
649 | ┌─── | |
650 | XKMOverlayRowDesc | |
651 | name: XKMCountedString | |
652 | row_under: CARD8 | |
653 | num_keys: CARD8 | |
654 | pad: CARD16 | |
655 | keys: LISTofXKMOverlayKeyDesc | |
656 | └─── | |
657 | ||
658 | ┌─── | |
659 | XKMOverlayKeyDesc | |
660 | over: XKMKeyname | |
661 | under: XKMKeyname | |
662 | └─── | |
663 | ||
664 | ❧❧❧❧❧❧❧❧❧❧❧ | |
665 | ||
666 | 3.3.6 XKMVirtualMods | |
667 | ||
668 | ┌─── | |
669 | XKMOverlayRowDesc | |
670 | section_info: XKMSectionInfo | |
671 | name: XKMCountedString | |
672 | bound_mask: SETofVMODBITS | |
673 | named_mask: SETofVMODBITS | |
674 | vmods: LISTofCARD8 | |
675 | pad: pad(vmods) | |
676 | names: LISTofXKMCountedString | |
677 | └─── | |
678 | ||
679 | VMODBITS: CARD16 | |
680 | ||
681 | Number of elements in vmods is equal to the number of bits set in | |
682 | bound_mask. The padding completes vmods to a multiple of 4 byte units. | |
683 | Number of elements in names is equal to the number of bits set in | |
684 | named_mask. |