685 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			685 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
                        XKM File Format Description
 | 
						|
                                Version 15
 | 
						|
 | 
						|
1. Introduction
 | 
						|
 | 
						|
The XKM file format is the exchange format for XKB keyboard descriptions
 | 
						|
between the server and xkbcomp. Usually, the server forks off xkbcomp,
 | 
						|
xkbcomp compiles the XKM format from the given parameters.
 | 
						|
The resulting XKM file is put into a directory readable by the server and
 | 
						|
then parsed.
 | 
						|
 | 
						|
The XKM format is little more than a binary dump of various XKB-specific
 | 
						|
structures and hence tied to the ABI of the server.
 | 
						|
 | 
						|
                              ❧❧❧❧❧❧❧❧❧❧❧
 | 
						|
 | 
						|
1.1 About this file format description
 | 
						|
 | 
						|
This description was produced by analyzing the XKM parsing code. Parts of
 | 
						|
the file description present in the original format specification may be
 | 
						|
missing. This description thus cannot be a reference document for XKM
 | 
						|
implementations.
 | 
						|
 | 
						|
No description of the meaning of the various fields is given here. Refer to
 | 
						|
the XKB protocol specification for more details.
 | 
						|
                              ❧❧❧❧❧❧❧❧❧❧❧
 | 
						|
 | 
						|
2. Notations used in this document
 | 
						|
 | 
						|
Notation for structures:
 | 
						|
 | 
						|
┌───
 | 
						|
  Name of struct
 | 
						|
	name of field:		type or fixed value of field
 | 
						|
	name of field:		type or fixed value of field
 | 
						|
└───
 | 
						|
 | 
						|
Data types are identical to those used in the X Protocol specification
 | 
						|
except where noted otherwise. Structs specific to XKM are prefixed with XKM,
 | 
						|
defines specific to the XKB protocol specification are prefixed with Xkb and
 | 
						|
their value is equivalent to that in the protocol specification.
 | 
						|
 | 
						|
Multiple instances of a given type are denoted in the following form:
 | 
						|
	name of field:		LISTofFIELDTYPE
 | 
						|
 | 
						|
Length specifiers for such fields are usually prefixed with num_. For
 | 
						|
example, a struct containing a num_foo of 8 and a 'foo' field contains 8
 | 
						|
structures of type 'foo'.
 | 
						|
 | 
						|
Variable length padding is specified as pad(x), where x is the length of the
 | 
						|
data to be padded out to a multiple of 4 bytes. For example, given an x of
 | 
						|
10, pad(x) would be the remaining 2 bytes to pad the whole struct to 12
 | 
						|
bytes.
 | 
						|
 | 
						|
A special notation is a variable content struct. In this case, the contents
 | 
						|
of the struct depend on the value of one or more specific fields.
 | 
						|
┌───
 | 
						|
  Name of struct
 | 
						|
	field:			type or fixed value of field
 | 
						|
	field:			type or fixed value of field
 | 
						|
	───
 | 
						|
	field ⇒ value 1
 | 
						|
	⇒
 | 
						|
		specific field:		type
 | 
						|
		specific field:		type
 | 
						|
	───
 | 
						|
        field ⇒ value 2
 | 
						|
	⇒
 | 
						|
		specific field:		type
 | 
						|
		specific field:		type
 | 
						|
└───
 | 
						|
This notation denotes that if field is of value 1, this struct contains the
 | 
						|
specific fields listed underneath value 1.
 | 
						|
 | 
						|
                              ❧❧❧❧❧❧❧❧❧❧❧
 | 
						|
 | 
						|
3. XKM Format
 | 
						|
 | 
						|
The XKM format is a binary format with structs usually being padded to a
 | 
						|
multiple of 4 bytes. No provisions for endianess are provided, the parser is
 | 
						|
left to guess the endianess of the XKM file.
 | 
						|
 | 
						|
                              ❧❧❧❧❧❧❧❧❧❧❧
 | 
						|
