summaryrefslogtreecommitdiff
path: root/specs/kbproto/ch12.xml
blob: efc6d6a2ca63725247d43161eea3e8f6b42cd5c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024

<chapter id='Interactions_Between_XKB_and_the_Core_Protocol'>
<title>Interactions Between XKB and the Core Protocol</title>

<para>
In addition to providing a number of new requests, XKB replaces or extends
existing core protocol requests and events. Some aspects of the this extension,
such as the ability to lock any key or modifier, are visible even to clients
that are unaware of the XKB extension. Other capabilities, such as control of
keysym selection on a per-key basis, are available only to XKB-aware clients.
</para>


<para>
Though they do not have access to some advanced extension capabilities, the XKB
extension includes compatibility mechanisms to ensure that non-XKB clients
behave as expected and operate at least as well with an XKB-capable server as
they do today.
</para>


<para>
There are a few significant areas in which XKB state and mapping differences
might be visible to XKB-unaware clients:
</para>

<itemizedlist>
<listitem>
  <para>The core protocol uses a modifier to choose between two keyboard
groups, while this extension provides explicit support for multiple groups.
  </para>
</listitem>
<listitem>
  <para>The order of the symbols associated with any given key by XKB might not
match the ordering demanded by the core protocol.
  </para>
</listitem>
</itemizedlist>

<para>
To minimize problems that might result from these differences, XKB includes
ways to specify the correspondence between core protocol and XKB modifiers and
symbols.
</para>


<para>
This section describes the differences between the core X protocol’s notion
of a keyboard mapping and XKB and explains the ways they can interact.
</para>

<sect1 id='Group_Compatibility_Map'>
<title>Group Compatibility Map</title>

<para>
As described in <link linkend='Keyboard_State'>Keyboard
State</link>, the current keyboard group is reported to XKB-aware clients in
bits 13-14 of the state field of many core protocol events. XKB-unaware clients
cannot interpret those bits, but they might use a keyboard modifier to
implement support for a single keyboard group. To ensure that pre-XKB clients
continue to work when XKB is present, XKB makes it possible to map an XKB state
field, which includes both keyboard group and modifier state into a pre-XKB
state field which contains only modifiers.
</para>


<para>
A keyboard description includes one <emphasis>
group compatibility map</emphasis>
 per keyboard group (four in all). Each such map is a modifier definition (i.e.
specifies both real and virtual modifiers) which specifies the modifiers to be
set in the compatibility states when the corresponding keyboard group is
active. Here are a few examples to illustrate the application of the group
compatibility map:
</para>

<informaltable frame='topbot'>
<?dbfo keep-together="always" ?>
<tgroup cols='6' align='left' colsep='0' rowsep='0'>
<colspec colname='c1' colwidth='1.0*'/>
<colspec colname='c2' colwidth='2.0*'/>
<colspec colname='c3' colwidth='1.5*'/>
<colspec colname='c4' colwidth='2.2*'/>
<colspec colname='c5' colwidth='1.5*'/>
<colspec colname='c6' colwidth='2.0*'/>
<thead>
  <row rowsep='1'>
    <entry>Group</entry>
    <entry>GroupCompat Map</entry>
    <entry>Effective Modifiers</entry>
    <entry> State for XKB Clients</entry>
    <entry>Compatibility Modifiers</entry>
    <entry>State for non-XKB Clients</entry>
  </row>
</thead>
<tbody>
  <row>
    <entry>1</entry>
    <entry>Group1=None</entry>
    <entry>Shift</entry>
    <entry>x00xxxxx00000001</entry>
    <entry>Shift</entry>
    <entry>xxxxxxxx00000001</entry>
  </row>
  <row>
    <entry>2</entry>
    <entry>Group2=Mod3</entry>
    <entry>None</entry>
    <entry>x01xxxxx00000000</entry>
    <entry>Mod3</entry>
    <entry>xxxxxxxx00100000</entry>
  </row>
  <row>
    <entry>3</entry>
    <entry>Group3=Mod2</entry>
    <entry>Shift</entry>
    <entry>x10xxxxx00000001</entry>
    <entry>Shift+Mod2</entry>
    <entry>xxxxxxxx00010001</entry>
  </row>
  <row>
    <entry>4</entry>
    <entry>Group4=None</entry>
    <entry>Control</entry>
    <entry>x11xxxxx00000100</entry>
    <entry>Control</entry>
    <entry>xxxxxxxx00000100</entry>
  </row>
