aboutsummaryrefslogtreecommitdiff
path: root/libX11/specs/XKB/ch08.xml
diff options
context:
space:
mode:
Diffstat (limited to 'libX11/specs/XKB/ch08.xml')
-rw-r--r--libX11/specs/XKB/ch08.xml2087
1 files changed, 2087 insertions, 0 deletions
diff --git a/libX11/specs/XKB/ch08.xml b/libX11/specs/XKB/ch08.xml
new file mode 100644
index 000000000..0d19a3d7a
--- /dev/null
+++ b/libX11/specs/XKB/ch08.xml
@@ -0,0 +1,2087 @@
+<chapter id='indicators'>
+<title>Indicators</title>
+
+<para>
+Although the core X implementation supports up to 32 LEDs on an input device,
+it does not provide any linkage between the state of the LEDs and the logical
+state of the input device. For example, most keyboards have a <emphasis>
+CapsLock</emphasis>
+ LED, but X does not provide a mechanism to make the LED automatically follow
+the logical state of the <emphasis>
+CapsLock</emphasis>
+ key.
+</para>
+
+
+<para>
+Furthermore, the core X implementation does not provide clients with the
+ability to determine what bits in the <emphasis>
+led_mask</emphasis>
+ field of the <emphasis>
+XKeyboardState</emphasis>
+ map to the particular LEDs on the keyboard. For example, X does not provide a
+method for a client to determine what bit to set in the <emphasis>
+led_mask</emphasis>
+ field to turn on the <emphasis>
+Scroll Lock </emphasis>
+LED or whether the keyboard even has a <emphasis>
+Scroll Lock</emphasis>
+ LED.
+</para>
+
+
+<para>
+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. This chapter describes Xkb indicators and the functions
+used for manipulating them.
+</para>
+
+<sect1 id='indicator_names'>
+<title>Indicator Names</title>
+
+<para>
+Xkb provides the capability of symbolically naming indicators. Xkb itself
+doesn’t use these symbolic names for anything; they are there only to help
+make the keyboard description comprehensible to humans. To set the names of
+specific indicators, use <emphasis>
+XkbSetNames</emphasis>
+ as discussed in Chapter 18. Then set the map using <emphasis> <!-- xref -->
+XkbSetMap</emphasis>
+ (see section 14.3) or <emphasis> <!-- xref -->
+XkbSetNamedIndicator</emphasis>
+ (below). To retrieve indicator names, use <emphasis>
+XkbGetNames</emphasis>
+ (Chapter 18). <!-- xref -->
+</para>
+
+
+</sect1>
+<sect1 id='indicator_data_structures'>
+<title>Indicator Data Structures</title>
+
+<para>
+Use the indicator description record, <emphasis>
+XkbIndicatorRec</emphasis>
+, and its indicator map, <emphasis>
+XkbIndicatorMapRec</emphasis>
+, to inquire about and control most indicator properties and behaviors.
+</para>
+
+
+<sect2 id='xkbindicatorrec'>
+<title>XkbIndicatorRec</title>
+
+<para>
+The description for all the Xkb indicators is held in the <emphasis>
+indicators</emphasis>
+ field of the complete keyboard description (see Chapter 6), which is defined <!-- xref -->
+as follows:
+</para>
+
+<para><programlisting>
+#define XkbNumIndicators 32
+</programlisting></para>
+<para><programlisting>
+typedef struct {
+ unsigned long phys_indicators; /* LEDs existence */
+ XkbIndicatorMapRec maps[XkbNumIndicators]; /* indicator maps */
+} <emphasis>XkbIndicatorRec</emphasis>,*XkbIndicatorPtr;
+</programlisting></para>
+
+<para>
+This structure contains the <emphasis>
+phys_indicators</emphasis>
+ field, which relates some information about the correspondence between
+indicators and physical LEDs on the keyboard, and an array of indicator
+<emphasis>
+maps</emphasis>
+, one map per indicator.
+</para>
+
+<para>
+The <emphasis>
+phys_indicators</emphasis>
+ field indicates which indicators are bound to physical LEDs on the keyboard;
+if a bit is set in <emphasis>
+phys_indicators</emphasis>
+, then the associated indicator has a physical LED associated with it. This
+field is necessary because some indicators may not have corresponding physical
+LEDs on the keyboard. For example, most keyboards have an LED for indicating
+the state of <emphasis>
+CapsLock</emphasis>
+, but most keyboards do not have an LED that indicates the current group.
+Because <emphasis>
+phys_indicators</emphasis>
+ describes a physical characteristic of the keyboard, you cannot directly
+change it under program control. However, if a client program loads a
+completely new keyboard description via <emphasis>
+XkbGetKeyboardByName</emphasis>
+, or if a new keyboard is attached and the X implementation notices, <emphasis>
+phys_indicators</emphasis>
+ changes if the indicators for the new keyboard are different.
+</para>
+
+
+</sect2>
+<sect2 id='xkbindicatormaprec'>
+<title>XkbIndicatorMapRec</title>
+
+<para>
+Each indicator has its own set of attributes that specify whether clients can
+explicitly set its state and whether it tracks the keyboard state. The
+attributes of each indicator are held in the <emphasis>
+maps</emphasis>
+ array, which is an array of <emphasis>
+XkbIndicatorRec</emphasis>
+ structures:
+</para>
+
+<para><programlisting>
+typedef struct {
+ unsigned char flags; /* how the indicator can be changed */
+ unsigned char which_groups; /* match criteria for groups */
+ unsigned char groups; /* which keyboard groups the indicator watches */
+ unsigned char which_mods; /* match criteria for modifiers */
+ XkbModsRec mods; /* which modifiers the indicator watches */
+ unsigned int ctrls; /* which controls the indicator watches */
+} <emphasis>XkbIndicatorMapRec</emphasis>, *XkbIndicatorMapPtr;
+</programlisting></para>
+
+<para>
+This indicator map specifies for each indicator:
+</para>
+
+<itemizedlist>
+<listitem>
+ <para>
+The conditions under which the keyboard modifier state affects the indicator
+ </para>
+</listitem>
+<listitem>
+ <para>
+The conditions under which the keyboard group state affects the indicator
+ </para>
+</listitem>
+<listitem>
+ <para>
+The conditions under which the state of the boolean controls affects the
+indicator
+ </para>
+</listitem>
+<listitem>
+ <para>
+The effect (if any) of attempts to explicitly change the state of the indicator
+using the functions <emphasis>
+XkbSetControls</emphasis>
+ or <emphasis>
+XChangeKeyboardControl</emphasis>
+
+ </para>
+</listitem>
+</itemizedlist>
+
+<para>
+For more information on the effects of explicit changes to indicators and the
+relationship to the indicator map, see section 8.4.1. <!-- xref -->
+</para>
+
+<sect3 id='xkbindicatormaprec_flags_field'>
+<title>XkbIndicatorMapRec flags field</title>
+
+<para>
+The <emphasis>
+flags</emphasis>
+ field specifies the conditions under which the indicator can be changed and
+the effects of changing the indicator. The valid values for <emphasis>
+flags</emphasis>
+ and their effects are shown in Table 8.1. <!-- xref -->
+</para>
+
+<table frame='none'>
+<title>XkbIndicatorMapRec flags Field</title>
+<tgroup cols='3'>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>Value</entry>
+ <entry></entry>
+ <entry>Effect</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='0'>
+ <entry>XkbIM_NoExplicit</entry>
+ <entry>(1L&lt;&lt;7)</entry>
+ <entry>Client applications cannot change the state of the indicator.</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_NoAutomatic</entry>
+ <entry>(1L&lt;&lt;6)</entry>
+ <entry>Xkb does not automatically change the value of the indicator based
+upon a change in the keyboard state, regardless of the values for the other
+fields of the indicator map.</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_LEDDrivesKB</entry>
+ <entry>(1L&lt;&lt;5)</entry>
+ <entry>A client application changing the state of the indicator causes the
+state of the keyboard to change.</entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+Note that if <emphasis>
+XkbIM_NoAutomatic</emphasis>
+ is not set, by default the indicator follows the keyboard state.
+</para>
+
+
+<para>
+If <emphasis>
+XkbIM_LEDDrivesKB</emphasis>
+ is set and <emphasis>
+XkbIM_NoExplicit</emphasis>
+ is not, and if you call a function which updates the server’s image of the
+indicator map (such as <emphasis>
+XkbSetIndicatorMap</emphasis>
+ or <emphasis>
+XkbSetNamedIndicator</emphasis>
+), Xkb changes the keyboard state and controls to reflect the other fields of
+the indicator map, as described in the remainder of this section. If you
+attempt to explicitly change the value of an indicator for which <emphasis>
+XkbIM_LEDDrivesKB</emphasis>
+ is absent or for which <emphasis>
+XkbIM_NoExplicit</emphasis>
+ is present, keyboard state or controls are unaffected.
+</para>
+
+
+<para>
+For example, a keyboard designer may want to make the <emphasis>
+CapsLock</emphasis>
+ LED controllable only by the server, but allow the <emphasis>
+Scroll Lock</emphasis>
+ LED to be controlled by client applications. To do so, the keyboard designer
+could set the <emphasis>
+XkbIM_NoExplicit</emphasis>
+ flag for the <emphasis>
+CapsLock</emphasis>
+<emphasis>
+ </emphasis>
+LED, but not set it for the <emphasis>
+Scroll Lock</emphasis>
+ LED. Or the keyboard designer may wish to allow the <emphasis>
+CapsLock</emphasis>
+ LED to be controlled by both the server and client applications and also have
+the server to automatically change the <emphasis>
+CapsLock</emphasis>
+<emphasis>
+ </emphasis>
+modifier state whenever a client application changes the <emphasis>
+CapsLock</emphasis>
+ LED. To do so, the keyboard designer would not set the <emphasis>
+XkbIM_NoExplicit</emphasis>
+ flag, but would instead set the <emphasis>
+XkbIM_LEDDrivesKB</emphasis>
+ flag.
+</para>
+
+<para>
+The remaining fields in the indicator map specify the conditions under which
+Xkb automatically turns an indicator on or off (only if <emphasis>
+XkbIM_NoAutomatic</emphasis>
+ is not set). If these conditions match the keyboard state, Xkb turns the
+indicator on. If the conditions do not match, Xkb turns the indicator off.
+</para>
+
+</sect3>
+
+<sect3 id='xkbindicatormaprec_which_groups_and_groups_fields'>
+<title>XkbIndicatorMapRec which_groups and groups fields</title>
+
+<para>
+The <emphasis>
+which_groups</emphasis>
+ and the <emphasis>
+groups</emphasis>
+ fields of an indicator map determine how the keyboard group state affects the
+corresponding indicator. The <emphasis>
+which_groups</emphasis>
+ field controls the interpretation of <emphasis>
+groups</emphasis>
+ and may contain any one of the following values:
+</para>
+
+<para><programlisting>
+#define XkbIM_UseNone 0
+#define XkbIM_UseBase (1L &lt;&lt; 0)
+#define XkbIM_UseLatched (1L &lt;&lt; 1)
+#define XkbIM_UseLocked (1L &lt;&lt; 2)
+#define XkbIM_UseEffective (1L &lt;&lt; 3)
+#define XkbIM_UseAnyGroup XkbIM_UseLatched | XkbIM_UseLocked |
+ XkbIM_UseEffective
+</programlisting></para>
+
+<para>
+The <emphasis>
+groups </emphasis>
+field specifies what keyboard groups an indicator watches and is the bitwise
+inclusive OR of the following valid values:
+</para>
+
+<para><programlisting>
+#define XkbGroup1Mask (1&lt;&lt;0)
+#define XkbGroup2Mask (1&lt;&lt;1)
+#define XkbGroup3Mask (1&lt;&lt;2)
+#define XkbGroup4Mask (1&lt;&lt;3)
+#define XkbAnyGroupMask (1&lt;&lt;7)
+#define XkbAllGroupsMask (0xf)
+</programlisting></para>
+
+<para>
+If <emphasis>
+XkbIM_NoAutomatic</emphasis>
+ is not set (the keyboard drives the indicator), the effect of <emphasis>
+which_groups</emphasis>
+ and <emphasis>
+groups</emphasis>
+ is shown in Table 8.2. <!-- xref -->
+</para>
+
+<table frame='none'>
+<title>XkbIndicatorMapRec which_groups and groups, Keyboard Drives
+Indicator</title>
+<tgroup cols='2'>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>which_groups</entry>
+ <entry>Effect</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='0'>
+ <entry>XkbIM_UseNone</entry>
+ <entry>
+The <emphasis>
+groups</emphasis>
+ field and the current keyboard group state are ignored.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseBase</entry>
+ <entry>
+If <emphasis>
+groups</emphasis>
+ is nonzero, the indicator is lit whenever the base keyboard group is nonzero.
+If <emphasis>
+groups</emphasis>
+ is zero, the indicator is lit whenever the base keyboard group is zero.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseLatched</entry>
+ <entry>
+If <emphasis>
+groups</emphasis>
+ is nonzero, the indicator is lit whenever the latched keyboard group is
+nonzero. If <emphasis>
+groups</emphasis>
+ is zero, the indicator is lit whenever the latched keyboard group is zero.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseLocked</entry>
+ <entry>
+The <emphasis>
+groups</emphasis>
+ 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 <emphasis>
+groups</emphasis>.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseEffective</entry>
+ <entry>
+The <emphasis>
+groups</emphasis>
+ 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 <emphasis>
+groups</emphasis>
+.
+ </entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+The effect of <emphasis>
+which_groups</emphasis>
+ and <emphasis>
+groups</emphasis>
+ when you change an indicator for which <emphasis>
+XkbIM_LEDDrivesKB</emphasis>
+ is set (the indicator drives the keyboard) is shown in Table 8.3. The "New
+State" column refers to the new state to which you set the indicator.
+</para>
+
+<table frame='none'>
+<title>XkbIndicatorMapRec which_groups and groups, Indicator Drives
+Keyboard</title>
+<tgroup cols='3'>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>which_groups</entry>
+ <entry>New State</entry>
+ <entry>Effect on Keyboard Group State</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='0'>
+ <entry>XkbIM_UseNone </entry>
+ <entry>On or Off</entry>
+ <entry>No effect</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseBase</entry>
+ <entry>On or Off</entry>
+ <entry>No effect</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseLatched</entry>
+ <entry>On</entry>
+ <entry>
+The <emphasis>
+groups</emphasis>
+ field is treated as a group mask. The keyboard group latch is changed to the
+lowest numbered group specified in <emphasis>
+groups</emphasis>
+; if <emphasis>
+groups</emphasis>
+ is empty, the keyboard group latch is changed to zero.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseLatched</entry>
+ <entry>Off</entry>
+ <entry>
+The <emphasis>
+groups</emphasis>
+ 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
+<emphasis>
+groups</emphasis>
+; if <emphasis>
+groups</emphasis>
+ is zero, the keyboard group latch is set to the index of the highest legal
+keyboard group.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseLocked or XkbIM_UseEffective</entry>
+ <entry>On</entry>
+ <entry>
+If the <emphasis>
+groups</emphasis>
+ mask is empty, group is not changed; otherwise, the locked keyboard group is
+changed to the lowest numbered group specified in <emphasis>
+groups</emphasis>.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseLocked or XkbIM_UseEffective</entry>
+ <entry>Off</entry>
+ <entry>
+Locked keyboard group is changed to the lowest numbered group that is not
+specified in the <emphasis>
+groups</emphasis>
+ mask, or to <emphasis>
+Group1</emphasis>
+ if the <emphasis>
+groups</emphasis>
+ mask contains all keyboard groups.
+ </entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+</sect3>
+<sect3 id='xkbindicatormaprec_which_mods_and_mods_fields'>
+<title>XkbIndicatorMapRec which_mods and mods fields</title>
+
+<para>
+The <emphasis>
+mods </emphasis>
+field specifies what modifiers an indicator watches. The <emphasis>
+mods</emphasis>
+ field is an Xkb modifier definition, <emphasis>
+XkbModsRec</emphasis>
+, as described in section 7.2, which can specify both real and virtual <!-- xref -->
+modifiers. The <emphasis>
+mods</emphasis>
+ field takes effect even if some or all of the virtual indicators specified in
+<emphasis>
+mods</emphasis>
+ are unbound. To specify the mods field, in general, assign the modifiers of
+interest to <emphasis>
+mods.real_mods</emphasis>
+ and the virtual modifiers of interest to <emphasis>
+mods.vmods</emphasis>
+. You can disregard the <emphasis>
+mods.mask</emphasis>
+ field unless your application needs to interpret the indicator map directly
+(that is, to simulate automatic indicator behavior on its own). Relatively few
+applications need to do so, but if you find it necessary, you can either read
+the indicator map back from the server after you update it (the server
+automatically updates the mask field whenever any of the real or virtual
+modifiers are changed in the modifier definition) or you can use <emphasis>
+XkbVirtualModsToReal</emphasis>
+ to determine the proper contents for the mask field, assuming that the
+<emphasis>
+XkbDescRec</emphasis>
+ contains the virtual modifier definitions.
+</para>
+
+<para>
+<emphasis>
+which_mods</emphasis>
+ specifies what criteria Xkb uses to determine a match with the corresponding
+<emphasis>
+mods</emphasis>
+ field by specifying one or more components of the Xkb keyboard state. If
+<emphasis>
+XkbIM_NoAutomatic</emphasis>
+ is not set (the keyboard drives the indicator), the indicator is lit whenever
+any of the modifiers specified in the <emphasis>
+mask</emphasis>
+ field of the<emphasis>
+ mods</emphasis>
+ modifier definition are also set in any of the current keyboard state
+components specified by <emphasis>
+which_mods</emphasis>
+. Remember that the <emphasis>
+mask</emphasis>
+ field is comprised of all of the real modifiers specified in the definition
+plus any real modifiers that are bound to the virtual modifiers specified in
+the definition. (See Chapter 5 for more information on the keyboard state and <!-- xref -->
+Chapter 7 for more information on virtual modifiers.) Use a bitwise inclusive
+OR of the following values to compose a value for <emphasis>
+which_mods</emphasis>:
+</para>
+
+<para><programlisting>
+#define XkbIM_UseNone 0
+#define XkbIM_UseBase (1L &lt;&lt; 0)
+#define XkbIM_UseLatched (1L &lt;&lt; 1)
+#define XkbIM_UseLocked (1L &lt;&lt; 2)
+#define XkbIM_UseEffective (1L &lt;&lt; 3)
+#define XkbIM_UseCompat (1L &lt;&lt; 4)
+#define XkbIM_UseAnyMods XkbIM_UseBase | XkbIM_UseLatched |
+ XkbIM_UseLocked | XkbIM_UseEffective |
+ XkbIM_UseCompat
+</programlisting></para>
+
+<para>
+If <emphasis>
+XkbIM_NoAutomatic</emphasis>
+ is not set (the keyboard drives the indicator), the effect of <emphasis>
+which_mods</emphasis>
+ and <emphasis>
+mods</emphasis>
+ is shown in Table 8.4 <!-- xref -->
+</para>
+
+<table frame='none'>
+<title>XkbIndicatorMapRec which_mods and mods, Keyboard Drives Indicator</title>
+<tgroup cols='2'>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>which_mods</entry>
+ <entry>Effect on Keyboard Modifiers</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='0'>
+ <entry>XkbIM_UseNone</entry>
+ <entry>The mods field and the current keyboard modifier state are
+ignored.</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseBase</entry>
+ <entry>
+The indicator is lit when any of the modifiers specified in the <emphasis>
+mask</emphasis>
+ field of <emphasis>
+mods</emphasis>
+ are on in the keyboard base state. If both <emphasis>
+mods.real_mods</emphasis>
+ and <emphasis>
+mods.vmods</emphasis>
+ are zero, the indicator is lit when the base keyboard state contains no
+modifiers.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseLatched</entry>
+ <entry>
+The indicator is lit when any of the modifiers specified in the <emphasis>
+mask</emphasis>
+ field of <emphasis>
+mods</emphasis>
+ are latched. If both <emphasis>
+mods.real_mods</emphasis>
+ and <emphasis>
+mods.vmods</emphasis>
+ are zero, the indicator is lit when none of the modifier keys are latched.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseLocked</entry>
+ <entry>
+The indicator is lit when any of the modifiers specified in the <emphasis>
+mask</emphasis>
+ field of <emphasis>
+mods</emphasis>
+ are locked. If both <emphasis>
+mods.real_mods</emphasis>
+ and <emphasis>
+mods.vmods</emphasis>
+ are zero, the indicator is lit when none of the modifier keys are locked.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseEffective</entry>
+ <entry>
+The indicator is lit when any of the modifiers specified in the <emphasis>
+mask</emphasis>
+ field of <emphasis>
+mods</emphasis>
+ are in the effective keyboard state. If both <emphasis>
+mods.real_mods</emphasis>
+ and <emphasis>
+mods.vmods</emphasis>
+ are zero, the indicator is lit when the effective keyboard state contains no
+modifiers.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseCompat</entry>
+ <entry>
+The indicator is lit when any of the modifiers specified in the <emphasis>
+mask</emphasis>
+ field of <emphasis>
+mods</emphasis>
+ are in the keyboard compatibility state. If both <emphasis>
+mods.real_mods</emphasis>
+ and <emphasis>
+mods.vmods</emphasis>
+ are zero, the indicator is lit when the keyboard compatibility state contains
+no modifiers.
+ </entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+The effect on the keyboard modifiers of <emphasis>
+which_mods</emphasis>
+ and <emphasis>
+mods</emphasis>
+ when you change an indicator for which <emphasis>
+XkbIM_LEDDrivesKB</emphasis>
+ is set (the indicator drives the keyboard) is shown in Table 8.5. The "New
+State" column refers to the new state to which you set the indicator.
+</para> <!-- xref -->
+
+<table frame='none'>
+<title>XkbIndicatorMapRec which_mods and mods, Indicator Drives Keyboard</title>
+<tgroup cols='3'>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>which_mods</entry>
+ <entry>New State</entry>
+ <entry>Effect on Keyboard Modifiers</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='0'>
+ <entry>XkbIM_UseNone or XkbIM_UseBase</entry>
+ <entry>On or Off</entry>
+ <entry>No Effect</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseLatched</entry>
+ <entry>On</entry>
+ <entry>
+Any modifiers specified in the <emphasis>
+mask</emphasis>
+ field of <emphasis>
+mods</emphasis>
+ are added to the latched modifiers.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseLatched</entry>
+ <entry>Off</entry>
+ <entry>
+Any modifiers specified in the <emphasis>
+mask</emphasis>
+ field of <emphasis>
+mods</emphasis>
+ are removed from the latched modifiers.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseLocked, XkbIM_UseCompat, or XkbIM_UseEffective</entry>
+ <entry>On</entry>
+ <entry>
+Any modifiers specified in the <emphasis>
+mask</emphasis>
+ field of <emphasis>
+mods</emphasis>
+ are added to the locked modifiers.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseLocked</entry>
+ <entry>Off</entry>
+ <entry>
+Any modifiers specified in the <emphasis>
+mask</emphasis>
+ field of <emphasis>
+mods</emphasis>
+ are removed from the locked modifiers.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>XkbIM_UseCompat or XkbIM_UseEffective</entry>
+ <entry>Off</entry>
+ <entry>
+Any modifiers specified in the <emphasis>
+mask</emphasis>
+ field of <emphasis>
+mods</emphasis>
+ are removed from both the locked and latched modifiers.
+ </entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+</sect3>
+<sect3 id='xkbindicatormaprec_ctrls_field'>
+<title>XkbIndicatorMapRec ctrls field</title>
+
+<para>
+The <emphasis>
+ctrls</emphasis>
+ field specifies what controls (see Chapter 10) the indicator watches and is
+composed using the bitwise inclusive OR of the following values:
+</para> <!-- xref -->
+
+<para><programlisting>
+#define XkbRepeatKeysMask (1L &lt;&lt; 0)
+#define XkbSlowKeysMask (1L &lt;&lt; 1)
+#define XkbBounceKeysMask (1L &lt;&lt; 2)
+#define XkbStickyKeysMask (1L &lt;&lt; 3)
+#define XkbMouseKeysMask (1L &lt;&lt; 4)
+#define XkbMouseKeysAccelMask (1L &lt;&lt; 5)
+#define XkbAccessXKeysMask (1L &lt;&lt; 6)
+#define XkbAccessXTimeoutMask (1L &lt;&lt; 7)
+#define XkbAccessXFeedbackMask (1L &lt;&lt; 8)
+#define XkbAudibleBellMask (1L &lt;&lt; 9)
+#define XkbOverlay1Mask (1L &lt;&lt; 10)
+#define XkbOverlay2Mask (1L &lt;&lt; 11)
+#define XkbAllBooleanCtrlsMask (0x00001FFF)
+</programlisting></para>
+
+<para>
+Xkb lights the indicator whenever any of the boolean controls specified in
+<emphasis>
+ctrls</emphasis>
+ is enabled.
+</para>
+
+
+</sect3>
+</sect2>
+</sect1>
+<sect1 id='getting_information_about_indicators'>
+<title>Getting Information About Indicators</title>
+
+<para>
+Xkb allows applications to obtain information about indicators using two
+different methods. The first method, which is similar to the core X
+implementation, uses a mask to specify the indicators. The second method, which
+is more suitable for applications concerned with interoperability, uses
+indicator names. The correspondence between the indicator name and the bit
+position in masks is as follows: one of the parameters returned from <emphasis>
+XkbGetNamedIndicators</emphasis>
+ is an index that is the bit position to use in any function call that requires
+a mask of indicator bits, as well as the indicator’s index into the <emphasis>
+XkbIndicatorRec</emphasis>
+ array of indicator maps.
+</para>
+
+
+<sect2 id='getting_indicator_state'>
+<title>Getting Indicator State</title>
+
+<para>
+Because the state of the indicators is relatively volatile, the keyboard
+description does not hold the current state of the indicators. To obtain the
+current state of the keyboard indicators, use <emphasis>
+XkbGetIndicatorState</emphasis>.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Status <emphasis>
+XkbGetIndicatorState</emphasis>
+(<emphasis>
+display</emphasis>
+, <emphasis>
+device_spec</emphasis>
+, <emphasis>
+state_return</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>
+state_return</emphasis>
+; /* backfilled with a mask of the indicator state */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbGetIndicatorState</emphasis>
+ queries the <emphasis>
+display</emphasis>
+ for the state of the indicators on the device specified by the <emphasis>
+device_spec</emphasis>
+. For each indicator that is "turned on" on the device, the associated bit is
+set in <emphasis>
+state_return</emphasis>
+. If a compatible version of the Xkb extension is not available in the server,
+<emphasis>
+XkbGetIndicatorState</emphasis>
+ returns a <emphasis>
+BadMatch</emphasis>
+ error. Otherwise, it sends the request to the X server, places the state of
+the indicators into <emphasis>
+state_return,</emphasis>
+ and returns <emphasis>
+Success</emphasis>
+. Thus the value reported by <emphasis>
+XkbGetIndicatorState</emphasis>
+ is identical to the value reported by the core protocol.
+</para>
+
+
+</sect2>
+<sect2 id='getting_indicator_information_by_index'>
+<title>Getting Indicator Information by Index</title>
+
+<para>
+To get the map for one or more indicators, using a mask to specify the
+indicators, use <emphasis>
+XkbGetIndicatorMap</emphasis>.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Status <emphasis>
+XkbGetIndicatorMap</emphasis>
+(<emphasis>
+dpy</emphasis>
+,<emphasis>
+ which</emphasis>
+,<emphasis>
+ desc</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+dpy</emphasis>
+; /* connection to the X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+which</emphasis>
+; /* mask of indicators for which maps should be returned */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr <emphasis>
+desc</emphasis>
+; /* keyboard description to be updated */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbGetIndicatorMap</emphasis>
+ obtains the maps from the server for only those indicators specified by the
+<emphasis>
+which</emphasis>
+ mask and copies the values into the keyboard description specified by
+<emphasis>
+desc</emphasis>
+. If the <emphasis>
+indicators</emphasis>
+ field of the <emphasis>
+desc</emphasis>
+ parameter is <emphasis>
+NULL</emphasis>
+, <emphasis>
+XkbGetIndicatorMap</emphasis>
+ allocates and initializes it.
+</para>
+
+
+<para>
+<emphasis>
+XkbGetIndicatorMap</emphasis>
+ can generate <emphasis>
+BadAlloc</emphasis>
+, <emphasis>
+BadLength</emphasis>
+, <emphasis>
+BadMatch</emphasis>
+, and <emphasis>
+BadImplementation</emphasis>
+ errors.
+</para>
+
+
+<para>
+To free the indicator maps, use <emphasis>
+XkbFreeIndicatorMaps</emphasis>
+ (see section 8.6).
+</para>
+
+
+</sect2>
+<sect2 id='getting_indicator_information_by_name'>
+<title>Getting Indicator Information by Name</title>
+
+<para>
+Xkb also allows applications to refer to indicators by name. Use <emphasis>
+XkbGetNames</emphasis>
+ to get the indicator names (see Chapter 18). Using names eliminates the need
+for hard-coding bitmask values for particular keyboards. For example, instead
+of using vendor-specific constants such as <emphasis>
+WSKBLed_ScrollLock</emphasis>
+ mask on Digital workstations or <emphasis>
+XLED_SCROLL_LOCK</emphasis>
+ on Sun workstations, you can instead use <emphasis>
+XkbGetNamedIndicator</emphasis>
+ to look up information on the indicator named "Scroll Lock."
+</para>
+
+<para>
+Use <emphasis>
+XkbGetNamedIndicator</emphasis>
+ to look up the indicator map and other information for an indicator by name.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbGetNamedIndicator</emphasis>
+(<emphasis>
+dpy</emphasis>
+,<emphasis>
+ dev_spec</emphasis>
+,<emphasis>
+ name</emphasis>
+,<emphasis>
+ ndx_rtrn</emphasis>
+,<emphasis>
+ state_rtrn</emphasis>
+,<emphasis>
+ map_rtrn</emphasis>
+, <emphasis>
+real_rtrn</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+dpy</emphasis>
+; /* connection to the X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+ device_spec</emphasis>
+; /* keyboard device ID, or <emphasis>
+XkbUseCoreKbd</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Atom <emphasis>
+ name</emphasis>
+; /* name of the indicator to be retrieved */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+int * <emphasis>
+ndx_rtrn</emphasis>
+; /* backfilled with the index of the retrieved indicator */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Bool * <emphasis>
+state_rtrn</emphasis>
+; /* backfilled with the current state of the retrieved indicator */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbIndicatorMapPtr <emphasis>
+ map_rtrn</emphasis>
+; /* backfilled with the mapping for the retrieved indicator */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Bool * <emphasis>
+real_rtrn</emphasis>
+; /* backfilled with <emphasis>
+True</emphasis>
+ if the named indicator is real (physical) */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+If the device specified by <emphasis>
+device_spec</emphasis>
+ has an indicator named <emphasis>
+name</emphasis>
+,<emphasis>
+ XkbGetNamedIndicator</emphasis>
+ returns <emphasis>
+True</emphasis>
+ and populates the rest of the parameters with information about the indicator.
+Otherwise, <emphasis>
+XkbGetNamedIndicator</emphasis>
+ returns <emphasis>
+False</emphasis>
+.
+</para>
+
+
+<para>
+The <emphasis>
+ndx_rtrn</emphasis>
+ field returns the zero-based index of the named indicator. This index is the
+bit position to use in any function call that requires a mask of indicator
+bits, as well as the indicator’s index into the <emphasis>
+XkbIndicatorRec</emphasis>
+ array of indicator maps. <emphasis>
+state_rtrn</emphasis>
+ returns the current state of the named indicator (<emphasis>
+True</emphasis>
+ = on, <emphasis>
+False</emphasis>
+ = off). <emphasis>
+map_rtrn</emphasis>
+ returns the indicator map for the named indicator. In addition, if the
+indicator is mapped to a physical LED, the <emphasis>
+real_rtrn</emphasis>
+ parameter is set to <emphasis>
+True</emphasis>
+.
+</para>
+
+
+<para>
+Each of the "<emphasis>
+_rtrn</emphasis>
+" arguments is optional; you can pass <emphasis>
+NULL</emphasis>
+ for any unneeded "<emphasis>
+_rtrn</emphasis>
+" arguments.
+</para>
+
+
+<para>
+<emphasis>
+XkbGetNamedIndicator</emphasis>
+ can generate <emphasis>
+BadAtom</emphasis>
+ and <emphasis>
+BadImplementation</emphasis>
+ errors.
+</para>
+
+
+</sect2>
+</sect1>
+<sect1 id='changing_indicator_maps_and_state'>
+<title>Changing Indicator Maps and State</title>
+
+<para>
+Just as you can get the indicator map using a mask or using an indicator name,
+so you can change it using a mask or a name.
+</para>
+
+<note><para>You cannot change the <emphasis>
+phys_indicators</emphasis>
+ field of the indicators structure. The only way to change the <emphasis>
+phys_indicators</emphasis>
+ field is to change the keyboard map.</para></note>
+
+<para>
+There are two ways to make changes to indicator maps and state: either change a
+local copy of the indicator maps and use <emphasis>
+XkbSetIndicatorMap</emphasis>
+ or <emphasis>
+XkbSetNamedIndicator</emphasis>
+, or, to reduce network traffic, use an<emphasis>
+ XkbIndicatorChangesRec</emphasis>
+ structure and use <emphasis>
+XkbChangeIndicators</emphasis>.
+</para>
+
+
+<sect2 id='effects_of_explicit_changes_on_indicators'>
+<title>Effects of Explicit Changes on Indicators</title>
+
+<para>
+This section discusses the effects of explicitly changing indicators depending
+upon different settings in the indicator map. See Tables 8.3 and Table 8.5 for
+information on the effects of the indicator map fields when explicit changes
+are made.
+</para>
+
+
+<para>
+If <emphasis>
+XkbIM_LEDDrivesKB</emphasis>
+ is set and <emphasis>
+XkbIM_NoExplicit</emphasis>
+ is not, and if you call a function that updates the server’s image of the
+indicator map (such as <emphasis>
+XkbSetIndicatorMap</emphasis>
+ or <emphasis>
+XkbSetNamedIndicator</emphasis>
+), Xkb changes the keyboard state and controls to reflect the other fields of
+the indicator map. If you attempt to explicitly change the value of an
+indicator for which <emphasis>
+XkbIM_LEDDrivesKB</emphasis>
+ is absent or for which <emphasis>
+XkbIM_NoExplicit</emphasis>
+ is present, keyboard state or controls are unaffected.
+</para>
+
+
+<para>
+If neither <emphasis>
+XkbIM_NoAutomatic</emphasis>
+ nor <emphasis>
+XkbIM_NoExplicit</emphasis>
+ is set in an indicator map, Xkb honors any request to change the state of the
+indicator, but the new state might be immediately superseded by automatic
+changes to the indicator state if the keyboard state or controls change.
+</para>
+
+
+<para>
+The effects of changing an indicator that drives the keyboard are cumulative;
+it is possible for a single change to affect keyboard group, modifiers, and
+controls simultaneously.
+</para>
+
+
+<para>
+If you change an indicator for which both the <emphasis>
+XkbIM_LEDDrivesKB</emphasis>
+ and <emphasis>
+XkbIM_NoAutomatic</emphasis>
+ flags are specified, Xkb applies the keyboard changes specified in the other
+indicator map fields and changes the indicator to reflect the state that was
+explicitly requested. The indicator remains in the new state until it is
+explicitly changed again.
+</para>
+
+
+<para>
+If the <emphasis>
+XkbIM_NoAutomatic</emphasis>
+ flag is not set and <emphasis>
+XkbIM_LEDDrivesKB</emphasis>
+ is set, Xkb applies the changes specified in the other indicator map fields
+and sets the state of the indicator 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, Xkb
+does not extinguish an indicator with <emphasis>
+which_mods</emphasis>
+ of <emphasis>
+XkbIM_UseBase</emphasis>
+ and <emphasis>
+mods</emphasis>
+ of <emphasis>
+Shift</emphasis>
+ if, at the time Xkb processes the request to extinguish the indicator, one of
+the <emphasis>
+Shift</emphasis>
+ keys is physically depressed.
+</para>
+
+
+<para>
+If you explicitly light an indicator for which <emphasis>
+XkbIM_LEDDrivesKB</emphasis>
+ is set, Xkb enables all of the boolean controls specified in the <emphasis>
+ctrls</emphasis>
+ field of its indicator map. Explicitly extinguishing such an indicator causes
+Xkb to disable all of the boolean controls specified in <emphasis>
+ctrls</emphasis>
+.
+</para>
+
+
+</sect2>
+<sect2 id='changing_indicator_maps_by_index'>
+<title>Changing Indicator Maps by Index</title>
+
+<para>
+To update the maps for one or more indicators, first modify a local copy of the
+keyboard description, then use <emphasis>
+XkbSetIndicatorMap</emphasis>
+ to download the changes to the server:
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool<emphasis>
+ XkbSetIndicatorMap</emphasis>
+(<emphasis>
+dpy</emphasis>
+,<emphasis>
+ which</emphasis>
+,<emphasis>
+ desc</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+dpy</emphasis>
+; /* connection to the X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+which</emphasis>
+; /* mask of indicators to change */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr <emphasis>
+desc</emphasis>
+; /* keyboard description from which the maps are taken */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+For each<emphasis>
+ </emphasis>
+bit set in the <emphasis>
+which </emphasis>
+parameter,<emphasis>
+ XkbSetIndicatorMap</emphasis>
+ sends the corresponding indicator map from the <emphasis>
+desc</emphasis>
+ parameter to the server.
+</para>
+
+
+</sect2>
+<sect2 id='changing_indicator_maps_by_name'>
+<title>Changing Indicator Maps by Name</title>
+
+<para>
+<emphasis>
+XkbSetNamedIndicator</emphasis>
+ can do several related things:
+</para>
+
+<itemizedlist>
+<listitem>
+ <para>
+Name an indicator if it is not already named
+ </para>
+</listitem>
+<listitem>
+ <para>
+Toggle the state of the indicator
+ </para>
+</listitem>
+<listitem>
+ <para>
+Set the indicator to a specified state
+ </para>
+</listitem>
+<listitem>
+ <para>
+Set the indicator map for the indicator
+ </para>
+</listitem>
+</itemizedlist>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool<emphasis>
+ XkbSetNamedIndicator</emphasis>
+(<emphasis>
+dpy</emphasis>
+,<emphasis>
+ device_spec</emphasis>
+,<emphasis>
+ name</emphasis>
+,<emphasis>
+ change_state, state</emphasis>
+,<emphasis>
+ create_new</emphasis>
+,<emphasis>
+ map</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+ dpy</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'>
+Atom <emphasis>
+ name</emphasis>
+; /* name of the indicator to change */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Bool <emphasis>
+ change_state</emphasis>
+; /* whether to change the indicator state or not */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Bool <emphasis>
+ state</emphasis>
+; /* desired new state for the indicator */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Bool <emphasis>
+create_new</emphasis>
+; /* whether a new indicator with the specified name should be
+created when necessary */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbIndicatorMapPtr <emphasis>
+map</emphasis>
+; /* new map for the indicator */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+If a compatible version of the Xkb extension is not available in the server,
+<emphasis>
+XkbSetNamedIndicator</emphasis>
+ returns <emphasis>
+False</emphasis>
+. Otherwise, it sends a request to the X server to change the indicator
+specified by <emphasis>
+name</emphasis>
+ and returns <emphasis>
+True</emphasis>.
+</para>
+
+
+<para>
+If <emphasis>
+change_state</emphasis>
+ is <emphasis>
+True</emphasis>
+, and the optional parameter, <emphasis>
+state</emphasis>
+, is not <emphasis>
+NULL</emphasis>
+, <emphasis>
+XkbSetNamedIndicator</emphasis>
+ tells the server to change the state of the named indicator to the value
+specified by <emphasis>
+state</emphasis>.
+</para>
+
+
+<para>
+If an indicator with the name specified by <emphasis>
+name</emphasis>
+ does not already exist, the <emphasis>
+create_new</emphasis>
+ parameter tells the server whether it should create a new named indicator. If
+<emphasis>
+create_new</emphasis>
+ is <emphasis>
+True</emphasis>
+, the server finds the first indicator that doesn’t have a name and gives it
+the name specified by <emphasis>
+name</emphasis>.
+</para>
+
+
+<para>
+If the optional parameter, <emphasis>
+map</emphasis>
+, is not <emphasis>
+NULL</emphasis>
+, <emphasis>
+XkbSetNamedIndicator</emphasis>
+ tells the server to change the indicator’s map to the values specified
+in <emphasis>map</emphasis>.
+</para>
+
+<para>
+<emphasis>
+XkbSetNamedIndicator</emphasis>
+ can generate <emphasis>
+BadAtom</emphasis>
+ and <emphasis>
+BadImplementation</emphasis>
+ errors. In addition, it can also generate <emphasis>
+XkbIndicatorStateNotify</emphasis>
+ (see section 8.5), <emphasis> <!-- xref -->
+XkbIndicatorMapNotify</emphasis>
+, and <emphasis>
+XkbNamesNotify</emphasis>
+ events (see section 18.5). <!-- xref -->
+</para>
+
+
+</sect2>
+<sect2 id='the_xkbindicatorchangesrec_structure'>
+<title>The XkbIndicatorChangesRec Structure</title>
+
+<para>
+The <emphasis>
+XkbIndicatorChangesRec</emphasis>
+ identifies small modifications to the indicator map. Use it with the function
+<emphasis>
+XkbChangeIndicators</emphasis>
+ to reduce the amount of traffic sent to the server.
+</para>
+
+<para><programlisting>
+typedef struct _XkbIndicatorChanges {
+ unsigned int state_changes;
+ unsigned int map_changes;
+}<emphasis>
+XkbIndicatorChangesRec</emphasis>,*XkbIndicatorChangesPtr;
+</programlisting></para>
+
+<para>
+The <emphasis>
+state_changes</emphasis>
+ field is a mask that specifies the indicators that have changed state, and
+<emphasis>
+map_changes</emphasis>
+ is a mask that specifies the indicators whose maps have changed.
+</para>
+
+
+<para>
+To change indicator maps or state without passing the entire keyboard
+description, use <emphasis>
+XkbChangeIndicators</emphasis>
+.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbChangeIndicators</emphasis>
+(<emphasis>
+dpy, xkb, changes, state</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+dpy</emphasis>
+; /* connection to the X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr <emphasis>
+xkb</emphasis>
+; /* keyboard description from which names are to be
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+ taken. */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbIndicatorChangesPtr <emphasis>
+changes</emphasis>
+; /* indicators to be updated on the server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+state</emphasis>
+; /* new state of indicators listed in
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+<emphasis>
+ changes</emphasis>
+-&gt;<emphasis>
+state_changes</emphasis>
+ */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbChangeIndicators</emphasis>
+ copies any maps specified by <emphasis>
+changes</emphasis>
+ from the keyboard description, <emphasis>
+xkb</emphasis>
+, to the server specified by <emphasis>
+dpy</emphasis>
+. If any bits are set in the <emphasis>
+state_changes</emphasis>
+ field of <emphasis>
+changes</emphasis>
+, <emphasis>
+XkbChangeIndicators</emphasis>
+ also sets the state of those indicators to the values specified in the
+<emphasis>
+state</emphasis>
+ mask. A 1 bit in <emphasis>
+state</emphasis>
+ turns the corresponding indicator on, a 0 bit turns it off.
+</para>
+
+
+<para>
+<emphasis>
+XkbChangeIndicator</emphasis>
+s can generate <emphasis>
+BadAtom</emphasis>
+ and <emphasis>
+BadImplementation</emphasis>
+ errors. In addition, it can also generate <emphasis>
+XkbIndicatorStateNotify</emphasis>
+ and <emphasis>
+XkbIndicatorMapNotify</emphasis>
+ events (see section 8.5). <!-- xref -->
+</para>
+
+
+</sect2>
+</sect1>
+<sect1 id='tracking_changes_to_indicator_state_or_map'>
+<title>Tracking Changes to Indicator State or Map</title>
+
+<para>
+Whenever an indicator changes state, the server sends <emphasis>
+XkbIndicatorStateNotify</emphasis>
+ events to all interested clients. Similarly, whenever an indicator’s map
+changes, the server sends <emphasis>
+XkbIndicatorMapNotify</emphasis>
+ events to all interested clients.
+</para>
+
+
+<para>
+To receive <emphasis>
+XkbIndicatorStateNotify</emphasis>
+ events, use <emphasis>
+XkbSelectEvents</emphasis>
+ (see section 4.3) with both the <emphasis> <!-- xref -->
+bits_to_change </emphasis>
+and<emphasis>
+ values_for_bits</emphasis>
+ parameters containing <emphasis>
+XkbIndicatorStateNotifyMask</emphasis>
+. To receive <emphasis>
+XkbIndicatorMapNotify</emphasis>
+ events, use <emphasis>
+XkbSelectEvents</emphasis>
+ with <emphasis>
+XkbIndicatorMapNotifyMask</emphasis>
+.
+</para>
+
+
+<para>
+To receive events for only specific indicators, use <emphasis>
+XkbSelectEventDetails</emphasis>
+. Set the <emphasis>
+event_type</emphasis>
+ parameter<emphasis>
+ to XkbIndicatorStateNotify</emphasis>
+ or <emphasis>
+XkbIndicatorMapNotify</emphasis>
+, and set both the <emphasis>
+bits_to_change </emphasis>
+and<emphasis>
+ values_for_bits</emphasis>
+ detail parameters to a mask where each bit specifies one indicator, turning on
+those bits that specify the indicators for which you want to receive events.
+</para>
+
+
+<para>
+Both types of indicator events use the same structure:
+</para>
+
+<para><programlisting>
+typedef struct _XkbIndicatorNotify {
+ int type; /* Xkb extension base event code */
+ unsigned long serial; /* X server serial number for event */
+ Bool send_event; /* <emphasis> True</emphasis> =&gt; synthetically generated */
+ Display * display; /* server connection where event generated */
+ Time time; /* server time when event generated */
+ int xkb_type; /* specifies state or map notify */
+ int device; /* Xkb device ID, will not be <emphasis> XkbUseCoreKbd</emphasis> */
+ unsigned int changed; /* mask of indicators with new state or map */
+ unsigned int state; /* current state of all indicators */
+} <emphasis>XkbIndicatorNotifyEvent</emphasis>;
+</programlisting></para>
+
+<para>
+<emphasis>
+xkb_type</emphasis>
+ is either <emphasis>
+XkbIndicatorStateNotify</emphasis>
+ or <emphasis>
+XkbIndicatorMapNotify</emphasis>
+, depending on whether the event is a <emphasis>
+kbIndicatorStateNotify</emphasis>
+ event or <emphasis>
+kbIndicatorMapNotify</emphasis>
+ event.
+</para>
+
+<para>
+The <emphasis>
+changed</emphasis>
+ parameter is a mask that is the bitwise inclusive OR of the indicators that
+have changed. If the event is of type <emphasis>
+XkbIndicatorMapNotify</emphasis>
+, <emphasis>
+changed</emphasis>
+ reports the maps that changed. If the event is of type <emphasis>
+XkbIndicatorStateNotify</emphasis>
+, <emphasis>
+changed</emphasis>
+ reports the indicators that have changed state. <emphasis>
+state</emphasis>
+ is a mask that specifies the current state of all indicators, whether they
+have changed or not, for both <emphasis>
+XkbIndicatorStateNotify</emphasis>
+ and <emphasis>IndicatorMapNotify</emphasis> events.
+</para>
+
+<para>
+When your client application receives either a <emphasis>
+XkbIndicatorStateNotify</emphasis>
+ event or <emphasis>
+XkbIndicatorMapNotify</emphasis>
+ event, you can note the changes in a changes structure by calling <emphasis>
+XkbNoteIndicatorChanges</emphasis>.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+void <emphasis>
+XkbNoteIndicatorChanges</emphasis>
+(<emphasis>
+old</emphasis>
+,<emphasis>
+ new</emphasis>
+,<emphasis>
+ wanted</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbIndicatorChangesPtr <emphasis>
+ old</emphasis>
+; /* XkbIndicatorChanges structure to be updated */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbIndicatorNotifyEvent * <emphasis>
+new</emphasis>
+; /* event from which changes are to be copied */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+ wanted</emphasis>
+; /* which changes are to be noted */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+The <emphasis>
+wanted</emphasis>
+ parameter is the bitwise inclusive OR of <emphasis>
+XkbIndicatorMapMask</emphasis>
+ and <emphasis>
+XkbIndicatorStateMask</emphasis>
+. <emphasis>
+XkbNoteIndicatorChanges</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>
+To update a local copy of the keyboard description with the actual values, pass
+the results of one or more calls to <emphasis>
+XkbNoteIndicatorChanges</emphasis>
+ to <emphasis>
+XkbGetIndicatorChanges</emphasis>:
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Status <emphasis>
+XkbGetIndicatorChanges</emphasis>
+(<emphasis>
+dpy</emphasis>
+,<emphasis>
+ xkb</emphasis>
+,<emphasis>
+ changes</emphasis>
+,<emphasis>
+ state</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+dpy</emphasis>
+; /* connection to the X server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr <emphasis>
+xkb</emphasis>
+; /* keyboard description to hold the new values */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbIndicatorChangesPtr <emphasis>
+changes</emphasis>
+; /* indicator maps/state to be obtained from the server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int * <emphasis>
+state</emphasis>
+; /* backfilled with the state of the indicators */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbGetIndicatorChanges</emphasis>
+ examines the <emphasis>
+changes</emphasis>
+ parameter, pulls over the necessary information from the server, and copies
+the results into the <emphasis>
+xkb</emphasis>
+ keyboard description. If any bits are set in the <emphasis>
+state_changes</emphasis>
+ field of <emphasis>
+changes</emphasis>
+, <emphasis>
+XkbGetIndicatorChanges</emphasis>
+ also places the state of those indicators in <emphasis>
+state</emphasis>
+. If the <emphasis>
+indicators</emphasis>
+ field of <emphasis>
+xkb</emphasis>
+ is <emphasis>
+NULL</emphasis>
+, <emphasis>
+XkbGetIndicatorChanges</emphasis>
+ allocates and initializes it. To free the <emphasis>
+indicators</emphasis>
+ field, use <emphasis>
+XkbFreeIndicators</emphasis>
+ (see section 8.6). <!-- xref -->
+</para>
+
+
+<para>
+<emphasis>
+XkbGetIndicatorChanges</emphasis>
+ can generate <emphasis>
+BadAlloc</emphasis>
+, <emphasis>
+BadImplementation,</emphasis>
+ and <emphasis>
+BadMatch</emphasis>
+ errors.
+</para>
+
+
+</sect1>
+<sect1 id='allocating_and_freeing_indicator_maps'>
+<title>Allocating and Freeing Indicator Maps</title>
+
+<para>
+Most applications do not need to directly allocate the <emphasis>
+indicators</emphasis>
+ member of the keyboard description record (the keyboard description record is
+described in Chapter 6). If the need arises, however, use <emphasis>
+XkbAllocIndicatorMaps.</emphasis>
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Status <emphasis>
+XkbAllocIndicatorMaps</emphasis>
+(<emphasis>
+xkb</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr <emphasis>
+xkb</emphasis>
+; /* keyboard description structure */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+The <emphasis>
+xkb</emphasis>
+ parameter must point to a valid keyboard description. If it doesn’t,
+<emphasis>
+XkbAllocIndicatorMaps</emphasis>
+ returns a <emphasis>
+BadMatch</emphasis>
+ error. Otherwise, <emphasis>
+XkbAllocIndicatorMaps</emphasis>
+ allocates and initializes the <emphasis>
+indicators</emphasis>
+ member of the keyboard description record and returns <emphasis>
+Success</emphasis>
+. If <emphasis>
+XkbAllocIndicatorMaps</emphasis>
+ was unable to allocate the indicators record, it reports a Bad<emphasis>
+Alloc</emphasis>
+ error.
+</para>
+
+<para>
+To free memory used by the <emphasis>
+indicators</emphasis>
+ member of an <emphasis>
+XkbDescRec</emphasis>
+ structure, use <emphasis>
+XkbFreeIndicatorMaps.</emphasis>
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+void <emphasis>
+XkbFreeIndicatorMaps</emphasis>
+(<emphasis>
+xkb</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr <emphasis>
+xkb</emphasis>
+; /* keyboard description structure */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+If the <emphasis>indicators</emphasis>
+ member of the keyboard description record
+pointed to by <emphasis>xkb</emphasis>
+is not <emphasis>NULL</emphasis>
+, <emphasis>XkbFreeIndicatorMaps</emphasis>
+frees the memory associated with
+the <emphasis>indicators</emphasis>
+member of <emphasis>xkb</emphasis>.
+</para>
+
+</sect1>
+</chapter>