3.1 Common data types
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMCountedString
 | 
						|
	count:			CARD16
 | 
						|
	string:			count * CHAR
 | 
						|
	pad:			pad(count + 2)
 | 
						|
└───
 | 
						|
 | 
						|
XKMCountedString is used for user-readable identifiers. Prime example are
 | 
						|
the level names and the section names ("complete", "evdev(inet)", etc.)
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMGroupBits:		CARD8
 | 
						|
	group1			0x1
 | 
						|
	group2			0x2
 | 
						|
	group3			0x4
 | 
						|
	group4			0x8
 | 
						|
└───
 | 
						|
 | 
						|
                              ❧❧❧❧❧❧❧❧❧❧❧
 | 
						|
 | 
						|
3.2 Header and Table of Contents
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMHeader
 | 
						|
	version:		CARD8
 | 
						|
	identifier1:		'm'
 | 
						|
	identifier2:		'k'
 | 
						|
	idenfifier3:		'x'
 | 
						|
└───
 | 
						|
 | 
						|
The XKM file format has a 4 byte header identifying the file and the XKM
 | 
						|
version. The header is followed by the table of contents indicating the
 | 
						|
sections present in this file.
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMFileInfo
 | 
						|
	type:			CARD8
 | 
						|
	min_keycode:		CARD8
 | 
						|
	max_keycode:		CARD8
 | 
						|
	num_sectioninfo:	CARD8
 | 
						|
	present:		CARD16
 | 
						|
	pad:			CARD16
 | 
						|
	sectioninfo:		LISTofXKMSectionInfo
 | 
						|
└───
 | 
						|
 | 
						|
min_keycode and max_keycode specify the keycode range for this keyboard
 | 
						|
descriptions. The core protocol requires min_keycode always be equal to or
 | 
						|
greater than 8.
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMSectionInfo
 | 
						|
	type:			CARD16
 | 
						|
		XkmTypesIndex		0
 | 
						|
		XkmCompatMapIndex	1
 | 
						|
		XkmSymbolsIndex		2
 | 
						|
		XkmIndicatorsIndex	3
 | 
						|
		XkmKeyNamesIndex	4
 | 
						|
		XkmGeometryIndex	5
 | 
						|
		XkmVirtualModsIndex	6
 | 
						|
	format:			CARD16
 | 
						|
	size:			CARD16
 | 
						|
	offset:			CARD16
 | 
						|
└───
 | 
						|
 | 
						|
Describes the section found in a chunk of a file. This struct is found
 | 
						|
_twice_ in the file per section, once as part of the XKMFileInfo, once at
 | 
						|
the beginning of the actual section (see offset).
 | 
						|
The type specifies the type of the section, the section is to be parsed
 | 
						|
according to this type.
 | 
						|
Size and offset specify the size in bytes and the offset into the file in
 | 
						|
bytes, respectively.
 | 
						|
 | 
						|
3.3 Sections
 | 
						|
 | 
						|
Each section resides at the offset specified in the XKMFileInfo sectioninfo.
 | 
						|
 | 
						|
                              ❧❧❧❧❧❧❧❧❧❧❧
 | 
						|
 | 
						|
3.3.1 XKMTypes
 | 
						|
 | 
						|
An XKMTypes section describes the key types defined in a layout. Roughly
 | 
						|
speaking, a key type defines how many levels a given key has and which
 | 
						|
modifiers change to a particular level.
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMTypesSection
 | 
						|
	section_info:		XKMSectionInfo
 | 
						|
	name:			XKMCountedString
 | 
						|
	num_types:		CARD16
 | 
						|
	pad:			CARD16
 | 
						|
	types:			LISTofXKMKeyType
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMKeyType
 | 
						|
	real_mods:		CARD8
 | 
						|
	num_levels:		CARD8
 | 
						|
	virt_mods:		CARD16
 | 
						|
	num_map_entries: 	CARD8
 | 
						|
	num_level_names: 	CARD8
 | 
						|
	perserve:	 	CARD8
 | 
						|
	pad:			CARD8
 | 
						|
	map_entries:		LISTofXKMKTMapEntry
 | 
						|
	name:			XKMCountedString
 | 
						|
	mods:			LISTofXKMModsDesc
 | 
						|
	level_names:		LISXTofXKMCountedString
 | 
						|
