ch17.xml   [plain text]


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