</tbody>
</tgroup>
</informaltable>

<para>
Note that non-XKB clients (i.e. clients that are linked with a version of the X
library that does not support XKB) cannot detect the fact that <emphasis>
Group4</emphasis>
 is active in this example because the group compatibility map for <emphasis>
Group4</emphasis>
 does not specify any modifiers.
</para>


<sect2 id='Setting_a_Passive_Grab_for_an_XKB_State'>
<title>Setting a Passive Grab for an XKB State</title>

<para>
The fact that the <emphasis>
state</emphasis>
 field of an event might look different when XKB is present can cause problems
with passive grabs. Existing clients specify the modifiers they wish to grab
using the rules defined by the core protocol, which use a normal modifier to
indicate keyboard group. If we used an XKB state field, the high bits of the
state field would be non-zero whenever the keyboard was in any group other than
<emphasis>
Group1</emphasis>
, and none of the passive grabs set by clients could ever be triggered.
</para>


<para>
To avoid this behavior, the X server normally uses the compatibility grab state
to decide whether or not to activate a passive grab, even for XKB-aware
clients. The group compatibility map attempts to encode the keyboard group in
one or more modifiers of the compatibility state, so existing clients continue
to work exactly the way they do today. By default, there is no way to directly
specify a keyboard group in a <emphasis>
Grabbed</emphasis>
 or <emphasis>
GrabButton</emphasis>
 request, but groups can be specified indirectly by correctly adjusting the
group compatibility map.
</para>


<para>
Clients that wish to specify an XKB keyboard state, including a separate
keyboard group, can set the <emphasis>
GrabsUseXKBState</emphasis>
 per-client flag which indicates that all subsequent key and button grabs from
the requesting clients are specified using an XKB state.
</para>


<para>
Whether the XKB or core state should be used to trigger a grab is determined by
the setting of the <emphasis>
GrabsUseXKBState</emphasis>
 flag for the requesting client at the time the key or button is grabbed. There
is no way to change the state to be used for a grab that is already registered
or for grabs that are set by some other client.
</para>


</sect2>
</sect1>
<sect1 id='Changing_the_Keyboard_Mapping_Using_the_Core_Protocol'>
<title>Changing the Keyboard Mapping Using the Core Protocol</title>

<para>
An XKB keyboard description includes a lot of information that is not present
in the core protocol description of a keyboard. Whenever a client remaps the
keyboard using core protocol requests, XKB examines the map to determine likely
default values for the components that cannot be specified using the core
protocol.
</para>


<para>
Some aspects of this automatic mapping are configurable, and make it fairly
easy to take advantage of many XKB features using existing tools like <emphasis>
xmodmap</emphasis>
, but much of the process of mapping a core keyboard description into an XKB
description is designed to preserve compatible behavior for pre-XKB clients and
cannot be redefined by the user. Clients or users that want behavior that
cannot be described using this mapping should use XKB functions directly.
</para>


<sect2 id='Explicit_Keyboard_Mapping_Components'>
<title>Explicit Keyboard Mapping Components</title>

<para>
This automatic remapping might accidentally replace definitions that were
explicitly requested by an application, so the XKB keyboard description defines
a set of <emphasis>
explicit components</emphasis>
 for each key; any components that are listed in the explicit components for a
key are not changed by the automatic keyboard mapping. The explicit components
field for a key can contain any combination of the following values:
</para>

<informaltable frame='topbot'>
<?dbfo keep-together="always" ?>
<tgroup cols='2' align='left' colsep='0' rowsep='0'>
<colspec colname='c1' colwidth='1.0*'/>
<colspec colname='c2' colwidth='3.0*'/>
<thead>
  <row rowsep='1'>
    <entry>Bit in Explicit Mask</entry>
    <entry>Protects Against</entry>
  </row>
</thead>
<tbody>
  <row>
    <entry>ExplicitKeyType1</entry>
    <entry>Automatic determination of the key type associated with <emphasis>
Group1</emphasis>
 (see <link linkend='Assigning_Types_To_Groups_of_Symbols_for_a_Key'>Assigning Types To Groups of
Symbols for a Key</link>)</entry>
  </row>
  <row>
    <entry>ExplicitKeyType2</entry>
    <entry>Automatic determination of the key type associated with <emphasis>
