# Xkb Keyboard Mapping

The Xkb keyboard mapping contains all the information the server and clients need to interpret key events. This chapter provides an overview of the terminology used to describe an Xkb keyboard mapping and introduces common utilities for manipulating the keyboard mapping.

The mapping consists of two components, a server map and a client map. The client map
is the collection of information a client needs to interpret key events from the keyboard. It contains a global list of key types and an array of key symbol maps, each of which describes the symbols bound to a key and the rules to be used to interpret those symbols. The server map
contains the information the server needs to interpret key events. This includes actions and behaviors for each key, explicit components for a key, and the virtual modifiers and the per-key virtual modifier mapping.

For detailed information on particular components of the keyboard map, refer to Xkb_Client_Keyboard_Mapping, and Xkb_Server_Keyboard_Mapping.

## Notation and Terminology

The graphic characters or control functions that may be accessed by one key are logically arranged in groups and levels, where group and level are defined as in the ISO9995 standard:

Group:

- A logical state of a keyboard providing access to a collection of graphic characters. Usually these graphic characters logically belong together and may be arranged on several levels within a group.

Level:

- One of several states (normally 2 or 3) governing which graphic character is produced when a graphic key is actuated. In certain cases the level may also affect function keys.

These definitions, taken from the ISO standard, refer to graphic keys and characters. In the context of Xkb, Group and Level are not constrained to graphic keys and characters; they may be used with any key to access any character the key is capable of generating.

Level is often referred to as Shift Level. Levels are numbered sequentially starting at one.

Shift level is derived from the modifier state, but not necessarily in the same way for all keys. For example, the Shift modifier selects shift level 2 on most keys, but for keypad keys the modifier bound to Num_Lock (that is, the NumLock virtual modifier) also selects shift level 2.

For example, consider the following key (the gray characters indicate symbols that are implied or expected but are not actually engraved on the key):

### Shift Levels and Groups

This key has two groups, indicated by the columns, and each group has two shift levels. For the first group (Group1), the symbol shift level one is a, and the symbol for shift level two is A. For the second group, the symbol for shift level one is æ, and the symbol for shift level two is Æ.

### Core Implementation

The standard interpretation rules for the core X keymap only allow clients to access keys such as the one shown in Figure 14.1. That is, clients using the standard interpretation rules can only access one of four keysyms for any given KeyPress event — two different symbols in two different groups.

In general, the Shift modifier, the Lock modifier, and the modifier bound to the Num_Lock key are used to change between shift level 1 and shift level 2. To switch between groups, the core implementation uses the modifier bound to the Mode_switch key. When the Mode_switch modifier is set, the keyboard is logically in Group 2. When the Mode_switch modifier is not set, the keyboard is logically in Group 1.

The core implementation does not clearly specify the behavior of keys. For example, the locking behavior of the CapsLock and Num_Lock keys depends on the vendor.

### Xkb Implementation

Xkb extends the core implementation by providing access to up to four keyboard groups with up to 63 shift levels per key

The core implementation restricts the number of symbols per key to 255. With four groups, this allows for up to 63 symbols (or shift levels) per group. Most keys will only have a few shift levels.

. In addition, Xkb provides precise specifications regarding the behavior of keys. In Xkb, modifier state and the current group are independent (with the exception of compatibility mapping, discussed in The_Xkb_Compatibility_Map).

Xkb handles switching between groups via key actions, independent of any modifier state information. Key actions are in the server map component and are described in detail in section 16.1.4.

Xkb handles shift levels by associating a key type with each group on each key. Each key type defines the shift levels available for the groups on keys of its type and specifies the modifier combinations necessary to access each level.

For example, Xkb allows key types where the Control modifier can be used to access the shift level two of a key. Key types are in the client map component and are described in detail in section 15.2.

Xkb provides precise specification of the behavior of a key using key behaviors. Key behaviors are in the server map component and are described in detail in section 16.2.

## Getting Map Components from the Server

