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