└───
 | 
						|
 | 
						|
The num_map_entries specifies the number of structs in both map_entries and mods. mods is only present if preserve is TRUE.
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMKTMapEntry
 | 
						|
	level:			CARD8
 | 
						|
	real_mods:		CARD8
 | 
						|
	virt_mods:		CARD16
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMModsDesc
 | 
						|
	real_mods:		CARD8
 | 
						|
	pad:			CARD8
 | 
						|
	virt_mods:		CARD16
 | 
						|
└───
 | 
						|
 | 
						|
                              ❧❧❧❧❧❧❧❧❧❧❧
 | 
						|
3.3.2 XKMCompatMap
 | 
						|
 | 
						|
An XKMCompatMap section describes the actions a keyboard may trigger. This
 | 
						|
ranges from the TerminateServer action to simple modifier bits.
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMCompatMap
 | 
						|
	section_info:		XKMSectionInfo
 | 
						|
	name:			XKMCountedString
 | 
						|
	num_si:			CARD16
 | 
						|
	group_mask:		XKMGroupBits
 | 
						|
	pad:			CARD8
 | 
						|
	si:			LISTofXKMSymInterpreterDesc
 | 
						|
	groups:			LISTofXKMModsDesc
 | 
						|
└───
 | 
						|
 | 
						|
One XKMModsDesc is present for each bit set in group_mask.
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMSymInterpretDesc
 | 
						|
	sym:			CARD32
 | 
						|
	mods:			CARD8
 | 
						|
	match:			CARD8
 | 
						|
	virtual_mod:		CARD8
 | 
						|
	flags:			CARD8
 | 
						|
	action_type:		CARD8
 | 
						|
	action_data:		XKMActionData
 | 
						|
└───
 | 
						|
 | 
						|
Where the action is 7 bytes of CARD8 whose content is determined by
 | 
						|
