# Keyboard Indicators

Although the core X protocol supports thirty-two LEDs on a keyboard, it does not provide any way to link the state of the LEDs and the logical state of the keyboard. For example, most keyboards have a "Caps Lock" LED, but X does not provide any standard way to make the LED automatically follow the logical state of the modifier bound to the Caps Lock key.

The core protocol also gives no way to determine which bits in the led_mask field of the keyboard state map to the particular LEDs on the keyboard. For example, X does not provide a method for a client to determine which bit to set in the led_mask to turn on the "Scroll Lock" LED, or even if the keyboard has a "Scroll Lock" LED.

Most X servers implement some kind of automatic behavior for one or more of the keyboard LEDs, but the details of that automatic behavior are implementation-specific and can be difficult or impossible to control.

XKB provides indicator names and programmable indicators to help solve these problems. Using XKB, clients can determine the names of the various indicators, determine and control the way that the individual indicators should be updated to reflect keyboard changes, and determine which of the 32 keyboard indicators reported by the protocol are actually present on the keyboard. Clients may also request immediate notification of changes to the state of any subset of the keyboard indicators, which makes it straightforward to provide an on-screen "virtual" LED panel.

## Global Information About Indicators

XKB provides only two pieces of information about the indicators as a group.

The physical indicators mask reports which of the 32 logical keyboard indicators supported by the core protocol and XKB corresponds to some actual indicator on the keyboard itself. Because the physical indicators mask describes a physical characteristic of the keyboard, it cannot be directly changed under program control. It is possible, however, for the set of physical indicators to be change if a new keyboard is attached or if a completely new keyboard description is loaded by the XkbGetKeyboardByName request (see Using the Server’s Database of Keyboard Components).

The indicator state mask reports the current state of the 32 logical keyboard indicators. This field and the core protocol indicator state (as reported by the led-mask field of the core protocol GetKeyboardControl request) are always identical.

## Per-Indicator Information

Each of the thirty-two keyboard indicators has a symbolic name, of type ATOM. The XkbGetNames request reports the symbolic names for all keyboard components, including the indicators. Use the XkbSetNames request to change symbolic names. Both requests are described in Querying and Changing Symbolic Names.

### Indicator Maps

XKB also provides an indicator map for each of the thirty-two keyboard indicators; an indicator map specifies:

- The conditions under which the keyboard modifier state affects the indicator.

- The conditions under which the keyboard group state affects the indicator.

- The conditions under which the state of the boolean controls affects the indicator.

- The effect (if any) of attempts to explicitly change the state of the indicator using the core protocol SetKeyboardControl request.

If IM_NoAutomatic is set in the flags field of an indicator map, that indicator never changes in response to changes in keyboard state or controls, regardless of the values for the other fields of the indicator map. If IM_NoAutomatic is not set in flags , the other fields of the indicator map specify the automatic changes to the indicator in response to changes in the keyboard state or controls.

The which_groups and the groups fields of an indicator map determine how the keyboard group state affects the corresponding indicator. The which_groups field controls the interpretation of groups and may contain any one of the following values:

Value | Interpretation of the Groups Field
--- | ---
IM_UseNone | The groups field and the current keyboard group state are ignored.
IM_UseBase | If groups is non-zero, the indicator is lit whenever the base keyboard group is non-zero. If groups is zero, the indicator is lit whenever the base keyboard group is zero.
IM_UseLatched | If groups is non-zero, the indicator is lit whenever the latched keyboard group is non-zero. If groups is zero, the indicator is lit whenever the latched keyboard group is zero.
IM_UseLocked | The groups field is interpreted as a mask. The indicator is lit when the current locked keyboard group matches one of the bits that are set in groups .
IM_UseEffective | The groups field is interpreted as a mask. The indicator is lit when the current effective keyboard group matches one of the bits that are set in groups .

The which_mods and mods fields of an indicator map determine how the state of the keyboard modifiers affect the corresponding indicator. The mods field is an XKB modifier definition, as described in Modifier Definitions, which can specify both real and virtual modifiers. The mods field takes effect even if some or all of the virtual indicators specified in mods are unbound.

The which_mods field can specify one or more components of the XKB keyboard state. The corresponding indicator is lit whenever any of the real modifiers specified in the mask field of the mods modifier definition are also set in any of the current keyboard state components specified by the which_mods . The which_mods field may have any combination of the following values:

Value | Keyboard State Component To Be Considered
--- | ---
IM_UseBase | Base modifier state
IM_UseLatched | Latched modifier state
IM_UseLocked | Locked modifier state
IM_UseEffective | Effective modifier state
IM_UseCompat | Modifier compatibility state

The controls field specifies a subset of the boolean keyboard controls (see "Boolean" Controls and The EnabledControls Control). The indicator is lit whenever any of the boolean controls specified in controls are enabled.

An indicator is lit whenever any of the conditions specified by its indicator map are met, unless overridden by the IM_NoAutomatic flag (described above) or an explicit indicator change (described below).

#### Effects of Explicit Changes on Indicators

If the IM_NoExplicit flag is set in an indicator map, attempts to change the state of the indicator are ignored.

If both IM_NoExplicit and IM_NoAutomatic are both absent from an indicator map, requests to change the state of the indicator are honored but might be immediately superseded by automatic changes to the indicator state which reflect changes to keyboard state or controls.

If the IM_LEDDrivesKB flag is set and the IM_NoExplicit flag is not, the keyboard state and controls are changed to reflect the other fields of the indicator map, as described in the remainder of this section. Attempts to explicitly change the value of an indicator for which IM_LEDDrivesKB is absent or for which IM_NoExplicit is present do not affect keyboard state or controls.

The effect on group state of changing an explicit indicator which drives the keyboard is determined by the value of which_groups and groups , as follows:

which_groups | New State | Effect on Keyboard Group State
--- | --- | ---
IM_UseNone , or IM_UseBase | On or Off | No Effect
IM_UseLatched | On | The groups field is treated as a group mask. The keyboard group latch is changed to the lowest numbered group specified in groups ; if groups is empty, the keyboard group latch is changed to zero.
IM_UseLatched | Off | The groups field is treated as a group mask. If the indicator is explicitly extinguished, keyboard group latch is changed to the lowest numbered group not specified in groups ; if groups is zero, the keyboard group latch is set to the index of the highest legal keyboard group.
IM_UseLocked , or IM_UseEffective | On | If the groups mask is empty, group is not changed, otherwise the locked keyboard group is changed to the lowest numbered group specified in groups .
IM_UseLocked , or IM_UseEffective | Off | Locked keyboard group is changed to the lowest numbered group that is not specified in the groups mask, or to Group1 if the groups mask contains all keyboard groups.

The effect on the keyboard modifiers of changing an explicit indicator which drives the keyboard is determined by the values that are set in of which_mods and mods , as follows:

Set in which_mods | New State | Effect on Keyboard Modifiers
--- | --- | ---
IM_UseBase | On or Off | No Effect
IM_UseLatched | On | Any modifiers specified in the mask field of mods are added to the latched modifiers.
IM_UseLatched | Off | Any modifiers specified in the mask field of mods are removed from the latched modifiers.
IM_UseLocked , IM_UseCompat , or IM_UseEffective | On | Any modifiers specified in the mask field of mods are added to the locked modifiers.
IM_UseLocked | Off | Any modifiers specified in the mask field of mods are removed from the locked modifiers.
IM_UseCompat , or IM_UseEffective | Off | Any modifiers specified in the mask field of mods are removed from both the locked and latched modifiers.

Lighting an explicit indicator which drives the keyboard also enables all of the boolean controls specified in the controls field of its indicator map. Explicitly extinguishing such an indicator disables all of the boolean controls specified in controls .

The effects of changing an indicator which drives the keyboard are cumulative; it is possible for a single change to affect keyboard group, modifiers and controls simultaneously.

If an indicator for which both the IM_LEDDrivesKB and IM_NoAutomatic flags are specified is changed, the keyboard changes specified above are applied and the indicator is changed to reflect the state that was explicitly requested. The indicator will remain in the new state until it is explicitly changed again.

If the IM_NoAutomatic flag is not set for an indicator which drives the keyboard, the changes specified above are applied and the state of the indicator is set to the values specified by the indicator map. Note that it is possible in this case for the indicator to end up in a different state than the one that was explicitly requested. For example, an indicator with which_mods of IM_UseBase and mods of Shift is not extinguished if one of the Shift keys is physically depressed when the request to extinguish the indicator is processed.