# Keyboard Controls

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.

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 Boolean Controls . 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 Non-Boolean Controls , are always active. The XkbControlsRec 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.

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 XkbControlsRec structure (see section 10.8).

You can manipulate the Xkb controls individually, via convenience functions, or as a whole. To treat them as a group, modify an XkbControlsRec 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 XkbControlsChangesRec (see section 10.10.1) to reduce network traffic. When using a convenience function to manipulate one control individually, you do not use an XkbControlsRec structure directly.

The Xkb controls are grouped as shown in Table 10.1.

## Xkb Keyboard Controls

Type of Control | Control Name | Boolean Control?
--- | --- | ---
Controls for enabling and disabling other controls | EnabledControls | No
| AutoReset | No
Control for bell behavior | AudibleBell | Boolean
Controls for repeat key behavior | PerKeyRepeat | No
| RepeatKeys | Boolean
| DetectableAutorepeat | Boolean
Controls for keyboard overlays | Overlay1 | Boolean
| Overlay2 | Boolean
Controls for using the mouse from the keyboard | MouseKeys | Boolean
| MouseKeysAccel | Boolean
Controls for better keyboard access by | AccessXFeedback | Boolean
physically impaired persons | AccessXKeys | Boolean
| AccessXTimeout | Boolean
| BounceKeys | Boolean
| SlowKeys | Boolean
| StickyKeys | Boolean
Controls for general keyboard mapping | GroupsWrap | No
| IgnoreGroupLock | Boolean
| IgnoreLockMods | No
| InternalMods | No
Miscellaneous per-client controls | GrabsUseXKBState | Boolean
| LookupStateWhenGrabbed | Boolean
| SendEventUsesXKBState | Boolean

The individual categories and controls are described first, together with functions for manipulating them. A description of the XkbControlsRec structure and the general functions for dealing with all of the controls at once follow at the end of the chapter.

## Controls that Enable and Disable Other Controls

Enable and disable the boolean controls under program control by using the EnabledControls control; enable and disable them upon program exit by configuring the AutoReset control.

### The EnabledControls Control

The EnabledControls 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 enabled_ctrls field of an XkbControlsRec structure (see section 10.8). The bits describing which controls are turned on or off are defined in Table 10.7.

Use XkbChangeEnabledControls to manipulate the EnabledControls control.

Bool XkbChangeEnabledControls ( dpy , device_spec , mask , values )
Display * dpy ; /* connection to X server */
unsigned int device_spec ; /* keyboard device to modify */
unsigned int mask ; /* 1 bit -> controls to enable / disable */
unsigned int values ; /* 1 bit => enable, 0 bit => disable */

The mask parameter specifies the boolean controls to be enabled or disabled, and the values 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 enabled_ctrls column.

If the X server does not support a compatible version of Xkb or the Xkb extension has not been properly initialized, XkbChangeEnabledControls returns False ; otherwise, it sends the request to the X server and returns True .

Note that the EnabledControls control only enables and disables controls; it does not configure them. Some controls, such as the AudibleBell 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 RepeatControl control uses repeat_delay and repeat_interval fields to describe the timing behavior of keys that repeat. The RepeatControl behavior is turned on or off depending on the value of the XkbRepeatKeysMask bit, but you must use other means, as described in this chapter, to configure its behavior in detail.

### The AutoReset Control

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 auto-reset mask are set to the corresponding value from the auto-reset values 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 EnabledControls control bits.

For example, a client that replaces the keyboard bell with some other audible cue might want to turn off the AudibleBell control to prevent the server from also generating a sound and avoid cacophony. If the client were to exit without resetting the AudibleBell control, the user would be left without any feedback at all. Setting AudibleBell in both the auto-reset mask and auto-reset values guarantees that the audible bell will be turned back on when the client exits.

To get the current values of the auto-reset controls, use XkbGetAutoResetControls .

Bool XkbGetAutoResetControls ( dpy , auto_ctrls , auto_values )
Display * dpy ; /* connection to X server */
unsigned int * auto_ctrls ; /* specifies which bits in auto_values are relevant */
unsigned int * auto_values ; /* 1 bit => corresponding control has auto-reset on */

XkbGetAutoResetControls backfills auto_ctrls and auto_values with the AutoReset control attributes for this particular client. It returns True if successful, and False otherwise.

To change the current values of the AutoReset control attributes, use XkbSetAutoResetControls.

Bool XkbSetAutoResetControls ( dpy , changes , auto_ctrls , auto_values )
Display * dpy ; /* connection to X server */
unsigned int changes ; /* controls for which to change auto-reset values */
unsigned int * auto_ctrls ; /* controls from changes that should auto reset */
unsigned int * auto_values ; /* 1 bit => auto-reset on */

XkbSetAutoResetControls changes the auto-reset status and associated auto-reset values for the controls selected by changes . For any control selected by changes , if the corresponding bit is set in auto_ctrls , the control is configured to auto-reset when the client exits. If the corresponding bit in auto_values is on, the control is turned on when the client exits; if zero, the control is turned off when the client exits. For any control selected by changes , if the corresponding bit is not set in auto_ctrls , the control is configured to not reset when the client exits. For example:

To leave the auto-reset controls for StickyKeys the way they are:

    ok = XkbSetAutoResetControls(dpy, 0, 0, 0);

To change the auto-reset controls so that StickyKeys are unaffected when the client exits:

    ok = XkbSetAutoResetControls(dpy, XkbStickyKeysMask, 0, 0);

To change the auto-reset controls so that StickyKeys are turned off when the client exits:

    ok = XkbSetAutoResetControls(dpy, XkbStickyKeysMask, XkbStickyKeysMask, 0);

To change the auto-reset controls so that StickyKeys are turned on when the client exits:

    ok = XkbSetAutoResetControls(dpy, XkbStickyKeysMask, XkbStickyKeysMask,
    XkbStickyKeysMask);

XkbSetAutoResetControls backfills auto_ctrls and auto_values 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 changes mask.

## Control for Bell Behavior

The X server’s generation of sounds is controlled by the AudibleBell control. Configuration of different bell sounds is discussed in Chapter 9.

### The AudibleBell Control

The AudibleBell control is a boolean control that has no attributes. As such, you may enable and disable it using either the EnabledControls control or the AutoReset control discussed in section 10.1.1. When enabled, protocol requests to 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.

## Controls for Repeat Key Behavior

The repeating behavior of keyboard keys is governed by three controls, the PerKeyRepeat control, which is always active, and the RepeatKeys and DetectableAutorepeat controls, which are boolean controls that may be enabled and disabled. PerKeyRepeat determines which keys are allowed to repeat. RepeatKeys governs the behavior of an individual key when it is repeating. DetectableAutorepeat allows a client to detect when a key is repeating as a result of being held down.

### The PerKeyRepeat Control

The PerKeyRepeat 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 PerKeyRepeat 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 PerKeyRepeat control settings are carried in the per_key_repeat field of an XkbControlsRec structure, discussed in section 10.8.

### The RepeatKeys Control

The core protocol allows only control over whether or not the entire keyboard or individual keys should auto-repeat when held down. RepeatKeys 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. RepeatKeys is coupled with the core auto-repeat control: when RepeatKeys is enabled or disabled, the core auto-repeat is enabled or disabled and vice versa.

Auto-repeating keys are controlled by two attributes. The first, timeout , is the delay after the initial press of an auto-repeating key and the first generated repeat event. The second, interval , 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.