action_type.
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMActionData:
 | 
						|
	pad0:			CARD8
 | 
						|
	pad1:			CARD16
 | 
						|
	pad2:			CARD32
 | 
						|
	───
 | 
						|
        action_type ⇒ XkbSA_SetMods ||
 | 
						|
        action_type ⇒ XkbSA_LatchMods ||
 | 
						|
        action_type ⇒ XkbSA_LockMods
 | 
						|
	⇒
 | 
						|
		flags:			CARD8
 | 
						|
		mask:			CARD8
 | 
						|
		real_mods:		CARD8
 | 
						|
		vmods1:			CARD8
 | 
						|
		vmods2:			CARD8
 | 
						|
		pad:			CARD16
 | 
						|
	───
 | 
						|
        action_type ⇒ XkbSA_SetGroup ||
 | 
						|
        action_type ⇒ XkbSA_LatchGroup ||
 | 
						|
        action_type ⇒ XkbSA_LockGroup
 | 
						|
	⇒
 | 
						|
		flags:			CARD8
 | 
						|
		group_XXX:		CARD8
 | 
						|
		pad0:			CARD8
 | 
						|
		pad1:			CARD32
 | 
						|
	───
 | 
						|
        action_type ⇒ XkbSA_MovePtr
 | 
						|
	⇒
 | 
						|
		flags:			CARD8
 | 
						|
		high_XXX:		CARD8
 | 
						|
		low_XXX:		CARD8
 | 
						|
		high_YYY:		CARD8
 | 
						|
		low_YYY:		CARD8
 | 
						|
		pad:			CARD16
 | 
						|
	───
 | 
						|
        action_type ⇒ XkbSA_PtrBtn ||
 | 
						|
        action_type ⇒ XkbSA_LockPtrBtn
 | 
						|
	⇒
 | 
						|
		flags:			CARD8
 | 
						|
		count:			CARD8
 | 
						|
		button:			CARD8
 | 
						|
		pad:			CARD32
 | 
						|
	───
 | 
						|
        action_type ⇒ XkbSA_DeviceBtn ||
 | 
						|
        action_type ⇒ XkbSA_LockLockPtrBtn
 | 
						|
	⇒
 | 
						|
		flags:			CARD8
 | 
						|
		count:			CARD8
 | 
						|
		button:			CARD8
 | 
						|
		device:			CARD8
 | 
						|
		pad0:			CARD8
 | 
						|
		pad1:			CARD16
 | 
						|
	───
 | 
						|
        action_type ⇒ XkbSA_SetPtrDflt
 | 
						|
	⇒
 | 
						|
		flags:			CARD8
 | 
						|
		affect:			CARD8
 | 
						|
		valueXXX:		CARD8
 | 
						|
		pad0:			CARD32
 | 
						|
	───
 | 
						|
        action_type ⇒ XkbSA_ISOLock
 | 
						|
	⇒
 | 
						|
		flags:			CARD8
 | 
						|
		mask:			CARD8
 | 
						|
		real_mods:		CARD8
 | 
						|
		group_XXX:		CARD8
 | 
						|
		affect:			CARD8
 | 
						|
		vmods1:			CARD8
 | 
						|
		vmods1:			CARD8
 | 
						|
	───
 | 
						|
        action_type ⇒ XkbSA_SwitchScreen
 | 
						|
	⇒
 | 
						|
		flags:			CARD8
 | 
						|
		screenXXX:		CARD8
 | 
						|
		pad0:			CARD8
 | 
						|
		pad1:			CARD32
 | 
						|
	───
 | 
						|
        action_type ⇒ XkbSA_SetControls ||
 | 
						|
        action_type ⇒ XkbSA_LockControls
 | 
						|
	⇒
 | 
						|
		flags:			CARD8
 | 
						|
		ctrls3:			CARD8
 | 
						|
		ctrls2:			CARD8
 | 
						|
		ctrls1:			CARD8
 | 
						|
		ctrls0:			CARD8
 | 
						|
		pad:			CARD16
 | 
						|
	───
 | 
						|
        action_type ⇒ XkbSA_RedirectKey
 | 
						|
	⇒
 | 
						|
		new_key:		CARD8
 | 
						|
		mods_mask:		CARD8
 | 
						|
		mods:			CARD8
 | 
						|
		vmods_mask0:		CARD8
 | 
						|
		vmods_mask1:		CARD8
 | 
						|
		vmods0:			CARD8
 | 
						|
		vmods1:			CARD8
 | 
						|
	───
 | 
						|
        action_type ⇒ XkbSA_DeviceValuator
 | 
						|
	⇒
 | 
						|
		device:		CARD8
 | 
						|
		v1_what:		CARD8
 | 
						|
		v1_idx:			CARD8
 | 
						|
		v1_value:		CARD8
 | 
						|
		v2_what:		CARD8
 | 
						|
		v2_idx:			CARD8
 | 
						|
		v2_value:		CARD8
 | 
						|
		pad:			CARD8
 | 
						|
	───
 | 
						|
        action_type ⇒ XkbSA_XFree86Private ||
 | 
						|
        action_type ⇒ XkbSA_Terminate
 | 
						|
	⇒
 | 
						|
		pad0:			CARD8
 | 
						|
		pad1:			CARD16
 | 
						|
		pad2:			CARD32
 | 
						|
	───
 | 
						|
        action_type ⇒ XkbSA_ActionMessage
 | 
						|
	⇒
 | 
						|
		press_msg:		BOOL
 | 
						|
		release_msg:		BOOL
 | 
						|
		gen_event:		BOOL
 | 
						|
		message:		4 * CHAR
 | 
						|
└───
 | 
						|
 | 
						|
Note: XkbSA_ActionMessage is currently unsupported and the contents are
 | 
						|
ignored.
 | 
						|
 | 
						|
                              ❧❧❧❧❧❧❧❧❧❧❧
 | 
						|
