1 XKM File Format Description 2 Version 15 3 41. Introduction 5 6The XKM file format is the exchange format for XKB keyboard descriptions 7between the server and xkbcomp. Usually, the server forks off xkbcomp, 8xkbcomp compiles the XKM format from the given parameters. 9The resulting XKM file is put into a directory readable by the server and 10then parsed. 11 12The XKM format is little more than a binary dump of various XKB-specific 13structures and hence tied to the ABI of the server. 14 15 ❧❧❧❧❧❧❧❧❧❧❧ 16 171.1 About this file format description 18 19This description was produced by analyzing the XKM parsing code. Parts of 20the file description present in the original format specification may be 21missing. This description thus cannot be a reference document for XKM 22implementations. 23 24No description of the meaning of the various fields is given here. Refer to 25the XKB protocol specification for more details. 26 ❧❧❧❧❧❧❧❧❧❧❧ 27 282. Notations used in this document 29 30Notation 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 38Data types are identical to those used in the X Protocol specification 39except where noted otherwise. Structs specific to XKM are prefixed with XKM, 40defines specific to the XKB protocol specification are prefixed with Xkb and 41their value is equivalent to that in the protocol specification. 42 43Multiple instances of a given type are denoted in the following form: 44 name of field: LISTofFIELDTYPE 45 46Length specifiers for such fields are usually prefixed with num_. For 47example, a struct containing a num_foo of 8 and a 'foo' field contains 8 48structures of type 'foo'. 49 50Variable length padding is specified as pad(x), where x is the length of the 51data to be padded out to a multiple of 4 bytes. For example, given an x of 5210, pad(x) would be the remaining 2 bytes to pad the whole struct to 12 53bytes. 54 55A special notation is a variable content struct. In this case, the contents 56of 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└─── 72This notation denotes that if field is of value 1, this struct contains the 73specific fields listed underneath value 1. 74 75 ❧❧❧❧❧❧❧❧❧❧❧ 76 773. XKM Format 78 79The XKM format is a binary format with structs usually being padded to a 80multiple of 4 bytes. No provisions for endianess are provided, the parser is 81left to guess the endianess of the XKM file. 82 83 ❧❧❧❧❧❧❧❧❧❧❧ 843.1 Common data types 85 86┌─── 87 XKMCountedString 88 count: CARD16 89 string: count * CHAR 90 pad: pad(count + 2) 91└─── 92 93XKMCountedString is used for user-readable identifiers. Prime example are 94the 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 1063.2 Header and Table of Contents 107 108┌─── 109 XKMHeader 110 version: CARD8 111 identifier1: 'm' 112 identifier2: 'k' 113 idenfifier3: 'x' 114└─── 115 116The XKM file format has a 4 byte header identifying the file and the XKM 117version. The header is followed by the table of contents indicating the 118sections 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 131min_keycode and max_keycode specify the keycode range for this keyboard 132descriptions. The core protocol requires min_keycode always be equal to or 133greater 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 150Describes 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 152the beginning of the actual section (see offset). 153The type specifies the type of the section, the section is to be parsed 154according to this type. 155Size and offset specify the size in bytes and the offset into the file in 156bytes, respectively. 157 1583.3 Sections 159 160Each section resides at the offset specified in the XKMFileInfo sectioninfo. 161 162 ❧❧❧❧❧❧❧❧❧❧❧ 163 1643.3.1 XKMTypes 165 166An XKMTypes section describes the key types defined in a layout. Roughly 167speaking, a key type defines how many levels a given key has and which 168modifiers 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 194The 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 ❧❧❧❧❧❧❧❧❧❧❧ 2113.3.2 XKMCompatMap 212 213An XKMCompatMap section describes the actions a keyboard may trigger. This 214ranges 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 227One 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 240Where the action is 7 bytes of CARD8 whose content is determined by 241action_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 366Note: XkbSA_ActionMessage is currently unsupported and the contents are 367ignored. 368 369 ❧❧❧❧❧❧❧❧❧❧❧ 3703.3.3 XkmSymbols 371 372The 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└─── 386One group_name is present for each bit set in group_names_mask. 387The 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 400Presence of names is conditional on the XkmKeyHasTypes flag. The number of 401strings is equal to the number of group bits in group_names_mask in the 402preceeding XKMSymbols section. 403The number of elements in syms is equal to width * num_groups. 404Presence 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 4223.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 4483.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 462keynames 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 4773.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 636WARNING: XKMGeomDoodad has variable length depending on the type. 637NOTE: The current server implementation does not use all fields of all 638structures. 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 6663.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 681Number of elements in vmods is equal to the number of bits set in 682bound_mask. The padding completes vmods to a multiple of 4 byte units. 683Number of elements in names is equal to the number of bits set in 684named_mask. 685