Xkb provides two functions to obtain the keyboard mapping components from the server. The first function, `XkbGetMap`, allocates an XkbDescRec structure, retrieves mapping components from the server, and stores them in the XkbDescRec structure it just allocated. The second function, `XkbGetUpdatedMap`, retrieves mapping components from the server and stores them in an XkbDescRec structure that has previously been allocated.

To allocate an XkbDescRec structure and populate it with the server’s keyboard client map and server map, use `XkbGetMap`. `XkbGetMap` is similar to `XkbGetKeyboard` (see section 6.2), but is used only for obtaining the address of an XkbDescRec structure that is populated with keyboard mapping components. It allows finer control over which substructures of the keyboard mapping components are to be populated. `XkbGetKeyboard` always returns fully populated components, while `XkbGetMap` can be instructed to return a partially populated component.

        XkbDescPtr XkbGetMap

        Display *display
        unsigned int which
        unsigned int device_spec

`display`

- connection to X server

`which`

- mask selecting subcomponents to populate

`device_spec`

- device_id, or XkbUseCoreKbd

The `which` mask is a bitwise inclusive OR of the masks defined in Table 14.1. Only those portions of the keyboard server map and the keyboard client maps that are specified in `which` are allocated and populated.

In addition to allocating and obtaining the server map and the client map, `XkbGetMap` also sets the `device_spec`, the min_key_code, and max_key_code fields of the keyboard description.

`XkbGetMap` is synchronous; it queries the server for the desired information, waits for a reply, and then returns. If successful, `XkbGetMap` returns a pointer to the XkbDescRec structure it allocated. If unsuccessful, `XkbGetMap` returns NULL. When unsuccessful, one of the following protocol errors is also generated: BadAlloc (unable to allocate the XkbDescRec structure), BadValue (some mask bits in `which` are undefined), or BadImplementation (a compatible version of the Xkb extension is not available in the server). To free the returned data, use `XkbFreeClientMap`.

Xkb also provides convenience functions to get partial component definitions from the server. These functions are specified in the convenience functions column in Table 14.1. Refer to the sections listed in the table for more information on these functions.

## Xkb Mapping Component Masks and Convenience Functions

Mask | Value | Map | Fields | Convenience Functions | Section
XkbKeyTypesMask | (1<<0) | client | types size_types num_types | `XkbGetKeyTypes` `XkbResizeKeyType` `XkbCopyKeyType` `XkbCopyKeyTypes` | 15.2
XkbKeySymsMask | (1<<1) | client | syms size_syms num_syms key_sym_map | `XkbGetKeySyms` `XkbResizeKeySyms` `XkbChangeTypesOfKey` | 15.3
XkbModifierMapMask | (1<<2) | client | modmap | `XkbGetKeyModifierMap` | 15.4
XkbExplicitComponentsMask | (1<<3) | server | explicit | `XkbGetKeyExplicitComponents` | 16.3
XkbKeyActionsMask | (1<<4) | server | key_acts acts num_acts size_acts | `XkbGetKeyActions` `XkbResizeKeyActions` | 16.1
XkbKeyBehaviorsMask | (1<<5) | server | behaviors | `XkbGetKeyBehaviors` | 16.2
XkbVirtualModsMask | (1<<6) | server | vmods | `XkbGetVirtualMods` | 16.4
XkbVirtualModMapMask | (1<<7) | server | vmodmap | `XkbGetVirtualModMap` | 16.4

Xkb defines combinations of these masks for convenience:

    #define  XkbResizableInfoMask      (XkbKeyTypesMask)
    #define  XkbAllClientInfoMask      (XkbKeyTypesMask | XkbKeySymsMask |
                                        XkbModifierMapMask)
    #define  XkbAllServerInfoMask      (XkbExplicitComponentsMask |
                                        XkbKeyActionsMask| XkbKeyBehaviorsMask |
                                        XkbVirtualModsMask | XkbVirtualModMapMask)
    #define  XkbAllMapComponentsMask   (XkbAllClientInfoMask|XkbAllServerInfoMask)