Group2 </emphasis>
(see <link linkend='Assigning_Types_To_Groups_of_Symbols_for_a_Key'>Assigning Types To Groups of
Symbols for a Key</link>)</entry>
  </row>
  <row>
    <entry>ExplicitKeyType3</entry>
    <entry>Automatic determination of the key type associated with <emphasis>
Group3 </emphasis>
(see <link linkend='Assigning_Types_To_Groups_of_Symbols_for_a_Key'>Assigning Types To Groups of
Symbols for a Key</link>).</entry>
  </row>
  <row>
    <entry>ExplicitKeyType4</entry>
    <entry>Automatic determination of the key type associated with <emphasis>
Group4 </emphasis>
(see <link linkend='Assigning_Types_To_Groups_of_Symbols_for_a_Key'>Assigning Types To Groups of
Symbols for a Key</link>).</entry>
  </row>
  <row>
    <entry>ExplicitInterpret</entry>
    <entry>Application of any of the fields of a symbol interpretation to the
key in question (see <link linkend='Assigning_Actions_To_Keys'>Assigning
Actions To Keys</link>).</entry>
  </row>
  <row>
    <entry>ExplicitAutoRepeat</entry>
    <entry>Automatic determination of autorepeat status for the key, as
specified in a symbol interpretation (see <link linkend='Assigning_Actions_To_Keys'>Assigning Actions To
Keys</link>).</entry>
  </row>
  <row>
    <entry>ExplicitBehavior</entry>
    <entry>Automatic assignment of the <emphasis>
KB_Lock</emphasis>
 behavior to the key, if the <emphasis>
LockingKey</emphasis>
 flag is set in a symbol interpretation (see <link linkend='Assigning_Actions_To_Keys'>Assigning Actions To
Keys</link>).</entry>
  </row>
  <row>
    <entry>ExplicitVModMap</entry>
    <entry>Automatic determination of the virtual modifier map for the key
based on the actions assigned to the key and the symbol interpretations which
match the key (see <link linkend='Assigning_Actions_To_Keys'>Assigning
Actions To Keys</link>).</entry>
  </row>
</tbody>
</tgroup>
</informaltable>

</sect2>
<sect2 id='Assigning_Symbols_To_Groups'>
<title>Assigning Symbols To Groups</title>

<para>
The first step in applying the changes specified by a core protocol <emphasis>
ChangeKeyboardMapping</emphasis>
 request to the XKB description of a keyboard is to determine the number of
groups that are defined for the key and the width of each group. The XKB
extension does not change key types in response to core protocol <emphasis>
SetModifierMapping</emphasis>
 requests, but it does choose key actions as described in <link linkend='Assigning_Actions_To_Keys'>Assigning Actions To Keys</link>.
</para>


<para>
Determining the number of symbols required for each group is straightforward.
If the key type for some group is not protected by the corresponding <emphasis>
ExplicitKeyType</emphasis>
 component, that group has two symbols. If any of the explicit components for
the key include <emphasis>
ExplicitKeyType3</emphasis>
 or <emphasis>
ExplicitKeyType4</emphasis>
, the width of the key type currently assigned to that group determines the
number of symbols required for the group in the core protocol keyboard
description. The explicit type components for <emphasis>
Group1</emphasis>
 and <emphasis>
Group2</emphasis>
 behave similarly, but for compatibility reasons the first two groups must have
at least two symbols in the core protocol symbol mapping. Even if an explicit
type assigned to either of the first two keyboard groups has fewer than two
symbols, XKB requires two symbols for it in the core keyboard description.
</para>


<para>
If the core protocol request contains fewer symbols than XKB needs, XKB adds
trailing <emphasis>
NoSymbol</emphasis>
 keysyms to the request to pad it to the required length. If the core protocol
request includes more symbols than it needs, XKB truncates the list of keysyms
to the appropriate length.
</para>


<para>
Finally, XKB divides the symbols from the (possibly padded or truncated) list
of symbols specified by the core protocol request among the four keyboard
groups. In most cases, the symbols for each group are taken from the core
protocol definition in sequence (i.e. the first pair of symbols is assigned to
<emphasis>
Group1</emphasis>
, the second pair of symbols is assigned to <emphasis>
Group2</emphasis>
, and so forth). If either <emphasis>
Group1</emphasis>
 or <emphasis>
