857c658f08
shadchin@ on various architectures. Bump major.
1189 lines
33 KiB
XML
1189 lines
33 KiB
XML
<chapter id='server_database_of_keyboard_components'>
|
||
<title>Server Database of Keyboard Components</title>
|
||
|
||
<para>
|
||
The X server maintains a database of keyboard components, identified by
|
||
component type. The database contains all the information necessary to build a
|
||
complete keyboard description for a particular device, as well as to assemble
|
||
partial descriptions. Table 20.1 identifies the component types and the type of
|
||
information they contain.
|
||
</para>
|
||
|
||
<table frame='none'>
|
||
<title>Server Database Keyboard Components</title>
|
||
<tgroup cols='3'>
|
||
<colspec colsep='0'/>
|
||
<colspec colsep='0'/>
|
||
<colspec colsep='0'/>
|
||
<thead>
|
||
<row rowsep='0'>
|
||
<entry>Component Type</entry>
|
||
<entry>Component Primary Contents</entry>
|
||
<entry>May also contain</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row rowsep='0'>
|
||
<entry>Keymap</entry>
|
||
<entry>
|
||
<para>Complete keyboard description</para>
|
||
<para>Normally assembled using a complete component from each of the other types</para>
|
||
</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>Keycodes</entry>
|
||
<entry>
|
||
<para>Symbolic name for each key</para>
|
||
<para>Minimum and maximum legal keycodes</para>
|
||
</entry>
|
||
<entry>
|
||
<para>Aliases for some keys</para>
|
||
<para>Symbolic names for indicators</para>
|
||
<para>Description of indicators physically present</para>
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>Types</entry>
|
||
<entry>Key types</entry>
|
||
<entry>
|
||
Real modifier bindings and symbolic names for some virtual modifiers
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>Compatibility</entry>
|
||
<entry>Rules used to assign actions to keysyms</entry>
|
||
<entry>
|
||
<para>Maps for some indicators</para>
|
||
<para>Real modifier bindings and symbolic names for some virtual modifiers</para>
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>Symbols</entry>
|
||
<entry>
|
||
<para>Symbol mapping for keyboard keys</para>
|
||
<para>Modifier mapping</para>
|
||
<para>Symbolic names for groups</para>
|
||
</entry>
|
||
<entry>
|
||
<para>Explicit actions and behaviors for some keys</para>
|
||
<para>Real modifier bindings and symbolic names for some virtual modifiers</para>
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>Geometry</entry>
|
||
<entry>Layout of the keyboard</entry>
|
||
<entry>
|
||
<para>Aliases for some keys; overrides keycodes component aliases</para>
|
||
<para>Symbolic names for some indicators</para>
|
||
<para>Description of indicators physically present</para>
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
|
||
<para>
|
||
While a keymap is a database entry for a complete keyboard description, and
|
||
therefore logically different from the individual component database entries,
|
||
the rules for processing keymap entries are identical to those for the
|
||
individual components. In the discussion that follows, the term component is
|
||
used to refer to either individual components or a keymap.
|
||
</para>
|
||
|
||
<para>
|
||
There may be multiple entries for each of the component types. An entry may be
|
||
either <emphasis>
|
||
complete</emphasis>
|
||
or <emphasis>
|
||
partial</emphasis>
|
||
. Partial entries describe only a piece of the corresponding keyboard component
|
||
and are designed to be combined with other entries of the same type to form a
|
||
complete entry.
|
||
</para>
|
||
|
||
<para>
|
||
For example, a partial symbols map might describe the differences between a
|
||
common ASCII keyboard and some national layout. Such a partial map is not
|
||
useful on its own because it does not include those symbols that are the same
|
||
on both the ASCII and national layouts (such as function keys). On the other
|
||
hand, this partial map can be used to configure <emphasis>
|
||
any</emphasis>
|
||
ASCII keyboard to use a national layout.
|
||
</para>
|
||
|
||
<para>
|
||
When a keyboard description is built, the components are processed in the order
|
||
in which they appear in Table 20.1; later definitions override earlier ones.
|
||
</para>
|
||
|
||
<sect1 id='component_names'>
|
||
<title>Component Names</title>
|
||
|
||
<para>
|
||
Component names have the form "<emphasis>
|
||
class(member)</emphasis>
|
||
" where <emphasis>
|
||
class</emphasis>
|
||
describes a subset of the available components for a particular type and the
|
||
optional <emphasis>
|
||
member</emphasis>
|
||
identifies a specific component from that subset. For example, the name
|
||
"atlantis(acme)" for a symbols component might specify the symbols used for the
|
||
atlantis national keyboard layout by the vendor "acme." Each class has an
|
||
optional <emphasis>
|
||
default</emphasis>
|
||
member — references that specify a class but not a member refer to the
|
||
default member of the class, if one exists. Xkb places no constraints on the
|
||
interpretation of the class and member names used in component names.
|
||
</para>
|
||
|
||
<para>
|
||
The <emphasis>
|
||
class</emphasis>
|
||
and <emphasis>
|
||
member</emphasis>
|
||
names are both specified using characters from the Latin-1 character set. Xkb
|
||
implementations must accept all alphanumeric characters, minus (‘-’) and
|
||
underscore (‘_’) in class or member names, and must not accept parentheses,
|
||
plus, vertical bar, percent sign, asterisk, question mark, or white space. The
|
||
use of other characters is implementation-dependent.
|
||
</para>
|
||
|
||
</sect1>
|
||
<sect1 id='listing_the_known_keyboard_components'>
|
||
<title>Listing the Known Keyboard Components</title>
|
||
|
||
<para>
|
||
You may ask the server for a list of components for one or more component
|
||
types. The request takes the form of a set of patterns, one pattern for each of
|
||
the component types, including a pattern for the complete keyboard description.
|
||
To obtain this list, use <emphasis>
|
||
XkbListComponents</emphasis>
|
||
.
|
||
</para>
|
||
|
||
<informaltable frame='none'>
|
||
<tgroup cols='1'>
|
||
<colspec colsep='0'/>
|
||
<tbody>
|
||
<row rowsep='0'>
|
||
<entry role='functiondecl'>
|
||
XkbComponentListPtr<emphasis>
|
||
XkbListComponents</emphasis>
|
||
(<emphasis>
|
||
dpy</emphasis>
|
||
, <emphasis>
|
||
device_spec</emphasis>
|
||
, <emphasis>
|
||
ptrns</emphasis>
|
||
, <emphasis>
|
||
max_inout</emphasis>
|
||
)
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry role='functionargdecl'>
|
||
Display * <emphasis>
|
||
dpy</emphasis>
|
||
; /* connection to X server */
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry role='functionargdecl'>
|
||
unsigned int <emphasis>
|
||
device_spec</emphasis>
|
||
; /* device ID, or <emphasis>
|
||
XkbUseCoreKbd</emphasis>
|
||
*/
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry role='functionargdecl'>
|
||
XkbComponentNamesPtr <emphasis>
|
||
ptrns</emphasis>
|
||
; /* namelist for components of interest */
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry role='functionargdecl'>
|
||
int * <emphasis>
|
||
max_inout</emphasis>
|
||
; /* max # returned names, # left over */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbListComponents</emphasis>
|
||
queries the server for a list of component names matching the patterns
|
||
specified in <emphasis>
|
||
ptrns</emphasis>
|
||
. It waits for a reply and returns the matching component names in an <emphasis>
|
||
XkbComponentListRec</emphasis>
|
||
structure. When you are done using the structure, you should free it using
|
||
<emphasis>
|
||
XkbFreeComponentList</emphasis>
|
||
. <emphasis>
|
||
device_spec</emphasis>
|
||
indicates a particular device in which the caller is interested. A server is
|
||
allowed (but not required) to restrict its reply to portions of the database
|
||
that are relevant for that particular device.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
<emphasis>
|
||
ptrns</emphasis>
|
||
is a pointer to an <emphasis>
|
||
XkbComponentNamesRec</emphasis>
|
||
, described below. Each of the fields in <emphasis>
|
||
ptrns</emphasis>
|
||
contains a pattern naming the components of interest. Each of the patterns is
|
||
composed of characters from the ISO <emphasis>
|
||
Latin1</emphasis>
|
||
encoding, but can contain only parentheses, the wildcard characters
|
||
‘<emphasis>
|
||
?</emphasis>
|
||
’ and ‘<emphasis>
|
||
*</emphasis>
|
||
’, and characters permitted in a component class or member name (see section
|
||
20.1). A pattern may be <emphasis>
|
||
NULL</emphasis>
|
||
, in which case no components for that type is returned. Pattern matches with
|
||
component names are case sensitive. The ‘<emphasis>
|
||
?</emphasis>
|
||
’ wildcard matches any single character, except a left or right parenthesis;
|
||
the ‘<emphasis>
|
||
*</emphasis>
|
||
’ wildcard matches any number of characters, except a left or right
|
||
parenthesis. If an implementation allows additional characters in a component
|
||
class or member name other than those required by the Xkb extension (see
|
||
section 20.1), the result of comparing one of the additional characters to
|
||
either of the wildcard characters is implementation-dependent.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If a pattern contains illegal characters, the illegal characters are ignored.
|
||
The matching process is carried out as if the illegal characters were omitted
|
||
from the pattern.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
<emphasis>
|
||
max_inout</emphasis>
|
||
is used to throttle the amount of data passed to and from the server. On
|
||
input, it specifies the maximum number of names to be returned (the total
|
||
number of names in all component categories). Upon return from <emphasis>
|
||
XkbListComponents</emphasis>
|
||
, <emphasis>
|
||
max_inout</emphasis>
|
||
contains the number of names that matched the request but were not returned
|
||
because of the limit.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The component name patterns used to describe the request are passed to
|
||
<emphasis>
|
||
XkbListComponents</emphasis>
|
||
using an <emphasis>
|
||
XkbComponentNamesRec</emphasis>
|
||
structure. This structure has no special allocation constraints or
|
||
interrelationships with other structures; allocate and free this structure
|
||
using standard <emphasis>
|
||
malloc</emphasis>
|
||
and <emphasis>
|
||
free</emphasis>
|
||
calls or their equivalent:
|
||
</para>
|
||
|
||
<para><programlisting>
|
||
typedef struct _XkbComponentNames {
|
||
char * keymap; /* keymap names */
|
||
char * keycodes; /* keycode names */
|
||
char * types; /* type names */
|
||
char * compat; /* compatibility map names */
|
||
char * symbols; /* symbol names */
|
||
char * geometry; /* geometry names */
|
||
} <emphasis>XkbComponentNamesRec</emphasis>, *XkbComponentNamesPtr;
|
||
</programlisting></para>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbListComponents</emphasis>
|
||
returns a pointer to an <emphasis>
|
||
XkbComponentListRec</emphasis>
|
||
:
|
||
</para>
|
||
|
||
<para><programlisting>
|
||
typedef struct _XkbComponentList {
|
||
int num_keymaps; /* number of entries in keymap */
|
||
int num_keycodes; /* number of entries in keycodes */
|
||
int num_types; /* number of entries in types */
|
||
int num_compat; /* number of entries in compat */
|
||
int num_symbols; /* number of entries in symbols */
|
||
int num_geometry; /* number of entries in geometry;
|
||
XkbComponentNamePtr keymap; /* keymap names */
|
||
XkbComponentNamePtr keycodes; /* keycode names */
|
||
XkbComponentNamePtr types; /* type names */
|
||
XkbComponentNamePtr compat; /* compatibility map names */
|
||
XkbComponentNamePtr symbols; /* symbol names */
|
||
XkbComponentNamePtr geometry; /* geometry names */
|
||
} <emphasis>XkbComponentListRec</emphasis>, *XkbComponentListPtr;
|
||
</programlisting></para>
|
||
|
||
<para><programlisting>
|
||
typedef struct _XkbComponentName {
|
||
unsigned short flags; /* hints regarding component name */
|
||
char * name; /* name of component */
|
||
} <emphasis>XkbComponentNameRec</emphasis>, *XkbComponentNamePtr;
|
||
</programlisting></para>
|
||
|
||
<para>
|
||
Note that the structure used to specify patterns on input is an <emphasis>
|
||
XkbComponentNamesRec</emphasis>
|
||
, and that used to hold the individual component names upon return is an
|
||
<emphasis>
|
||
XkbComponentNameRec</emphasis>
|
||
(no trailing ‘s’ in Name).
|
||
</para>
|
||
|
||
|
||
<para>
|
||
When you are done using the structure returned by <emphasis>
|
||
XkbListComponents</emphasis>
|
||
, free it using <emphasis>
|
||
XkbFreeComponentList</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<informaltable frame='none'>
|
||
<tgroup cols='1'>
|
||
<colspec colsep='0'/>
|
||
<tbody>
|
||
<row rowsep='0'>
|
||
<entry role='functiondecl'>
|
||
void <emphasis>
|
||
XkbFreeComponentList</emphasis>
|
||
(list)
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry role='functionargdecl'>
|
||
XkbComponentListPtr list; /* pointer to <emphasis>
|
||
XkbComponentListRec</emphasis>
|
||
to free */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
|
||
</sect1>
|
||
<sect1 id='component_hints'>
|
||
<title>Component Hints</title>
|
||
|
||
<para>
|
||
A set of flags is associated with each component; these flags provide
|
||
additional hints about the component’s use. These hints are designated by bit
|
||
masks in the flags field of the <emphasis>
|
||
XkbComponentNameRec</emphasis>
|
||
structures contained in the <emphasis>
|
||
XkbComponentListRec</emphasis>
|
||
returned from <emphasis>
|
||
XkbListComponents</emphasis>
|
||
. The least significant byte of the flags field has the same meaning for all
|
||
types of keyboard components; the interpretation of the most significant byte
|
||
is dependent on the type of component. The flags bits are defined in Table
|
||
20.2. The symbols hints in Table 20.2 apply only to partial symbols components
|
||
(those with <emphasis>
|
||
XkbLC_Partial</emphasis>
|
||
also set); full symbols components are assumed to specify all of the pieces.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The alphanumeric, modifier, keypad or function keys symbols hints should
|
||
describe the primary intent of the component designer and should not be simply
|
||
an exhaustive list of the kinds of keys that are affected. For example,
|
||
national keyboard layouts affect primarily alphanumeric keys, but many affect a
|
||
few modifier keys as well; such mappings should set only the <emphasis>
|
||
XkbLC_AlphanumericKeys</emphasis>
|
||
hint. In general, symbols components should set only one of the four flags
|
||
(<emphasis>
|
||
XkbLC_AlternateGroup</emphasis>
|
||
may be combined with any of the other flags).
|
||
</para>
|
||
|
||
<table frame='none'>
|
||
<title>XkbComponentNameRec Flags Bits</title>
|
||
<tgroup cols='4'>
|
||
<colspec colsep='0'/>
|
||
<colspec colsep='0'/>
|
||
<colspec colsep='0'/>
|
||
<colspec colsep='0'/>
|
||
<thead>
|
||
<row rowsep='0'>
|
||
<entry>Component Type</entry>
|
||
<entry>Component Hints (flags)</entry>
|
||
<entry>Meaning</entry>
|
||
<entry>Value</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row rowsep='0'>
|
||
<entry>All Components</entry>
|
||
<entry><para><emphasis>XkbLC_Hidden</emphasis></para></entry>
|
||
<entry>Do not present to user</entry>
|
||
<entry>(1L<<0)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry></entry>
|
||
<entry><emphasis>XkbLC_Default</emphasis></entry>
|
||
<entry>Default member of class</entry>
|
||
<entry>(1L<<1)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry></entry>
|
||
<entry><emphasis>XkbLC_Partial</emphasis></entry>
|
||
<entry>Partial component</entry>
|
||
<entry>(1L<<2)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>Keymap</entry>
|
||
<entry>none</entry>
|
||
<entry></entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>Keycodes</entry>
|
||
<entry>none</entry>
|
||
<entry></entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>Types</entry>
|
||
<entry>none</entry>
|
||
<entry></entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>Compatibility</entry>
|
||
<entry>none</entry>
|
||
<entry></entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>Symbols</entry>
|
||
<entry><emphasis>XkbLC_AlphanumericKeys</emphasis></entry>
|
||
<entry>Bindings primarily for alphanumeric keyboard section</entry>
|
||
<entry>(1L<<8)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry></entry>
|
||
<entry><emphasis>XkbLC_ModifierKeys</emphasis></entry>
|
||
<entry>Bindings primarily for modifier keys</entry>
|
||
<entry>(1L<<9)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry></entry>
|
||
<entry><emphasis>XkbLC_KeypadKeys</emphasis></entry>
|
||
<entry>Bindings primarily for numeric keypad keys</entry>
|
||
<entry>(1L<<10)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry></entry>
|
||
<entry><emphasis>XkbLC_FunctionKeys</emphasis></entry>
|
||
<entry>Bindings primarily for function keys</entry>
|
||
<entry>(1L<<11)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry></entry>
|
||
<entry><emphasis>XkbLC_AlternateGroup</emphasis></entry>
|
||
<entry>Bindings for an alternate group</entry>
|
||
<entry>(1L<<12)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>Geometry</entry>
|
||
<entry>none</entry>
|
||
<entry></entry>
|
||
<entry></entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
|
||
</sect1>
|
||
<sect1 id='building_a_keyboard_description_using_the_server_database'>
|
||
<title>Building a Keyboard Description Using the Server Database</title>
|
||
|
||
<para>
|
||
A client may request that the server fetch one or more components from its
|
||
database and use those components to build a new server keyboard description.
|
||
The new keyboard description may be built from scratch, or it may be built
|
||
starting with the current keyboard description for a particular device. Once
|
||
the keyboard description is built, all or part of it may be returned to the
|
||
client. The parts returned to the client need not include all of the parts used
|
||
to build the description. At the time it requests the server to build a new
|
||
keyboard description, a client may also request that the server use the new
|
||
description internally to replace the current keyboard description for a
|
||
specific device, in which case the behavior of the device changes accordingly.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
To build a new keyboard description from a set of named components, and to
|
||
optionally have the server use the resulting description to replace an active
|
||
one, use <emphasis>
|
||
XkbGetKeyboardByName</emphasis>
|
||
.
|
||
</para>
|
||
|
||
<informaltable frame='none'>
|
||
<tgroup cols='1'>
|
||
<colspec colsep='0'/>
|
||
<tbody>
|
||
<row rowsep='0'>
|
||
<entry role='functiondecl'>
|
||
XkbDescPtr <emphasis>
|
||
XkbGetKeyboardByName</emphasis>
|
||
(<emphasis>
|
||
dpy</emphasis>
|
||
, <emphasis>
|
||
device_spec</emphasis>
|
||
, <emphasis>
|
||
names</emphasis>
|
||
, <emphasis>
|
||
want</emphasis>
|
||
, <emphasis>
|
||
need</emphasis>
|
||
, <emphasis>
|
||
load</emphasis>
|
||
)
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry role='functionargdecl'>
|
||
Display * <emphasis>
|
||
dpy</emphasis>
|
||
; /* connection to X server */
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry role='functionargdecl'>
|
||
unsigned int <emphasis>
|
||
device_spec</emphasis>
|
||
; /* device ID, or <emphasis>
|
||
XkbUseCoreKbd</emphasis>
|
||
*/
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry role='functionargdecl'>
|
||
XkbComponentNamesPtr <emphasis>
|
||
names</emphasis>
|
||
; /* names of components to fetch */
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry role='functionargdecl'>
|
||
unsigned int <emphasis>
|
||
want</emphasis>
|
||
; /* desired structures in returned record */
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry role='functionargdecl'>
|
||
unsigned int <emphasis>
|
||
need</emphasis>
|
||
; /* mandatory structures in returned record */
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry role='functionargdecl'>
|
||
Bool <emphasis>
|
||
load</emphasis>
|
||
; /* <emphasis>
|
||
True</emphasis>
|
||
=> load into <emphasis>
|
||
device_spec</emphasis>
|
||
*/
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
names</emphasis>
|
||
contains a set of expressions describing the keyboard components the server
|
||
should use to build the new keyboard description. <emphasis>
|
||
want</emphasis>
|
||
and <emphasis>
|
||
need</emphasis>
|
||
are bit fields describing the parts of the resulting keyboard description that
|
||
should be present in the returned <emphasis>
|
||
XkbDescRec</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The individual fields in <emphasis>
|
||
names</emphasis>
|
||
are <emphasis>
|
||
component expressions</emphasis>
|
||
composed of keyboard component names (no wildcarding as may be used in
|
||
<emphasis>
|
||
XkbListComponents</emphasis>
|
||
), the special component name symbol ‘%’, and the special operator
|
||
characters ‘<emphasis>
|
||
+</emphasis>
|
||
’ and ‘<emphasis>
|
||
|</emphasis>
|
||
’. A component expression is parsed left to right, as follows:
|
||
</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
The special component name "<emphasis>
|
||
computed</emphasis>
|
||
" may be used in <emphasis>
|
||
keycodes</emphasis>
|
||
component expressions and refers to a component consisting of a set of
|
||
keycodes computed automatically by the server as needed.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The special component name "<emphasis>
|
||
canonical</emphasis>
|
||
" may be used in <emphasis>
|
||
types</emphasis>
|
||
component expressions and refers to a partial component defining the four
|
||
standard key types: <emphasis>
|
||
ALPHABETIC</emphasis>
|
||
, <emphasis>
|
||
ONE_LEVEL</emphasis>
|
||
, <emphasis>
|
||
TWO_LEVEL</emphasis>
|
||
, and <emphasis>
|
||
KEYPAD</emphasis>
|
||
.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The special component name ‘<emphasis>
|
||
%</emphasis>
|
||
’ refers to the keyboard description for the device specified in <emphasis>
|
||
device_spec</emphasis>
|
||
or the keymap names component. If a keymap names component is specified that
|
||
does not begin with ‘+’ or ‘|’ and does not contain ‘<emphasis>
|
||
%</emphasis>
|
||
’, then ‘<emphasis>
|
||
%</emphasis>
|
||
’ refers to the description generated by the keymap names component.
|
||
Otherwise, it refers to the keyboard description for <emphasis>
|
||
device_spec</emphasis>
|
||
.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The ‘<emphasis>
|
||
+</emphasis>
|
||
’ operator specifies that the following component should <emphasis>
|
||
override</emphasis>
|
||
the currently assembled description; any definitions that are present in both
|
||
components are taken from the second.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The ‘<emphasis>
|
||
|</emphasis>
|
||
’ operator specifies that the next specified component should <emphasis>
|
||
augment</emphasis>
|
||
the currently assembled description; any definitions that are present in both
|
||
components are taken from the first.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
If the component expression begins with an operator, a leading ‘<emphasis>
|
||
%</emphasis>
|
||
’ is implied.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
If any unknown or illegal characters appear anywhere in the expression, the
|
||
entire expression is invalid and is ignored.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>
|
||
For example, if <emphasis>
|
||
names->symbols</emphasis>
|
||
contained the expression "+de", it specifies that the default member of the
|
||
"de" class of symbols should be applied to the current keyboard mapping,
|
||
overriding any existing definitions (it could also be written "+de(default)").
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Here is a slightly more involved example: the expression
|
||
"acme(ascii)+de(basic)|iso9995-3" constructs a German (de) mapping for the
|
||
ASCII keyboard supplied by the "acme" vendor. The new definition begins with
|
||
the symbols for the ASCII keyboard for Acme (<emphasis>
|
||
acme(ascii)</emphasis>
|
||
), overrides them with definitions for the basic German keyboard (<emphasis>
|
||
de(basic)</emphasis>
|
||
), and then applies the definitions from the default iso9995-3 keyboard
|
||
(<emphasis>
|
||
iso9995-3</emphasis>
|
||
) to any undefined keys or groups of keys (part three of the iso9995 standard
|
||
defines a common set of bindings for the secondary group, but allows national
|
||
layouts to override those definitions where necessary).
|
||
</para>
|
||
|
||
<note><para>The interpretation of the above expression components (acme, ascii,
|
||
de, basic, iso9995-3) is not defined by Xkb; only the operations and their
|
||
ordering are.</para></note>
|
||
|
||
<para>
|
||
Note that the presence of a keymap <emphasis>
|
||
names</emphasis>
|
||
component that does not contain ‘<emphasis>
|
||
%</emphasis>
|
||
’ (either explicit or implied by virtue of an expression starting with an
|
||
operator) indicates a description that is independent of the keyboard
|
||
description for the device specified in <emphasis>
|
||
device_spec</emphasis>
|
||
. The same is true of requests in which the keymap names component is empty and
|
||
all five other names components contain expressions void of references to
|
||
‘<emphasis>
|
||
%</emphasis>
|
||
’. Requests of this form allow you to deal with keyboard definitions
|
||
independent of any actual device.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The server parses all non-<emphasis>
|
||
NULL</emphasis>
|
||
fields in <emphasis>
|
||
names</emphasis>
|
||
and uses them to build a keyboard description. However, before parsing the
|
||
expressions in <emphasis>
|
||
names</emphasis>
|
||
, the server ORs the bits in <emphasis>
|
||
want</emphasis>
|
||
and <emphasis>
|
||
need</emphasis>
|
||
together and examines the result in relationship to the expressions in
|
||
<emphasis>
|
||
names</emphasis>
|
||
. Table 20.3 identifies the components that are required for each of the
|
||
possible bits in <emphasis>
|
||
want</emphasis>
|
||
or <emphasis>
|
||
need</emphasis>
|
||
. If a required component has not been specified in the <emphasis>
|
||
names</emphasis>
|
||
structure (the corresponding field is <emphasis>
|
||
NULL</emphasis>
|
||
), the server substitutes the expression "<emphasis>
|
||
%</emphasis>
|
||
", resulting in the component values being taken from <emphasis>
|
||
device_spec</emphasis>
|
||
. In addition, if <emphasis>
|
||
load</emphasis>
|
||
is <emphasis>
|
||
True</emphasis>
|
||
, the server modifies <emphasis>
|
||
names</emphasis>
|
||
if necessary (again using a "<emphasis>
|
||
%</emphasis>
|
||
" entry) to ensure all of the following fields are non-<emphasis>
|
||
NULL</emphasis>
|
||
: <emphasis>
|
||
types</emphasis>
|
||
, <emphasis>
|
||
keycodes</emphasis>
|
||
, <emphasis>
|
||
symbols</emphasis>
|
||
, and <emphasis>
|
||
compat</emphasis>
|
||
.<emphasis>
|
||
</emphasis>
|
||
</para>
|
||
|
||
<table frame='none'>
|
||
<title>Want and Need Mask Bits and Required Names Components</title>
|
||
<tgroup cols='3'>
|
||
<colspec colsep='0'/>
|
||
<colspec colsep='0'/>
|
||
<colspec colsep='0'/>
|
||
<thead>
|
||
<row rowsep='0'>
|
||
<entry>want or need mask bit</entry>
|
||
<entry>Required names Components</entry>
|
||
<entry>value</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_TypesMask</entry>
|
||
<entry>Types</entry>
|
||
<entry>(1L<<0)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_CompatMapMask</entry>
|
||
<entry>Compat</entry>
|
||
<entry>(1L<<1)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_ClientSymbolsMask</entry>
|
||
<entry>Types + Symbols + Keycodes</entry>
|
||
<entry>(1L<<2)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_ServerSymbolsMask</entry>
|
||
<entry>Types + Symbols + Keycodes</entry>
|
||
<entry>(1L<<3)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_SymbolsMask</entry>
|
||
<entry>Symbols</entry>
|
||
<entry>(1L<<1)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_IndicatorMapMask</entry>
|
||
<entry>Compat</entry>
|
||
<entry>(1L<<4)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_KeyNamesMask</entry>
|
||
<entry>Keycodes</entry>
|
||
<entry>(1L<<5)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_GeometryMask</entry>
|
||
<entry>Geometry</entry>
|
||
<entry>(1L<<6)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_OtherNamesMask</entry>
|
||
<entry>Types + Symbols + Keycodes + Compat + Geometry</entry>
|
||
<entry>(1L<<7)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_AllComponentsMask</entry>
|
||
<entry></entry>
|
||
<entry>(0xff)</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
|
||
<para>
|
||
<emphasis>
|
||
need</emphasis>
|
||
specifies a set of keyboard components that the server must be able to resolve
|
||
in order for <emphasis>
|
||
XkbGetKeyboardByName</emphasis>
|
||
to succeed; if any of the components specified in <emphasis>
|
||
need</emphasis>
|
||
cannot be successfully resolved, <emphasis>
|
||
XkbGetKeyboardByName</emphasis>
|
||
fails.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
<emphasis>
|
||
want</emphasis>
|
||
specifies a set of keyboard components that the server should attempt to
|
||
resolve, but that are not mandatory. If the server is unable to resolve any of
|
||
these components, <emphasis>
|
||
XkbGetKeyboardByName</emphasis>
|
||
still succeeds. Bits specified in <emphasis>
|
||
want</emphasis>
|
||
that are also specified in <emphasis>
|
||
need</emphasis>
|
||
have no effect in the context of <emphasis>
|
||
want</emphasis>
|
||
.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If <emphasis>
|
||
load</emphasis>
|
||
is <emphasis>
|
||
True</emphasis>
|
||
, the server updates its keyboard description for <emphasis>
|
||
device_spec</emphasis>
|
||
to match the result of the keyboard description just built. If load is
|
||
<emphasis>
|
||
False</emphasis>
|
||
, the server’s description for device <emphasis>
|
||
device_spec</emphasis>
|
||
is not updated. In all cases, the parts specified by <emphasis>
|
||
want</emphasis>
|
||
and <emphasis>
|
||
need</emphasis>
|
||
from the just-built keyboard description are returned.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The <emphasis>
|
||
names</emphasis>
|
||
structure in an <emphasis>
|
||
XkbDescRec</emphasis>
|
||
keyboard description record (see Chapter 18) contains one field for each of
|
||
the five component types used to build a keyboard description. When a keyboard
|
||
description is built from a set of database components, the corresponding
|
||
fields in this <emphasis>
|
||
names</emphasis>
|
||
structure are set to match the expressions used to build the component.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
The entire process of building a new keyboard description from the server
|
||
database of components and returning all or part of it is diagrammed in Figure
|
||
20.1:
|
||
</para>
|
||
|
||
<mediaobject>
|
||
<imageobject> <imagedata format="SVG" fileref="XKBlib-21.svg"/>
|
||
</imageobject>
|
||
<caption>Building a New Keyboard Description from the Server Database</caption>
|
||
</mediaobject>
|
||
|
||
<para>
|
||
The information returned to the client in the <emphasis>
|
||
XkbDescRec</emphasis>
|
||
is essentially the result of a series of calls to extract information from a
|
||
fictitious device whose description matches the one just built. The calls
|
||
corresponding to each of the mask bits are summarized in Table 20.4, together
|
||
with the <emphasis>
|
||
XkbDescRec</emphasis>
|
||
components that are filled in.
|
||
</para>
|
||
|
||
<table frame='none'>
|
||
<title>XkbDescRec Components Returned for Values of Want & Needs</title>
|
||
<tgroup cols='3'>
|
||
<colspec colsep='0'/>
|
||
<colspec colsep='0'/>
|
||
<colspec colsep='0'/>
|
||
<thead>
|
||
<row rowsep='0'>
|
||
<entry>Request (want+need)</entry>
|
||
<entry>Fills in Xkb components</entry>
|
||
<entry>Equivalent Function Call</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_TypesMask</entry>
|
||
<entry>map.types</entry>
|
||
<entry>XkbGetUpdatedMap(dpy, XkbTypesMask, Xkb)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_ServerSymbolsMask</entry>
|
||
<entry>server</entry>
|
||
<entry>XkbGetUpdatedMap(dpy, XkbAllClientInfoMask, Xkb)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_ClientSymbolsMask</entry>
|
||
<entry>map, including map.types</entry>
|
||
<entry>XkbGetUpdatedMap(dpy, XkbAllServerInfoMask, Xkb)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_IndicatorMaps</entry>
|
||
<entry>indicators</entry>
|
||
<entry>XkbGetIndicatorMap(dpy, XkbAllIndicators, Xkb)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_CompatMapMask</entry>
|
||
<entry>compat</entry>
|
||
<entry>XkbGetCompatMap(dpy, XkbAllCompatMask, Xkb)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_GeometryMask</entry>
|
||
<entry>geom</entry>
|
||
<entry>XkbGetGeometry(dpy, Xkb)</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_KeyNamesMask</entry>
|
||
<entry>
|
||
<para>names.keys</para>
|
||
<para>names.key_aliases</para>
|
||
</entry>
|
||
<entry>
|
||
XkbGetNames(dpy, XkbKeyNamesMask | XkbKeyAliasesMask, Xkb)
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry>XkbGBN_OtherNamesMask</entry>
|
||
<entry>
|
||
<para>names.keycodes</para>
|
||
<para>names.geometry</para>
|
||
<para>names.symbols</para>
|
||
<para>names.types</para>
|
||
<para>map.types[*].lvl_names[*]</para>
|
||
<para>names.compat</para>
|
||
<para>names.vmods</para>
|
||
<para>names.indicators</para>
|
||
<para>names.groups</para>
|
||
<para>names.radio_groups</para>
|
||
<para>names.phys_symbols</para>
|
||
</entry>
|
||
<entry>
|
||
<para>XkbGetNames(dpy, XkbAllNamesMask &</para>
|
||
<para>~(XkbKeyNamesMask | XkbKeyAliasesMask),</para>
|
||
<para>Xkb)</para>
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
|
||
<para>
|
||
There is no way to determine which components specified in <emphasis>
|
||
want</emphasis>
|
||
(but not in <emphasis>
|
||
need</emphasis>
|
||
) were actually fetched, other than breaking the call into successive calls to
|
||
<emphasis>
|
||
XkbGetKeyboardByName</emphasis>
|
||
and specifying individual components.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbGetKeyboardByName</emphasis>
|
||
always sets <emphasis>
|
||
min_key_code</emphasis>
|
||
and <emphasis>
|
||
max_key_code</emphasis>
|
||
in the returned <emphasis>
|
||
XkbDescRec</emphasis>
|
||
structure.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
<emphasis>XkbGetKeyboardByName</emphasis>
|
||
is synchronous; it sends the request to the server to build a new keyboard
|
||
description and waits for the reply. If successful, the return value is
|
||
non-<emphasis>NULL</emphasis>.
|
||
<emphasis>XkbGetKeyboardByName</emphasis>
|
||
generates a <emphasis>BadMatch</emphasis>
|
||
protocol error if errors are encountered when building the keyboard
|
||
description.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If you simply want to obtain information about the current keyboard device,
|
||
rather than generating a new keyboard description from elements in the server
|
||
database, use <emphasis>
|
||
XkbGetKeyboard</emphasis>
|
||
(see section 6.2).
|
||
</para>
|
||
|
||
<informaltable frame='none'>
|
||
<tgroup cols='1'>
|
||
<colspec colsep='0'/>
|
||
<tbody>
|
||
<row rowsep='0'>
|
||
<entry role='functiondecl'>
|
||
XkbDescPtr <emphasis>
|
||
XkbGetKeyboard</emphasis>
|
||
(<emphasis>
|
||
dpy</emphasis>
|
||
, <emphasis>
|
||
which</emphasis>
|
||
, <emphasis>
|
||
device_spec</emphasis>
|
||
)
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry role='functionargdecl'>
|
||
Display * <emphasis>
|
||
dpy</emphasis>
|
||
; /* connection to X server */
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry role='functionargdecl'>
|
||
unsigned int<emphasis>
|
||
which</emphasis>
|
||
; /* mask of components of <emphasis>
|
||
XkbDescRec</emphasis>
|
||
of interest */
|
||
</entry>
|
||
</row>
|
||
<row rowsep='0'>
|
||
<entry role='functionargdecl'>
|
||
unsigned int <emphasis>
|
||
device_spec</emphasis>
|
||
; /* device ID */
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbGetKeyboard</emphasis>
|
||
is used to read the current description for one or more components of a
|
||
keyboard device. It calls <emphasis>
|
||
XkbGetKeyboardByName</emphasis>
|
||
as follows:
|
||
</para>
|
||
|
||
|
||
<para>
|
||
<emphasis>
|
||
XkbGetKeyboardByName</emphasis>
|
||
(<emphasis>
|
||
dpy</emphasis>
|
||
, <emphasis>
|
||
device_spec</emphasis>
|
||
, <emphasis>
|
||
NULL</emphasis>
|
||
, <emphasis>
|
||
which</emphasis>
|
||
, <emphasis>
|
||
which</emphasis>
|
||
, <emphasis>
|
||
False</emphasis>
|
||
).
|
||
</para>
|
||
|
||
</sect1>
|
||
</chapter>
|