aboutsummaryrefslogtreecommitdiff
path: root/libX11/specs/XKB/ch17.xml
diff options
context:
space:
mode:
Diffstat (limited to 'libX11/specs/XKB/ch17.xml')
-rw-r--r--libX11/specs/XKB/ch17.xml1789
1 files changed, 1789 insertions, 0 deletions
diff --git a/libX11/specs/XKB/ch17.xml b/libX11/specs/XKB/ch17.xml
new file mode 100644
index 000000000..3c44da5c1
--- /dev/null
+++ b/libX11/specs/XKB/ch17.xml
@@ -0,0 +1,1789 @@
+<chapter id='the_xkb_compatibility_map'>
+<title>The Xkb Compatibility Map</title>
+
+<para>
+As shown in Figure 17.1, the X server is normally dealing with more than one
+client, each of which may be receiving events from the keyboard, and each of
+which may issue requests to modify the keyboard in some manner. Each client may
+be either Xkb-unaware, Xkb-capable, or Xkb-aware. The server itself may be
+either Xkb-aware or Xkb-unaware. If the server is Xkb-unaware, Xkb state and
+keyboard mappings are not involved in any manner, and Xkb-aware clients may not
+issue Xkb requests to the server. If the server is Xkb-aware, the server must
+be able to deliver events and accept requests in which the keyboard state and
+mapping are compatible with the mode in which the client is operating.
+Consequently, for some situations, conversions must be made between Xkb state /
+keyboard mappings and core protocol state / keyboard mappings, and vice versa.
+</para>
+
+<mediaobject>
+ <imageobject> <imagedata format="SVG" fileref="XKBlib-18.svg"/>
+ </imageobject>
+ <caption>Server Interaction with Types of Clients</caption>
+</mediaobject>
+
+
+
+<para>
+In addition to these situations involving a single server, there are cases
+where a client that deals with multiple servers may need to configure keyboards
+on different servers to be similar and the different servers may not all be
+Xkb-aware. Finally, a client may be dealing with descriptions of keyboards
+(files, and so on) that are based on core protocol and therefore may need to be
+able to map these descriptions to Xkb descriptions.
+</para>
+
+
+<para>
+An Xkb-aware server maintains keyboard state and mapping as an Xkb keyboard
+state and an Xkb keyboard mapping plus a compatibility map used to convert from
+Xkb components to core components and vice versa. In addition, the server also
+maintains a core keyboard mapping that approximates the Xkb keyboard mapping.
+The core keyboard mapping may be updated piecemeal, on a per-key basis. When
+the server receives a core protocol <emphasis>
+ChangeKeyboardMapping</emphasis>
+ or <emphasis>
+SetModifierMapping</emphasis>
+ request, it updates its core keyboard mapping, then uses the compatibility map
+to update its Xkb keyboard mapping. When the server receives an <emphasis>
+XkbSetMap</emphasis>
+ request, it updates those portions of its Xkb keyboard mapping specified by
+the request, then uses its compatibility map to update the corresponding parts
+of its core keyboard map. Consequently, the server’s Xkb keyboard map and
+also its core keyboard map may contain components that were set directly and
+others that were computed. Figure 17.2 illustrates these relationships.
+</para>
+
+<note><para>The core keyboard map is contained only in the server, not in any
+client-side data structures.</para></note>
+
+<mediaobject>
+ <imageobject> <imagedata format="SVG" fileref="XKBlib-19.svg"/>
+ </imageobject>
+ <caption>Server Derivation of State and Keyboard Mapping Components</caption>
+</mediaobject>
+
+
+
+<para>
+There are three kinds of compatibility transformations made by the server:
+</para>
+
+<orderedlist>
+ <listitem>
+ <para><emphasis role='bold'>Xkb State to Core State</emphasis></para>
+ <para>
+Keyboard state information reported to a client in the state field of various
+core events may be translated from the Xkb keyboard state maintained by the
+server, which includes a group number, to core protocol state, which does
+not.
+ </para>
+ <para>
+In addition, whenever the Xkb state is retrieved, the <emphasis>
+compat_state</emphasis>
+, <emphasis>
+compat_grab_mods</emphasis>
+, and <emphasis>
+compat_lookup_mods</emphasis>
+ fields of the <emphasis>
+XkbStateRec</emphasis>
+ returned indicate the result of applying the compatibility map to the current
+Xkb state in the server.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis role='bold'>Core Keyboard Mapping to Xkb Keyboard Mapping</emphasis></para>
+ <para>
+After core protocol requests received by the server to change the keyboard
+mapping (<emphasis>
+ChangeKeyboardMapping</emphasis>
+ and <emphasis>
+SetModifierMapping</emphasis>
+) have been applied to the server’s core keyboard map, the results must be
+transformed to achieve an equivalent change of the Xkb keyboard mapping
+maintained by the server.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis role='bold'>Xkb Keyboard Mapping to Core Keyboard Mapping</emphasis></para>
+ <para>
+After Xkb protocol requests received by the server to change the keyboard
+mapping (<emphasis>
+XkbSetMap</emphasis>
+) have been applied to the server’s Xkb keyboard map, the results are
+transformed to achieve an approximately equivalent change to the core keyboard
+mapping maintained by the server.
+ </para>
+ </listitem>
+</orderedlist>
+
+<para>
+This chapter discusses how a client may modify the compatibility map so that
+subsequent transformations have a particular result.
+</para>
+
+
+<sect1 id='the_xkbcompatmap_structure'>
+<title>The XkbCompatMap Structure</title>
+
+<para>
+All configurable aspects of mapping Xkb state and configuration to and from
+core protocol state and configuration are defined by a compatibility map,
+contained in an <emphasis>
+XkbCompatMap</emphasis>
+ structure; plus a set of explicit override controls used to prevent particular
+components of type 2 (core-to-Xkb keyboard mapping) transformations from
+automatically occurring. These explicit override controls are maintained in a
+separate data structure discussed in section 16.3. <!-- xref -->
+</para>
+
+
+<para>
+The <emphasis>
+compat</emphasis>
+ member of an Xkb keyboard description (<emphasis>
+XkbDescRec</emphasis>
+) points to the<emphasis>
+ XkbCompatMap</emphasis>
+ structure:
+</para>
+
+<para><programlisting>
+typedef struct _XkbCompatMapRec {
+ XkbSymInterpretPtr sym_interpret; /* symbol based key semantics*/
+ XkbModsRec groups[XkbNumKbdGroups]; /* group =&gt; modifier map */
+ unsigned short num_si; /* # structures used in
+ <emphasis>sym_interpret</emphasis> */
+ unsigned short size_si; /* # structures allocated in
+ <emphasis>sym_interpret</emphasis> */
+} <emphasis>XkbCompatMapRec</emphasis>, *XkbCompatMapPtr;
+</programlisting></para>
+
+<mediaobject>
+ <imageobject> <imagedata format="SVG" fileref="XKBlib-20.svg"/>
+ </imageobject>
+ <caption>Xkb Compatibility Data Structures</caption>
+</mediaobject>
+
+
+<para>
+The subsections that follow discuss how the compatibility map and explicit
+override controls are used in each of the three cases where compatibility
+transformations are made.
+</para>
+
+<sect2 id='xkb_state_to_core_protocol_state_transformation'>
+<title>Xkb State to Core Protocol State Transformation</title>
+
+<para>
+As shown in Figure 17.3, there are four <emphasis>
+group compatibility maps</emphasis>
+ (contained in <emphasis>
+groups</emphasis>
+ [0..3]) in the <emphasis>
+XkbCompatMapRec</emphasis>
+ structure, one per possible Xkb group. Each group compatibility map is a
+modifier definition (see section 7.2 for a description of modifier
+definitions). The <emphasis>
+mask</emphasis>
+ component of the definition specifies which real modifiers should be set in
+the core protocol state field when the corresponding group is active. Because
+only one group is active at any one time, only one of the four possible
+transformations is ever applied at any one point in time. If the device
+described by the <emphasis>
+XkbDescRec</emphasis>
+ does not support four groups, the extra groups fields are present, but
+undefined.
+</para>
+
+<para>
+Normally, the Xkb-aware server reports keyboard state in the <emphasis>
+state</emphasis>
+ member of events such as a <emphasis>
+KeyPress</emphasis>
+ event and <emphasis>
+ButtonPress</emphasis>
+ event, encoded as follows:
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='2'>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<thead>
+ <row rowsep='0'>
+ <entry>bits</entry>
+ <entry>meaning</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='0'>
+ <entry>15</entry>
+ <entry>0</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>13-14</entry>
+ <entry>Group index</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>8-12</entry>
+ <entry>Pointer Buttons</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>0-7</entry>
+ <entry>Modifiers</entry>
+ </row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+For Xkb-unaware clients, only core protocol keyboard information may be
+reported. Because core protocol does not define the group index, the group
+index is mapped to modifier bits as specified by the <emphasis>
+groups</emphasis>
+[group index] field of the compatibility map (the bits set in the compatibility
+map are ORed into bits 0-7 of the state), and bits 13-14 are reported in the
+event as zero.
+</para>
+
+</sect2>
+<sect2 id='core_keyboard_mapping_to_xkb_keyboard_mapping_transformation'>
+<title>Core Keyboard Mapping to Xkb Keyboard Mapping Transformation</title>
+
+<para>
+When a core protocol keyboard mapping request is received by the server, the
+server’s core keyboard map is updated, and then the Xkb map maintained by the
+server is updated. Because a client may have explicitly configured some of the
+Xkb keyboard mapping in the server, this automatic regeneration of the Xkb
+keyboard mapping from the core protocol keyboard mapping should not modify any
+components of the Xkb keyboard mapping that were explicitly set by a client.
+The client must set explicit override controls to prevent this from happening
+(see section 16.3). The core-to-Xkb mapping is done as follows:
+</para>
+
+<orderedlist>
+ <listitem>
+ <para>
+Map the symbols from the keys in the core keyboard map to groups and symbols on
+keys in the Xkb keyboard map. The core keyboard mapping is of fixed width, so
+each key in the core mapping has the same number of symbols associated with it.
+The Xkb mapping allows a different number of symbols to be associated with each
+key; those symbols may be divided into a different number of groups (1-4) for
+each key. For each key, this process therefore involves partitioning the fixed
+number of symbols from the core mapping into a set of variable-length groups
+with a variable number of symbols in each group. For example, if the core
+protocol map is of width five, the partition for one key might result in one
+group with two symbols and another with three symbols. A different key might
+result in two groups with two symbols plus a third group with one symbol. The
+core protocol map requires at least two symbols in each of the first two
+groups.
+ </para>
+ <orderedlist>
+ <listitem>
+ <para>
+For each changed key, determine the number of groups represented in the new
+core keyboard map. This results in a tentative group count for each key in the
+Xkb map.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+For each changed key, determine the number of symbols in each of the groups
+found in step 1a. There is one explicit override control associated with each
+of the four possible groups for each Xkb key, <emphasis>
+ExplicitKeyType1</emphasis>
+ through <emphasis>
+ExplicitKeyType4</emphasis>
+. If no explicit override control is set for a group, the number of symbols
+used for that group from the core map is two. If the explicit override control
+is set for a group on the key, the number of symbols used for that Xkb group
+from the core map is the width of the Xkb group with one exception: because of
+the core protocol requirement for at least two symbols in each of groups one
+and two, the number of symbols used for groups one and two is the maximum of 2
+or the width of the Xkb group.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+For each changed key, assign the symbols in the core map to the appropriate
+group on the key. If the total number of symbols required by the Xkb map for a
+particular key needs more symbols than the core protocol map contains, the
+additional symbols are taken to be <emphasis>
+NoSymbol</emphasis>
+ keysyms appended to the end of the core set. If the core map contains more
+symbols than are needed by the Xkb map, trailing symbols in the core map are
+discarded. In the absence of an explicit override for group one or two, symbols
+are assigned in order by group; the first symbols in the core map are assigned
+to group one, in order, followed by group two, and so on. For example, if the
+core map contained eight symbols per key, and a particular Xkb map contained 2
+symbols for G1 and G2 and three for G3, the symbols would be assigned as (G is
+group, L is shift level):
+ </para>
+<literallayout>
+ G1L1 G1L2 G2L1 G2L2 G3L1 G3L2 G3L3
+</literallayout>
+ <para>
+If an explicit override control is set for group one or two, the symbols are
+taken from the core set in a somewhat different order. The first four symbols
+from the core set are assigned to G1L1, G1L2, G2L1, G2L2, respectively. If
+group one requires more symbols, they are taken next, and then any additional
+symbols needed by group two. Group three and four symbols are taken in complete
+sequence after group two. For example, a key with four groups and three symbols
+in each group would take symbols from the core set in the following order:
+ </para>
+<literallayout>
+G1L1 G1L2 G2L1 G2L2 G1L3 G2L3 G3L1 G3L2 G3L3 G4L1 G4L2 G4L3
+</literallayout>
+ <para>
+As previously noted, the core protocol map requires at lease two symbols in
+groups one and two. Because of this, if an explicit override control for an Xkb
+key is set and group one and / or group two is of width one, it is not possible
+to generate the symbols taken from the core protocol set and assigned to
+position G1L2 and / or G2L2.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+For each group on each changed key, assign a key type appropriate for the
+symbols in the group.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+For each changed key, remove any empty or redundant groups.
+ </para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+ <listitem>
+ <para>
+At this point, the groups and their associated symbols have been assigned to
+the corresponding key definitions in the Xkb map.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Apply symbol interpretations to modify key operation. This phase is completely
+skipped if the <emphasis>
+ExplicitInterpret</emphasis>
+ override control bit is set in the explicit controls mask for the Xkb key (see
+section 16.3).
+ </para>
+ <orderedlist>
+ <listitem>
+ <para>
+For each symbol on each changed key, attempt to match the symbol and modifiers
+from the Xkb map to a symbol interpretation describing how to generate the
+symbol.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+When a match is found in step 2a, apply the symbol interpretation to change the
+semantics associated with the symbol in the Xkb key map. If no match is found,
+apply a default interpretation.
+ </para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+</orderedlist>
+
+<para>
+The symbol interpretations used in step 2 are configurable and may be specified
+using <emphasis>
+XkbSymInterpretRec</emphasis>
+ structures referenced by the <emphasis>
+sym_interpret</emphasis>
+ field of an <emphasis>
+XkbCompatMapRec</emphasis>
+ (see Figure 17.3).
+</para>
+
+<sect3 id='symbol_interpretations_the_xkbsyminterpretrec_structure'>
+<title>Symbol Interpretations — the XkbSymInterpretRec Structure</title>
+
+<para>
+Symbol interpretations are used to guide the X server when it modifies the Xkb
+keymap in step 2. An initial set of symbol interpretations is loaded by the
+server when it starts. A client may add new ones using <emphasis>
+XkbSetCompatMap</emphasis>
+ (see section 17.4).
+</para>
+
+
+<para>
+Symbol interpretations result in key semantics being set. When a symbol
+interpretation is applied, the following components of server key event
+processing may be modified for the particular key involved:
+</para>
+
+<literallayout>
+ Virtual modifier map
+ Auto repeat
+ Key behavior (may be set to <emphasis>XkbKB_Lock</emphasis>)
+ Key action (see section 16.1)
+</literallayout>
+
+<para>
+The <emphasis>XkbSymInterpretRec</emphasis>
+structure specifies a symbol interpretation:
+</para>
+
+<para><programlisting>
+typedef struct {
+ KeySym sym; /* keysym of interest or <emphasis>NULL</emphasis> */
+ unsigned char flags; /* <emphasis>XkbSI_AutoRepeat, XkbSI_LockingKey</emphasis> */
+ unsigned char match; /* specifies how mods is interpreted */
+ unsigned char mods; /* modifier bits, correspond to eight real modifiers */
+ unsigned char virtual_mod; /* 1 modifier to add to key virtual mod map */
+ XkbAnyAction act; /* action to bind to symbol position on key */
+} <emphasis>XkbSymInterpretRec</emphasis>,*XkbSymInterpretPtr;
+</programlisting></para>
+
+<para>
+If <emphasis>
+sym</emphasis>
+ is not <emphasis>
+NULL</emphasis>
+, it limits the symbol interpretation to keys on which that particular keysym
+is selected by the modifiers matching the criteria specified by <emphasis>
+mods</emphasis>
+ and <emphasis>
+match</emphasis>
+. If <emphasis>
+sym</emphasis>
+ is <emphasis>
+NULL</emphasis>
+, the interpretation may be applied to any symbol selected on a key when the
+modifiers match the criteria specified by <emphasis>
+mods</emphasis>
+ and <emphasis>
+match</emphasis>
+.
+</para>
+
+
+<para>
+<emphasis>match</emphasis>
+must be one of the values shown in Table 17.1 and specifies how the real
+modifiers specified in <emphasis>mods</emphasis>
+are to be interpreted.
+</para>
+
+<table frame='none'>
+<title>Symbol Interpretation Match Criteria</title>
+<tgroup cols='3'>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='1'>
+ <entry>Match Criteria</entry>
+ <entry>Value</entry>
+ <entry>Effect</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='1'>
+ <entry><emphasis>XkbSI_NoneOf</emphasis></entry>
+ <entry>(0)</entry>
+ <entry>
+None of the bits that are on in <emphasis>mods</emphasis>
+ can be set, but other bits can be.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry><emphasis>XkbSI_AnyOfOrNone</emphasis></entry>
+ <entry>(1)</entry>
+ <entry>
+Zero or more of the bits that are on in <emphasis>
+mods</emphasis>
+ can be set, as well as others.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry><emphasis>XkbSI_AnyOf</emphasis></entry>
+ <entry>(2)</entry>
+ <entry>
+One or more of the bits that are on in <emphasis>
+mods</emphasis>
+ can be set, as well as any others.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry><emphasis>XkbSI_AllOf</emphasis></entry>
+ <entry>(3)</entry>
+ <entry>
+All of the bits that are on in <emphasis>
+mods</emphasis>
+ must be set, but others may be set as well.
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry><emphasis>XkbSI_Exactly</emphasis></entry>
+ <entry>(4)</entry>
+ <entry>
+All of the bits that are on in <emphasis>
+mods</emphasis>
+ must be set, and no other bits may be set.
+ </entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+In addition to the above bits, <emphasis>
+match</emphasis>
+ may contain the <emphasis>
+XkbSI_LevelOneOnly</emphasis>
+ bit, in which case the modifier match criteria specified by <emphasis>
+mods</emphasis>
+ and <emphasis>
+match</emphasis>
+ applies only if <emphasis>
+sym</emphasis>
+ is in level one of its group; otherwise, <emphasis>
+mods</emphasis>
+ and <emphasis>
+match</emphasis>
+ are ignored and the symbol matches a condition where no modifiers are set.
+</para>
+
+<para><programlisting>
+#define XkbSI_LevelOneOnly (0x80)
+/* use mods + match only if sym is level 1 */
+</programlisting></para>
+
+<para>
+If no matching symbol interpretation is found, the server uses a default
+interpretation where:
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='2'>
+<colspec colsep='0'/>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry><emphasis>sym</emphasis> =</entry>
+ <entry>0</entry>
+ </row>
+ <row rowsep='0'>
+ <entry><emphasis>flags</emphasis> =</entry>
+ <entry><emphasis>XkbSI_AutoRepeat</emphasis></entry>
+ </row>
+ <row rowsep='0'>
+ <entry><emphasis>match</emphasis> =</entry>
+ <entry><emphasis>XkbSI_AnyOfOrNone</emphasis></entry>
+ </row>
+ <row rowsep='0'>
+ <entry><emphasis>mods</emphasis> =</entry>
+ <entry>0</entry>
+ </row>
+ <row rowsep='0'>
+ <entry><emphasis>virtual_mod</emphasis> =</entry>
+ <entry><emphasis>XkbNoModifier</emphasis></entry>
+ </row>
+ <row rowsep='0'>
+
+ <entry><emphasis>act</emphasis> =</entry>
+ <entry><emphasis>SA_NoAction</emphasis></entry>
+ </row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+When a matching symbol interpretation is found in step 2a, the interpretation
+is applied to modify the Xkb map as follows.
+</para>
+
+<para>
+The <emphasis>
+act</emphasis>
+ field specifies a single action to be bound to the symbol position; any key
+event that selects the symbol causes the action to be taken. Valid actions are
+defined in section 16.1.
+</para>
+
+
+<para>
+If the Xkb keyboard map for the key does not have its <emphasis>
+ExplicitVModMap</emphasis>
+ control set, the <emphasis>
+XkbSI_LevelOneOnly</emphasis>
+ bit and symbol position are examined. If the <emphasis>
+XkbSI_LevelOneOnly</emphasis>
+ bit is not set in <emphasis>
+match</emphasis>
+ or the symbol is in position G1L1, the <emphasis>
+virtual_mod</emphasis>
+ field is examined. If <emphasis>
+virtual_mod</emphasis>
+ is not <emphasis>
+XkbNoModifier</emphasis>
+, <emphasis>
+virtual_mod</emphasis>
+ specifies a single virtual modifier to be added to the virtual modifier map
+for the key.<emphasis>
+ virtual_mod</emphasis>
+ is specified as an index in the range [0..15].
+</para>
+
+
+<para>
+If the matching symbol is in position G1L1 of the key, two bits in the flags
+field potentially specify additional behavior modifications:
+</para>
+
+<para><programlisting>
+#define XkbSI_AutoRepeat (1&lt;&lt;0)
+ /* key repeats if sym is in position G1L1 */
+#define XkbSI_LockingKey (1&lt;&lt;1)
+ /* set <emphasis> KB_Lock</emphasis>
+ behavior if sym is in psn G1L1 */
+</programlisting></para>
+
+<para>
+If the Xkb keyboard map for the key does not have its <emphasis>
+ExplicitAutoRepeat</emphasis>
+ control set, its auto repeat behavior is set based on the value of the
+<emphasis>
+XkbSI_AutoRepeat</emphasis>
+ bit. If the <emphasis>
+XkbSI_AutoRepeat</emphasis>
+ bit is set, the auto-repeat behavior of the key is turned on; otherwise, it is
+turned off.
+</para>
+
+
+<para>
+If the Xkb keyboard map for the key does not have its <emphasis>
+ExplicitBehavior</emphasis>
+ control set, its locking behavior is set based on the value of the <emphasis>
+XkbSI_LockingKey</emphasis>
+ bit. If <emphasis>
+XkbSI_LockingKey</emphasis>
+ is set, the key behavior is set to <emphasis>
+KB_Lock</emphasis>
+; otherwise, it is turned off (see section 16.3).
+</para>
+
+
+</sect3>
+</sect2>
+<sect2 id='xkb_keyboard_mapping_to_core_keyboard_mapping_transformations'>
+<title>Xkb Keyboard Mapping to Core Keyboard Mapping Transformations</title>
+
+<para>
+Whenever the server processes Xkb requests to change the keyboard mapping, it
+discards the affected portion of its core keyboard mapping and regenerates it
+based on the new Xkb mapping.
+</para>
+
+
+<para>
+When the Xkb mapping for a key is transformed to a core protocol mapping, the
+symbols for the core map are taken in the following order from the Xkb map:
+</para>
+
+
+<para>
+G1L1 G1L2 G2L1 G2L2 G1L3-n G2L3-n G3L1-n G4L1-n
+</para>
+
+
+<para>
+If group one is of width one in the Xkb map, G1L2 is taken to be NoSymbol;
+similarly, if group two is of width one in the Xkb map, G2L2 is taken to be
+NoSymbol.
+</para>
+
+
+<para>
+If the Xkb key map for a particular key has fewer groups than the core
+keyboard, the symbols for group one are repeated to fill in the missing core
+components. For example, an Xkb key with a single width-three group would be
+mapped to a core mapping counting three groups as:
+</para>
+
+
+<para>
+G1L1 G1L2 G1L1 G1L2 G1L3 G1L3 G1L1 G1L2 G1L3
+</para>
+
+
+<para>
+When a core keyboard map entry is generated from an Xkb keyboard map entry, a
+modifier mapping is generated as well. The modifier mapping contains all of the
+modifiers affected by any of the actions associated with the key combined with
+all of the real modifiers associated with any of the virtual modifiers bound to
+the key. In addition, if any of the actions associated with the key affect any
+component of the keyboard group, all of the modifiers in the <emphasis>
+mask</emphasis>
+ field of all of the group compatibility maps are added to the modifier mapping
+as well. While an <emphasis>
+XkbSA_ISOLock</emphasis>
+ action can theoretically affect any modifier, if the Xkb mapping for a key
+specifies an <emphasis>
+XkbSA_ISOLock</emphasis>
+ action, only the modifiers or group that are set by default are added to the
+modifier mapping.
+</para>
+
+
+</sect2>
+</sect1>
+<sect1 id='getting_compatibility_map_components_from_the_server'>
+<title>Getting Compatibility Map Components From the Server</title>
+
+<para>
+Use <emphasis>
+XkbGetCompatMap</emphasis>
+ to fetch any combination of the current compatibility map components from the
+server. When another client modifies the compatibility map, you are notified if
+you have selected for <emphasis>
+XkbCompatMapNotify</emphasis>
+ events (see section 17.5). <emphasis>
+XkbGetCompatMap</emphasis>
+ is particularly useful when you receive an event of this type, as it allows
+you to update your program’s version of the compatibility map to match the
+modified version now in the server. If your program is dealing with multiple
+servers and needs to configure them all in a similar manner, the updated
+compatibility map may be used to reconfigure other servers.
+</para>
+
+<note><para>To make a complete matching configuration you must also update the
+explicit override components of the server state.</para></note>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Status <emphasis>
+XkbGetCompatMap</emphasis>
+(<emphasis>
+display, which, xkb</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+ display</emphasis>
+; /* connection to server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ which</emphasis>
+; /* mask of compatibility map components to fetch */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescRec * <emphasis>
+ xkb</emphasis>
+; /* keyboard description where results placed */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbGetCompatMap</emphasis>
+ fetches the components of the compatibility map specified in <emphasis>
+which</emphasis>
+ from the server specified by <emphasis>
+display</emphasis>
+ and places them in the <emphasis>
+compat</emphasis>
+ structure of the keyboard description <emphasis>
+xkb</emphasis>
+. Valid values for <emphasis>
+which</emphasis>
+ are an inclusive OR of the values shown in Table 17.2.
+</para>
+
+<table frame='none'>
+<title>Compatibility Map Component Masks</title>
+<tgroup cols='3'>
+<colspec colsep='0'/>
+<thead>
+<row rowsep='0'>
+ <entry>Mask</entry>
+ <entry>Value</entry>
+ <entry>Affecting</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='0'>
+ <entry><emphasis>XkbSymInterpMask</emphasis></entry>
+ <entry>(1&lt;&lt;0)</entry>
+ <entry>Symbol interpretations</entry>
+ </row>
+ <row rowsep='0'>
+ <entry><emphasis>XkbGroupCompatMask</emphasis></entry>
+ <entry>(1&lt;&lt;1)</entry>
+ <entry>Group maps</entry>
+ </row>
+ <row rowsep='0'>
+ <entry><emphasis>XkbAllCompatMask</emphasis></entry>
+ <entry>(0x3)</entry>
+ <entry>All compatibility map components</entry>
+ </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+If no compatibility map structure is allocated in <emphasis>
+xkb</emphasis>
+ upon entry, <emphasis>
+XkbGetCompatMap</emphasis>
+ allocates one. If one already exists, its contents are overwritten with the
+returned results.
+</para>
+
+
+<para>
+<emphasis>
+XkbGetCompatMap</emphasis>
+ fetches compatibility map information for the device specified by the
+<emphasis>
+device_spec</emphasis>
+ field of <emphasis>
+xkb</emphasis>
+. Unless you have specifically modified this field, it is the default keyboard
+device. <emphasis>
+XkbGetCompatMap</emphasis>
+ returns <emphasis>
+Success</emphasis>
+ if successful, <emphasis>
+BadAlloc</emphasis>
+ if it is unable to obtain necessary storage for either the return values or
+work space, <emphasis>
+BadMatch</emphasis>
+ if the <emphasis>
+dpy</emphasis>
+ field of the <emphasis>
+xkb</emphasis>
+ argument is non-<emphasis>
+NULL</emphasis>
+ and does not match the <emphasis>
+display</emphasis>
+ argument, and <emphasis>
+BadLength</emphasis>
+ under certain conditions caused by server or Xkb implementation errors.
+</para>
+
+
+</sect1>
+<sect1 id='using_the_compatibility_map'>
+<title>Using the Compatibility Map</title>
+
+<para>
+Xkb provides several functions that make it easier to apply the compatibility
+map to configure a client-side Xkb keyboard mapping, given a core protocol
+representation of part or all of a keyboard mapping. Obtain a core protocol
+representation of a keyboard mapping from an actual server (by using <emphasis>
+XGetKeyboardMapping</emphasis>
+, for example), a data file, or some other source.
+</para>
+
+<para>
+To update a local Xkb keyboard map to reflect the mapping expressed by a core
+format mapping by calling the function <emphasis>
+XkbUpdateMapFromCore</emphasis>
+.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbUpdateMapFromCore</emphasis>
+(<emphasis>
+xkb</emphasis>
+,<emphasis>
+ first_key</emphasis>
+,<emphasis>
+ num_keys</emphasis>
+,<emphasis>
+ map_width</emphasis>
+,<emphasis>
+ core_keysyms</emphasis>
+,<emphasis>
+ changes</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr <emphasis>
+ xkb</emphasis>
+; /* keyboard description to update */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+KeyCode <emphasis>
+ first_key</emphasis>
+; /* keycode of first key description to update */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+int <emphasis>
+ num_keys</emphasis>
+; /* number of key descriptions to update */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+int <emphasis>
+ map_width</emphasis>
+; /* width of core protocol keymap */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+KeySym *<emphasis>
+ core_keysyms</emphasis>
+; /* symbols in core protocol keymap */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbChangesPtr <emphasis>
+ changes</emphasis>
+; /* backfilled with changes made to Xkb */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbUpdateMapFromCore</emphasis>
+ interprets input argument information representing a keyboard map in core
+format to update the Xkb keyboard description passed in <emphasis>
+xkb</emphasis>
+. Only a portion of the Xkb map is updated — the portion corresponding to
+keys with keycodes in the range <emphasis>
+first_key</emphasis>
+ through <emphasis>
+first_key</emphasis>
+ + <emphasis>
+num_keys</emphasis>
+ - 1. If <emphasis>
+XkbUpdateMapFromCore</emphasis>
+ is being called in response to a<emphasis>
+ </emphasis>
+<emphasis>
+MappingNotify</emphasis>
+<emphasis>
+ </emphasis>
+event<emphasis>
+, first_key</emphasis>
+ and <emphasis>
+num_keys</emphasis>
+ are reported in the <emphasis>
+MappingNotify</emphasis>
+ event. <emphasis>
+core_keysyms</emphasis>
+ contains the keysyms corresponding to the keycode range being updated, in core
+keyboard description order. <emphasis>
+map_width</emphasis>
+ is the number of keysyms per key in <emphasis>
+core_keysyms</emphasis>
+. Thus, the first <emphasis>
+map_width</emphasis>
+ entries in <emphasis>
+core_keysyms</emphasis>
+ are for the key with keycode <emphasis>
+first_key</emphasis>
+, the next <emphasis>
+map_width</emphasis>
+ entries are for key <emphasis>
+first_key</emphasis>
+ + 1, and so on.
+</para>
+
+
+<para>
+In addition to modifying the Xkb keyboard mapping in <emphasis>
+xkb</emphasis>
+, <emphasis>
+XkbUpdateMapFromCore</emphasis>
+ backfills the changes structure whose address is passed in <emphasis>
+changes</emphasis>
+ to indicate the modifications that were made. You may then use <emphasis>
+changes</emphasis>
+ in subsequent calls such as <emphasis>
+XkbSetMap</emphasis>
+, to propagate the local modifications to a server.
+</para>
+
+
+<para>
+When dealing with core keyboard mappings or descriptions, it is sometimes
+necessary to determine the Xkb key types appropriate for the symbols bound to a
+key in a core keyboard mapping. Use <emphasis>
+XkbKeyTypesForCoreSymbols</emphasis>
+ for this purpose:
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+int <emphasis>
+XkbKeyTypesForCoreSymbols</emphasis>
+(<emphasis>
+map_width</emphasis>
+,<emphasis>
+ core_syms</emphasis>
+,<emphasis>
+ protected, types_inout, xkb_syms_rtrn</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr<emphasis>
+ xkb</emphasis>
+; /* keyboard description in which to place symbols*/
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+int<emphasis>
+ map_width</emphasis>
+; /* width of core protocol keymap in <emphasis>
+xkb_syms_rtrn</emphasis>
+ */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+KeySym *<emphasis>
+ core_syms</emphasis>
+; /* core protocol format array of KeySyms */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int <emphasis>
+protected</emphasis>
+; /* explicit key types */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+int *<emphasis>
+ types_inout;</emphasis>
+ /* backfilled with the canonical types bound to groups one and two
+for the key */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+KeySym * <emphasis>
+xkb_syms_rtrn</emphasis>
+ ; /* backfilled with symbols bound to the key in the Xkb mapping */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbKeyTypesForCoreSymbols</emphasis>
+ expands the symbols in <emphasis>
+core_syms</emphasis>
+ and types in <emphasis>
+types_inout</emphasis>
+ according to the rules specified in section 12 of the core protocol, then
+chooses canonical key types (canonical key types are defined in section 15.2.1)
+for groups 1 and 2 using the rules specified by the Xkb protocol and places
+them in <emphasis>
+xkb_syms_rtrn</emphasis>
+, which will be non-<emphasis>
+NULL</emphasis>
+.
+</para>
+
+
+<para>
+A core keymap is a two-dimensional array of keysyms. It has <emphasis>
+map_width</emphasis>
+ columns and <emphasis>
+max_key_code</emphasis>
+ rows. <emphasis>
+XkbKeyTypesForCoreSymbols</emphasis>
+ takes a single row from a core keymap, determines the number of groups
+associated with it, the type of each group, and the symbols bound to each
+group. The return value is the number of groups, <emphasis>
+types_inout</emphasis>
+ has the types for each group, and <emphasis>
+xkb_syms_rtrn</emphasis>
+ has the symbols in Xkb order (that is, groups are contiguous, regardless of
+size).
+</para>
+
+
+<para>
+<emphasis>
+protected</emphasis>
+ contains the explicitly protected key types. There is one explicit override
+control associated with each of the four possible groups for each Xkb key,
+<emphasis>
+ExplicitKeyType1</emphasis>
+ through <emphasis>
+ExplicitKeyType4</emphasis>
+<emphasis>
+; protected </emphasis>
+is an inclusive OR of these controls. <emphasis>
+map_width</emphasis>
+ is the width of the core keymap and is not dependent on any Xkb definitions.
+<emphasis>
+types_inout</emphasis>
+ is an array of four type indices. On input, <emphasis>
+types_inout</emphasis>
+ contains the indices of any types already assigned to the key, in case they
+are explicitly protected from change.
+</para>
+
+
+<para>
+Upon return, <emphasis>
+types_inout</emphasis>
+ contains any automatically selected (that is, canonical) types plus any
+protected types. Canonical types are assigned to all four groups if there are
+enough symbols to do so. The four entries in <emphasis>
+types_inout</emphasis>
+ correspond to the four groups for the key in question.
+</para>
+
+
+<para>
+If the groups mapping does not change, but the symbols assigned to an Xkb
+keyboard compatibility map do change, the semantics of the key may be modified.
+To apply the new compatibility mapping to an individual key to get its
+semantics updated, use <emphasis>
+XkbApplyCompatMapToKey</emphasis>
+.
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbApplyCompatMapToKey</emphasis>
+(<emphasis>
+xkb</emphasis>
+,<emphasis>
+ key</emphasis>
+,<emphasis>
+ changes</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+ XkbDescPtr<emphasis>
+ xkb; </emphasis>
+/* keyboard description to be updated */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+ KeyCode<emphasis>
+ key</emphasis>
+; /* key to be updated */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+ XkbChangesPtr<emphasis>
+ changes</emphasis>
+; /* notes changes to the Xkb keyboard description */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbApplyCompatMapToKey</emphasis>
+ essentially performs the operation described in section 17.1.2 to a specific
+key. This updates the behavior, actions, repeat status, and virtual modifier
+bindings of the key.
+</para>
+
+
+</sect1>
+<sect1 id='changing_the_servers_compatibility_map'>
+<title>Changing the Server’s Compatibility Map</title>
+
+<para>
+To modify the server’s compatibility map, first modify a local copy of the
+Xkb compatibility map, then call <emphasis>
+XkbSetCompatMap</emphasis>
+. You may allocate a new compatibility map for this purpose using <emphasis>
+XkbAllocCompatMap</emphasis>
+ (see section 17.6). You may also use a compatibility map from another server,
+although you need to adjust the <emphasis>
+device_spec</emphasis>
+ field in the <emphasis>
+XkbDescRec</emphasis>
+ accordingly. Note that symbol interpretations in a compatibility map
+(<emphasis>
+sym_interpret</emphasis>
+, the vector of <emphasis>
+XkbSymInterpretRec</emphasis>
+ structures) are also allocated using this same function.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Bool <emphasis>
+XkbSetCompatMap</emphasis>
+(<emphasis>
+display, which, xkb, update_actions</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Display * <emphasis>
+ display</emphasis>
+; /* connection to server */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ which</emphasis>
+; /* mask of compat map components to set */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr <emphasis>
+ xkb</emphasis>
+; /* source for compat map components */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Bool <emphasis>
+ update_actions</emphasis>
+; /* <emphasis>
+True</emphasis>
+ =&gt; apply to server’s keyboard map */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbSetCompatMap</emphasis>
+ copies compatibility map information from the keyboard description in
+<emphasis>
+xkb</emphasis>
+ to the server specified in <emphasis>
+display</emphasis>
+’s compatibility map for the device specified by the <emphasis>
+device_spec</emphasis>
+ field of <emphasis>
+xkb</emphasis>
+. Unless you have specifically modified this field, it is the default keyboard
+device.<emphasis>
+ which</emphasis>
+ specifies the compatibility map components to be set, and is an inclusive OR
+of the bits shown in Table 17.2.
+</para>
+
+
+<para>
+After updating its compatibility map for the specified device, if <emphasis>
+update_actions</emphasis>
+ is <emphasis>
+True,</emphasis>
+ the server applies the new compatibility map to its entire keyboard for the
+device to generate a new set of key semantics, compatibility state, and a new
+core keyboard map. If <emphasis>
+update_actions</emphasis>
+ is <emphasis>
+False</emphasis>
+, the new compatibility map is not used to generate any modifications to the
+current device semantics, state, or core keyboard map. One reason for not
+applying the compatibility map immediately would be if one server was being
+configured to match another on a piecemeal basis; the map should not be applied
+until everything is updated. To force an update at a later time, use <emphasis>
+XkbSetCompatMap</emphasis>
+ specifying <emphasis>
+which</emphasis>
+ as zero and <emphasis>
+update_actions</emphasis>
+ as <emphasis>
+True</emphasis>
+.
+</para>
+
+
+<para>
+<emphasis>
+XkbSetCompatMap</emphasis>
+ returns <emphasis>
+True</emphasis>
+ if successful and <emphasis>
+False</emphasis>
+ if unsuccessful. The server may report problems it encounters when processing
+the request subsequently via protocol errors.
+</para>
+
+
+<para>
+To add a symbol interpretation to the list of symbol interpretations in an
+<emphasis>
+XkbCompatRec</emphasis>
+, use <emphasis>
+XkbAddSymInterpret</emphasis>
+.
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+XkbSymInterpretPtr <emphasis>
+XkbAddSymInterpret</emphasis>
+(<emphasis>
+xkb, si, updateMap, changes</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr<emphasis>
+ xkb</emphasis>
+; /* keyboard description to be updated */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbSymInterpretPtr<emphasis>
+ si</emphasis>
+; /* symbol interpretation to be added */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Bool<emphasis>
+ updateMap</emphasis>
+; /* <emphasis>
+True</emphasis>
+=&gt;apply compatibility map to keys */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbChangesPtr<emphasis>
+ changes</emphasis>
+; /* changes are put here */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+XkbAddSymInterpret</emphasis>
+ adds <emphasis>
+si</emphasis>
+ to the list of symbol interpretations in <emphasis>
+xkb</emphasis>
+. If <emphasis>
+updateMap</emphasis>
+ is <emphasis>
+True</emphasis>
+, it (re)applies the compatibility map to all of the keys on the keyboard. If
+<emphasis>
+changes</emphasis>
+ is non-<emphasis>
+NULL</emphasis>
+, it reports the parts of the keyboard that were affected (unless <emphasis>
+updateMap</emphasis>
+ is <emphasis>
+True</emphasis>
+, not much changes). <emphasis>
+XkbAddSymInterpret</emphasis>
+ returns a pointer to the actual new symbol interpretation in the list or
+<emphasis>
+NULL</emphasis>
+ if it failed.
+</para>
+
+
+</sect1>
+<sect1 id='tracking_changes_to_the_compatibility_map'>
+<title>Tracking Changes to the Compatibility Map</title>
+
+<para>
+The server automatically generates <emphasis>
+MappingNotify</emphasis>
+ events when the keyboard mapping changes. If you wish to be notified of
+changes to the compatibility map, you should select for <emphasis>
+XkbCompatMapNotify</emphasis>
+ events. If you select for <emphasis>
+XkbMapNotify</emphasis>
+ events, you no longer receive the automatically generated <emphasis>
+MappingNotify</emphasis>
+ events. If you subsequently deselect <emphasis>
+XkbMapNotifyEvent</emphasis>
+ delivery, you again receive <emphasis>
+MappingNotify</emphasis>
+ events.
+</para>
+
+
+<para>
+To receive <emphasis>
+XkbCompatMapNotify</emphasis>
+ events under all possible conditions, use <emphasis>
+XkbSelectEvents</emphasis>
+ (see section 4.3) and pass <emphasis>
+XkbCompatMapNotifyMask</emphasis>
+ in both <emphasis>
+bits_to_change</emphasis>
+ and <emphasis>
+values_for_bits</emphasis>
+.
+</para>
+
+
+<para>
+To receive <emphasis>
+XkbCompatMapNotify</emphasis>
+ events only under certain conditions, use <emphasis>
+XkbSelectEventDetails</emphasis>
+ using <emphasis>
+XkbCompatMapNotify</emphasis>
+ as the <emphasis>
+event_type</emphasis>
+ and specifying the desired map changes in <emphasis>
+bits_to_change</emphasis>
+ and <emphasis>
+values_for_bits</emphasis>
+ using mask bits from Table 17.2.
+</para>
+
+
+<para>
+Note that you are notified of changes you make yourself, as well as changes
+made by other clients.
+</para>
+
+
+<para>
+The structure for the <emphasis>
+XkbCompatMapNotifyEvent</emphasis>
+ is:
+</para>
+
+<para><programlisting>
+typedef struct {
+ int type; /* Xkb extension base event code */
+ unsigned long serial; /* X server serial number for event */
+ Bool send_event; /* <emphasis>True</emphasis> =&gt;
+ synthetically generated */
+ Display * display; /* server connection where event generated */
+ Time time; /* server time when event generated */
+ int xkb_type; /* <emphasis>XkbCompatMapNotify</emphasis> */
+ int device; /* Xkb device ID, will not be
+ <emphasis>XkbUseCoreKbd</emphasis> */
+ unsigned int changed_groups;/* number of group maps changed */
+ int first_si; /* index to 1st changed symbol
+ interpretation */
+ int num_si; /* number of changed symbol
+ interpretations */
+ int num_total_si; /* total number of valid symbol
+ interpretations */
+} <emphasis>XkbCompatMapNotifyEvent</emphasis>;
+</programlisting></para>
+
+<para>
+<emphasis>
+changed_groups</emphasis>
+ is the number of group compatibility maps that have changed. If you are
+maintaining a corresponding copy of the compatibility map, or get a fresh copy
+from the server using <emphasis>
+XkbGetCompatMap</emphasis>
+, <emphasis>
+changed_groups</emphasis>
+ references <emphasis>
+groups</emphasis>
+[0..<emphasis>
+changed_groups</emphasis>
+-1] in the <emphasis>
+XkbCompatMapRec</emphasis>
+ structure.
+</para>
+
+
+<para>
+<emphasis>
+first_si</emphasis>
+ is the index of the first changed symbol interpretation, <emphasis>
+num_si</emphasis>
+ is the number of changed symbol interpretations, and <emphasis>
+num_total_si</emphasis>
+ is the total number of valid symbol interpretations. If you are maintaining a
+corresponding copy of the compatibility map, or get a fresh copy from the
+server using <emphasis>
+XkbGetCompatMap</emphasis>
+, <emphasis>
+first_si</emphasis>
+, <emphasis>
+num_si</emphasis>
+, and <emphasis>
+num_total_si</emphasis>
+ are appropriate for use with the <emphasis>
+compat.sym_interpret</emphasis>
+ vector in this structure.
+</para>
+
+
+</sect1>
+<sect1 id='allocating_and_freeing_the_compatibility_map'>
+<title>Allocating and Freeing the Compatibility Map</title>
+
+<para>
+If you are modifying the compatibility map, you need to allocate a new
+compatibility map if you do not already have one available. To do so, use
+<emphasis>
+XkbAllocCompatMap</emphasis>
+.
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+Status <emphasis>
+XkbAllocCompatMap</emphasis>
+(<emphasis>
+xkb, which, num_si</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr <emphasis>
+ xkb</emphasis>
+; /* keyboard description in which to allocate compat map */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ which</emphasis>
+; /* mask of compatibility map components to allocate */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ num_si</emphasis>
+; /* number of symbol interpretations to allocate */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+xkb</emphasis>
+ specifies the keyboard description for which compatibility maps are to be
+allocated. The compatibility map is the <emphasis>
+compat</emphasis>
+ field in this structure.
+</para>
+
+
+<para>
+<emphasis>
+which</emphasis>
+ specifies the compatibility map components to be allocated (see <emphasis>
+XkbGetCompatMap</emphasis>
+, in section 17.2). <emphasis>
+which</emphasis>
+ is an inclusive OR of the bits shown in Table 17.2.
+</para>
+
+
+<para>
+<emphasis>
+num_si</emphasis>
+ specifies the total number of entries to allocate in the symbol interpretation
+vector (<emphasis>
+xkb.compat.sym_interpret</emphasis>
+).
+</para>
+
+
+<para>
+Note that symbol interpretations in a compatibility map (the <emphasis>
+sym_interpret</emphasis>
+ vector of <emphasis>
+XkbSymInterpretRec</emphasis>
+ structures) are also allocated using this same function. To ensure that there
+is sufficient space in the symbol interpretation vector for entries to be
+added, use <emphasis>
+XkbAllocCompatMap</emphasis>
+ specifying <emphasis>
+which</emphasis>
+ as <emphasis>
+XkbSymInterpretMask</emphasis>
+ and the number of free symbol interpretations needed in <emphasis>
+num_si</emphasis>
+.
+</para>
+
+
+<para>
+<emphasis>
+XkbAllocCompatMap</emphasis>
+ returns <emphasis>
+Success</emphasis>
+ if successful, <emphasis>
+BadMatch</emphasis>
+ if <emphasis>
+xkb</emphasis>
+ is <emphasis>
+NULL</emphasis>
+, or <emphasis>
+BadAlloc</emphasis>
+ if errors are encountered when attempting to allocate storage.
+</para>
+
+
+<para>
+To free an entire compatibility map or selected portions of one, use <emphasis>
+XkbFreeCompatMap</emphasis>
+.
+</para>
+
+
+<informaltable frame='none'>
+<tgroup cols='1'>
+<colspec colsep='0'/>
+<tbody>
+ <row rowsep='0'>
+ <entry role='functiondecl'>
+void <emphasis>
+XkbFreeCompatMap</emphasis>
+(<emphasis>
+xkb, which, free_map</emphasis>
+)
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+XkbDescPtr <emphasis>
+ xkb</emphasis>
+; /* Xkb description in which to free compatibility map */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+unsigned int<emphasis>
+ which</emphasis>
+; /* mask of compatibility map components to free */
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry role='functionargdecl'>
+Bool <emphasis>
+ free_map</emphasis>
+; /* <emphasis>
+True</emphasis>
+ =&gt; free <emphasis>
+XkbCompatMap</emphasis>
+ structure itself */
+ </entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+<emphasis>
+which</emphasis>
+ specifies the compatibility map components to be freed (see <emphasis>
+XkbGetCompatMap</emphasis>
+, in section 17.2). <emphasis>
+which</emphasis>
+ is an inclusive OR of the bits shown in Table 17.2
+</para>
+
+
+<para>
+<emphasis>
+free_map</emphasis>
+ indicates whether the <emphasis>
+XkbCompatMap</emphasis>
+ structure itself should be freed. If <emphasis>
+free_map</emphasis>
+ is <emphasis>
+True</emphasis>
+, <emphasis>
+which</emphasis>
+ is ignored, all non-<emphasis>
+NULL</emphasis>
+ compatibility map components are freed, and the <emphasis>
+compat</emphasis>
+ field in the <emphasis>
+XkbDescRec</emphasis>
+ referenced by <emphasis>
+xkb</emphasis>
+ is set to <emphasis>
+NULL</emphasis>
+.
+</para>
+
+</sect1>
+</chapter>