summaryrefslogtreecommitdiff
path: root/specs/kbproto/ch03.xml
blob: d71f353783cabb8c03d13aaec1c8944282d0dc16 (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
<chapter id='Virtual_Modifiers'>
<title>Virtual Modifiers</title>
<para>
The core protocol specifies that
certain keysyms, when bound to modifiers, affect the rules of keycode to keysym
interpretation for all keys; for example, when <emphasis>
Num_Lock</emphasis>
 is bound to some modifier, that modifier is used to choose shifted or
unshifted state for the numeric keypad keys. The core protocol does not provide
a convenient way to determine the mapping of modifier bits, in particular
<emphasis>
Mod1</emphasis>
 through <emphasis>
Mod5</emphasis>
, to keysyms such as <emphasis>
Num_Lock</emphasis>
 and <emphasis>
Mode_switch</emphasis>
. Clients must retrieve and search the modifier map to determine the keycodes
bound to each modifier, and then retrieve and search the keyboard mapping to
determine the keysyms bound to the keycodes. They must repeat this process for
all modifiers whenever any part of the modifier mapping is changed.
</para>

<para>
XKB provides a set of sixteen named virtual modifiers, each of which can be
bound to any set of the eight "real" modifiers (<emphasis>
Shift</emphasis>
, <emphasis>
Lock</emphasis>
, <emphasis>
Control</emphasis>
 and <emphasis>
Mod1</emphasis>
-<emphasis>
Mod5</emphasis>
 as reported in the keyboard state). This makes it easier for applications and
keyboard layout designers to specify to the function a modifier key or data
structure should fulfill without having to worry about which modifier is bound
to a particular keysym.
</para>


<para>
The use of a single, server-driven mechanism for reporting changes to all data
structures makes it easier for clients to stay synchronized. For example, the
core protocol specifies a special interpretation for the modifier bound to the
<emphasis>
Num_Lock</emphasis>
 key. Whenever any keys or modifiers are rebound, every application has to
check the keyboard mapping to make sure that the binding for <emphasis>
Num_Lock</emphasis>
 has not changed. If <emphasis>
Num_Lock</emphasis>
 is remapped when XKB is in use, the keyboard description is automatically
updated to reflect the new binding, and clients are notified immediately and
explicitly if there is a change they need to consider.
</para>


<para>
The separation of function from physical modifier bindings also makes it easier
to specify more clearly the intent of a binding. X servers do not all assign
modifiers the same way — for example, <emphasis>
Num_Lock</emphasis>
 might be bound to <emphasis>
Mod2</emphasis>
 for one vendor and to <emphasis>
Mod4</emphasis>
 for another. This makes it cumbersome to automatically remap the keyboard to a
desired configuration without some kind of prior knowledge about the keyboard
layout and bindings. With XKB, applications simply use virtual modifiers to
specify the behavior they want, without regard for the actual physical bindings
in effect.
</para>


<para>
XKB puts most aspects of the keyboard under user or program control, so it is
even more important to clearly and uniformly refer to modifiers by function.
</para>

<sect1 id='Modifier_Definitions'>
<title>Modifier Definitions</title>
<para>
Use an <emphasis>
XKB modifier definition</emphasis>
 to specify the modifiers affected by any XKB control or data structure. An XKB
modifier definition consists of a set of real modifiers, a set of virtual
modifiers, and an effective mask. The mask is derived from the real and virtual
modifiers and cannot be explicitly changed — it contains all of the real
modifiers specified in the definition <emphasis>
plus</emphasis>
 any real modifiers that are bound to the virtual modifiers specified in the
definition. For example, this modifier definition specifies the numeric lock
modifier if the <emphasis>
Num_Lock</emphasis>
 keysym is not bound to any real modifier:
</para>
<literallayout class='monospaced'>
{ real_mods= None, virtual_mods= NumLock, mask= None }
</literallayout>

<para>
If we assign <emphasis>
Mod2</emphasis>
 to the <emphasis>
Num_Lock</emphasis>
 key, the definition changes to:
</para>

<literallayout class='monospaced'>
{ real_mods= None, virtual_mods= NumLock, mask= Mod2 }
</literallayout>

<para>
Using this kind of modifier definition makes it easy to specify the desired
behavior in such a way that XKB can automatically update all of the data
structures that make up a keymap to reflect user or application specified
changes in any one aspect of the keymap.
</para>


<para>
The use of modifier definitions also makes it possible to unambiguously specify
the reason that a modifier is of interest. On a system for which the <emphasis>
Alt</emphasis>
 and <emphasis>
Meta</emphasis>
 keysyms are bound to the same modifier, the following definitions behave
identically:
</para>

<literallayout class='monospaced'>
{ real_mods= None, virtual_mods= Alt, mask= Mod1 }
{ real_mods= None, virtual_mods= Meta, mask= Mod1 }
</literallayout>

<para>
If we rebind one of the modifiers, the modifier definitions automatically
reflect the change:
</para>

<literallayout class='monospaced'>
{ real_mods= None, virtual_mods= Alt, mask= Mod1 }
{ real_mods= None, virtual_mods= Meta, mask= Mod4 }
</literallayout>

<para>
Without the level of indirection provided by virtual modifier maps and modifier
definitions, we would have no way to tell which of the two definitions is
concerned with <emphasis>
Alt</emphasis>
 and which is concerned with <emphasis>
Meta</emphasis>.
</para>


<sect2 id='Inactive_Modifier_Definitions'>
<title>Inactive Modifier Definitions</title>
<para>
Some XKB structures ignore modifier
definitions in which the virtual modifiers are unbound. Consider this
example:
</para>
<literallayout class='monospaced'>
if ( state matches { Shift } ) Do OneThing;
if ( state matches { Shift+NumLock } ) Do Another;
</literallayout>

<para>
If the <emphasis>
NumLock</emphasis>
 virtual modifier is not bound to any real modifiers, these effective masks for
these two cases are identical (i.e. they contain only <emphasis>
Shift</emphasis>
). When it is essential to distinguish between <emphasis>
OneThing</emphasis>
 and Another, XKB considers only those modifier definitions for which all
virtual modifiers are bound.
</para>
</sect2>
</sect1>

<sect1 id='Virtual_Modifier_Mapping'>
<title>Virtual Modifier Mapping</title>
<para>
XKB maintains a <emphasis>
virtual modifier mapping</emphasis>
, which lists the virtual modifiers associated with each key. The real
modifiers bound to a virtual modifier always include all of the modifiers bound
to any of the keys that specify that virtual modifier in their virtual modifier
mapping.
</para>

<para>
For example, if <emphasis>
Mod3</emphasis>
 is bound to the <emphasis>
Num_Lock</emphasis>
 key by the core protocol modifier mapping, and the <emphasis>
NumLock</emphasis>
 virtual modifier is bound to they <emphasis>
Num_Lock</emphasis>
 key by the virtual modifier mapping, <emphasis>
Mod3</emphasis>
 is added to the set of modifiers associated with the <emphasis>
NumLock</emphasis>
 virtual modifier.
</para>


<para>
The virtual modifier mapping is normally updated automatically whenever actions
are assigned to keys (see <link linkend='Changing_the_Keyboard_Mapping_Using_the_Core_Protocol'>Changing
the Keyboard Mapping Using the Core Protocol</link> for details) and few
applications should need to change the virtual modifier mapping explicitly.
</para>
</sect1>
</chapter>