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