Key types, symbol maps, and actions are all interrelated: changes in one require changes in the others. The convenience functions make it easier to edit these components and handle the interdependencies.

To update the client or server map information in an existing keyboard description, use `XkbGetUpdatedMap`.

        Status XkbGetUpdatedMap

        Display *display
        unsigned int which
        XkbDescPtr xkb

`display`

- connection to X server

`which`

- mask selecting subcomponents to populate

`xkb`

- keyboard description to be updated

The `which` parameter is a bitwise inclusive OR of the masks in Table 14.1. If the needed components of the `xkb` structure are not already allocated, `XkbGetUpdatedMap` allocates them. `XkbGetUpdatedMap` fetches the requested information for the device specified in the XkbDescRec passed in the `xkb` parameter.

`XkbGetUpdatedMap` is synchronous; it queries the server for the desired information, waits for a reply, and then returns. If successful, `XkbGetUpdatedMap` returns Success. If unsuccessful, `XkbGetUpdatedMap` returns one of the following: BadAlloc (unable to allocate a component in the XkbDescRec structure), BadValue (some mask bits in `which` are undefined), BadImplementation (a compatible version of the Xkb extension is not available in the server or the reply from the server was invalid).

## Changing Map Components in the Server

There are two ways to make changes to map components: either change a local copy of the keyboard map and call `XkbSetMap` to send the modified map to the server, or, to reduce network traffic, use an XkbMapChangesRec structure and call `XkbChangeMap`.

        Bool XkbSetMap

        Display *dpy
        unsigned int which
        XkbDescPtr xkb

`dpy`

- connection to X server

`which`

- mask selecting subcomponents to update

`xkb`

- description from which new values are taken

Use `XkbSetMap` to send a complete new set of values for entire components (for example, all symbols, all actions, and so on) to the server. The `which` parameter specifies the components to be sent to the server, and is a bitwise inclusive OR of the masks listed in Table 14.1. The `xkb` parameter is a pointer to an XkbDescRec structure and contains the information to be copied to the server. For each bit set in the `which` parameter, `XkbSetMap` takes the corresponding structure values from the `xkb` parameter and sends it to the server specified by `dpy`.

If any components specified by `which` are not present in the `xkb` parameter, `XkbSetMap` returns False. Otherwise, it sends the update request to the server and returns True. `XkbSetMap` can generate BadAlloc, BadLength, and BadValue protocol errors.

Key types, symbol maps, and actions are all interrelated; changes in one require changes in the others. Xkb provides functions to make it easier to edit these components and handle the interdependencies. Table 14.1 lists these helper functions and provides a pointer to where they are defined.

### The XkbMapChangesRec Structure

Use the XkbMapChangesRec structure to identify and track partial modifications to the mapping components and to reduce the amount of traffic between the server and clients.

    typedef struct _XkbMapChanges {
        unsigned short    changed;              /* identifies valid components
                                                   in structure */
        KeyCode           min_key_code;         /* lowest numbered keycode for
                                                   device */
        KeyCode           max_key_code;         /* highest numbered keycode for
                                                   device */
        unsigned char     first_type;           /* index of first key type
                                                   modified */
        unsigned char     num_types;            /* # types modified */
        KeyCode           first_key_sym;        /* first key whose key_sym_map
                                                   changed */
        unsigned char     num_key_syms;         /* # key_sym_map
                                                   entries changed */
        KeyCode           first_key_act;        /* first key whose key_acts
                                                   entry changed */
        unsigned char     num_key_acts;         /* # key_acts
                                                   entries changed */
        KeyCode           first_key_behavior;   /* first key whose behaviors
                                                   changed */
        unsigned char     num_key_behaviors;    /* # behaviors
                                                   entries changed */
        KeyCode           first_key_explicit;   /* first key whose explicit
                                                   entry changed */
        unsigned char     num_key_explicit;     /* # explicit
                                                   entries changed */
        KeyCode           first_modmap_key;     /* first key whose modmap
                                                   entry changed */
        unsigned char     num_modmap_keys;      /* # modmap
                                                   entries changed */
        KeyCode           first_vmodmap_key;    /* first key whose vmodmap
                                                   changed */
        unsigned char     num_vmodmap_keys;     /* # vmodmap
                                                   entries changed */
        unsigned char     pad1;                 /* reserved */
        unsigned short    vmods;                /* mask indicating which vmods
                                                   changed */
    } XkbMapChangesRec, *XkbMapChangesPtr;