To get the current attributes of the RepeatKeys control for a keyboard device, use XkbGetAutoRepeatRate .

Bool XkbGetAutoRepeatRate ( display, device_spec, timeout_rtrn, interval_rtrn )
Display * display ; /* connection to X server */
unsigned int device_spec ; /* desired device ID, or XkbUseCoreKbd */
unsigned int * timeout_rtrn ; /* backfilled with initial repeat delay, ms */
unsigned int * interval_rtrn ; /* backfilled with subsequent repeat delay, ms */

XkbGetAutoRepeatRate queries the server for the current values of the RepeatControls control attributes, backfills timeout_rtrn and interval_rtrn with them, and returns True . If a compatible version of the Xkb extension is not available in the server XkbGetAutoRepeatRate returns False .

To set the attributes of the RepeatKeys control for a keyboard device, use XkbSetAutoRepeatRate .

Bool XkbSetAutoRepeatRate ( display, device_spec, timeout, interval )
Display * display ; /* connection to X server */
unsigned int device_spec ; /* device to configure, or XkbUseCoreKbd */
unsigned int timeout ; /* initial delay, ms */
unsigned int interval ; /* delay between repeats, ms */

XkbSetAutoRepeatRate sends a request to the X server to configure the AutoRepeat control attributes to the values specified in timeout and interval .

XkbSetAutoRepeatRate does not wait for a reply; it normally returns True . Specifying a zero value for either timeout or interval causes the server to generate a BadValue protocol error. If a compatible version of the Xkb extension is not available in the server, XkbSetAutoRepeatRate returns False .

### The DetectableAutorepeat Control

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 KeyPress events with no intervening KeyRelease event. The standard behavior of the X server is to generate a KeyRelease event for every KeyPress event. If the keyboard hardware and device-dependent software of the X server implement auto-repeat by generating multiple KeyPress events, the device-independent part of the X server by default synthetically generates a KeyRelease event after each KeyPress event. This provides predictable behavior for X clients, but does not allow those clients to detect the fact that a key is auto-repeating.

Xkb allows clients to request detectable auto-repeat . If a client requests and the server supports DetectableAutorepeat , Xkb generates KeyRelease events only when the key is physically released. If DetectableAutorepeat is not supported or has not been requested, the server synthesizes a KeyRelease event for each repeating KeyPress event it generates.

DetectableAutorepeat , unlike the other controls in this chapter, is not contained in the XkbControlsRec structure, nor can it be enabled or disabled via the EnabledControls control. Instead, query and set DetectableAutorepeat using XkbGetDetectableAutorepeat and XkbSetDetectableAutorepeat .

DetectableAutorepeat 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 DetectableAutorepeat involve a device specifier.

To determine whether or not the server supports DetectableAutorepeat , use XkbGetDetectableAutorepeat .

Bool XkbGetDetectableAutorepeat ( display, supported_rtrn )
Display * display ; /* connection to X server */
Bool * supported_rtrn ; /* backfilled True if DetectableAutorepeat supported */

XkbGetDetectableAutorepeat queries the server for the current state of DetectableAutorepeat and waits for a reply. If supported_rtrn is not NULL , it backfills supported_rtrn with True if the server supports DetectableAutorepeat , and False otherwise. XkbGetDetectableAutorepeat returns the current state of DetectableAutorepeat for the requesting client: True if DetectableAutorepeat is set, and False otherwise.

To set DetectableAutorepeat , use XkbSetDetectableAutorepeat . 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.

Bool XkbSetDetectableAutorepeat ( display, detectable, supported_rtrn )
Display * display ; /* connection to X server */
Bool detectable ; /* True => set DetectableAutorepeat */
Bool * supported_rtrn ; /* backfilled True if DetectableAutorepeat supported */

XkbSetDetectableAutorepeat sends a request to the server to set DetectableAutorepeat on for the current client if detectable is True , and off it detectable is False ; it then waits for a reply. If supported_rtrn is not NULL , XkbSetDetectableAutorepeat backfills supported_rtrn with True if the server supports DetectableAutorepeat , and False if it does not. XkbSetDetectableAutorepeat returns the current state of DetectableAutorepeat for the requesting client: True if DetectableAutorepeat is set, and False otherwise.

## Controls for Keyboard Overlays (Overlay1 and Overlay2 Controls)

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.

Xkb includes direct support for two keyboard overlays, using the Overlay1 and Overlay2 controls. When Overlay1 is enabled, all of the keys that are members of the first keyboard overlay generate an alternate keycode. When Overlay2 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. Overlay1 and Overlay2 are boolean controls. As such, you may enable and disable them using either the EnabledControls control or the AutoReset control discussed in section 10.1.1.

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 XkbKB_Overlay1 or XkbKB_Overlay2 key behaviors, as described in section 16.2.

## Controls for Using the Mouse from the Keyboard

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 MouseKeys control determines whether or not simulation of the pointer device is active, as well as configuring the default button; the MouseKeysAccel 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 EnabledControls control or the AutoReset control discussed in section 10.1.1. The individual keys that simulate different aspects of the pointer device are determined by the keyboard mapping, discussed in Chapter 16.

### The MouseKeys Control

The MouseKeys control allows a user to control all the mouse functions from the keyboard. When MouseKeys are enabled, all keys with MouseKeys actions bound to them generate core pointer events instead of normal KeyPress and KeyRelease events.

The MouseKeys control has a single attribute, mk_dflt_btn 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 XkbGetControls and XkbSetControls (see sections 10.9 and 10.10).

MouseKeys can also be turned on and off by pressing the key combination necessary to produce an XK_Pointer_EnableKeys keysym. The de facto default standard for this is Shift+Alt+NumLock , but this may vary depending on the keymap.

### The MouseKeysAccel Control

When the MouseKeysAccel 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 MouseKeysAccel is enabled, mouse movement is defined by an initial distance specified in the XkbSA_MovePtr action and the following fields in the XkbControlsRec structure (see section 10.8).

#### MouseKeysAccel Fields

Field | Function
--- | ---
mk_delay | Time (ms) between the initial key press and the first repeated motion event
mk_interval | Time (ms) between repeated motion events
mk_time_to_max | Number of events (count) before the pointer reaches maximum speed
mk_max_speed | The maximum speed (in pixels per event) the pointer reaches
mk_curve | The ramp used to reach maximum pointer speed

There are no convenience functions to query or change the attributes of the MouseKeysAccel control; instead use XkbGetControls and XkbSetControls (see sections 10.9 and 10.10).

The effects of the attributes of the MouseKeysAccel control depend on whether the XkbSA_MovePtr action (see section 16.1) specifies relative or absolute pointer motion.

#### Absolute Pointer Motion

If an XkbSA_MovePtr 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 XkbSA_MovePtr 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.

#### Relative Pointer Motion

If the XkbSA_MovePtr action specifies relative motion, the initial event always moves the cursor the distance specified in the action. After mk_delay milliseconds, a second motion event is generated, and another occurs every mk_interval milliseconds until the user releases the key.

Between the time of the second motion event and mk_time_to_max intervals, the change in pointer distance per interval increases with each interval. After mk_time_to_max 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 mk_max_speed .

For example, if the XkbSA_MovePtr action specifies a relative motion in the X direction of 5, mk_delay =160, mk_interval =40, mk_time_to_max =30, and mk_max_speed =30, the following happens when the user presses the key:

