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 Chapter 15, "Xkb Client Keyboard Mapping" and Chapter 16, "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 Chapter 17). 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, which, device_spec ) Display * display ; /* connection to X server */ unsigned int which ; /* mask selecting subcomponents to populate */ unsigned int 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, which, xkb ) Display * display ; /* connection to X server */ unsigned int which ; /* mask selecting subcomponents to populate */ XkbDescPtr 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 ( dpy , which , xkb ) Display * dpy ; /* connection to X server */ unsigned int which ; /* mask selecting subcomponents to update */ XkbDescPtr 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] XkbVirtuawModsMask 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 ( dpy , xkb , changes ) Display * dpy ; /* connection to X server */ XkbDescPtr xkb ; /* description from which new values are taken */ XkbMapChangesPtr 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 in t 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 ( xkb, which, type_count ) XkbDescPtr xkb ; /* keyboard description in which to allocate client map */ unsigned int which ; /* mask selecting map components to allocate */ unsigned int 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 ( xkb, which, free_all ) XkbDescPtr xkb ; /* keyboard description containing client map to free */ unsigned int which ; /* mask identifying components of map to free */ Bool 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 ( xkb, which, count_acts ) XkbDescPtr xkb ; /* keyboard description in which to allocate server map */ unsigned int which ; /* mask selecting map components to allocate */ unsigned int 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 ( xkb, which, free_all ) XkbDescPtr xkb ; /* keyboard description containing server map to free */ unsigned int which ; /* mask identifying components of map to free */ Bool 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.