The changed field identifies the map components that have changed in an XkbDescRec structure and may contain any of the bits in Table 14.1, which are also shown in Table 14.2. Every 1 bit in changed also identifies which other fields in the XkbMapChangesRec structure contain valid values, as indicated in Table 14.2. The min_key_code and max_key_code fields are for reference only; they are ignored on any requests sent to the server and are always updated by the server whenever it returns the data for an XkbMapChangesRec.

### XkbMapChangesRec Masks

Mask | Valid XkbMapChangesRec Fields | XkbDescRec Field Containing Changed Data
XkbKeyTypesMask | first_type, num_types | map->type[first_type] .. map->type[first_type + num_types - 1]
XkbKeySymsMask | first_key_sym, num_key_syms | map->key_sym_map[first_key_sym] .. map->key_sym_map[first_key_sym + num_key_syms - 1]
XkbModifierMapMask | first_modmap_key, num_modmap_keys | map->modmap[first_modmap_key] .. map->modmap[first_modmap_key + num_modmap_keys-1]
XkbExplicitComponentsMask | first_key_explicit, num_key_explicit | server->explicit[first_key_explicit] .. server->explicit[first_key_explicit + num_key_explicit - 1]
XkbKeyActionsMask | first_key_act, num_key_acts | server->key_acts[first_key_act] .. server->key_acts[first_key_act + num_key_acts - 1]
XkbKeyBehaviorsMask | first_key_behavior, num_key_behaviors | server->behaviors[first_key_behavior] .. server->behaviors[first_key_behavior + num_key_behaviors - 1]
XkbVirtualModsMask | vmods | server->vmods[*]
XkbVirtualModMapMask | first_vmodmap_key, num_vmodmap_keys | server->vmodmap[first_vmodmap_key] .. server->vmodmap[first_vmodmap_key + num_vmodmap_keys - 1]

To update only partial components of a keyboard description, modify the appropriate fields in the server and map components of a local copy of the keyboard description, then call `XkbChangeMap` with an XkbMapChangesRec structure indicating which components have changed.

        Bool XkbChangeMap

        Display *dpy
        XkbDescPtr xkb
        XkbMapChangesPtr changes

`dpy`

- connection to X server

`xkb`

- description from which new values are taken

`changes`

- identifies component parts to update

`XkbChangeMap` copies any components specified by the `changes` structure from the keyboard description, `xkb`, to the X server specified by `dpy`.

If any components specified by `changes` are not present in the `xkb` parameter, `XkbChangeMap` returns False. Otherwise, it sends a request to the server and returns True.

`XkbChangeMap` can generate BadAlloc, BadLength, and BadValue protocol errors.

## Tracking Changes to Map Components

The Xkb extension reports XkbMapNotify events to clients wanting notification whenever a map component of the Xkb description for a device changes. There are many different types of Xkb keyboard map changes. Xkb uses an event detail mask to identify each type of change. The event detail masks are identical to the masks listed in Table 14.1.

To receive XkbMapNotify events under all possible conditions, use `XkbSelectEvents` (see section 4.3) and pass XkbMapNotifyMask in both `bits_to_change` and `values_for_bits`.

To receive XkbMapNotify events only under certain conditions, use `XkbSelectEventDetails` using XkbMapNotify as the event_type and specifying the desired map changes in `bits_to_change` and `values_for_bits` using mask bits from Table 14.1.