- The pointer immediately moves 5 pixels in the X direction when the key is pressed.

- After 160 milliseconds ( mk_delay ), and every 40 milliseconds thereafter ( mk_interval ), the pointer moves in the X direction.

- The distance in the X direction increases with each interval until 30 intervals ( mk_time_to_max ) have elapsed.

- After 30 intervals, the pointer stops accelerating, and moves 150 pixels ( mk_max_speed * the original distance) every interval thereafter, until the key is released.

The increase in pointer difference for each interval is a function of mk_curve. Events after the first but before maximum acceleration has been achieved are accelerated according to the formula:

Where action_delta is the relative motion specified by the XkbSA_MovePtr action, mk_max_speed and mk_time_to_max are parameters to the MouseKeysAccel control, and the curveFactor is computed using the MouseKeysAccel mk_curve parameter as follows:

With the result that a mk_curve of zero causes the distance moved to increase linearly from action_delta to

. A negative mk_curve 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 mk_time_to_max . The legal values for mk_curve are between -1000 and 1000.

A distance vs. time graph of the pointer motion is shown in Figure 10.1.

MouseKeys Acceleration

## Controls for Better Keyboard Access by Physically Impaired Persons

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

### The AccessXKeys Control

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 SlowKeys (see section 10.6.6) may not even be able to start the graphical application, let alone use it, if SlowKeys is not enabled. To allow easier access to some of the controls, the AccessXKeys control provides a set of special key sequences similar to those available in AccessDOS.

When the AccessXKeys control is enabled, the user can turn controls on or off from the keyboard by entering the following standard key sequences:

- Holding down a shift key by itself for eight seconds toggles the SlowKeys control.

- Pressing and releasing the left or right Shift 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 StickyKeys control.

- Simultaneously operating two or more modifier keys deactivates the StickyKeys control.

When the AccessXKeys control is disabled, Xkb does not look for the above special key sequences.

Some of these key sequences optionally generate audible feedback of the change in state, as described in section 10.6.3, or XkbControlsNotify events, described in section 10.11.

### The AccessXTimeout Control

In environments where computers are shared, features such as SlowKeys present a problem: if SlowKeys 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 AccessXTimeout control to automatically change the enabled/disabled state of any boolean controls and to change the value of the AccessXKeys and AccessXFeedback control attributes if the keyboard is idle for a specified period of time.

When a timeout as specified by AccessXTimeout occurs and a control is consequently modified, Xkb generates an XkbControlsNotify event. For more information on XkbControlsNotify events, refer to section 10.11.

Use XkbGetAccessXTimeout to query the current AccessXTimeout options for a keyboard device.

Bool XkbGetAccessXTimeout ( display , device_spec , timeout_rtrn , ctrls_mask_rtrn , ctrls_values_rtrn , options_mask_rtrn, options_values_rtrn )
Display * display ; /* connection to X server */
unsigned int device_spec ; /* device to query, or XkbUseCoreKbd */
unsigned short * timeout_rtrn ; /* delay until AccessXTimeout, seconds */
unsigned int * ctrls_mask_rtrn ; /* backfilled with controls to modify */
unsigned int * ctrls_values_rtrn ; /* backfilled with on/off status for controls */
unsigned short * opts_mask_rtrn ; /* backfilled with ax_options to modify */
unsigned short * opts_values_rtrn ; /* backfilled with values for ax_options */

XkbGetAccessXTimeout sends a request to the X server to obtain the current values for the AccessXTimeout attributes, waits for a reply, and backfills the values into the appropriate arguments. The parameters opts_mask_rtrn and opts_values_rtrn are backfilled with the options to modify and the values for ax_options , which is a field in the XkbControlsRec structure (see section 10.8). XkbGetAccessXTimeout returns True if successful; if a compatible version of the Xkb extension is not available in the server, XkbGetAccessXTimeout returns False .

To configure the AccessXTimeout options for a keyboard device, use XkbSetAccessXTimeout .

Bool XkbSetAccessXTimeout ( display , device_spec, timeout, ctrls_mask, ctrls_values, opts_mask, opts_values )
Display * display ; /* connection to X server */
unsigned int device_spec ; /* device to configure, or XkbUseCoreKbd */
unsigned short timeout ; /* seconds idle until AccessXTimeout occurs */
unsigned int ctrls_mask ; /* boolean controls to modify */
unsigned int ctrls_values ; /* new bits for controls selected by ctrls_mask */
unsigned short opts_mask ; /* ax_options to change */
unsigned short opts_values ; /* new bits for ax_options selected by opts_mask */

timeout specifies the number of seconds the keyboard must be idle before the controls are modified. ctrls_mask specifies what controls are to be enabled or disabled, and ctrls_values 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 opts_mask field specifies which attributes of the AccessXKeys and AccessXFeedback controls are to be changed, and opts_values specifies the new values for those options. The bit values correspond to those for the ax_options field of an XkbDescRec (see section 10.8).

XkbSetAccessXTimeout sends a request to configure the AccessXTimeout control to the server. It does not wait for a reply, and normally returns True . If a compatible version of the Xkb extension is not available in the server, XkbSetAccessXTimeout returns False .

### The AccessXFeedback Control

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 AccessXFeedback control to configure the specific types of operations that generate feedback.

There is no convenience function for modifying the AccessXFeedback 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 ax_options field of an XkbControlsRec structure and using XkbSetControls (see section 10.10):

#### AccessXFeedback Masks

Action | Beep Code | ax_options bit
--- | --- | ---
LED turned on | High-pitched beep | XkbAX_IndicatorFBMask
LED turned off | Low-pitched beep | XkbAX_IndicatorFBMask
More than one LED changed state | Two high-pitched beeps | XkbAX_IndicatorFBMask
Control turned on | Rising tone | XkbAX_FeatureFBMask
Control turned off | Falling tone | XkbAX_FeatureFBMask
More than one control changed state | Two high-pitched beeps | XkbAX_FeatureFBMask
SlowKeys and BounceKeys about to be turned on or off | Three high-pitched beeps | XkbAX_SlowWarnFBMask
SlowKeys key pressed | Medium-pitched beep | XkbAX_SKPressFBMask
SlowKeys key accepted | Medium-pitched beep | XkbAX_SKAcceptFBMask
SlowKeys key rejected | Low-pitched beep | XkbAX_SKRejectFBMask
Accepted SlowKeys key released | Medium-pitched beep | XkbAX_SKReleaseFBMask
BounceKeys key rejected | Low-pitched beep | XkbAX_BKRejectFBMask
StickyKeys key latched | Low-pitched beep followed by high-pitched beep | XkbAX_StickyKeysFBMask
StickyKeys key locked | High-pitched beep | XkbAX_StickyKeysFBMask
StickyKeys key unlocked | Low-pitched beep | XkbAX_StickyKeysFBMask

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 XkbAX_DumbBellFBMask bit of ax_options to indicate that the bell can only ring with a fixed pitch.

When any of the above feedbacks occur, Xkb may generate a XkbBellNotify event (see section 9.4).

### AccessXNotify Events

