ch10.xml   [plain text]


<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>