The structure for XkbMapNotify events is:

    typedef struct {
        int            type;         /* Xkb extension base event code */
        unsigned long  serial;       /* X server serial number for event */
        Bool           send_event;   /* True ⇒ synthetically generated */
        Display *      display;      /* server connection where event generated */
        Time           time;         /* server time when event generated */
        int            xkb_type;     /* XkbMapNotify */
        int            device;       /* Xkb device ID, will not be XkbUseCoreKbd */
        unsigned int   changed;      /* identifies valid fields in rest of event */
        unsigned int   resized;      /* reserved */
        int            first_type;   /* index of first key type modified */
        int            num_types     /* # types modified */
        KeyCode        min_key_code; /* minimum keycode for device */
        KeyCode        max_key_code; /* maximum keycode for device */
        KeyCode        first_key_sym; /* first key whose key_sym_map changed */
        KeyCode        first_key_act; /* first key whose key_acts entry changed */
        KeyCode        first_key_behavior; /* first key whose behaviors changed */
        KeyCode        first_key_explicit; /* first key whose explicit entry changed */
        KeyCode        first_modmap_key;   /* first key whose modmap entry changed */
        KeyCode        first_vmodmap_key;  /* # modmap entries changed */
        int            num_key_syms;       /* # key_sym_map entries changed */
        int            num_key_acts;       /* # key_acts entries changed */
        int            num_key_behaviors;  /* # behaviors entries changed */
        int            num_key_explicit;   /* # explicit entries changed */
        int            num_modmap_keys;    /* # modmap entries changed */
        int            num_vmodmap_keys;   /* # vmodmap entries changed */
        unsigned int   vmods;              /* mask indicating which vmods changed */
    } XkbMapNotifyEvent;

The changed field specifies the map components that have changed and is the bitwise inclusive OR of the mask bits defined in Table 14.1. The other fields in this event are interpreted as the like-named fields in an XkbMapChangesRec (see section 14.3.1). The XkbMapNotifyEvent structure also has an additional resized field that is reserved for future use.

## Allocating and Freeing Client and Server Maps

Calling `XkbGetMap` (see section 14.2) should be sufficient for most applications to get client and server maps. As a result, most applications do not need to directly allocate client and server maps.

If you change the number of key types or construct map components without loading the necessary components from the X server, do not allocate any map components directly using `malloc` or `Xmalloc`. Instead, use the Xkb allocators, `XkbAllocClientMap`, and `XkbAllocServerMap`.

Similarly, use the Xkb destructors, `XkbFreeClientMap`, and `XkbFreeServerMap` instead of `free` or `Xfree`.

### Allocating an Empty Client Map

To allocate and initialize an empty client map description record, use `XkbAllocClientMap`.

        Status XkbAllocClientMap

        XkbDescPtr xkb
        unsigned int which
        unsigned int type_count

`xkb`

- keyboard description in which to allocate client map

`which`

- mask selecting map components to allocate

`type_count`

- value of num_types field in map to be allocated

`XkbAllocClientMap` allocates and initializes an empty client map in the map field of the keyboard description specified by `xkb`. The `which` parameter specifies the particular components of the client map structure to allocate and is a mask composed by a bitwise inclusive OR of one or more of the masks shown in Table 14.3.

### XkbAllocClientMap Masks

Mask | Effect
XkbKeyTypesMask | The `type_count` field specifies the number of entries to preallocate for the types field of the client map. If the `type_count` field is less than XkbNumRequiredTypes (see section 15.2.1), returns BadValue.
XkbKeySymsMask | The min_key_code and max_key_code fields of the `xkb` parameter are used to allocate the syms and key_sym_map fields of the client map. The fields are allocated to contain the maximum number of entries necessary for max_key_code − min_key_code + 1 keys.
XkbModifierMapMask | The min_key_code and max_key_code fields of the `xkb` parameter are used to allocate the modmap field of the client map. The field is allocated to contain the maximum number of entries necessary for max_key_code − min_key_code + 1 keys.

The min_key_code and max_key_code fields of the `xkb` parameter must be legal values if the XkbKeySymsMask or XkbModifierMapMask masks are set in the `which` parameter. If they are not valid, `XkbAllocClientMap` returns BadValue.

