The Xkb Compatibility Map
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.
Server Interaction with Types of Clients
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.
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
ChangeKeyboardMapping
or
SetModifierMapping
request, it updates its core keyboard mapping, then uses the compatibility map
to update its Xkb keyboard mapping. When the server receives an
XkbSetMap
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.
The core keyboard map is contained only in the server, not in any
client-side data structures.
Server Derivation of State and Keyboard Mapping Components
There are three kinds of compatibility transformations made by the server:
Xkb State to Core State
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.
In addition, whenever the Xkb state is retrieved, the
compat_state
,
compat_grab_mods
, and
compat_lookup_mods
fields of the
XkbStateRec
returned indicate the result of applying the compatibility map to the current
Xkb state in the server.
Core Keyboard Mapping to Xkb Keyboard Mapping
After core protocol requests received by the server to change the keyboard
mapping (
ChangeKeyboardMapping
and
SetModifierMapping
) 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.
Xkb Keyboard Mapping to Core Keyboard Mapping
After Xkb protocol requests received by the server to change the keyboard
mapping (
XkbSetMap
) 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.
This chapter discusses how a client may modify the compatibility map so that
subsequent transformations have a particular result.
The XkbCompatMap Structure
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
XkbCompatMap
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.
The
compat
member of an Xkb keyboard description (
XkbDescRec
) points to the
XkbCompatMap
structure:
typedef struct _XkbCompatMapRec {
XkbSymInterpretPtr sym_interpret; /* symbol based key semantics*/
XkbModsRec groups[XkbNumKbdGroups]; /* group => modifier map */
unsigned short num_si; /* # structures used in
sym_interpret */
unsigned short size_si; /* # structures allocated in
sym_interpret */
} XkbCompatMapRec, *XkbCompatMapPtr;
Xkb Compatibility Data Structures
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.
Xkb State to Core Protocol State Transformation
As shown in Figure 17.3, there are four
group compatibility maps
(contained in
groups
[0..3]) in the
XkbCompatMapRec
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
mask
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
XkbDescRec
does not support four groups, the extra groups fields are present, but
undefined.
Normally, the Xkb-aware server reports keyboard state in the
state
member of events such as a
KeyPress
event and
ButtonPress
event, encoded as follows:
bits
meaning
15
0
13-14
Group index
8-12
Pointer Buttons
0-7
Modifiers
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
groups
[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.
Core Keyboard Mapping to Xkb Keyboard Mapping Transformation
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:
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.
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.
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,
ExplicitKeyType1
through
ExplicitKeyType4
. 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.
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
NoSymbol
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):
G1L1 G1L2 G2L1 G2L2 G3L1 G3L2 G3L3
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:
G1L1 G1L2 G2L1 G2L2 G1L3 G2L3 G3L1 G3L2 G3L3 G4L1 G4L2 G4L3
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.
For each group on each changed key, assign a key type appropriate for the
symbols in the group.
For each changed key, remove any empty or redundant groups.
At this point, the groups and their associated symbols have been assigned to
the corresponding key definitions in the Xkb map.
Apply symbol interpretations to modify key operation. This phase is completely
skipped if the
ExplicitInterpret
override control bit is set in the explicit controls mask for the Xkb key (see
section 16.3).
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.
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.
The symbol interpretations used in step 2 are configurable and may be specified
using
XkbSymInterpretRec
structures referenced by the
sym_interpret
field of an
XkbCompatMapRec
(see Figure 17.3).
Symbol Interpretations — the XkbSymInterpretRec Structure
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
XkbSetCompatMap
(see section 17.4).
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:
Virtual modifier map
Auto repeat
Key behavior (may be set to XkbKB_Lock)
Key action (see section 16.1)
The XkbSymInterpretRec
structure specifies a symbol interpretation:
typedef struct {
KeySym sym; /* keysym of interest or NULL */
unsigned char flags; /* XkbSI_AutoRepeat, XkbSI_LockingKey */
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 */
} XkbSymInterpretRec,*XkbSymInterpretPtr;
If
sym
is not
NULL
, it limits the symbol interpretation to keys on which that particular keysym
is selected by the modifiers matching the criteria specified by
mods
and
match
. If
sym
is
NULL
, the interpretation may be applied to any symbol selected on a key when the
modifiers match the criteria specified by
mods
and
match
.
match
must be one of the values shown in Table 17.1 and specifies how the real
modifiers specified in mods
are to be interpreted.
Symbol Interpretation Match Criteria
Match Criteria
Value
Effect
XkbSI_NoneOf
(0)
None of the bits that are on in mods
can be set, but other bits can be.
XkbSI_AnyOfOrNone
(1)
Zero or more of the bits that are on in
mods
can be set, as well as others.
XkbSI_AnyOf
(2)
One or more of the bits that are on in
mods
can be set, as well as any others.
XkbSI_AllOf
(3)
All of the bits that are on in
mods
must be set, but others may be set as well.
XkbSI_Exactly
(4)
All of the bits that are on in
mods
must be set, and no other bits may be set.
In addition to the above bits,
match
may contain the
XkbSI_LevelOneOnly
bit, in which case the modifier match criteria specified by
mods
and
match
applies only if
sym
is in level one of its group; otherwise,
mods
and
match
are ignored and the symbol matches a condition where no modifiers are set.
#define XkbSI_LevelOneOnly (0x80)
/* use mods + match only if sym is level 1 */
If no matching symbol interpretation is found, the server uses a default
interpretation where:
sym =
0
flags =
XkbSI_AutoRepeat
match =
XkbSI_AnyOfOrNone
mods =
0
virtual_mod =
XkbNoModifier
act =
SA_NoAction
When a matching symbol interpretation is found in step 2a, the interpretation
is applied to modify the Xkb map as follows.
The
act
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.
If the Xkb keyboard map for the key does not have its
ExplicitVModMap
control set, the
XkbSI_LevelOneOnly
bit and symbol position are examined. If the
XkbSI_LevelOneOnly
bit is not set in
match
or the symbol is in position G1L1, the
virtual_mod
field is examined. If
virtual_mod
is not
XkbNoModifier
,
virtual_mod
specifies a single virtual modifier to be added to the virtual modifier map
for the key.
virtual_mod
is specified as an index in the range [0..15].
If the matching symbol is in position G1L1 of the key, two bits in the flags
field potentially specify additional behavior modifications:
#define XkbSI_AutoRepeat (1<<0)
/* key repeats if sym is in position G1L1 */
#define XkbSI_LockingKey (1<<1)
/* set KB_Lock
behavior if sym is in psn G1L1 */
If the Xkb keyboard map for the key does not have its
ExplicitAutoRepeat
control set, its auto repeat behavior is set based on the value of the
XkbSI_AutoRepeat
bit. If the
XkbSI_AutoRepeat
bit is set, the auto-repeat behavior of the key is turned on; otherwise, it is
turned off.
If the Xkb keyboard map for the key does not have its
ExplicitBehavior
control set, its locking behavior is set based on the value of the
XkbSI_LockingKey
bit. If
XkbSI_LockingKey
is set, the key behavior is set to
KB_Lock
; otherwise, it is turned off (see section 16.3).
Xkb Keyboard Mapping to Core Keyboard Mapping Transformations
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.
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:
G1L1 G1L2 G2L1 G2L2 G1L3-n G2L3-n G3L1-n G4L1-n
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.
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:
G1L1 G1L2 G1L1 G1L2 G1L3 G1L3 G1L1 G1L2 G1L3
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
mask
field of all of the group compatibility maps are added to the modifier mapping
as well. While an
XkbSA_ISOLock
action can theoretically affect any modifier, if the Xkb mapping for a key
specifies an
XkbSA_ISOLock
action, only the modifiers or group that are set by default are added to the
modifier mapping.
Getting Compatibility Map Components From the Server
Use
XkbGetCompatMap
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
XkbCompatMapNotify
events (see section 17.5).
XkbGetCompatMap
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.
To make a complete matching configuration you must also update the
explicit override components of the server state.
Status
XkbGetCompatMap
(
display, which, xkb
)
Display *
display
; /* connection to server */
unsigned int
which
; /* mask of compatibility map components to fetch */
XkbDescRec *
xkb
; /* keyboard description where results placed */
XkbGetCompatMap
fetches the components of the compatibility map specified in
which
from the server specified by
display
and places them in the
compat
structure of the keyboard description
xkb
. Valid values for
which
are an inclusive OR of the values shown in Table 17.2.
Compatibility Map Component Masks
Mask
Value
Affecting
XkbSymInterpMask
(1<<0)
Symbol interpretations
XkbGroupCompatMask
(1<<1)
Group maps
XkbAllCompatMask
(0x3)
All compatibility map components
If no compatibility map structure is allocated in
xkb
upon entry,
XkbGetCompatMap
allocates one. If one already exists, its contents are overwritten with the
returned results.
XkbGetCompatMap
fetches compatibility map information for the device specified by the
device_spec
field of
xkb
. Unless you have specifically modified this field, it is the default keyboard
device.
XkbGetCompatMap
returns
Success
if successful,
BadAlloc
if it is unable to obtain necessary storage for either the return values or
work space,
BadMatch
if the
dpy
field of the
xkb
argument is non-
NULL
and does not match the
display
argument, and
BadLength
under certain conditions caused by server or Xkb implementation errors.
Using the Compatibility Map
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
XGetKeyboardMapping
, for example), a data file, or some other source.
To update a local Xkb keyboard map to reflect the mapping expressed by a core
format mapping by calling the function
XkbUpdateMapFromCore
.
Bool
XkbUpdateMapFromCore
(
xkb
,
first_key
,
num_keys
,
map_width
,
core_keysyms
,
changes
)
XkbDescPtr
xkb
; /* keyboard description to update */
KeyCode
first_key
; /* keycode of first key description to update */
int
num_keys
; /* number of key descriptions to update */
int
map_width
; /* width of core protocol keymap */
KeySym *
core_keysyms
; /* symbols in core protocol keymap */
XkbChangesPtr
changes
; /* backfilled with changes made to Xkb */
XkbUpdateMapFromCore
interprets input argument information representing a keyboard map in core
format to update the Xkb keyboard description passed in
xkb
. Only a portion of the Xkb map is updated — the portion corresponding to
keys with keycodes in the range
first_key
through
first_key
+
num_keys
- 1. If
XkbUpdateMapFromCore
is being called in response to a
MappingNotify
event
, first_key
and
num_keys
are reported in the
MappingNotify
event.
core_keysyms
contains the keysyms corresponding to the keycode range being updated, in core
keyboard description order.
map_width
is the number of keysyms per key in
core_keysyms
. Thus, the first
map_width
entries in
core_keysyms
are for the key with keycode
first_key
, the next
map_width
entries are for key
first_key
+ 1, and so on.
In addition to modifying the Xkb keyboard mapping in
xkb
,
XkbUpdateMapFromCore
backfills the changes structure whose address is passed in
changes
to indicate the modifications that were made. You may then use
changes
in subsequent calls such as
XkbSetMap
, to propagate the local modifications to a server.
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
XkbKeyTypesForCoreSymbols
for this purpose:
int
XkbKeyTypesForCoreSymbols
(
map_width
,
core_syms
,
protected, types_inout, xkb_syms_rtrn
)
XkbDescPtr
xkb
; /* keyboard description in which to place symbols*/
int
map_width
; /* width of core protocol keymap in
xkb_syms_rtrn
*/
KeySym *
core_syms
; /* core protocol format array of KeySyms */
unsigned int
protected
; /* explicit key types */
int *
types_inout;
/* backfilled with the canonical types bound to groups one and two
for the key */
KeySym *
xkb_syms_rtrn
; /* backfilled with symbols bound to the key in the Xkb mapping */
XkbKeyTypesForCoreSymbols
expands the symbols in
core_syms
and types in
types_inout
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
xkb_syms_rtrn
, which will be non-
NULL
.
A core keymap is a two-dimensional array of keysyms. It has
map_width
columns and
max_key_code
rows.
XkbKeyTypesForCoreSymbols
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,
types_inout
has the types for each group, and
xkb_syms_rtrn
has the symbols in Xkb order (that is, groups are contiguous, regardless of
size).
protected
contains the explicitly protected key types. There is one explicit override
control associated with each of the four possible groups for each Xkb key,
ExplicitKeyType1
through
ExplicitKeyType4
; protected
is an inclusive OR of these controls.
map_width
is the width of the core keymap and is not dependent on any Xkb definitions.
types_inout
is an array of four type indices. On input,
types_inout
contains the indices of any types already assigned to the key, in case they
are explicitly protected from change.
Upon return,
types_inout
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
types_inout
correspond to the four groups for the key in question.
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
XkbApplyCompatMapToKey
.
Bool
XkbApplyCompatMapToKey
(
xkb
,
key
,
changes
)
XkbDescPtr
xkb;
/* keyboard description to be updated */
KeyCode
key
; /* key to be updated */
XkbChangesPtr
changes
; /* notes changes to the Xkb keyboard description */
XkbApplyCompatMapToKey
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.
Changing the Server’s Compatibility Map
To modify the server’s compatibility map, first modify a local copy of the
Xkb compatibility map, then call
XkbSetCompatMap
. You may allocate a new compatibility map for this purpose using
XkbAllocCompatMap
(see section 17.6). You may also use a compatibility map from another server,
although you need to adjust the
device_spec
field in the
XkbDescRec
accordingly. Note that symbol interpretations in a compatibility map
(
sym_interpret
, the vector of
XkbSymInterpretRec
structures) are also allocated using this same function.
Bool
XkbSetCompatMap
(
display, which, xkb, update_actions
)
Display *
display
; /* connection to server */
unsigned int
which
; /* mask of compat map components to set */
XkbDescPtr
xkb
; /* source for compat map components */
Bool
update_actions
; /*
True
=> apply to server’s keyboard map */
XkbSetCompatMap
copies compatibility map information from the keyboard description in
xkb
to the server specified in
display
’s compatibility map for the device specified by the
device_spec
field of
xkb
. Unless you have specifically modified this field, it is the default keyboard
device.
which
specifies the compatibility map components to be set, and is an inclusive OR
of the bits shown in Table 17.2.
After updating its compatibility map for the specified device, if
update_actions
is
True,
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
update_actions
is
False
, 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
XkbSetCompatMap
specifying
which
as zero and
update_actions
as
True
.
XkbSetCompatMap
returns
True
if successful and
False
if unsuccessful. The server may report problems it encounters when processing
the request subsequently via protocol errors.
To add a symbol interpretation to the list of symbol interpretations in an
XkbCompatRec
, use
XkbAddSymInterpret
.
XkbSymInterpretPtr
XkbAddSymInterpret
(
xkb, si, updateMap, changes
)
XkbDescPtr
xkb
; /* keyboard description to be updated */
XkbSymInterpretPtr
si
; /* symbol interpretation to be added */
Bool
updateMap
; /*
True
=>apply compatibility map to keys */
XkbChangesPtr
changes
; /* changes are put here */
XkbAddSymInterpret
adds
si
to the list of symbol interpretations in
xkb
. If
updateMap
is
True
, it (re)applies the compatibility map to all of the keys on the keyboard. If
changes
is non-
NULL
, it reports the parts of the keyboard that were affected (unless
updateMap
is
True
, not much changes).
XkbAddSymInterpret
returns a pointer to the actual new symbol interpretation in the list or
NULL
if it failed.
Tracking Changes to the Compatibility Map
The server automatically generates
MappingNotify
events when the keyboard mapping changes. If you wish to be notified of
changes to the compatibility map, you should select for
XkbCompatMapNotify
events. If you select for
XkbMapNotify
events, you no longer receive the automatically generated
MappingNotify
events. If you subsequently deselect
XkbMapNotifyEvent
delivery, you again receive
MappingNotify
events.
To receive
XkbCompatMapNotify
events under all possible conditions, use
XkbSelectEvents
(see section 4.3) and pass
XkbCompatMapNotifyMask
in both
bits_to_change
and
values_for_bits
.
To receive
XkbCompatMapNotify
events only under certain conditions, use
XkbSelectEventDetails
using
XkbCompatMapNotify
as the
event_type
and specifying the desired map changes in
bits_to_change
and
values_for_bits
using mask bits from Table 17.2.
Note that you are notified of changes you make yourself, as well as changes
made by other clients.
The structure for the
XkbCompatMapNotifyEvent
is:
typedef struct {
int type; /* Xkb extension base event code */
unsigned long serial; /* X server serial number for event */
Bool send_event; /* True =>
synthetically generated */
Display * display; /* server connection where event generated */
Time time; /* server time when event generated */
int xkb_type; /* XkbCompatMapNotify */
int device; /* Xkb device ID, will not be
XkbUseCoreKbd */
unsigned int changed_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 */
} XkbCompatMapNotifyEvent;
changed_groups
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
XkbGetCompatMap
,
changed_groups
references
groups
[0..
changed_groups
-1] in the
XkbCompatMapRec
structure.
first_si
is the index of the first changed symbol interpretation,
num_si
is the number of changed symbol interpretations, and
num_total_si
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
XkbGetCompatMap
,
first_si
,
num_si
, and
num_total_si
are appropriate for use with the
compat.sym_interpret
vector in this structure.
Allocating and Freeing the Compatibility Map
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
XkbAllocCompatMap
.
Status
XkbAllocCompatMap
(
xkb, which, num_si
)
XkbDescPtr
xkb
; /* keyboard description in which to allocate compat map */
unsigned int
which
; /* mask of compatibility map components to allocate */
unsigned int
num_si
; /* number of symbol interpretations to allocate */
xkb
specifies the keyboard description for which compatibility maps are to be
allocated. The compatibility map is the
compat
field in this structure.
which
specifies the compatibility map components to be allocated (see
XkbGetCompatMap
, in section 17.2).
which
is an inclusive OR of the bits shown in Table 17.2.
num_si
specifies the total number of entries to allocate in the symbol interpretation
vector (
xkb.compat.sym_interpret
).
Note that symbol interpretations in a compatibility map (the
sym_interpret
vector of
XkbSymInterpretRec
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
XkbAllocCompatMap
specifying
which
as
XkbSymInterpretMask
and the number of free symbol interpretations needed in
num_si
.
XkbAllocCompatMap
returns
Success
if successful,
BadMatch
if
xkb
is
NULL
, or
BadAlloc
if errors are encountered when attempting to allocate storage.
To free an entire compatibility map or selected portions of one, use
XkbFreeCompatMap
.
void
XkbFreeCompatMap
(
xkb, which, free_map
)
XkbDescPtr
xkb
; /* Xkb description in which to free compatibility map */
unsigned int
which
; /* mask of compatibility map components to free */
Bool
free_map
; /*
True
=> free
XkbCompatMap
structure itself */
which
specifies the compatibility map components to be freed (see
XkbGetCompatMap
, in section 17.2).
which
is an inclusive OR of the bits shown in Table 17.2
free_map
indicates whether the
XkbCompatMap
structure itself should be freed. If
free_map
is
True
,
which
is ignored, all non-
NULL
compatibility map components are freed, and the
compat
field in the
XkbDescRec
referenced by
xkb
is set to
NULL
.