3.3.3 XkmSymbols
 | 
						|
 | 
						|
The symbols in a keymap define the actual keysyms each key may produce.
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMSymbols
 | 
						|
	section_info:		XKMSectionInfo
 | 
						|
	name:			XKMCountedString
 | 
						|
	min_keycode:		CARD8
 | 
						|
	max_keycode:		CARD8
 | 
						|
	group_names_mask:	XKMGroupBits
 | 
						|
	num_vmod_maps:		CARD8
 | 
						|
	group_names:		LISTofXKMCountedString
 | 
						|
	keysyms:		XKMKeysymMapDesc
 | 
						|
	vmod_maps:		XKMVModMapDesc
 | 
						|
└───
 | 
						|
One group_name is present for each bit set in group_names_mask.
 | 
						|
The number of keysyms present is max_keycode - min_keycode + 1.
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMKeysymMapDesc
 | 
						|
	width:			CARD8
 | 
						|
	num_groups:		CARD8
 | 
						|
	modifier_map:		CARD8
 | 
						|
	flags:			CARD8
 | 
						|
	names:			LISTofXKMCountedString
 | 
						|
	syms:			LISTofCARD32
 | 
						|
	behavior:		XKMBehaviorDesc
 | 
						|
└───
 | 
						|
 | 
						|
Presence of names is conditional on the XkmKeyHasTypes flag. The number of
 | 
						|
strings is equal to the number of group bits in group_names_mask in the
 | 
						|
preceeding XKMSymbols section.
 | 
						|
The number of elements in syms is equal to width * num_groups.
 | 
						|
Presence of behavior is conditional on the XkmKeyHasBehavior flag.
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMKeyBehaviorDesc
 | 
						|
	type:			CARD8
 | 
						|
	data:			CARD8
 | 
						|
	pad:			CARD16
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMVModMapDesc
 | 
						|
	key:			CARD8
 | 
						|
	pad:			CARD8
 | 
						|
	vmods:			CARD16
 | 
						|
└───
 | 
						|
 | 
						|
                              ❧❧❧❧❧❧❧❧❧❧❧
 | 
						|
 | 
						|
3.3.4 XKMIndicators
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMIndicators
 | 
						|
	section_info:		XKMSectionInfo
 | 
						|
	name:			XKMCountedString
 | 
						|
	num_indicators:		CARD8
 | 
						|
	pad0:			CARD8
 | 
						|
	pad1:			CARD16
 | 
						|
	indicators:		LISTofXKMIndicatorMapDesc
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMIndicatorMapDesc
 | 
						|
	name:			XKMCountedString
 | 
						|
	indicator:		CARD8
 | 
						|
	flags:			CARD8
 | 
						|
	which_mods:		CARD8
 | 
						|
	real_mods:		CARD8
 | 
						|
	vmods:			CARD16
 | 
						|
	which_groups:		CARD8
 | 
						|
	groups:			CARD8
 | 
						|
	ctrls:			CARD32
 | 
						|
└───
 | 
						|
                              ❧❧❧❧❧❧❧❧❧❧❧
 | 
						|
 | 
						|
3.3.5 XKMKeyNames
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMKeyNames
 | 
						|
	section_info:		XKMSectionInfo
 | 
						|
	name:			XKMCountedString
 | 
						|
	min_keycode:		CARD8
 | 
						|
	max_keycode:		CARD8
 | 
						|
	num_aliases:		CARD8
 | 
						|
	pad:			CARD8
 | 
						|
	keynames:		LISTofXKMKeyname
 | 
						|
	aliases:		LISTofXKMKeyAlias
 | 
						|
└───
 | 
						|
 | 
						|
keynames contains max_keycode - min_keycode + 1 entries.
 | 
						|
 | 
						|
┌───
 | 
						|
  XkmKeyname
 | 
						|
	name:			4 * CHAR8
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XkmKeyAlias
 | 
						|
	real:			XkmKeyname
 | 
						|
	alias:			XkmKeyname
 | 
						|