The server can generate XkbAccessXNotify events for some of the global keyboard controls. The structure for the XkbAccessXNotify event type is as follows:

    typedef struct {
          int             type;            /* Xkb extension base event code */
          unsigned long   serial;          /* X server serial number for event */
          Bool            send_event;      /*  True => synthetically generated */
          Display *       display;         /* server connection where event generated */
          Time            time;            /* server time when event generated */
          int             xkb_type;        /*  XkbAccessXNotify */
          int             device;          /* Xkb device ID, will not be  XkbUseCoreKbd */
          int             detail;          /* XkbAXN_* */
          KeyCode         keycode;         /* key of event */
          int             slowKeysDelay;   /* current SlowKeys delay */
          int             debounceDelay;   /* current debounce delay */
    } XkbAccessXNotifyEvent;

The detail field describes what AccessX event just occurred and can be any of the values in Table 10.4.

#### AccessXNotify Events

detail | Reason
--- | ---
XkbAXN_SKPress | A key was pressed when SlowKeys was enabled.
XkbAXN_SKAccept | A key was accepted (held longer than the SlowKeys delay).
XkbAXN_SKRelease | An accepted SlowKeys key was released.
XkbAXN_SKReject | A key was rejected (released before the SlowKeys delay expired).
XkbAXN_BKAccept | A key was accepted by BounceKeys.
XkbAXN_BKReject | A key was rejected (pressed before the BounceKeys delay expired).
XkbAXN_AXKWarning | AccessXKeys is about to turn on/off StickyKeys or BounceKeys.

The keycode field reports the keycode of the key for which the event occurred. If the action is related to SlowKeys , the slowKeysDelay field contains the current SlowKeys acceptance delay. If the action is related to BounceKeys , the debounceDelay field contains the current BounceKeys debounce delay.

#### Selecting for AccessX Events

To receive XkbAccessXNotify events under all possible conditions, use XkbSelectEvents (see section 4.3) and pass XkbAccesXNotifyMask in both bits_to_change and values_for_bits .

To receive XkbStateNotify events only under certain conditions, use XkbSelectEventDetails using XkbAccessXNotify as the event_type and specifying the desired state changes in bits_to_change and values_for_bits using mask bits from Table 10.5.

##### AccessXNotify Event Details

XkbAccessXNotify Event Details | Value | Circumstances
--- | --- | ---
XkbAXN_SKPressMask | (1<<0) | Slow key press notification wanted
XkbAXN_SKAcceptMask | (1<<1) | Slow key accept notification wanted
XkbAXN_SKRejectMask | (1<<2) | Slow key reject notification wanted
XkbAXN_SKReleaseMask | (1<<3) | Slow key release notification wanted
XkbAXN_BKAcceptMask | (1<<4) | Bounce key accept notification wanted
XkbAXN_BKRejectMask | (1<<5) | Bounce key reject notification wanted
XkbAXN_AXKWarningMask | (1<<6) | AccessX warning notification wanted
XkbAXN_AllEventsMask | (0x7f) | All AccessX features notifications wanted

### StickyKeys, RepeatKeys, and MouseKeys Events

The StickyKeys , RepeatKeys , and MouseKeys controls do not generate specific events. Instead, the latching, unlatching, locking, or unlocking of modifiers using StickyKeys generates XkbStateNotify events as described in section 5.4. Repeating keys generate normal KeyPress and KeyRelease events, though the auto-repeat can be detected using DetectableAutorepeat (see section 10.3.3). Finally, MouseKeys generates pointer events identical to those of the core pointer device.

### The SlowKeys Control

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 SlowKeys control helps filter these accidental bumps by telling the server to wait a specified period, called the SlowKeys acceptance delay , 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. SlowKeys is a boolean control with one configurable attribute.

When the SlowKeys 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 AccessXNotify event (see section 10.6.4).

To get the SlowKeys acceptance delay for a keyboard device, use XkbGetSlowKeysDelay .

Bool XkbGetSlowKeysDelay ( display , device_spec , delay_rtrn )
Display * display ; /* connection to X server */
unsigned int device_spec ; /* device ID, or XkbUseCoreKbd */
unsigned int * delay_rtrn ; /* backfilled with SlowKeys delay, ms */

XkbGetSlowKeysDelay requests the attributes of the SlowKeys control from the server, waits for a reply and backfills delay_rtrn with the SlowKeys delay attribute. XkbGetSlowKeysDelay returns True if successful; if a compatible version of the Xkb extension is not available in the server, XkbGetSlowKeysDelay returns False .

To set the SlowKeys acceptance delay for a keyboard device, use XkbSetSlowKeysDelay .

Bool XkbSetSlowKeysDelay ( display , device_spec , delay )
Display * display ; /* connection to X server */
unsigned int device_spec ; /* device to configure, or XkbUseCoreKbd */
unsigned int delay ; /* SlowKeys delay, ms */

XkbSetSlowKeysDelay sends a request to configure the SlowKeys control to the server. It does not wait for a reply, and normally returns True . Specifying a value of 0 for the delay parameter causes XkbSetSlowKeys to generate a BadValue protocol error. If a compatible version of the Xkb extension is not available in the server XkbSetSlowKeysDelay returns False .

### The BounceKeys Control

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 BounceKeys 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 BounceKeys delay . BounceKeys is a boolean control.

When the BounceKeys control is active, the server reports acceptance or rejection of any key to interested clients by sending an appropriate AccessXNotify event (see section 10.6.4).

Use XkbGetBounceKeysDelay to query the current BounceKeys delay for a keyboard device.

Bool XkbGetBounceKeysDelay ( display , device_spec , delay_rtrn )
Display * display ; /* connection to X server */
unsigned int device_spec ; /* device ID, or XkbUseCoreKbd */
unsigned int * delay_rtrn ; /* backfilled with bounce keys delay, ms */

XkbGetBounceKeysDelay requests the attributes of the BounceKeys control from the server, waits for a reply, and backfills delay_rtrn with the BounceKeys delay attribute. XkbGetBounceKeysDelay returns True if successful; if a compatible version of the Xkb extension is not available in the server XkbGetSlowKeysDelay returns False .

To set the BounceKeys delay for a keyboard device, use XkbSetBounceKeysDelay .

Bool XkbSetBounceKeysDelay ( display , device_spec , delay )
Display * display ; /* connection to X server */
unsigned int device_spec ; /* device to configure, or XkbUseCoreKbd */
unsigned int delay ; /* bounce keys delay, ms */

XkbSetBounceKeysDelay sends a request to configure the BounceKeys control to the server. It does not wait for a reply and normally returns True . Specifying a value of zero for the delay parameter causes XkbSetBounceKeysDelay to generate a BadValue protocol error. If a compatible version of the Xkb extension is not available in the server, XkbSetBounceKeysDelay returns False .

### The StickyKeys Control

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 Shift and 1 keys at the same time. The StickyKeys control solves this problem by changing the behavior of the modifier keys. With StickyKeys , 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 Shift key, release it, and then press the 1 key.

StickyKeys also allows users to lock modifier keys without requiring special locking keys. When StickyKeys 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.

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 Shift + Control + Z the user could press and release the Shift key to latch it, then press and release the Control key to latch it, and finally press and release the Z key. Because the Control key is a modifier key, pressing it does not unlatch the Shift key. Thus, after the user presses the Control key, both the Shift and Control modifiers are latched. When the user presses the Z key, the effect is as though the user had pressed Shift + Control + Z . In addition, because the Z key is not a modifier key, the Shift and Control modifiers are unlatched.

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 Shift key twice to lock the Shift modifier. Then, when the user presses the 9 , ‘ , x , k , b , ‘ , and 0 keys in sequence, it generates ("XKB"). To unlock the Shift modifier, the user can press and release the Shift key.

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

