Server Database of Keyboard Components
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.
Server Database Keyboard Components
Component Type
Component Primary Contents
May also contain
Keymap
Complete keyboard description
Normally assembled using a complete component from each of the other types
Keycodes
Symbolic name for each key
Minimum and maximum legal keycodes
Aliases for some keys
Symbolic names for indicators
Description of indicators physically present
Types
Key types
Real modifier bindings and symbolic names for some virtual modifiers
Compatibility
Rules used to assign actions to keysyms
Maps for some indicators
Real modifier bindings and symbolic names for some virtual modifiers
Symbols
Symbol mapping for keyboard keys
Modifier mapping
Symbolic names for groups
Explicit actions and behaviors for some keys
Real modifier bindings and symbolic names for some virtual modifiers
Geometry
Layout of the keyboard
Aliases for some keys; overrides keycodes component aliases
Symbolic names for some indicators
Description of indicators physically present
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.
There may be multiple entries for each of the component types. An entry may be
either
complete
or
partial
. 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.
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
any
ASCII keyboard to use a national layout.
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.
Component Names
Component names have the form "
class(member)
" where
class
describes a subset of the available components for a particular type and the
optional
member
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
default
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.
The
class
and
member
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.
Listing the Known Keyboard Components
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
XkbListComponents
.
XkbComponentListPtr
XkbListComponents
(
dpy
,
device_spec
,
ptrns
,
max_inout
)
Display *
dpy
; /* connection to X server */
unsigned int
device_spec
; /* device ID, or
XkbUseCoreKbd
*/
XkbComponentNamesPtr
ptrns
; /* namelist for components of interest */
int *
max_inout
; /* max # returned names, # left over */
XkbListComponents
queries the server for a list of component names matching the patterns
specified in
ptrns
. It waits for a reply and returns the matching component names in an
XkbComponentListRec
structure. When you are done using the structure, you should free it using
XkbFreeComponentList
.
device_spec
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.
ptrns
is a pointer to an
XkbComponentNamesRec
, described below. Each of the fields in
ptrns
contains a pattern naming the components of interest. Each of the patterns is
composed of characters from the ISO
Latin1
encoding, but can contain only parentheses, the wildcard characters
‘
?
’ and ‘
*
’, and characters permitted in a component class or member name (see section
20.1). A pattern may be
NULL
, in which case no components for that type is returned. Pattern matches with
component names are case sensitive. The ‘
?
’ wildcard matches any single character, except a left or right parenthesis;
the ‘
*
’ 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.
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.
max_inout
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
XkbListComponents
,
max_inout
contains the number of names that matched the request but were not returned
because of the limit.
The component name patterns used to describe the request are passed to
XkbListComponents
using an
XkbComponentNamesRec
structure. This structure has no special allocation constraints or
interrelationships with other structures; allocate and free this structure
using standard
malloc
and
free
calls or their equivalent:
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 */
} XkbComponentNamesRec, *XkbComponentNamesPtr;
XkbListComponents
returns a pointer to an
XkbComponentListRec
:
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 */
} XkbComponentListRec, *XkbComponentListPtr;
typedef struct _XkbComponentName {
unsigned short flags; /* hints regarding component name */
char * name; /* name of component */
} XkbComponentNameRec, *XkbComponentNamePtr;
Note that the structure used to specify patterns on input is an
XkbComponentNamesRec
, and that used to hold the individual component names upon return is an
XkbComponentNameRec
(no trailing ‘s’ in Name).
When you are done using the structure returned by
XkbListComponents
, free it using
XkbFreeComponentList
.
void
XkbFreeComponentList
(list)
XkbComponentListPtr list; /* pointer to
XkbComponentListRec
to free */
Component Hints
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
XkbComponentNameRec
structures contained in the
XkbComponentListRec
returned from
XkbListComponents
. 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
XkbLC_Partial
also set); full symbols components are assumed to specify all of the pieces.
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
XkbLC_AlphanumericKeys
hint. In general, symbols components should set only one of the four flags
(
XkbLC_AlternateGroup
may be combined with any of the other flags).
XkbComponentNameRec Flags Bits
Component Type
Component Hints (flags)
Meaning
Value
All Components
XkbLC_Hidden
Do not present to user
(1L<<0)
XkbLC_Default
Default member of class
(1L<<1)
XkbLC_Partial
Partial component
(1L<<2)
Keymap
none
Keycodes
none
Types
none
Compatibility
none
Symbols
XkbLC_AlphanumericKeys
Bindings primarily for alphanumeric keyboard section
(1L<<8)
XkbLC_ModifierKeys
Bindings primarily for modifier keys
(1L<<9)
XkbLC_KeypadKeys
Bindings primarily for numeric keypad keys
(1L<<10)
XkbLC_FunctionKeys
Bindings primarily for function keys
(1L<<11)
XkbLC_AlternateGroup
Bindings for an alternate group
(1L<<12)
Geometry
none
Building a Keyboard Description Using the Server Database
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.
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
XkbGetKeyboardByName
.
XkbDescPtr
XkbGetKeyboardByName
(
dpy
,
device_spec
,
names
,
want
,
need
,
load
)
Display *
dpy
; /* connection to X server */
unsigned int
device_spec
; /* device ID, or
XkbUseCoreKbd
*/
XkbComponentNamesPtr
names
; /* names of components to fetch */
unsigned int
want
; /* desired structures in returned record */
unsigned int
need
; /* mandatory structures in returned record */
Bool
load
; /*
True
=> load into
device_spec
*/
names
contains a set of expressions describing the keyboard components the server
should use to build the new keyboard description.
want
and
need
are bit fields describing the parts of the resulting keyboard description that
should be present in the returned
XkbDescRec
.
The individual fields in
names
are
component expressions
composed of keyboard component names (no wildcarding as may be used in
XkbListComponents
), the special component name symbol ‘%’, and the special operator
characters ‘
+
’ and ‘
|
’. A component expression is parsed left to right, as follows:
The special component name "
computed
" may be used in
keycodes
component expressions and refers to a component consisting of a set of
keycodes computed automatically by the server as needed.
The special component name "
canonical
" may be used in
types
component expressions and refers to a partial component defining the four
standard key types:
ALPHABETIC
,
ONE_LEVEL
,
TWO_LEVEL
, and
KEYPAD
.
The special component name ‘
%
’ refers to the keyboard description for the device specified in
device_spec
or the keymap names component. If a keymap names component is specified that
does not begin with ‘+’ or ‘|’ and does not contain ‘
%
’, then ‘
%
’ refers to the description generated by the keymap names component.
Otherwise, it refers to the keyboard description for
device_spec
.
The ‘
+
’ operator specifies that the following component should
override
the currently assembled description; any definitions that are present in both
components are taken from the second.
The ‘
|
’ operator specifies that the next specified component should
augment
the currently assembled description; any definitions that are present in both
components are taken from the first.
If the component expression begins with an operator, a leading ‘
%
’ is implied.
If any unknown or illegal characters appear anywhere in the expression, the
entire expression is invalid and is ignored.
For example, if
names->symbols
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)").
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 (
acme(ascii)
), overrides them with definitions for the basic German keyboard (
de(basic)
), and then applies the definitions from the default iso9995-3 keyboard
(
iso9995-3
) 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).
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.
Note that the presence of a keymap
names
component that does not contain ‘
%
’ (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
device_spec
. 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
‘
%
’. Requests of this form allow you to deal with keyboard definitions
independent of any actual device.
The server parses all non-
NULL
fields in
names
and uses them to build a keyboard description. However, before parsing the
expressions in
names
, the server ORs the bits in
want
and
need
together and examines the result in relationship to the expressions in
names
. Table 20.3 identifies the components that are required for each of the
possible bits in
want
or
need
. If a required component has not been specified in the
names
structure (the corresponding field is
NULL
), the server substitutes the expression "
%
", resulting in the component values being taken from
device_spec
. In addition, if
load
is
True
, the server modifies
names
if necessary (again using a "
%
" entry) to ensure all of the following fields are non-
NULL
:
types
,
keycodes
,
symbols
, and
compat
.
Want and Need Mask Bits and Required Names Components
want or need mask bit
Required names Components
value
XkbGBN_TypesMask
Types
(1L<<0)
XkbGBN_CompatMapMask
Compat
(1L<<1)
XkbGBN_ClientSymbolsMask
Types + Symbols + Keycodes
(1L<<2)
XkbGBN_ServerSymbolsMask
Types + Symbols + Keycodes
(1L<<3)
XkbGBN_SymbolsMask
Symbols
(1L<<1)
XkbGBN_IndicatorMapMask
Compat
(1L<<4)
XkbGBN_KeyNamesMask
Keycodes
(1L<<5)
XkbGBN_GeometryMask
Geometry
(1L<<6)
XkbGBN_OtherNamesMask
Types + Symbols + Keycodes + Compat + Geometry
(1L<<7)
XkbGBN_AllComponentsMask
(0xff)
need
specifies a set of keyboard components that the server must be able to resolve
in order for
XkbGetKeyboardByName
to succeed; if any of the components specified in
need
cannot be successfully resolved,
XkbGetKeyboardByName
fails.
want
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,
XkbGetKeyboardByName
still succeeds. Bits specified in
want
that are also specified in
need
have no effect in the context of
want
.
If
load
is
True
, the server updates its keyboard description for
device_spec
to match the result of the keyboard description just built. If load is
False
, the server’s description for device
device_spec
is not updated. In all cases, the parts specified by
want
and
need
from the just-built keyboard description are returned.
The
names
structure in an
XkbDescRec
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
names
structure are set to match the expressions used to build the component.
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:
Building a New Keyboard Description from the Server Database
The information returned to the client in the
XkbDescRec
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
XkbDescRec
components that are filled in.
XkbDescRec Components Returned for Values of Want & Needs
Request (want+need)
Fills in Xkb components
Equivalent Function Call
XkbGBN_TypesMask
map.types
XkbGetUpdatedMap(dpy, XkbTypesMask, Xkb)
XkbGBN_ServerSymbolsMask
server
XkbGetUpdatedMap(dpy, XkbAllClientInfoMask, Xkb)
XkbGBN_ClientSymbolsMask
map, including map.types
XkbGetUpdatedMap(dpy, XkbAllServerInfoMask, Xkb)
XkbGBN_IndicatorMaps
indicators
XkbGetIndicatorMap(dpy, XkbAllIndicators, Xkb)
XkbGBN_CompatMapMask
compat
XkbGetCompatMap(dpy, XkbAllCompatMask, Xkb)
XkbGBN_GeometryMask
geom
XkbGetGeometry(dpy, Xkb)
XkbGBN_KeyNamesMask
names.keys
names.key_aliases
XkbGetNames(dpy, XkbKeyNamesMask | XkbKeyAliasesMask, Xkb)
XkbGBN_OtherNamesMask
names.keycodes
names.geometry
names.symbols
names.types
map.types[*].lvl_names[*]
names.compat
names.vmods
names.indicators
names.groups
names.radio_groups
names.phys_symbols
XkbGetNames(dpy, XkbAllNamesMask &
~(XkbKeyNamesMask | XkbKeyAliasesMask),
Xkb)
There is no way to determine which components specified in
want
(but not in
need
) were actually fetched, other than breaking the call into successive calls to
XkbGetKeyboardByName
and specifying individual components.
XkbGetKeyboardByName
always sets
min_key_code
and
max_key_code
in the returned
XkbDescRec
structure.
XkbGetKeyboardByName
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-NULL.
XkbGetKeyboardByName
generates a BadMatch
protocol error if errors are encountered when building the keyboard
description.
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
XkbGetKeyboard
(see section 6.2).
XkbDescPtr
XkbGetKeyboard
(
dpy
,
which
,
device_spec
)
Display *
dpy
; /* connection to X server */
unsigned int
which
; /* mask of components of
XkbDescRec
of interest */
unsigned int
device_spec
; /* device ID */
XkbGetKeyboard
is used to read the current description for one or more components of a
keyboard device. It calls
XkbGetKeyboardByName
as follows:
XkbGetKeyboardByName
(
dpy
,
device_spec
,
NULL
,
which
,
which
,
False
).