└───
 | 
						|
 | 
						|
                              ❧❧❧❧❧❧❧❧❧❧❧
 | 
						|
 | 
						|
3.3.5 XKMGeometry
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMGeometry
 | 
						|
	section_info:		XKMSectionInfo
 | 
						|
	name:			XKMCountedString
 | 
						|
	width_mm:		CARD16
 | 
						|
	height_mm:		CARD16
 | 
						|
	base_color_ndx:		CARD8
 | 
						|
	label_color_ndx:	CARD8
 | 
						|
	num_properties:		CARD16
 | 
						|
	num_colors:		CARD16
 | 
						|
	num_shapes:		CARD16
 | 
						|
	num_sections:		CARD16
 | 
						|
	num_doodads:		CARD16
 | 
						|
	num_key_aliases:	CARD16
 | 
						|
	pad:			CARD16
 | 
						|
	label_font:		XKMCountedString
 | 
						|
	properties:		LISTofXKMGeomProperty
 | 
						|
	colors:			LISTofXKMCountedString
 | 
						|
	shapes:			LISTofXKMGeomShape
 | 
						|
	sections:		LISTofXKMGeomSection
 | 
						|
	doodads:		LISTofXKMGeomDoodad
 | 
						|
	key_aliases:		LISTofXKMKeyAlias
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMGeomProperty
 | 
						|
	name:			XKMCountedString
 | 
						|
	value:			XKMCountedString
 | 
						|
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMGeomShape
 | 
						|
	name:			XKMCountedString
 | 
						|
	num_outlines:		CARD8
 | 
						|
	primary_idx:		CARD8
 | 
						|
	approx_idx:		CARD8
 | 
						|
	pad:			CARD8
 | 
						|
	outlines:		LISTofXKMOutlineDesc
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMOutlineDesc
 | 
						|
	num_points:		CARD8
 | 
						|
	corner_radius:		CARD8
 | 
						|
	pad:			CARD16
 | 
						|
	points:			LISTofXKMPointDesc
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMPointDesc
 | 
						|
	x:			INT16
 | 
						|
	y:			INT16
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMGeomSection
 | 
						|
	name:			XKMCountedString
 | 
						|
	top:			INT16
 | 
						|
	left:			INT16
 | 
						|
	width:			CARD16
 | 
						|
	height:			CARD16
 | 
						|
	angle:			INT16
 | 
						|
	priority:		CARD8
 | 
						|
	num_rows:		CARD8
 | 
						|
	num_doodads:		CARD8
 | 
						|
	num_overlays:		CARD8
 | 
						|
	pad:			CARD16
 | 
						|
	rows:			LISTofXKMRowDesc
 | 
						|
	doodads:		LISTofXKMGeomDoodad
 | 
						|
	overlays:		LISTofXKMGeomOverlay
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMRowDesc
 | 
						|
	top:			INT16
 | 
						|
	left:			INT16
 | 
						|
	num_keys:		CARD8
 | 
						|
	vertical:		BOOL
 | 
						|
	pad:			CARD16
 | 
						|
	keys:			XKMKeyDesc
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMKeyDesc
 | 
						|
	name:			XKMKeyname
 | 
						|
	gap:			INT16
 | 
						|
	shape_idx:		CARD8
 | 
						|
	color_idx:		CARD8
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMGeomDoodad
 | 
						|
	name:			XKMCountedString
 | 
						|
	type:			CARD8
 | 
						|
	priority:		CARD8
 | 
						|
	top:			INT16
 | 
						|
	left:			INT16
 | 
						|
	pad1:			CARD16
 | 
						|
	pad2:			CARD32
 | 
						|
	pad3:			CARD32
 | 
						|
	───
 | 
						|
        type ⇒ XkbOutlineDoodad ||
 | 
						|
        type ⇒ XkbSolideDoodad
 | 
						|
	⇒
 | 
						|
		type:			CARD8
 | 
						|
		priority:		CARD8
 | 
						|
		top:			INT16
 | 
						|
		left:			INT16
 | 
						|
		angle:			INT16
 | 
						|
		color_idx:		CARD8
 | 
						|
		shape_idx:		CARD8
 | 
						|
		pad0:			CARD16
 | 
						|
		pad1:			CARD32
 | 
						|
	───
 | 
						|
        type ⇒ XkbTextDoodad
 | 
						|
	⇒
 | 
						|
		type:			CARD8
 | 
						|
		priority:		CARD8
 | 
						|
		top:			INT16
 | 
						|
		left:			INT16
 | 
						|
		angle:			INT16
 | 
						|
		width:			CARD16
 | 
						|
		height:			CARD16
 | 
						|
		color_idx:		CARD8
 | 
						|
		pad0:			CARD8
 | 
						|
		pad1:			CARD16
 | 
						|
		text:			XKMCountedString
 | 
						|
		font:			XKMCountedString
 | 
						|
	───
 | 
						|
        type ⇒ XkbIndicatorDoodad
 | 
						|
	⇒
 | 
						|
		type:			CARD8
 | 
						|
		priority:		CARD8
 | 
						|
		top:			INT16
 | 
						|
		left:			INT16
 | 
						|
		shape_idx:		CARD8
 | 
						|
		on_color_idx:		CARD8
 | 
						|
		off_color_idx:		CARD8
 | 
						|
		pad0:			CARD8
 | 
						|
		pad1:			CARD16
 | 
						|
		pad2:			CARD32
 | 
						|
	───
 | 
						|
        type ⇒ XkbLogoDoodad
 | 
						|
	⇒
 | 
						|
		type:			CARD8
 | 
						|
		priority:		CARD8
 | 
						|
		top:			INT16
 | 
						|
		left:			INT16
 | 
						|
		angle:			INT16
 | 
						|
		color_idx:		CARD8
 | 
						|
		shape_idx:		CARD8
 | 
						|
		pad0:			CARD16
 | 
						|
		pad1:			CARD32
 | 
						|
		logo_name:		XKMCountedString
 | 
						|