#### StickyKeys Options

The StickyKeys control has two options that can be accessed via the ax_options of an XkbControlsRec structure (see section 10.8). The first option, TwoKeys , specifies whether StickyKeys 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 StickyKeys off if a previous user left StickyKeys on. The second option, LatchToLock , specifies whether or not StickyKeys locks a modifier when pressed twice in a row.

Use XkbGetStickyKeysOptions to query the current StickyKeys attributes for a keyboard device.

Bool XkbGetStickyKeysOptions ( display , device_spec , options_rtrn )
Display * display ; /* connection to X server */
unsigned int device_spec ; /* device ID, or XkbUseCoreKbd */
unsigned int * options_rtrn ; /* backfilled with StickyKeys option mask */

XkbGetStickyKeysOptions requests the attributes of the StickyKeys control from the server, waits for a reply, and backfills options_rtrn with a mask indicating whether the individual StickyKeys options are on or off. Valid bits in options_rtrn are:

         XkbAX_TwoKeysMask
         XkbAX_LatchToLockMask

XkbGetStickyKeysOptions returns True if successful; if a compatible version of the Xkb extension is not available in the server XkbGetStickyKeysOptions returns False .

To set the StickyKeys attributes for a keyboard device, use XkbSetStickyKeysOptions .

Bool XkbSetStickyKeysOptions ( display , device_spec, mask, values )
Display * display ; /* connection to X server */
unsigned int device_spec ; /* device to configure, or XkbUseCoreKbd */
unsigned int mask ; /* selects StickyKeys attributes to modify */
unsigned int values; /* values for selected attributes */

XkbSetStickyKeysOptions sends a request to configure the StickyKeys control to the server. It does not wait for a reply and normally returns True . The valid bits to use for both the mask and values parameters are:

         XkbAX_TwoKeysMask
         XkbAX_LatchToLockMask

If a compatible version of the Xkb extension is not available in the server, XkbSetStickyKeysOptions returns False .

## Controls for General Keyboard Mapping

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:

         GroupsWrap
         IgnoreGroupLock
         IgnoreLockMods
         InternalMods

IgnoreGroupLock is a boolean control; the rest are always active.

Without the modifier processing options provided by Xkb, passive grabs set via translations in a client (for example, Alt<KeyPress>space ) 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 NumLock or a secondary keyboard group is active. The IgnoreLockMods and IgnoreGroupLock controls make it possible to avoid this behavior without exhaustively specifying a grab for every possible modifier combination.

### The GroupsWrap Control

The GroupsWrap 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 GroupsWrap control specifies how this is done.

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 GroupsWrap control specifies which one is used:

- XkbRedirectIntoRange

  All invalid group numbers are converted to a valid group number by taking the last four bits of the GroupsWrap control and using them as the group index. If the result is still out of range, Group one is used.

- XkbClampIntoRange

  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.

- XkbWrapIntoRange

  All invalid group numbers are converted to a valid group number using integer modulus applied to the group index.

There are no convenience functions for manipulating the GroupsWrap control. Manipulate the GroupsWrap control via the groups_wrap field in the XkbControlsRec structure, then use XkbSetControls and XkbGetControls (see section 10.9 and section 10.10) to query and change this control.

See also section 15.3.2 or a discussion of the related field, group_info , which also normalizes a group under certain circumstances.

### The IgnoreLockMods Control

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.

The IgnoreLockMods control specifies modifiers that should be excluded from grab calculations. These modifiers are also not reported in any core events except KeyPress and KeyRelease events that do not activate a passive grab and that do not occur while a grab is active.

Manipulate the IgnoreLockMods control via the ignore_lock field in the XkbControlsRec structure, then use XkbSetControls and XkbGetControls (see sections 10.9 and 10.10) to query and change this control. Alternatively, use XkbSetIgnoreLockMods .

To set the modifiers that, if locked, are not to be reported in matching events to passive grabs, use XkbSetIgnoreLockMods.

Bool XkbSetIgnoreLockMods ( display, device_spec, affect_real, real_values, affect_virtual, virtual_values )
Display * display ; /* connection to the X server */
unsigned int device_spec ; /* device ID, or XkbUseCoreKbd */
unsigned int affect_real ; /* mask of real modifiers affected by this call */
unsigned int real_values ; /* values for affected real modifiers (1=>set, 0=>unset) */
unsigned int affect_virtual ; /* mask of virtual modifiers affected by this call */
unsigned int virtual_values ; /* values for affected virtual modifiers (1=>set, 0=>unset) */

XkbSetIgnoreLockMods sends a request to the server to change the server’s IgnoreLockMods control. affect_real and real_values are masks of real modifier bits indicating which real modifiers are to be added and removed from the server’s IgnoreLockMods control. Modifiers selected by both affect_real and real_values are added to the server’s IgnoreLockMods control; those selected by affect_real but not by real_values are removed from the server’s IgnoreLockMods control. Valid values for affect_real and real_values consist of any combination of the eight core modifier bits: ShiftMask , LockMask , ControlMask , Mod1Mask - Mod5Mask . affect_virtual and virtual_values are masks of virtual modifier bits indicating which virtual modifiers are to be added and removed from the server’s IgnoreLockMods control. Modifiers selected by both affect_virtual and virtual_values are added to the server’s IgnoreLockMods control; those selected by affect_virtual but not by virtual_values are removed from the server’s IgnoreLockMods control. See section 7.1 for a discussion of virtual modifier masks to use in affect_virtual and virtual_values . XkbSetIgnoreLockMods does not wait for a reply from the server. It returns True if the request was sent, and False otherwise.

### The IgnoreGroupLock Control

The IgnoreGroupLock 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.

Because IgnoreGroupLock is a boolean control with no attributes, use the general boolean controls functions (see section 10.1) to change its state.

### The InternalMods Control

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 InternalMods 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 InternalMods 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 InternalMods control are not used to determine grabs and are not used to calculate core protocol compatibility state.

Manipulate the InternalMods control via the internal field in the XkbControlsRec structure, using XkbSetControls and XkbGetControls (see sections10.9 and 10.10). Alternatively, use XkbSetServerInternalMods .

To set the modifiers that are consumed by the server before events are delivered to the client, use XkbSetServerInternalMods.

Bool XkbSetServerInternalMods ( display, device_spec, affect_real, real_values, affect_virtual, virtual_values )
Display * display ; /* connection to the X server */
unsigned int device_spec ;‘ /* device ID, or XkbUseCoreKbd */
unsigned int affect_real ; /* mask of real modifiers affected by this call */
unsigned int real_values ; /* values for affected real modifiers (1=>set, 0=>unset) */
unsigned int affect_virtual ; /* mask of virtual modifiers affected by this call */
unsigned int virtual_values ; /* values for affected virtual modifiers (1=>set, 0=>unset) */

XkbSetServerInternalMods sends a request to the server to change the internal modifiers consumed by the server. affect_real and real_values 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 affect_real and real_values are added to the server’s internal modifiers control; those selected by affect_real but not by real_values are removed from the server’s internal modifiers mask. Valid values for affect_real and real_values consist of any combination of the eight core modifier bits: ShiftMask , LockMask , ControlMask , Mod1Mask - Mod5Mask . affect_virtual and virtual_values 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 affect_virtual and virtual_values are added to the server’s internal modifiers control; those selected by affect_virtual but not by virtual_values are removed from the server’s internal modifiers control. See section 7.1 for a discussion of virtual modifier masks to use in affect_virtual and virtual_values . XkbSetServerInternalMods does not wait for a reply from the server. It returns True if the request was sent and False otherwise.