Group2</emphasis>
 has an explicitly defined key type with a width other than two, it gets a
little more complicated.
</para>


<sect3 id='Assigning_Symbols_to_Groups_One_and_Two_with_Explicitly_Defined_Key_Types'>
<title>Assigning Symbols to Groups One and Two with Explicitly Defined Key Types</title>

<para>
The server assigns the first four symbols from the expanded or truncated map to
the symbol positions <emphasis>G1L1</emphasis> , <emphasis>G1L2</emphasis>,
<emphasis>G2L1</emphasis> and <emphasis>G2L2</emphasis>, respectively. If the key
type assigned to <emphasis>Group1</emphasis> reports more than two shift levels,
the fifth and following symbols contain
the extra keysyms for <emphasis>
Group2</emphasis>
. If the key type assigned to <emphasis>
Group2</emphasis>
 reports more than two shift levels, the extra symbols follow the symbols (if
any) for <emphasis>
Group1</emphasis>
 in the core protocol list of symbols. Symbols for <emphasis>
Group3</emphasis>
 and <emphasis>
Group4</emphasis>
 are contiguous and follow the extra symbols, if any, for <emphasis>
Group1</emphasis>
 and <emphasis>
Group2</emphasis>
.
</para>


<para>
For example, consider a key with a key type that returns three shift levels
bound to each group. The symbols bound to the core protocol are assigned in
sequence to the symbol positions:
</para>

<literallayout class='monospaced'>
<emphasis>G1L1</emphasis>, <emphasis>G1L2</emphasis>, <emphasis>G2L1</emphasis>, <emphasis>G2L2</emphasis>, <emphasis>G1L3</emphasis>, <emphasis>G2L3</emphasis>, <emphasis>G3L1</emphasis>, <emphasis>G3L2</emphasis>, <emphasis>G3L3</emphasis>, <emphasis>G4L1</emphasis>, <emphasis>G4L2</emphasis>, and <emphasis>G4L3</emphasis>
</literallayout>

<para>
For a key with a width one key type on group one, a width two key type on group
two and a width three key type on group three, the symbols bound to the key by
the core protocol are assigned to the following key positions:
</para>

<literallayout class='monospaced'>
<emphasis>G1L1</emphasis>, (<emphasis>G1L2</emphasis>), <emphasis>G2L1</emphasis>, <emphasis>G2L2</emphasis>, <emphasis>G3L1</emphasis>, <emphasis>G3L2</emphasis>, <emphasis>G3L3</emphasis>
</literallayout>

<para>
Note that the second and fourth symbols (positions <emphasis>
G1L2 and G2L2</emphasis>
) can never be generated if the key type associated with the group yields only
one symbol. XKB accepts and ignores them in order to maintain compatibility
with the core protocol.
</para>


</sect3>
</sect2>
<sect2 id='Assigning_Types_To_Groups_of_Symbols_for_a_Key'>
<title>Assigning Types To Groups of Symbols for a Key</title>

<para>
Once the symbols specified by <emphasis>
ChangeKeyboardMapping</emphasis>
 have been assigned to the four keyboard groups for a key, the X server assigns
a key type to each group on the key from a canonical list of key types. The
first four key types in any keyboard map are reserved for these standard key
types:
</para>

<informaltable frame='topbot'>
<?dbfo keep-together="always" ?>
<tgroup cols='2' align='left' colsep='0' rowsep='0'>
<colspec colname='c1' colwidth='1.0*'/>
<colspec colname='c2' colwidth='3.0*'/>
<thead>
  <row rowsep='1'>
    <entry>Key Type Name</entry>
    <entry>Standard Definition</entry>
  </row>
</thead>
<tbody>
  <row>
    <entry><emphasis>
ONE_LEVEL</emphasis>
</entry>
    <entry>Describes keys that have exactly one symbol per group. Most special
or function keys (such as <emphasis>
Return</emphasis>
) are <emphasis>
ONE_LEVEL</emphasis>
 keys. Any combination of modifiers yields level <emphasis>
0</emphasis>
. Index <emphasis>
0</emphasis>
 in any key symbol map specifies key type <emphasis>