└───
 | 
						|
 | 
						|
WARNING: XKMGeomDoodad has variable length depending on the type.
 | 
						|
NOTE: The current server implementation does not use all fields of all
 | 
						|
structures.
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMOverlayDesc
 | 
						|
	name:			XKMCountedString
 | 
						|
	num_rows:		CARD8
 | 
						|
	pad0:			CARD8
 | 
						|
	pad1:			CARD16
 | 
						|
	rows:			LISTofXKMOverlayRowDesc
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMOverlayRowDesc
 | 
						|
	name:			XKMCountedString
 | 
						|
	row_under:		CARD8
 | 
						|
	num_keys:		CARD8
 | 
						|
	pad:			CARD16
 | 
						|
	keys:			LISTofXKMOverlayKeyDesc
 | 
						|
└───
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMOverlayKeyDesc
 | 
						|
	over:			XKMKeyname
 | 
						|
	under:			XKMKeyname
 | 
						|
└───
 | 
						|
 | 
						|
                              ❧❧❧❧❧❧❧❧❧❧❧
 | 
						|
 | 
						|
3.3.6 XKMVirtualMods
 | 
						|
 | 
						|
┌───
 | 
						|
  XKMOverlayRowDesc
 | 
						|
	section_info:		XKMSectionInfo
 | 
						|
	name:			XKMCountedString
 | 
						|
	bound_mask:		SETofVMODBITS
 | 
						|
	named_mask:		SETofVMODBITS
 | 
						|
	vmods:			LISTofCARD8
 | 
						|
	pad:			pad(vmods)
 | 
						|
	names:			LISTofXKMCountedString
 | 
						|
└───
 | 
						|
 | 
						|
	VMODBITS:		CARD16
 | 
						|
 | 
						|
Number of elements in vmods is equal to the number of bits set in
 | 
						|
bound_mask. The padding completes vmods to a multiple of 4 byte units.
 | 
						|
Number of elements in names is equal to the number of bits set in
 | 
						|
named_mask.
 |