## The XkbControlsRec Structure

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 XkbControlsRec 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 XkbGetControls and XkbSetControls functions. This is the only way to manipulate those controls that have no convenience functions.

The XkbControlsRec structure is defined as follows:

    #define      XkbMaxLegalKeyCode       255
    #define      XkbPerKeyBitArraySize    ((XkbMaxLegalKeyCode+1)/8)

    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  enabled_ctrls to modify */
          unsigned int         axt_ctrls_values;  /* values for new bits in  enabled_ctrls */
          unsigned char        per_key_repeat[XkbPerKeyBitArraySize];           /* per key auto repeat */
    } XkbControlsRec, *XkbControlsPtr;

The general-purpose functions that work with the XkbControlsRec 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 ( which parameter), and the data fields in the XkbControlsRec 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.

### Xkb Controls

Control | Control Selection Mask (which parameter) | Relevant XkbControlsRec Data Fields | Boolean Control enabled_ctrls bit | Section
--- | --- | --- | --- | ---
AccessXFeedback | XkbAccessXFeedbackMask | ax_options: XkbAX_*FBMask | XkbAccessXFeedbackMask | 10.6.3
AccessXKeys |  |  | XkbAccessXKeysMask | 10.6.1
AccessXTimeout | XkbAccessXTimeoutMask | ax_timeout axt_opts_mask axt_opts_values axt_ctrls_mask axt_ctrls_values | XkbAccessXTimeoutMask | 10.6.2
AudibleBell |  |  | XkbAudibleBellMask | 9.2
AutoReset |  |  |  | 10.1.2
BounceKeys | XkbBounceKeysMask | debounce_delay | XkbBounceKeysMask | 10.6.7
Detectable-Autorepeat |  |  |  | 10.3.3
EnabledControls | XkbControlsEnabledMask | enabled_ctrls | Non-Boolean Control | 10.1.1
GroupsWrap | XkbGroupsWrapMask | groups_wrap | Non-Boolean Control | 10.7.1
IgnoreGroupLock |  |  | XkbIgnoreGroupLockMask | 10.7.3
IgnoreLockMods | XkbIgnoreLockModsMask | ignore_lock | Non-Boolean Control | 5.1
InternalMods | XkbInternalModsMask | internal | Non-Boolean Control | 5.1
MouseKeys | XkbMouseKeysMask | mk_dflt_btn | XkbMouseKeysMask | 10.5.1
MouseKeysAccel | XkbMouseKeysAccelMask | mk_delay mk_interval mk_time_to_max mk_max_speed mk_curve | XkbMouseKeysAccelMask | 10.5.2
Overlay1 |  |  | XkbOverlay1Mask | 10.4
Overlay2 |  |  | XkbOverlay2Mask | 10.4
PerKeyRepeat | XkbPerKeyRepeatMask | per_key_repeat | Non-Boolean Control | 10.3.1
RepeatKeys | XkbRepeatKeysMask | repeat_delay repeat_interval | XkbRepeatKeysMask | 10.3
SlowKeys | XkbSlowKeysMask | slow_keys_delay | XkbSlowKeysMask | 10.6.6
StickyKeys | XkbStickyKeysMask | ax_options: XkbAX_TwoKeysMask XkbAX_LatchToLockMask | XkbStickyKeysMask | 10.6.8

Table 10.7 shows the actual values for the individual mask bits used to select 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 ( which ), and to enable and disable the control ( enabled_ctrls ). 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.

### Controls Mask Bits

Mask Bit | which or changed_ctrls | enabled_ctrls | Value
--- | --- | --- | ---
XkbRepeatKeysMask | ok | ok | (1L<<0)
XkbSlowKeysMask | ok | ok | (1L<<1)
XkbBounceKeysMask | ok | ok | (1L<<2)
XkbStickyKeysMask | ok | ok | (1L<<3)
XkbMouseKeysMask | ok | ok | (1L<<4)
XkbMouseKeysAccelMask | ok | ok | (1L<<5)
XkbAccessXKeysMask | ok | ok | (1L<<6)
XkbAccessXTimeoutMask | ok | ok | (1L<<7)
XkbAccessXFeedbackMask | ok | ok | (1L<<8)
XkbAudibleBellMask |  | ok | (1L<<9)
XkbOverlay1Mask |  | ok | (1L<<10)
XkbOverlay2Mask |  | ok | (1L<<11)
XkbIgnoreGroupLockMask |  | ok | (1L<<12)
XkbGroupsWrapMask | ok |  | (1L<<27)
XkbInternalModsMask | ok |  | (1L<<28)
XkbIgnoreLockModsMask | ok |  | (1L<<29)
XkbPerKeyRepeatMask | ok |  | (1L<<30)
XkbControlsEnabledMask | ok |  | (1L<<31)
XkbAccessXOptionsMask | ok | ok | (XkbStickyKeysMask | XkbAccessXFeedbackMask)
XkbAllBooleanCtrlsMask |  | ok | (0x00001FFF)
XkbAllControlsMask | ok |  | (0xF8001FFF)

The individual fields of the XkbControlsRec structure are defined as follows.

###

#### mk_dflt_btn

mk_dflt_btn is an attribute of the MouseKeys control (see section 10.5 ). It specifies the mouse button number to use for keyboard simulated mouse button operations. Its value should be one of the core symbols Button1 - Button5 .

#### num_groups

num_groups is not a part of any control, but is reported in the XkbControlsRec 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.

#### groups_wrap

groups_wrap is an attribute of the GroupsWrap control (see section 10.7.1). It specifies the handling of illegal groups on a global basis. Valid values for groups_wrap are shown in Table 10.8.

##### GroupsWrap options (groups_wrap field)

groups_wrap symbolic name | value
--- | ---
XkbWrapIntoRange | (0x00)
XkbClampIntoRange | (0x40)
XkbRedirectIntoRange | (0x80)

When groups_wrap is set to XkbRedirectIntoRange , its four low-order bits specify the index of the group to use.

#### internal

internal is an attribute of the InternalMods control (see section 10.7.4). It specifies modifiers to be consumed in the server and not passed on to clients when events are reported. Valid values consist of any combination of the eight core modifier bits: ShiftMask , LockMask , ControlMask , Mod1Mask - Mod5Mask .

#### ignore_lock

ignore_lock is an attribute of the IgnoreLockMods control (see section 10.7.2). It specifies modifiers to be ignored in grab calculations. Valid values consist of any combination of the eight core modifier bits: ShiftMask , LockMask , ControlMask , Mod1Mask - Mod5Mask .

#### enabled_ctrls

enabled_ctrls is an attribute of the EnabledControls control (see section 10.1.1). It contains one bit per boolean control. Each 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 enabled_ctrls column.

#### repeat_delay and repeat_interval

repeat_delay and repeat_interval are attributes of the RepeatKeys control (see section 10.3.2). repeat_delay is the initial delay before a key begins repeating, in milliseconds; repeat_interval is the delay between subsequent key events, in milliseconds.

#### slow_keys_delay

