2625 lines
64 KiB
XML
2625 lines
64 KiB
XML
<chapter id='Xkb_Client_Keyboard_Mapping'>
|
||
<title>Xkb Client Keyboard Mapping</title>
|
||
|
||
<para>
|
||
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.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Figure 15.1 shows the relationships between elements in the client map:
|
||
</para>
|
||
|
||
<mediaobject>
|
||
<imageobject> <imagedata format="SVG" fileref="XKBlib-15.svg"/>
|
||
</imageobject>
|
||
<caption>Xkb Client Map</caption>
|
||
</mediaobject>
|
||
|
||
|
||
<!--
|
||
<H5 CLASS="Figure">
|
||
Xkb Client Map</H5>
|
||
-->
|
||
|
||
<sect1 id='The_XkbClientMapRec_Structure'>
|
||
<title>The XkbClientMapRec Structure</title>
|
||
|
||
<para>
|
||
The <emphasis>
|
||
map </emphasis>
|
||
field of the complete Xkb keyboard description (see section 6.1) is a pointer
|
||
to the Xkb client map, which is of type <emphasis>
|
||
XkbClientMapRec</emphasis>
|
||
:
|
||
</para>
|
||
|
||
<para><programlisting>
|
||
typedef struct { /* Client Map */
|
||
unsigned char size_types; /* # occupied entries in <emphasis> types</emphasis> */
|
||
unsigned char num_types; /* # entries in <emphasis>types</emphasis> */
|
||
XkbKeyTypePtr types; /* vector of key types used by this keymap */
|
||
unsigned short size_syms; /* length of the <emphasis>syms</emphasis> array */
|
||
unsigned short num_syms; /* # entries in <emphasis>syms</emphasis> */
|
||
KeySym * syms; /* linear 2d tables of keysyms, 1 per key */
|
||
XkbSymMapPtr key_sym_map; /* 1 per keycode, maps keycode to <emphasis>syms</emphasis> */
|
||
unsigned char * modmap; /* 1 per keycode, real mods bound to key */
|
||
} <emphasis>XkbClientMapRec</emphasis>, *XkbClientMapPtr;
|
||
</programlisting></para>
|
||
|
||
<para>
|
||
The following sections describe each of the elements of the <emphasis>
|
||
XkbClientMapRec</emphasis>
|
||
structure in more detail.
|
||
</para>
|
||
|
||
|
||
</sect1>
|
||
<sect1 id='Key_Types'>
|
||
<title>Key Types</title>
|
||
|
||
<para>
|
||
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 <emphasis>
|
||
types</emphasis>
|
||
field of the client map, whose total size is stored in <emphasis>
|
||
size_types</emphasis>
|
||
, and whose total number of valid entries is stored in <emphasis>
|
||
num_types</emphasis>
|
||
. Key types are defined using the following structures:
|
||
</para>
|
||
|
||
<para><programlisting>
|
||
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 <emphasis>map</emphasis>,
|
||
<emphasis> preserve</emphasis>
|
||
(if non-<emphasis> NULL</emphasis>) */
|
||
XkbKTMapEntryPtr map; /* vector of modifiers for each
|
||
shift level */
|
||
XkbModsPtr preserve; /* mods to preserve for corresponding
|
||
<emphasis>map</emphasis> entry */
|
||
Atom name; /* name of key type */
|
||
Atom * level_names; /* array of names of each shift level */
|
||
} <emphasis>XkbKeyTypeRec</emphasis>, *XkbKeyTypePtr;
|
||
</programlisting></para>
|
||
|
||
<para><programlisting>
|
||
typedef struct { /* Modifiers for a key type */
|
||
Bool active; /* <emphasis> True</emphasis> => entry
|
||
active when determining shift level */
|
||
unsigned char level; /* shift level if modifiers match <emphasis> mods</emphasis> */
|
||
XkbModsRec mods; /* mods needed for this level to be
|
||
selected */
|
||
} <emphasis>XkbKTMapEntryRec</emphasis>,*XkbKTMapEntryPtr;
|
||
</programlisting></para>
|
||
|
||
<para>
|
||
The <emphasis>
|
||
mods</emphasis>
|
||
field of a key type is an <emphasis>
|
||
XkbModsRec</emphasis>
|
||
(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
|
||
<emphasis>
|
||
real_mods</emphasis>
|
||
and <emphasis>
|
||
vmods</emphasis>
|
||
fields of the <emphasis>
|
||
mods</emphasis>
|
||
<emphasis>
|
||
XkbModsRec</emphasis>
|
||
accordingly. The <emphasis>
|
||
mask</emphasis>
|
||
field of the <emphasis>
|
||
XkbModsRec</emphasis>
|
||
is reserved for use by Xkb and is calculated from the <emphasis>
|
||
real_mods</emphasis>
|
||
and <emphasis>
|
||
vmods</emphasis>
|
||
fields.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The <emphasis>
|
||
num_levels</emphasis>
|
||
field holds the total number of shift levels for the key type. Xkb uses
|
||
<emphasis>
|
||
num_levels</emphasis>
|
||
to ensure the array of symbols bound to a key is large enough. Do not modify
|
||
<emphasis>
|
||
num_levels</emphasis>
|
||
directly to change the number if shift levels for a key type. Instead, use
|
||
<emphasis>
|
||
XkbResizeKeyType</emphasis>
|
||
(see section 15.2.3).
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The <emphasis>
|
||
map</emphasis>
|
||
field is a vector of <emphasis>
|
||
XkbKTMapEntryRec</emphasis>
|
||
structures, with <emphasis>
|
||
map_count</emphasis>
|
||
entries, that specify the modifier combinations for each possible shift level.
|
||
Each map entry contains an <emphasis>
|
||
active</emphasis>
|
||
field, a <emphasis>
|
||
mods</emphasis>
|
||
field, and a <emphasis>
|
||
level</emphasis>
|
||
field. The <emphasis>
|
||
active</emphasis>
|
||
field determines whether the modifier combination listed in the <emphasis>
|
||
mods</emphasis>
|
||
field should be considered when determining shift level. If <emphasis>
|
||
active</emphasis>
|
||
is <emphasis>
|
||
False</emphasis>
|
||
, this <emphasis>
|
||
map</emphasis>
|
||
entry is ignored. If <emphasis>
|
||
active</emphasis>
|
||
is <emphasis>
|
||
True</emphasis>
|
||
, the <emphasis>
|
||
level</emphasis>
|
||
field of the <emphasis>
|
||
map </emphasis>
|
||
entry specifies the shift level to use when the current modifier combination
|
||
matches the combination specified in the <emphasis>
|
||
mods</emphasis>
|
||
field of the <emphasis>
|
||
map</emphasis>
|
||
entry.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Any combination of modifiers not explicitly listed somewhere in the <emphasis>
|
||
map</emphasis>
|
||
yields shift level one. In addition, <emphasis>
|
||
map</emphasis>
|
||
entries specifying unbound virtual modifiers are not considered.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Any modifiers specified in <emphasis>
|
||
mods</emphasis>
|
||
are normally <emphasis>
|
||
consumed</emphasis>
|
||
by <emphasis>
|
||
XkbTranslateKeyCode</emphasis>
|
||
(see section 12.1.3). For those rare occasions a modifier <emphasis>
|
||
should</emphasis>
|
||
be considered despite having been used to look up a symbol, key types include
|
||
an optional <emphasis>
|
||
preserve</emphasis>
|
||
field. If a <emphasis>
|
||
preserve</emphasis>
|
||
member of a key type is not <emphasis>
|
||
NULL</emphasis>
|
||
, it represents a list of modifiers where each entry corresponds directly to
|
||
one of the key type’s <emphasis>
|
||
map</emphasis>
|
||
. Each entry lists the modifiers that should <emphasis>
|
||
not</emphasis>
|
||
be consumed if the matching map entry is used to determine shift level.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Each shift level has a name and these names are held in the <emphasis>
|
||
level_names</emphasis>
|
||
array, whose length is <emphasis>
|
||
num_levels</emphasis>
|
||
. The type itself also has a name, which is held in the <emphasis>
|
||
name</emphasis>
|
||
field.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
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):
|
||
</para>
|
||
|
||
<table frame='topbot'>
|
||
<title>Example Key Type</title>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='2' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<colspec colname='c2' colwidth='1.0*'/>
|
||
<thead>
|
||
<row rowsep='1'>
|
||
<entry>Symbolic Description</entry>
|
||
<entry>Key Type Data Structure</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>type "ALPHATHREE" {</entry>
|
||
<entry>Xkb->map->types[i].name</entry>
|
||
</row>
|
||
<row>
|
||
<entry>modifiers = Shift+Lock+LevelThree;</entry>
|
||
<entry>Xkb->map->types[i].mods</entry>
|
||
</row>
|
||
<row>
|
||
<entry><emphasis>map[None]= Level1;</emphasis></entry>
|
||
<entry>Xkb->map->types[i].map[0]</entry>
|
||
</row>
|
||
<row>
|
||
<entry><emphasis>map[Lock]= Level1;</emphasis></entry>
|
||
<entry>Xkb->map->types[i].map[1]</entry>
|
||
</row>
|
||
<row>
|
||
<entry>map[Shift]= Level2;</entry>
|
||
<entry>Xkb->map->types[i].map[2]</entry>
|
||
</row>
|
||
<row>
|
||
<entry>map[LevelThree]= Level3;</entry>
|
||
<entry>Xkb->map->types[i].map[3]</entry>
|
||
</row>
|
||
<row>
|
||
<entry>map[Shift+LevelThree]= Level3;</entry>
|
||
<entry>Xkb->map->types[i].map[4]</entry>
|
||
</row>
|
||
<row>
|
||
<entry><emphasis>preserve[None]= None;</emphasis></entry>
|
||
<entry>Xkb->map->types[i].perserve[0]</entry>
|
||
</row>
|
||
<row>
|
||
<entry>preserve[Lock]= Lock;</entry>
|
||
<entry>Xkb->map->types[i].preserve[1]</entry>
|
||
</row>
|
||
<row>
|
||
<entry><emphasis>preserve[Shift]= None;</emphasis></entry>
|
||
<entry>Xkb->map->types[i].preserve[2]</entry>
|
||
</row>
|
||
<row>
|
||
<entry><emphasis>preserve[LevelThree]= None;</emphasis></entry>
|
||
<entry>Xkb->map->types[i].preserve[3]</entry>
|
||
</row>
|
||
<row>
|
||
<entry><emphasis>preserve[Shift+Level3]= None;</emphasis> </entry>
|
||
<entry>Xkb->map->types[i].preserve[4]</entry>
|
||
</row>
|
||
<row>
|
||
<entry>level_name[Level1]= "Base";</entry>
|
||
<entry>Xkb->map->types[i].level_names[0]</entry>
|
||
</row>
|
||
<row>
|
||
<entry>level_name[Level2]= "Caps";</entry>
|
||
<entry>Xkb->map->types[i].level_names[1]</entry>
|
||
</row>
|
||
<row>
|
||
<entry>level_name[Level3]= "Level3";</entry>
|
||
<entry>Xkb->map->types[i].level_names[2]</entry>
|
||
</row>
|
||
<row>
|
||
<entry>};</entry>
|
||
<entry></entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
|
||
<para>
|
||
The <emphasis>
|
||
name</emphasis>
|
||
of the example key type is "ALPHATHREE," and the modifiers it pays attention
|
||
to are <emphasis>
|
||
Shift</emphasis>
|
||
, <emphasis>
|
||
Lock</emphasis>
|
||
, and the virtual modifier <emphasis>
|
||
LevelThree</emphasis>
|
||
. 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."
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Given the combination of the <emphasis>
|
||
map</emphasis>
|
||
and <emphasis>
|
||
preserve</emphasis>
|
||
specifications, there are five <emphasis>
|
||
map</emphasis>
|
||
entries. The first map entry specifies that shift level one is to be used if
|
||
no modifiers are set. The second entry specifies the <emphasis>
|
||
Lock</emphasis>
|
||
modifier alone also yields shift level one. The third entry specifies the
|
||
<emphasis>
|
||
Shift</emphasis>
|
||
modifier alone yields shift level two. The fourth and fifth entries specify
|
||
that the virtual <emphasis>
|
||
LevelThree</emphasis>
|
||
modifier alone, or in combination with the <emphasis>
|
||
Shift</emphasis>
|
||
modifier, yields shift level three.
|
||
</para>
|
||
|
||
<note><para>Shift level three can be reached only if the virtual modifier
|
||
<emphasis>
|
||
LevelThree</emphasis>
|
||
is bound to a real modifier (see section 16.4). If <emphasis>
|
||
LevelThree</emphasis>
|
||
is not bound to a real modifier, the <emphasis>
|
||
map</emphasis>
|
||
entries associated with it are ignored.</para></note>
|
||
|
||
<para>
|
||
Because the <emphasis>
|
||
Lock</emphasis>
|
||
modifier is to be preserved for further event processing, the <emphasis>
|
||
preserve</emphasis>
|
||
list is not <emphasis>
|
||
NULL</emphasis>
|
||
and parallels the <emphasis>
|
||
map</emphasis>
|
||
list. All <emphasis>
|
||
preserve</emphasis>
|
||
entries, except for the one corresponding to the <emphasis>
|
||
map</emphasis>
|
||
entry that specifies the <emphasis>
|
||
Lock </emphasis>
|
||
modifier, do not list any modifiers. For the <emphasis>
|
||
map</emphasis>
|
||
entry that specifies the <emphasis>
|
||
Lock</emphasis>
|
||
modifier, the corresponding <emphasis>
|
||
preserve</emphasis>
|
||
list entry lists the <emphasis>
|
||
Lock</emphasis>
|
||
modifier, meaning do not consume the <emphasis>
|
||
Lock</emphasis>
|
||
modifier. In this particular case, the preserved modifier is passed to Xlib
|
||
translation functions and causes them to notice that the <emphasis>
|
||
Lock</emphasis>
|
||
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.
|
||
</para>
|
||
|
||
|
||
<sect2 id='The_Canonical_Key_Types'>
|
||
<title>The Canonical Key Types</title>
|
||
|
||
<para>
|
||
Xkb allows up to <emphasis>
|
||
XkbMaxKeyTypes</emphasis>
|
||
(255) key types to be defined, but requires at least <emphasis>
|
||
XkbNumRequiredTypes</emphasis>
|
||
(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 <emphasis>
|
||
XkbNumRequiredTypes</emphasis>
|
||
entries of the <emphasis>
|
||
types</emphasis>
|
||
field of the client map and are indexed using the following constants:
|
||
</para>
|
||
|
||
<para><programlisting>
|
||
<emphasis>XkbOneLevelIndex</emphasis>
|
||
<emphasis>XkbTwoLevelIndex</emphasis>
|
||
<emphasis>XkbAlphabeticIndex</emphasis>
|
||
<emphasis>XkbKeypadIndex</emphasis>
|
||
</programlisting></para>
|
||
|
||
<sect3 id='ONE_LEVEL'>
|
||
<title>ONE_LEVEL</title>
|
||
|
||
<para>
|
||
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:
|
||
</para>
|
||
|
||
<literallayout>
|
||
type "ONE_LEVEL" {
|
||
modifiers = None;
|
||
map[None]= Level1;
|
||
level_name[Level1]= "Any";
|
||
};
|
||
</literallayout>
|
||
|
||
<para>
|
||
The description of the ONE_LEVEL key type is stored in the <emphasis>
|
||
types</emphasis>
|
||
[<emphasis>
|
||
XkbOneLevelIndex</emphasis>
|
||
] entry of the client key map.
|
||
</para>
|
||
|
||
|
||
</sect3>
|
||
<sect3 id='TWO_LEVEL'>
|
||
<title>TWO_LEVEL</title>
|
||
|
||
<para>
|
||
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 <emphasis>
|
||
Shift</emphasis>
|
||
modifier. It returns shift level two if <emphasis>
|
||
Shift</emphasis>
|
||
is set, and level one if it is not. A symbolic representation of this key type
|
||
could look like the following:
|
||
</para>
|
||
|
||
<literallayout>
|
||
type "TWO_LEVEL" {
|
||
modifiers = Shift;
|
||
map[Shift]= Level2;
|
||
level_name[Level1]= "Base";
|
||
level_name[Level2]= "Shift";
|
||
};
|
||
</literallayout>
|
||
|
||
<para>
|
||
The description of the TWO_LEVEL key type is stored in the <emphasis>
|
||
types</emphasis>
|
||
[<emphasis>
|
||
XkbTwoLevelIndex</emphasis>
|
||
] entry of the client key map.
|
||
</para>
|
||
|
||
|
||
</sect3>
|
||
<sect3 id='ALPHABETIC'>
|
||
<title>ALPHABETIC</title>
|
||
|
||
<para>
|
||
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 <emphasis>
|
||
Shift</emphasis>
|
||
and <emphasis>
|
||
Lock</emphasis>
|
||
modifiers as follows:
|
||
</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
If <emphasis>
|
||
Shift</emphasis>
|
||
and <emphasis>
|
||
Lock</emphasis>
|
||
are both set, the default ALPHABETIC type yields level one.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
If <emphasis>
|
||
Shift</emphasis>
|
||
alone is set, it yields level two.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
If <emphasis>
|
||
Lock</emphasis>
|
||
alone is set, it yields level one, but preserves the <emphasis>
|
||
Lock</emphasis>
|
||
modifier so Xlib notices and applies the appropriate capitalization rules. The
|
||
Xlib functions are locale-sensitive and apply different capitalization rules
|
||
for different locales.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
If neither <emphasis>
|
||
Shift</emphasis>
|
||
nor <emphasis>
|
||
Lock</emphasis>
|
||
is set, it yields level one.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>
|
||
A symbolic representation of this key type could look like the following:
|
||
</para>
|
||
|
||
<literallayout>
|
||
type "ALPHABETIC" {
|
||
modifiers = Shift+Lock;
|
||
map[Shift]= Level2;
|
||
preserve[Lock]= Lock;
|
||
level_name[Level1]= "Base";
|
||
level_name[Level2]= "Caps";
|
||
};
|
||
</literallayout>
|
||
|
||
<para>
|
||
The description of the ALPHABETIC key type is stored in the <emphasis>
|
||
types</emphasis>
|
||
[<emphasis>
|
||
XkbAlphabeticIndex</emphasis>
|
||
] entry of the client key map.
|
||
</para>
|
||
|
||
|
||
</sect3>
|
||
<sect3 id='KEYPAD'>
|
||
<title>KEYPAD</title>
|
||
|
||
<para>
|
||
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 <emphasis>
|
||
NumLock</emphasis>
|
||
modifier, as follows:
|
||
</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
If <emphasis>
|
||
Shift</emphasis>
|
||
and <emphasis>
|
||
NumLock</emphasis>
|
||
are both set, the default KEYPAD type yields level one.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
If <emphasis>
|
||
Shift</emphasis>
|
||
alone is set, it yields level two.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
If <emphasis>
|
||
NumLock</emphasis>
|
||
alone is set, it yields level two.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
If neither <emphasis>
|
||
Shift</emphasis>
|
||
nor <emphasis>
|
||
NumLock</emphasis>
|
||
is set, it yields level one.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>
|
||
A symbolic representation of this key type could look like the following:
|
||
</para>
|
||
|
||
<literallayout>
|
||
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";
|
||
};
|
||
</literallayout>
|
||
|
||
<para>
|
||
The description of the KEYPAD key type is stored in the <emphasis>
|
||
types</emphasis>
|
||
[<emphasis>
|
||
XkbKeypadIndex</emphasis>
|
||
] entry of the client key map.
|
||
</para>
|
||
|
||
|
||
</sect3>
|
||
<sect3 id='Initializing_the_Canonical_Key_Types_in_a_New_Client_Map'>
|
||
<title>Initializing the Canonical Key Types in a New Client Map</title>
|
||
|
||
<para>
|
||
To set the definitions of the canonical key types in a client map to their
|
||
default values, use <emphasis>
|
||
XkbInitCanonicalKeyTypes.</emphasis>
|
||
</para>
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
Status <emphasis>
|
||
XkbInitCanonicalKeyTypes</emphasis>
|
||
(<emphasis>
|
||
xkb, which, keypadVMod</emphasis>
|
||
)
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* keyboard description containing client map to initialize */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
unsigned int <emphasis>
|
||
which</emphasis>
|
||
; /* mask of types to initialize */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int <emphasis>
|
||
keypadVMod</emphasis>
|
||
; /* index of NumLock virtual modifier */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbInitCanonicalKeyTypes</emphasis>
|
||
initializes the first <emphasis>
|
||
XkbNumRequiredTypes</emphasis>
|
||
key types of the keyboard specified by the <emphasis>
|
||
xkb</emphasis>
|
||
parameter to their default values. The <emphasis>
|
||
which</emphasis>
|
||
parameter specifies what canonical key types to initialize and is a bitwise
|
||
inclusive OR of the following masks: <emphasis>
|
||
XkbOneLevelMask</emphasis>
|
||
, <emphasis>
|
||
XkbTwoLevelMask</emphasis>
|
||
, <emphasis>
|
||
XkbAlphabeticMask</emphasis>
|
||
, and <emphasis>
|
||
XkbKeypadMask</emphasis>
|
||
. Only those canonical types specified by the <emphasis>
|
||
which</emphasis>
|
||
mask are initialized.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If <emphasis>
|
||
XkbKeypadMask</emphasis>
|
||
is set in the <emphasis>
|
||
which</emphasis>
|
||
parameter, <emphasis>
|
||
XkbInitCanonicalKeyTypes</emphasis>
|
||
looks up the <emphasis>
|
||
NumLock</emphasis>
|
||
named virtual modifier to determine which virtual modifier to use when
|
||
initializing the KEYPAD key type. If the <emphasis>
|
||
NumLock</emphasis>
|
||
virtual modifier does not exist, <emphasis>
|
||
XkbInitCanonicalKeyTypes</emphasis>
|
||
creates it.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbInitCanonicalKeyTypes</emphasis>
|
||
normally returns Success. It returns <emphasis>
|
||
BadAccess</emphasis>
|
||
if the Xkb extension has not been properly initialized, and <emphasis>
|
||
BadAccess</emphasis>
|
||
if the <emphasis>
|
||
xkb</emphasis>
|
||
parameter is not valid.
|
||
</para>
|
||
|
||
|
||
|
||
</sect3>
|
||
</sect2>
|
||
<sect2 id='Getting_Key_Types_from_the_Server'>
|
||
<title>Getting Key Types from the Server</title>
|
||
|
||
<para>
|
||
To obtain the list of available key types in the server’s keyboard mapping,
|
||
use <emphasis>
|
||
XkbGetKeyTypes</emphasis>
|
||
.
|
||
</para>
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
Status <emphasis>
|
||
XkbGetKeyTypes</emphasis>
|
||
(<emphasis>
|
||
dpy</emphasis>
|
||
,<emphasis>
|
||
first</emphasis>
|
||
,<emphasis>
|
||
num</emphasis>
|
||
,<emphasis>
|
||
xkb</emphasis>
|
||
)
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
Display *<emphasis>
|
||
dpy</emphasis>
|
||
; /* connection to X server */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
unsigned int<emphasis>
|
||
first</emphasis>
|
||
; /* index to first type to get, 0 => 1st type */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
unsigned int <emphasis>
|
||
num</emphasis>
|
||
; /* number of key types to be returned */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* keyboard description containing client map to update */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
<note><para><emphasis>
|
||
XkbGetKeyTypes</emphasis>
|
||
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 <emphasis>
|
||
key_sym_map</emphasis>
|
||
field of the client map (see section 15.3.1).</para></note>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbGetKeyTypes</emphasis>
|
||
queries the server for the desired types, waits for a reply, and returns the
|
||
desired types in the <emphasis>
|
||
xkb->map->types</emphasis>
|
||
. If successful, it returns Success.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbGetKeyTypes</emphasis>
|
||
returns <emphasis>
|
||
BadAccess</emphasis>
|
||
if the Xkb extension has not been properly initialized and <emphasis>
|
||
BadValue</emphasis>
|
||
if the combination of <emphasis>
|
||
first</emphasis>
|
||
and <emphasis>
|
||
num</emphasis>
|
||
results in numbers out of valid range.
|
||
</para>
|
||
|
||
|
||
</sect2>
|
||
<sect2 id='Changing_the_Number_of_Levels_in_a_Key_Type'>
|
||
<title>Changing the Number of Levels in a Key Type</title>
|
||
|
||
<para>
|
||
To change the number of levels in a key type, use <emphasis>
|
||
XkbResizeKeyType</emphasis>
|
||
.
|
||
</para>
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
Status <emphasis>
|
||
XkbResizeKeyType</emphasis>
|
||
(<emphasis>
|
||
xkb</emphasis>
|
||
,<emphasis>
|
||
type_ndx</emphasis>
|
||
,<emphasis>
|
||
map_count</emphasis>
|
||
,<emphasis>
|
||
want_preserve</emphasis>
|
||
,<emphasis>
|
||
new_num_lvls</emphasis>
|
||
)
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr<emphasis>
|
||
xkb</emphasis>
|
||
; /* keyboard description containing client map to update */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int <emphasis>
|
||
type_ndx</emphasis>
|
||
; /* index in xkb->map->types of type to change */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int <emphasis>
|
||
map_count</emphasis>
|
||
; /* total # of map entries needed for the type */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
Bool <emphasis>
|
||
want_preserve</emphasis>
|
||
; /* <emphasis>
|
||
True</emphasis>
|
||
=> list of preserved modifiers is necessary */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int <emphasis>
|
||
new_num_lvls</emphasis>
|
||
; /* new max # of levels for type */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbResizeKeyType</emphasis>
|
||
changes the type specified by <emphasis>
|
||
xkb</emphasis>
|
||
-><emphasis>
|
||
map->types</emphasis>
|
||
[<emphasis>
|
||
type_ndx</emphasis>
|
||
], and reallocates the symbols and actions bound to all keys that use the type,
|
||
if necessary. <emphasis>
|
||
XkbResizeKeyType</emphasis>
|
||
updates only the local copy of the types in <emphasis>
|
||
xkb</emphasis>
|
||
; to update the server’s copy for the physical device, use <emphasis>
|
||
XkbSetMap</emphasis>
|
||
or <emphasis>
|
||
XkbChangeMap</emphasis>
|
||
after calling <emphasis>
|
||
XkbResizeKeyType</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The <emphasis>
|
||
map_count</emphasis>
|
||
parameter specifies the total number of map entries needed for the type, and
|
||
can be zero or greater. If <emphasis>
|
||
map_count</emphasis>
|
||
is zero, <emphasis>
|
||
XkbResizeKeyType</emphasis>
|
||
frees the existing <emphasis>
|
||
map</emphasis>
|
||
and <emphasis>
|
||
preserve</emphasis>
|
||
entries for the type if they exist and sets them to <emphasis>
|
||
NULL</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The <emphasis>
|
||
want_preserve</emphasis>
|
||
parameter specifies whether a <emphasis>
|
||
preserve</emphasis>
|
||
list for the key should be created. If <emphasis>
|
||
want_preserve</emphasis>
|
||
is <emphasis>
|
||
True</emphasis>
|
||
, the <emphasis>
|
||
preserve</emphasis>
|
||
list with <emphasis>
|
||
map_count</emphasis>
|
||
entries is allocated or reallocated if it already exists. Otherwise, if
|
||
<emphasis>
|
||
want_preserve</emphasis>
|
||
is <emphasis>
|
||
False</emphasis>
|
||
, the <emphasis>
|
||
preserve</emphasis>
|
||
field is freed if necessary and set to <emphasis>
|
||
NULL</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The <emphasis>
|
||
new_num_lvls</emphasis>
|
||
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.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If <emphasis>
|
||
type_ndx</emphasis>
|
||
does not specify a legal type, <emphasis>
|
||
new_num_lvls</emphasis>
|
||
is less than 1, or the <emphasis>
|
||
map_count</emphasis>
|
||
is less than zero, <emphasis>
|
||
XkbResizeKeyType</emphasis>
|
||
returns <emphasis>
|
||
BadValue</emphasis>
|
||
. If <emphasis>
|
||
XkbResizeKeyType</emphasis>
|
||
encounters any problems with allocation, it returns <emphasis>
|
||
BadAlloc</emphasis>
|
||
. Otherwise, it returns <emphasis>
|
||
Success</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
</sect2>
|
||
<sect2 id='Copying_Key_Types'>
|
||
<title>Copying Key Types</title>
|
||
|
||
<para>
|
||
Use <emphasis>
|
||
XkbCopyKeyType</emphasis>
|
||
and <emphasis>
|
||
XkbCopyKeyTypes</emphasis>
|
||
to copy one or more <emphasis>
|
||
XkbKeyTypeRec</emphasis>
|
||
structures.
|
||
</para>
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
Status <emphasis>
|
||
XkbCopyKeyType</emphasis>
|
||
(<emphasis>
|
||
from</emphasis>
|
||
,<emphasis>
|
||
into</emphasis>
|
||
)
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbKeyTypePtr <emphasis>
|
||
from</emphasis>
|
||
; /* pointer to XkbKeyTypeRec to be copied */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbKeyTypePtr <emphasis>
|
||
into</emphasis>
|
||
; /* pointer to XkbKeyTypeRec to be changed */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbCopyKeyType</emphasis>
|
||
copies the key type specified by <emphasis>
|
||
from</emphasis>
|
||
to the key type specified by <emphasis>
|
||
into</emphasis>
|
||
. Both must point to legal <emphasis>
|
||
XkbKeyTypeRec</emphasis>
|
||
structures. Xkb assumes <emphasis>
|
||
from</emphasis>
|
||
and <emphasis>
|
||
into</emphasis>
|
||
point to different places. As a result, overlaps can be fatal. <emphasis>
|
||
XkbCopyKeyType</emphasis>
|
||
frees any existing <emphasis>
|
||
map</emphasis>
|
||
, <emphasis>
|
||
preserve</emphasis>
|
||
, and <emphasis>
|
||
level_names</emphasis>
|
||
in <emphasis>
|
||
into</emphasis>
|
||
prior to copying. If any allocation errors occur while copying <emphasis>
|
||
from</emphasis>
|
||
to <emphasis>
|
||
into</emphasis>
|
||
, <emphasis>
|
||
XkbCopyKeyType</emphasis>
|
||
returns <emphasis>
|
||
BadAlloc</emphasis>
|
||
. Otherwise, <emphasis>
|
||
XkbCopyKeyType</emphasis>
|
||
copies <emphasis>
|
||
from</emphasis>
|
||
to <emphasis>
|
||
into</emphasis>
|
||
and returns <emphasis>
|
||
Success</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
Status <emphasis>
|
||
XkbCopyKeyTypes</emphasis>
|
||
(<emphasis>
|
||
from</emphasis>
|
||
,<emphasis>
|
||
into</emphasis>
|
||
, <emphasis>
|
||
num_types</emphasis>
|
||
)
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbKeyTypePtr <emphasis>
|
||
from</emphasis>
|
||
; /* pointer to array of XkbKeyTypeRecs to copy */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbKeyTypePtr <emphasis>
|
||
into</emphasis>
|
||
; /* pointer to array of XkbKeyTypeRecs to change */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int <emphasis>
|
||
num_types</emphasis>
|
||
; /* number of types to copy */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbCopyKeyTypes</emphasis>
|
||
copies <emphasis>
|
||
num_types</emphasis>
|
||
<emphasis>
|
||
XkbKeyTypeRec</emphasis>
|
||
structures from the array specified by <emphasis>
|
||
from</emphasis>
|
||
into the array specified by <emphasis>
|
||
into</emphasis>
|
||
. 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 <emphasis>
|
||
from</emphasis>
|
||
and <emphasis>
|
||
into</emphasis>
|
||
parameters in <emphasis>
|
||
XkbCopyKeyType</emphasis>
|
||
apply to each entry of the <emphasis>
|
||
from</emphasis>
|
||
and <emphasis>
|
||
into</emphasis>
|
||
arrays of <emphasis>
|
||
XkbCopyKeyTypes</emphasis>
|
||
. If any allocation errors occur while copying <emphasis>
|
||
from</emphasis>
|
||
to <emphasis>
|
||
into</emphasis>
|
||
, <emphasis>
|
||
XkbCopyKeyTypes</emphasis>
|
||
returns <emphasis>
|
||
BadAlloc</emphasis>
|
||
. Otherwise, <emphasis>
|
||
XkbCopyKeyTypes</emphasis>
|
||
copies <emphasis>
|
||
from</emphasis>
|
||
to <emphasis>
|
||
into</emphasis>
|
||
and returns <emphasis>
|
||
Success</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
</sect2>
|
||
</sect1>
|
||
<sect1 id='Key_Symbol_Map'>
|
||
<title>Key Symbol Map</title>
|
||
|
||
<para>
|
||
The entire list of key symbols for the keyboard mapping is held in the
|
||
<emphasis>
|
||
syms</emphasis>
|
||
field of the client map. Whereas the core keyboard mapping is a
|
||
two-dimensional array of <emphasis>
|
||
KeySyms</emphasis>
|
||
whose rows are indexed by keycode, the <emphasis>
|
||
syms</emphasis>
|
||
field of Xkb is a linear list of <emphasis>
|
||
KeySyms</emphasis>
|
||
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.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The reason the <emphasis>
|
||
syms</emphasis>
|
||
field is a linear list of <emphasis>
|
||
KeySyms</emphasis>
|
||
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 <emphasis>
|
||
KeySyms</emphasis>
|
||
would potentially be very large and sparse. Instead, Xkb provides a small
|
||
two-dimensional array of <emphasis>
|
||
KeySyms</emphasis>
|
||
for each key. To store all of these individual arrays, Xkb concatenates each
|
||
array together in the <emphasis>
|
||
syms</emphasis>
|
||
field of the client map.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
In order to determine which <emphasis>
|
||
KeySyms</emphasis>
|
||
in the <emphasis>
|
||
syms</emphasis>
|
||
field are associated with each keycode, the client map contains an array of
|
||
key symbol mappings, held in the <emphasis>
|
||
key_sym_map</emphasis>
|
||
field. The <emphasis>
|
||
key_sym_map</emphasis>
|
||
field is an array of <emphasis>
|
||
XkbSymMapRec</emphasis>
|
||
structures indexed by keycode. The <emphasis>
|
||
key_sym_map</emphasis>
|
||
array has <emphasis>
|
||
min_key_code</emphasis>
|
||
unused entries at the start to allow direct indexing using a keycode. All
|
||
keycodes falling between the minimum and maximum legal keycodes, inclusive,
|
||
have <emphasis>
|
||
key_sym_map</emphasis>
|
||
arrays, whether or not any key actually yields that code. The <emphasis>
|
||
KeySymMapRec</emphasis>
|
||
structure is defined as follows:
|
||
</para>
|
||
|
||
<para><programlisting>
|
||
#define XkbNumKbdGroups 4
|
||
#define XkbMaxKbdGroup (XkbNumKbdGroups-1)
|
||
</programlisting></para>
|
||
|
||
<para><programlisting>
|
||
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 <emphasis> syms</emphasis> array */
|
||
} <emphasis>XkbSymMapRec</emphasis>, *XkbSymMapPtr;
|
||
</programlisting></para>
|
||
|
||
<para>
|
||
These fields are described in detail in the following sections.
|
||
</para>
|
||
|
||
|
||
<sect2 id='Per_Key_Key_Type_Indices'>
|
||
<title>Per-Key Key Type Indices</title>
|
||
|
||
<para>
|
||
The <emphasis>
|
||
kt_index</emphasis>
|
||
array of the <emphasis>
|
||
XkbSymMapRec</emphasis>
|
||
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:
|
||
</para>
|
||
|
||
<note><para>The array of key types is of fixed width and is large enough to
|
||
hold key types for the maximum legal number of groups (<emphasis>
|
||
XkbNumKbdGroups</emphasis>
|
||
, currently four); if a key has fewer than <emphasis>
|
||
XkbNumKbdGroups</emphasis>
|
||
groups, the extra key types are reported but ignored.</para></note>
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
int <emphasis>
|
||
XkbKeyTypeIndex</emphasis>
|
||
(<emphasis>
|
||
xkb, keycode, group</emphasis>
|
||
) /* macro*/
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* Xkb description of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
KeyCode <emphasis>
|
||
keycode</emphasis>
|
||
; /* keycode of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int <emphasis>
|
||
group</emphasis>
|
||
; /* group index */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbKeyTypeIndex</emphasis>
|
||
computes an index into the <emphasis>
|
||
types</emphasis>
|
||
vector of the client map in <emphasis>
|
||
xkb</emphasis>
|
||
from the given <emphasis>
|
||
keycode</emphasis>
|
||
and <emphasis>
|
||
group</emphasis>
|
||
index.
|
||
</para>
|
||
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
XkbKeyTypePtr <emphasis>
|
||
XkbKeyType</emphasis>
|
||
(<emphasis>
|
||
xkb, keycode, group</emphasis>
|
||
) /* macro */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* Xkb description of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
KeyCode <emphasis>
|
||
keycode</emphasis>
|
||
; /* keycode of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int <emphasis>
|
||
group</emphasis>
|
||
; /* group index */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbKeyType</emphasis>
|
||
returns a pointer to the key type in the <emphasis>
|
||
types</emphasis>
|
||
vector of the client map in <emphasis>
|
||
xkb</emphasis>
|
||
corresponding to the given <emphasis>
|
||
keycode</emphasis>
|
||
and <emphasis>
|
||
group</emphasis>
|
||
index.
|
||
</para>
|
||
|
||
|
||
</sect2>
|
||
<sect2 id='Per_Key_Group_Information'>
|
||
<title>Per-Key Group Information</title>
|
||
|
||
<para>
|
||
The <emphasis>
|
||
group_info</emphasis>
|
||
field of an <emphasis>
|
||
XkbSymMapRec</emphasis>
|
||
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 <emphasis>
|
||
NoSymbol</emphasis>
|
||
. To obtain the number of groups of symbols bound to the key, use <emphasis>
|
||
XkbKeyNumGroups</emphasis>
|
||
. To change the number of groups bound to a key, use <emphasis>
|
||
XkbChangeTypesOfKey</emphasis>
|
||
(see section 15.3.6). To obtain a mask that determines the treatment of
|
||
out-of-range groups, use <emphasis>
|
||
XkbKeyGroupInfo</emphasis>
|
||
and <emphasis>
|
||
XkbOutOfRangeGroupInfo</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The keyboard controls (see Chapter 10) contain a <emphasis>
|
||
groups_wrap</emphasis>
|
||
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 <emphasis>
|
||
groups_wrap</emphasis>
|
||
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 <emphasis>
|
||
group_info</emphasis>
|
||
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 <emphasis>
|
||
Enter</emphasis>
|
||
key usually has just one group defined. If the user performs an action causing
|
||
the global keyboard group to change to <emphasis>
|
||
Group2</emphasis>
|
||
, the <emphasis>
|
||
group_info</emphasis>
|
||
field for the <emphasis>
|
||
Enter</emphasis>
|
||
key describes how to handle this situation.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
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 <emphasis>
|
||
group_info</emphasis>
|
||
flag, as shown in Table 15.2. See section 10.7.1 for more details on the
|
||
normalization methods in this table.
|
||
</para>
|
||
|
||
<table frame='topbot'>
|
||
<title>group_info Range Normalization</title>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='2' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<colspec colname='c2' colwidth='1.0*'/>
|
||
<thead>
|
||
<row rowsep='1'>
|
||
<entry>Bits set in group_info</entry>
|
||
<entry>Normalization method</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>XkbRedirectIntoRange</entry>
|
||
<entry>XkbRedirectIntoRange</entry>
|
||
</row>
|
||
<row>
|
||
<entry>XkbClampIntoRange</entry>
|
||
<entry>XkbClampIntoRange</entry>
|
||
</row>
|
||
<row>
|
||
<entry>none of the above</entry>
|
||
<entry>XkbWrapIntoRange</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
|
||
<para>
|
||
Xkb provides the following macros to access group information:
|
||
</para>
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
int <emphasis>
|
||
XkbKeyNumGroups</emphasis>
|
||
(<emphasis>
|
||
xkb, keycode</emphasis>
|
||
) /* macro */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* Xkb description of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
KeyCode <emphasis>
|
||
keycode</emphasis>
|
||
; /* keycode of interest */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbKeyNumGroups</emphasis>
|
||
returns the number of groups of symbols bound to the key corresponding to
|
||
<emphasis>
|
||
keycode</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
unsigned char <emphasis>
|
||
XkbKeyGroupInfo</emphasis>
|
||
(<emphasis>
|
||
xkb, keycode</emphasis>
|
||
) /*macro */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* Xkb description of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
KeyCode <emphasis>
|
||
keycode</emphasis>
|
||
; /* keycode of interest */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbKeyGroupInfo</emphasis>
|
||
returns the <emphasis>
|
||
group_info</emphasis>
|
||
field from the <emphasis>
|
||
XkbSymMapRec</emphasis>
|
||
structure associated with the key corresponding to <emphasis>
|
||
keycode</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
unsigned char <emphasis>
|
||
XkbOutOfRangeGroupInfo</emphasis>
|
||
(<emphasis>
|
||
grp_inf</emphasis>
|
||
) /* macro */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
unsigned char <emphasis>
|
||
grp_inf</emphasis>
|
||
; /* group_info field of <emphasis>
|
||
XkbSymMapRec</emphasis>
|
||
*/
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbOutOfRangeGroupInfo</emphasis>
|
||
returns only the out-of-range processing information from the <emphasis>
|
||
group_info</emphasis>
|
||
field of an <emphasis>
|
||
XkbSymMapRec</emphasis>
|
||
structure.
|
||
</para>
|
||
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
unsigned char <emphasis>
|
||
XkbOutOfRangeGroupNumber</emphasis>
|
||
(<emphasis>
|
||
grp_inf</emphasis>
|
||
) /* macro */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
unsigned char <emphasis>
|
||
grp_inf</emphasis>
|
||
; /* group_info field of <emphasis>
|
||
XkbSymMapRec</emphasis>
|
||
*/
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbOutOfRangeGroupNumber</emphasis>
|
||
returns the out-of-range group number, represented as a group index, from the
|
||
<emphasis>
|
||
group_info</emphasis>
|
||
field of an <emphasis>
|
||
XkbSymMapRec</emphasis>
|
||
structure.
|
||
</para>
|
||
|
||
|
||
</sect2>
|
||
<sect2 id='Key_Width'>
|
||
<title>Key Width</title>
|
||
|
||
<para>
|
||
The maximum number of shift levels for a type is also referred to as the width
|
||
of a key type. The <emphasis>
|
||
width</emphasis>
|
||
field of the <emphasis>
|
||
key_sym_map</emphasis>
|
||
entry for a key contains the width of the widest type associated with the key.
|
||
The <emphasis>
|
||
width </emphasis>
|
||
field cannot be explicitly changed; it is updated automatically whenever the
|
||
symbols or set of types bound to a key are changed.
|
||
</para>
|
||
|
||
|
||
</sect2>
|
||
<sect2 id='Offset_in_to_the_Symbol_Map'>
|
||
<title>Offset in to the Symbol Map</title>
|
||
|
||
<para>
|
||
The key width and number of groups associated with a key are used to form a
|
||
small two-dimensional array of <emphasis>
|
||
KeySyms</emphasis>
|
||
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 <emphasis>
|
||
syms</emphasis>
|
||
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:
|
||
</para>
|
||
|
||
<literallayout>
|
||
idx = group_index * key_width + shift_level
|
||
</literallayout>
|
||
|
||
<para>
|
||
The <emphasis>
|
||
offset</emphasis>
|
||
field of the <emphasis>
|
||
key_sym_map</emphasis>
|
||
entry for a key is used to access the beginning of the array.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Xkb provides the following macros for accessing the <emphasis>
|
||
width</emphasis>
|
||
and <emphasis>
|
||
offset</emphasis>
|
||
for individual keys, as well as macros for accessing the two-dimensional array
|
||
of symbols bound to the key:
|
||
</para>
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
int <emphasis>
|
||
XkbKeyGroupsWidth</emphasis>
|
||
(<emphasis>
|
||
xkb, keycode</emphasis>
|
||
) /* macro */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* Xkb description of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
KeyCode <emphasis>
|
||
keycode</emphasis>
|
||
; /* keycode of interest */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbKeyGroupsWidth</emphasis>
|
||
computes the maximum width associated with the key corresponding to <emphasis>
|
||
keycode</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
int <emphasis>
|
||
XkbKeyGroupWidth</emphasis>
|
||
(<emphasis>
|
||
xkb, keycode, grp</emphasis>
|
||
) /* macro */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* Xkb description of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
KeyCode <emphasis>
|
||
keycode</emphasis>
|
||
; /* keycode of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int <emphasis>
|
||
grp</emphasis>
|
||
; /* group of interest */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbKeyGroupWidth</emphasis>
|
||
computes the width of the type associated with the group <emphasis>
|
||
grp</emphasis>
|
||
for the key corresponding to <emphasis>
|
||
keycode</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
int <emphasis>
|
||
XkbKeySymsOffset</emphasis>
|
||
(<emphasis>
|
||
xkb, keycode</emphasis>
|
||
) /* macro */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* Xkb description of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
KeyCode <emphasis>
|
||
keycode</emphasis>
|
||
; /* keycode of interest */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbKeySymsOffset</emphasis>
|
||
returns the offset of the two-dimensional array of keysyms for the key
|
||
corresponding to <emphasis>
|
||
keycode</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
int <emphasis>
|
||
XkbKeyNumSyms</emphasis>
|
||
(<emphasis>
|
||
xkb, keycode</emphasis>
|
||
) /* macro */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* Xkb description of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
KeyCode <emphasis>
|
||
keycode</emphasis>
|
||
; /* keycode of interest */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbKeyNumSyms</emphasis>
|
||
returns the total number of keysyms for the key corresponding to <emphasis>
|
||
keycode</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
KeySym * <emphasis>
|
||
XkbKeySymsPtr</emphasis>
|
||
(<emphasis>
|
||
xkb, keycode</emphasis>
|
||
) /* macro */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* Xkb description of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
KeyCode <emphasis>
|
||
keycode</emphasis>
|
||
; /* keycode of interest */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbKeySymsPtr</emphasis>
|
||
returns the pointer to the two-dimensional array of keysyms for the key
|
||
corresponding to <emphasis>
|
||
keycode</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
KeySym <emphasis>
|
||
XkbKeySymEntry</emphasis>
|
||
(<emphasis>
|
||
xkb, keycode, shift, grp</emphasis>
|
||
) /* macro */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* Xkb description of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
KeyCode <emphasis>
|
||
keycode</emphasis>
|
||
; /* keycode of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int <emphasis>
|
||
shift</emphasis>
|
||
; /* shift level of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int <emphasis>
|
||
grp</emphasis>
|
||
; /* group of interest */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbKeySymEntry</emphasis>
|
||
returns the <emphasis>
|
||
keysym</emphasis>
|
||
corresponding to shift level <emphasis>
|
||
shift</emphasis>
|
||
and group <emphasis>
|
||
grp</emphasis>
|
||
from the two-dimensional array of keysyms for the key corresponding to
|
||
<emphasis>
|
||
keycode</emphasis>
|
||
</para>
|
||
|
||
|
||
</sect2>
|
||
<sect2 id='Getting_the_Symbol_Map_for_Keys_from_the_Server'>
|
||
<title>Getting the Symbol Map for Keys from the Server</title>
|
||
|
||
<para>
|
||
To obtain the symbols for a subset of the keys in a keyboard description, use
|
||
<emphasis>
|
||
XkbGetKeySyms</emphasis>
|
||
:
|
||
</para>
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
Status <emphasis>
|
||
XkbGetKeySyms</emphasis>
|
||
(<emphasis>
|
||
dpy</emphasis>
|
||
,<emphasis>
|
||
first</emphasis>
|
||
, <emphasis>
|
||
num</emphasis>
|
||
,<emphasis>
|
||
xkb</emphasis>
|
||
)
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
Display *<emphasis>
|
||
dpy</emphasis>
|
||
; /* connection to X server */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
unsigned int<emphasis>
|
||
first</emphasis>
|
||
; /* keycode of first key to get */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
unsigned int <emphasis>
|
||
num</emphasis>
|
||
; /* number of keycodes for which syms desired */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* Xkb description to be updated */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbGetKeySyms</emphasis>
|
||
sends a request to the server to obtain the set of keysyms bound to <emphasis>
|
||
num</emphasis>
|
||
keys starting with the key whose keycode is <emphasis>
|
||
first</emphasis>
|
||
. It waits for a reply and returns the keysyms in the <emphasis>
|
||
map.syms</emphasis>
|
||
field of <emphasis>
|
||
xkb</emphasis>
|
||
. If successful, <emphasis>
|
||
XkbGetKeySyms</emphasis>
|
||
returns <emphasis>
|
||
Success</emphasis>
|
||
. The <emphasis>
|
||
xkb</emphasis>
|
||
parameter must be a pointer to a valid Xkb keyboard description.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If the client <emphasis>
|
||
map</emphasis>
|
||
in the <emphasis>
|
||
xkb</emphasis>
|
||
parameter has not been allocated, <emphasis>
|
||
XkbGetKeySyms</emphasis>
|
||
allocates and initializes it before obtaining the symbols.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If a compatible version of Xkb is not available in the server or the Xkb
|
||
extension has not been properly initialized, <emphasis>
|
||
XkbGetKeySyms</emphasis>
|
||
returns <emphasis>
|
||
BadAccess</emphasis>
|
||
. If <emphasis>
|
||
num</emphasis>
|
||
is less than 1 or greater than <emphasis>
|
||
XkbMaxKeyCount</emphasis>
|
||
, <emphasis>
|
||
XkbGetKeySyms</emphasis>
|
||
returns <emphasis>
|
||
BadValue</emphasis>
|
||
. If any allocation errors occur, <emphasis>
|
||
XkbGetKeySyms</emphasis>
|
||
returns <emphasis>
|
||
BadAlloc</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
</sect2>
|
||
<sect2 id='Changing_the_Number_of_Groups_and_Types_Bound_to_a_Key'>
|
||
<title>Changing the Number of Groups and Types Bound to a Key</title>
|
||
|
||
<para>
|
||
To change the number of groups and the types bound to a key, use <emphasis>
|
||
XkbChangeTypesOfKey</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Status <emphasis>
|
||
XkbChangeTypesOfKey</emphasis>
|
||
(<emphasis>
|
||
xkb</emphasis>
|
||
,<emphasis>
|
||
key</emphasis>
|
||
,<emphasis>
|
||
n_groups</emphasis>
|
||
,<emphasis>
|
||
groups</emphasis>
|
||
,<emphasis>
|
||
new_types_in</emphasis>
|
||
,<emphasis>
|
||
p_changes</emphasis>
|
||
)
|
||
</para>
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* keyboard description to be changed */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int <emphasis>
|
||
key</emphasis>
|
||
; /* keycode for key of interest */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int <emphasis>
|
||
n_groups</emphasis>
|
||
; /* new number of groups for key */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
unsigned int <emphasis>
|
||
groups</emphasis>
|
||
; /* mask indicating groups to change */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int * <emphasis>
|
||
new_types_in</emphasis>
|
||
; /* indices for new groups specified in <emphasis>
|
||
groups</emphasis>
|
||
*/
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbMapChangesPtr <emphasis>
|
||
p_changes</emphasis>
|
||
; /* notes changes made to <emphasis>
|
||
xkb</emphasis>
|
||
*/
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbChangeTypesOfKey</emphasis>
|
||
reallocates the symbols and actions bound to the key, if necessary, and
|
||
initializes any new symbols or actions to <emphasis>
|
||
NoSymbol</emphasis>
|
||
or <emphasis>
|
||
NoAction</emphasis>
|
||
, as appropriate. If the <emphasis>
|
||
p_changes</emphasis>
|
||
parameter is not <emphasis>
|
||
NULL</emphasis>
|
||
, <emphasis>
|
||
XkbChangeTypesOfKey</emphasis>
|
||
adds the <emphasis>
|
||
XkbKeySymsMask</emphasis>
|
||
to the <emphasis>
|
||
changes</emphasis>
|
||
field of <emphasis>
|
||
p_changes</emphasis>
|
||
and modifies the <emphasis>
|
||
first_key_sym</emphasis>
|
||
and <emphasis>
|
||
num_key_syms</emphasis>
|
||
fields of <emphasis>
|
||
p_changes</emphasis>
|
||
to include the <emphasis>
|
||
key</emphasis>
|
||
that was changed. See section 14.3.1 for more information on the <emphasis>
|
||
XkbMapChangesPtr</emphasis>
|
||
structure. If successful, <emphasis>
|
||
XkbChangeTypesOfKey</emphasis>
|
||
returns <emphasis>
|
||
Success</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The <emphasis>
|
||
n_groups</emphasis>
|
||
parameter specifies the new number of groups for the key. The <emphasis>
|
||
groups</emphasis>
|
||
parameter is a mask specifying the groups for which new types are supplied and
|
||
is a bitwise inclusive OR of the following masks: <emphasis>
|
||
XkbGroup1Mask</emphasis>
|
||
, <emphasis>
|
||
XkbGroup2Mask</emphasis>
|
||
, <emphasis>
|
||
XkbGroup3Mask</emphasis>
|
||
, and <emphasis>
|
||
XkbGroup4Mask</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The <emphasis>
|
||
new_types_in</emphasis>
|
||
parameter is an integer array of length <emphasis>
|
||
n_groups</emphasis>
|
||
. Each entry represents the type to use for the associated group and is an
|
||
index into <emphasis>
|
||
xkb</emphasis>
|
||
-><emphasis>
|
||
map->types</emphasis>
|
||
. The <emphasis>
|
||
new_types_in</emphasis>
|
||
array is indexed by group index; if <emphasis>
|
||
n_groups</emphasis>
|
||
is four and <emphasis>
|
||
groups</emphasis>
|
||
only has <emphasis>
|
||
Group1Mask</emphasis>
|
||
and <emphasis>
|
||
Group3Mask</emphasis>
|
||
set, <emphasis>
|
||
new_types_in</emphasis>
|
||
looks like this:
|
||
</para>
|
||
|
||
<literallayout>
|
||
new_types_in[0] = type for Group1
|
||
new_types_in[1] = ignored
|
||
new_types_in[2] = type for Group3
|
||
new_types_in[3] = ignored
|
||
</literallayout>
|
||
|
||
<para>
|
||
For convenience, Xkb provides the following constants to use as indices to the
|
||
groups:
|
||
</para>
|
||
|
||
<table frame='topbot'>
|
||
<title>Group Index Constants</title>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='2' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<colspec colname='c2' colwidth='1.0*'/>
|
||
<thead>
|
||
<row rowsep='1'>
|
||
<entry>Constant Name</entry>
|
||
<entry>Value</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>XkbGroup1Index</entry>
|
||
<entry>0</entry>
|
||
</row>
|
||
<row>
|
||
<entry>XkbGroup2Index</entry>
|
||
<entry>1</entry>
|
||
</row>
|
||
<row>
|
||
<entry>XkbGroup3Index</entry>
|
||
<entry>2</entry>
|
||
</row>
|
||
<row>
|
||
<entry>XkbGroup4Index</entry>
|
||
<entry>3</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
|
||
<para>
|
||
If the Xkb extension has not been properly initialized, <emphasis>
|
||
XkbChangeTypesOfKey</emphasis>
|
||
returns <emphasis>
|
||
BadAccess</emphasis>
|
||
. If the <emphasis>
|
||
xkb</emphasis>
|
||
parameter it not valid (that is, it is <emphasis>
|
||
NULL</emphasis>
|
||
or it does not contain a valid client map), <emphasis>
|
||
XkbChangeTypesOfKey</emphasis>
|
||
returns <emphasis>
|
||
Bad</emphasis>
|
||
Match. If the <emphasis>
|
||
key</emphasis>
|
||
is not a valid keycode, <emphasis>
|
||
n_groups</emphasis>
|
||
is greater than <emphasis>
|
||
XkbNumKbdGroups</emphasis>
|
||
, or the <emphasis>
|
||
groups</emphasis>
|
||
mask does not contain any of the valid group mask bits, <emphasis>
|
||
XkbChangeTypesOfKey</emphasis>
|
||
returns <emphasis>
|
||
BadValue</emphasis>
|
||
. If it is necessary to resize the key symbols or key actions arrays and any
|
||
allocation errors occur, <emphasis>
|
||
XkbChangeTypesOfKey</emphasis>
|
||
returns <emphasis>
|
||
BadAlloc</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
</sect2>
|
||
<sect2 id='Changing_the_Number_of_Symbols_Bound_to_a_Key'>
|
||
<title>Changing the Number of Symbols Bound to a Key</title>
|
||
|
||
<para>
|
||
To change the number of symbols bound to a key, use <emphasis>
|
||
XkbResizeKeySyms</emphasis>
|
||
.
|
||
</para>
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
KeySym *<emphasis>
|
||
XkbResizeKeySyms</emphasis>
|
||
(<emphasis>
|
||
xkb</emphasis>
|
||
,<emphasis>
|
||
key</emphasis>
|
||
,<emphasis>
|
||
needed</emphasis>
|
||
)
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescRec *<emphasis>
|
||
xkb</emphasis>
|
||
; /* keyboard description to be changed */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int <emphasis>
|
||
key</emphasis>
|
||
; /* keycode for key to modify */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
int <emphasis>
|
||
needed</emphasis>
|
||
; /* new number of keysyms required for key */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbResizeKeySyms</emphasis>
|
||
reserves the space needed for <emphasis>
|
||
needed</emphasis>
|
||
keysyms and returns a pointer to the beginning of the new array that holds the
|
||
keysyms. It adjusts the <emphasis>
|
||
offset</emphasis>
|
||
field of the <emphasis>
|
||
key_sym_map</emphasis>
|
||
entry for the key if necessary and can also change the <emphasis>
|
||
syms</emphasis>
|
||
, <emphasis>
|
||
num_syms</emphasis>
|
||
, and <emphasis>
|
||
size_syms</emphasis>
|
||
fields of <emphasis>
|
||
xkb</emphasis>
|
||
-<emphasis>
|
||
>map</emphasis>
|
||
if it is necessary to reallocate the <emphasis>
|
||
syms</emphasis>
|
||
array. <emphasis>
|
||
XkbResizeKeySyms</emphasis>
|
||
does not modify either the width or number of groups associated with the key.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If <emphasis>
|
||
needed</emphasis>
|
||
is greater than the current number of keysyms for the key, <emphasis>
|
||
XkbResizeKeySyms</emphasis>
|
||
initializes all new keysyms in the array to <emphasis>
|
||
NoSymbol</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Because the number of symbols needed by a key is normally computed as width *
|
||
number of groups, and <emphasis>
|
||
XkbResizeKeySyms</emphasis>
|
||
does not modify either the width or number of groups for the key, a
|
||
discrepancy exists upon return from <emphasis>
|
||
XkbResizeKeySyms</emphasis>
|
||
between the space allocated for the keysyms and the number required. The
|
||
unused entries in the list of symbols returned by <emphasis>
|
||
XkbResizeKeySyms</emphasis>
|
||
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
|
||
<emphasis>
|
||
XkbChangeTypesOfKey</emphasis>
|
||
will update the mapping.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If any allocation errors occur while resizing the number of symbols bound to
|
||
the key, <emphasis>
|
||
XkbResizeKeySyms</emphasis>
|
||
returns <emphasis>
|
||
NULL</emphasis>
|
||
.
|
||
</para>
|
||
|
||
<note><para>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.</para></note>
|
||
|
||
|
||
</sect2>
|
||
</sect1>
|
||
<sect1 id='The_Per_Key_Modifier_Map'>
|
||
<title>The Per-Key Modifier Map</title>
|
||
|
||
<para>
|
||
The <emphasis>
|
||
modmap</emphasis>
|
||
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: <emphasis>
|
||
ShiftMask</emphasis>
|
||
, <emphasis>
|
||
LockMask</emphasis>
|
||
, <emphasis>
|
||
ControlMask</emphasis>
|
||
, <emphasis>
|
||
Mod1Mask</emphasis>
|
||
, <emphasis>
|
||
Mod2Mask</emphasis>
|
||
, <emphasis>
|
||
Mod3Mask</emphasis>
|
||
, <emphasis>
|
||
Mod4Mask</emphasis>
|
||
, and <emphasis>
|
||
Mod5Mask</emphasis>
|
||
. If a bit is set in a <emphasis>
|
||
modmap</emphasis>
|
||
entry, the corresponding key is bound to that modifier.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
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).
|
||
</para>
|
||
|
||
|
||
<sect2 id='Getting_the_Per_Key_Modifier_Map_from_the_Server'>
|
||
<title>Getting the Per-Key Modifier Map from the Server</title>
|
||
|
||
<para>
|
||
To update the modifier map for one or more of the keys in a keyboard
|
||
description, use <emphasis>
|
||
XkbGetKeyModifierMap</emphasis>
|
||
.
|
||
</para>
|
||
|
||
<informaltable frame='none'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='1' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<tbody>
|
||
<row>
|
||
<entry role='functiondecl'>
|
||
Status <emphasis>
|
||
XkbGetKeyModifierMap</emphasis>
|
||
(<emphasis>
|
||
dpy</emphasis>
|
||
,<emphasis>
|
||
first</emphasis>
|
||
,<emphasis>
|
||
num</emphasis>
|
||
,<emphasis>
|
||
xkb</emphasis>
|
||
)
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
Display *<emphasis>
|
||
dpy</emphasis>
|
||
; /* connection to X server */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
unsigned int <emphasis>
|
||
first</emphasis>
|
||
; /* keycode of first key to get */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
unsigned int <emphasis>
|
||
num</emphasis>
|
||
; /* number of keys for which information is desired */
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry role='functionargdecl'>
|
||
XkbDescPtr <emphasis>
|
||
xkb</emphasis>
|
||
; /* keyboard description to update */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbGetKeyModifierMap</emphasis>
|
||
sends a request to the server for the modifier mappings for <emphasis>
|
||
num</emphasis>
|
||
keys starting with the key whose keycode is <emphasis>
|
||
first</emphasis>
|
||
. It waits for a reply and places the results in the <emphasis>
|
||
xkb</emphasis>
|
||
->map->modmap array. If successful, <emphasis>
|
||
XkbGetKeyModifier</emphasis>
|
||
returns <emphasis>
|
||
Success</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If the map component of the <emphasis>
|
||
xkb</emphasis>
|
||
parameter has not been allocated, <emphasis>
|
||
XkbGetKeyModifierMap</emphasis>
|
||
allocates and initializes it.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If a compatible version of Xkb is not available in the server or the Xkb
|
||
extension has not been properly initialized, <emphasis>
|
||
XkbGetKeySyms</emphasis>
|
||
returns <emphasis>
|
||
BadAccess</emphasis>
|
||
. If any allocation errors occur while obtaining the modifier map, <emphasis>
|
||
XkbGetKeyModifierMap</emphasis>
|
||
returns <emphasis>
|
||
BadAlloc</emphasis>
|
||
.
|
||
</para>
|
||
</sect2>
|
||
</sect1>
|
||
</chapter>
|