ONE_LEVEL</emphasis>
.</entry>
  </row>
  <row>
    <entry><emphasis>
TWO_LEVEL</emphasis>
</entry>
    <entry>Describes non-keypad and non-alphabetic keys that have exactly two
symbols per group. By default, the <emphasis>
TWO_LEVEL</emphasis>
 type yields column <emphasis>
1</emphasis>
 if the Shift modifier is set, column <emphasis>
0</emphasis>
 otherwise. Index <emphasis>
1</emphasis>
 in any key symbol map specifies key type <emphasis>
TWO_LEVEL</emphasis>
.</entry>
  </row>
  <row>
    <entry><emphasis>
ALPHABETIC</emphasis>
</entry>
    <entry>Describes alphabetic keys that have exactly two symbols per group.
The default definition of the <emphasis>
ALPHABETIC</emphasis>
 type provides shift-cancels-caps behavior as described in <link linkend='Key_Types'>Key Types</link>. Index <emphasis>
2</emphasis>
 in any key symbol map specifies key type <emphasis>
ALPHABETIC</emphasis>
.</entry>
  </row>
  <row>
    <entry><emphasis>
KEYPAD</emphasis>
</entry>
    <entry>Describes numeric keypad keys with two symbols per group. Yields
column <emphasis>
1</emphasis>
 if either of the <emphasis>
Shift</emphasis>
 modifier or the real modifier bound to the virtual modifier named <emphasis>
NumLock</emphasis>
 are set. Yields column <emphasis>
0</emphasis>
 if neither or both modifiers are set. Index <emphasis>
3</emphasis>
 in any key symbol map specifies key type <emphasis>
KEYPAD</emphasis>
.</entry>
  </row>
</tbody>
</tgroup>
</informaltable>

<para>
Users or applications may change these key types to get different default
behavior (to make shift cancel caps lock, for example) but they must always
have the specified number of symbols per group.
</para>


<para>
Before assigning key types to groups, the X server expands any alphanumeric
symbol definitions as follows:
</para>


<para>
If the second symbol of either group is <emphasis>
NoSymbol</emphasis>
 and the first symbol of that group is an alphabetic keysym for which both
lowercase and uppercase forms are defined, the X server treats the key as if
the first element of the group were the lowercase form of the symbol and the
second element were the uppercase form of the symbol. For the purposes of this
expansion, XKB ignores the locale and uses the capitalization rules defined in
<link linkend="default_symbol_transformations">Default Symbol Transformations</link>.
</para>


<para>
For each keyboard group that does not have an explicit type definition, XKB
chooses a key type from the canonical key types. If the second symbol assigned
to a group is <emphasis>
NoSymbol</emphasis>
 (after alphabetic expansion), the server assigns key type <emphasis>
ONE_LEVEL</emphasis>
. If the group contains the lowercase and uppercase forms of a single glyph
(after alphanumeric expansion), the server assigns key type <emphasis>
ALPHABETIC</emphasis>
. If either of the symbols in a group is a numeric keypad keysym (<emphasis>
KP_*</emphasis>
), the server assigns key type <emphasis>
KEYPAD</emphasis>
. Otherwise, it assigns key type <emphasis>
TWO_LEVEL</emphasis>
.
</para>


<para>
Finally, XKB determines the number of groups of symbols that are actually
defined for the key. Trailing empty groups (i.e. groups that have <emphasis>
NoSymbol</emphasis>
 in all symbol positions) are ignored.
</para>


<para>
There are two last special cases for compatibility with the core protocol: If,
after trailing empty groups are excluded, all of the groups of symbols bound to
the key have identical type and symbol bindings, XKB assigns only one group to
the key. If <emphasis>
Group2</emphasis>
 is empty and either of <emphasis>
Group3</emphasis>
 or <emphasis>
Group4</emphasis>
 are not, and if neither <emphasis>
Group1</emphasis>
 nor <emphasis>
Group2</emphasis>
 have explicit key types, XKB copies the symbols and key type from <emphasis>
Group1</emphasis>
 into <emphasis>
Group2</emphasis>
.
</para>


</sect2>
<sect2 id='Assigning_Actions_To_Keys'>
<title>Assigning Actions To Keys</title>

<para>
Once symbols have been divided into groups and key types chosen for the keys
affected by a <emphasis>
ChangeKeyboardMapping</emphasis>
 request, XKB examines the symbols and modifier mapping for each changed key
