ch19.xml revision e9fcaa8a
1e9fcaa8aSmrg<chapter id='replacing_a_keyboard_on_the_fly'>
2e9fcaa8aSmrg<title>Replacing a Keyboard "On the Fly"</title>
3e9fcaa8aSmrg
4e9fcaa8aSmrg<para>
5e9fcaa8aSmrgSome operating system and X server implementations allow "hot plugging" of
6e9fcaa8aSmrginput devices. When using these implementations, input devices can be unplugged
7e9fcaa8aSmrgand new ones plugged in without restarting the software that is using those
8e9fcaa8aSmrgdevices. There is no provision in the standard X server for notification of
9e9fcaa8aSmrgclient programs if input devices are unplugged and/or new ones plugged in. In
10e9fcaa8aSmrgthe case of the X keyboard, this could result in the X server having a keymap
11e9fcaa8aSmrgthat does not match the new keyboard.
12e9fcaa8aSmrg</para>
13e9fcaa8aSmrg
14e9fcaa8aSmrg
15e9fcaa8aSmrg<para>
16e9fcaa8aSmrgIf the X server implementation supports the X input device extension, a client
17e9fcaa8aSmrgprogram may also change the X keyboard programmatically. The
18e9fcaa8aSmrgXChangeKeyboardDevice input extension request allows a client to designate an
19e9fcaa8aSmrginput extension keyboard device as the X keyboard, in which case the old X
20e9fcaa8aSmrgkeyboard device becomes inaccessible except via the input device extension. In
21e9fcaa8aSmrgthis case, core protocol <emphasis>
22e9fcaa8aSmrgXMappingNotify</emphasis>
23e9fcaa8aSmrg and input extension <emphasis>
24e9fcaa8aSmrgXChangeDeviceNotify</emphasis>
25e9fcaa8aSmrg events are generated to notify all clients that a new keyboard with a new
26e9fcaa8aSmrgkeymap has been designated.
27e9fcaa8aSmrg</para>
28e9fcaa8aSmrg
29e9fcaa8aSmrg
30e9fcaa8aSmrg<para>
31e9fcaa8aSmrgWhen a client opens a connection to the X server, the server reports the
32e9fcaa8aSmrgminimum and maximum keycodes. The server keeps track of the minimum and maximum
33e9fcaa8aSmrgkeycodes last reported to each client. When delivering events to a particular
34e9fcaa8aSmrgclient, the server filters out any events that fall outside of the valid range
35e9fcaa8aSmrgfor the client.
36e9fcaa8aSmrg</para>
37e9fcaa8aSmrg
38e9fcaa8aSmrg
39e9fcaa8aSmrg<para>
40e9fcaa8aSmrgXkb provides an <emphasis>
41e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
42e9fcaa8aSmrg event that reports a change in keyboard geometry and/or the range of supported
43e9fcaa8aSmrgkeycodes. The server can generate an <emphasis>
44e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
45e9fcaa8aSmrg event when it detects a new keyboard or in response to an <emphasis>
46e9fcaa8aSmrgXkbGetKeyboardByName</emphasis>
47e9fcaa8aSmrg request that loads a new keyboard description. Selecting for <emphasis>
48e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
49e9fcaa8aSmrg events allows Xkb-aware clients to be notified whenever a keyboard change
50e9fcaa8aSmrgoccurs that may affect the keymap.
51e9fcaa8aSmrg</para>
52e9fcaa8aSmrg
53e9fcaa8aSmrg
54e9fcaa8aSmrg<para>
55e9fcaa8aSmrgWhen a client requests <emphasis>
56e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
57e9fcaa8aSmrg events, the server compares the range of keycodes for the current keyboard to
58e9fcaa8aSmrgthe range of keycodes that are valid for the client. If they are not the same,
59e9fcaa8aSmrgthe server immediately sends the client an <emphasis>
60e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
61e9fcaa8aSmrg event. Even if the "new" keyboard is not new to the server, it is new to this
62e9fcaa8aSmrgparticular client.
63e9fcaa8aSmrg</para>
64e9fcaa8aSmrg
65e9fcaa8aSmrg
66e9fcaa8aSmrg<para>
67e9fcaa8aSmrgWhen the server sends an <emphasis>
68e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
69e9fcaa8aSmrg event to a client to inform it of a new keycode range, it resets the stored
70e9fcaa8aSmrgrange of legal keycodes for the client to the keycode range reported in the
71e9fcaa8aSmrgevent; it does not reset this range for the client if it does not sent an
72e9fcaa8aSmrg<emphasis>
73e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
74e9fcaa8aSmrg event to a client. Because Xkb-unaware clients and Xkb-aware clients that do
75e9fcaa8aSmrgnot request <emphasis>
76e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
77e9fcaa8aSmrg events are never sent these events, the server’s notion of the legal keycode
78e9fcaa8aSmrgrange never changes, and these clients never receive events from keys that fall
79e9fcaa8aSmrgoutside of their notion of the legal keycode range.
80e9fcaa8aSmrg</para>
81e9fcaa8aSmrg
82e9fcaa8aSmrg
83e9fcaa8aSmrg<para>
84e9fcaa8aSmrgClients that have not selected to receive <emphasis>
85e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
86e9fcaa8aSmrg events do, however, receive the <emphasis>
87e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
88e9fcaa8aSmrg event when a keyboard change occurs. Clients that have not selected to receive
89e9fcaa8aSmrgthis event also receive numerous other events detailing the individual changes
90e9fcaa8aSmrgthat occur when a keyboard change occurs.
91e9fcaa8aSmrg</para>
92e9fcaa8aSmrg
93e9fcaa8aSmrg
94e9fcaa8aSmrg<para>
95e9fcaa8aSmrgClients wishing to track changes in <emphasis>
96e9fcaa8aSmrgmin_key_code</emphasis>
97e9fcaa8aSmrg and <emphasis>
98e9fcaa8aSmrgmax_key_code</emphasis>
99e9fcaa8aSmrg must watch for both <emphasis>
100e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
101e9fcaa8aSmrg and <emphasis>
102e9fcaa8aSmrgXkbMapNotify</emphasis>
103e9fcaa8aSmrg events, because a simple mapping change causes an <emphasis>
104e9fcaa8aSmrgXkbMapNotify</emphasis>
105e9fcaa8aSmrg event and may change the range of valid keycodes, but does not cause an
106e9fcaa8aSmrg<emphasis>
107e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
108e9fcaa8aSmrg event. If a client does not select for <emphasis>
109e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
110e9fcaa8aSmrg events, the server restricts the range of keycodes reported to the client.
111e9fcaa8aSmrg</para>
112e9fcaa8aSmrg
113e9fcaa8aSmrg
114e9fcaa8aSmrg<para>
115e9fcaa8aSmrgIn addition to filtering out-of-range key events, Xkb:
116e9fcaa8aSmrg</para>
117e9fcaa8aSmrg
118e9fcaa8aSmrg<itemizedlist>
119e9fcaa8aSmrg<listitem>
120e9fcaa8aSmrg  <para>
121e9fcaa8aSmrgAdjusts core protocol <emphasis>
122e9fcaa8aSmrgMappingNotify</emphasis>
123e9fcaa8aSmrg events to refer only to keys that match the stored legal range.
124e9fcaa8aSmrg  </para>
125e9fcaa8aSmrg</listitem>
126e9fcaa8aSmrg<listitem>
127e9fcaa8aSmrg  <para>
128e9fcaa8aSmrgReports keyboard mappings for keys that match the stored legal range to clients
129e9fcaa8aSmrgthat issue a core protocol <emphasis>
130e9fcaa8aSmrgGetKeyboardMapping</emphasis>
131e9fcaa8aSmrg request.
132e9fcaa8aSmrg  </para>
133e9fcaa8aSmrg</listitem>
134e9fcaa8aSmrg<listitem>
135e9fcaa8aSmrg  <para>
136e9fcaa8aSmrgReports modifier mappings only for keys that match the stored legal range to
137e9fcaa8aSmrgclients that issue a core protocol <emphasis>
138e9fcaa8aSmrgGetModifierMapping</emphasis>
139e9fcaa8aSmrg request.
140e9fcaa8aSmrg  </para>
141e9fcaa8aSmrg</listitem>
142e9fcaa8aSmrg<listitem>
143e9fcaa8aSmrg  <para>
144e9fcaa8aSmrgRestricts the core protocol <emphasis>
145e9fcaa8aSmrgChangeKeyboardMapping</emphasis>
146e9fcaa8aSmrg and <emphasis>
147e9fcaa8aSmrgSetModifierMapping</emphasis>
148e9fcaa8aSmrg requests to keys that fall inside the stored legal range.
149e9fcaa8aSmrg  </para>
150e9fcaa8aSmrg</listitem>
151e9fcaa8aSmrg</itemizedlist>
152e9fcaa8aSmrg
153e9fcaa8aSmrg<para>
154e9fcaa8aSmrgIn short, Xkb does everything possible to hide from Xkb-unaware clients the
155e9fcaa8aSmrgfact that the range of legal keycodes has changed, because such clients cannot
156e9fcaa8aSmrgbe expected to deal with them. Xkb events and requests are not modified in this
157e9fcaa8aSmrgmanner; all Xkb events report the full range of legal keycodes. No requested
158e9fcaa8aSmrgXkb events are discarded, and no Xkb requests have their keycode range clamped.
159e9fcaa8aSmrg</para>
160e9fcaa8aSmrg
161e9fcaa8aSmrg
162e9fcaa8aSmrg<para>
163e9fcaa8aSmrgThe structure for the <emphasis>
164e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
165e9fcaa8aSmrg event is defined as follows:
166e9fcaa8aSmrg</para>
167e9fcaa8aSmrg
168e9fcaa8aSmrg<para><programlisting>
169e9fcaa8aSmrgtypedef struct _XkbNewKeyboardNotify {
170e9fcaa8aSmrg      int            type;         /* Xkb extension base event code */
171e9fcaa8aSmrg      unsigned long  serial;       /* X server serial number for event*/
172e9fcaa8aSmrg      Bool           send_event;   /* <emphasis>True</emphasis>
173e9fcaa8aSmrg                                      =&gt; synthetically generated */
174e9fcaa8aSmrg      Display *      display;      /* server connection where event generated */
175e9fcaa8aSmrg      Time           time;         /* server time when event generated */
176e9fcaa8aSmrg      int            xkb_type;  /* <emphasis>XkbNewKeyboardNotify</emphasis> */
177e9fcaa8aSmrg      int            device;       /* device ID of new keyboard */
178e9fcaa8aSmrg      int            old_device;   /* device ID of old keyboard */
179e9fcaa8aSmrg      int            min_key_code; /* min keycode of new keyboard */
180e9fcaa8aSmrg      int            max_key_code; /* max keycode of new keyboard */
181e9fcaa8aSmrg      int            old_min_key_code; /* min keycode of old keyboard */
182e9fcaa8aSmrg      int            old_max_key_code; /* max keycode of old keyboard */
183e9fcaa8aSmrg      unsigned int            changed; /* changed aspects - see masks below */
184e9fcaa8aSmrg      char            req_major;   /* major request that caused change */
185e9fcaa8aSmrg      char            req_minor;   /* minor request that caused change */
186e9fcaa8aSmrg} <emphasis>XkbNewKeyboardNotifyEvent</emphasis>;
187e9fcaa8aSmrg</programlisting></para>
188e9fcaa8aSmrg
189e9fcaa8aSmrg<para>
190e9fcaa8aSmrgTo receive name notify events, use <emphasis>
191e9fcaa8aSmrgXkbSelectEvents</emphasis>
192e9fcaa8aSmrg (see section 4.3) with <emphasis>
193e9fcaa8aSmrgXkbNewKeyboardNotifyMask</emphasis>
194e9fcaa8aSmrg in both the <emphasis>
195e9fcaa8aSmrgbits_to_change</emphasis>
196e9fcaa8aSmrg and <emphasis>
197e9fcaa8aSmrgvalues_for_bits</emphasis>
198e9fcaa8aSmrg parameters. To receive events for only specific names, use <emphasis>
199e9fcaa8aSmrgXkbSelectEventDetails</emphasis>
200e9fcaa8aSmrg. Set the <emphasis>
201e9fcaa8aSmrgevent_type</emphasis>
202e9fcaa8aSmrg parameter to <emphasis>
203e9fcaa8aSmrgXkbNewKeyboardNotify</emphasis>
204e9fcaa8aSmrg, and set both the <emphasis>
205e9fcaa8aSmrgbits_to_change </emphasis>
206e9fcaa8aSmrgand<emphasis>
207e9fcaa8aSmrg values_for_bits</emphasis>
208e9fcaa8aSmrg detail parameter to a mask composed of a bitwise OR of masks in Table 19.1.
209e9fcaa8aSmrg</para>
210e9fcaa8aSmrg
211e9fcaa8aSmrg<table frame='none'>
212e9fcaa8aSmrg<title>XkbNewKeyboardNotifyEvent Details</title>
213e9fcaa8aSmrg<tgroup cols='3'>
214e9fcaa8aSmrg<colspec colsep='0'/>
215e9fcaa8aSmrg<colspec colsep='0'/>
216e9fcaa8aSmrg<colspec colsep='0'/>
217e9fcaa8aSmrg<thead>
218e9fcaa8aSmrg<row rowsep='1'>
219e9fcaa8aSmrg  <entry>XkbNewKeyboardNotify Event Details</entry>
220e9fcaa8aSmrg  <entry>Value</entry>
221e9fcaa8aSmrg  <entry>Circumstances</entry>
222e9fcaa8aSmrg  </row>
223e9fcaa8aSmrg</thead>
224e9fcaa8aSmrg<tbody>
225e9fcaa8aSmrg  <row rowsep='1'>
226e9fcaa8aSmrg    <entry><emphasis>XkbNKN_KeycodesMask</emphasis></entry>
227e9fcaa8aSmrg    <entry>(1L&lt;&lt;0)</entry>
228e9fcaa8aSmrg    <entry>Notification of keycode range changes wanted</entry>
229e9fcaa8aSmrg  </row>
230e9fcaa8aSmrg  <row rowsep='0'>
231e9fcaa8aSmrg    <entry><emphasis>XkbNKN_GeometryMask</emphasis></entry>
232e9fcaa8aSmrg    <entry>(1L&lt;&lt;1)</entry>
233e9fcaa8aSmrg    <entry>Notification of geometry changes wanted</entry>
234e9fcaa8aSmrg  </row>
235e9fcaa8aSmrg  <row rowsep='0'>
236e9fcaa8aSmrg    <entry>XkbNKN_DeviceIDMask</entry>
237e9fcaa8aSmrg    <entry>(1L&lt;&lt;2)</entry>
238e9fcaa8aSmrg    <entry>Notification of device ID changes wanted</entry>
239e9fcaa8aSmrg  </row>
240e9fcaa8aSmrg  <row rowsep='0'>
241e9fcaa8aSmrg    <entry><emphasis>XkbNKN_AllChangesMask</emphasis></entry>
242e9fcaa8aSmrg    <entry>(0x7)</entry>
243e9fcaa8aSmrg    <entry>Includes all of the above masks</entry>
244e9fcaa8aSmrg  </row>
245e9fcaa8aSmrg</tbody>
246e9fcaa8aSmrg</tgroup>
247e9fcaa8aSmrg</table>
248e9fcaa8aSmrg
249e9fcaa8aSmrg<para>
250e9fcaa8aSmrgThe <emphasis>
251e9fcaa8aSmrgreq_major</emphasis>
252e9fcaa8aSmrg and <emphasis>
253e9fcaa8aSmrgreq_minor</emphasis>
254e9fcaa8aSmrg fields indicate what type of keyboard change has occurred.
255e9fcaa8aSmrg</para>
256e9fcaa8aSmrg
257e9fcaa8aSmrg
258e9fcaa8aSmrg<para>
259e9fcaa8aSmrgIf <emphasis>
260e9fcaa8aSmrgreq_major</emphasis>
261e9fcaa8aSmrg and <emphasis>
262e9fcaa8aSmrgreq_minor</emphasis>
263e9fcaa8aSmrg are zero, the device change was not caused by a software request to the server
264e9fcaa8aSmrg— a spontaneous change has occurred, such as hot-plugging a new device. In
265e9fcaa8aSmrgthis case, <emphasis>
266e9fcaa8aSmrgdevice</emphasis>
267e9fcaa8aSmrg is the device identifier for the new, current X keyboard device, but no
268e9fcaa8aSmrgimplementation-independent guarantee can be made about <emphasis>
269e9fcaa8aSmrgold_device</emphasis>
270e9fcaa8aSmrg. <emphasis>
271e9fcaa8aSmrgold_device</emphasis>
272e9fcaa8aSmrg may be identical to <emphasis>
273e9fcaa8aSmrgdevice</emphasis>
274e9fcaa8aSmrg (an implementor is permitted to reuse the device specifier when the device
275e9fcaa8aSmrgchanges); or it may be different. Note that <emphasis>
276e9fcaa8aSmrgreq_major</emphasis>
277e9fcaa8aSmrg and <emphasis>
278e9fcaa8aSmrgreq_minor</emphasis>
279e9fcaa8aSmrg being zero do not necessarily mean that the physical keyboard device has
280e9fcaa8aSmrgchanged; rather, they only imply a spontaneous change outside of software
281e9fcaa8aSmrgcontrol (some systems have keyboards that can change personality at the press
282e9fcaa8aSmrgof a key).
283e9fcaa8aSmrg</para>
284e9fcaa8aSmrg
285e9fcaa8aSmrg
286e9fcaa8aSmrg<para>
287e9fcaa8aSmrgIf the keyboard change is the result of an X Input Extension <emphasis>
288e9fcaa8aSmrgChangeKeyboardDevice</emphasis>
289e9fcaa8aSmrg request, <emphasis>
290e9fcaa8aSmrgreq_major</emphasis>
291e9fcaa8aSmrg contains the input extension major opcode, and <emphasis>
292e9fcaa8aSmrgreq_minor</emphasis>
293e9fcaa8aSmrg contains the input extension request number for <emphasis>
294e9fcaa8aSmrgX_ChangeKeyboardDevice</emphasis>
295e9fcaa8aSmrg. In this case, <emphasis>
296e9fcaa8aSmrgdevice</emphasis>
297e9fcaa8aSmrg and <emphasis>
298e9fcaa8aSmrgold_device</emphasis>
299e9fcaa8aSmrg are different, with <emphasis>
300e9fcaa8aSmrgdevice</emphasis>
301e9fcaa8aSmrg being the identifier for the new, current X keyboard device, and <emphasis>
302e9fcaa8aSmrgold_device</emphasis>
303e9fcaa8aSmrg being the identifier for the former device.
304e9fcaa8aSmrg</para>
305e9fcaa8aSmrg
306e9fcaa8aSmrg
307e9fcaa8aSmrg<para>
308e9fcaa8aSmrgIf the keyboard change is the result of an <emphasis>
309e9fcaa8aSmrgXkbGetKeyboardByName</emphasis>
310e9fcaa8aSmrg function call, which generates an <emphasis>
311e9fcaa8aSmrgX_kbGetKbdByName</emphasis>
312e9fcaa8aSmrg request, <emphasis>
313e9fcaa8aSmrgreq_major</emphasis>
314e9fcaa8aSmrg contains the Xkb extension base event code (see section 2.4), and <emphasis>
315e9fcaa8aSmrgreq_minor</emphasis>
316e9fcaa8aSmrg contains the event code for the Xkb extension request <emphasis>
317e9fcaa8aSmrgX_kbGetKbdByName</emphasis>
318e9fcaa8aSmrg. <emphasis>
319e9fcaa8aSmrgdevice</emphasis>
320e9fcaa8aSmrg contains the device identifier for the new device, but nothing definitive can
321e9fcaa8aSmrgbe said for <emphasis>
322e9fcaa8aSmrgold_device</emphasis>
323e9fcaa8aSmrg; it may be identical to <emphasis>
324e9fcaa8aSmrgdevice</emphasis>
325e9fcaa8aSmrg, or it may be different, depending on the implementation.
326e9fcaa8aSmrg</para>
327e9fcaa8aSmrg
328e9fcaa8aSmrg</chapter>
329