slow_keys_delay is an attribute of the SlowKeys control (see section 10.6.6). Its value specifies the SlowKeys acceptance delay period in milliseconds before a key press is accepted by the server.

#### debounce_delay

debounce_delay is an attribute of the BounceKeys control (see section 10.6.7). Its value specifies the BounceKeys 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.

#### mk_delay, mk_interval, mk_time_to_max, mk_max_speed, and mk_curve

mk_delay , mk_interval , mk_time_to_max , mk_max_speed , and mk_curve are attributes of the MouseKeysAccel control. Refer to section 10.5.2 for a description of these fields and the units involved.

#### ax_options

The ax_options field contains attributes used to configure two different controls, the StickyKeys control (see section 10.6.8) and the AccessXFeedback control (see section 10.6.3). The ax_options field is a bitmask and may include any combination of the bits defined in Table 10.9.

##### Access X Enable/Disable Bits (ax_options field)

Access X Control | ax_options bit | value
--- | --- | ---
AccessXFeedback | XkbAX_SKPressFBMask | (1L<<0)
| XkbAX_SKAcceptFBMask | (1L << 1)
| XkbAX_FeatureFBMask | (1L << 2)
| XkbAX_SlowWarnFBMask | (1L << 3)
| XkbAX_IndicatorFBMask | (1L << 4)
| XkbAX_StickyKeysFBMask | (1L << 5)
| XkbAX_SKReleaseFBMask | (1L << 8)
| XkbAX_SKRejectFBMask | (1L << 9)
| XkbAX_BKRejectFBMask | (1L << 10)
| XkbAX_DumbBellFBMask | (1L << 11)
StickyKeys | XkbAX_TwoKeysMask | (1L << 6)
| XkbAX_LatchToLockMask | (1L << 7)
| XkbAX_AllOptionsMask | (0xFFF)

The fields pertaining to each control are relevant only when the control is enabled ( XkbAccessXFeedbackMask or XkbStickyKeysMask bit is turned on in the enabled_cntrls field).

Xkb provides a set of convenience macros for working with the ax_options field of an XkbControlsRec structure:

    #define      XkbAX_NeedOption
    (c,w)      ((c)->ax_options&(w))

The XkbAX_NeedOption macro is useful for determining whether a particular AccessX option is enabled or not. It accepts a pointer to an XkbControlsRec structure and a valid mask bit from Table 10.9. If the specified mask bit in the ax_options field of the controls structure is set, the macro returns the mask bit. Otherwise, it returns zero. Thus,

XkbAX_NeedOption(ctlrec, XkbAX_LatchToLockMask)

is nonzero if the latch to lock transition for latching keys is enabled, and zero if it is disabled. Note that XkbAX_NeedOption only determines whether or not the particular capability is configured to operate; the XkbAccessXFeedbackMask bit must also be turned on in enabled_ctrls for the capability to actually be functioning.

    #define      XkbAX_AnyFeedback
    (c)      ((c)->enabled_ctrls&XkbAccessXFeedbackMask)

The XkbAX_AnyFeeback macro accepts a pointer to an XkbControlsRec structure and tells whether the AccessXFeedback control is enabled or not. If the AccessXFeedback control is enabled, the macro returns XkbAccessXFeedbackMask . Otherwise, it returns zero.

    #define      XkbAX_NeedFeedback
    (c,w)      (XkbAX_AnyFeedback(c)&&XkbAX_NeedOption(c,w))

The XkbAX_NeedFeedback macro is useful for determining if both the AccessXFeedback control and a particular AccessX feedback option are enabled. The macro accepts a pointer to an XkbControlsRec structure and a feedback option from the table above. If both the AccessXFeedback control and the specified feedback option are enabled, the macro returns True . Otherwise it returns False .

#### ax_timeout, axt_opts_mask, axt_opts_values, axt_ctrls_mask, and axt_ctrls_values

ax_timeout , act_opts_mask , axt_opts_values , axt_ctrls_mask , and axt_ctrls_values are attributes of the AccessXTimeout control. Refer to section 10.6.2 for a description of these fields and the units involved.

#### per_key_repeat

The per_key_repeat field mirrors the auto_repeats field of the core protocol XKeyboardState structure: changing the auto_repeats field automatically changes per_key_repeat 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 XkbGetControls . If the per_key_repeat were not in this structure, you would have to call both XGetKeyboardControl and XkbGetControls to get this information. The bits correspond to keycodes. The first seven keys (keycodes 1-7) are indicated in per_key_repeat [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.

## Querying Controls

Use XkbGetControls to find the current state of Xkb server controls.

Status XkbGetControls ( display, which, xkb)
Display * display ; /* connection to X server */
unsigned long which ; /* mask of controls requested */
XkbDescPtr xkb ; /* keyboard description for controls information*/

XkbGetControls 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 ctrls structure of the xkb argument. Only those components specified by the which parameter are copied. Valid values for which are any combination of the masks listed in Table 10.7 that have "ok" in the which column.

If xkb -> ctrls is NULL , XkbGetControls allocates and initializes it before obtaining the values specified by which . If xkb -> ctrls is not NULL , XkbGetControls modifies only those portions of xkb -> ctrls corresponding to the values specified by which .

XkbGetControls returns Success if successful; otherwise, it returns BadAlloc if it cannot obtain sufficient storage, BadMatch if xkb is NULL or which is empty, or BadImplementation .

To free the ctrls member of a keyboard description, use XkbFreeControls (see section 10.12)

The num_groups field in the ctrls structure is always filled in by XkbGetControls , regardless of which bits are selected by which .

## Changing Controls

There are two ways to make changes to controls: either change a local copy keyboard description and call XkbSetControls , or, to reduce network traffic, use an XkbControlsChangesRec structure and call XkbChangeControls .

To change the state of one or more controls, first modify the ctrls structure in a local copy of the keyboard description and then use XkbSetControls to copy those changes to the X server.

Bool XkbSetControls ( display, which, xkb)
Display * display ; /* connection to X server */
unsigned long which ; /* mask of controls to change */
XkbDescPtr xkb ; /* ctrls field contains new values to be set */

For each bit that is set in the which parameter, XkbSetControls sends the corresponding values from the xkb -> ctrls field to the server. Valid values for which are any combination of the masks listed in Table 10.7 that have "ok" in the which column.

If xkb -> ctrls is NULL , the server does not support a compatible version of Xkb, or the Xkb extension has not been properly initialized, XkbSetControls returns False . Otherwise, it sends the request to the X server and returns True .

Note that changes to attributes of controls in the XkbControlsRec structure are apparent only when the associated control is enabled, although the corresponding values are still updated in the X server. For example, the repeat_delay and repeat_interval fields are ignored unless the RepeatKeys control is enabled (that is, the X server’s equivalent of xkb->ctrls has XkbRepeatKeyMask set in enabled_ctrls ). 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 for more information on enabling and disabling controls.

Note that the enabled_ctrls field is itself a control — the EnabledControls control. As such, to set a specific configuration of enabled and disabled boolean controls, you must set enabled_ctrls to the appropriate bits to enable only the controls you want and disable all others, then specify the XkbControlsEnabledMask in a call to XkbSetControls . 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 ( XkbChangeEnabledControls , section 10.1.1).

### The XkbControlsChangesRec Structure

The XkbControlsChangesRec structure allows applications to track modifications to an XkbControlsRec structure and thereby reduce the amount of traffic sent to the server. The same XkbControlsChangesRec structure may be used in several successive modifications to the same XkbControlsRec structure, then subsequently used to cause all of the changes, and only the changes, to be propagated to the server. The XkbControlsChangesRec structure is defined as follows:

    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;     /*  True if
                                                  number of keyboard groups changed */
    } XkbControlsChangesRec,*XkbControlsChangesPtr;