and assigns server actions where appropriate. XKB also automatically assigns
server actions to changed keys if the client issues a core protocol <emphasis>
SetModifierMapping</emphasis>
 request, and does so optionally in response to <emphasis>
XkbSetMap</emphasis>
 and <emphasis>
XkbSetCompatMap</emphasis>
 requests.
</para>


<para>
The compatibility map includes a list of <emphasis>
symbol interpretations</emphasis>
, which XKB compares to each symbol associated with any changed keys in turn,
unless the <emphasis>
ExplicitInterp</emphasis>
 component is set for a key. Setting the <emphasis>
ExplicitInterp</emphasis>
 component prevents the application of symbol interpretations to that key.
</para>


<para>
If the modifiers and keysym specified in a symbol interpretation match the
modifier mapping and a symbol bound to a changed key that is not protected by
<emphasis>
ExplicitInterp</emphasis>
, the server applies the symbol interpretation to the symbol position. The
server considers all symbol interpretations which specify an explicit keysym
before considering any that do not. The server uses the first interpretation
which matches the given combination of keysym and modifier mapping; other
matching interpretations are ignored.
</para>


<para>
XKB uses four of the fields of a symbol interpretation to decide if it matches
one of the symbols bound to some changed key:
</para>

<itemizedlist>
<listitem>
  <para>The <emphasis>
symbol</emphasis>
 field is a keysym which matches if it has the value <emphasis>
NoSymbol</emphasis>
 or is identical to the symbol in question.
  </para>
</listitem>
<listitem>
  <para>The modifiers specified in the <emphasis>
mods</emphasis>
 field are compared to the modifiers affected by the key in question as
indicated by <emphasis>
match</emphasis>
.
  </para>
</listitem>
<listitem>
  <para>The <emphasis>
match</emphasis>
 field can specify any of the comparisons: <emphasis>
NoneOf</emphasis>
, <emphasis>
AnyOfOrNone</emphasis>
, <emphasis>
AnyOf</emphasis>
, <emphasis>
AllOf</emphasis>
 or <emphasis>
Exactly</emphasis>
.
  </para>
</listitem>
<listitem>
  <para>The <emphasis>
levelOneOnly</emphasis>
 setting, indicates that the interpretation in question should only use the
modifiers bound to this key by the modifier mapping if the symbol that matches
in level one of its group. Otherwise, if the symbol being considered is not in
shift level one of its group, the server behaves as if the modifier map for the
key were empty. Note that it is still possible for such an interpretation to
apply to a symbol in a shift level other than one if it matches a key without
modifiers; the <emphasis>
levelOneOnly</emphasis>
 flag only controls the way that matches are determined and that the key
modifiers are applied when an interpretation does match.
  </para>
</listitem>
</itemizedlist>

<para>
Applying a symbol interpretation can affect several aspects of the XKB
definition of the key symbol mapping to which it is applied:
</para>

<itemizedlist>
<listitem>
  <para>The <emphasis>
action</emphasis>
 specified in the symbol interpretation is bound to the symbol position; any
key event which yields that symbol will also activate the new action.
  </para>
</listitem>
<listitem>
  <para>If the matching symbol is in position G1L1, the autorepeat behavior of
the key is set from the <emphasis>
autorepeat</emphasis>
 field of the symbol interpretation. The <emphasis>
ExplicitAutoRepeat</emphasis>
 component protects the autorepeat status of a key from symbol interpretation
initiated changes.
  </para>
</listitem>
<listitem>
  <para>If the symbol interpretation specifies an associated virtual modifier,
that virtual modifier is added to the virtual modifier map for the key. The
<emphasis>
ExplicitVModMap</emphasis>
 component guards the virtual modifier map for a key from automatic changes. If
the <emphasis>
levelOneOnly</emphasis>
 flag is set for the interpretation, and the symbol in question is not in
position G1L1, the virtual modifier map is not updated.
  </para>
</listitem>
<listitem>
  <para>If the matching symbol is in position G1L1, and the <emphasis>
locking key</emphasis>
 field is set in the symbol interpretation, the behavior of the key is changed
to <emphasis>
KB_Lock</emphasis>
 (see <link linkend='Key_Behavior'>Key Behavior</link>). The
