1<chapter id='Key_Event_Processing_in_the_Client'>
2<title>Key Event Processing in the Client</title>
3
4<para>
5The XKB <emphasis>
6client map</emphasis>
7 for a keyboard is the collection of information a client needs to interpret
8key events that come from that keyboard. It contains a global list of <emphasis>
9key types</emphasis>
10, described in <link linkend='Key_Types'>Key Types</link>,
11and an array of <emphasis>
12key symbol map</emphasis>
13s, each of which describes the symbols bound to one particular key and the
14rules to be used to interpret those symbols.
15</para>
16
17<sect1 id='Notation_and_Terminology'>
18<title>Notation and Terminology</title>
19
20<para>
21XKB associates a two-dimensional array of symbols with each key. Symbols are
22addressed by keyboard group (see <link linkend='Keyboard_State'>
23Keyboard State</link>) and shift level, where level is defined as in the
24ISO9995 standard:
25</para>
26
27<variablelist>
28  <varlistentry>
29    <term>Level</term>
30    <listitem>
31      <para>
32One of several states (normally 2 or 3) which govern which graphic
33character is produced when a graphic key is actuated. In certain cases the
34level may also affect function keys.
35      </para>
36    </listitem>
37  </varlistentry>
38</variablelist>
39
40<para>
41Note that shift level is derived from the modifier state, but not necessarily
42in the same way for all keys. For example, the <emphasis>
43Shift</emphasis>
44 modifier selects shift level 2 on most keys, but for keypad keys the modifier
45bound to <emphasis>
46Num_Lock</emphasis>
47 (i.e. the <emphasis>
48NumLock</emphasis>
49 virtual modifier) also selects shift level 2.gray symbols on a key
50</para>
51
52<para>
53We use the notation G<emphasis>
54n</emphasis>
55L<emphasis>
56n</emphasis>
57 to specify the position of a symbol on a key or in memory:
58</para>
59
60<mediaobject>
61 <imageobject> <imagedata format="SVG" fileref="XKBproto-6.svg"/>
62 </imageobject>
63 </mediaobject>
64
65
66<para>
67The gray characters indicate symbols that are implied or expected but are not
68actually engraved on the key.
69</para>
70
71<note><para>Unfortunately, the "natural" orientation of symbols on a key and
72the natural orientation in memory are reversed from one another, so keyboard
73group refers to a column on the key and a row in memory. There’s no real help
74for it, but we try to minimize confusion by using "group" and "level" (or
75"shift level") to refer to symbols regardless of context.</para></note>
76
77</sect1>
78<sect1 id='Determining_the_KeySym_Associated_with_a_Key_Event'>
79<title>Determining the KeySym Associated with a Key Event</title>
80
81<para>
82To look up the symbol associated with an XKB key event, we need to know the
83group and shift level that correspond to the event.
84</para>
85
86
87<para>
88Group is reported in bits 13-14 of the state field of the key event, as
89described in <link linkend='Computing_A_State_Field_from_an_XKB_State'>Computing A State
90Field from an XKB State</link>. The keyboard group reported in the event might
91be out-of-range for any particular key because the number of groups can vary
92from key to key. The XKB description of each key contains a <emphasis>
93group info</emphasis>
94 field which is interpreted identically to the global groups wrap control (see
95<link linkend='Computing_Effective_Modifier_and_Group'>Computing Effective Modifier and
96Group</link>) and which specifies the interpretation of groups that are
97out-of-range for that key.
98</para>
99
100
101<para>
102Once we have determined the group to be used for the event, we have to
103determine the shift level. The description of a key includes a <emphasis>
104key type</emphasis>
105 for each group of symbols bound to the key. Given the modifiers from the key
106event, this key type yields a shift level and a set of "leftover" modifiers, as
107described in <link linkend='Key_Types'>Key Types</link>
108below.
109</para>
110
111
112<para>
113Finally, we can use the effective group and the shift level returned by the
114type of that group to look up a symbol in a two-dimensional array of symbols
115associated with the key.
116</para>
117
118
119<sect2 id='Key_Types'>
120<title>Key Types</title>
121
122<para>
123Each entry of a key type’s <emphasis>
124map</emphasis>
125 field specifies the shift level that corresponds to some XKB modifier
126definition; any combination of modifiers that is not explicitly listed
127somewhere in the map yields shift level one. Map entries which specify unbound
128virtual modifiers (see <link linkend='Inactive_Modifier_Definitions'>Inactive
129Modifier Definitions</link>) are not considered; each entry contains an
130automatically-updated <emphasis>
131active</emphasis>
132 field which indicates whether or not it should be used.
133</para>
134
135
136<para>
137Each key type includes a few fields that are derived from the contents of the
138map and which report some commonly used values so they don’t have to be
139constantly recalculated. The <emphasis>
140numLevels</emphasis>
141 field contains the highest shift level reported by any of its map entries; XKB
142uses <emphasis>
143numLevels</emphasis>
144 to insure that the array of symbols bound to a key is large enough (the number
145of levels reported by a key type is also referred to as its width). The
146<emphasis>
147modifiers</emphasis>
148 field reports all real modifiers considered by any of the map entries for the
149type. Both <emphasis>
150modifiers</emphasis>
151<emphasis>
152 </emphasis>
153and <emphasis>
154numLevels</emphasis>
155 are updated automatically by XKB and neither can be changed explicitly.
156</para>
157
158
159<para>
160Any modifiers specified in <emphasis>
161modifiers</emphasis>
162 are normally <emphasis>
163consumed</emphasis>
164 (see <link linkend='Transforming_the_KeySym_Associated_with_a_Key_Event'>Transforming the KeySym
165Associated with a Key Event</link>), which means that they are not considered
166during any of the later stages of event processing. For those rare occasions
167that a modifier <emphasis>
168should</emphasis>
169 be considered despite having been used to look up a symbol, key types include
170an optional <emphasis>
171preserve</emphasis>
172 field. If a <emphasis>
173preserve</emphasis>
174 list is present, each entry corresponds to one of the key type’s map entries
175and lists the modifiers that should <emphasis>
176not</emphasis>
177 be consumed if the matching map entry is used to determine shift level.
178</para>
179
180
181<para>
182For example, the following key type implements caps lock as defined by the core
183protocol (using the second symbol bound to the key):
184</para>
185
186<literallayout class='monospaced'>
187type "ALPHABETIC" {
188	modifiers = Shift+Lock;
189	map[Shift]= Level2;
190	map[Lock]= Level2;
191	map[Shift+Lock]= Level2;
192};
193</literallayout>
194
195<para>
196The problem with this kind of definition is that we could assign completely
197unrelated symbols to the two shift levels, and "Caps Lock" would choose the
198second symbol. Another definition for alphabetic keys uses system routines to
199capitalize the keysym:
200</para>
201
202<literallayout class='monospaced'>
203type "ALPHABETIC" {
204	modifiers= Shift;
205	map[Shift]= Level2;
206};
207</literallayout>
208
209<para>
210When caps lock is applied using this definition, we take the symbol from shift
211level one and capitalize it using system-specific capitalization rules. If
212shift and caps lock are both set, we take the symbol from shift level two and
213try to capitalize it, which usually has no effect.
214</para>
215
216
217<para>
218The following key type implements shift-cancels-caps lock behavior for
219alphabetic keys:
220</para>
221
222<literallayout class='monospaced'>
223type "ALPHABETIC" {
224	modifiers = Shift+Lock;
225	map[Shift] = Level2;
226	preserve[Lock]= Lock;
227};
228</literallayout>
229
230<para>
231Consider the four possible states that can affect alphabetic keys: no
232modifiers, shift alone, caps lock alone or shift and caps lock together. The
233map contains no explicit entry for <emphasis>
234None</emphasis>
235 (no modifiers), so if no modifiers are set, any group with this type returns
236the first keysym. The map entry for <emphasis>
237Shift</emphasis>
238 reports <emphasis>
239Level2</emphasis>
240, so any group with this type returns the second symbol when <emphasis>
241Shift</emphasis>
242 is set. There is no map entry for <emphasis>
243Lock</emphasis>
244 alone, but the type specifies that the <emphasis>
245Lock</emphasis>
246 modifier should be preserved in this case, so <emphasis>
247Lock</emphasis>
248 alone returns the first symbol in the group but first applies the
249capitalization transformation, yielding the capital form of the symbol. In the
250final case, there is no map entry for <emphasis>
251Shift+Lock</emphasis>
252, so it returns the first symbol in the group; there is no preserve entry, so
253the <emphasis>
254Lock</emphasis>
255 modifier is consumed and the symbol is not capitalized.
256</para>
257
258
259</sect2>
260<sect2 id='Key_Symbol_Map'>
261<title>Key Symbol Map</title>
262
263<para>
264The <emphasis>
265key symbol map</emphasis>
266 for a key contains all of the information that a client needs to process
267events generated by that key. Each key symbol mapping reports:
268</para>
269
270<itemizedlist>
271<listitem>
272  <para>The number of groups of symbols bound to the key (<emphasis>
273numGroups</emphasis>
274).
275  </para>
276</listitem>
277<listitem>
278  <para>The treatment of out-of-range groups (<emphasis>
279groupInfo</emphasis>
280).
281  </para>
282</listitem>
283<listitem>
284  <para>The index of the key type to for each <emphasis>
285possible</emphasis>
286 group (<emphasis>
287kt_index[MaxKbdGroups]</emphasis>
288).
289  </para>
290</listitem>
291<listitem>
292  <para>The width of the widest type associated with the key (<emphasis>
293groupsWidth</emphasis>
294).
295  </para>
296</listitem>
297<listitem>
298  <para>The two-dimensional (numGroups <emphasis>
299×</emphasis>
300 groupsWidth) array of symbols bound to the key.
301  </para>
302</listitem>
303</itemizedlist>
304
305<para>
306It is legal for a key to have zero groups, in which case it also has zero
307symbols and all events from that key yield <emphasis>
308NoSymbol</emphasis>
309. The array of key types is of fixed width and is large enough to hold key
310types for the maximum legal number of groups (<emphasis>
311MaxKbdGroups</emphasis>
312, currently four); if a key has fewer than <emphasis>
313MaxKbdGroups</emphasis>
314 groups, the extra key types are reported but ignored. The <emphasis>
315groupsWidth</emphasis>
316 field cannot be explicitly changed; it is updated automatically whenever the
317symbols or set of types bound to a key are changed.
318</para>
319
320
321<para>
322If, when looking up a symbol, the effective keyboard group is out-of-range for
323the key, the <emphasis>
324groupInfo</emphasis>
325 field of the key symbol map specifies the rules for determining the
326corresponding legal group as follows:
327</para>
328
329<itemizedlist>
330<listitem>
331  <para>If the <emphasis>
332RedirectIntoRange</emphasis>
333 flag is set, the two least significant bits of <emphasis>
334groupInfo</emphasis>
335 specify the index of a group to which all illegal groups correspond. If the
336specified group is also out of range, all illegal groups map to <emphasis>
337Group1</emphasis>
338.
339  </para>
340</listitem>
341<listitem>
342  <para>If <emphasis>
343ClampIntoRange</emphasis>
344 flag is set, out-of-range groups correspond to the nearest legal group.
345Effective groups larger than the highest supported group are mapped to the
346highest supported group; effective groups less than <emphasis>
347Group1</emphasis>
348 are mapped to <emphasis>
349Group1</emphasis>
350. For example, a key with two groups of symbols uses <emphasis>
351Group2</emphasis>
352 type and symbols if the global effective group is either <emphasis>
353Group3</emphasis>
354 or <emphasis>
355Group4</emphasis>
356.
357  </para>
358</listitem>
359<listitem>
360  <para>If neither flag is set, group is wrapped into range using integer
361modulus. For example, a key with two groups of symbols for which groups wrap
362uses <emphasis>
363Group1</emphasis>
364 symbols if the global effective group is <emphasis>
365Group3</emphasis>
366 or <emphasis>
367Group2</emphasis>
368 symbols if the global effective group is <emphasis>
369Group4</emphasis>
370.
371  </para>
372</listitem>
373</itemizedlist>
374
375<para>
376The client map contains an array of key symbol mappings, with one entry for
377each key between the minimum and maximum legal keycodes, inclusive. All
378keycodes which fall in that range have key symbol mappings, whether or not any
379key actually yields that code.
380</para>
381
382
383</sect2>
384</sect1>
385<sect1 id='Transforming_the_KeySym_Associated_with_a_Key_Event'>
386<title>Transforming the KeySym Associated with a Key Event</title>
387
388<para>
389Any modifiers that were not used to look up the keysym, or which were
390explicitly preserved, might indicate further transformations to be performed on
391the keysym or the character string that is derived from it. For example, If the
392<emphasis>
393Lock</emphasis>
394 modifier is set, the symbol and corresponding string should be capitalized
395according to the locale-sensitive capitalization rules specified by the system.
396If the <emphasis>
397Control</emphasis>
398 modifier is set, the keysym is not affected, but the corresponding character
399should be converted to a control character as described in <link
400linkend="default_symbol_transformations">Default Symbol Transformations</link>.
401</para>
402
403
404<para>
405This extension specifies the transformations to be applied when the <emphasis>
406Control</emphasis>
407 or <emphasis>
408Lock</emphasis>
409 modifiers are active but were not used to determine the keysym to be used:
410</para>
411
412<informaltable frame='topbot'>
413<?dbfo keep-together="always" ?>
414<tgroup cols='2' align='left' colsep='0' rowsep='0'>
415<colspec colname='c1' colwidth='1.0*'/>
416<colspec colname='c2' colwidth='3.0*'/>
417<thead>
418  <row rowsep='1'>
419    <entry>Modifier</entry>
420    <entry>Transformation</entry>
421  </row>
422</thead>
423<tbody>
424  <row>
425    <entry><emphasis>
426Control</emphasis>
427    </entry>
428    <entry>Report the control character associated with the symbol. This
429extension defines the control characters associated with the ASCII alphabetic
430characters (both upper and lower case) and for a small set of punctuation
431characters (see
432<link linkend="default_symbol_transformations">Default Symbol Transformations</link>).
433Applications are
434free to associate control characters with any symbols that are not specified by
435this extension.</entry>
436  </row>
437  <row>
438    <entry><emphasis>
439Lock</emphasis>
440    </entry>
441    <entry>Capitalize the symbol either according to capitalization rules
442appropriate to the application locale or using the capitalization rules defined
443by this extension (see <link linkend="default_symbol_transformations">Default Symbol Transformations</link>).</entry>
444  </row>
445</tbody>
446</tgroup>
447</informaltable>
448
449<para>
450Interpretation of other modifiers is application dependent.
451</para>
452
453<note><para>This definition of capitalization is fundamentally different from
454the core protocol’s, which uses the lock modifier to select from the symbols
455bound to the key. Consider key 9 in the
456<link linkend='Client_Map_Example'>client map example</link>;
457the core protocol provides no way to generate the capital form
458of either symbol bound to this key. XKB specifies that we first look up the
459symbol and then capitalize, so XKB yields the capital form of the two symbols
460when caps lock is active. </para></note>
461
462<para>
463XKB specifies the behavior of <emphasis>
464Lock</emphasis>
465 and <emphasis>
466Control</emphasis>
467, but interpretation of other modifiers is left to the application.
468</para>
469
470
471</sect1>
472<sect1 id='Client_Map_Example'>
473<title>Client Map Example</title>
474
475<para>
476Consider a simple, if unlikely, keyboard with the following keys (gray
477characters indicate symbols that are implied or expected but are not actually
478engraved on the key):
479</para>
480
481<mediaobject>
482 <imageobject> <imagedata format="SVG" fileref="XKBproto-7.svg"/>
483 </imageobject>
484 </mediaobject>
485
486
487<para>
488The core protocol represents this keyboard as a simple array with one row per
489key and four columns (the widest key, key 10, determines the width of the
490entire array).
491</para>
492
493<informaltable frame='topbot'>
494<?dbfo keep-together="always" ?>
495<tgroup cols='5' align='left' colsep='0' rowsep='0'>
496<colspec colname='c1' colwidth='1.0*'/>
497<colspec colname='c2' colwidth='2.0*'/>
498<colspec colname='c3' colwidth='2.0*'/>
499<colspec colname='c4' colwidth='2.0*'/>
500<colspec colname='c5' colwidth='2.0*'/>
501<thead>
502  <row rowsep='1'>
503    <entry>Key</entry>
504    <entry>G1L1</entry>
505    <entry>G1L2</entry>
506    <entry>G2L1</entry>
507    <entry>G2L2</entry>
508  </row>
509</thead>
510<tbody>
511  <row>
512    <entry>8</entry>
513    <entry>Q</entry>
514    <entry>NoSymbol</entry>
515    <entry>at</entry>
516    <entry>NoSymbol</entry>
517  </row>
518  <row>
519    <entry>9</entry>
520    <entry>odiaeresis</entry>
521    <entry>egrave</entry>
522    <entry>NoSymbol</entry>
523    <entry>NoSymbol</entry>
524  </row>
525  <row>
526    <entry>10</entry>
527    <entry>A</entry>
528    <entry>NoSymbol</entry>
529    <entry>Æ</entry>
530    <entry>NoSymbol</entry>
531  </row>
532  <row>
533    <entry>11</entry>
534    <entry>ssharp</entry>
535    <entry>question</entry>
536    <entry>backslash</entry>
537    <entry>questiondown</entry>
538  </row>
539  <row>
540    <entry>12</entry>
541    <entry>KP_End</entry>
542    <entry>KP_1</entry>
543    <entry>NoSymbol</entry>
544    <entry>NoSymbol</entry>
545  </row>
546  <row>
547    <entry>13</entry>
548    <entry>Num_Lock</entry>
549    <entry>NoSymbol</entry>
550    <entry>NoSymbol</entry>
551    <entry>NoSymbol</entry>
552  </row>
553  <row>
554    <entry>14</entry>
555    <entry>NoSymbol</entry>
556    <entry>NoSymbol</entry>
557    <entry>NoSymbol</entry>
558    <entry>NoSymbol</entry>
559  </row>
560  <row>
561    <entry>15</entry>
562    <entry>Return</entry>
563    <entry>NoSymbol</entry>
564    <entry>NoSymbol</entry>
565    <entry>NoSymbol</entry>
566  </row>
567</tbody>
568</tgroup>
569</informaltable>
570
571<para>
572The row to be used for a given key event is determined by keycode; the column
573to be used is determined by the symbols bound to the key, the state of the
574<emphasis>
575Shift</emphasis>
576 and <emphasis>
577Lock</emphasis>
578 Modifiers and the state of the modifiers bound to the <emphasis>
579Num_Lock</emphasis>
580 and <emphasis>
581Mode_switch</emphasis>
582 keys as specified by the core protocol.
583</para>
584
585
586<para>
587The XKB description of this keyboard consists of six key symbol maps, each of
588which specifies the types and symbols associated with each keyboard group for
589one key:
590</para>
591
592<informaltable frame='topbot'>
593<?dbfo keep-together="always" ?>
594<tgroup cols='4' align='left' colsep='0' rowsep='0'>
595<colspec colname='c1' colwidth='1.0*'/>
596<colspec colname='c2' colwidth='1.0*'/>
597<colspec colname='c3' colwidth='1.0*'/>
598<colspec colname='c4' colwidth='1.0*'/>
599<thead>
600  <row rowsep='1'>
601    <entry>Key</entry>
602    <entry>Group: Type</entry>
603    <entry>L1</entry>
604    <entry>L2</entry>
605  </row>
606</thead>
607<tbody>
608  <row>
609    <entry>8</entry>
610    <entry>G1:	ALPHABETIC</entry>
611    <entry>q</entry>
612    <entry>Q</entry>
613  </row>
614  <row>
615    <entry>G2:	ONE_LEVEL</entry>
616    <entry>@</entry>
617    <entry>NoSymbol</entry>
618  </row>
619  <row>
620    <entry>9</entry>
621    <entry>G1:	TWO_LEVEL</entry>
622    <entry>odiaeresis</entry>
623    <entry>egrave</entry>
624  </row>
625  <row>
626    <entry>10</entry>
627    <entry>G1:	ALPHABETIC</entry>
628    <entry>a</entry>
629    <entry>A</entry>
630  </row>
631  <row>
632    <entry>G2:	ALPHABETIC</entry>
633    <entry>ae</entry>
634    <entry>AE</entry>
635  </row>
636  <row>
637    <entry>11</entry>
638    <entry>G1:	TWO_LEVEL</entry>
639    <entry>ssharp</entry>
640    <entry>question</entry>
641  </row>
642  <row>
643    <entry>G2:	ONE_LEVEL</entry>
644    <entry>backslash</entry>
645    <entry>questiondown</entry>
646  </row>
647  <row>
648    <entry>12</entry>
649    <entry>G1:	KEYPAD</entry>
650    <entry>KP_End</entry>
651    <entry>KP_1</entry>
652  </row>
653  <row>
654    <entry>13</entry>
655    <entry>G1:	ONE_LEVEL</entry>
656    <entry>Num_Lock</entry>
657    <entry>&#x0020;</entry>
658  </row>
659  <row>
660    <entry>14</entry>
661    <entry>No Groups</entry>
662    <entry>&#x0020;</entry>
663    <entry>&#x0020;</entry>
664  </row>
665  <row>
666    <entry>15</entry>
667    <entry>G1:	ONE_LEVEL</entry>
668    <entry>Return</entry>
669    <entry>&#x0020;</entry>
670  </row>
671</tbody>
672</tgroup>
673</informaltable>
674
675<para>
676The keycode reported in a key event determines the row to be used for that
677event; the effective keyboard group determines the list of symbols and key type
678to be used. The key type determines which symbol is chosen from the list.
679</para>
680
681
682<para>
683<link linkend='Determining_the_KeySym_Associated_with_a_Key_Event'>Determining the KeySym Associated
684with a Key Event</link> details the procedure to map from a key event to a
685symbol and/or a string.
686</para>
687</sect1>
688</chapter>
689