Xkb Client Keyboard Mapping
The Xkb client map for a keyboard is the collection of information a client
needs to interpret key events from the keyboard. It contains a global list of
key types and an array of key symbol maps, each of which describes the symbols
bound to a key and the rules to be used to interpret those symbols.
Figure 15.1 shows the relationships between elements in the client map:
Xkb Client Map
The XkbClientMapRec Structure
The
map
field of the complete Xkb keyboard description (see section 6.1) is a pointer
to the Xkb client map, which is of type
XkbClientMapRec
:
typedef struct { /* Client Map */
unsigned char size_types; /* # occupied entries in types */
unsigned char num_types; /* # entries in types */
XkbKeyTypePtr types; /* vector of key types used by this keymap */
unsigned short size_syms; /* length of the syms array */
unsigned short num_syms; /* # entries in syms */
KeySym * syms; /* linear 2d tables of keysyms, 1 per key */
XkbSymMapPtr key_sym_map; /* 1 per keycode, maps keycode to syms */
unsigned char * modmap; /* 1 per keycode, real mods bound to key */
} XkbClientMapRec, *XkbClientMapPtr;
The following sections describe each of the elements of the
XkbClientMapRec
structure in more detail.
Key Types
Key types are used to determine the shift level of a key given the current
state of the keyboard. The set of all possible key types for the Xkb keyboard
description are held in the
types
field of the client map, whose total size is stored in
size_types
, and whose total number of valid entries is stored in
num_types
. Key types are defined using the following structures:
typedef struct { /* Key Type */
XkbModsRec mods; /* modifiers used to compute shift
level */
unsigned char num_levels; /* total # shift levels, do not
modify directly */
unsigned char map_count; /* # entries in map,
preserve
(if non- NULL) */
XkbKTMapEntryPtr map; /* vector of modifiers for each
shift level */
XkbModsPtr preserve; /* mods to preserve for corresponding
map entry */
Atom name; /* name of key type */
Atom * level_names; /* array of names of each shift level */
} XkbKeyTypeRec, *XkbKeyTypePtr;
typedef struct { /* Modifiers for a key type */
Bool active; /* True => entry
active when determining shift level */
unsigned char level; /* shift level if modifiers match mods */
XkbModsRec mods; /* mods needed for this level to be
selected */
} XkbKTMapEntryRec,*XkbKTMapEntryPtr;
The
mods
field of a key type is an
XkbModsRec
(see section 7.2) specifying the modifiers the key type uses when calculating
the shift level, and can be composed of both the core modifiers and virtual
modifiers. To set the modifiers associated with a key type, modify the
real_mods
and
vmods
fields of the
mods
XkbModsRec
accordingly. The
mask
field of the
XkbModsRec
is reserved for use by Xkb and is calculated from the
real_mods
and
vmods
fields.
The
num_levels
field holds the total number of shift levels for the key type. Xkb uses
num_levels
to ensure the array of symbols bound to a key is large enough. Do not modify
num_levels
directly to change the number if shift levels for a key type. Instead, use
XkbResizeKeyType
(see section 15.2.3).
The
map
field is a vector of
XkbKTMapEntryRec
structures, with
map_count
entries, that specify the modifier combinations for each possible shift level.
Each map entry contains an
active
field, a
mods
field, and a
level
field. The
active
field determines whether the modifier combination listed in the
mods
field should be considered when determining shift level. If
active
is
False
, this
map
entry is ignored. If
active
is
True
, the
level
field of the
map
entry specifies the shift level to use when the current modifier combination
matches the combination specified in the
mods
field of the
map
entry.
Any combination of modifiers not explicitly listed somewhere in the
map
yields shift level one. In addition,
map
entries specifying unbound virtual modifiers are not considered.
Any modifiers specified in
mods
are normally
consumed
by
XkbTranslateKeyCode
(see section 12.1.3). For those rare occasions a modifier
should
be considered despite having been used to look up a symbol, key types include
an optional
preserve
field. If a
preserve
member of a key type is not
NULL
, it represents a list of modifiers where each entry corresponds directly to
one of the key type’s
map
. Each entry lists the modifiers that should
not
be consumed if the matching map entry is used to determine shift level.
Each shift level has a name and these names are held in the
level_names
array, whose length is
num_levels
. The type itself also has a name, which is held in the
name
field.
For example, consider how the server handles the following possible symbolic
description of a possible key type (note that the format used to specify
keyboard mappings in the server database is not specified by the Xkb extension,
although this format is one possible example):
Example Key Type
Symbolic Description
Key Type Data Structure
type "ALPHATHREE" {
Xkb->map->types[i].name
modifiers = Shift+Lock+LevelThree;
Xkb->map->types[i].mods
map[None]= Level1;
Xkb->map->types[i].map[0]
map[Lock]= Level1;
Xkb->map->types[i].map[1]
map[Shift]= Level2;
Xkb->map->types[i].map[2]
map[LevelThree]= Level3;
Xkb->map->types[i].map[3]
map[Shift+LevelThree]= Level3;
Xkb->map->types[i].map[4]
preserve[None]= None;
Xkb->map->types[i].perserve[0]
preserve[Lock]= Lock;
Xkb->map->types[i].preserve[1]
preserve[Shift]= None;
Xkb->map->types[i].preserve[2]
preserve[LevelThree]= None;
Xkb->map->types[i].preserve[3]
preserve[Shift+Level3]= None;
Xkb->map->types[i].preserve[4]
level_name[Level1]= "Base";
Xkb->map->types[i].level_names[0]
level_name[Level2]= "Caps";
Xkb->map->types[i].level_names[1]
level_name[Level3]= "Level3";
Xkb->map->types[i].level_names[2]
};
The
name
of the example key type is "ALPHATHREE," and the modifiers it pays attention
to are
Shift
,
Lock
, and the virtual modifier
LevelThree
. There are three shift levels. The name of shift level one is "Base," the name
of shift level two is "Caps," and the name of shift level three is "Level3."
Given the combination of the
map
and
preserve
specifications, there are five
map
entries. The first map entry specifies that shift level one is to be used if
no modifiers are set. The second entry specifies the
Lock
modifier alone also yields shift level one. The third entry specifies the
Shift
modifier alone yields shift level two. The fourth and fifth entries specify
that the virtual
LevelThree
modifier alone, or in combination with the
Shift
modifier, yields shift level three.
Shift level three can be reached only if the virtual modifier
LevelThree
is bound to a real modifier (see section 16.4). If
LevelThree
is not bound to a real modifier, the
map
entries associated with it are ignored.
Because the
Lock
modifier is to be preserved for further event processing, the
preserve
list is not
NULL
and parallels the
map
list. All
preserve
entries, except for the one corresponding to the
map
entry that specifies the
Lock
modifier, do not list any modifiers. For the
map
entry that specifies the
Lock
modifier, the corresponding
preserve
list entry lists the
Lock
modifier, meaning do not consume the
Lock
modifier. In this particular case, the preserved modifier is passed to Xlib
translation functions and causes them to notice that the
Lock
modifier is set; consequently, the Xlib functions apply the appropriate
capitalization rules to the symbol. Because this preserve entry is set only for
a modifier that yields shift level one, the capitalization occurs only for
level-one symbols.
The Canonical Key Types
Xkb allows up to
XkbMaxKeyTypes
(255) key types to be defined, but requires at least
XkbNumRequiredTypes
(4) predefined types to be in a key map. These predefined key types are
referred to as the canonical key types and describe the types of keys available
on most keyboards. The definitions for the canonical key types are held in the
first
XkbNumRequiredTypes
entries of the
types
field of the client map and are indexed using the following constants:
XkbOneLevelIndex
XkbTwoLevelIndex
XkbAlphabeticIndex
XkbKeypadIndex
ONE_LEVEL
The ONE_LEVEL key type describes groups that have only one symbol. The default
ONE_LEVEL key type has no map entries and does not pay attention to any
modifiers. A symbolic representation of this key type could look like the
following:
type "ONE_LEVEL" {
modifiers = None;
map[None]= Level1;
level_name[Level1]= "Any";
};
The description of the ONE_LEVEL key type is stored in the
types
[
XkbOneLevelIndex
] entry of the client key map.
TWO_LEVEL
The TWO_LEVEL key type describes groups that consist of two symbols but are
neither alphabetic nor numeric keypad keys. The default TWO_LEVEL type uses
only the
Shift
modifier. It returns shift level two if
Shift
is set, and level one if it is not. A symbolic representation of this key type
could look like the following:
type "TWO_LEVEL" {
modifiers = Shift;
map[Shift]= Level2;
level_name[Level1]= "Base";
level_name[Level2]= "Shift";
};
The description of the TWO_LEVEL key type is stored in the
types
[
XkbTwoLevelIndex
] entry of the client key map.
ALPHABETIC
The ALPHABETIC key type describes groups consisting of two symbols: the
lowercase form of a symbol followed by the uppercase form of the same symbol.
The default ALPHABETIC type implements locale-sensitive "Shift cancels
CapsLock" behavior using both the
Shift
and
Lock
modifiers as follows:
If
Shift
and
Lock
are both set, the default ALPHABETIC type yields level one.
If
Shift
alone is set, it yields level two.
If
Lock
alone is set, it yields level one, but preserves the
Lock
modifier so Xlib notices and applies the appropriate capitalization rules. The
Xlib functions are locale-sensitive and apply different capitalization rules
for different locales.
If neither
Shift
nor
Lock
is set, it yields level one.
A symbolic representation of this key type could look like the following:
type "ALPHABETIC" {
modifiers = Shift+Lock;
map[Shift]= Level2;
preserve[Lock]= Lock;
level_name[Level1]= "Base";
level_name[Level2]= "Caps";
};
The description of the ALPHABETIC key type is stored in the
types
[
XkbAlphabeticIndex
] entry of the client key map.
KEYPAD
The KEYPAD key type describes groups that consist of two symbols, at least one
of which is a numeric keypad symbol. The numeric keypad symbol is assumed to
reside at level two. The default KEYPAD key type implements "Shift cancels
NumLock" behavior using the Shift modifier and the real modifier bound to the
virtual modifier named "NumLock," known as the
NumLock
modifier, as follows:
If
Shift
and
NumLock
are both set, the default KEYPAD type yields level one.
If
Shift
alone is set, it yields level two.
If
NumLock
alone is set, it yields level two.
If neither
Shift
nor
NumLock
is set, it yields level one.
A symbolic representation of this key type could look like the following:
type "KEYPAD" {
modifiers = Shift+NumLock;
map[None]= Level1;
map[Shift]= Level2;
map[NumLock]= Level2;
map[Shift+NumLock]= Level1;
level_name[Level1]= "Base";
level_name[Level2]= "Caps";
};
The description of the KEYPAD key type is stored in the
types
[
XkbKeypadIndex
] entry of the client key map.
Initializing the Canonical Key Types in a New Client Map
To set the definitions of the canonical key types in a client map to their
default values, use
XkbInitCanonicalKeyTypes.
Status
XkbInitCanonicalKeyTypes
(
xkb, which, keypadVMod
)
XkbDescPtr
xkb
; /* keyboard description containing client map to initialize */
unsigned int
which
; /* mask of types to initialize */
int
keypadVMod
; /* index of NumLock virtual modifier */
XkbInitCanonicalKeyTypes
initializes the first
XkbNumRequiredTypes
key types of the keyboard specified by the
xkb
parameter to their default values. The
which
parameter specifies what canonical key types to initialize and is a bitwise
inclusive OR of the following masks:
XkbOneLevelMask
,
XkbTwoLevelMask
,
XkbAlphabeticMask
, and
XkbKeypadMask
. Only those canonical types specified by the
which
mask are initialized.
If
XkbKeypadMask
is set in the
which
parameter,
XkbInitCanonicalKeyTypes
looks up the
NumLock
named virtual modifier to determine which virtual modifier to use when
initializing the KEYPAD key type. If the
NumLock
virtual modifier does not exist,
XkbInitCanonicalKeyTypes
creates it.
XkbInitCanonicalKeyTypes
normally returns Success. It returns
BadAccess
if the Xkb extension has not been properly initialized, and
BadAccess
if the
xkb
parameter is not valid.
Getting Key Types from the Server
To obtain the list of available key types in the server’s keyboard mapping,
use
XkbGetKeyTypes
.
Status
XkbGetKeyTypes
(
dpy
,
first
,
num
,
xkb
)
Display *
dpy
; /* connection to X server */
unsigned int
first
; /* index to first type to get, 0 => 1st type */
unsigned int
num
; /* number of key types to be returned */
XkbDescPtr
xkb
; /* keyboard description containing client map to update */
XkbGetKeyTypes
is used to obtain descriptions of the key types themselves, not the key types
bound to individual keys. To obtain the key types bound to an individual key,
refer to the
key_sym_map
field of the client map (see section 15.3.1).
XkbGetKeyTypes
queries the server for the desired types, waits for a reply, and returns the
desired types in the
xkb->map->types
. If successful, it returns Success.
XkbGetKeyTypes
returns
BadAccess
if the Xkb extension has not been properly initialized and
BadValue
if the combination of
first
and
num
results in numbers out of valid range.
Changing the Number of Levels in a Key Type
To change the number of levels in a key type, use
XkbResizeKeyType
.
Status
XkbResizeKeyType
(
xkb
,
type_ndx
,
map_count
,
want_preserve
,
new_num_lvls
)
XkbDescPtr
xkb
; /* keyboard description containing client map to update */
int
type_ndx
; /* index in xkb->map->types of type to change */
int
map_count
; /* total # of map entries needed for the type */
Bool
want_preserve
; /*
True
=> list of preserved modifiers is necessary */
int
new_num_lvls
; /* new max # of levels for type */
XkbResizeKeyType
changes the type specified by
xkb
->
map->types
[
type_ndx
], and reallocates the symbols and actions bound to all keys that use the type,
if necessary.
XkbResizeKeyType
updates only the local copy of the types in
xkb
; to update the server’s copy for the physical device, use
XkbSetMap
or
XkbChangeMap
after calling
XkbResizeKeyType
.
The
map_count
parameter specifies the total number of map entries needed for the type, and
can be zero or greater. If
map_count
is zero,
XkbResizeKeyType
frees the existing
map
and
preserve
entries for the type if they exist and sets them to
NULL
.
The
want_preserve
parameter specifies whether a
preserve
list for the key should be created. If
want_preserve
is
True
, the
preserve
list with
map_count
entries is allocated or reallocated if it already exists. Otherwise, if
want_preserve
is
False
, the
preserve
field is freed if necessary and set to
NULL
.
The
new_num_lvls
parameter specifies the new maximum number of shift levels for the type and is
used to calculate and resize the symbols and actions bound to all keys that use
the type.
If
type_ndx
does not specify a legal type,
new_num_lvls
is less than 1, or the
map_count
is less than zero,
XkbResizeKeyType
returns
BadValue
. If
XkbResizeKeyType
encounters any problems with allocation, it returns
BadAlloc
. Otherwise, it returns
Success
.
Copying Key Types
Use
XkbCopyKeyType
and
XkbCopyKeyTypes
to copy one or more
XkbKeyTypeRec
structures.
Status
XkbCopyKeyType
(
from
,
into
)
XkbKeyTypePtr
from
; /* pointer to XkbKeyTypeRec to be copied */
XkbKeyTypePtr
into
; /* pointer to XkbKeyTypeRec to be changed */
XkbCopyKeyType
copies the key type specified by
from
to the key type specified by
into
. Both must point to legal
XkbKeyTypeRec
structures. Xkb assumes
from
and
into
point to different places. As a result, overlaps can be fatal.
XkbCopyKeyType
frees any existing
map
,
preserve
, and
level_names
in
into
prior to copying. If any allocation errors occur while copying
from
to
into
,
XkbCopyKeyType
returns
BadAlloc
. Otherwise,
XkbCopyKeyType
copies
from
to
into
and returns
Success
.
Status
XkbCopyKeyTypes
(
from
,
into
,
num_types
)
XkbKeyTypePtr
from
; /* pointer to array of XkbKeyTypeRecs to copy */
XkbKeyTypePtr
into
; /* pointer to array of XkbKeyTypeRecs to change */
int
num_types
; /* number of types to copy */
XkbCopyKeyTypes
copies
num_types
XkbKeyTypeRec
structures from the array specified by
from
into the array specified by
into
. It is intended for copying between, rather than within, keyboard
descriptions, so it doesn’t check for overlaps. The same rules that apply to
the
from
and
into
parameters in
XkbCopyKeyType
apply to each entry of the
from
and
into
arrays of
XkbCopyKeyTypes
. If any allocation errors occur while copying
from
to
into
,
XkbCopyKeyTypes
returns
BadAlloc
. Otherwise,
XkbCopyKeyTypes
copies
from
to
into
and returns
Success
.
Key Symbol Map
The entire list of key symbols for the keyboard mapping is held in the
syms
field of the client map. Whereas the core keyboard mapping is a
two-dimensional array of
KeySyms
whose rows are indexed by keycode, the
syms
field of Xkb is a linear list of
KeySyms
that needs to be indexed uniquely for each key. This section describes the key
symbol map and the methods for determining the symbols bound to a key.
The reason the
syms
field is a linear list of
KeySyms
is to reduce the memory consumption associated with a keymap; because Xkb
allows individual keys to have multiple shift levels and a different number of
groups per key, a single two-dimensional array of
KeySyms
would potentially be very large and sparse. Instead, Xkb provides a small
two-dimensional array of
KeySyms
for each key. To store all of these individual arrays, Xkb concatenates each
array together in the
syms
field of the client map.
In order to determine which
KeySyms
in the
syms
field are associated with each keycode, the client map contains an array of
key symbol mappings, held in the
key_sym_map
field. The
key_sym_map
field is an array of
XkbSymMapRec
structures indexed by keycode. The
key_sym_map
array has
min_key_code
unused entries at the start to allow direct indexing using a keycode. All
keycodes falling between the minimum and maximum legal keycodes, inclusive,
have
key_sym_map
arrays, whether or not any key actually yields that code. The
KeySymMapRec
structure is defined as follows:
#define XkbNumKbdGroups 4
#define XkbMaxKbdGroup (XkbNumKbdGroups-1)
typedef struct { /* map to keysyms for a single keycode */
unsigned char kt_index[XkbNumKbdGroups]; /* key type index for each group */
unsigned char group_info; /* # of groups and out of range group handling */
unsigned char width; /* max # of shift levels for key */
unsigned short offset; /* index to keysym table in syms array */
} XkbSymMapRec, *XkbSymMapPtr;
These fields are described in detail in the following sections.
Per-Key Key Type Indices
The
kt_index
array of the
XkbSymMapRec
structure contains the indices of the key types (see section 15.2) for each
possible group of symbols associated with the key. To obtain the index of a key
type or the pointer to a key type, Xkb provides the following macros, to access
the key types:
The array of key types is of fixed width and is large enough to
hold key types for the maximum legal number of groups (
XkbNumKbdGroups
, currently four); if a key has fewer than
XkbNumKbdGroups
groups, the extra key types are reported but ignored.
int
XkbKeyTypeIndex
(
xkb, keycode, group
) /* macro*/
XkbDescPtr
xkb
; /* Xkb description of interest */
KeyCode
keycode
; /* keycode of interest */
int
group
; /* group index */
XkbKeyTypeIndex
computes an index into the
types
vector of the client map in
xkb
from the given
keycode
and
group
index.
XkbKeyTypePtr
XkbKeyType
(
xkb, keycode, group
) /* macro */
XkbDescPtr
xkb
; /* Xkb description of interest */
KeyCode
keycode
; /* keycode of interest */
int
group
; /* group index */
XkbKeyType
returns a pointer to the key type in the
types
vector of the client map in
xkb
corresponding to the given
keycode
and
group
index.
Per-Key Group Information
The
group_info
field of an
XkbSymMapRec
is an encoded value containing the number of groups of symbols bound to the
key as well as the specification of the treatment of out-of-range groups. It is
legal for a key to have zero groups, in which case it also has zero symbols and
all events from that key yield
NoSymbol
. To obtain the number of groups of symbols bound to the key, use
XkbKeyNumGroups
. To change the number of groups bound to a key, use
XkbChangeTypesOfKey
(see section 15.3.6). To obtain a mask that determines the treatment of
out-of-range groups, use
XkbKeyGroupInfo
and
XkbOutOfRangeGroupInfo
.
The keyboard controls (see Chapter 10) contain a
groups_wrap
field specifying the handling of illegal groups on a global basis. That is,
when the user performs an action causing the effective group to go out of the
legal range, the
groups_wrap
field specifies how to normalize the effective keyboard group to a group that
is legal for the keyboard as a whole, but there is no guarantee that the
normalized group will be within the range of legal groups for any individual
key. The per-key
group_info
field specifies how a key treats a legal effective group if the key does not
have a type specified for the group of concern. For example, the
Enter
key usually has just one group defined. If the user performs an action causing
the global keyboard group to change to
Group2
, the
group_info
field for the
Enter
key describes how to handle this situation.
Out-of-range groups for individual keys are mapped to a legal group using the
same options as are used for the overall keyboard group. The particular type of
mapping used is controlled by the bits set in the
group_info
flag, as shown in Table 15.2. See section 10.7.1 for more details on the
normalization methods in this table.
group_info Range Normalization
Bits set in group_info
Normalization method
XkbRedirectIntoRange
XkbRedirectIntoRange
XkbClampIntoRange
XkbClampIntoRange
none of the above
XkbWrapIntoRange
Xkb provides the following macros to access group information:
int
XkbKeyNumGroups
(
xkb, keycode
) /* macro */
XkbDescPtr
xkb
; /* Xkb description of interest */
KeyCode
keycode
; /* keycode of interest */
XkbKeyNumGroups
returns the number of groups of symbols bound to the key corresponding to
keycode
.
unsigned char
XkbKeyGroupInfo
(
xkb, keycode
) /*macro */
XkbDescPtr
xkb
; /* Xkb description of interest */
KeyCode
keycode
; /* keycode of interest */
XkbKeyGroupInfo
returns the
group_info
field from the
XkbSymMapRec
structure associated with the key corresponding to
keycode
.
unsigned char
XkbOutOfRangeGroupInfo
(
grp_inf
) /* macro */
unsigned char
grp_inf
; /* group_info field of
XkbSymMapRec
*/
XkbOutOfRangeGroupInfo
returns only the out-of-range processing information from the
group_info
field of an
XkbSymMapRec
structure.
unsigned char
XkbOutOfRangeGroupNumber
(
grp_inf
) /* macro */
unsigned char
grp_inf
; /* group_info field of
XkbSymMapRec
*/
XkbOutOfRangeGroupNumber
returns the out-of-range group number, represented as a group index, from the
group_info
field of an
XkbSymMapRec
structure.
Key Width
The maximum number of shift levels for a type is also referred to as the width
of a key type. The
width
field of the
key_sym_map
entry for a key contains the width of the widest type associated with the key.
The
width
field cannot be explicitly changed; it is updated automatically whenever the
symbols or set of types bound to a key are changed.
Offset in to the Symbol Map
The key width and number of groups associated with a key are used to form a
small two-dimensional array of
KeySyms
for a key. This array may be different sizes for different keys. The array for
a single key is stored as a linear list, in row-major order. The arrays for all
of the keys are stored in the
syms
field of the client map. There is one row for each group associated with a key
and one column for each level. The index corresponding to a given group and
shift level is computed as:
idx = group_index * key_width + shift_level
The
offset
field of the
key_sym_map
entry for a key is used to access the beginning of the array.
Xkb provides the following macros for accessing the
width
and
offset
for individual keys, as well as macros for accessing the two-dimensional array
of symbols bound to the key:
int
XkbKeyGroupsWidth
(
xkb, keycode
) /* macro */
XkbDescPtr
xkb
; /* Xkb description of interest */
KeyCode
keycode
; /* keycode of interest */
XkbKeyGroupsWidth
computes the maximum width associated with the key corresponding to
keycode
.
int
XkbKeyGroupWidth
(
xkb, keycode, grp
) /* macro */
XkbDescPtr
xkb
; /* Xkb description of interest */
KeyCode
keycode
; /* keycode of interest */
int
grp
; /* group of interest */
XkbKeyGroupWidth
computes the width of the type associated with the group
grp
for the key corresponding to
keycode
.
int
XkbKeySymsOffset
(
xkb, keycode
) /* macro */
XkbDescPtr
xkb
; /* Xkb description of interest */
KeyCode
keycode
; /* keycode of interest */
XkbKeySymsOffset
returns the offset of the two-dimensional array of keysyms for the key
corresponding to
keycode
.
int
XkbKeyNumSyms
(
xkb, keycode
) /* macro */
XkbDescPtr
xkb
; /* Xkb description of interest */
KeyCode
keycode
; /* keycode of interest */
XkbKeyNumSyms
returns the total number of keysyms for the key corresponding to
keycode
.
KeySym *
XkbKeySymsPtr
(
xkb, keycode
) /* macro */
XkbDescPtr
xkb
; /* Xkb description of interest */
KeyCode
keycode
; /* keycode of interest */
XkbKeySymsPtr
returns the pointer to the two-dimensional array of keysyms for the key
corresponding to
keycode
.
KeySym
XkbKeySymEntry
(
xkb, keycode, shift, grp
) /* macro */
XkbDescPtr
xkb
; /* Xkb description of interest */
KeyCode
keycode
; /* keycode of interest */
int
shift
; /* shift level of interest */
int
grp
; /* group of interest */
XkbKeySymEntry
returns the
keysym
corresponding to shift level
shift
and group
grp
from the two-dimensional array of keysyms for the key corresponding to
keycode
Getting the Symbol Map for Keys from the Server
To obtain the symbols for a subset of the keys in a keyboard description, use
XkbGetKeySyms
:
Status
XkbGetKeySyms
(
dpy
,
first
,
num
,
xkb
)
Display *
dpy
; /* connection to X server */
unsigned int
first
; /* keycode of first key to get */
unsigned int
num
; /* number of keycodes for which syms desired */
XkbDescPtr
xkb
; /* Xkb description to be updated */
XkbGetKeySyms
sends a request to the server to obtain the set of keysyms bound to
num
keys starting with the key whose keycode is
first
. It waits for a reply and returns the keysyms in the
map.syms
field of
xkb
. If successful,
XkbGetKeySyms
returns
Success
. The
xkb
parameter must be a pointer to a valid Xkb keyboard description.
If the client
map
in the
xkb
parameter has not been allocated,
XkbGetKeySyms
allocates and initializes it before obtaining the symbols.
If a compatible version of Xkb is not available in the server or the Xkb
extension has not been properly initialized,
XkbGetKeySyms
returns
BadAccess
. If
num
is less than 1 or greater than
XkbMaxKeyCount
,
XkbGetKeySyms
returns
BadValue
. If any allocation errors occur,
XkbGetKeySyms
returns
BadAlloc
.
Changing the Number of Groups and Types Bound to a Key
To change the number of groups and the types bound to a key, use
XkbChangeTypesOfKey
.
Status
XkbChangeTypesOfKey
(
xkb
,
key
,
n_groups
,
groups
,
new_types_in
,
p_changes
)
XkbDescPtr
xkb
; /* keyboard description to be changed */
int
key
; /* keycode for key of interest */
int
n_groups
; /* new number of groups for key */
unsigned int
groups
; /* mask indicating groups to change */
int *
new_types_in
; /* indices for new groups specified in
groups
*/
XkbMapChangesPtr
p_changes
; /* notes changes made to
xkb
*/
XkbChangeTypesOfKey
reallocates the symbols and actions bound to the key, if necessary, and
initializes any new symbols or actions to
NoSymbol
or
NoAction
, as appropriate. If the
p_changes
parameter is not
NULL
,
XkbChangeTypesOfKey
adds the
XkbKeySymsMask
to the
changes
field of
p_changes
and modifies the
first_key_sym
and
num_key_syms
fields of
p_changes
to include the
key
that was changed. See section 14.3.1 for more information on the
XkbMapChangesPtr
structure. If successful,
XkbChangeTypesOfKey
returns
Success
.
The
n_groups
parameter specifies the new number of groups for the key. The
groups
parameter is a mask specifying the groups for which new types are supplied and
is a bitwise inclusive OR of the following masks:
XkbGroup1Mask
,
XkbGroup2Mask
,
XkbGroup3Mask
, and
XkbGroup4Mask
.
The
new_types_in
parameter is an integer array of length
n_groups
. Each entry represents the type to use for the associated group and is an
index into
xkb
->
map->types
. The
new_types_in
array is indexed by group index; if
n_groups
is four and
groups
only has
Group1Mask
and
Group3Mask
set,
new_types_in
looks like this:
new_types_in[0] = type for Group1
new_types_in[1] = ignored
new_types_in[2] = type for Group3
new_types_in[3] = ignored
For convenience, Xkb provides the following constants to use as indices to the
groups:
Group Index Constants
Constant Name
Value
XkbGroup1Index
0
XkbGroup2Index
1
XkbGroup3Index
2
XkbGroup4Index
3
If the Xkb extension has not been properly initialized,
XkbChangeTypesOfKey
returns
BadAccess
. If the
xkb
parameter it not valid (that is, it is
NULL
or it does not contain a valid client map),
XkbChangeTypesOfKey
returns
Bad
Match. If the
key
is not a valid keycode,
n_groups
is greater than
XkbNumKbdGroups
, or the
groups
mask does not contain any of the valid group mask bits,
XkbChangeTypesOfKey
returns
BadValue
. If it is necessary to resize the key symbols or key actions arrays and any
allocation errors occur,
XkbChangeTypesOfKey
returns
BadAlloc
.
Changing the Number of Symbols Bound to a Key
To change the number of symbols bound to a key, use
XkbResizeKeySyms
.
KeySym *
XkbResizeKeySyms
(
xkb
,
key
,
needed
)
XkbDescRec *
xkb
; /* keyboard description to be changed */
int
key
; /* keycode for key to modify */
int
needed
; /* new number of keysyms required for key */
XkbResizeKeySyms
reserves the space needed for
needed
keysyms and returns a pointer to the beginning of the new array that holds the
keysyms. It adjusts the
offset
field of the
key_sym_map
entry for the key if necessary and can also change the
syms
,
num_syms
, and
size_syms
fields of
xkb
-
>map
if it is necessary to reallocate the
syms
array.
XkbResizeKeySyms
does not modify either the width or number of groups associated with the key.
If
needed
is greater than the current number of keysyms for the key,
XkbResizeKeySyms
initializes all new keysyms in the array to
NoSymbol
.
Because the number of symbols needed by a key is normally computed as width *
number of groups, and
XkbResizeKeySyms
does not modify either the width or number of groups for the key, a
discrepancy exists upon return from
XkbResizeKeySyms
between the space allocated for the keysyms and the number required. The
unused entries in the list of symbols returned by
XkbResizeKeySyms
are not preserved across future calls to any of the map editing functions, so
you must update the key symbol mapping (which updates the width and number of
groups for the key) before calling another allocator function. A call to
XkbChangeTypesOfKey
will update the mapping.
If any allocation errors occur while resizing the number of symbols bound to
the key,
XkbResizeKeySyms
returns
NULL
.
A change to the number of symbols bound to a key should be
accompanied by a change in the number of actions bound to a key. Refer to
section 16.1.16 for more information on changing the number of actions bound to
a key.
The Per-Key Modifier Map
The
modmap
entry of the client map is an array, indexed by keycode, specifying the real
modifiers bound to a key. Each entry is a mask composed of a bitwise inclusive
OR of the legal real modifiers:
ShiftMask
,
LockMask
,
ControlMask
,
Mod1Mask
,
Mod2Mask
,
Mod3Mask
,
Mod4Mask
, and
Mod5Mask
. If a bit is set in a
modmap
entry, the corresponding key is bound to that modifier.
Pressing or releasing the key bound to a modifier changes the modifier set and
unset state. The particular manner in which the modifier set and unset state
changes is determined by the behavior and actions assigned to the key (see
Chapter 16).
Getting the Per-Key Modifier Map from the Server
To update the modifier map for one or more of the keys in a keyboard
description, use
XkbGetKeyModifierMap
.
Status
XkbGetKeyModifierMap
(
dpy
,
first
,
num
,
xkb
)
Display *
dpy
; /* connection to X server */
unsigned int
first
; /* keycode of first key to get */
unsigned int
num
; /* number of keys for which information is desired */
XkbDescPtr
xkb
; /* keyboard description to update */
XkbGetKeyModifierMap
sends a request to the server for the modifier mappings for
num
keys starting with the key whose keycode is
first
. It waits for a reply and places the results in the
xkb
->map->modmap array. If successful,
XkbGetKeyModifier
returns
Success
.
If the map component of the
xkb
parameter has not been allocated,
XkbGetKeyModifierMap
allocates and initializes it.
If a compatible version of Xkb is not available in the server or the Xkb
extension has not been properly initialized,
XkbGetKeySyms
returns
BadAccess
. If any allocation errors occur while obtaining the modifier map,
XkbGetKeyModifierMap
returns
BadAlloc
.