<emphasis>
ExplicitBehavior</emphasis>
 component prevents this change.
  </para>
</listitem>
</itemizedlist>

<para>
If no interpretations match a given symbol or key, the server uses: <emphasis>
SA_NoAction</emphasis>
, autorepeat enabled, non-locking key. with no virtual modifiers.
</para>


<para>
If all of the actions computed for a key are <emphasis>
SA_NoAction</emphasis>
, the server assigns an length zero list of actions to the key.
</para>


<para>
If the core protocol modifier mapping is changed, the server regenerates
actions for the affected keys. The <emphasis>
XkbSetMap</emphasis>
 and <emphasis>
XkbSetCompatMap</emphasis>
 requests can also cause actions for some or all keyboard keys to be recomputed.
</para>


</sect2>
<sect2 id='Updating_Everything_Else'>
<title>Updating Everything Else</title>

<para>
Changes to the symbols or modifier mapping can affect the bindings of virtual
modifiers. If any virtual modifiers change, XKB updates all of its data
structures to reflect the change. Applying virtual modifier changes to the
keyboard mapping night result in changes to types, the group compatibility map,
indicator maps, internal modifiers or ignore locks modifiers.
</para>


</sect2>
</sect1>
<sect1 id='Effects_of_XKB_on_Core_Protocol_Events'>
<title>Effects of XKB on Core Protocol Events</title>

<para>
After applying server actions which modify the base, latched or locked modifier
or group state of the keyboard, the X server recomputes the effective group and
state. Several components of the keyboard state are reported to XKB-aware
clients depending on context (see <link linkend='Keyboard_State'>
Keyboard State</link> for a detailed description of each of the keyboard state
components):
</para>

<itemizedlist>
<listitem>
  <para>The effective modifier state is reported in <emphasis>
XkbStateNotify</emphasis>
 events and in response to <emphasis>
XkbGetState</emphasis>
 requests.
  </para>
</listitem>
<listitem>
  <para>The symbol lookup state is reported to XKB-aware clients in the state
field of core protocol and input extension key press and release events that do
not activate passive grabs. Unless the <emphasis>
LookupStateWhenGrabbed</emphasis>
 per-client flag is set, the lookup state is only reported in these events when
no grabs are active.
  </para>
</listitem>
<listitem>
  <para>The grab state is reported to XKB-aware clients in the state field of
all core protocol events that report keyboard state, except <emphasis>
KeyPress</emphasis>
 and <emphasis>
KeyRelease</emphasis>
 events that do not activate passive grabs.
  </para>
</listitem>
<listitem>
  <para>The effective group is the sum of the base, latched and locked keyboard
groups. An out of range effective group is wrapped or truncated into range
according to the setting of the <emphasis>
groupsWrap</emphasis>
 flag for the keyboard.
  </para>
</listitem>
</itemizedlist>

<para>
The server reports compatibility states to any clients that have not issued a
successful <emphasis>
XkbUseExtension</emphasis>
 request. The server computes the compatibility symbol lookup state and the
compatibility effective grab state by applying the compatibility modifier map
to the corresponding computed XKB states.
</para>


<para>
The compatibility symbol lookup state is reported to non-XKB clients whenever
an XKB-aware client would receive the XKB lookup state. The compatibility grab
state is reported to XKB-unaware clients whenever an XKB client would receive
the XKB grab state.
</para>


<para>
If the <emphasis>
GrabsUseXKBState</emphasis>
 per-client option is not set, even XKB-aware clients receive the compatibility
grab state in events that trigger or terminate passive grabs. If this flag is
not set, XKB clients also receive the compatibility grab or lookup state
whenever any keyboard grab is active.
</para>


<para>
If the <emphasis>
LookupStateWhenGrabbed</emphasis>
 per-client option is set, clients receive either the XKB or compatibility
lookup state when the keyboard is grabbed, otherwise they receive either the
XKB or compatibility grab state. All non-XKB clients receive the compatibility
form of the appropriate state component; the form that is sent to an XKB-aware
client depends on the setting of the <emphasis>
GrabsUseXKBState</emphasis>
 option for that client.
</para>


</sect1>
<sect1 id='Effect_of_XKB_on_Core_Protocol_Requests'>
<title>Effect of XKB on Core Protocol Requests</title>

