ch05.xml revision eb411b4b
1<chapter id='Keyboard_State'>
2<title>Keyboard State</title>
3
4<para>
5Keyboard state encompasses all of the transitory information necessary to map a physical key press or release to an appropriate event. The Xkb keyboard state consists of primitive components and additional derived components that are maintained for efficiency reasons. Figure 5.1 shows the components of Xkb keyboard state and their relationships.
6</para>
7
8<mediaobject>
9<!-- <title>Keyboard State Description</title> -->
10 <imageobject> <imagedata format="SVG" fileref="XKBlib-2.svg"/>
11 </imageobject>
12<caption>Xkb State</caption>
13</mediaobject>
14
15
16<sect1 id='Keyboard_State_Description'>
17<title>Keyboard State Description</title>
18<para>
19The Xkb keyboard state is comprised of the state of all keyboard modifiers, the keyboard group, and the state of the pointer buttons. These are grouped into the following components:
20</para>
21
22<itemizedlist>
23<listitem>
24  <para>
25The locked group and locked modifiers
26  </para>
27</listitem>
28<listitem>
29  <para>
30The latched group and latched modifiers
31  </para>
32</listitem>
33<listitem>
34  <para>
35The base group and base modifiers
36  </para>
37</listitem>
38<listitem>
39  <para>
40The effective group and effective modifiers
41  </para>
42</listitem>
43<listitem>
44  <para>
45The state of the core pointer buttons
46  </para>
47</listitem>
48</itemizedlist>
49
50<para>
51The <emphasis>
52modifiers</emphasis>
53 are <emphasis>
54Shift</emphasis>
55, <emphasis>
56Lock</emphasis>
57, <emphasis>
58Control</emphasis>
59, and <emphasis>
60Mod1</emphasis>
61-<emphasis>
62Mod5</emphasis>
63, as defined by the core protocol. A modifier can be thought of as a toggle that is either set or unset. All modifiers are initially unset. When a modifier is locked, it is set and remains set for all future key events, until it is explicitly unset. A latched modifier is set, but automatically unsets after the next key event that does not change the keyboard state. Locked and latched modifier state can be changed by keyboard activity or via Xkb extension library functions.
64</para>
65
66
67<para>
68The Xkb extension provides support for <emphasis>
69keysym</emphasis>
70 <emphasis>
71groups</emphasis>
72, as defined by ISO9995:
73</para>
74
75
76<variablelist>
77  <varlistentry>
78    <term>Group</term>
79    <listitem>
80      <para>
81A logical state of a keyboard providing access to a collection of characters.
82A group usually contains a set of characters that logically belong together
83and that may be arranged on several shift levels within that group.
84      </para>
85    </listitem>
86  </varlistentry>
87</variablelist>
88
89
90
91<para>
92The Xkb extension supports up to four keysym groups. Groups are named beginning with one and indexed beginning with zero. All group states are indicated using the group index. At any point in time, there is zero or one locked group, zero or one latched group, and one base group. When a group is locked, it supersedes any previous locked group and remains the locked group for all future key events, until a new group is locked. A latched group applies only to the next key event that does not change the keyboard state. The locked and latched group can be changed by keyboard activity or via Xkb extension library functions.
93</para>
94
95
96<para>
97Changing to a different group changes the keyboard state to produce characters from a different group. Groups are typically used to switch between keysyms of different languages and locales.
98</para>
99
100
101<para>
102The <emphasis>
103pointer buttons</emphasis>
104 are <emphasis>
105Button1</emphasis>
106 - <emphasis>
107Button5</emphasis>
108, as defined by the core protocol.
109</para>
110
111
112<para>
113The <emphasis>
114base group</emphasis>
115 and <emphasis>
116base modifiers</emphasis>
117 represent keys that are physically or logically down. These
118and the pointer buttons can be changed by keyboard activity and
119not by Xkb requests. It is possible for a key to be logically
120down, but not physically down, and neither latched nor locked.
121<footnote><para>
122Keys may be logically down when they are physically up because
123of their electrical properties or because of the keyboard extension
124in the X server having filtered the key release, for esoteric reasons.
125</para></footnote>
126
127</para>
128
129
130<para>
131The <emphasis>
132effective modifiers</emphasis>
133 are the bitwise union of the locked, latched, and the base modifiers.
134</para>
135
136
137<para>
138The <emphasis>
139effective group</emphasis>
140 is the arithmetic sum of the group indices of the latched group, locked group, and base group, which is then normalized by some function. The result is a meaningful group index.
141</para>
142
143<simplelist type='vert' columns='1'>
144<member>
145n = number of keyboard groups, 1&lt;= n &lt;= 4
146</member>
147
148<member>
1490 &lt;= any of locked, latched, or base group &lt; n
150</member>
151
152<member>
153effective group = f(locked group + latched group + base group)
154</member>
155</simplelist>
156
157<para>
158The function f ensures that the effective group is within range. The precise function is specified for the keyboard and can be retrieved through the keyboard description. It may wrap around, clamp down, or default. Few applications will actually examine the effective group, and far fewer still will examine the locked, latched, and base groups.
159</para>
160
161
162<para>
163There are two circumstances under which groups are normalized:
164</para>
165
166<orderedlist>
167  <listitem><para>
168The global locked or effective group changes. In this case, the changed group is normalized into range according to the settings of the <emphasis>
169groups_wrap</emphasis>
170 field of the <emphasis>
171XkbControlsRec</emphasis>
172 structure for the keyboard (see section 10.7.1). <!-- xref -->
173  </para></listitem>
174  <listitem><para>
175
176The Xkb library is interpreting an event with an effective group that is legal for the keyboard as a whole, but not for the key in question. In this case, the group to use for this event only is determined using the <emphasis>
177group_info</emphasis>
178 field of the key symbol mapping (<emphasis>
179XkbSymMapRec</emphasis>
180) for the event key.
181  </para></listitem>
182</orderedlist>
183
184<para>
185Each nonmodifier key on a keyboard has zero or more symbols, or keysyms, associated with it. These are the logical symbols that the key can generate when it is pressed. The set of all possible keysyms for a keyboard is divided into groups. Each key is associated with zero or more groups; each group contains one or more symbols. When a key is pressed, the determination of which symbol for the key is selected is based on the effective group and the shift level, which is determined by which modifiers are set.
186</para>
187
188
189<para>
190A client that does not explicitly call Xkb functions, but that otherwise makes use of an X library containing the Xkb extension, will have keyboard state represented in bits 0 - 14 of the state field of events that report modifier and button state. Such a client is said to be <emphasis>
191Xkb-capable</emphasis>
192. A client that does explicitly call Xkb functions is an <emphasis>
193Xkb-aware</emphasis>
194 client. The Xkb keyboard state includes information derived from the effective state and from two server parameters that can be set through the keyboard extension. The following components of keyboard state pertain to Xkb-capable and Xkb-aware clients:
195</para>
196
197<itemizedlist>
198<listitem>
199  <para>
200lookup state: lookup group and lookup modifiers
201  </para>
202</listitem>
203<listitem>
204  <para>
205grab state: grab group and grab modifiers
206  </para>
207</listitem>
208</itemizedlist>
209
210<para>
211The <emphasis>
212lookup modifiers</emphasis>
213 and <emphasis>
214lookup group</emphasis>
215 are represented in the state field of core X events. The modifier state and keycode of a key event are used to determine the symbols associated with the event. For <emphasis>
216KeyPress</emphasis>
217 and <emphasis>
218KeyRelease</emphasis>
219 events, the lookup modifiers are computed as:
220</para>
221
222<literallayout>
223   ((base | latched | locked) &amp; ~<emphasis> server_internal_modifiers</emphasis>)
224</literallayout>
225
226<para>
227Otherwise the lookup modifiers are computed as:
228</para>
229
230<literallayout>
231(((base | latched | (locked &amp; ~<emphasis> ignore_locks</emphasis>)) &amp; ~<emphasis> server_internal_modifiers</emphasis>)
232</literallayout>
233
234<para>
235The lookup group is the same as the effective group.
236</para>
237
238
239<para>
240When an Xkb-capable or Xkb-aware client wishes to map a keycode to a keysym, it should use the <emphasis>
241lookup state</emphasis>
242 — the lookup group and the lookup modifiers.
243</para>
244
245
246<para>
247The <emphasis>
248grab state</emphasis>
249 is the state used when matching events to passive grabs. If the event activates a grab, the <emphasis>
250grab modifiers</emphasis>
251 and <emphasis>
252grab group</emphasis>
253 are represented in the state field of core X events; otherwise, the lookup state is used. The grab modifiers are computed as:
254</para>
255
256<literallayout>
257(((base | latched | (locked &amp; ~ignore_locks)) &amp; ~server_internal_modifiers)
258</literallayout>
259
260<para>
261If the server’s <emphasis>
262IgnoreGroupLock</emphasis>
263 control (see section 10.7.3) is not set, the grab group is the same as the effective group. Otherwise, the grab group is computed from the base group and latched group, ignoring the locked group.
264</para>
265
266
267<para>
268The final three components of Xkb state are applicable to clients that are not linked with an Xlib containing the X keyboard extension library and therefore are not aware of the keyboard extension (<emphasis>
269Xkb-unaware </emphasis>
270clients):
271</para>
272
273<itemizedlist>
274<listitem>
275  <para>
276The compatibility modifier state
277  </para>
278</listitem>
279<listitem>
280  <para>
281The compatibility lookup modifier state
282  </para>
283</listitem>
284<listitem>
285  <para>
286The compatibility grab modifier state
287  </para>
288</listitem>
289</itemizedlist>
290
291<para>
292The X11 protocol interpretation of modifiers does not include direct support for multiple groups. When an Xkb-extended X server connects to an Xkb-unaware client, the compatibility states remap the keyboard group into a core modifier whenever possible. The compatibility state corresponds to the effective modifier and effective group state, with the group remapped to a modifier. The compatibility lookup and grab states correspond to the lookup and grab states, respectively, with the group remapped to a modifier. The compatibility lookup state is reported in events that do not trigger passive grabs; otherwise, the compatibility grab state is reported.
293</para>
294
295
296</sect1>
297<sect1 id='Changing_the_Keyboard_State'>
298<title>Changing the Keyboard State</title>
299
300<sect2 id='Changing_Modifiers'>
301<title>Changing Modifiers</title>
302
303<para>
304The functions in this section that change the use of modifiers use a mask in the parameter <emphasis>
305affect</emphasis>
306. It is a bitwise inclusive OR of the legal modifier masks:
307</para>
308
309<table frame='none'>
310<title>Real Modifier Masks</title>
311<?dbfo keep-together="always" ?>
312<tgroup cols='1' align='left' colsep='0' rowsep='0'>
313<colspec colname='c1' colwidth='1.0*'/>
314<tbody>
315  <row>
316    <entry>Mask</entry>
317  </row>
318  <row>
319    <entry>ShiftMask</entry>
320  </row>
321  <row>
322    <entry>LockMask</entry>
323  </row>
324  <row>
325    <entry>ControlMask</entry>
326  </row>
327  <row>
328    <entry>Mod1Mask</entry>
329  </row>
330  <row>
331    <entry>Mod2Mask</entry>
332  </row>
333  <row>
334    <entry>Mod3Mask</entry>
335  </row>
336  <row>
337    <entry>Mod4Mask</entry>
338  </row>
339  <row>
340    <entry>Mod5Mask</entry>
341  </row>
342</tbody>
343</tgroup>
344</table>
345
346<para>
347To lock and unlock any of the eight real keyboard modifiers, use <emphasis>
348XkbLockModifiers:</emphasis>
349</para>
350
351<informaltable frame='none'>
352<?dbfo keep-together="always" ?>
353<tgroup cols='1' align='left' colsep='0' rowsep='0'>
354<colspec colname='c1' colwidth='1.0*'/>
355<tbody>
356  <row>
357    <entry role='functiondecl'>
358Bool <emphasis> XkbLockModifiers</emphasis>
359(<emphasis>
360display, device_spec, affect, values</emphasis>
361)
362    </entry>
363  </row>
364  <row>
365    <entry role='functionargdecl'>
366Display *      <emphasis>
367display</emphasis>
368;            /* connection to the X server */
369    </entry>
370  </row>
371  <row>
372    <entry role='functionargdecl'>
373unsigned int      <emphasis>
374device_spec</emphasis>
375;            /* device ID, or <emphasis>
376XkbUseCoreKbd</emphasis>
377 */
378    </entry>
379  </row>
380  <row>
381    <entry role='functionargdecl'>
382unsigned int<emphasis>
383      affect</emphasis>
384;            /* mask of real modifiers whose lock state is to change */
385    </entry>
386  </row>
387  <row>
388    <entry role='functionargdecl'>
389unsigned int      <emphasis>
390values</emphasis>
391;            /* 1 =&gt; lock, 0 =&gt; unlock; only for modifiers selected by <emphasis>
392affect</emphasis>
393 */
394    </entry>
395</row>
396</tbody>
397</tgroup>
398</informaltable>
399
400<para>
401<emphasis>
402XkbLockModifiers</emphasis>
403 sends a request to the server to lock the real modifiers selected by both <emphasis>
404affect</emphasis>
405 and <emphasis>
406values</emphasis>
407 and to unlock the real modifiers selected by <emphasis>
408affect</emphasis>
409 but not selected by <emphasis>
410values</emphasis>
411. <emphasis>
412XkbLockModifiers</emphasis>
413 does not wait for a reply from the server. It returns <emphasis>
414True</emphasis>
415 if the request was sent, and <emphasis>
416False</emphasis>
417 otherwise.
418</para>
419
420
421<para>
422To latch and unlatch any of the eight real keyboard modifiers, use <emphasis>
423XkbLatchModifiers:</emphasis>
424</para>
425
426
427<informaltable frame='none'>
428<?dbfo keep-together="always" ?>
429<tgroup cols='1' align='left' colsep='0' rowsep='0'>
430<colspec colname='c1' colwidth='1.0*'/>
431<tbody>
432  <row>
433    <entry role='functiondecl'>
434Bool <emphasis>
435XkbLatchModifiers</emphasis>
436(d<emphasis>
437isplay, device_spec, affect, values</emphasis>
438)
439    </entry>
440  </row>
441  <row>
442    <entry role='functionargdecl'>
443Display *      <emphasis>
444display</emphasis>
445;            /* connection to the X server */
446    </entry>
447  </row>
448  <row>
449    <entry role='functionargdecl'>
450unsigned int      <emphasis>
451device_spec</emphasis>
452;            /* device ID, or <emphasis>
453XkbUseCoreKbd</emphasis>
454 */
455    </entry>
456  </row>
457  <row>
458    <entry role='functionargdecl'>
459unsigned int<emphasis>
460      affect</emphasis>
461;            /* mask of modifiers whose latch state is to change */
462    </entry>
463  </row>
464  <row>
465    <entry role='functionargdecl'>
466unsigned int <emphasis>values</emphasis>;
467/* 1 =&gt; latch, 0 =&gt; unlatch; only for mods selected by <emphasis>
468affect</emphasis>
469 */
470    </entry>
471</row>
472</tbody>
473</tgroup>
474</informaltable>
475
476<para>
477<emphasis>
478XkbLatchModifiers</emphasis>
479 sends a request to the server to latch the real modifiers selected by both <emphasis>
480affect</emphasis>
481 and <emphasis>
482values</emphasis>
483 and to unlatch the real modifiers selected by <emphasis>
484affect</emphasis>
485 but not selected by <emphasis>
486values</emphasis>
487. <emphasis>
488XkbLatchModifiers</emphasis>
489 does not wait for a reply from the server. It returns <emphasis>
490True</emphasis>
491 if the request was sent, and <emphasis>
492False</emphasis>
493 otherwise.
494</para>
495
496
497</sect2>
498<sect2 id='Changing_Groups'>
499<title>Changing Groups</title>
500
501<para>
502Reference the keysym group indices with these symbolic constants:
503</para>
504
505<table frame='topbot'>
506<title>Symbolic Group Names</title>
507<?dbfo keep-together="always" ?>
508<tgroup cols='2' align='left' colsep='0' rowsep='0'>
509<colspec colname='c1' colwidth='1.0*'/>
510<colspec colname='c2' colwidth='2.0*'/>
511<tbody>
512  <row rowsep='1'>
513    <entry>Symbolic Name</entry>
514    <entry>Value</entry>
515  </row>
516  <row>
517    <entry>XkbGroup1Index</entry>
518    <entry>0</entry>
519  </row>
520  <row>
521    <entry>XkbGroup2Index</entry>
522    <entry>1</entry>
523  </row>
524  <row>
525    <entry>XkbGroup3Index</entry>
526    <entry>2</entry>
527  </row>
528  <row>
529    <entry>XkbGroup4Index</entry>
530    <entry>3</entry>
531  </row>
532</tbody>
533</tgroup>
534</table>
535
536<para>
537To lock the keysym group, use <emphasis>
538XkbLockGroup. </emphasis>
539</para>
540
541<informaltable frame='none'>
542<?dbfo keep-together="always" ?>
543<tgroup cols='1' align='left' colsep='0' rowsep='0'>
544<colspec colname='c1' colwidth='1.0*'/>
545<tbody>
546  <row>
547    <entry role='functiondecl'>
548Bool <emphasis>
549XkbLockGroup</emphasis>
550(<emphasis>
551display, device_spec, group</emphasis>
552)
553    </entry>
554  </row>
555  <row>
556    <entry role='functionargdecl'>
557Display *      <emphasis>
558display</emphasis>
559;            /* connection to the X server */
560    </entry>
561  </row>
562  <row>
563    <entry role='functionargdecl'>
564unsigned int      <emphasis>
565device_spec</emphasis>
566;            /* device ID, or <emphasis>
567XkbUseCoreKbd</emphasis>
568 */
569    </entry>
570  </row>
571  <row>
572    <entry role='functionargdecl'>
573unsigned int      <emphasis>
574group</emphasis>
575;            /* index of the keysym group to lock */
576    </entry>
577</row>
578</tbody>
579</tgroup>
580</informaltable>
581
582<para>
583<emphasis>
584XkbLockGroup</emphasis>
585 sends a request to the server to lock the specified <emphasis>
586group </emphasis>
587and does not wait for a reply. It returns <emphasis>
588True</emphasis>
589 if the request was sent and <emphasis>
590False</emphasis>
591 otherwise.
592</para>
593
594
595<para>
596To latch the keysym group, use <emphasis>
597XkbLatchGroup.</emphasis>
598</para>
599
600
601<informaltable frame='none'>
602<?dbfo keep-together="always" ?>
603<tgroup cols='1' align='left' colsep='0' rowsep='0'>
604<colspec colname='c1' colwidth='1.0*'/>
605<tbody>
606  <row>
607    <entry role='functiondecl'>
608Bool <emphasis>
609XkbLatchGroup</emphasis>
610(<emphasis>
611display, device_spec, group</emphasis>
612)
613    </entry>
614  </row>
615  <row>
616    <entry role='functionargdecl'>
617Display *      <emphasis>
618display</emphasis>
619;            /* connection to the X server */
620    </entry>
621  </row>
622  <row>
623    <entry role='functionargdecl'>
624unsigned int<emphasis>
625      device_spec</emphasis>
626;            /* device ID, or <emphasis>
627XkbUseCoreKbd</emphasis>
628 */
629    </entry>
630  </row>
631  <row>
632    <entry role='functionargdecl'>
633unsigned int<emphasis>
634      group</emphasis>
635;            /* index of the keysym group to latch */
636    </entry>
637</row>
638</tbody>
639</tgroup>
640</informaltable>
641
642<para>
643<emphasis>
644XkbLatchGroup</emphasis>
645 sends a request to the server to latch the specified group and does not wait for a reply. It returns <emphasis>
646True</emphasis>
647 if the request was sent and <emphasis>
648False</emphasis>
649 otherwise.
650</para>
651
652
653</sect2>
654</sect1>
655<sect1 id='Determining_Keyboard_State'>
656<title>Determining Keyboard State</title>
657
658<para>
659Xkb keyboard state may be represented in an <emphasis>
660XkbStateRec</emphasis>
661 structure:
662</para>
663
664<para><programlisting>
665typedef struct {
666      unsigned char            group;                /* effective group index */
667      unsigned char            base_group;           /* base group index */
668      unsigned char            latched_group;        /* latched group index */
669      unsigned char            locked_group;         /* locked group index */
670      unsigned char            mods;                 /* effective modifiers */
671      unsigned char            base_mods;            /* base modifiers */
672      unsigned char            latched_mods;         /* latched modifiers */
673      unsigned char            locked_mods;          /* locked modifiers */
674      unsigned char            compat_state;         /* effective group =&gt; modifiers */
675      unsigned char            grab_mods;            /* modifiers used for grabs */
676      unsigned char            compat_grab_mods;     /* mods used for compatibility mode grabs */
677      unsigned char            lookup_mods;          /* modifiers used to lookup symbols */
678      unsigned char            compat_lookup_mods;   /* mods used for compatibility lookup */
679      unsigned short            ptr_buttons;         /* 1 bit =&gt; corresponding pointer btn is down */
680} <emphasis>
681XkbStateRec</emphasis>
682,*XkbStatePtr;
683</programlisting></para>
684
685<para>
686To obtain the keyboard state, use <emphasis>
687XkbGetState.</emphasis>
688</para>
689
690<informaltable frame='none'>
691<?dbfo keep-together="always" ?>
692<tgroup cols='1' align='left' colsep='0' rowsep='0'>
693<colspec colname='c1' colwidth='1.0*'/>
694<tbody>
695  <row>
696    <entry role='functiondecl'>
697Status <emphasis>
698XkbGetState</emphasis>
699(<emphasis>
700display</emphasis>
701, <emphasis>
702device_spec</emphasis>
703, <emphasis>
704state_return</emphasis>
705)
706    </entry>
707  </row>
708  <row>
709    <entry role='functionargdecl'>
710Display *            <emphasis>
711display</emphasis>
712;            /* connection to the X server */
713    </entry>
714  </row>
715  <row>
716    <entry role='functionargdecl'>
717unsigned int            <emphasis>
718device_spec</emphasis>
719;            /* device ID, or <emphasis>
720XkbUseCoreKbd</emphasis>
721 */
722    </entry>
723  </row>
724  <row>
725    <entry role='functionargdecl'>
726XkbStatePtr            <emphasis>
727state_return</emphasis>
728;            /* backfilled with Xkb state */
729    </entry>
730</row>
731</tbody>
732</tgroup>
733</informaltable>
734
735<para>
736The <emphasis>
737XkbGetState </emphasis>
738function queries the server for the current keyboard state, waits for a reply, and then backfills <emphasis>
739state_return</emphasis>
740 with the results.
741</para>
742
743
744<para>
745All group values are expressed as group indices in the range [0..3]. Modifiers and the compatibility modifier state values are expressed as the bitwise union of the core X11 modifier masks. The pointer button state is reported as in the core X11 protocol.
746</para>
747
748
749</sect1>
750<sect1 id='Tracking_Keyboard_State'>
751<title>Tracking Keyboard State</title>
752
753<para>
754The Xkb extension reports <emphasis>
755XkbStateNotify </emphasis>
756events to clients wanting notification whenever the Xkb state changes. The changes reported include changes to any aspect of the keyboard state: when a modifier is set or unset, when the current group changes, or when a pointer button is pressed or released. As with all Xkb events, <emphasis>
757XkbStateNotify</emphasis>
758 events are reported to all interested clients without regard to the current keyboard input focus or grab state.
759</para>
760
761
762<para>
763There are many different types of Xkb state changes. Xkb defines an event detail mask corresponding to each type of change. The event detail masks are listed in Table 5.3.
764</para>
765
766<table frame='topbot'>
767<title>XkbStateNotify Event Detail Masks</title>
768<?dbfo keep-together="always" ?>
769<tgroup cols='2' align='left' colsep='0' rowsep='0'>
770<colspec colname='c1' colwidth='1.0*'/>
771<colspec colname='c2' colwidth='1.0*'/>
772<thead>
773  <row rowsep='1'>
774    <entry>Mask</entry>
775    <entry>Value</entry>
776  </row>
777</thead>
778<tbody>
779  <row>
780    <entry>XkbModifierStateMask</entry>
781    <entry>(1L &lt;&lt; 0)</entry>
782  </row>
783  <row>
784    <entry>XkbModifierBaseMask</entry>
785    <entry>(1L &lt;&lt; 1)</entry>
786  </row>
787  <row>
788    <entry>XkbModifierLatchMask</entry>
789    <entry>(1L &lt;&lt; 2)</entry>
790  </row>
791  <row>
792    <entry>XkbModifierLockMask</entry>
793    <entry>(1L &lt;&lt; 3)</entry>
794  </row>
795  <row>
796    <entry>XkbGroupStateMask</entry>
797    <entry>(1L &lt;&lt; 4)</entry>
798  </row>
799  <row>
800    <entry>XkbGroupBaseMask</entry>
801    <entry>(1L &lt;&lt; 5)</entry>
802  </row>
803  <row>
804    <entry>XkbGroupLatchMask</entry>
805    <entry>(1L &lt;&lt; 6)</entry>
806  </row>
807  <row>
808    <entry>XkbGroupLockMask</entry>
809    <entry>(1L &lt;&lt; 7)</entry>
810  </row>
811  <row>
812    <entry>XkbCompatStateMask</entry>
813    <entry>(1L &lt;&lt; 8)</entry>
814  </row>
815  <row>
816    <entry>XkbGrabModsMask</entry>
817    <entry>(1L &lt;&lt; 9)</entry>
818  </row>
819  <row>
820    <entry>XkbCompatGrabModsMask</entry>
821    <entry>(1L &lt;&lt; 10)</entry>
822  </row>
823  <row>
824    <entry>XkbLookupModsMask</entry>
825    <entry>(1L &lt;&lt; 11)</entry>
826  </row>
827  <row>
828    <entry>XkbCompatLookupModsMask</entry>
829    <entry>(1L &lt;&lt; 12)</entry>
830  </row>
831  <row>
832    <entry>XkbPointerButtonMask</entry>
833    <entry>(1L &lt;&lt; 13)</entry>
834  </row>
835  <row>
836    <entry>XkbAllStateComponentsMask</entry>
837    <entry>(0x3fff)</entry>
838  </row>
839</tbody>
840</tgroup>
841</table>
842
843<para>
844To track changes in the keyboard state for a particular device, select to receive <emphasis>
845XkbStateNotify</emphasis>
846 events by calling either <emphasis>
847XkbSelectEvents</emphasis>
848 or <emphasis>
849XkbSelectEventDetails</emphasis>
850 (see section 4.3). <!-- xref -->
851</para>
852
853
854<para>
855To receive <emphasis>
856XkbStateNotify</emphasis>
857 events under all possible conditions, use <emphasis>
858XkbSelectEvents</emphasis>
859 and pass <emphasis>
860XkbStateNotifyMask</emphasis>
861 in both <emphasis>
862bits_to_change</emphasis>
863 and <emphasis>
864values_for_bits</emphasis>
865.
866</para>
867
868
869<para>
870To receive <emphasis>
871XkbStateNotify</emphasis>
872 events only under certain conditions, use <emphasis>
873XkbSelectEventDetails</emphasis>
874 using <emphasis>
875XkbStateNotify</emphasis>
876 as the <emphasis>
877event_type</emphasis>
878 and specifying the desired state changes in <emphasis>
879bits_to_change</emphasis>
880 and <emphasis>
881values_for_bits</emphasis>
882 using mask bits from Table 5.3. <!-- xref -->
883</para>
884
885
886<para>
887The structure for <emphasis>
888XkbStateNotify</emphasis>
889 events is:
890</para>
891
892<para><programlisting>
893typedef struct {
894      int            type;            /* Xkb extension base event code */
895      unsigned long  serial;          /* X server serial number for event */
896      Bool           send_event;      /* <emphasis> True</emphasis> =&gt; synthetically generated */
897      Display *      display;         /* server connection where event generated */
898      Time           time;            /* server time when event generated */
899      int            xkb_type;        /* <emphasis> XkbStateNotify</emphasis> */
900      int            device;          /* Xkb device ID, will not be <emphasis> XkbUseCoreKbd</emphasis> */
901      unsigned int   changed;         /* bits indicating what has changed */
902      int            group;           /* group index of effective group */
903      int            base_group;      /* group index of base group */
904      int            latched_group;   /* group index of latched group */
905      int            locked_group;    /* group index of locked group */
906      unsigned int   mods;            /* effective modifiers */
907      unsigned int   base_mods;       /* base modifiers */
908      unsigned int   latched_mods;    /* latched modifiers */
909      unsigned int   locked_mods;     /* locked modifiers */
910      int            compat_state;    /* computed compatibility state */
911      unsigned char  grab_mods;       /* modifiers used for grabs */
912      unsigned char  compat_grab_mods;  /* modifiers used for compatibility grabs */
913      unsigned char  lookup_mods;     /* modifiers used to lookup symbols */
914      unsigned char  compat_lookup_mods;                  /* mods used for compatibility look up */
915      int            ptr_buttons;     /* core pointer buttons */
916      KeyCode        keycode;         /* keycode causing event, 0 if programmatic */
917      char           event_type;      /* core event if <emphasis> req_major</emphasis> or
918                                         <emphasis> req_minor</emphasis> non zero */
919      char           req_major;       /* major request code if program trigger, else 0 */
920      char           req_minor;       /* minor request code if program trigger, else 0 */
921} <emphasis>XkbStateNotifyEvent</emphasis>
922;
923</programlisting></para>
924
925<para>
926When you receive an <emphasis>
927XkbStateNotify</emphasis>
928 event, the <emphasis>
929changed</emphasis>
930 field indicates which elements of keyboard state have changed.
931This will be the bitwise inclusive OR of one or more of the <emphasis>
932XkbStateNotify</emphasis>
933 event detail masks shown in Table 5.3. All fields reported in  <!-- xref -->
934the event are valid, but only those indicated in <emphasis>
935changed</emphasis>
936 have changed values.
937</para>
938
939
940<para>
941The <emphasis>
942group</emphasis>
943 field is the group index of the effective keysym group. The <emphasis>
944base_group</emphasis>
945, <emphasis>
946latched_group</emphasis>
947, and <emphasis>
948locked_group</emphasis>
949 fields are set to a group index value representing the base group,
950the latched group, and the locked group, respectively. The X
951server can set the modifier and compatibility state fields to
952a union of the core modifier mask bits; this union represents the
953corresponding modifier states. The <emphasis>ptr_button</emphasis>
954 field gives the state of the core pointer buttons as a
955mask composed of an inclusive OR of zero or more of the
956core pointer button masks.
957</para>
958
959
960<para>
961Xkb state changes can occur either in response to keyboard
962activity or under application control. If a key event
963caused the state change, the <emphasis>
964keycode</emphasis>
965 field gives the keycode of the key event, and the <emphasis>
966event_type</emphasis>
967 field is set to either <emphasis>KeyPress</emphasis>
968 or <emphasis>
969KeyRelease</emphasis>
970. If a pointer button event caused the state change, the <emphasis>
971keycode</emphasis>
972 field is zero, and the <emphasis>event_type</emphasis>
973 field is set to either <emphasis>ButtonPress</emphasis>
974 or <emphasis>ButtonRelease</emphasis>
975. Otherwise, the major and minor codes of the request that caused the
976state change are given in the <emphasis>
977req_major</emphasis>
978 and <emphasis>
979req_minor</emphasis>
980 fields, and the <emphasis>
981keycode</emphasis>
982 field is zero. The <emphasis>
983req_major</emphasis>
984 value is the same as the major extension opcode.
985</para>
986</sect1>
987</chapter>
988