diff options
Diffstat (limited to 'libX11/specs/XKB/ch10.xml')
-rw-r--r-- | libX11/specs/XKB/ch10.xml | 5347 |
1 files changed, 5347 insertions, 0 deletions
diff --git a/libX11/specs/XKB/ch10.xml b/libX11/specs/XKB/ch10.xml new file mode 100644 index 000000000..76acd032f --- /dev/null +++ b/libX11/specs/XKB/ch10.xml @@ -0,0 +1,5347 @@ +<chapter id='keyboard_controls'> +<title>Keyboard Controls</title> + +<para> +The Xkb extension is composed of two parts: a server extension, and a +client-side X library extension. This chapter discusses functions used to +modify controls effecting the behavior of the server portion of the Xkb +extension. Chapter 11 discusses functions used to modify controls that affect +only the behavior of the client portion of the extension; those controls are +known as Library Controls. +</para> + + +<para> +Xkb contains control features that affect the entire keyboard, known as global +keyboard controls. Some of the controls may be selectively enabled and +disabled; these controls are known as the <emphasis> +Boolean Controls</emphasis> +. Boolean Controls can be turned on or off under program control and can also +be automatically set to an on or off condition when a client program exits. The +remaining controls, known as the <emphasis> +Non-Boolean Controls</emphasis> +, are always active. The<emphasis> + XkbControlsRec</emphasis> + structure describes the current state of most of the global controls and the +attributes effecting the behavior of each of these Xkb features. This chapter +describes the Xkb controls and how to manipulate them. +</para> + + +<para> +There are two possible components for each of the Boolean Controls: attributes +describing how the control should work, and a state describing whether the +behavior as a whole is enabled or disabled. The attributes and state for most +of these controls are held in the <emphasis> +XkbControlsRec</emphasis> + structure (see section 10.8). +</para> + + +<para> +You can manipulate the Xkb controls individually, via convenience functions, or +as a whole. To treat them as a group, modify an <emphasis> +XkbControlsRec</emphasis> + structure to describe all of the changes to be made, and then pass that +structure and appropriate flags to an Xkb library function, or use a <emphasis> +XkbControlsChangesRec</emphasis> + (see section 10.10.1) to reduce network traffic. When using a convenience +function to manipulate one control individually, you do not use an <emphasis> +XkbControlsRec</emphasis> + structure directly. +</para> + + +<para> +The Xkb controls are grouped as shown in Table 10.1. <!-- xref --> +</para> + +<table frame='none'> +<title>Xkb Keyboard Controls</title> +<tgroup cols='3'> +<colspec colsep='0'/> +<colspec colsep='0'/> +<colspec colsep='0'/> +<thead> +<row rowsep='0'> + <entry>Type of Control</entry> + <entry>Control Name</entry> + <entry>Boolean Control?</entry> + </row> +</thead> +<tbody> + <row rowsep='0'> + <entry>Controls for enabling and disabling other controls</entry> + <entry>EnabledControls</entry> + <entry>No</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>AutoReset</entry> + <entry>No</entry> + </row> + <row rowsep='0'> + <entry>Control for bell behavior</entry> + <entry>AudibleBell</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry>Controls for repeat key behavior</entry> + <entry>PerKeyRepeat</entry> + <entry>No</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>RepeatKeys</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>DetectableAutorepeat</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry>Controls for keyboard overlays</entry> + <entry>Overlay1</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>Overlay2</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry>Controls for using the mouse from the keyboard</entry> + <entry>MouseKeys</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>MouseKeysAccel</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry>Controls for better keyboard access by </entry> + <entry>AccessXFeedback</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry>physically impaired persons</entry> + <entry>AccessXKeys</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>AccessXTimeout</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>BounceKeys</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>SlowKeys</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>StickyKeys</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry>Controls for general keyboard mapping</entry> + <entry>GroupsWrap</entry> + <entry>No</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>IgnoreGroupLock</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>IgnoreLockMods</entry> + <entry>No</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>InternalMods</entry> + <entry>No</entry> + </row> + <row rowsep='0'> + <entry>Miscellaneous per-client controls</entry> + <entry>GrabsUseXKBState</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>LookupStateWhenGrabbed</entry> + <entry>Boolean</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>SendEventUsesXKBState</entry> + <entry>Boolean</entry> + </row> +</tbody> +</tgroup> +</table> + +<para> +The individual categories and controls are described first, together with +functions for manipulating them. A description of the <emphasis> +XkbControlsRec</emphasis> + structure and the general functions for dealing with all of the controls at +once follow at the end of the chapter. +</para> + +<sect1 id='controls_that_enable_and_disable_other_controls'> +<title>Controls that Enable and Disable Other Controls</title> + +<para> +Enable and disable the boolean controls under program control by using the +<emphasis> +EnabledControls</emphasis> + control; enable and disable them upon program exit by configuring the +<emphasis> +AutoReset</emphasis> + control. +</para> + + +<sect2 id='the_enabledcontrols_control'> +<title>The EnabledControls Control</title> + +<para> +The <emphasis> +EnabledControls</emphasis> + control is a bit mask where each bit that is turned on means the corresponding +control is enabled, and when turned off, disabled. It corresponds to the +<emphasis> +enabled_ctrls</emphasis> + field of an <emphasis> +XkbControlsRec</emphasis> + structure (see section 10.8). The bits describing which controls are turned on +or off are defined in Table 10.7. <!-- xref --> +</para> + + +<para> +Use <emphasis> +XkbChangeEnabledControls</emphasis> + to manipulate the <emphasis> +EnabledControls</emphasis> + control. +</para> + +<informaltable frame='none'> +<tgroup cols='1'> +<colspec colsep='0'/> +<tbody> + <row rowsep='0'> + <entry role='functiondecl'> +Bool <emphasis> +XkbChangeEnabledControls</emphasis> +(<emphasis> +dpy</emphasis> +, <emphasis> +device_spec</emphasis> +, <emphasis> +mask</emphasis> +,<emphasis> + values</emphasis> +) + </entry> + </row> + <row rowsep='0'> + <entry role='functionargdecl'> +Display *<emphasis> + dpy</emphasis> +; /* connection to X server */ + </entry> + </row> + <row rowsep='0'> + <entry role='functionargdecl'> +unsigned int <emphasis> +device_spec</emphasis> +; /* keyboard device to modify */ + </entry> + </row> + <row rowsep='0'> + <entry role='functionargdecl'> +unsigned int <emphasis> +mask</emphasis> +; /* 1 bit -> controls to enable / disable */ + </entry> + </row> + <row rowsep='0'> + <entry role='functionargdecl'> +unsigned int <emphasis> +values</emphasis> +; /* 1 bit => enable, 0 bit => 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 => 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 => 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> + => 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&D Center at the University of +Wisconsin. For more information on AccessDOS, contact the Trace R&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> => 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<<0)</entry> + <entry>Slow key press notification wanted</entry> + </row> + <row rowsep='0'> + <entry>XkbAXN_SKAcceptMask</entry> + <entry>(1<<1)</entry> + <entry>Slow key accept notification wanted</entry> + </row> + <row rowsep='0'> + <entry>XkbAXN_SKRejectMask</entry> + <entry>(1<<2)</entry> + <entry>Slow key reject notification wanted</entry> + </row> + <row rowsep='0'> + <entry>XkbAXN_SKReleaseMask</entry> + <entry>(1<<3)</entry> + <entry>Slow key release notification wanted</entry> + </row> + <row rowsep='0'> + <entry>XkbAXN_BKAcceptMask</entry> + <entry>(1<<4)</entry> + <entry>Bounce key accept notification wanted</entry> + </row> + <row rowsep='0'> + <entry>XkbAXN_BKRejectMask</entry> + <entry>(1<<5)</entry> + <entry>Bounce key reject notification wanted</entry> + </row> + <row rowsep='0'> + <entry>XkbAXN_AXKWarningMask</entry> + <entry>(1<<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<KeyPress>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=>set, 0=>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=>set, 0=>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=>set, 0=>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=>set, 0=>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 => 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 => Access X option enabled */ + unsigned short ax_timeout; /* seconds until Access X disabled */ + unsigned short axt_opts_mask; /* 1 bit => options to reset on Access X timeout */ + unsigned short axt_opts_values; /* 1 bit => turn option on, 0=> 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<<0)</entry> + </row> + <row rowsep='0'> + <entry>XkbSlowKeysMask</entry> + <entry>ok</entry> + <entry>ok</entry> + <entry>(1L<<1)</entry> + </row> + <row rowsep='0'> + <entry>XkbBounceKeysMask</entry> + <entry>ok</entry> + <entry>ok</entry> + <entry>(1L<<2)</entry> + </row> + <row rowsep='0'> + <entry>XkbStickyKeysMask</entry> + <entry>ok</entry> + <entry>ok</entry> + <entry>(1L<<3)</entry> + </row> + <row rowsep='0'> + <entry>XkbMouseKeysMask</entry> + <entry>ok</entry> + <entry>ok</entry> + <entry>(1L<<4)</entry> + </row> + <row rowsep='0'> + <entry>XkbMouseKeysAccelMask</entry> + <entry>ok</entry> + <entry>ok</entry> + <entry>(1L<<5)</entry> + </row> + <row rowsep='0'> + <entry>XkbAccessXKeysMask</entry> + <entry>ok</entry> + <entry>ok</entry> + <entry>(1L<<6)</entry> + </row> + <row rowsep='0'> + <entry>XkbAccessXTimeoutMask</entry> + <entry>ok</entry> + <entry>ok</entry> + <entry>(1L<<7)</entry> + </row> + <row rowsep='0'> + <entry>XkbAccessXFeedbackMask</entry> + <entry>ok</entry> + <entry>ok</entry> + <entry>(1L<<8)</entry> + </row> + <row rowsep='0'> + <entry>XkbAudibleBellMask</entry> + <entry></entry> + <entry>ok</entry> + <entry>(1L<<9)</entry> + </row> + <row rowsep='0'> + <entry>XkbOverlay1Mask</entry> + <entry></entry> + <entry>ok</entry> + <entry>(1L<<10)</entry> + </row> + <row rowsep='0'> + <entry>XkbOverlay2Mask</entry> + <entry></entry> + <entry>ok</entry> + <entry>(1L<<11)</entry> + </row> + <row rowsep='0'> + <entry>XkbIgnoreGroupLockMask</entry> + <entry></entry> + <entry>ok</entry> + <entry>(1L<<12)</entry> +</row> +<row rowsep='0'> + <entry>XkbGroupsWrapMask</entry> + <entry>ok</entry> + <entry></entry> + <entry>(1L<<27)</entry> +</row> +<row rowsep='0'> + <entry>XkbInternalModsMask</entry> + <entry>ok</entry> + <entry></entry> + <entry>(1L<<28)</entry> +</row> +<row rowsep='0'> + <entry>XkbIgnoreLockModsMask</entry> + <entry>ok</entry> + <entry></entry> + <entry>(1L<<29)</entry> +</row> +<row rowsep='0'> + <entry>XkbPerKeyRepeatMask</entry> + <entry>ok</entry> + <entry></entry> + <entry>(1L<<30)</entry> +</row> +<row rowsep='0'> + <entry>XkbControlsEnabledMask</entry> + <entry>ok</entry> + <entry></entry> + <entry>(1L<<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<<0)</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>XkbAX_SKAcceptFBMask</entry> + <entry>(1L << 1)</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>XkbAX_FeatureFBMask</entry> + <entry>(1L << 2)</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>XkbAX_SlowWarnFBMask</entry> + <entry>(1L << 3)</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>XkbAX_IndicatorFBMask</entry> + <entry>(1L << 4)</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>XkbAX_StickyKeysFBMask</entry> + <entry>(1L << 5)</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>XkbAX_SKReleaseFBMask</entry> + <entry>(1L << 8)</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>XkbAX_SKRejectFBMask</entry> + <entry>(1L << 9)</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>XkbAX_BKRejectFBMask</entry> + <entry>(1L << 10)</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>XkbAX_DumbBellFBMask</entry> + <entry>(1L << 11)</entry> + </row> + <row rowsep='0'> + <entry>StickyKeys</entry> + <entry>XkbAX_TwoKeysMask</entry> + <entry>(1L << 6)</entry> + </row> + <row rowsep='0'> + <entry></entry> + <entry>XkbAX_LatchToLockMask</entry> + <entry>(1L << 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)->ax_options&(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)->enabled_ctrls&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)&&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> +-><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> +-><emphasis> +ctrls</emphasis> + is not <emphasis> +NULL</emphasis> +, <emphasis> +XkbGetControls</emphasis> + modifies only those portions of <emphasis> +xkb</emphasis> +-><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> +-><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> +-><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->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->ctrls</emphasis> + */ + </entry> + </row> + <row rowsep='0'> + <entry role='functionargdecl'> +XkbControlsChangesPtr <emphasis> +changes</emphasis> +; /* which parts of <emphasis> +xkb->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> +-><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> => 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 => 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->ctrls</emphasis> + will be updated */ + </entry> + </row> + <row rowsep='0'> + <entry role='functionargdecl'> +XkbNameChangesPtr <emphasis> +changes</emphasis> +; /* indicates which parts of <emphasis> +xkb->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> +-><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> + => 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 => 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 => change control */ + </entry> + </row> + <row rowsep='0'> + <entry role='functionargdecl'> +unsigned int * <emphasis> +value</emphasis> +; /* 1 bit => 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> |