If the client map of the keyboard description is not NULL, and any fields are already allocated in the client map, `XkbAllocClientMap` does not overwrite the existing values; it simply ignores that part of the request. The only exception is the types array. If `type_count` is greater than the current num_types field of the client map, `XkbAllocClientMap` resizes the types array and resets the num_types field accordingly.

If `XkbAllocClientMap` is successful, it returns Success. Otherwise, it can return either BadMatch, BadAlloc, or BadValue errors.

### Freeing a Client Map

To free memory used by the client map member of an XkbDescRec structure, use `XkbFreeClientMap`.

        void XkbFreeClientMap

        XkbDescPtr xkb
        unsigned int which
        Bool free_all

`xkb`

- keyboard description containing client map to free

`which`

- mask identifying components of map to free

`free_all`

- True ⇒ free all client components and map itself

`XkbFreeClientMap` frees the components of client map specified by `which` in the XkbDescRec structure specified by the `xkb` parameter and sets the corresponding structure component values to NULL. The `which` parameter specifies a combination of the client map masks shown in Table 14.3.

If `free_all` is True, `which` is ignored; `XkbFreeClientMap` frees every non- NULL structure component in the client map, frees the XkbClientMapRec structure referenced by the map member of the `xkb` parameter, and sets the map member to NULL.

### Allocating an Empty Server Map

To allocate and initialize an empty server map description record, use `XkbAllocServerMap`.

        Status XkbAllocServerMap

        XkbDescPtr xkb
        unsigned int which
        unsigned int count_acts

`xkb`

- keyboard description in which to allocate server map

`which`

- mask selecting map components to allocate

`count_acts`

- value of num_acts field in map to be allocated

`XkbAllocServerMap` allocates and initializes an empty server map in the server field of the keyboard description specified by `xkb`. The `which` parameter specifies the particular components of the server map structure to allocate, as specified in Table 14.4.

### XkbAllocServerMap Masks

Mask | Effect
XkbExplicitComponentsMask | The min_key_code and max_key_code fields of the `xkb` parameter are used to allocate the explicit field of the server map.
XkbKeyActionsMask | The min_key_code and max_key_code fields of the `xkb` parameter are used to allocate the key_acts field of the server map. The `count_acts` parameter is used to allocate the acts field of the server map.
XkbKeyBehaviorsMask | The min_key_code and max_key_code fields of the `xkb` parameter are used to allocate the behaviors field of the server map.
XkbVirtualModMapMask | The min_key_code and max_key_code fields of the `xkb` parameter are used to allocate the vmodmap field of the server map.

The min_key_code and max_key_code fields of the `xkb` parameter must be legal values. If they are not valid, `XkbAllocServerMap` returns BadValue.

If the server map of the keyboard description is not NULL and any fields are already allocated in the server map, `XkbAllocServerMap` does not overwrite the existing values. The only exception is with the acts array. If the `count_acts` parameter is greater than the current num_acts field of the server map, `XkbAllocServerMap` resizes the acts array and resets the num_acts field accordingly.

If `XkbAllocServerMap` is successful, it returns Success. Otherwise, it can return either BadMatch or BadAlloc errors.

### Freeing a Server Map

To free memory used by the server member of an XkbDescRec structure, use `XkbFreeServerMap`.

        void XkbFreeServerMap

        XkbDescPtr xkb
        unsigned int which
        Bool free_all

`xkb`

- keyboard description containing server map to free

`which`

- mask identifying components of map to free

`free_all`

- True ⇒ free all server map components and server itself

The `XkbFreeServerMap` function frees the specified components of server map in the XkbDescRec structure specified by the `xkb` parameter and sets the corresponding structure component values to NULL. The `which` parameter specifies a combination of the server map masks and is a bitwise inclusive OR of the masks listed in Table 14.4. If `free_all` is True, `which` is ignored and `XkbFreeServerMap` frees every non- NULL structure component in the server map, frees the XkbServerMapRec structure referenced by the server member of the `xkb` parameter, and sets the server member to NULL.