<para>
Whenever a client updates the keyboard mapping using a core protocol request,
the server saves the requested core protocol keyboard mapping and reports it to
any clients that issue <emphasis>
GetKeyboardMapping</emphasis>
 or <emphasis>
GetModifierMapping</emphasis>
 requests. Whenever a client updates the keyboard mapping using XKB requests,
the server discards the affected portion of the stored core keyboard
description and regenerates it based on the XKB description of the keyboard.
</para>


<para>
The symbols associated with the XKB keyboard description appear in the order:
</para>

<literallayout class='monospaced'>
G1L1 G1L2 G2L1 G2L2 G1L3-n G2L3-n G3L* G4L*
</literallayout>

<para>
If the type associated with <emphasis>
Group1</emphasis>
 is width one, the second symbol is <emphasis>
NoSymbol</emphasis>
; if the type associated with <emphasis>
Group2</emphasis>
 is width one, the fourth symbol is <emphasis>
NoSymbol</emphasis>
.
</para>


<para>
If a key has only one group but the keyboard has several, the symbols for
<emphasis>
Group1</emphasis>
 are repeated for each group. For example, given a keyboard with three groups
and a key with one group that contains the symbols { <emphasis>
a A</emphasis>
 }, the core protocol description would contain the six symbols: { <emphasis>
a</emphasis>
 <emphasis>
A</emphasis>
 <emphasis>
a</emphasis>
 <emphasis>
A</emphasis>
 <emphasis>
a</emphasis>
 <emphasis>
A</emphasis>
 }. As a slightly more complicated example, an XKB key which had a single width
three group with the symbols { <emphasis>
a</emphasis>
 <emphasis>
b</emphasis>
 <emphasis>
c</emphasis>
 } would show up in the generated core protocol keyboard description with the
symbols { <emphasis>
a</emphasis>
 <emphasis>
b</emphasis>
 <emphasis>
a</emphasis>
 <emphasis>
b</emphasis>
 <emphasis>
c</emphasis>
 <emphasis>
c</emphasis>
 <emphasis>
a</emphasis>
 <emphasis>
b</emphasis>
 <emphasis>
c</emphasis>
 } for a keyboard with three groups.
</para>


<para>
The generated modifier mapping for a key contains all of the modifiers affected
by all of the actions associated with the key plus all of the modifiers
associated with any virtual modifiers bound to the key by the virtual modifier
mapping. If any of the actions associated with a key affect any component of
the keyboard group, any modifiers specified in any entry of the group
compatibility map (see <link linkend='Group_Compatibility_Map'>Group
Compatibility Map</link>) are reported in the modifier mask. The <emphasis>
SA_ISOLock</emphasis>
 action can theoretically affect any modifier, but the modifier map of an
<emphasis>
SA_ISOLock</emphasis>
 key contains only the modifiers or group state that it sets by default.
</para>


<para>
The server notifies interested clients of keyboard map changes in one of two
ways. It sends <emphasis>
XkbMapNotify</emphasis>
 to clients that have explicitly selected them and core protocol <emphasis>
MappingNotify</emphasis>
 events to clients that have not. Once a client requests <emphasis>
XkbMapNotify</emphasis>
 events, the server stops sending it <emphasis>
MappingNotify</emphasis>
 events to inform it of keyboard changes.
</para>


</sect1>
<sect1 id='Sending_Events_to_Clients'>
<title>Sending Events to Clients</title>

<para>
XKB normally assumes that events sent to clients using the core protocol
<emphasis>
SendEvent</emphasis>
 request contain a core protocol state, if applicable. If the client which will
receive the event is not XKB-capable, XKB attempts to convert the core state to
an XKB state as follows: if any of the modifiers bound to <emphasis>
Group2</emphasis>
 in the group compatibility map are set in the event state, XKB clears them in
the resulting event but sets the effective group in the event state to
<emphasis>
Group2</emphasis>
.
</para>


<para>
If the <emphasis>
PCF_SendEventUsesXKBState</emphasis>
 per-client flag is set at the time of the SendEvent request, XKB instead
assumes that the event reported in the event is an XKB state. If the receiving
client is not XKB-aware, the extension converts the XKB state (which contains
the effective state in bits 13-14) to a core state by applying the group
compatibility map just as it would for actual key events.
</para>

</sect1>
</chapter>