The changed_ctrls field is a mask specifying which logical sets of data in the controls structure have been modified. In this context, modified means set , 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 changed_ctrls are any combination of the masks listed in Table 10.7 that have "ok" in the changed_ctrls column. Setting a bit implies the corresponding data fields from the "Relevant XkbControlsRec Data Fields" column in Table 10.6 have been modified. The enabled_ctrls_changes field specifies which bits in the enabled_ctrls field have changed. If the number of keyboard groups has changed, the num_groups_changed field is set to True.

If you have an Xkb description with controls that have been modified and an XkbControlsChangesRec that describes the changes that have been made, the XkbChangeControls function provides a flexible method for updating the controls in a server to match those in the changed keyboard description.

Bool XkbChangeControls ( dpy, xkb, changes )
Display * dpy ; /* connection to X server */
XkbDescPtr xkb ; /* keyboard description with changed xkb->ctrls */
XkbControlsChangesPtr changes ; /* which parts of xkb->ctrls have changed */

XkbChangeControls copies any controls fields specified by changes from the keyboard description controls structure, xkb -> ctrls , to the server specified by dpy .

## Tracking Changes to Keyboard Controls

Whenever a field in the controls structure changes in the server’s keyboard description, the server sends an XkbControlsNotify event to all interested clients.To receive XkbControlsNotify events under all possible conditions, use XkbSelectEvents (see section 4.3) and pass XkbControlsNotifyMask in both bits_to_change and values_for_bits .

To receive XkbControlsNotify events only under certain conditions, use XkbSelectEventDetails using XkbControlsNotify as the event_type and specifying the desired state changes in bits_to_change and values_for_bits using mask bits from Table 10.7.

The structure for the XkbControlsNotify event is defined as follows:

    typedef struct {
          int            type;            /* Xkb extension base event code */
          unsigned long  serial;          /* X server serial number for event */
          Bool           send_event;      /*  True => synthetically generated */
          Display *      display;         /* server connection where event generated */
          Time           time;            /* server time when event generated */
          int            xkb_type;        /*  XkbCompatMapNotify */
          int            device;          /* Xkb device ID, will not be  XkbUseCoreKbd */
          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 */
    } XkbControlsNotifyEvent;

The changed_ctrls 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 changed_ctrls column.

The controls currently enabled in the server are reported in the enabled_ctrls field. If any controls were just enabled or disabled (that is, the contents of the enabled_ctrls field changed), they are flagged in the enabled_ctrl_changes field. The valid bits for these fields are the masks listed in Table 10.7 with "ok" in the enabled_ctrls column. The num_groups 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.

If the change was caused by a request from a client, the keycode and event_type fields are set to zero and the req_major and req_minor fields identify the request. The req_major value is the same as the major extension opcode. Otherwise, event_type is set to the type of event that caused the change (one of KeyPress , KeyRelease , DeviceKeyPress , DeviceKeyRelease , ButtonPress or ButtonRelease ), and req_major and req_minor are undefined. If event_type is KeyPress , KeyRelease , DeviceKeyPress , or DeviceKeyRelease , the keycode field is set to the key that caused the change. If event_type is ButtonPress or ButtonRelease , keycode contains the button number.

When a client receives an XkbControlsNotify event, it can note the changes in a changes structure using XkbNoteControlsChanges .

void XkbNoteControlsChanges ( changes , new , wanted )
XkbControlsChangesPtr changes ; /* records changes indicated by new */
XkbControlsNotifyEvent * new ; /* tells which things have changed */
unsigned int wanted ; /* tells which parts of new to record in changes */

The wanted parameter is a bitwise inclusive OR of bits taken from the set of masks specified in Table 10.7 with "ok" in the changed_ctrls column. XkbNoteControlsChanges copies any changes reported in new and specified in wanted into the changes record specified by old .

Use XkbGetControlsChanges to update a local copy of a keyboard description with the changes previously noted by one or more calls to XkbNoteControlsChanges.

Status XkbGetControlsChanges ( dpy , xkb , changes )
Display * dpy ; /* connection to X server */
XkbDescPtr xkb ; /* xkb->ctrls will be updated */
XkbNameChangesPtr changes ; /* indicates which parts of xkb->ctrls to update */

XkbGetControlsChanges examines the changes parameter, queries the server for the necessary information, and copies the results into the xkb -> ctrls keyboard description. If the ctrls field of xkb is NULL , XkbGetControlsChanges allocates and initializes it. To free the ctrls field, use XkbFreeControls (see section 10.12).

XkbGetControlsChanges returns Success if successful and can generate BadAlloc , BadImplementation, and BadMatch errors.

## Allocating and Freeing an XkbControlsRec

The need to allocate an XkbControlsRec structure seldom arises; Xkb creates one when an application calls XkbGetControls or a related function. For those situations where there is not an XkbControlsRec structure allocated in the XkbDescRec , allocate one by calling XkbAllocControls .

Status XkbAllocControls ( xkb, which )
XkbDescPtr xkb ; /* Xkb description in which to allocate ctrls rec */
unsigned int which ; /* mask of components of ctrls to allocate */

XkbAllocControls allocates the ctrls field of the xkb parameter, initializes all fields to zero, and returns Success . If the ctrls field is not NULL , XkbAllocControls simply returns Success . If xkb is NULL , XkbAllocControls reports a BadMatch error. If the ctrls field could not be allocated, it reports a BadAlloc error.

The which mask specifies the individual fields of the ctrls 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.

To free memory used by the ctrls member of an XkbDescRec structure, use XkbFreeControls:

void XkbFreeControls ( xkb, which, free_all )
XkbDescPtr xkb ; /* Xkb description in which to free controls components */
unsigned int which ; /* mask of components of ctrls to free */
Bool free_all ; /* True => free everything + ctrls itself */

XkbFreeControls frees the specified components of the ctrls field in the xkb keyboard description and sets the corresponding structure component values to NULL or zero . The which mask specifies the fields of ctrls to be freed and can contain any of the controls components specified in Table 10.7.

If free_all is True , XkbFreeControls frees every non- NULL structure component in the controls, frees the XkbControlsRec structure referenced by the ctrls member of xkb , and sets ctrls to NULL.

## The Miscellaneous Per-client Controls

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 of the XKB Protocol specification for more details.

To get the current values of the per-client controls, use XkbGetPerClientControls .

Bool XkbGetPerClientControls ( dpy , ctrls )
Display * dpy ; /* connection to X server */
unsigned int * ctrls ; /* 1 bit => corresponding control is on */

XkbGetPerClientControls backfills ctrls with the per-client control attributes for this particular client. It returns True if successful, and False otherwise.

To change the current values of the per-client control attributes, use XkbSetPerClientControls.

Bool XkbSetPerClientControls ( dpy , ctrls )
Display * dpy ; /* connection to X server */
unsigned int change ; /* 1 bit => change control */
unsigned int * value ; /* 1 bit => control on */

XkbSetPerClientControls changes the per-client values for the controls selected by 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 per-client control attributes for this particular client. It returns True if successful, and False otherwise.