1025 lines
33 KiB
XML
1025 lines
33 KiB
XML
|
||
<chapter id='Interactions_Between_XKB_and_the_Core_Protocol'>
|
||
<title>Interactions Between XKB and the Core Protocol</title>
|
||
|
||
<para>
|
||
In addition to providing a number of new requests, XKB replaces or extends
|
||
existing core protocol requests and events. Some aspects of the this extension,
|
||
such as the ability to lock any key or modifier, are visible even to clients
|
||
that are unaware of the XKB extension. Other capabilities, such as control of
|
||
keysym selection on a per-key basis, are available only to XKB-aware clients.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Though they do not have access to some advanced extension capabilities, the XKB
|
||
extension includes compatibility mechanisms to ensure that non-XKB clients
|
||
behave as expected and operate at least as well with an XKB-capable server as
|
||
they do today.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
There are a few significant areas in which XKB state and mapping differences
|
||
might be visible to XKB-unaware clients:
|
||
</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>The core protocol uses a modifier to choose between two keyboard
|
||
groups, while this extension provides explicit support for multiple groups.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>The order of the symbols associated with any given key by XKB might not
|
||
match the ordering demanded by the core protocol.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>
|
||
To minimize problems that might result from these differences, XKB includes
|
||
ways to specify the correspondence between core protocol and XKB modifiers and
|
||
symbols.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
This section describes the differences between the core X protocol’s notion
|
||
of a keyboard mapping and XKB and explains the ways they can interact.
|
||
</para>
|
||
|
||
<sect1 id='Group_Compatibility_Map'>
|
||
<title>Group Compatibility Map</title>
|
||
|
||
<para>
|
||
As described in <link linkend='Keyboard_State'>Keyboard
|
||
State</link>, the current keyboard group is reported to XKB-aware clients in
|
||
bits 13-14 of the state field of many core protocol events. XKB-unaware clients
|
||
cannot interpret those bits, but they might use a keyboard modifier to
|
||
implement support for a single keyboard group. To ensure that pre-XKB clients
|
||
continue to work when XKB is present, XKB makes it possible to map an XKB state
|
||
field, which includes both keyboard group and modifier state into a pre-XKB
|
||
state field which contains only modifiers.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
A keyboard description includes one <emphasis>
|
||
group compatibility map</emphasis>
|
||
per keyboard group (four in all). Each such map is a modifier definition (i.e.
|
||
specifies both real and virtual modifiers) which specifies the modifiers to be
|
||
set in the compatibility states when the corresponding keyboard group is
|
||
active. Here are a few examples to illustrate the application of the group
|
||
compatibility map:
|
||
</para>
|
||
|
||
<informaltable frame='topbot'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='6' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<colspec colname='c2' colwidth='2.0*'/>
|
||
<colspec colname='c3' colwidth='1.5*'/>
|
||
<colspec colname='c4' colwidth='2.2*'/>
|
||
<colspec colname='c5' colwidth='1.5*'/>
|
||
<colspec colname='c6' colwidth='2.0*'/>
|
||
<thead>
|
||
<row rowsep='1'>
|
||
<entry>Group</entry>
|
||
<entry>GroupCompat Map</entry>
|
||
<entry>Effective Modifiers</entry>
|
||
<entry> State for XKB Clients</entry>
|
||
<entry>Compatibility Modifiers</entry>
|
||
<entry>State for non-XKB Clients</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>1</entry>
|
||
<entry>Group1=None</entry>
|
||
<entry>Shift</entry>
|
||
<entry>x00xxxxx00000001</entry>
|
||
<entry>Shift</entry>
|
||
<entry>xxxxxxxx00000001</entry>
|
||
</row>
|
||
<row>
|
||
<entry>2</entry>
|
||
<entry>Group2=Mod3</entry>
|
||
<entry>None</entry>
|
||
<entry>x01xxxxx00000000</entry>
|
||
<entry>Mod3</entry>
|
||
<entry>xxxxxxxx00100000</entry>
|
||
</row>
|
||
<row>
|
||
<entry>3</entry>
|
||
<entry>Group3=Mod2</entry>
|
||
<entry>Shift</entry>
|
||
<entry>x10xxxxx00000001</entry>
|
||
<entry>Shift+Mod2</entry>
|
||
<entry>xxxxxxxx00010001</entry>
|
||
</row>
|
||
<row>
|
||
<entry>4</entry>
|
||
<entry>Group4=None</entry>
|
||
<entry>Control</entry>
|
||
<entry>x11xxxxx00000100</entry>
|
||
<entry>Control</entry>
|
||
<entry>xxxxxxxx00000100</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
Note that non-XKB clients (i.e. clients that are linked with a version of the X
|
||
library that does not support XKB) cannot detect the fact that <emphasis>
|
||
Group4</emphasis>
|
||
is active in this example because the group compatibility map for <emphasis>
|
||
Group4</emphasis>
|
||
does not specify any modifiers.
|
||
</para>
|
||
|
||
|
||
<sect2 id='Setting_a_Passive_Grab_for_an_XKB_State'>
|
||
<title>Setting a Passive Grab for an XKB State</title>
|
||
|
||
<para>
|
||
The fact that the <emphasis>
|
||
state</emphasis>
|
||
field of an event might look different when XKB is present can cause problems
|
||
with passive grabs. Existing clients specify the modifiers they wish to grab
|
||
using the rules defined by the core protocol, which use a normal modifier to
|
||
indicate keyboard group. If we used an XKB state field, the high bits of the
|
||
state field would be non-zero whenever the keyboard was in any group other than
|
||
<emphasis>
|
||
Group1</emphasis>
|
||
, and none of the passive grabs set by clients could ever be triggered.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
To avoid this behavior, the X server normally uses the compatibility grab state
|
||
to decide whether or not to activate a passive grab, even for XKB-aware
|
||
clients. The group compatibility map attempts to encode the keyboard group in
|
||
one or more modifiers of the compatibility state, so existing clients continue
|
||
to work exactly the way they do today. By default, there is no way to directly
|
||
specify a keyboard group in a <emphasis>
|
||
Grabbed</emphasis>
|
||
or <emphasis>
|
||
GrabButton</emphasis>
|
||
request, but groups can be specified indirectly by correctly adjusting the
|
||
group compatibility map.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Clients that wish to specify an XKB keyboard state, including a separate
|
||
keyboard group, can set the <emphasis>
|
||
GrabsUseXKBState</emphasis>
|
||
per-client flag which indicates that all subsequent key and button grabs from
|
||
the requesting clients are specified using an XKB state.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Whether the XKB or core state should be used to trigger a grab is determined by
|
||
the setting of the <emphasis>
|
||
GrabsUseXKBState</emphasis>
|
||
flag for the requesting client at the time the key or button is grabbed. There
|
||
is no way to change the state to be used for a grab that is already registered
|
||
or for grabs that are set by some other client.
|
||
</para>
|
||
|
||
|
||
</sect2>
|
||
</sect1>
|
||
<sect1 id='Changing_the_Keyboard_Mapping_Using_the_Core_Protocol'>
|
||
<title>Changing the Keyboard Mapping Using the Core Protocol</title>
|
||
|
||
<para>
|
||
An XKB keyboard description includes a lot of information that is not present
|
||
in the core protocol description of a keyboard. Whenever a client remaps the
|
||
keyboard using core protocol requests, XKB examines the map to determine likely
|
||
default values for the components that cannot be specified using the core
|
||
protocol.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Some aspects of this automatic mapping are configurable, and make it fairly
|
||
easy to take advantage of many XKB features using existing tools like <emphasis>
|
||
xmodmap</emphasis>
|
||
, but much of the process of mapping a core keyboard description into an XKB
|
||
description is designed to preserve compatible behavior for pre-XKB clients and
|
||
cannot be redefined by the user. Clients or users that want behavior that
|
||
cannot be described using this mapping should use XKB functions directly.
|
||
</para>
|
||
|
||
|
||
<sect2 id='Explicit_Keyboard_Mapping_Components'>
|
||
<title>Explicit Keyboard Mapping Components</title>
|
||
|
||
<para>
|
||
This automatic remapping might accidentally replace definitions that were
|
||
explicitly requested by an application, so the XKB keyboard description defines
|
||
a set of <emphasis>
|
||
explicit components</emphasis>
|
||
for each key; any components that are listed in the explicit components for a
|
||
key are not changed by the automatic keyboard mapping. The explicit components
|
||
field for a key can contain any combination of the following values:
|
||
</para>
|
||
|
||
<informaltable frame='topbot'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='2' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<colspec colname='c2' colwidth='3.0*'/>
|
||
<thead>
|
||
<row rowsep='1'>
|
||
<entry>Bit in Explicit Mask</entry>
|
||
<entry>Protects Against</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>ExplicitKeyType1</entry>
|
||
<entry>Automatic determination of the key type associated with <emphasis>
|
||
Group1</emphasis>
|
||
(see <link linkend='Assigning_Types_To_Groups_of_Symbols_for_a_Key'>Assigning Types To Groups of
|
||
Symbols for a Key</link>)</entry>
|
||
</row>
|
||
<row>
|
||
<entry>ExplicitKeyType2</entry>
|
||
<entry>Automatic determination of the key type associated with <emphasis>
|
||
Group2 </emphasis>
|
||
(see <link linkend='Assigning_Types_To_Groups_of_Symbols_for_a_Key'>Assigning Types To Groups of
|
||
Symbols for a Key</link>)</entry>
|
||
</row>
|
||
<row>
|
||
<entry>ExplicitKeyType3</entry>
|
||
<entry>Automatic determination of the key type associated with <emphasis>
|
||
Group3 </emphasis>
|
||
(see <link linkend='Assigning_Types_To_Groups_of_Symbols_for_a_Key'>Assigning Types To Groups of
|
||
Symbols for a Key</link>).</entry>
|
||
</row>
|
||
<row>
|
||
<entry>ExplicitKeyType4</entry>
|
||
<entry>Automatic determination of the key type associated with <emphasis>
|
||
Group4 </emphasis>
|
||
(see <link linkend='Assigning_Types_To_Groups_of_Symbols_for_a_Key'>Assigning Types To Groups of
|
||
Symbols for a Key</link>).</entry>
|
||
</row>
|
||
<row>
|
||
<entry>ExplicitInterpret</entry>
|
||
<entry>Application of any of the fields of a symbol interpretation to the
|
||
key in question (see <link linkend='Assigning_Actions_To_Keys'>Assigning
|
||
Actions To Keys</link>).</entry>
|
||
</row>
|
||
<row>
|
||
<entry>ExplicitAutoRepeat</entry>
|
||
<entry>Automatic determination of autorepeat status for the key, as
|
||
specified in a symbol interpretation (see <link linkend='Assigning_Actions_To_Keys'>Assigning Actions To
|
||
Keys</link>).</entry>
|
||
</row>
|
||
<row>
|
||
<entry>ExplicitBehavior</entry>
|
||
<entry>Automatic assignment of the <emphasis>
|
||
KB_Lock</emphasis>
|
||
behavior to the key, if the <emphasis>
|
||
LockingKey</emphasis>
|
||
flag is set in a symbol interpretation (see <link linkend='Assigning_Actions_To_Keys'>Assigning Actions To
|
||
Keys</link>).</entry>
|
||
</row>
|
||
<row>
|
||
<entry>ExplicitVModMap</entry>
|
||
<entry>Automatic determination of the virtual modifier map for the key
|
||
based on the actions assigned to the key and the symbol interpretations which
|
||
match the key (see <link linkend='Assigning_Actions_To_Keys'>Assigning
|
||
Actions To Keys</link>).</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
</sect2>
|
||
<sect2 id='Assigning_Symbols_To_Groups'>
|
||
<title>Assigning Symbols To Groups</title>
|
||
|
||
<para>
|
||
The first step in applying the changes specified by a core protocol <emphasis>
|
||
ChangeKeyboardMapping</emphasis>
|
||
request to the XKB description of a keyboard is to determine the number of
|
||
groups that are defined for the key and the width of each group. The XKB
|
||
extension does not change key types in response to core protocol <emphasis>
|
||
SetModifierMapping</emphasis>
|
||
requests, but it does choose key actions as described in <link linkend='Assigning_Actions_To_Keys'>Assigning Actions To Keys</link>.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Determining the number of symbols required for each group is straightforward.
|
||
If the key type for some group is not protected by the corresponding <emphasis>
|
||
ExplicitKeyType</emphasis>
|
||
component, that group has two symbols. If any of the explicit components for
|
||
the key include <emphasis>
|
||
ExplicitKeyType3</emphasis>
|
||
or <emphasis>
|
||
ExplicitKeyType4</emphasis>
|
||
, the width of the key type currently assigned to that group determines the
|
||
number of symbols required for the group in the core protocol keyboard
|
||
description. The explicit type components for <emphasis>
|
||
Group1</emphasis>
|
||
and <emphasis>
|
||
Group2</emphasis>
|
||
behave similarly, but for compatibility reasons the first two groups must have
|
||
at least two symbols in the core protocol symbol mapping. Even if an explicit
|
||
type assigned to either of the first two keyboard groups has fewer than two
|
||
symbols, XKB requires two symbols for it in the core keyboard description.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If the core protocol request contains fewer symbols than XKB needs, XKB adds
|
||
trailing <emphasis>
|
||
NoSymbol</emphasis>
|
||
keysyms to the request to pad it to the required length. If the core protocol
|
||
request includes more symbols than it needs, XKB truncates the list of keysyms
|
||
to the appropriate length.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Finally, XKB divides the symbols from the (possibly padded or truncated) list
|
||
of symbols specified by the core protocol request among the four keyboard
|
||
groups. In most cases, the symbols for each group are taken from the core
|
||
protocol definition in sequence (i.e. the first pair of symbols is assigned to
|
||
<emphasis>
|
||
Group1</emphasis>
|
||
, the second pair of symbols is assigned to <emphasis>
|
||
Group2</emphasis>
|
||
, and so forth). If either <emphasis>
|
||
Group1</emphasis>
|
||
or <emphasis>
|
||
Group2</emphasis>
|
||
has an explicitly defined key type with a width other than two, it gets a
|
||
little more complicated.
|
||
</para>
|
||
|
||
|
||
<sect3 id='Assigning_Symbols_to_Groups_One_and_Two_with_Explicitly_Defined_Key_Types'>
|
||
<title>Assigning Symbols to Groups One and Two with Explicitly Defined Key Types</title>
|
||
|
||
<para>
|
||
The server assigns the first four symbols from the expanded or truncated map to
|
||
the symbol positions <emphasis>G1L1</emphasis> , <emphasis>G1L2</emphasis>,
|
||
<emphasis>G2L1</emphasis> and <emphasis>G2L2</emphasis>, respectively. If the key
|
||
type assigned to <emphasis>Group1</emphasis> reports more than two shift levels,
|
||
the fifth and following symbols contain
|
||
the extra keysyms for <emphasis>
|
||
Group2</emphasis>
|
||
. If the key type assigned to <emphasis>
|
||
Group2</emphasis>
|
||
reports more than two shift levels, the extra symbols follow the symbols (if
|
||
any) for <emphasis>
|
||
Group1</emphasis>
|
||
in the core protocol list of symbols. Symbols for <emphasis>
|
||
Group3</emphasis>
|
||
and <emphasis>
|
||
Group4</emphasis>
|
||
are contiguous and follow the extra symbols, if any, for <emphasis>
|
||
Group1</emphasis>
|
||
and <emphasis>
|
||
Group2</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
For example, consider a key with a key type that returns three shift levels
|
||
bound to each group. The symbols bound to the core protocol are assigned in
|
||
sequence to the symbol positions:
|
||
</para>
|
||
|
||
<literallayout class='monospaced'>
|
||
<emphasis>G1L1</emphasis>, <emphasis>G1L2</emphasis>, <emphasis>G2L1</emphasis>, <emphasis>G2L2</emphasis>, <emphasis>G1L3</emphasis>, <emphasis>G2L3</emphasis>, <emphasis>G3L1</emphasis>, <emphasis>G3L2</emphasis>, <emphasis>G3L3</emphasis>, <emphasis>G4L1</emphasis>, <emphasis>G4L2</emphasis>, and <emphasis>G4L3</emphasis>
|
||
</literallayout>
|
||
|
||
<para>
|
||
For a key with a width one key type on group one, a width two key type on group
|
||
two and a width three key type on group three, the symbols bound to the key by
|
||
the core protocol are assigned to the following key positions:
|
||
</para>
|
||
|
||
<literallayout class='monospaced'>
|
||
<emphasis>G1L1</emphasis>, (<emphasis>G1L2</emphasis>), <emphasis>G2L1</emphasis>, <emphasis>G2L2</emphasis>, <emphasis>G3L1</emphasis>, <emphasis>G3L2</emphasis>, <emphasis>G3L3</emphasis>
|
||
</literallayout>
|
||
|
||
<para>
|
||
Note that the second and fourth symbols (positions <emphasis>
|
||
G1L2 and G2L2</emphasis>
|
||
) can never be generated if the key type associated with the group yields only
|
||
one symbol. XKB accepts and ignores them in order to maintain compatibility
|
||
with the core protocol.
|
||
</para>
|
||
|
||
|
||
</sect3>
|
||
</sect2>
|
||
<sect2 id='Assigning_Types_To_Groups_of_Symbols_for_a_Key'>
|
||
<title>Assigning Types To Groups of Symbols for a Key</title>
|
||
|
||
<para>
|
||
Once the symbols specified by <emphasis>
|
||
ChangeKeyboardMapping</emphasis>
|
||
have been assigned to the four keyboard groups for a key, the X server assigns
|
||
a key type to each group on the key from a canonical list of key types. The
|
||
first four key types in any keyboard map are reserved for these standard key
|
||
types:
|
||
</para>
|
||
|
||
<informaltable frame='topbot'>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='2' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='1.0*'/>
|
||
<colspec colname='c2' colwidth='3.0*'/>
|
||
<thead>
|
||
<row rowsep='1'>
|
||
<entry>Key Type Name</entry>
|
||
<entry>Standard Definition</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry><emphasis>
|
||
ONE_LEVEL</emphasis>
|
||
</entry>
|
||
<entry>Describes keys that have exactly one symbol per group. Most special
|
||
or function keys (such as <emphasis>
|
||
Return</emphasis>
|
||
) are <emphasis>
|
||
ONE_LEVEL</emphasis>
|
||
keys. Any combination of modifiers yields level <emphasis>
|
||
0</emphasis>
|
||
. Index <emphasis>
|
||
0</emphasis>
|
||
in any key symbol map specifies key type <emphasis>
|
||
ONE_LEVEL</emphasis>
|
||
.</entry>
|
||
</row>
|
||
<row>
|
||
<entry><emphasis>
|
||
TWO_LEVEL</emphasis>
|
||
</entry>
|
||
<entry>Describes non-keypad and non-alphabetic keys that have exactly two
|
||
symbols per group. By default, the <emphasis>
|
||
TWO_LEVEL</emphasis>
|
||
type yields column <emphasis>
|
||
1</emphasis>
|
||
if the Shift modifier is set, column <emphasis>
|
||
0</emphasis>
|
||
otherwise. Index <emphasis>
|
||
1</emphasis>
|
||
in any key symbol map specifies key type <emphasis>
|
||
TWO_LEVEL</emphasis>
|
||
.</entry>
|
||
</row>
|
||
<row>
|
||
<entry><emphasis>
|
||
ALPHABETIC</emphasis>
|
||
</entry>
|
||
<entry>Describes alphabetic keys that have exactly two symbols per group.
|
||
The default definition of the <emphasis>
|
||
ALPHABETIC</emphasis>
|
||
type provides shift-cancels-caps behavior as described in <link linkend='Key_Types'>Key Types</link>. Index <emphasis>
|
||
2</emphasis>
|
||
in any key symbol map specifies key type <emphasis>
|
||
ALPHABETIC</emphasis>
|
||
.</entry>
|
||
</row>
|
||
<row>
|
||
<entry><emphasis>
|
||
KEYPAD</emphasis>
|
||
</entry>
|
||
<entry>Describes numeric keypad keys with two symbols per group. Yields
|
||
column <emphasis>
|
||
1</emphasis>
|
||
if either of the <emphasis>
|
||
Shift</emphasis>
|
||
modifier or the real modifier bound to the virtual modifier named <emphasis>
|
||
NumLock</emphasis>
|
||
are set. Yields column <emphasis>
|
||
0</emphasis>
|
||
if neither or both modifiers are set. Index <emphasis>
|
||
3</emphasis>
|
||
in any key symbol map specifies key type <emphasis>
|
||
KEYPAD</emphasis>
|
||
.</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
Users or applications may change these key types to get different default
|
||
behavior (to make shift cancel caps lock, for example) but they must always
|
||
have the specified number of symbols per group.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Before assigning key types to groups, the X server expands any alphanumeric
|
||
symbol definitions as follows:
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If the second symbol of either group is <emphasis>
|
||
NoSymbol</emphasis>
|
||
and the first symbol of that group is an alphabetic keysym for which both
|
||
lowercase and uppercase forms are defined, the X server treats the key as if
|
||
the first element of the group were the lowercase form of the symbol and the
|
||
second element were the uppercase form of the symbol. For the purposes of this
|
||
expansion, XKB ignores the locale and uses the capitalization rules defined in
|
||
<link linkend="default_symbol_transformations">Default Symbol Transformations</link>.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
For each keyboard group that does not have an explicit type definition, XKB
|
||
chooses a key type from the canonical key types. If the second symbol assigned
|
||
to a group is <emphasis>
|
||
NoSymbol</emphasis>
|
||
(after alphabetic expansion), the server assigns key type <emphasis>
|
||
ONE_LEVEL</emphasis>
|
||
. If the group contains the lowercase and uppercase forms of a single glyph
|
||
(after alphanumeric expansion), the server assigns key type <emphasis>
|
||
ALPHABETIC</emphasis>
|
||
. If either of the symbols in a group is a numeric keypad keysym (<emphasis>
|
||
KP_*</emphasis>
|
||
), the server assigns key type <emphasis>
|
||
KEYPAD</emphasis>
|
||
. Otherwise, it assigns key type <emphasis>
|
||
TWO_LEVEL</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Finally, XKB determines the number of groups of symbols that are actually
|
||
defined for the key. Trailing empty groups (i.e. groups that have <emphasis>
|
||
NoSymbol</emphasis>
|
||
in all symbol positions) are ignored.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
There are two last special cases for compatibility with the core protocol: If,
|
||
after trailing empty groups are excluded, all of the groups of symbols bound to
|
||
the key have identical type and symbol bindings, XKB assigns only one group to
|
||
the key. If <emphasis>
|
||
Group2</emphasis>
|
||
is empty and either of <emphasis>
|
||
Group3</emphasis>
|
||
or <emphasis>
|
||
Group4</emphasis>
|
||
are not, and if neither <emphasis>
|
||
Group1</emphasis>
|
||
nor <emphasis>
|
||
Group2</emphasis>
|
||
have explicit key types, XKB copies the symbols and key type from <emphasis>
|
||
Group1</emphasis>
|
||
into <emphasis>
|
||
Group2</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
</sect2>
|
||
<sect2 id='Assigning_Actions_To_Keys'>
|
||
<title>Assigning Actions To Keys</title>
|
||
|
||
<para>
|
||
Once symbols have been divided into groups and key types chosen for the keys
|
||
affected by a <emphasis>
|
||
ChangeKeyboardMapping</emphasis>
|
||
request, XKB examines the symbols and modifier mapping for each changed key
|
||
and assigns server actions where appropriate. XKB also automatically assigns
|
||
server actions to changed keys if the client issues a core protocol <emphasis>
|
||
SetModifierMapping</emphasis>
|
||
request, and does so optionally in response to <emphasis>
|
||
XkbSetMap</emphasis>
|
||
and <emphasis>
|
||
XkbSetCompatMap</emphasis>
|
||
requests.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The compatibility map includes a list of <emphasis>
|
||
symbol interpretations</emphasis>
|
||
, which XKB compares to each symbol associated with any changed keys in turn,
|
||
unless the <emphasis>
|
||
ExplicitInterp</emphasis>
|
||
component is set for a key. Setting the <emphasis>
|
||
ExplicitInterp</emphasis>
|
||
component prevents the application of symbol interpretations to that key.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If the modifiers and keysym specified in a symbol interpretation match the
|
||
modifier mapping and a symbol bound to a changed key that is not protected by
|
||
<emphasis>
|
||
ExplicitInterp</emphasis>
|
||
, the server applies the symbol interpretation to the symbol position. The
|
||
server considers all symbol interpretations which specify an explicit keysym
|
||
before considering any that do not. The server uses the first interpretation
|
||
which matches the given combination of keysym and modifier mapping; other
|
||
matching interpretations are ignored.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
XKB uses four of the fields of a symbol interpretation to decide if it matches
|
||
one of the symbols bound to some changed key:
|
||
</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>The <emphasis>
|
||
symbol</emphasis>
|
||
field is a keysym which matches if it has the value <emphasis>
|
||
NoSymbol</emphasis>
|
||
or is identical to the symbol in question.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>The modifiers specified in the <emphasis>
|
||
mods</emphasis>
|
||
field are compared to the modifiers affected by the key in question as
|
||
indicated by <emphasis>
|
||
match</emphasis>
|
||
.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>The <emphasis>
|
||
match</emphasis>
|
||
field can specify any of the comparisons: <emphasis>
|
||
NoneOf</emphasis>
|
||
, <emphasis>
|
||
AnyOfOrNone</emphasis>
|
||
, <emphasis>
|
||
AnyOf</emphasis>
|
||
, <emphasis>
|
||
AllOf</emphasis>
|
||
or <emphasis>
|
||
Exactly</emphasis>
|
||
.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>The <emphasis>
|
||
levelOneOnly</emphasis>
|
||
setting, indicates that the interpretation in question should only use the
|
||
modifiers bound to this key by the modifier mapping if the symbol that matches
|
||
in level one of its group. Otherwise, if the symbol being considered is not in
|
||
shift level one of its group, the server behaves as if the modifier map for the
|
||
key were empty. Note that it is still possible for such an interpretation to
|
||
apply to a symbol in a shift level other than one if it matches a key without
|
||
modifiers; the <emphasis>
|
||
levelOneOnly</emphasis>
|
||
flag only controls the way that matches are determined and that the key
|
||
modifiers are applied when an interpretation does match.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>
|
||
Applying a symbol interpretation can affect several aspects of the XKB
|
||
definition of the key symbol mapping to which it is applied:
|
||
</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>The <emphasis>
|
||
action</emphasis>
|
||
specified in the symbol interpretation is bound to the symbol position; any
|
||
key event which yields that symbol will also activate the new action.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>If the matching symbol is in position G1L1, the autorepeat behavior of
|
||
the key is set from the <emphasis>
|
||
autorepeat</emphasis>
|
||
field of the symbol interpretation. The <emphasis>
|
||
ExplicitAutoRepeat</emphasis>
|
||
component protects the autorepeat status of a key from symbol interpretation
|
||
initiated changes.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>If the symbol interpretation specifies an associated virtual modifier,
|
||
that virtual modifier is added to the virtual modifier map for the key. The
|
||
<emphasis>
|
||
ExplicitVModMap</emphasis>
|
||
component guards the virtual modifier map for a key from automatic changes. If
|
||
the <emphasis>
|
||
levelOneOnly</emphasis>
|
||
flag is set for the interpretation, and the symbol in question is not in
|
||
position G1L1, the virtual modifier map is not updated.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>If the matching symbol is in position G1L1, and the <emphasis>
|
||
locking key</emphasis>
|
||
field is set in the symbol interpretation, the behavior of the key is changed
|
||
to <emphasis>
|
||
KB_Lock</emphasis>
|
||
(see <link linkend='Key_Behavior'>Key Behavior</link>). The
|
||
<emphasis>
|
||
ExplicitBehavior</emphasis>
|
||
component prevents this change.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>
|
||
If no interpretations match a given symbol or key, the server uses: <emphasis>
|
||
SA_NoAction</emphasis>
|
||
, autorepeat enabled, non-locking key. with no virtual modifiers.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If all of the actions computed for a key are <emphasis>
|
||
SA_NoAction</emphasis>
|
||
, the server assigns an length zero list of actions to the key.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If the core protocol modifier mapping is changed, the server regenerates
|
||
actions for the affected keys. The <emphasis>
|
||
XkbSetMap</emphasis>
|
||
and <emphasis>
|
||
XkbSetCompatMap</emphasis>
|
||
requests can also cause actions for some or all keyboard keys to be recomputed.
|
||
</para>
|
||
|
||
|
||
</sect2>
|
||
<sect2 id='Updating_Everything_Else'>
|
||
<title>Updating Everything Else</title>
|
||
|
||
<para>
|
||
Changes to the symbols or modifier mapping can affect the bindings of virtual
|
||
modifiers. If any virtual modifiers change, XKB updates all of its data
|
||
structures to reflect the change. Applying virtual modifier changes to the
|
||
keyboard mapping night result in changes to types, the group compatibility map,
|
||
indicator maps, internal modifiers or ignore locks modifiers.
|
||
</para>
|
||
|
||
|
||
</sect2>
|
||
</sect1>
|
||
<sect1 id='Effects_of_XKB_on_Core_Protocol_Events'>
|
||
<title>Effects of XKB on Core Protocol Events</title>
|
||
|
||
<para>
|
||
After applying server actions which modify the base, latched or locked modifier
|
||
or group state of the keyboard, the X server recomputes the effective group and
|
||
state. Several components of the keyboard state are reported to XKB-aware
|
||
clients depending on context (see <link linkend='Keyboard_State'>
|
||
Keyboard State</link> for a detailed description of each of the keyboard state
|
||
components):
|
||
</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>The effective modifier state is reported in <emphasis>
|
||
XkbStateNotify</emphasis>
|
||
events and in response to <emphasis>
|
||
XkbGetState</emphasis>
|
||
requests.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>The symbol lookup state is reported to XKB-aware clients in the state
|
||
field of core protocol and input extension key press and release events that do
|
||
not activate passive grabs. Unless the <emphasis>
|
||
LookupStateWhenGrabbed</emphasis>
|
||
per-client flag is set, the lookup state is only reported in these events when
|
||
no grabs are active.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>The grab state is reported to XKB-aware clients in the state field of
|
||
all core protocol events that report keyboard state, except <emphasis>
|
||
KeyPress</emphasis>
|
||
and <emphasis>
|
||
KeyRelease</emphasis>
|
||
events that do not activate passive grabs.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>The effective group is the sum of the base, latched and locked keyboard
|
||
groups. An out of range effective group is wrapped or truncated into range
|
||
according to the setting of the <emphasis>
|
||
groupsWrap</emphasis>
|
||
flag for the keyboard.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>
|
||
The server reports compatibility states to any clients that have not issued a
|
||
successful <emphasis>
|
||
XkbUseExtension</emphasis>
|
||
request. The server computes the compatibility symbol lookup state and the
|
||
compatibility effective grab state by applying the compatibility modifier map
|
||
to the corresponding computed XKB states.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The compatibility symbol lookup state is reported to non-XKB clients whenever
|
||
an XKB-aware client would receive the XKB lookup state. The compatibility grab
|
||
state is reported to XKB-unaware clients whenever an XKB client would receive
|
||
the XKB grab state.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If the <emphasis>
|
||
GrabsUseXKBState</emphasis>
|
||
per-client option is not set, even XKB-aware clients receive the compatibility
|
||
grab state in events that trigger or terminate passive grabs. If this flag is
|
||
not set, XKB clients also receive the compatibility grab or lookup state
|
||
whenever any keyboard grab is active.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If the <emphasis>
|
||
LookupStateWhenGrabbed</emphasis>
|
||
per-client option is set, clients receive either the XKB or compatibility
|
||
lookup state when the keyboard is grabbed, otherwise they receive either the
|
||
XKB or compatibility grab state. All non-XKB clients receive the compatibility
|
||
form of the appropriate state component; the form that is sent to an XKB-aware
|
||
client depends on the setting of the <emphasis>
|
||
GrabsUseXKBState</emphasis>
|
||
option for that client.
|
||
</para>
|
||
|
||
|
||
</sect1>
|
||
<sect1 id='Effect_of_XKB_on_Core_Protocol_Requests'>
|
||
<title>Effect of XKB on Core Protocol Requests</title>
|
||
|
||
<para>
|
||
Whenever a client updates the keyboard mapping using a core protocol request,
|
||
the server saves the requested core protocol keyboard mapping and reports it to
|
||
any clients that issue <emphasis>
|
||
GetKeyboardMapping</emphasis>
|
||
or <emphasis>
|
||
GetModifierMapping</emphasis>
|
||
requests. Whenever a client updates the keyboard mapping using XKB requests,
|
||
the server discards the affected portion of the stored core keyboard
|
||
description and regenerates it based on the XKB description of the keyboard.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The symbols associated with the XKB keyboard description appear in the order:
|
||
</para>
|
||
|
||
<literallayout class='monospaced'>
|
||
G1L1 G1L2 G2L1 G2L2 G1L3-n G2L3-n G3L* G4L*
|
||
</literallayout>
|
||
|
||
<para>
|
||
If the type associated with <emphasis>
|
||
Group1</emphasis>
|
||
is width one, the second symbol is <emphasis>
|
||
NoSymbol</emphasis>
|
||
; if the type associated with <emphasis>
|
||
Group2</emphasis>
|
||
is width one, the fourth symbol is <emphasis>
|
||
NoSymbol</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If a key has only one group but the keyboard has several, the symbols for
|
||
<emphasis>
|
||
Group1</emphasis>
|
||
are repeated for each group. For example, given a keyboard with three groups
|
||
and a key with one group that contains the symbols { <emphasis>
|
||
a A</emphasis>
|
||
}, the core protocol description would contain the six symbols: { <emphasis>
|
||
a</emphasis>
|
||
<emphasis>
|
||
A</emphasis>
|
||
<emphasis>
|
||
a</emphasis>
|
||
<emphasis>
|
||
A</emphasis>
|
||
<emphasis>
|
||
a</emphasis>
|
||
<emphasis>
|
||
A</emphasis>
|
||
}. As a slightly more complicated example, an XKB key which had a single width
|
||
three group with the symbols { <emphasis>
|
||
a</emphasis>
|
||
<emphasis>
|
||
b</emphasis>
|
||
<emphasis>
|
||
c</emphasis>
|
||
} would show up in the generated core protocol keyboard description with the
|
||
symbols { <emphasis>
|
||
a</emphasis>
|
||
<emphasis>
|
||
b</emphasis>
|
||
<emphasis>
|
||
a</emphasis>
|
||
<emphasis>
|
||
b</emphasis>
|
||
<emphasis>
|
||
c</emphasis>
|
||
<emphasis>
|
||
c</emphasis>
|
||
<emphasis>
|
||
a</emphasis>
|
||
<emphasis>
|
||
b</emphasis>
|
||
<emphasis>
|
||
c</emphasis>
|
||
} for a keyboard with three groups.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The generated modifier mapping for a key contains all of the modifiers affected
|
||
by all of the actions associated with the key plus all of the modifiers
|
||
associated with any virtual modifiers bound to the key by the virtual modifier
|
||
mapping. If any of the actions associated with a key affect any component of
|
||
the keyboard group, any modifiers specified in any entry of the group
|
||
compatibility map (see <link linkend='Group_Compatibility_Map'>Group
|
||
Compatibility Map</link>) are reported in the modifier mask. The <emphasis>
|
||
SA_ISOLock</emphasis>
|
||
action can theoretically affect any modifier, but the modifier map of an
|
||
<emphasis>
|
||
SA_ISOLock</emphasis>
|
||
key contains only the modifiers or group state that it sets by default.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The server notifies interested clients of keyboard map changes in one of two
|
||
ways. It sends <emphasis>
|
||
XkbMapNotify</emphasis>
|
||
to clients that have explicitly selected them and core protocol <emphasis>
|
||
MappingNotify</emphasis>
|
||
events to clients that have not. Once a client requests <emphasis>
|
||
XkbMapNotify</emphasis>
|
||
events, the server stops sending it <emphasis>
|
||
MappingNotify</emphasis>
|
||
events to inform it of keyboard changes.
|
||
</para>
|
||
|
||
|
||
</sect1>
|
||
<sect1 id='Sending_Events_to_Clients'>
|
||
<title>Sending Events to Clients</title>
|
||
|
||
<para>
|
||
XKB normally assumes that events sent to clients using the core protocol
|
||
<emphasis>
|
||
SendEvent</emphasis>
|
||
request contain a core protocol state, if applicable. If the client which will
|
||
receive the event is not XKB-capable, XKB attempts to convert the core state to
|
||
an XKB state as follows: if any of the modifiers bound to <emphasis>
|
||
Group2</emphasis>
|
||
in the group compatibility map are set in the event state, XKB clears them in
|
||
the resulting event but sets the effective group in the event state to
|
||
<emphasis>
|
||
Group2</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If the <emphasis>
|
||
PCF_SendEventUsesXKBState</emphasis>
|
||
per-client flag is set at the time of the SendEvent request, XKB instead
|
||
assumes that the event reported in the event is an XKB state. If the receiving
|
||
client is not XKB-aware, the extension converts the XKB state (which contains
|
||
the effective state in bits 13-14) to a core state by applying the group
|
||
compatibility map just as it would for actual key events.
|
||
</para>
|
||
|
||
</sect1>
|
||
</chapter>
|