aboutsummaryrefslogtreecommitdiff
path: root/libX11/specs/XKB/ch10.xml
diff options
context:
space:
mode:
Diffstat (limited to 'libX11/specs/XKB/ch10.xml')
-rw-r--r--libX11/specs/XKB/ch10.xml5347
1 files changed, 5347 insertions, 0 deletions
diff --git a/libX11/specs/XKB/ch10.xml b/libX11/specs/XKB/ch10.xml
new file mode 100644
index 000000000..76acd032f
--- /dev/null
+++ b/libX11/specs/XKB/ch10.xml
@@ -0,0 +1,5347 @@
+<chapter id='keyboard_controls'>
+<title>Keyboard Controls</title>
+
+<para>
+The Xkb extension is composed of two parts: a server extension, and a
+client-side X library extension. This chapter discusses functions used to
+modify controls effecting the behavior of the server portion of the Xkb
+extension. Chapter 11 discusses functions used to modify controls that affect
+only the behavior of the client portion of the extension; those controls are
+known as Library Controls.
+</para>
+
+
+<para>
+Xkb contains control features that affect the entire keyboard, known as global
+keyboard controls. Some of the controls may be selectively enabled and
+disabled; these controls are known as the <emphasis>
+Boolean Controls</emphasis>
+. Boolean Controls can be turned on or off under program control and can also
+be automatically set to an on or off condition when a client program exits. The
+remaining controls, known as the <emphasis>
+Non-Boolean Controls</emphasis>
+, are always active. The<emphasis>
+ XkbControlsRec</emphasis>
+ structure describes the current state of most of the global controls and the
+attributes effecting the behavior of each of these Xkb features. This chapter
+describes the Xkb controls and how to manipulate them.
+</para>
+
+
+<para>
+There are two possible components for each of the Boolean Controls: attributes
+describing how the control should work, and a state describing whether the
+behavior as a whole is enabled or disabled. The attributes and state for most
+of these controls are held in the <emphasis>
+XkbControlsRec</emphasis>
+ structure (see section 10.8).
+</para>
+
+
+<para>
+You can manipulate the Xkb controls individually, via convenience functions, or
+as a whole. To treat them as a group, modify an <emphasis>
+XkbControlsRec</emphasis>
+ structure to describe all of the changes to be made, and then pass that
+structure and appropriate flags to an Xkb library function, or use a <emphasis>
+XkbControlsChangesRec</emphasis>
+ (see section 10.10.1) to reduce network traffic. When using a convenience
+function to manipulate one control individually, you do not use an <emphasis>
+XkbControlsRec</emphasis>
+ structure directly.
+</para>
+
+
+<para>
+The Xkb controls are grouped as shown in Table 10.1. <!-- xref -->
+</para>
+
+<table frame='none'>
+<title>Xkb Keyboard Controls</title>
+<tgroup cols='3'>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>Type of Control</entry>
+ <entry>Control Name</entry>
+ <entry>Boolean Control?</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='0'>
+ <entry>Controls for enabling and disabling other controls</entry>
+ <entry>EnabledControls</entry>
+ <entry>No</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>AutoReset</entry>
+ <entry>No</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>Control for bell behavior</entry>
+ <entry>AudibleBell</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>Controls for repeat key behavior</entry>
+ <entry>PerKeyRepeat</entry>
+ <entry>No</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>RepeatKeys</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>DetectableAutorepeat</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>Controls for keyboard overlays</entry>
+ <entry>Overlay1</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>Overlay2</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>Controls for using the mouse from the keyboard</entry>
+ <entry>MouseKeys</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>MouseKeysAccel</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>Controls for better keyboard access by </entry>
+ <entry>AccessXFeedback</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>physically impaired persons</entry>
+ <entry>AccessXKeys</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>AccessXTimeout</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>BounceKeys</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>SlowKeys</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>StickyKeys</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>Controls for general keyboard mapping</entry>
+ <entry>GroupsWrap</entry>
+ <entry>No</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>IgnoreGroupLock</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>IgnoreLockMods</entry>
+ <entry>No</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>InternalMods</entry>
+ <entry>No</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>Miscellaneous per-client controls</entry>
+ <entry>GrabsUseXKBState</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>LookupStateWhenGrabbed</entry>
+ <entry>Boolean</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>SendEventUsesXKBState</entry>
+ <entry>Boolean</entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+The individual categories and controls are described first, together with
+functions for manipulating them. A description of the <emphasis>
+XkbControlsRec</emphasis>
+ structure and the general functions for dealing with all of the controls at
+once follow at the end of the chapter.
+</para>
+
+<sect1 id='controls_that_enable_and_disable_other_controls'>
+<title>Controls that Enable and Disable Other Controls</title>
+
+<para>
+Enable and disable the boolean controls under program control by using the
+<emphasis>
+EnabledControls</emphasis>
+ control; enable and disable them upon program exit by configuring the
+<emphasis>
+AutoReset</emphasis>
+ control.
+</para>
+
+
+<sect2 id='the_enabledcontrols_control'>
+<title>The EnabledControls Control</title>
+
+<para>
+The <emphasis>
+EnabledControls</emphasis>
+ control is a bit mask where each bit that is turned on means the corresponding
+control is enabled, and when turned off, disabled. It corresponds to the
+<emphasis>
+enabled_ctrls</emphasis>
+ field of an <emphasis>
+XkbControlsRec</emphasis>
+ structure (see section 10.8). The bits describing which controls are turned on
+or off are defined in Table 10.7. <!-- xref -->
+</para>
+
+
+<para>
+Use <emphasis>
+XkbChangeEnabledControls</emphasis>
+ to manipulate the <emphasis>
+EnabledControls</emphasis>
+ control.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbChangeEnabledControls</emphasis>
+(<emphasis>
+dpy</emphasis>
+, <emphasis>
+device_spec</emphasis>
+, <emphasis>
+mask</emphasis>
+,<emphasis>
+ values</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ dpy</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+device_spec</emphasis>
+; /* keyboard device to modify */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+mask</emphasis>
+; /* 1 bit -&gt; controls to enable / disable */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+values</emphasis>
+; /* 1 bit =&gt; enable, 0 bit =&gt; disable */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+The <emphasis>
+mask</emphasis>
+ parameter specifies the boolean controls to be enabled or disabled, and the
+<emphasis>
+values</emphasis>
+ mask specifies the new state for those controls. Valid values for both of
+these masks are composed of a bitwise inclusive OR of bits taken from the set
+of mask bits in Table 10.7, using only those masks with "ok" in the <emphasis>
+enabled_ctrls</emphasis>
+ column.
+</para>
+
+
+<para>
+If the X server does not support a compatible version of Xkb or the Xkb
+extension has not been properly initialized, <emphasis>
+XkbChangeEnabledControls</emphasis>
+ returns <emphasis>
+False</emphasis>
+; otherwise, it sends the request to the X server and returns <emphasis>
+True</emphasis>
+.
+</para>
+
+
+<para>
+Note that the <emphasis>
+EnabledControls</emphasis>
+ control only enables and disables controls; it does not configure them. Some
+controls, such as the <emphasis>
+AudibleBell</emphasis>
+ control, have no configuration attributes and are therefore manipulated solely
+by enabling and disabling them. Others, however, have additional attributes to
+configure their behavior. For example, the <emphasis>
+RepeatControl</emphasis>
+ control uses <emphasis>
+repeat_delay</emphasis>
+ and <emphasis>
+repeat_interval</emphasis>
+ fields to describe the timing behavior of keys that repeat. The <emphasis>
+RepeatControl</emphasis>
+ behavior is turned on or off depending on the value of the <emphasis>
+XkbRepeatKeysMask</emphasis>
+ bit, but you must use other means, as described in this chapter, to configure
+its behavior in detail.
+</para>
+
+
+</sect2>
+<sect2 id='the_autoreset_control'>
+<title>The AutoReset Control</title>
+
+<para>
+You can configure the boolean controls to automatically be enabled or disabled
+when a program exits. This capability is controlled via two masks maintained in
+the X server on a per-client basis. There is no client-side Xkb data structure
+corresponding to these masks. Whenever the client exits for any reason, any
+boolean controls specified in the <emphasis>
+auto-reset mask</emphasis>
+ are set to the corresponding value from the <emphasis>
+auto-reset values</emphasis>
+ mask. This makes it possible for clients to "clean up after themselves"
+automatically, even if abnormally terminated. The bits used in the masks
+correspond to the <emphasis>
+EnabledControls</emphasis>
+ control bits.
+</para>
+
+
+<para>
+For example, a client that replaces the keyboard bell with some other audible
+cue might want to turn off the <emphasis>
+AudibleBell</emphasis>
+ control to prevent the server from also generating a sound and avoid
+cacophony. If the client were to exit without resetting the <emphasis>
+AudibleBell </emphasis>
+control, the user would be left without any feedback at all. Setting <emphasis>
+AudibleBell</emphasis>
+ in both the auto-reset mask and auto-reset values guarantees that the audible
+bell will be turned back on when the client exits.
+</para>
+
+
+<para>
+To get the current values of the auto-reset controls, use <emphasis>
+XkbGetAutoResetControls</emphasis>
+.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbGetAutoResetControls</emphasis>
+(<emphasis>
+dpy</emphasis>
+, <emphasis>
+auto_ctrls</emphasis>
+, <emphasis>
+auto_values</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+dpy</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int * <emphasis>
+auto_ctrls</emphasis>
+; /* specifies which bits in <emphasis>
+auto_values</emphasis>
+ are relevant */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int * <emphasis>
+auto_values</emphasis>
+; /* 1 bit =&gt; corresponding control has auto-reset on */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbGetAutoResetControls</emphasis>
+ backfills <emphasis>
+auto_ctrls</emphasis>
+ and <emphasis>
+auto_values</emphasis>
+ with the <emphasis>
+AutoReset</emphasis>
+ control attributes for this particular client. It returns <emphasis>
+True</emphasis>
+ if successful, and <emphasis>
+False</emphasis>
+ otherwise.
+</para>
+
+
+<para>
+To change the current values of the <emphasis>
+AutoReset</emphasis>
+ control attributes, use <emphasis>
+XkbSetAutoResetControls.</emphasis>
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbSetAutoResetControls</emphasis>
+(<emphasis>
+dpy</emphasis>
+, <emphasis>
+changes</emphasis>
+,<emphasis>
+ auto_ctrls</emphasis>
+, <emphasis>
+auto_values</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+dpy</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+changes</emphasis>
+; /* controls for which to change auto-reset values */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int * <emphasis>
+auto_ctrls</emphasis>
+; /* controls from changes that should auto reset */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int * <emphasis>
+auto_values</emphasis>
+; /* 1 bit =&gt; auto-reset on */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbSetAutoResetControls changes the auto-reset status and associated auto-reset
+values for the controls selected by </emphasis>
+<emphasis>
+changes</emphasis>
+<emphasis>
+. For any control selected by </emphasis>
+<emphasis>
+changes</emphasis>
+<emphasis>
+, if the corresponding bit is set in </emphasis>
+<emphasis>
+auto_ctrls</emphasis>
+<emphasis>
+, the control is configured to auto-reset when the client exits. If the
+corresponding bit in </emphasis>
+<emphasis>
+auto_values</emphasis>
+<emphasis>
+ is on, the control is turned on when the client exits; if zero, the control is
+turned off when the client exits.</emphasis>
+ For any control selected by <emphasis>
+changes</emphasis>
+, if the corresponding bit is not set in <emphasis>
+auto_ctrls</emphasis>
+, the control is configured to not reset when the client exits. For example:
+</para>
+
+
+<para>
+<emphasis>
+To leave the auto-reset controls for </emphasis>
+<emphasis>
+StickyKeys</emphasis>
+<emphasis>
+ the way they are:</emphasis>
+</para>
+
+<para><programlisting>
+ok = XkbSetAutoResetControls(dpy, 0, 0, 0);
+</programlisting></para>
+
+<para>
+<emphasis>
+To change the auto-reset controls so that </emphasis>
+<emphasis>
+StickyKeys</emphasis>
+<emphasis>
+ are unaffected when the client exits:</emphasis>
+</para>
+
+<para><programlisting>
+ok = XkbSetAutoResetControls(dpy, XkbStickyKeysMask, 0, 0);
+</programlisting></para>
+
+<para>
+<emphasis>
+To change the auto-reset controls so that </emphasis>
+<emphasis>
+StickyKeys</emphasis>
+<emphasis>
+ are turned off when the client exits:</emphasis>
+</para>
+
+<para><programlisting>
+ok = XkbSetAutoResetControls(dpy, XkbStickyKeysMask, XkbStickyKeysMask, 0);
+</programlisting></para>
+
+<para>
+<emphasis>
+To change the auto-reset controls so that </emphasis>
+<emphasis>
+StickyKeys</emphasis>
+<emphasis>
+ are turned on when the client exits:</emphasis>
+</para>
+
+<para><programlisting>
+ok = XkbSetAutoResetControls(dpy, XkbStickyKeysMask, XkbStickyKeysMask,
+XkbStickyKeysMask);
+</programlisting></para>
+
+<para>
+<emphasis>
+XkbSetAutoResetControls</emphasis>
+ backfills <emphasis>
+auto_ctrls</emphasis>
+ and <emphasis>
+auto_values</emphasis>
+ with the auto-reset controls for this particular client. Note that all of the
+bits are valid in the returned values, not just the ones selected in the
+<emphasis>
+changes</emphasis>
+ mask.
+</para>
+
+
+</sect2>
+</sect1>
+<sect1 id='control_for_bell_behavior'>
+<title>Control for Bell Behavior</title>
+
+<para>
+The X server’s generation of sounds is controlled by the <emphasis>
+AudibleBell</emphasis>
+ control. Configuration of different bell sounds is discussed in Chapter 9.
+</para>
+
+
+<sect2 id='the_audiblebell_control'>
+<title>The AudibleBell Control</title>
+
+<para>
+The <emphasis>
+AudibleBell</emphasis>
+ control is a boolean control that has no attributes. As such, you may enable
+and disable it using either the <emphasis>
+EnabledControls</emphasis>
+ control or the <emphasis>
+AutoReset</emphasis>
+ control discussed in section 10.1.1. When enabled, protocol requests to <!-- xref -->
+generate a sound result in the X server actually producing a real sound; when
+disabled, requests to the server to generate a sound are ignored unless the
+sound is forced. See section 9.2. <!-- xref -->
+</para>
+
+
+</sect2>
+</sect1>
+<sect1 id='controls_for_repeat_key_behavior'>
+<title>Controls for Repeat Key Behavior</title>
+
+<para>
+The repeating behavior of keyboard keys is governed by three controls, the
+<emphasis>
+PerKeyRepeat</emphasis>
+ control, which is always active, and the <emphasis>
+RepeatKeys</emphasis>
+ and <emphasis>
+DetectableAutorepeat</emphasis>
+ controls, which are boolean controls that may be enabled and disabled.
+<emphasis>
+PerKeyRepeat</emphasis>
+ determines which keys are allowed to repeat. <emphasis>
+RepeatKeys</emphasis>
+ governs the behavior of an individual key when it is repeating. <emphasis>
+DetectableAutorepeat</emphasis>
+ allows a client to detect when a key is repeating as a result of being held
+down.
+</para>
+
+
+<sect2 id='the_perkeyrepeat_control'>
+<title>The PerKeyRepeat Control</title>
+
+<para>
+The <emphasis>
+PerKeyRepeat</emphasis>
+ control is a bitmask long enough to contain a bit for each key on the device;
+it determines which individual keys are allowed to repeat. The Xkb <emphasis>
+PerKeyRepeat</emphasis>
+ control provides no functionality different from that available via the core X
+protocol. There are no convenience functions in Xkb for manipulating this
+control. The <emphasis>
+PerKeyRepeat</emphasis>
+ control settings are carried in the <emphasis>
+per_key_repeat</emphasis>
+ field of an <emphasis>
+XkbControlsRec</emphasis>
+ structure, discussed in section 10.8. <!-- xref -->
+</para>
+
+
+</sect2>
+<sect2 id='the_repeatkeys_control'>
+<title>The RepeatKeys Control</title>
+
+<para>
+The core protocol allows only control over whether or not the entire keyboard
+or individual keys should auto-repeat when held down. <emphasis>
+RepeatKeys</emphasis>
+ is a boolean control that extends this capability by adding control over the
+delay until a key begins to repeat and the rate at which it repeats. <emphasis>
+RepeatKeys</emphasis>
+ is coupled with the core auto-repeat control: when <emphasis>
+RepeatKeys</emphasis>
+ is enabled or disabled, the core auto-repeat is enabled or disabled and vice
+versa.
+</para>
+
+
+<para>
+Auto-repeating keys are controlled by two attributes. The first, <emphasis>
+timeout</emphasis>
+, is the delay after the initial press of an auto-repeating key and the first
+generated repeat event. The second, <emphasis>
+interval</emphasis>
+, is the delay between all subsequent generated repeat events. As with all
+boolean controls, configuring the attributes that determine how the control
+operates does not automatically enable the control as a whole; see section 10.1.
+</para>
+
+
+<para>
+To get the current attributes of the <emphasis>
+RepeatKeys</emphasis>
+ control for a keyboard device, use <emphasis>
+XkbGetAutoRepeatRate</emphasis>
+.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbGetAutoRepeatRate</emphasis>
+(<emphasis>
+display, device_spec, timeout_rtrn, interval_rtrn</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ display</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+ device_spec</emphasis>
+; /* desired device ID, or <emphasis>
+XkbUseCoreKbd</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+* timeout_rtrn</emphasis>
+; /* backfilled with initial repeat delay, ms */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+* interval_rtrn</emphasis>
+; /* backfilled with subsequent repeat delay, ms */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbGetAutoRepeatRate</emphasis>
+ queries the server for the current values of the <emphasis>
+RepeatControls</emphasis>
+ control attributes, backfills <emphasis>
+timeout_rtrn</emphasis>
+ and <emphasis>
+interval_rtrn</emphasis>
+ with them, and returns <emphasis>
+True</emphasis>
+. If a compatible version of the Xkb extension is not available in the server
+<emphasis>
+XkbGetAutoRepeatRate</emphasis>
+ returns <emphasis>
+False</emphasis>
+.
+</para>
+
+
+<para>
+To set the attributes of the RepeatKeys control for a keyboard device, use
+<emphasis>
+XkbSetAutoRepeatRate</emphasis>
+.
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbSetAutoRepeatRate</emphasis>
+(<emphasis>
+display, device_spec, timeout, interval</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ display</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+device_spec</emphasis>
+; /* device to configure, or <emphasis>
+XkbUseCoreKbd</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ timeout</emphasis>
+; /* initial delay, ms */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+ interval</emphasis>
+; /* delay between repeats, ms */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbSetAutoRepeatRate</emphasis>
+ sends a request to the X server to configure the <emphasis>
+AutoRepeat</emphasis>
+ control attributes to the values specified in <emphasis>
+timeout</emphasis>
+ and <emphasis>
+interval</emphasis>
+.
+</para>
+
+
+<para>
+<emphasis>
+XkbSetAutoRepeatRate</emphasis>
+ does not wait for a reply; it normally returns <emphasis>
+True</emphasis>
+. Specifying a zero value for either <emphasis>
+timeout</emphasis>
+ or <emphasis>
+interval</emphasis>
+ causes the server to generate a <emphasis>
+BadValue</emphasis>
+ protocol error. If a compatible version of the Xkb extension is not available
+in the server, <emphasis>
+XkbSetAutoRepeatRate</emphasis>
+ returns <emphasis>
+False</emphasis>
+.
+</para>
+
+
+</sect2>
+<sect2 id='the_detectableautorepeat_control'>
+<title>The DetectableAutorepeat Control</title>
+
+<para>
+Auto-repeat is the generation of multiple key events by a keyboard when the
+user presses a key and holds it down. Keyboard hardware and device-dependent X
+server software often implement auto-repeat by generating multiple <emphasis>
+KeyPress</emphasis>
+ events with no intervening <emphasis>
+KeyRelease</emphasis>
+ event. The standard behavior of the X server is to generate a <emphasis>
+KeyRelease</emphasis>
+ event for every <emphasis>
+KeyPress</emphasis>
+ event. If the keyboard hardware and device-dependent software of the X server
+implement auto-repeat by generating multiple <emphasis>
+KeyPress</emphasis>
+ events, the device-independent part of the X server by default synthetically
+generates a <emphasis>
+KeyRelease</emphasis>
+ event after each <emphasis>
+KeyPress</emphasis>
+ event. This provides predictable behavior for X clients, but does not allow
+those clients to detect the fact that a key is auto-repeating.
+</para>
+
+
+<para>
+Xkb allows clients to request <emphasis>
+detectable auto-repeat</emphasis>
+. If a client requests and the server supports <emphasis>
+DetectableAutorepeat</emphasis>
+, Xkb generates <emphasis>
+KeyRelease</emphasis>
+ events only when the key is physically released. If <emphasis>
+DetectableAutorepeat</emphasis>
+ is not supported or has not been requested, the server synthesizes a <emphasis>
+KeyRelease</emphasis>
+ event for each repeating <emphasis>
+KeyPress</emphasis>
+ event it generates.
+</para>
+
+
+<para>
+<emphasis>
+DetectableAutorepeat</emphasis>
+, unlike the other controls in this chapter, is not contained in the <emphasis>
+XkbControlsRec</emphasis>
+ structure, nor can it be enabled or disabled via the <emphasis>
+EnabledControls</emphasis>
+ control. Instead, query and set <emphasis>
+DetectableAutorepeat</emphasis>
+ using <emphasis>
+XkbGetDetectableAutorepeat</emphasis>
+ and <emphasis>
+XkbSetDetectableAutorepeat</emphasis>
+.
+</para>
+
+
+<para>
+<emphasis>
+DetectableAutorepeat</emphasis>
+ is a condition that applies to all keyboard devices for a client’s
+connection to a given X server; it cannot be selectively set for some devices
+and not for others. For this reason, none of the Xkb library functions
+involving <emphasis>
+DetectableAutorepeat</emphasis>
+ involve a device specifier.
+</para>
+
+
+<para>
+To determine whether or not the server supports <emphasis>
+DetectableAutorepeat</emphasis>
+, use <emphasis>
+XkbGetDetectableAutorepeat</emphasis>
+.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbGetDetectableAutorepeat</emphasis>
+(<emphasis>
+display, supported_rtrn</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ display</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Bool *<emphasis>
+ supported_rtrn</emphasis>
+; /* backfilled <emphasis>
+True</emphasis>
+ if <emphasis>
+DetectableAutorepeat</emphasis>
+ supported */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbGetDetectableAutorepeat</emphasis>
+ queries the server for the current state of <emphasis>
+DetectableAutorepeat</emphasis>
+ and waits for a reply. If <emphasis>
+supported_rtrn</emphasis>
+ is not <emphasis>
+NULL</emphasis>
+, it backfills supported_rtrn with <emphasis>
+True</emphasis>
+ if the server supports <emphasis>
+DetectableAutorepeat</emphasis>
+, and <emphasis>
+False</emphasis>
+ otherwise. <emphasis>
+XkbGetDetectableAutorepeat</emphasis>
+ returns the current state of <emphasis>
+DetectableAutorepeat</emphasis>
+ for the requesting client: <emphasis>
+True</emphasis>
+ if <emphasis>
+DetectableAutorepeat</emphasis>
+ is set, and <emphasis>
+False</emphasis>
+ otherwise.
+</para>
+
+
+<para>
+To set <emphasis>
+DetectableAutorepeat</emphasis>
+, use <emphasis>
+XkbSetDetectableAutorepeat</emphasis>
+. This request affects all keyboard activity for the requesting client only;
+other clients still see the expected nondetectable auto-repeat behavior, unless
+they have requested otherwise.
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbSetDetectableAutorepeat</emphasis>
+(<emphasis>
+display, detectable, supported_rtrn</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ display</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Bool<emphasis>
+ detectable</emphasis>
+; /* <emphasis>
+True</emphasis>
+ =&gt; set <emphasis>
+DetectableAutorepeat</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Bool *<emphasis>
+ supported_rtrn</emphasis>
+; /* backfilled <emphasis>
+True</emphasis>
+ if <emphasis>
+DetectableAutorepeat</emphasis>
+ supported */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbSetDetectableAutorepeat</emphasis>
+ sends a request to the server to set <emphasis>
+DetectableAutorepeat</emphasis>
+ on for the current client if <emphasis>
+detectable</emphasis>
+ is <emphasis>
+True</emphasis>
+, and off it <emphasis>
+detectable</emphasis>
+ is <emphasis>
+False</emphasis>
+; it then waits for a reply. If <emphasis>
+supported_rtrn</emphasis>
+ is not <emphasis>
+NULL</emphasis>
+, <emphasis>
+XkbSetDetectableAutorepeat</emphasis>
+ backfills <emphasis>
+supported_rtrn</emphasis>
+ with <emphasis>
+True</emphasis>
+ if the server supports <emphasis>
+DetectableAutorepeat</emphasis>
+, and <emphasis>
+False</emphasis>
+ if it does not. <emphasis>
+XkbSetDetectableAutorepeat</emphasis>
+ returns the current state of <emphasis>
+DetectableAutorepeat</emphasis>
+ for the requesting client: <emphasis>
+True</emphasis>
+ if <emphasis>
+DetectableAutorepeat</emphasis>
+ is set, and <emphasis>
+False</emphasis>
+ otherwise.
+</para>
+
+
+</sect2>
+</sect1>
+<sect1 id='controls_for_keyboard_overlays_overlay1_and_overlay2_controls'>
+<title>Controls for Keyboard Overlays (Overlay1 and Overlay2 Controls)</title>
+
+<para>
+A keyboard overlay allows some subset of the keyboard to report alternate
+keycodes when the overlay is enabled. For example, a keyboard overlay can be
+used to simulate a numeric or editing keypad on a keyboard that does not
+actually have one by reusing some portion of the keyboard as an overlay. This
+technique is very common on portable computers and embedded systems with small
+keyboards.
+</para>
+
+
+<para>
+Xkb includes direct support for two keyboard overlays, using the <emphasis>
+Overlay1</emphasis>
+ and <emphasis>
+Overlay2</emphasis>
+ controls. When <emphasis>
+Overlay1</emphasis>
+ is enabled, all of the keys that are members of the first keyboard overlay
+generate an alternate keycode. When <emphasis>
+Overlay2</emphasis>
+ is enabled, all of the keys that are members of the second keyboard overlay
+generate an alternate keycode. The two overlays are mutually exclusive; any
+particular key may be in at most one overlay. <emphasis>
+Overlay1</emphasis>
+ and <emphasis>
+Overlay2</emphasis>
+ are boolean controls. As such, you may enable and disable them using either
+the <emphasis>
+EnabledControls</emphasis>
+ control or the <emphasis>
+AutoReset</emphasis>
+ control discussed in section 10.1.1. <!-- xref -->
+</para>
+
+
+<para>
+To specify the overlay to which a key belongs and the alternate keycode it
+should generate when that overlay is enabled, assign it either the <emphasis>
+XkbKB_Overlay1</emphasis>
+ or <emphasis>
+XkbKB_Overlay2</emphasis>
+ key behaviors, as described in section 16.2. <!-- xref -->
+</para>
+
+
+</sect1>
+<sect1 id='controls_for_using_the_mouse_from_the_keyboard'>
+<title>Controls for Using the Mouse from the Keyboard</title>
+
+<para>
+Using Xkb, it is possible to configure the keyboard to allow simulation of the
+X pointer device. This simulation includes both movement of the pointer itself
+and press and release events associated with the buttons on the pointer. Two
+controls affect this behavior: the <emphasis>
+MouseKeys</emphasis>
+ control determines whether or not simulation of the pointer device is active,
+as well as configuring the default button; the <emphasis>
+MouseKeysAccel</emphasis>
+ control determines the movement characteristics of the pointer when simulated
+via the keyboard. Both of them are boolean controls; as such, you may enable
+and disable them using either the <emphasis>
+EnabledControls</emphasis>
+ control or the <emphasis>
+AutoReset</emphasis>
+ control discussed in section 10.1.1. The individual keys that simulate <!-- xref -->
+different aspects of the pointer device are determined by the keyboard mapping,
+discussed in Chapter 16. <!-- xref -->
+</para>
+
+
+<sect2 id='the_mousekeys_control'>
+<title>The MouseKeys Control</title>
+
+<para>
+The <emphasis>
+MouseKeys</emphasis>
+ control allows a user to control all the mouse functions from the keyboard.
+When <emphasis>
+MouseKeys</emphasis>
+ are enabled, all keys with <emphasis>
+MouseKeys</emphasis>
+ actions bound to them generate core pointer events instead of normal <emphasis>
+KeyPress</emphasis>
+ and <emphasis>
+KeyRelease</emphasis>
+ events.
+</para>
+
+
+<para>
+The <emphasis>
+MouseKeys</emphasis>
+ control has a single attribute, <emphasis>
+mk_dflt_btn</emphasis>
+ that specifies the core button number to be used by mouse keys actions that do
+not explicitly specify a button. There is no convenience function for getting
+or setting the attribute; instead use <emphasis>
+XkbGetControls</emphasis>
+ and <emphasis>
+XkbSetControls</emphasis>
+ (see sections 10.9 and 10.10). <!-- xref -->
+</para>
+
+<note><para><emphasis>
+MouseKeys</emphasis>
+ can also be turned on and off by pressing the key combination necessary to
+produce an <emphasis>
+XK_Pointer_EnableKeys</emphasis>
+ keysym. The de facto default standard for this is <emphasis>
+Shift+Alt+NumLock</emphasis>
+, but this may vary depending on the keymap.</para></note>
+
+</sect2>
+<sect2 id='the_mousekeysaccel_control'>
+<title>The MouseKeysAccel Control</title>
+
+<para>
+When the <emphasis>
+MouseKeysAccel</emphasis>
+ control is enabled, the effect of a key-activated pointer motion action
+changes as a key is held down. If the control is disabled, pressing a
+mouse-pointer key yields one mouse event. When <emphasis>
+MouseKeysAccel</emphasis>
+ is enabled, mouse movement is defined by an initial distance specified in the
+<emphasis>
+XkbSA_MovePtr</emphasis>
+ action and the following fields in the <emphasis>
+XkbControlsRec</emphasis>
+ structure (see section 10.8). <!-- xref -->
+</para>
+
+<table frame='none'>
+<title>MouseKeysAccel Fields</title>
+<tgroup cols='2'>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>Field</entry>
+ <entry>Function</entry>
+</row>
+</thead>
+<tbody>
+<row rowsep='0'>
+ <entry>mk_delay</entry>
+ <entry>Time (ms) between the initial key press and the first repeated
+motion event</entry>
+</row>
+<row rowsep='0'>
+ <entry>mk_interval</entry>
+ <entry>Time (ms) between repeated motion events</entry>
+</row>
+<row rowsep='0'>
+ <entry>mk_time_to_max</entry>
+ <entry>Number of events (count) before the pointer reaches maximum
+speed</entry>
+</row>
+<row rowsep='0'>
+ <entry>mk_max_speed</entry>
+ <entry>The maximum speed (in pixels per event) the pointer reaches</entry>
+</row>
+<row rowsep='0'>
+ <entry>mk_curve</entry>
+ <entry>The ramp used to reach maximum pointer speed</entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+There are no convenience functions to query or change the attributes of the
+<emphasis>
+MouseKeysAccel</emphasis>
+ control; instead use <emphasis>
+XkbGetControls</emphasis>
+ and <emphasis>
+XkbSetControls</emphasis>
+ (see sections 10.9 and 10.10). <!-- xref -->
+</para>
+
+
+<para>
+The effects of the attributes of the <emphasis>
+MouseKeysAccel</emphasis>
+ control depend on whether the <emphasis>
+XkbSA_MovePtr</emphasis>
+ action (see section 16.1) specifies relative or absolute pointer motion. <!-- xref -->
+</para>
+
+<sect3 id='absolute_pointer_motion'>
+<title>Absolute Pointer Motion</title>
+
+<para>
+If an <emphasis>
+XkbSA_MovePtr</emphasis>
+ action specifies an absolute position for one of the coordinates but still
+allows acceleration, all repeated events contain any absolute coordinates
+specified in the action. For example, if the <emphasis>
+XkbSA_MovePtr</emphasis>
+ action specifies an absolute position for the X direction, but a relative
+motion for the Y direction, the pointer accelerates in the Y direction, but
+stays at the same X position.
+</para>
+
+
+</sect3>
+<sect3 id='relative_pointer_motion'>
+<title>Relative Pointer Motion</title>
+
+<para>
+If the <emphasis>
+XkbSA_MovePtr</emphasis>
+ action specifies relative motion, the initial event always moves the cursor
+the distance specified in the action. After <emphasis>
+mk_delay</emphasis>
+ milliseconds, a second motion event is generated, and another occurs every
+<emphasis>
+mk_interval</emphasis>
+ milliseconds until the user releases the key.
+</para>
+
+
+<para>
+Between the time of the second motion event and <emphasis>
+mk_time_to_max</emphasis>
+ intervals, the change in pointer distance per interval increases with each
+interval. After <emphasis>
+mk_time_to_max</emphasis>
+ intervals have elapsed, the change in pointer distance per interval remains
+the same and is calculated by multiplying the original distance specified in
+the action by <emphasis>
+mk_max_speed</emphasis>
+.
+</para>
+
+
+<para>
+For example, if the <emphasis>
+XkbSA_MovePtr</emphasis>
+ action specifies a relative motion in the X direction of 5, <emphasis>
+mk_delay</emphasis>
+=160, <emphasis>
+mk_interval</emphasis>
+=40, <emphasis>
+mk_time_to_max</emphasis>
+=30, and <emphasis>
+mk_max_speed</emphasis>
+=30, the following happens when the user presses the key:
+</para>
+
+<itemizedlist>
+<listitem>
+ <para>
+The pointer immediately moves 5 pixels in the X direction when the key is
+pressed.
+ </para>
+</listitem>
+<listitem>
+ <para>
+After 160 milliseconds (<emphasis>
+mk_delay</emphasis>
+), and every 40 milliseconds thereafter (<emphasis>
+mk_interval</emphasis>
+), the pointer moves in the X direction.
+ </para>
+</listitem>
+<listitem>
+ <para>
+The distance in the X direction increases with each interval until 30 intervals
+(<emphasis>
+mk_time_to_max</emphasis>
+) have elapsed.
+ </para>
+</listitem>
+<listitem>
+ <para>
+After 30 intervals, the pointer stops accelerating, and moves 150 pixels
+(<emphasis>
+mk_max_speed</emphasis>
+ * the original distance) every interval thereafter, until the key is released.
+ </para>
+</listitem>
+</itemizedlist>
+
+<para>
+The increase in pointer difference for each interval is a function of<emphasis>
+ mk_curve.</emphasis>
+ Events after the first but before maximum acceleration has been achieved are
+accelerated according to the formula:
+</para>
+
+<mediaobject>
+ <imageobject> <imagedata format="SVG" fileref="XKBlib-3.svg"/>
+ </imageobject>
+ </mediaobject>
+
+
+<para>
+Where <emphasis>
+action_delta</emphasis>
+ is the relative motion specified by the <emphasis>
+XkbSA_MovePtr</emphasis>
+ action, <emphasis>
+mk_max_speed </emphasis>
+and <emphasis>
+mk_time_to_max</emphasis>
+ are parameters to the <emphasis>
+MouseKeysAccel</emphasis>
+ control, and the curveFactor is computed using the <emphasis>
+MouseKeysAccel</emphasis>
+ <emphasis>
+mk_curve</emphasis>
+ parameter as follows:
+</para>
+
+<mediaobject>
+ <imageobject> <imagedata format="SVG" fileref="XKBlib-4.svg"/>
+ </imageobject>
+ </mediaobject>
+
+
+<para>
+With the result that a <emphasis>
+mk_curve</emphasis>
+ of zero causes the distance moved to increase linearly from <emphasis>
+action_delta</emphasis>
+ to <mediaobject>
+ <imageobject> <imagedata format="SVG" fileref="XKBlib-5.svg"/>
+ </imageobject>
+ </mediaobject>
+
+. A negative <emphasis>
+mk_curve</emphasis>
+ causes an initial sharp increase in acceleration that tapers off, and a
+positive curve yields a slower initial increase in acceleration followed by a
+sharp increase as the number of pointer events generated by the action
+approaches <emphasis>
+mk_time_to_max</emphasis>
+. The legal values for <emphasis>
+mk_curve</emphasis>
+ are between -1000 and 1000.
+</para>
+
+
+<para>
+A distance vs. time graph of the pointer motion is shown in Figure 10.1. <!-- xref -->
+</para>
+
+<mediaobject>
+ <imageobject> <imagedata format="SVG" fileref="XKBlib-6.svg"/>
+ </imageobject>
+<caption>MouseKeys Acceleration</caption>
+ </mediaobject>
+
+<!--
+<H5 CLASS="Figure">
+MouseKeys Acceleration</H5>
+-->
+</sect3>
+</sect2>
+</sect1>
+<sect1 id='controls_for_better_keyboard_access_by_physically_impaired_persons'>
+<title>Controls for Better Keyboard Access by Physically Impaired
+Persons</title>
+
+<para>
+The Xkb extension includes several controls specifically aimed at making
+keyboard use more effective for physically impaired people. All of these
+controls are boolean controls and may be individually enabled and disabled, as
+well as configured to tune their specific behavior. The behavior of these
+controls is based on the AccessDOS package
+<footnote><para>
+AccessDOS provides access to the DOS operating system for people with physical
+impairments and was developed by the Trace R&amp;D Center at the University of
+Wisconsin. For more information on AccessDOS, contact the Trace R&amp;D Center,
+Waisman Center and Department of Industrial Engineering, University of
+Wisconsin-Madison WI 53705-2280. Phone: 608-262-6966. e-mail: info@trace.wisc.edu.
+</para></footnote>.
+</para>
+
+<sect2 id='the_accessxkeys_control'>
+<title>The AccessXKeys Control</title>
+
+<para>
+Enabling or disabling the keyboard controls through a graphical user interface
+may be impossible for people who need to use the controls. For example, a user
+who needs <emphasis>
+SlowKeys</emphasis>
+ (see section 10.6.6) may not even be able to start the graphical application, <!-- xref -->
+let alone use it, if <emphasis>
+SlowKeys</emphasis>
+ is not enabled. To allow easier access to some of the controls, the <emphasis>
+AccessXKeys</emphasis>
+ control provides a set of special key sequences similar to those available in
+AccessDOS.
+</para>
+
+
+<para>
+When the <emphasis>
+AccessXKeys</emphasis>
+ control is enabled, the user can turn controls on or off from the keyboard by
+entering the following standard key sequences:
+</para>
+
+<itemizedlist>
+<listitem>
+ <para>
+Holding down a shift key by itself for eight seconds toggles the <emphasis>
+SlowKeys</emphasis>
+ control.
+ </para>
+</listitem>
+<listitem>
+ <para>
+Pressing and releasing the left or right <emphasis>
+Shift</emphasis>
+ key five times in a row, without any intervening key events and with less than
+30 seconds delay between consecutive presses, toggles the state of the
+<emphasis>
+StickyKeys</emphasis>
+ control.
+ </para>
+</listitem>
+<listitem>
+ <para>
+Simultaneously operating two or more modifier keys deactivates the <emphasis>
+StickyKeys</emphasis>
+ control.
+ </para>
+</listitem>
+</itemizedlist>
+
+<para>
+When the <emphasis>
+AccessXKeys</emphasis>
+ control is disabled, Xkb does not look for the above special key sequences.
+</para>
+
+
+<para>
+Some of these key sequences optionally generate audible feedback of the change
+in state, as described in section 10.6.3, or <!-- xref -->
+<emphasis>XkbControlsNotify</emphasis>
+ events, described in section 10.11. <!-- xref -->
+</para>
+
+</sect2>
+<sect2 id='the_accessxtimeout_control'>
+<title>The AccessXTimeout Control</title>
+
+<para>
+In environments where computers are shared, features such as <emphasis>
+SlowKeys</emphasis>
+ present a problem: if <emphasis>
+SlowKeys</emphasis>
+ is on, the keyboard can appear to be unresponsive because keys are not
+accepted until they are held for a certain period of time. To help solve this
+problem, Xkb provides an <emphasis>
+AccessXTimeout</emphasis>
+ control to automatically change the enabled/disabled state of any boolean
+controls and to change the value of the <emphasis>
+AccessXKeys</emphasis>
+ and <emphasis>
+AccessXFeedback</emphasis>
+ control attributes if the keyboard is idle for a specified period of time.
+</para>
+
+
+<para>
+When a timeout as specified by <emphasis>
+AccessXTimeout</emphasis>
+ occurs and a control is consequently modified, Xkb generates an <emphasis>
+XkbControlsNotify</emphasis>
+ event. For more information on <emphasis>
+XkbControlsNotify</emphasis>
+ events, refer to section 10.11. <!-- xref -->
+</para>
+
+
+<para>
+Use <emphasis>
+XkbGetAccessXTimeout</emphasis>
+ to query the current <emphasis>
+AccessXTimeout</emphasis>
+ options for a keyboard device.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbGetAccessXTimeout</emphasis>
+(<emphasis>
+display</emphasis>
+,<emphasis>
+ device_spec</emphasis>
+,<emphasis>
+ timeout_rtrn</emphasis>
+,<emphasis>
+ ctrls_mask_rtrn</emphasis>
+,<emphasis>
+ ctrls_values_rtrn</emphasis>
+,<emphasis>
+ options_mask_rtrn, options_values_rtrn</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ display</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+device_spec</emphasis>
+; /* device to query, or <emphasis>
+XkbUseCoreKbd</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned short * <emphasis>
+timeout_rtrn</emphasis>
+; /* delay until AccessXTimeout, seconds */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int *<emphasis>
+ ctrls_mask_rtrn</emphasis>
+; /* backfilled with controls to modify */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int * <emphasis>
+ctrls_values_rtrn</emphasis>
+; /* backfilled with on/off status for controls */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned short * <emphasis>
+opts_mask_rtrn</emphasis>
+; /* backfilled with <emphasis>
+ax_options</emphasis>
+ to modify */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned short * <emphasis>
+opts_values_rtrn</emphasis>
+; /* backfilled with values for <emphasis>
+ax_options</emphasis>
+ */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbGetAccessXTimeout</emphasis>
+ sends a request to the X server to obtain the current values for the <emphasis>
+AccessXTimeout</emphasis>
+ attributes, waits for a reply, and backfills the values into the appropriate
+arguments.<emphasis>
+ </emphasis>
+The parameters <emphasis>
+opts_mask_rtrn</emphasis>
+ and <emphasis>
+opts_values_rtrn</emphasis>
+ are backfilled with the options to modify and the values for <emphasis>
+ax_options</emphasis>
+, which is a field in the
+<emphasis>XkbControlsRec</emphasis>
+ structure (see section 10.8). <!-- xref -->
+<emphasis>
+XkbGetAccessXTimeout </emphasis>
+returns<emphasis>
+ </emphasis>
+<emphasis>
+True</emphasis>
+ if successful; if a compatible version of the Xkb extension is not available
+in the server, <emphasis>
+XkbGetAccessXTimeout</emphasis>
+ returns <emphasis>
+False</emphasis>
+.
+</para>
+
+
+<para>
+To configure the <emphasis>
+AccessXTimeout</emphasis>
+ options for a keyboard device, use <emphasis>
+XkbSetAccessXTimeout</emphasis>
+.
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbSetAccessXTimeout</emphasis>
+(<emphasis>
+display</emphasis>
+,<emphasis>
+ device_spec, timeout, ctrls_mask, ctrls_values, opts_mask,
+opts_values</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ display</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ device_spec</emphasis>
+; /* device to configure, or <emphasis>
+XkbUseCoreKbd</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned short <emphasis>
+timeout</emphasis>
+; /* seconds idle until AccessXTimeout occurs */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ ctrls_mask</emphasis>
+; /* boolean controls to modify */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ ctrls_values</emphasis>
+; /* new bits for controls selected by <emphasis>
+ctrls_mask</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned short <emphasis>
+opts_mask</emphasis>
+; /* <emphasis>
+ax_options</emphasis>
+ to change */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned short <emphasis>
+opts_values</emphasis>
+; /* new bits for <emphasis>
+ax_options</emphasis>
+ selected by <emphasis>
+opts_mask</emphasis>
+ */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+timeout</emphasis>
+ specifies the number of seconds the keyboard must be idle before the controls
+are modified. <emphasis>
+ctrls_mask</emphasis>
+ specifies what controls are to be enabled or disabled, and <emphasis>
+ctrls_values</emphasis>
+ specifies whether those controls are to be enabled or disabled. The bit values
+correspond to those for enabling and disabling boolean controls (see section
+10.1.1). The <emphasis>
+opts_mask</emphasis>
+ field specifies which attributes of the <emphasis>
+AccessXKeys</emphasis>
+ and <emphasis>
+AccessXFeedback</emphasis>
+ controls are to be changed, and <emphasis>
+opts_values</emphasis>
+ specifies the new values for those options. The bit values correspond to those
+for the <emphasis>
+ax_options</emphasis>
+ field of an <emphasis>
+XkbDescRec</emphasis>
+ (see section 10.8). <!-- xref -->
+</para>
+
+
+<para>
+<emphasis>
+XkbSetAccessXTimeout</emphasis>
+ sends a request to configure the <emphasis>
+AccessXTimeout</emphasis>
+ control to the server.<emphasis>
+ </emphasis>
+It does not wait for a reply, and normally returns <emphasis>
+True</emphasis>
+. If a compatible version of the Xkb extension is not available in the server,
+<emphasis>
+XkbSetAccessXTimeout</emphasis>
+ returns <emphasis>
+False</emphasis>
+.
+</para>
+
+
+</sect2>
+<sect2 id='the_accessxfeedback_control'>
+<title>The AccessXFeedback Control</title>
+
+<para>
+Just as some keyboards can produce keyclicks to indicate when a key is pressed
+or repeating, Xkb can provide feedback for the controls by using special beep
+codes. Use the <emphasis>
+AccessXFeedback</emphasis>
+ control to configure the specific types of operations that generate feedback.
+</para>
+
+
+<para>
+There is no convenience function for modifying the <emphasis>
+AccessXFeedback</emphasis>
+ control, although the feedback as a whole can be enabled or disabled just as
+other boolean controls are (see section 10.1). Individual beep codes are turned
+on or off by modifying the following bits in the <emphasis>
+ax_options</emphasis>
+ field of an <emphasis>
+XkbControlsRec</emphasis>
+ structure and using <emphasis>
+XkbSetControls</emphasis>
+ (see section 10.10): <!-- xref -->
+</para>
+
+<table frame='none'>
+<title>AccessXFeedback Masks</title>
+<tgroup cols='3'>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>Action</entry>
+ <entry>Beep Code</entry>
+ <entry>ax_options bit</entry>
+ </row>
+</thead>
+<tbody>
+<row rowsep='0'>
+ <entry>LED turned on</entry>
+ <entry>High-pitched beep</entry>
+ <entry>XkbAX_IndicatorFBMask</entry>
+</row>
+<row rowsep='0'>
+ <entry>LED turned off</entry>
+ <entry>Low-pitched beep</entry>
+ <entry>XkbAX_IndicatorFBMask</entry>
+</row>
+<row rowsep='0'>
+ <entry>More than one LED changed state</entry>
+ <entry>Two high-pitched beeps</entry>
+ <entry>XkbAX_IndicatorFBMask</entry>
+</row>
+<row rowsep='0'>
+ <entry>Control turned on</entry>
+ <entry>Rising tone</entry>
+ <entry>XkbAX_FeatureFBMask</entry>
+</row>
+<row rowsep='0'>
+ <entry>Control turned off</entry>
+ <entry>Falling tone</entry>
+ <entry>XkbAX_FeatureFBMask</entry>
+</row>
+<row rowsep='0'>
+ <entry>More than one control changed state</entry>
+ <entry>Two high-pitched beeps</entry>
+ <entry>XkbAX_FeatureFBMask</entry>
+</row>
+<row rowsep='0'>
+ <entry>SlowKeys and BounceKeys about to be turned on or off</entry>
+ <entry>Three high-pitched beeps</entry>
+ <entry>XkbAX_SlowWarnFBMask</entry>
+</row>
+<row rowsep='0'>
+ <entry>SlowKeys key pressed</entry>
+ <entry>Medium-pitched beep</entry>
+ <entry>XkbAX_SKPressFBMask</entry>
+</row>
+<row rowsep='0'>
+ <entry>SlowKeys key accepted</entry>
+ <entry>Medium-pitched beep</entry>
+ <entry>XkbAX_SKAcceptFBMask</entry>
+</row>
+<row rowsep='0'>
+ <entry>SlowKeys key rejected</entry>
+ <entry>Low-pitched beep</entry>
+ <entry>XkbAX_SKRejectFBMask</entry>
+</row>
+<row rowsep='0'>
+ <entry>Accepted SlowKeys key released</entry>
+ <entry>Medium-pitched beep</entry>
+ <entry>XkbAX_SKReleaseFBMask</entry>
+</row>
+<row rowsep='0'>
+ <entry>BounceKeys key rejected</entry>
+ <entry>Low-pitched beep</entry>
+ <entry>XkbAX_BKRejectFBMask</entry>
+</row>
+<row rowsep='0'>
+ <entry>StickyKeys key latched</entry>
+ <entry>Low-pitched beep followed by high-pitched beep</entry>
+ <entry>XkbAX_StickyKeysFBMask</entry>
+</row>
+<row rowsep='0'>
+ <entry>StickyKeys key locked</entry>
+ <entry>High-pitched beep</entry>
+ <entry>XkbAX_StickyKeysFBMask</entry>
+</row>
+<row rowsep='0'>
+ <entry>StickyKeys key unlocked</entry>
+ <entry>Low-pitched beep</entry>
+ <entry>XkbAX_StickyKeysFBMask</entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+Implementations that cannot generate continuous tones may generate multiple
+beeps instead of falling and rising tones; for example, they can generate a
+high-pitched beep followed by a low-pitched beep instead of a continuous
+falling tone. Other implementations can only ring the bell with one fixed
+pitch. In these cases, use the <emphasis>
+XkbAX_DumbBellFBMask</emphasis>
+ bit of <emphasis>
+ax_options</emphasis>
+ to indicate that the bell can only ring with a fixed pitch.
+</para>
+
+
+<para>
+When any of the above feedbacks occur, Xkb may generate a <emphasis>
+XkbBellNotify</emphasis>
+ event (see section 9.4). <!-- xref -->
+</para>
+
+
+</sect2>
+<sect2 id='accessxnotify_events'>
+<title>AccessXNotify Events</title>
+
+<para>
+The server can generate <emphasis>
+XkbAccessXNotify</emphasis>
+ events for some of the global keyboard controls. The structure for the
+<emphasis>
+XkbAccessXNotify</emphasis>
+ event type is as follows:
+</para>
+
+<para><programlisting>
+typedef struct {
+ int type; /* Xkb extension base event code */
+ unsigned long serial; /* X server serial number for event */
+ Bool send_event; /* <emphasis> True</emphasis> =&gt; synthetically generated */
+ Display * display; /* server connection where event generated */
+ Time time; /* server time when event generated */
+ int xkb_type; /* <emphasis> XkbAccessXNotify</emphasis> */
+ int device; /* Xkb device ID, will not be <emphasis> XkbUseCoreKbd</emphasis> */
+ int detail; /* XkbAXN_* */
+ KeyCode keycode; /* key of event */
+ int slowKeysDelay; /* current SlowKeys delay */
+ int debounceDelay; /* current debounce delay */
+} <emphasis>XkbAccessXNotifyEvent</emphasis>;
+</programlisting></para>
+
+<para>
+The <emphasis>
+detail</emphasis>
+ field describes what AccessX event just occurred and can be any of the values
+in Table 10.4. <!-- xref -->
+</para>
+
+<table frame='none'>
+<title>AccessXNotify Events</title>
+<tgroup cols='2'>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>detail</entry>
+ <entry>Reason</entry>
+</row>
+</thead>
+<tbody>
+<row rowsep='0'>
+ <entry>XkbAXN_SKPress</entry>
+ <entry>A key was pressed when SlowKeys was enabled.</entry>
+</row>
+<row rowsep='0'>
+ <entry>XkbAXN_SKAccept</entry>
+ <entry>A key was accepted (held longer than the SlowKeys delay).</entry>
+</row>
+<row rowsep='0'>
+ <entry>XkbAXN_SKRelease</entry>
+ <entry>An accepted SlowKeys key was released.</entry>
+</row>
+<row rowsep='0'>
+ <entry>XkbAXN_SKReject</entry>
+ <entry>A key was rejected (released before the SlowKeys delay
+expired).</entry>
+</row>
+<row rowsep='0'>
+ <entry>XkbAXN_BKAccept</entry>
+ <entry>A key was accepted by BounceKeys.</entry>
+</row>
+<row rowsep='0'>
+ <entry>XkbAXN_BKReject</entry>
+ <entry>A key was rejected (pressed before the BounceKeys delay
+expired).</entry>
+</row>
+<row rowsep='0'>
+ <entry>XkbAXN_AXKWarning</entry>
+ <entry>AccessXKeys is about to turn on/off StickyKeys or BounceKeys.</entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+The <emphasis>
+keycode</emphasis>
+ field reports the keycode of the key for which the event occurred. If the
+action is related to <emphasis>
+SlowKeys</emphasis>
+, the <emphasis>
+slowKeysDelay</emphasis>
+ field contains the current <emphasis>
+SlowKeys</emphasis>
+ acceptance delay. If the action is related to <emphasis>
+BounceKeys</emphasis>
+, the <emphasis>
+debounceDelay</emphasis>
+ field contains the current <emphasis>
+BounceKeys</emphasis>
+ debounce delay.
+</para>
+
+<sect3 id='selecting_for_accessx_events'>
+<title>Selecting for AccessX Events</title>
+
+<para>
+To receive <emphasis>
+XkbAccessXNotify</emphasis>
+ events under all possible conditions, use <emphasis>
+XkbSelectEvents</emphasis>
+ (see section 4.3) and pass <emphasis> <!-- xref -->
+XkbAccesXNotifyMask</emphasis>
+ in both <emphasis>
+bits_to_change</emphasis>
+ and <emphasis>
+values_for_bits</emphasis>
+.
+</para>
+
+
+<para>
+To receive <emphasis>
+XkbStateNotify</emphasis>
+ events only under certain conditions, use <emphasis>
+XkbSelectEventDetails</emphasis>
+ using <emphasis>
+XkbAccessXNotify</emphasis>
+ as the <emphasis>
+event_type</emphasis>
+ and specifying the desired state changes in <emphasis>
+bits_to_change</emphasis>
+ and <emphasis>
+values_for_bits</emphasis>
+ using mask bits from Table 10.5. <!-- xref -->
+</para>
+
+<table frame='none'>
+<title>AccessXNotify Event Details</title>
+<tgroup cols='3'>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>XkbAccessXNotify Event Details</entry>
+ <entry>Value</entry>
+ <entry>Circumstances</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='0'>
+ <entry>XkbAXN_SKPressMask</entry>
+ <entry>(1&lt;&lt;0)</entry>
+ <entry>Slow key press notification wanted</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbAXN_SKAcceptMask</entry>
+ <entry>(1&lt;&lt;1)</entry>
+ <entry>Slow key accept notification wanted</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbAXN_SKRejectMask</entry>
+ <entry>(1&lt;&lt;2)</entry>
+ <entry>Slow key reject notification wanted</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbAXN_SKReleaseMask</entry>
+ <entry>(1&lt;&lt;3)</entry>
+ <entry>Slow key release notification wanted</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbAXN_BKAcceptMask</entry>
+ <entry>(1&lt;&lt;4)</entry>
+ <entry>Bounce key accept notification wanted</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbAXN_BKRejectMask</entry>
+ <entry>(1&lt;&lt;5)</entry>
+ <entry>Bounce key reject notification wanted</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbAXN_AXKWarningMask</entry>
+ <entry>(1&lt;&lt;6)</entry>
+ <entry>AccessX warning notification wanted</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbAXN_AllEventsMask</entry>
+ <entry>(0x7f)</entry>
+ <entry>All AccessX features notifications wanted</entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+</sect3>
+</sect2>
+<sect2 id='stickykeys_repeatkeys_and_mousekeys_events'>
+<title>StickyKeys, RepeatKeys, and MouseKeys Events</title>
+
+<para>
+The <emphasis>
+StickyKeys</emphasis>
+, <emphasis>
+RepeatKeys</emphasis>
+, and <emphasis>
+MouseKeys</emphasis>
+ controls do not generate specific events. Instead, the latching, unlatching,
+locking, or unlocking of modifiers using <emphasis>
+StickyKeys</emphasis>
+ generates <emphasis>
+XkbStateNotify</emphasis>
+ events as described in section 5.4. Repeating keys generate normal <emphasis> <!-- xref -->
+KeyPress</emphasis>
+ and <emphasis>
+KeyRelease</emphasis>
+ events, though the auto-repeat can be detected using <emphasis>
+DetectableAutorepeat</emphasis>
+ (see section 10.3.3). Finally, <emphasis> <!-- xref -->
+MouseKeys</emphasis>
+ generates pointer events identical to those of the core pointer device.
+</para>
+
+
+</sect2>
+<sect2 id='the_slowkeys_control'>
+<title>The SlowKeys Control</title>
+
+<para>
+Some users may accidentally bump keys while moving a hand or typing stick
+toward the key they want. Usually, the keys that are accidentally bumped are
+just hit for a very short period of time. The <emphasis>
+SlowKeys</emphasis>
+ control helps filter these accidental bumps by telling the server to wait a
+specified period, called the <emphasis>
+SlowKeys acceptance delay</emphasis>
+, before delivering key events. If the key is released before this period
+elapses, no key events are generated. Users can then bump any number of keys on
+their way to the one they want without accidentally getting those characters.
+Once they have reached the key they want, they can then hold the desired key
+long enough for the computer to accept it. <emphasis>
+SlowKeys</emphasis>
+ is a boolean control with one configurable attribute.
+</para>
+
+<para>
+When the <emphasis>
+SlowKeys</emphasis>
+ control is active, the server reports the initial key press, subsequent
+acceptance or rejection, and release of any key to interested clients by
+sending an appropriate <emphasis>
+AccessXNotify</emphasis>
+ event (see section 10.6.4). <!-- xref -->
+</para>
+
+<para>
+To get the <emphasis>
+SlowKeys</emphasis>
+ acceptance delay for a keyboard device, use <emphasis>
+XkbGetSlowKeysDelay</emphasis>
+.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbGetSlowKeysDelay</emphasis>
+(<emphasis>
+display</emphasis>
+,<emphasis>
+ device_spec</emphasis>
+,<emphasis>
+ delay_rtrn</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ display</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+device_spec</emphasis>
+; /* device ID, or <emphasis>
+XkbUseCoreKbd</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int * <emphasis>
+delay_rtrn</emphasis>
+; /* backfilled with <emphasis>
+SlowKeys</emphasis>
+ delay, ms */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbGetSlowKeysDelay </emphasis>
+requests the attributes of the <emphasis>
+SlowKeys</emphasis>
+ control from the server, waits for a reply and backfills <emphasis>
+delay_rtrn </emphasis>
+with the <emphasis>
+SlowKeys</emphasis>
+ delay attribute. <emphasis>
+XkbGetSlowKeysDelay </emphasis>
+returns <emphasis>
+True</emphasis>
+ if successful; if a compatible version of the Xkb extension is not available
+in the server, <emphasis>
+XkbGetSlowKeysDelay</emphasis>
+ returns <emphasis>
+False</emphasis>
+.
+</para>
+
+
+<para>
+To set the <emphasis>
+SlowKeys</emphasis>
+ acceptance delay for a keyboard device, use <emphasis>
+XkbSetSlowKeysDelay</emphasis>
+.
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbSetSlowKeysDelay</emphasis>
+(<emphasis>
+display</emphasis>
+,<emphasis>
+ device_spec</emphasis>
+,<emphasis>
+ delay</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ display</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+device_spec</emphasis>
+; /* device to configure, or <emphasis>
+XkbUseCoreKbd</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+delay</emphasis>
+; /* <emphasis>
+SlowKeys</emphasis>
+ delay, ms */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbSetSlowKeysDelay</emphasis>
+ sends a request to configure the <emphasis>
+SlowKeys</emphasis>
+ control to the server.<emphasis>
+ </emphasis>
+It does not wait for a reply, and normally returns <emphasis>
+True</emphasis>
+. Specifying a value of <emphasis>
+0</emphasis>
+ for the <emphasis>
+delay </emphasis>
+parameter causes <emphasis>
+XkbSetSlowKeys</emphasis>
+ to generate a <emphasis>
+BadValue</emphasis>
+ protocol error. If a compatible version of the Xkb extension is not available
+in the server <emphasis>
+XkbSetSlowKeysDelay</emphasis>
+ returns <emphasis>
+False</emphasis>
+.
+</para>
+
+
+</sect2>
+<sect2 id='the_bouncekeys_control'>
+<title>The BounceKeys Control</title>
+
+<para>
+Some users may accidentally "bounce" on a key when they release it. They press
+it once, then accidentally press it again after they release it. The <emphasis>
+BounceKeys</emphasis>
+ control temporarily disables a key after it has been pressed, effectively
+"debouncing" the keyboard. The period of time the key is disabled after it is
+released is known as the <emphasis>
+BounceKeys delay</emphasis>
+. <emphasis>
+BounceKeys</emphasis>
+ is a boolean control.
+</para>
+
+
+<para>
+When the <emphasis>
+BounceKeys</emphasis>
+ control is active, the server reports acceptance or rejection of any key to
+interested clients by sending an appropriate <emphasis>
+AccessXNotify</emphasis>
+ event (see section 10.6.4). <!-- xref -->
+</para>
+
+
+<para>
+Use <emphasis>
+XkbGetBounceKeysDelay</emphasis>
+ to query the current <emphasis>
+BounceKeys</emphasis>
+ delay for a keyboard device.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbGetBounceKeysDelay</emphasis>
+(<emphasis>
+display</emphasis>
+,<emphasis>
+ device_spec</emphasis>
+,<emphasis>
+ delay_rtrn</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ display</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+device_spec</emphasis>
+; /* device ID, or <emphasis>
+XkbUseCoreKbd</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int * <emphasis>
+delay_rtrn</emphasis>
+; /* backfilled with bounce keys delay, ms */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbGetBounceKeysDelay </emphasis>
+requests the attributes of the <emphasis>
+BounceKeys</emphasis>
+ control from the server, waits for a reply, and backfills <emphasis>
+delay_rtrn </emphasis>
+with the <emphasis>
+BounceKeys</emphasis>
+ delay attribute. <emphasis>
+XkbGetBounceKeysDelay </emphasis>
+returns<emphasis>
+ </emphasis>
+<emphasis>
+True</emphasis>
+ if successful; if a compatible version of the Xkb extension is not available
+in the server <emphasis>
+XkbGetSlowKeysDelay</emphasis>
+ returns <emphasis>
+False</emphasis>
+.
+</para>
+
+
+<para>
+To set the <emphasis>
+BounceKeys</emphasis>
+ delay for a keyboard device, use <emphasis>
+XkbSetBounceKeysDelay</emphasis>
+.
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbSetBounceKeysDelay</emphasis>
+(<emphasis>
+display</emphasis>
+,<emphasis>
+ device_spec</emphasis>
+,<emphasis>
+ delay</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ display</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ device_spec</emphasis>
+; /* device to configure, or <emphasis>
+XkbUseCoreKbd</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+delay</emphasis>
+; /* bounce keys delay, ms */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbSetBounceKeysDelay</emphasis>
+ sends a request to configure the <emphasis>
+BounceKeys</emphasis>
+ control to the server.<emphasis>
+ </emphasis>
+It does not wait for a reply and normally returns <emphasis>
+True</emphasis>
+. Specifying a value of <emphasis>
+zero </emphasis>
+for the <emphasis>
+delay </emphasis>
+parameter causes <emphasis>
+XkbSetBounceKeysDelay</emphasis>
+ to generate a <emphasis>
+BadValue</emphasis>
+ protocol error. If a compatible version of the Xkb extension is not available
+in the server, <emphasis>
+XkbSetBounceKeysDelay</emphasis>
+ returns <emphasis>
+False</emphasis>
+.
+</para>
+
+</sect2>
+<sect2 id='the_stickykeys_control'>
+<title>The StickyKeys Control</title>
+
+<para>
+Some people find it difficult or even impossible to press two keys at once. For
+example, a one-fingered typist or someone using a mouth stick cannot press the
+<emphasis>
+Shift</emphasis>
+ and <emphasis>
+1</emphasis>
+ keys at the same time. The <emphasis>
+StickyKeys</emphasis>
+ control solves this problem by changing the behavior of the modifier keys.
+With <emphasis>
+StickyKeys</emphasis>
+, the user can first press a modifier, release it, then press another key. For
+example, to get an exclamation point on a PC-style keyboard, the user can press
+the <emphasis>
+Shift</emphasis>
+ key, release it, and then press the <emphasis>
+1</emphasis>
+ key.
+</para>
+
+
+<para>
+<emphasis>
+StickyKeys</emphasis>
+ also allows users to lock modifier keys without requiring special locking
+keys. When <emphasis>
+StickyKeys</emphasis>
+ is enabled, a modifier is latched when the user presses it just once. The user
+can press a modifier twice in a row to lock it, and then unlock it by pressing
+it one more time.
+</para>
+
+
+<para>
+When a modifier is latched, it becomes unlatched when the user presses a
+nonmodifier key or a pointer button. For instance, to enter the sequence
+<emphasis>
+Shift</emphasis>
++<emphasis>
+Control</emphasis>
++<emphasis>
+Z</emphasis>
+ the user could press and release the <emphasis>
+Shift</emphasis>
+ key to latch it, then press and release the <emphasis>
+Control</emphasis>
+ key to latch it, and finally press and release the Z key. Because the
+<emphasis>
+Control</emphasis>
+ key is a modifier key, pressing it does not unlatch the <emphasis>
+Shift</emphasis>
+ key. Thus, after the user presses the <emphasis>
+Control</emphasis>
+ key, both the <emphasis>
+Shift</emphasis>
+ and <emphasis>
+Control</emphasis>
+ modifiers are latched. When the user presses the <emphasis>
+Z</emphasis>
+ key, the effect is as though the user had pressed <emphasis>
+Shift</emphasis>
++<emphasis>
+Control</emphasis>
++<emphasis>
+Z</emphasis>
+. In addition, because the <emphasis>
+Z</emphasis>
+ key is not a modifier key, the <emphasis>
+Shift</emphasis>
+ and <emphasis>
+Control</emphasis>
+ modifiers are unlatched.
+</para>
+
+
+<para>
+Locking a modifier key means that the modifier affects any key or pointer
+button the user presses until the user unlocks it or it is unlocked
+programmatically. For example, to enter the sequence ("XKB") on a keyboard
+where ‘(’ is a shifted ‘9’, ‘)’ is a shifted ‘0’, and ‘"’
+is a shifted single quote, the user could press and release the <emphasis>
+Shift</emphasis>
+ key twice to lock the <emphasis>
+Shift</emphasis>
+ modifier. Then, when the user presses the <emphasis>
+9</emphasis>
+, <emphasis>
+‘</emphasis>
+, <emphasis>
+x</emphasis>
+, <emphasis>
+k</emphasis>
+, <emphasis>
+b</emphasis>
+, <emphasis>
+‘</emphasis>
+, and <emphasis>
+0</emphasis>
+ keys in sequence, it generates ("XKB"). To unlock the <emphasis>
+Shift</emphasis>
+ modifier, the user can press and release the <emphasis>
+Shift</emphasis>
+ key.
+</para>
+
+
+<para>
+<emphasis>StickyKeys</emphasis>
+ is a boolean control with two separate attributes that may be individually
+configured: one to automatically disable it, and one to control the latching
+behavior of modifier keys.
+</para>
+
+<sect3 id='stickykeys_options'>
+<title>StickyKeys Options</title>
+
+<para>
+The <emphasis>
+StickyKeys</emphasis>
+ control has two options that can be accessed via the <emphasis>
+ax_options</emphasis>
+ of an <emphasis>
+XkbControlsRec</emphasis>
+ structure (see section 10.8). The first option, <emphasis>
+TwoKeys</emphasis>
+, specifies whether <emphasis>
+StickyKeys</emphasis>
+ should automatically turn off when two keys are pressed at the same time. This
+feature is useful for shared computers so people who do not want them do not
+need to turn <emphasis>
+StickyKeys</emphasis>
+ off if a previous user left <emphasis>
+StickyKeys</emphasis>
+ on. The second option, <emphasis>
+LatchToLock</emphasis>
+, specifies whether or not <emphasis>
+StickyKeys</emphasis>
+ locks a modifier when pressed twice in a row.
+</para>
+
+
+<para>
+Use <emphasis>
+XkbGetStickyKeysOptions</emphasis>
+ to query the current <emphasis>
+StickyKeys</emphasis>
+ attributes for a keyboard device.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbGetStickyKeysOptions</emphasis>
+(<emphasis>
+display</emphasis>
+,<emphasis>
+ device_spec</emphasis>
+,<emphasis>
+ options_rtrn</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ display</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+device_spec</emphasis>
+; /* device ID, or <emphasis>
+XkbUseCoreKbd</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int * <emphasis>
+options_rtrn</emphasis>
+; /* backfilled with StickyKeys option mask */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbGetStickyKeysOptions </emphasis>
+requests the attributes of the <emphasis>
+StickyKeys</emphasis>
+ control from the server, waits for a reply, and backfills <emphasis>
+options_rtrn </emphasis>
+with a mask indicating whether the individual <emphasis>
+StickyKeys</emphasis>
+ options are on or off. Valid bits in <emphasis>
+options_rtrn</emphasis>
+ are:
+</para>
+
+<para>
+<programlisting>
+ <emphasis>XkbAX_TwoKeysMask</emphasis>
+ <emphasis>XkbAX_LatchToLockMask</emphasis>
+</programlisting>
+</para>
+
+<para>
+<emphasis>
+XkbGetStickyKeysOptions </emphasis>
+returns <emphasis>
+True</emphasis>
+ if successful; if a compatible version of the Xkb extension is not available
+in the server <emphasis>
+XkbGetStickyKeysOptions</emphasis>
+ returns <emphasis>
+False</emphasis>
+.
+</para>
+
+
+<para>
+To set the <emphasis>
+StickyKeys</emphasis>
+ attributes for a keyboard device, use <emphasis>
+XkbSetStickyKeysOptions</emphasis>
+.
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbSetStickyKeysOptions</emphasis>
+(<emphasis>
+display</emphasis>
+,<emphasis>
+ device_spec, mask, values</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ display</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+device_spec</emphasis>
+; /* device to configure, or XkbUseCoreKbd */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+mask</emphasis>
+; /* selects StickyKeys attributes to modify */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+values;</emphasis>
+ /* values for selected attributes */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbSetStickyKeysOptions</emphasis>
+ sends a request to configure the <emphasis>
+StickyKeys</emphasis>
+ control to the server.<emphasis>
+ </emphasis>
+It does not wait for a reply and normally returns <emphasis>
+True</emphasis>
+. The valid bits to use for both the <emphasis>
+mask</emphasis>
+ and <emphasis>
+values</emphasis>
+ parameters are:
+</para>
+
+<para>
+<programlisting>
+ <emphasis>XkbAX_TwoKeysMask</emphasis>
+ <emphasis>XkbAX_LatchToLockMask</emphasis>
+</programlisting>
+</para>
+
+<para>
+ If a compatible version of the Xkb extension is not available in the server,
+<emphasis>
+XkbSetStickyKeysOptions</emphasis>
+ returns <emphasis>
+False</emphasis>
+.
+</para>
+
+</sect3>
+</sect2>
+</sect1>
+<sect1 id='controls_for_general_keyboard_mapping'>
+<title>Controls for General Keyboard Mapping</title>
+
+<para>
+There are several controls that apply to the keyboard mapping in general. They
+control handling of out-of-range group indices and how modifiers are processed
+and consumed in the server. These are:
+</para>
+
+<para>
+<programlisting>
+ <emphasis>GroupsWrap</emphasis>
+ <emphasis>IgnoreGroupLock</emphasis>
+ <emphasis>IgnoreLockMods</emphasis>
+ <emphasis>InternalMods </emphasis>
+</programlisting>
+</para>
+
+<para>
+<emphasis>
+IgnoreGroupLock</emphasis>
+ is a boolean control; the rest are always active.
+</para>
+
+
+<para>
+Without the modifier processing options provided by Xkb, passive grabs set via
+translations in a client (for example, <emphasis>
+Alt&lt;KeyPress&gt;space</emphasis>
+) do not trigger if any modifiers other than those specified by the translation
+are set. This results in problems in the user interface when either <emphasis>
+NumLock</emphasis>
+ or a secondary keyboard group is active. The <emphasis>
+IgnoreLockMods</emphasis>
+ and <emphasis>
+IgnoreGroupLock</emphasis>
+ controls make it possible to avoid this behavior without exhaustively
+specifying a grab for every possible modifier combination.
+</para>
+
+<sect2 id='the_groupswrap_control'>
+<title>The GroupsWrap Control</title>
+
+<para>
+The <emphasis>
+GroupsWrap</emphasis>
+ control determines how illegal groups are handled on a global basis. There are
+a number of valid keyboard sequences that can cause the effective group number
+to go out of range. When this happens, the group must be normalized back to a
+valid number. The <emphasis>
+GroupsWrap</emphasis>
+ control specifies how this is done.
+</para>
+
+
+<para>
+When dealing with group numbers, all computations are done using the group
+index, which is the group number minus one. There are three different
+algorithms; the <emphasis>
+GroupsWrap</emphasis>
+ control specifies which one is used:
+</para>
+
+<itemizedlist>
+<listitem>
+ <para>XkbRedirectIntoRange</para>
+ <para>
+All invalid group numbers are converted to a valid group number by taking the
+last four bits of the <emphasis>
+GroupsWrap</emphasis>
+ control and using them as the group index. If the result is still out of
+range, Group one is used.
+ </para>
+</listitem>
+<listitem>
+ <para>
+XkbClampIntoRange
+ </para>
+ <para>
+All invalid group numbers are converted to the nearest valid group number.
+Group numbers larger than the highest supported group number are mapped to the
+highest supported group; those less than one are mapped to group one.
+ </para>
+</listitem>
+<listitem>
+ <para>XkbWrapIntoRange</para>
+ <para>
+All invalid group numbers are converted to a valid group number using integer
+modulus applied to the group index.
+ </para>
+</listitem>
+</itemizedlist>
+
+<para>
+There are no convenience functions for manipulating the <emphasis>
+GroupsWrap</emphasis>
+ control. Manipulate the <emphasis>
+GroupsWrap</emphasis>
+ control via the <emphasis>
+groups_wrap</emphasis>
+ field in the <emphasis>
+XkbControlsRec</emphasis>
+ structure, then use <emphasis>
+XkbSetControls</emphasis>
+ and <emphasis>
+XkbGetControls</emphasis>
+ (see section 10.9 and section 10.10) to query and change this control. <!-- xref -->
+</para>
+
+<note><para>See also section 15.3.2 or a discussion of the related field, <!-- xref -->
+<emphasis>
+group_info</emphasis>
+, which also normalizes a group under certain circumstances.</para></note>
+
+</sect2>
+<sect2 id='the_ignorelockmods_control'>
+<title>The IgnoreLockMods Control</title>
+
+<para>
+The core protocol does not provide a way to exclude specific modifiers from
+grab calculations, with the result that locking modifiers sometimes have
+unanticipated side effects.
+</para>
+
+
+<para>
+The <emphasis>
+IgnoreLockMods</emphasis>
+ control specifies modifiers that should be excluded from grab calculations.
+These modifiers are also not reported in any core events except <emphasis>
+KeyPress</emphasis>
+ and <emphasis>
+KeyRelease</emphasis>
+ events that do not activate a passive grab and that do not occur while a grab
+is active.
+</para>
+
+
+<para>
+Manipulate the <emphasis>
+IgnoreLockMods</emphasis>
+ control via the <emphasis>
+ignore_lock</emphasis>
+ field in the <emphasis>
+XkbControlsRec</emphasis>
+ structure, then use <emphasis>
+XkbSetControls</emphasis>
+ and <emphasis>
+XkbGetControls</emphasis>
+ (see sections 10.9 and 10.10) to query and change this control. Alternatively, <!-- xref -->
+use <emphasis>
+XkbSetIgnoreLockMods</emphasis>
+.
+</para>
+
+
+<para>
+To set the modifiers that, if locked, are not to be reported in matching events
+to passive grabs, use <emphasis>
+XkbSetIgnoreLockMods.</emphasis>
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbSetIgnoreLockMods</emphasis>
+(<emphasis>
+display, device_spec, affect_real, real_values, affect_virtual,
+virtual_values</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+display</emphasis>
+; /* connection to the X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+device_spec</emphasis>
+; /* device ID, or <emphasis>
+XkbUseCoreKbd</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ affect_real</emphasis>
+; /* mask of real modifiers affected by this call */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ real_values</emphasis>
+; /* values for affected real modifiers (1=&gt;set, 0=&gt;unset) */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ affect_virtual</emphasis>
+; /* mask of virtual modifiers affected by this call */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ virtual_values</emphasis>
+; /* values for affected virtual modifiers (1=&gt;set, 0=&gt;unset)
+*/
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbSetIgnoreLockMods</emphasis>
+ sends a request to the server to change the server’s <emphasis>
+IgnoreLockMods</emphasis>
+ control. <emphasis>
+affect_real</emphasis>
+ and <emphasis>
+real_values</emphasis>
+ are masks of real modifier bits indicating which real modifiers are to be
+added and removed from the server’s <emphasis>
+IgnoreLockMods</emphasis>
+ control. Modifiers selected by both <emphasis>
+affect_real</emphasis>
+ and <emphasis>
+real_values</emphasis>
+ are added to the server’s <emphasis>
+IgnoreLockMods</emphasis>
+ control; those selected by <emphasis>
+affect_real</emphasis>
+ but not by <emphasis>
+real_values</emphasis>
+ are removed from the server’s <emphasis>
+IgnoreLockMods</emphasis>
+ control. Valid values for <emphasis>
+affect_real</emphasis>
+ and <emphasis>
+real_values</emphasis>
+ consist of any combination of the eight core modifier bits: <emphasis>
+ShiftMask</emphasis>
+, <emphasis>
+LockMask</emphasis>
+, <emphasis>
+ControlMask</emphasis>
+, <emphasis>
+Mod1Mask</emphasis>
+ - <emphasis>
+Mod5Mask</emphasis>
+. <emphasis>
+affect_virtual</emphasis>
+ and <emphasis>
+virtual_values</emphasis>
+ are masks of virtual modifier bits indicating which virtual modifiers are to
+be added and removed from the server’s <emphasis>
+IgnoreLockMods</emphasis>
+ control. Modifiers selected by both <emphasis>
+affect_virtual</emphasis>
+ and <emphasis>
+virtual_values</emphasis>
+ are added to the server’s <emphasis>
+IgnoreLockMods</emphasis>
+ control; those selected by <emphasis>
+affect_virtual</emphasis>
+ but not by <emphasis>
+virtual_values</emphasis>
+ are removed from the server’s <emphasis>
+IgnoreLockMods</emphasis>
+ control.<emphasis>
+ </emphasis>
+See section 7.1 for a discussion of virtual modifier masks to use in <emphasis> <!-- xref -->
+affect_virtual</emphasis>
+ and <emphasis>
+virtual_values</emphasis>
+. <emphasis>
+XkbSetIgnoreLockMods</emphasis>
+ does not wait for a reply from the server. It returns <emphasis>
+True</emphasis>
+ if the request was sent, and <emphasis>
+False</emphasis>
+ otherwise.
+</para>
+
+</sect2>
+<sect2 id='the_ignoregrouplock_control'>
+<title>The IgnoreGroupLock Control</title>
+
+<para>
+The <emphasis>
+IgnoreGroupLock</emphasis>
+ control is a boolean control with no attributes. If enabled, it specifies that
+the locked state of the keyboard group should not be considered when activating
+passive grabs.
+</para>
+
+<para>
+Because <emphasis>
+IgnoreGroupLock</emphasis>
+ is a boolean control with no attributes, use the general boolean controls
+functions (see section 10.1) to change its state. <!-- xref -->
+</para>
+
+
+</sect2>
+<sect2 id='the_internalmods_control'>
+<title>The InternalMods Control</title>
+
+<para>
+The core protocol does not provide any means to prevent a modifier from being
+reported in events sent to clients; Xkb, however makes this possible via the
+<emphasis>
+InternalMods</emphasis>
+ control. It specifies modifiers that should be consumed by the server and not
+reported to clients. When a key is pressed and a modifier that has its bit set
+in the <emphasis>
+InternalMods</emphasis>
+ control is reported to the server, the server uses the modifier when
+determining the actions to apply for the key. The server then clears the bit,
+so it is not actually reported to the client. In addition, modifiers specified
+in the <emphasis>
+InternalMods</emphasis>
+ control are not used to determine grabs and are not used to calculate core
+protocol compatibility state.
+</para>
+
+
+<para>
+Manipulate the <emphasis>
+InternalMods</emphasis>
+ control via the <emphasis>
+internal</emphasis>
+ field in the <emphasis>
+XkbControlsRec</emphasis>
+ structure, using <emphasis>
+XkbSetControls</emphasis>
+ and <emphasis>
+XkbGetControls</emphasis>
+ (see sections10.9 and 10.10). Alternatively, use <emphasis> <!-- xref -->
+XkbSetServerInternalMods</emphasis>
+.
+</para>
+
+
+<para>
+To set the modifiers that are consumed by the server before events are
+delivered to the client, use <emphasis>
+XkbSetServerInternalMods.</emphasis>
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbSetServerInternalMods</emphasis>
+(<emphasis>
+display, device_spec, affect_real, real_values, affect_virtual,
+virtual_values</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+display</emphasis>
+; /* connection to the X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+device_spec</emphasis>
+;‘ /* device ID, or <emphasis>
+XkbUseCoreKbd</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ affect_real</emphasis>
+; /* mask of real modifiers affected by this call */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ real_values</emphasis>
+; /* values for affected real modifiers (1=&gt;set, 0=&gt;unset) */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ affect_virtual</emphasis>
+; /* mask of virtual modifiers affected by this call */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ virtual_values</emphasis>
+; /* values for affected virtual modifiers (1=&gt;set, 0=&gt;unset)
+*/
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbSetServerInternalMods</emphasis>
+ sends a request to the server to change the internal modifiers consumed by the
+server. <emphasis>
+affect_real</emphasis>
+ and <emphasis>
+real_values</emphasis>
+ are masks of real modifier bits indicating which real modifiers are to be
+added and removed from the server’s internal modifiers control. Modifiers
+selected by both <emphasis>
+affect_real</emphasis>
+ and <emphasis>
+real_values</emphasis>
+ are added to the server’s internal modifiers control; those selected by
+<emphasis>
+affect_real</emphasis>
+ but not by <emphasis>
+real_values</emphasis>
+ are removed from the server’s internal modifiers mask. Valid values for
+<emphasis>
+affect_real</emphasis>
+ and <emphasis>
+real_values</emphasis>
+ consist of any combination of the eight core modifier bits: <emphasis>
+ShiftMask</emphasis>
+, <emphasis>
+LockMask</emphasis>
+, <emphasis>
+ControlMask</emphasis>
+, <emphasis>
+Mod1Mask</emphasis>
+ - <emphasis>
+Mod5Mask</emphasis>
+.<emphasis>
+ affect_virtual</emphasis>
+ and <emphasis>
+virtual_values</emphasis>
+ are masks of virtual modifier bits indicating which virtual modifiers are to
+be added and removed from the server’s internal modifiers control. Modifiers
+selected by both <emphasis>
+affect_virtual</emphasis>
+ and <emphasis>
+virtual_values</emphasis>
+ are added to the server’s internal modifiers control; those selected by
+<emphasis>
+affect_virtual</emphasis>
+ but not by <emphasis>
+virtual_values</emphasis>
+ are removed from the server’s internal modifiers control.<emphasis>
+ </emphasis>
+See section 7.1 for a discussion of virtual modifier masks to use in <emphasis> <!-- xref -->
+affect_virtual</emphasis>
+ and <emphasis>
+virtual_values</emphasis>
+.<emphasis>
+ XkbSetServerInternalMods</emphasis>
+ does not wait for a reply from the server. It returns <emphasis>
+True</emphasis>
+ if the request was sent and <emphasis>
+False</emphasis>
+ otherwise.
+</para>
+
+
+</sect2>
+</sect1>
+<sect1 id='the_xkbcontrolsrec_structure'>
+<title>The XkbControlsRec Structure</title>
+
+<para>
+Many of the individual controls described in sections 10.1 through 10.7 may be
+manipulated via convenience functions discussed in those sections. Some of
+them, however, have no convenience functions. The <emphasis>
+XkbControlsRec</emphasis>
+ structure allows the manipulation of one or more of the controls in a single
+operation and to track changes to any of them in conjunction with the <emphasis>
+XkbGetControls</emphasis>
+ and <emphasis>
+XkbSetControls</emphasis>
+ functions. This is the only way to manipulate those controls that have no
+convenience functions.
+</para>
+
+
+<para>
+The <emphasis>
+XkbControlsRec</emphasis>
+ structure is defined as follows:
+</para>
+
+<para>
+<programlisting>
+#define XkbMaxLegalKeyCode 255
+#define XkbPerKeyBitArraySize ((XkbMaxLegalKeyCode+1)/8)
+</programlisting>
+</para>
+<para>
+<programlisting>
+typedef struct {
+ unsigned char mk_dflt_btn; /* default button for keyboard driven mouse */
+ unsigned char num_groups; /* number of keyboard groups */
+ unsigned char groups_wrap; /* how to wrap out-of-bounds groups */
+ XkbModsRec internal; /* defines server internal modifiers */
+ XkbModsRec ignore_lock; /* modifiers to ignore when checking for grab */
+ unsigned int enabled_ctrls; /* 1 bit =&gt; corresponding boolean control enabled */
+ unsigned short repeat_delay; /* ms delay until first repeat */
+ unsigned short repeat_interval; /* ms delay between repeats */
+ unsigned short slow_keys_delay; /* ms minimum time key must be down to be ok */
+ unsigned short debounce_delay; /* ms delay before key reactivated */
+ unsigned short mk_delay; /* ms delay to second mouse motion event */
+ unsigned short mk_interval; /* ms delay between repeat mouse events */
+ unsigned short mk_time_to_max; /* # intervals until constant mouse move */
+ unsigned short mk_max_speed; /* multiplier for maximum mouse speed */
+ short mk_curve; /* determines mouse move curve type */
+ unsigned short ax_options; /* 1 bit =&gt; Access X option enabled */
+ unsigned short ax_timeout; /* seconds until Access X disabled */
+ unsigned short axt_opts_mask; /* 1 bit =&gt; options to reset on Access X timeout */
+ unsigned short axt_opts_values; /* 1 bit =&gt; turn option on, 0=&gt; off */
+ unsigned int axt_ctrls_mask; /* which bits in <emphasis> enabled_ctrls</emphasis> to modify */
+ unsigned int axt_ctrls_values; /* values for new bits in <emphasis> enabled_ctrls</emphasis> */
+ unsigned char per_key_repeat[XkbPerKeyBitArraySize]; /* per key auto repeat */
+} <emphasis>XkbControlsRec</emphasis>, *XkbControlsPtr;
+</programlisting>
+</para>
+
+<para>
+The general-purpose functions that work with the <emphasis>
+XkbControlsRec</emphasis>
+ structure use a mask to specify which controls are to be manipulated. Table
+10.6 lists these controls, the masks used to select them in the general
+function calls (<emphasis>
+which</emphasis>
+ parameter), and the data fields in the <emphasis>
+XkbControlsRec</emphasis>
+ structure that comprise each of the individual controls. Also listed are the
+bit used to turn boolean controls on and off and the section where each control
+is described in more detail.
+</para>
+
+<table frame='none'>
+<title>Xkb Controls</title>
+<tgroup cols='5'>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>Control</entry>
+ <entry>Control Selection Mask (which parameter)</entry>
+ <entry>Relevant XkbControlsRec Data Fields</entry>
+ <entry>Boolean Control enabled_ctrls bit</entry>
+ <entry>Section</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='0'>
+ <entry>AccessXFeedback</entry>
+ <entry>XkbAccessXFeedbackMask</entry>
+ <entry>ax_options: XkbAX_*FBMask</entry>
+ <entry>XkbAccessXFeedbackMask</entry>
+ <entry>10.6.3</entry> <!-- xref -->
+ </row>
+ <row rowsep='0'>
+ <entry>AccessXKeys</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>XkbAccessXKeysMask</entry>
+ <entry>10.6.1</entry> <!-- xref -->
+ </row>
+ <row rowsep='0'>
+ <entry>AccessXTimeout</entry>
+ <entry>XkbAccessXTimeoutMask</entry>
+ <entry>
+ <para>ax_timeout</para>
+ <para>axt_opts_mask</para>
+ <para>axt_opts_values</para>
+ <para>axt_ctrls_mask</para>
+ <para>axt_ctrls_values</para>
+ </entry>
+ <entry>XkbAccessXTimeoutMask</entry>
+ <entry>10.6.2</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>AudibleBell</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>XkbAudibleBellMask</entry>
+ <entry>9.2</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>AutoReset</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>10.1.2</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>BounceKeys</entry>
+ <entry>XkbBounceKeysMask</entry>
+ <entry>debounce_delay</entry>
+ <entry>XkbBounceKeysMask</entry>
+ <entry>10.6.7</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>Detectable-Autorepeat</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>10.3.3</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>EnabledControls</entry>
+ <entry>XkbControlsEnabledMask</entry>
+ <entry>enabled_ctrls</entry>
+ <entry><emphasis>Non-Boolean Control</emphasis></entry>
+ <entry>10.1.1</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>GroupsWrap</entry>
+ <entry>XkbGroupsWrapMask</entry>
+ <entry>groups_wrap</entry>
+ <entry><emphasis>Non-Boolean Control</emphasis></entry>
+ <entry>10.7.1</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>IgnoreGroupLock</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>XkbIgnoreGroupLockMask</entry>
+ <entry>10.7.3</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>IgnoreLockMods</entry>
+ <entry>XkbIgnoreLockModsMask</entry>
+ <entry>ignore_lock</entry>
+ <entry><emphasis>Non-Boolean Control</emphasis></entry>
+ <entry>5.1</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>InternalMods</entry>
+ <entry>XkbInternalModsMask</entry>
+ <entry>internal</entry>
+ <entry><emphasis>Non-Boolean Control</emphasis></entry>
+ <entry>5.1</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>MouseKeys</entry>
+ <entry>XkbMouseKeysMask</entry>
+ <entry>mk_dflt_btn</entry>
+ <entry>XkbMouseKeysMask</entry>
+ <entry>10.5.1</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>MouseKeysAccel</entry>
+ <entry>XkbMouseKeysAccelMask</entry>
+ <entry>
+ <para>mk_delay</para>
+ <para>mk_interval</para>
+ <para>mk_time_to_max</para>
+ <para>mk_max_speed</para>
+ <para>mk_curve</para>
+ </entry>
+ <entry>XkbMouseKeysAccelMask</entry>
+ <entry>10.5.2</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>Overlay1</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>XkbOverlay1Mask</entry>
+ <entry>10.4</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>Overlay2</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>XkbOverlay2Mask</entry>
+ <entry>10.4</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>PerKeyRepeat</entry>
+ <entry>XkbPerKeyRepeatMask</entry>
+ <entry>per_key_repeat</entry>
+ <entry><emphasis>Non-Boolean Control</emphasis></entry>
+ <entry>10.3.1</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>RepeatKeys</entry>
+ <entry>XkbRepeatKeysMask</entry>
+ <entry>
+ <para>repeat_delay</para>
+ <para>repeat_interval</para>
+ </entry>
+ <entry>XkbRepeatKeysMask</entry>
+ <entry>10.3</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>SlowKeys</entry>
+ <entry>XkbSlowKeysMask</entry>
+ <entry>slow_keys_delay</entry>
+ <entry>XkbSlowKeysMask</entry>
+ <entry>10.6.6</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>StickyKeys</entry>
+ <entry>XkbStickyKeysMask</entry>
+ <entry>
+ <para>ax_options:</para>
+ <para>XkbAX_TwoKeysMask</para>
+ <para>XkbAX_LatchToLockMask</para>
+ </entry>
+ <entry>XkbStickyKeysMask</entry>
+ <entry>10.6.8</entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+Table 10.7 shows the actual values for the individual mask bits used to select <!-- xref -->
+controls for modification and to enable and disable the control. Note that the
+same mask bit is used to specify general modifications to the parameters used
+to configure the control (<emphasis>
+which</emphasis>
+), and to enable and disable the control (<emphasis>
+enabled_ctrls</emphasis>
+). The anomalies in the table (no "ok" in column) are for controls that have no
+configurable attributes; and for controls that are not boolean controls and
+therefore cannot be enabled or disabled.
+</para>
+
+<table frame='none'>
+<title>Controls Mask Bits</title>
+<tgroup cols='4'>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>Mask Bit</entry>
+ <entry>which or changed_ctrls</entry>
+ <entry>enabled_ctrls</entry>
+ <entry>Value</entry>
+</row>
+</thead>
+<tbody>
+<row rowsep='0'>
+ <entry>XkbRepeatKeysMask</entry>
+ <entry>ok</entry>
+ <entry>ok</entry>
+ <entry>(1L&lt;&lt;0)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbSlowKeysMask</entry>
+ <entry>ok</entry>
+ <entry>ok</entry>
+ <entry>(1L&lt;&lt;1)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbBounceKeysMask</entry>
+ <entry>ok</entry>
+ <entry>ok</entry>
+ <entry>(1L&lt;&lt;2)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbStickyKeysMask</entry>
+ <entry>ok</entry>
+ <entry>ok</entry>
+ <entry>(1L&lt;&lt;3)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbMouseKeysMask</entry>
+ <entry>ok</entry>
+ <entry>ok</entry>
+ <entry>(1L&lt;&lt;4)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbMouseKeysAccelMask</entry>
+ <entry>ok</entry>
+ <entry>ok</entry>
+ <entry>(1L&lt;&lt;5)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbAccessXKeysMask</entry>
+ <entry>ok</entry>
+ <entry>ok</entry>
+ <entry>(1L&lt;&lt;6)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbAccessXTimeoutMask</entry>
+ <entry>ok</entry>
+ <entry>ok</entry>
+ <entry>(1L&lt;&lt;7)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbAccessXFeedbackMask</entry>
+ <entry>ok</entry>
+ <entry>ok</entry>
+ <entry>(1L&lt;&lt;8)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbAudibleBellMask</entry>
+ <entry></entry>
+ <entry>ok</entry>
+ <entry>(1L&lt;&lt;9)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbOverlay1Mask</entry>
+ <entry></entry>
+ <entry>ok</entry>
+ <entry>(1L&lt;&lt;10)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbOverlay2Mask</entry>
+ <entry></entry>
+ <entry>ok</entry>
+ <entry>(1L&lt;&lt;11)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIgnoreGroupLockMask</entry>
+ <entry></entry>
+ <entry>ok</entry>
+ <entry>(1L&lt;&lt;12)</entry>
+</row>
+<row rowsep='0'>
+ <entry>XkbGroupsWrapMask</entry>
+ <entry>ok</entry>
+ <entry></entry>
+ <entry>(1L&lt;&lt;27)</entry>
+</row>
+<row rowsep='0'>
+ <entry>XkbInternalModsMask</entry>
+ <entry>ok</entry>
+ <entry></entry>
+ <entry>(1L&lt;&lt;28)</entry>
+</row>
+<row rowsep='0'>
+ <entry>XkbIgnoreLockModsMask</entry>
+ <entry>ok</entry>
+ <entry></entry>
+ <entry>(1L&lt;&lt;29)</entry>
+</row>
+<row rowsep='0'>
+ <entry>XkbPerKeyRepeatMask</entry>
+ <entry>ok</entry>
+ <entry></entry>
+ <entry>(1L&lt;&lt;30)</entry>
+</row>
+<row rowsep='0'>
+ <entry>XkbControlsEnabledMask</entry>
+ <entry>ok</entry>
+ <entry></entry>
+ <entry>(1L&lt;&lt;31)</entry>
+</row>
+<row rowsep='0'>
+ <entry>XkbAccessXOptionsMask</entry>
+ <entry>ok</entry>
+ <entry>ok</entry>
+ <entry>(XkbStickyKeysMask | XkbAccessXFeedbackMask)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbAllBooleanCtrlsMask</entry>
+ <entry></entry>
+ <entry>ok</entry>
+ <entry>(0x00001FFF) </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbAllControlsMask</entry>
+ <entry>ok</entry>
+ <entry></entry>
+ <entry>(0xF8001FFF)</entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+The individual fields of the <emphasis>
+XkbControlsRec</emphasis>
+ structure are defined as follows.
+</para>
+
+<sect2>
+<title/>
+<sect3 id='mk_dflt_btn'>
+<title>mk_dflt_btn</title>
+
+<para>
+<emphasis>
+mk_dflt_btn is an attribute of the </emphasis>
+<emphasis>
+MouseKeys</emphasis>
+<emphasis>
+ control</emphasis>
+ (see section 10.5<emphasis> <!-- xref -->
+). It</emphasis>
+ specifies the mouse button number to use for keyboard simulated mouse button
+operations. Its value should be one of the core symbols <emphasis>
+Button1</emphasis>
+ - <emphasis>
+Button5</emphasis>
+.
+</para>
+
+
+</sect3>
+<sect3 id='num_groups'>
+<title>num_groups</title>
+
+<para>
+<emphasis>
+num_groups</emphasis>
+ is not a part of any control, but is reported in the <emphasis>
+XkbControlsRec</emphasis>
+ structure whenever any of its components are fetched from the server. It
+reports the number of groups the particular keyboard configuration uses and is
+computed automatically by the server whenever the keyboard mapping changes.
+</para>
+
+
+</sect3>
+<sect3 id='groups_wrap'>
+<title>groups_wrap</title>
+
+<para>
+<emphasis>
+groups_wrap</emphasis>
+ is an attribute of the <emphasis>
+GroupsWrap</emphasis>
+ control (see section 10.7.1). It specifies the handling of illegal groups on a <!-- xref -->
+global basis. Valid values for <emphasis>
+groups_wrap</emphasis>
+ are shown in Table 10.8.
+</para>
+
+<table frame='none'>
+<title>GroupsWrap options (groups_wrap field)</title>
+<tgroup cols='2'>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>groups_wrap symbolic name</entry>
+ <entry>value</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='0'>
+ <entry>XkbWrapIntoRange</entry>
+ <entry>(0x00)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbClampIntoRange</entry>
+ <entry>(0x40)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbRedirectIntoRange</entry>
+ <entry>(0x80)</entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+When <emphasis>
+groups_wrap</emphasis>
+ is set to <emphasis>
+XkbRedirectIntoRange</emphasis>
+, its four low-order bits specify the index of the group to use.
+</para>
+
+
+</sect3>
+<sect3 id='internal'>
+<title>internal</title>
+
+<para>
+<emphasis>
+internal</emphasis>
+ is an attribute of the <emphasis>
+InternalMods</emphasis>
+ control (see section 10.7.4). It specifies modifiers to be consumed in the <!-- xref -->
+server and not passed on to clients when events are reported. Valid values
+consist of any combination of the eight core modifier bits: <emphasis>
+ShiftMask</emphasis>
+, <emphasis>
+LockMask</emphasis>
+, <emphasis>
+ControlMask</emphasis>
+, <emphasis>
+Mod1Mask</emphasis>
+ - <emphasis>
+Mod5Mask</emphasis>
+.
+</para>
+
+
+</sect3>
+<sect3 id='ignore_lock'>
+<title>ignore_lock</title>
+
+<para>
+<emphasis>
+ignore_lock</emphasis>
+ is an attribute of the <emphasis>
+IgnoreLockMods</emphasis>
+ control (see section 10.7.2). It specifies modifiers to be ignored in grab <!-- xref -->
+calculations. Valid values consist of any combination of the eight core
+modifier bits: <emphasis>
+ShiftMask</emphasis>
+, <emphasis>
+LockMask</emphasis>
+, <emphasis>
+ControlMask</emphasis>
+, <emphasis>
+Mod1Mask</emphasis>
+ - <emphasis>
+Mod5Mask</emphasis>
+.
+</para>
+
+
+</sect3>
+<sect3 id='enabled_ctrls'>
+<title>enabled_ctrls</title>
+
+<para>
+<emphasis>
+enabled_ctrls</emphasis>
+ is an attribute of the <emphasis>
+EnabledControls</emphasis>
+ control (see section 10.1.1). It contains one bit per boolean control. Each <!-- xref -->
+bit determines whether the corresponding control is enabled or disabled; a one
+bit means the control is enabled. The mask bits used to enable these controls
+are listed in Table 10.7, using only those masks with "ok" in the <emphasis>
+enabled_ctrls</emphasis>
+ column.
+</para>
+
+
+</sect3>
+<sect3 id='repeat_delay_and_repeat_interval'>
+<title>repeat_delay and repeat_interval</title>
+
+<para>
+<emphasis>
+repeat_delay</emphasis>
+ and <emphasis>
+repeat_interval</emphasis>
+ are attributes of the <emphasis>
+RepeatKeys</emphasis>
+ control (see section 10.3.2). <emphasis> <!-- xref -->
+repeat_delay</emphasis>
+ is the initial delay before a key begins repeating, in milliseconds; <emphasis>
+repeat_interval</emphasis>
+ is the delay between subsequent key events, in milliseconds.
+</para>
+
+
+</sect3>
+<sect3 id='slow_keys_delay'>
+<title>slow_keys_delay</title>
+
+<para>
+<emphasis>
+slow_keys_delay</emphasis>
+ is an attribute of the <emphasis>
+SlowKeys</emphasis>
+ control (see section 10.6.6). Its value specifies the <emphasis> <!-- xref -->
+SlowKeys</emphasis>
+ acceptance delay period in milliseconds before a key press is accepted by the
+server.
+</para>
+
+
+</sect3>
+<sect3 id='debounce_delay'>
+<title>debounce_delay</title>
+
+<para>
+<emphasis>
+debounce_delay</emphasis>
+ is an attribute of the <emphasis>
+BounceKeys</emphasis>
+ control (see section 10.6.7). Its value specifies the <emphasis> <!-- xref -->
+BounceKeys</emphasis>
+ delay period in milliseconds for which the key is disabled after having been
+pressed before another press of the same key is accepted by the server.
+</para>
+
+
+</sect3>
+<sect3 id='mk_delay_mk_interval_mk_time_to_max_mk_max_speed_and_mk_curve'>
+<title>mk_delay, mk_interval, mk_time_to_max, mk_max_speed, and mk_curve</title>
+
+<para>
+<emphasis>
+mk_delay</emphasis>
+, <emphasis>
+mk_interval</emphasis>
+, <emphasis>
+mk_time_to_max</emphasis>
+, <emphasis>
+mk_max_speed</emphasis>
+, and <emphasis>
+mk_curve</emphasis>
+ are attributes of the <emphasis>
+MouseKeysAccel</emphasis>
+ control. Refer to section 10.5.2 for a description of these fields and the <!-- xref -->
+units involved.
+</para>
+
+
+</sect3>
+<sect3 id='ax_options'>
+<title>ax_options</title>
+
+<para>
+The <emphasis>
+ax_options</emphasis>
+ field contains attributes used to configure two different controls, the
+<emphasis>
+StickyKeys</emphasis>
+ control (see section 10.6.8) and the <emphasis> <!-- xref -->
+AccessXFeedback</emphasis>
+ control (see section 10.6.3). The <emphasis> <!-- xref -->
+ax_options</emphasis>
+ field is a bitmask and may include any combination of the bits defined in
+Table 10.9. <!-- xref -->
+</para>
+
+<table frame='none'>
+<title>Access X Enable/Disable Bits (ax_options field)</title>
+<tgroup cols='3'>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>Access X Control</entry>
+ <entry>ax_options bit</entry>
+ <entry>value</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='0'>
+ <entry>AccessXFeedback</entry>
+ <entry>XkbAX_SKPressFBMask</entry>
+ <entry>(1L&lt;&lt;0)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>XkbAX_SKAcceptFBMask</entry>
+ <entry>(1L &lt;&lt; 1)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>XkbAX_FeatureFBMask</entry>
+ <entry>(1L &lt;&lt; 2)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>XkbAX_SlowWarnFBMask</entry>
+ <entry>(1L &lt;&lt; 3)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>XkbAX_IndicatorFBMask</entry>
+ <entry>(1L &lt;&lt; 4)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>XkbAX_StickyKeysFBMask</entry>
+ <entry>(1L &lt;&lt; 5)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>XkbAX_SKReleaseFBMask</entry>
+ <entry>(1L &lt;&lt; 8)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>XkbAX_SKRejectFBMask</entry>
+ <entry>(1L &lt;&lt; 9)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>XkbAX_BKRejectFBMask</entry>
+ <entry>(1L &lt;&lt; 10)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>XkbAX_DumbBellFBMask</entry>
+ <entry>(1L &lt;&lt; 11)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>StickyKeys</entry>
+ <entry>XkbAX_TwoKeysMask</entry>
+ <entry>(1L &lt;&lt; 6)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>XkbAX_LatchToLockMask</entry>
+ <entry>(1L &lt;&lt; 7)</entry>
+ </row>
+ <row rowsep='0'>
+ <entry></entry>
+ <entry>XkbAX_AllOptionsMask</entry>
+ <entry>(0xFFF)</entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+The fields pertaining to each control are relevant only when the control is
+enabled (<emphasis>
+XkbAccessXFeedbackMask</emphasis>
+ or <emphasis>
+XkbStickyKeysMask</emphasis>
+ bit is turned on in the <emphasis>
+enabled_cntrls</emphasis>
+ field).
+</para>
+
+
+<para>
+Xkb provides a set of convenience macros for working with the <emphasis>
+ax_options</emphasis>
+ field of an <emphasis>
+XkbControlsRec</emphasis>
+ structure:
+</para>
+
+<para><programlisting>
+#define <emphasis>XkbAX_NeedOption</emphasis>
+(c,w) ((c)-&gt;ax_options&amp;(w))
+</programlisting></para>
+
+<para>
+The <emphasis>
+XkbAX_NeedOption</emphasis>
+ macro is useful for determining whether a particular AccessX option is enabled
+or not. It accepts a pointer to an <emphasis>
+XkbControlsRec</emphasis>
+ structure and a valid mask bit from Table 10.9. If the specified mask bit in
+the <emphasis>
+ax_options</emphasis>
+ field of the controls structure is set, the macro returns the mask bit.
+Otherwise, it returns zero. Thus,
+</para>
+
+
+<para>
+XkbAX_NeedOption(ctlrec, XkbAX_LatchToLockMask)
+</para>
+
+
+<para>
+is nonzero if the latch to lock transition for latching keys is enabled, and
+zero if it is disabled. Note that <emphasis>
+XkbAX_NeedOption</emphasis>
+ only determines whether or not the particular capability is configured to
+operate; the <emphasis>
+XkbAccessXFeedbackMask</emphasis>
+ bit must also be turned on in <emphasis>
+enabled_ctrls</emphasis>
+ for the capability to actually be functioning.
+</para>
+
+<para><programlisting>
+#define <emphasis>XkbAX_AnyFeedback</emphasis>
+(c) ((c)-&gt;enabled_ctrls&amp;XkbAccessXFeedbackMask)
+</programlisting></para>
+
+<para>
+The <emphasis>
+XkbAX_AnyFeeback</emphasis>
+ macro accepts a pointer to an <emphasis>
+XkbControlsRec</emphasis>
+ structure and tells whether the <emphasis>
+AccessXFeedback</emphasis>
+ control is enabled or not. If the <emphasis>
+AccessXFeedback</emphasis>
+ control is enabled, the macro returns <emphasis>
+XkbAccessXFeedbackMask</emphasis>
+. Otherwise, it returns zero.
+</para>
+
+<para><programlisting>
+#define <emphasis>XkbAX_NeedFeedback</emphasis>
+(c,w) (XkbAX_AnyFeedback(c)&amp;&amp;XkbAX_NeedOption(c,w))
+</programlisting></para>
+
+<para>
+The <emphasis>
+XkbAX_NeedFeedback</emphasis>
+ macro is useful for determining if both the <emphasis>
+AccessXFeedback</emphasis>
+ control and a particular AccessX feedback option are enabled. The macro
+accepts a pointer to an <emphasis>
+XkbControlsRec</emphasis>
+ structure and a feedback option from the table above. If both the <emphasis>
+AccessXFeedback</emphasis>
+ control and the specified feedback option are enabled, the macro returns
+<emphasis>
+True</emphasis>
+. Otherwise it returns <emphasis>
+False</emphasis>
+.
+</para>
+
+
+</sect3>
+<sect3
+id='ax_timeout_axt_opts_mask_axt_opts_values_axt_ctrls_mask_and_axt_ctrls_values'>
+<title>ax_timeout, axt_opts_mask, axt_opts_values, axt_ctrls_mask, and axt_ctrls_values</title>
+
+<para>
+<emphasis>
+ax_timeout</emphasis>
+, <emphasis>
+act_opts_mask</emphasis>
+, <emphasis>
+axt_opts_values</emphasis>
+, <emphasis>
+axt_ctrls_mask</emphasis>
+, and <emphasis>
+axt_ctrls_values</emphasis>
+ are attributes of the <emphasis>
+AccessXTimeout</emphasis>
+ control. Refer to section 10.6.2 for a description of these fields and the <!-- xref -->
+units involved.
+</para>
+
+
+</sect3>
+<sect3 id='per_key_repeat'>
+<title>per_key_repeat</title>
+
+<para>
+The <emphasis>
+per_key_repeat</emphasis>
+ field mirrors the <emphasis>
+auto_repeats</emphasis>
+ field of the core protocol <emphasis>
+XKeyboardState</emphasis>
+ structure: changing the <emphasis>
+auto_repeats</emphasis>
+ field automatically changes <emphasis>
+per_key_repeat</emphasis>
+ and vice versa. It is provided for convenience and to reduce protocol traffic.
+For example, to obtain the individual repeat key behavior as well as the repeat
+delay and rate, use <emphasis>
+XkbGetControls</emphasis>
+. If the <emphasis>
+per_key_repeat</emphasis>
+ were not in this structure, you would have to call both <emphasis>
+XGetKeyboardControl</emphasis>
+ and <emphasis>
+XkbGetControls</emphasis>
+ to get this information. The bits correspond to keycodes. The first seven keys
+(keycodes 1-7) are indicated in <emphasis>
+per_key_repeat</emphasis>
+[0], with bit position 0 (low order) corresponding to the fictitious keycode 0.
+Following array elements correspond to 8 keycodes per element. A 1 bit
+indicates that the key is a repeating key.
+</para>
+
+
+</sect3>
+</sect2>
+</sect1>
+<sect1 id='querying_controls'>
+<title>Querying Controls</title>
+
+<para>
+Use <emphasis>
+XkbGetControls</emphasis>
+ to find the current state of Xkb server controls.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Status <emphasis>
+XkbGetControls</emphasis>
+(<emphasis>
+display, which, xkb)</emphasis>
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ display</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned long<emphasis>
+ which</emphasis>
+; /* mask of controls requested */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr<emphasis>
+ xkb</emphasis>
+; /* keyboard description for controls information*/
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbGetControls</emphasis>
+ queries the server for the requested control information, waits for a reply,
+and then copies the server’s values for the requested information into the
+<emphasis>
+ctrls</emphasis>
+ structure of the <emphasis>
+xkb</emphasis>
+ argument. Only those components specified by the <emphasis>
+which</emphasis>
+ parameter are copied. Valid values for <emphasis>
+which</emphasis>
+ are any combination of the masks listed in Table 10.7 that have "ok" in the
+<emphasis>
+which</emphasis>
+ column.
+</para>
+
+
+<para>
+If <emphasis>
+xkb</emphasis>
+-&gt;<emphasis>
+ctrls </emphasis>
+is <emphasis>
+NULL</emphasis>
+, <emphasis>
+XkbGetControls</emphasis>
+ allocates and initializes it before obtaining the values specified by
+<emphasis>
+which</emphasis>
+. If <emphasis>
+xkb</emphasis>
+-&gt;<emphasis>
+ctrls</emphasis>
+ is not <emphasis>
+NULL</emphasis>
+, <emphasis>
+XkbGetControls</emphasis>
+ modifies only those portions of <emphasis>
+xkb</emphasis>
+-&gt;<emphasis>
+ctrls</emphasis>
+ corresponding to the values specified by <emphasis>
+which</emphasis>
+.
+</para>
+
+
+<para>
+<emphasis>
+XkbGetControls</emphasis>
+ returns <emphasis>
+Success</emphasis>
+ if successful; otherwise, it returns <emphasis>
+BadAlloc</emphasis>
+ if it cannot obtain sufficient storage, <emphasis>
+BadMatch</emphasis>
+ if <emphasis>
+xkb</emphasis>
+ is <emphasis>
+NULL</emphasis>
+ or <emphasis>
+which</emphasis>
+ is empty, or <emphasis>
+BadImplementation</emphasis>
+.
+</para>
+
+
+<para>
+To free the <emphasis>
+ctrls</emphasis>
+ member of a keyboard description, use <emphasis>
+XkbFreeControls</emphasis>
+ (see section 10.12)
+</para>
+
+
+<para>
+The <emphasis>
+num_groups</emphasis>
+ field in the <emphasis>
+ctrls</emphasis>
+ structure is always filled in by <emphasis>
+XkbGetControls</emphasis>
+, regardless of which bits are selected by <emphasis>
+which</emphasis>
+.
+</para>
+
+
+</sect1>
+<sect1 id='changing_controls'>
+<title>Changing Controls</title>
+
+<para>
+There are two ways to make changes to controls: either change a local copy
+keyboard description and call <emphasis>
+XkbSetControls</emphasis>
+, or, to reduce network traffic, use an<emphasis>
+ XkbControlsChangesRec</emphasis>
+ structure and call <emphasis>
+XkbChangeControls</emphasis>
+.
+</para>
+
+
+<para>
+To change the state of one or more controls, first modify the <emphasis>
+ctrls</emphasis>
+ structure in a local copy of the keyboard description and then use <emphasis>
+XkbSetControls</emphasis>
+ to copy those changes to the X server.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbSetControls</emphasis>
+(<emphasis>
+display, which, xkb)</emphasis>
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display *<emphasis>
+ display</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned long <emphasis>
+ which </emphasis>
+; /* mask of controls to change */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr <emphasis>
+xkb</emphasis>
+; /* <emphasis>
+ctrls</emphasis>
+ field contains new values to be set */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+For each bit that is set in the <emphasis>
+which</emphasis>
+ parameter, <emphasis>
+XkbSetControls</emphasis>
+ sends the corresponding values from the <emphasis>
+xkb</emphasis>
+-&gt;<emphasis>
+ctrls</emphasis>
+ field to the server. Valid values for <emphasis>
+which</emphasis>
+ are any combination of the masks listed in Table 10.7 that have "ok" in the
+<emphasis>
+which</emphasis>
+ column.
+</para>
+
+
+<para>
+If <emphasis>
+xkb</emphasis>
+-&gt;<emphasis>
+ctrls</emphasis>
+ is <emphasis>
+NULL</emphasis>
+, the server does not support a compatible version of Xkb, or the Xkb extension
+has not been properly initialized, <emphasis>
+XkbSetControls</emphasis>
+ returns <emphasis>
+False</emphasis>
+. Otherwise, it sends the request to the X server and returns <emphasis>
+True</emphasis>
+.
+</para>
+
+
+<para>
+Note that changes to attributes of controls in the <emphasis>
+XkbControlsRec</emphasis>
+ structure are apparent only when the associated control is enabled, although
+the corresponding values are still updated in the X server. For example, the
+<emphasis>
+repeat_delay</emphasis>
+ and <emphasis>
+repeat_interval</emphasis>
+ fields are ignored unless the <emphasis>
+RepeatKeys</emphasis>
+ control is enabled (that is, the X server’s equivalent of <emphasis>
+xkb-&gt;ctrls</emphasis>
+ has <emphasis>
+XkbRepeatKeyMask</emphasis>
+ set in <emphasis>
+enabled_ctrls</emphasis>
+). It is permissible to modify the attributes of a control in one call to
+XkbSetControls and enable the control in a subsequent call. See section 10.1.1 <!-- xref -->
+for more information on enabling and disabling controls.
+</para>
+
+
+<para>
+Note that the <emphasis>
+enabled_ctrls</emphasis>
+ field is itself a control — the <emphasis>
+EnabledControls</emphasis>
+ control. As such, to set a specific configuration of enabled and disabled
+boolean controls, you must set <emphasis>
+enabled_ctrls</emphasis>
+ to the appropriate bits to enable only the controls you want and disable all
+others, then specify the <emphasis>
+XkbControlsEnabledMask</emphasis>
+ in a call to <emphasis>
+XkbSetControls</emphasis>
+. Because this is somewhat awkward if all you want to do is enable and disable
+controls, and not modify any of their attributes, a convenience function is
+also provided for this purpose (<emphasis>
+XkbChangeEnabledControls</emphasis>
+, section 10.1.1). <!-- xref -->
+</para>
+
+
+<sect2 id='the_xkbcontrolschangesrec_structure'>
+<title>The XkbControlsChangesRec Structure</title>
+
+<para>
+The <emphasis>
+XkbControlsChangesRec</emphasis>
+ structure allows applications to track modifications to an <emphasis>
+XkbControlsRec</emphasis>
+ structure and thereby reduce the amount of traffic sent to the server. The
+same <emphasis>
+XkbControlsChangesRec</emphasis>
+ structure may be used in several successive modifications to the same
+<emphasis>
+XkbControlsRec</emphasis>
+ structure, then subsequently used to cause all of the changes, and only the
+changes, to be propagated to the server. The <emphasis>
+XkbControlsChangesRec</emphasis>
+ structure is defined as follows:
+</para>
+
+<para><programlisting>
+typedef struct _XkbControlsChanges {
+ unsigned int changed_ctrls; /* bits indicating changed control data */
+ unsigned int enabled_ctrls_changes; /* bits indicating enabled/disabled controls */
+ Bool num_groups_changed; /* <emphasis> True</emphasis> if
+ number of keyboard groups changed */
+} <emphasis>XkbControlsChangesRec</emphasis>,*XkbControlsChangesPtr;
+</programlisting></para>
+
+<para>
+The <emphasis>
+changed_ctrls</emphasis>
+ field is a mask specifying which logical sets of data in the controls
+structure have been modified. In this context, modified means <emphasis>
+set</emphasis>
+, that is, if a value is set to the same value it previously contained, it has
+still been modified, and is noted as changed. Valid values for <emphasis>
+changed_ctrls</emphasis>
+ are any combination of the masks listed in Table 10.7 that have "ok" in the
+<emphasis>
+changed_ctrls</emphasis>
+ column. Setting a bit implies the corresponding data fields from the "Relevant
+XkbControlsRec Data Fields" column in Table 10.6 have been modified. The
+<emphasis>
+enabled_ctrls_changes</emphasis>
+ field specifies which bits in the <emphasis>
+enabled_ctrls</emphasis>
+ field have changed. If the number of keyboard groups has changed, the
+<emphasis>num_groups_changed</emphasis>
+ field is set to <emphasis>True</emphasis>.
+</para>
+
+
+<para>
+If you have an Xkb description with controls that have been modified and an
+<emphasis>
+XkbControlsChangesRec</emphasis>
+ that describes the changes that have been made, the <emphasis>
+XkbChangeControls</emphasis>
+ function provides a flexible method for updating the controls in a server to
+match those in the changed keyboard description.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbChangeControls</emphasis>
+(<emphasis>
+dpy, xkb, changes</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+dpy</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr <emphasis>
+xkb</emphasis>
+; /* keyboard description with changed <emphasis>
+xkb-&gt;ctrls</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbControlsChangesPtr <emphasis>
+changes</emphasis>
+; /* which parts of <emphasis>
+xkb-&gt;ctrls</emphasis>
+ have changed */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbChangeControls</emphasis>
+ copies any controls fields specified by <emphasis>
+changes</emphasis>
+ from the keyboard description controls structure, <emphasis>
+xkb</emphasis>
+-&gt;<emphasis>
+ctrls</emphasis>
+, to the server specified by <emphasis>
+dpy</emphasis>
+.
+</para>
+
+
+</sect2>
+</sect1>
+<sect1 id='tracking_changes_to_keyboard_controls'>
+<title>Tracking Changes to Keyboard Controls</title>
+
+<para>
+Whenever a field in the controls structure changes in the server’s keyboard
+description, the server sends an <emphasis>
+XkbControlsNotify</emphasis>
+ event to all interested clients.To receive <emphasis>
+XkbControlsNotify</emphasis>
+ events under all possible conditions, use <emphasis>
+XkbSelectEvents</emphasis>
+ (see section 4.3) and pass <emphasis>
+XkbControlsNotifyMask</emphasis>
+ in both <emphasis>
+bits_to_change</emphasis>
+ and <emphasis>
+values_for_bits</emphasis>
+.
+</para>
+
+
+<para>
+To receive <emphasis>
+XkbControlsNotify</emphasis>
+ events only under certain conditions, use <emphasis>
+XkbSelectEventDetails</emphasis>
+ using <emphasis>
+XkbControlsNotify</emphasis>
+ as the <emphasis>
+event_type</emphasis>
+ and specifying the desired state changes in <emphasis>
+bits_to_change</emphasis>
+ and <emphasis>
+values_for_bits</emphasis>
+ using mask bits from Table 10.7. <!-- xref -->
+</para>
+
+
+<para>
+The structure for the <emphasis>
+XkbControlsNotify</emphasis>
+ event is defined as follows:
+</para>
+
+<para><programlisting>
+typedef struct {
+ int type; /* Xkb extension base event code */
+ unsigned long serial; /* X server serial number for event */
+ Bool send_event; /* <emphasis> True</emphasis> =&gt; synthetically generated */
+ Display * display; /* server connection where event generated */
+ Time time; /* server time when event generated */
+ int xkb_type; /* <emphasis> XkbCompatMapNotify</emphasis> */
+ int device; /* Xkb device ID, will not be <emphasis> XkbUseCoreKbd</emphasis> */
+ unsigned int changed_ctrls; /* bits indicating which controls data have changed*/
+ unsigned int enabled_ctrls; /* controls currently enabled in server */
+ unsigned int enabled_ctrl_changes; /* bits indicating enabled/disabled controls */
+ int num_groups; /* current number of keyboard groups */
+ KeyCode keycode; /* != 0 =&gt; keycode of key causing change */
+ char event_type; /* Type of event causing change */
+ char req_major; /* major event code of event causing change */
+ char req_minor; /* minor event code of event causing change */
+} <emphasis>XkbControlsNotifyEvent</emphasis>;
+</programlisting></para>
+
+<para>
+The <emphasis>
+changed_ctrls</emphasis>
+ field specifies the controls components that have changed and consists of bits
+taken from the masks defined in Table 10.7 with "ok" in the <emphasis>
+changed_ctrls</emphasis>
+ column.
+</para>
+
+
+<para>
+The controls currently enabled in the server are reported in the <emphasis>
+enabled_ctrls</emphasis>
+ field. If any controls were just enabled or disabled (that is, the contents of
+the <emphasis>
+enabled_ctrls</emphasis>
+ field changed), they are flagged in the <emphasis>
+enabled_ctrl_changes</emphasis>
+ field. The valid bits for these fields are the masks listed in Table 10.7 with
+"ok" in the <emphasis>
+enabled_ctrls</emphasis>
+ column. The <emphasis>
+num_groups</emphasis>
+ field reports the number of groups bound to the key belonging to the most
+number of groups and is automatically updated when the keyboard mapping changes.
+</para>
+
+
+<para>
+If the change was caused by a request from a client, the <emphasis>
+keycode</emphasis>
+ and <emphasis>
+event_type</emphasis>
+ fields are set to <emphasis>
+zero </emphasis>
+and the <emphasis>
+req_major</emphasis>
+ and <emphasis>
+req_minor</emphasis>
+ fields identify the request. The <emphasis>
+req_major</emphasis>
+ value is the same as the major extension opcode. Otherwise, <emphasis>
+event_type</emphasis>
+ is set to the type of event that caused the change (one of <emphasis>
+KeyPress</emphasis>
+, <emphasis>
+KeyRelease</emphasis>
+, <emphasis>
+DeviceKeyPress</emphasis>
+, <emphasis>
+DeviceKeyRelease</emphasis>
+, <emphasis>
+ButtonPress</emphasis>
+ or <emphasis>
+ButtonRelease</emphasis>
+), and <emphasis>
+req_major</emphasis>
+ and <emphasis>
+req_minor</emphasis>
+ are undefined. If <emphasis>
+event_type</emphasis>
+ is <emphasis>
+KeyPress</emphasis>
+, <emphasis>
+KeyRelease</emphasis>
+, <emphasis>
+DeviceKeyPress</emphasis>
+, or <emphasis>
+DeviceKeyRelease</emphasis>
+, the <emphasis>
+keycode</emphasis>
+ field is set to the key that caused the change. If <emphasis>
+event_type</emphasis>
+ is <emphasis>
+ButtonPress</emphasis>
+ or <emphasis>
+ButtonRelease</emphasis>
+, <emphasis>
+keycode</emphasis>
+ contains the button number.
+</para>
+
+
+<para>
+When a client receives an <emphasis>
+XkbControlsNotify</emphasis>
+ event, it can note the changes in a changes structure using <emphasis>
+XkbNoteControlsChanges</emphasis>
+.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+void <emphasis>
+XkbNoteControlsChanges</emphasis>
+(<emphasis>
+changes</emphasis>
+,<emphasis>
+ new</emphasis>
+,<emphasis>
+ wanted</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbControlsChangesPtr <emphasis>
+ changes</emphasis>
+; /* records changes indicated by new */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbControlsNotifyEvent * <emphasis>
+ new</emphasis>
+; /* tells which things have changed */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+ wanted</emphasis>
+; /* tells which parts of new to record in changes */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+The <emphasis>
+wanted</emphasis>
+ parameter is a bitwise inclusive OR of bits taken from the set of masks
+specified in Table 10.7 with "ok" in the <emphasis>
+changed_ctrls</emphasis>
+ column. <emphasis>
+XkbNoteControlsChanges</emphasis>
+ copies any changes reported in <emphasis>
+new</emphasis>
+ and specified in <emphasis>
+wanted</emphasis>
+ into the changes record specified by <emphasis>
+old</emphasis>
+.
+</para>
+
+
+<para>
+Use <emphasis>
+XkbGetControlsChanges</emphasis>
+ to update a local copy of a keyboard description with the changes previously
+noted by one or more calls to <emphasis>
+XkbNoteControlsChanges.</emphasis>
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Status <emphasis>
+XkbGetControlsChanges</emphasis>
+(<emphasis>
+dpy</emphasis>
+,<emphasis>
+ xkb</emphasis>
+,<emphasis>
+ changes</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+dpy</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr <emphasis>
+xkb</emphasis>
+; /* <emphasis>
+xkb-&gt;ctrls</emphasis>
+ will be updated */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbNameChangesPtr <emphasis>
+changes</emphasis>
+; /* indicates which parts of <emphasis>
+xkb-&gt;ctrls</emphasis>
+ to update */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbGetControlsChanges</emphasis>
+ examines the <emphasis>
+changes</emphasis>
+ parameter, queries the server for the necessary information, and copies the
+results into the <emphasis>
+xkb</emphasis>
+-&gt;<emphasis>
+ctrls</emphasis>
+ keyboard description. If the <emphasis>
+ctrls</emphasis>
+ field of <emphasis>
+xkb</emphasis>
+ is <emphasis>
+NULL</emphasis>
+, <emphasis>
+XkbGetControlsChanges</emphasis>
+ allocates and initializes it. To free the <emphasis>
+ctrls</emphasis>
+ field, use <emphasis>
+XkbFreeControls</emphasis>
+ (see section 10.12). <!-- xref -->
+</para>
+
+
+<para>
+<emphasis>
+XkbGetControlsChanges</emphasis>
+ returns <emphasis>
+Success</emphasis>
+ if successful and can generate <emphasis>
+BadAlloc</emphasis>
+, <emphasis>
+BadImplementation,</emphasis>
+ and <emphasis>
+BadMatch</emphasis>
+ errors.
+</para>
+
+
+</sect1>
+<sect1 id='allocating_and_freeing_an_xkbcontrolsrec'>
+<title>Allocating and Freeing an XkbControlsRec</title>
+
+<para>
+The need to allocate an <emphasis>
+XkbControlsRec</emphasis>
+ structure seldom arises; Xkb creates one when an application calls <emphasis>
+XkbGetControls</emphasis>
+ or a related function. For those situations where there is not an <emphasis>
+XkbControlsRec</emphasis>
+ structure allocated in the <emphasis>
+XkbDescRec</emphasis>
+, allocate one by calling <emphasis>
+XkbAllocControls</emphasis>
+.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Status <emphasis>
+XkbAllocControls</emphasis>
+(<emphasis>
+xkb, which</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr <emphasis>
+ xkb</emphasis>
+; /* Xkb description in which to allocate ctrls rec */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ which</emphasis>
+; /* mask of components of <emphasis>
+ctrls</emphasis>
+ to allocate */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbAllocControls</emphasis>
+ allocates the <emphasis>
+ctrls</emphasis>
+ field of the <emphasis>
+xkb</emphasis>
+ parameter, initializes all fields to zero, and returns <emphasis>
+Success</emphasis>
+. If the <emphasis>
+ctrls</emphasis>
+ field is not <emphasis>
+NULL</emphasis>
+, <emphasis>
+XkbAllocControls</emphasis>
+ simply returns <emphasis>
+Success</emphasis>
+. If <emphasis>
+xkb</emphasis>
+ is <emphasis>
+NULL</emphasis>
+, <emphasis>
+XkbAllocControls</emphasis>
+ reports a <emphasis>
+BadMatch</emphasis>
+ error. If the <emphasis>
+ctrls</emphasis>
+ field could not be allocated, it reports a <emphasis>
+BadAlloc</emphasis>
+ error.
+</para>
+
+
+<para>
+The <emphasis>
+which</emphasis>
+ mask specifies the individual fields of the <emphasis>
+ctrls</emphasis>
+ structure to be allocated and can contain any of the valid masks defined in
+Table 10.7. Because none of the currently existing controls have any structures
+associated with them, which is currently of little practical value in this call.
+</para>
+
+
+<para>
+To free memory used by the <emphasis>
+ctrls</emphasis>
+ member of an <emphasis>
+XkbDescRec </emphasis>
+structure, use <emphasis>
+XkbFreeControls:</emphasis>
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+void <emphasis>
+XkbFreeControls</emphasis>
+(<emphasis>
+xkb, which, free_all</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr<emphasis>
+ xkb</emphasis>
+; /* Xkb description in which to free controls components */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+which</emphasis>
+; /* mask of components of <emphasis>
+ctrls</emphasis>
+ to free */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Bool <emphasis>
+free_all</emphasis>
+; /* <emphasis>
+True</emphasis>
+ =&gt; free everything + ctrls itself */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbFreeControls</emphasis>
+ frees the specified components of the <emphasis>
+ctrls</emphasis>
+ field in the <emphasis>
+xkb</emphasis>
+ keyboard description and sets the corresponding structure component values to
+<emphasis>
+NULL</emphasis>
+ or <emphasis>
+zero</emphasis>
+. The <emphasis>
+which</emphasis>
+ mask specifies the fields of <emphasis>
+ctrls</emphasis>
+ to be freed and can contain any of the controls components specified in Table
+10.7.
+</para>
+
+
+<para>
+If <emphasis>
+free_all</emphasis>
+ is <emphasis>
+True</emphasis>
+, <emphasis>
+XkbFreeControls</emphasis>
+ frees every non-<emphasis>
+NULL</emphasis>
+ structure component in the controls, frees the <emphasis>
+XkbControlsRec</emphasis>
+ structure referenced by the <emphasis>
+ctrls</emphasis>
+ member of <emphasis>
+xkb</emphasis>
+, and sets <emphasis>
+ctrls</emphasis>
+ to <emphasis>
+NULL.</emphasis>
+</para>
+
+</sect1>
+<sect1 id='the_miscellaneous_per_client_controls'>
+<title>The Miscellaneous Per-client Controls</title>
+
+<para>
+You can configure the boolean per-client controls which affect the state
+reported in button and key events. See section 12.1.1, 12.3, 12.5, and 16.3.11 <!-- xref -->
+of the XKB Protocol specification for more details.
+</para>
+
+
+<para>
+To get the current values of the <emphasis>
+per-client</emphasis>
+ controls, use <emphasis>
+XkbGetPerClientControls</emphasis>
+.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbGetPerClientControls</emphasis>
+(<emphasis>
+dpy</emphasis>
+, <emphasis>
+ctrls</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+dpy</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int * <emphasis>
+ctrls</emphasis>
+; /* 1 bit =&gt; corresponding control is on */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbGetPerClientControls</emphasis>
+ backfills <emphasis>
+ctrls</emphasis>
+ with the <emphasis>
+per-client </emphasis>
+control attributes for this particular client. It returns <emphasis>
+True</emphasis>
+ if successful, and <emphasis>
+False</emphasis>
+ otherwise.
+</para>
+
+
+<para>
+To change the current values of the <emphasis>
+per-client</emphasis>
+ control attributes, use <emphasis>
+XkbSetPerClientControls.</emphasis>
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbSetPerClientControls</emphasis>
+(<emphasis>
+dpy</emphasis>
+, <emphasis>
+ctrls</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+dpy</emphasis>
+; /* connection to X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+change</emphasis>
+; /* 1 bit =&gt; change control */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int * <emphasis>
+value</emphasis>
+; /* 1 bit =&gt; control on */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbSetPerClientControls changes the per-client values for the controls selected
+by </emphasis>
+<emphasis>
+change to the corresponding value in value. Legal values for change and value
+are: XkbPCF_GrabsUseXKBStateMask, XkbPCF_LookupStateWhenGrabbed, and
+XkbPCF_SendEventUsesXKBState. More than one control may be changed at one time
+by OR-ing the values together. XkbSetPerClientControls backfills value with the
+</emphasis>
+<emphasis>
+per-client </emphasis>
+<emphasis>
+control attributes for this particular client. </emphasis>
+It returns <emphasis>
+True</emphasis>
+ if successful, and <emphasis>
+False</emphasis>
+ otherwise.
+</para>
+
+</sect1>
+</chapter>