# Attaching Xkb Actions to X Input Extension Devices

The X input extension allows an X server to support multiple keyboards, as well as other input devices, in addition to the core X keyboard and pointer. The input extension categorizes devices by grouping them into classes. Keyboards and other input devices with keys are classified as KeyClass devices by the input extension. Other types of devices supported by the input extension include, but are not limited to: mice, tablets, touchscreens, barcode readers, button boxes, trackballs, identifier devices, data gloves, and eye trackers. Xkb provides additional control over all X input extension devices, whether they are KeyClass devices or not, as well as the core keyboard and pointer.

If an X server implements support for both the input extension and Xkb, the server implementor determines whether interaction between Xkb and the input extension is allowed. Implementors are free to restrict the effects of Xkb to only the core X keyboard device or allow interaction between Xkb and the input extension.

Several types of interaction between Xkb and the input extension are defined by Xkb. Some or all may be allowed by the X server implementation.

Regardless of whether the server allows interaction between Xkb and the input extension, the following access is provided:

- Xkb functionality for the core X keyboard device and its mapping is accessed via the functions described in the other chapters of this specification.

- Xkb functionality for the core X pointer device is accessed via the XkbGetDeviceInfo and XkbSetDeviceInfo functions described in this chapter.

If all types of interaction are allowed between Xkb and the input extension, the following additional access is provided:

- If allowed, Xkb functionality for additional KeyClass devices supported by the input extension is accessed via those same functions.

- If allowed, Xkb functionality for non- KeyClass devices supported by the input extension is also accessed via the XkbGetDeviceInfo and XkbSetDeviceInfo functions described in this chapter.

Each device has an X Input Extension device ID. Each device may have several classes of feedback. For example, there are two types of feedbacks that can generate bells: bell feedback and keyboard feedback ( BellFeedbackClass and KbdFeedbackClass ). A device can have more than one feedback of each type; the feedback ID identifies the particular feedback within its class.

A keyboard feedback has:

- Auto-repeat status (global and per key)

- 32 LEDs

- A bell

An indicator feedback has:

- Up to 32 LEDs

If the input extension is present and the server allows interaction between the input extension and Xkb, then the core keyboard, the core keyboard indicators, and the core keyboard bells may each be addressed using an appropriate device spec, class, and ID. The constant XkbXIDfltID may be used as the device ID to specify the core keyboard indicators for the core indicator feedback. The particular device ID corresponding to the core keyboard feedback and the core indicator feedback may be obtained by calling XkbGetDeviceInfo and specifying XkbUseCoreKbd as the device_spec ; the values will be returned in dflt_kbd_id and dflt_led_id .

If the server does not allow Xkb access to input extension KeyClass devices, attempts to use Xkb requests with those devices fail with a Bad Keyboard error. Attempts to access non- KeyClass input extension devices via XkbGetDeviceInfo and XkbSetDeviceInfo fail silently if Xkb access to those devices is not supported by the X server.

## XkbDeviceInfoRec

Information about X Input Extension devices is transferred between a client program and the Xkb extension in an XkbDeviceInfoRec structure:

    typedef struct {
          char *          name;          /* name for device */
          Atom            type;          /* name for class of devices */
          unsigned short  device_spec;   /* device of interest */
          Bool            has_own_state; /*  True =>this
                                            device has its own state */
          unsigned short  supported;     /* bits indicating supported capabilities */
          unsigned short  unsupported;   /* bits indicating unsupported capabilities */
          unsigned short  num_btns;      /* number of entries in  btn_acts */
          XkbAction *     btn_acts;      /* button actions */
          unsigned short  sz_leds;       /* total number of entries in LEDs vector */
          unsigned short  num_leds;      /* number of valid entries in LEDs vector */
          unsigned short  dflt_kbd_fb;   /* input extension ID of default (core kbd) indicator */
          unsigned short  dflt_led_fb;   /* input extension ID of default indicator feedback */
          XkbDeviceLedInfoPtr  leds;     /* LED descriptions */
    } XkbDeviceInfoRec, *XkbDeviceInfoPtr;

    typedef struct {
          unsigned short   led_class;         /* class for this LED device*/
          unsigned short   led_id;            /* ID for this LED device */
          unsigned int     phys_indicators;   /* bits for which LEDs physically
                                                 present */
          unsigned int     maps_present;      /* bits for which LEDs have maps in
                                                 maps */
          unsigned int     names_present;     /* bits for which LEDs are in
                                                  names */
          unsigned int     state;            /* 1 bit => corresponding LED is on */
          Atom             names[XkbNumIndicators];  /* names for LEDs */
          XkbIndicatorMapRec  maps;          /* indicator maps for each LED */
    } XkbDeviceLedInfoRec, *XkbDeviceLedInfoPtr;

The type field is a registered symbolic name for a class of devices (for example, "TABLET"). If a device is a keyboard (that is, is a member of KeyClass ), it has its own state, and has_own_state is True . If has_own_state is False , the state of the core keyboard is used. The supported and unsupported fields are masks where each bit indicates a capability. The meaning of the mask bits is listed in Table 21.1, together with the fields in the XkbDeviceInfoRec structure that are associated with the capability represented by each bit. The same bits are used to indicate the specific information desired in many of the functions described subsequently in this section.

### XkbDeviceInfoRec Mask Bits

Name | XkbDeviceInfoRec Fields Effected | Value | Capability If Set
--- | --- | --- | ---
XkbXI_KeyboardsMask |  | (1L << 0) | Clients can use all Xkb requests and events with KeyClass devices supported by the input device extension.
XkbXI_ButtonActionsMask | num_btns btn_acts | (1L <<1) | Clients can assign key actions to buttons on non- KeyClass input extension devices.
XkbXI_IndicatorNamesMask | leds->names | (1L <<2) | Clients can assign names to indicators on non- KeyClass input extension devices.
XkbXI_IndicatorMapsMask | leds->maps | (1L <<3) | Clients can assign indicator maps to indicators on non- KeyClass input extension devices.
XkbXI_IndicatorStateMask | leds->state | (1L <<4) | Clients can request the status of indicators on non- KeyClass input extension devices.
XkbXI_IndicatorsMask | sz_leds num_leds leds->* | (0x1c) | XkbXI_IndicatorNamesMask | XkbXI_IndicatorMapsMask | XkbXI_IndicatorStateMask
XkbXI_UnsupportedFeaturesMask | unsupported | (1L <<15) |
XkbXI_AllDeviceFeaturesMask | Those selected by Value column masks | (0x1e) | XkbXI_IndicatorsMask | XkbSI_ButtonActionsMask
XkbXI_AllFeaturesMask | Those selected by Value column masks | (0x1f) | XkbSI_AllDeviceFeaturesMask | XkbSI_KeyboardsMask
XkbXI_AllDetailsMask | Those selected by Value column masks | (0x801f) | XkbXI_AllFeaturesMask | XkbXI_UnsupportedFeaturesMask

The name , type , has_own_state , supported , and unsupported fields are always filled in when a valid reply is returned from the server involving an XkbDeviceInfoRec . All of the other fields are modified only if the particular function asks for them.

## Querying Xkb Features for Non-KeyClass Input Extension Devices

To determine whether the X server allows Xkb access to particular capabilities of input devices other than the core X keyboard, or to determine the status of indicator maps, indicator names or button actions on a non- KeyClass extension device, use XkbGetDeviceInfo.

XkbDeviceInfoPtr XkbGetDeviceInfo ( dpy , which, device_spec, ind_class, ind_id)
Display * dpy ; /* connection to X server */
unsigned int which; /* mask indicating information to return */
unsigned int device_spec ; /* device ID, or XkbUseCoreKbd */
unsigned int ind_class ; /* feedback class for indicator requests */
unsigned int ind_id ; /* feedback ID for indicator requests */

XkbGetDeviceInfo returns information about the input device specified by device_spec . Unlike the device_spec parameter of most Xkb functions, device_spec does not need to be a keyboard device. It must, however, indicate either the core keyboard or a valid X Input Extension device.

The which parameter is a mask specifying optional information to be returned. It is an inclusive OR of one or more of the values from Table 21.1 and causes the returned XkbDeviceInfoRec to contain values for the corresponding fields specified in the table.

The XkbDeviceInfoRec returned by XkbGetDeviceInfo always has values for name (may be a null string, ""), type , supported , unsupported , has_own_state , dflt_kbd_fd , and dflt_kbd_fb . Other fields are filled in as specified by which .

Upon return, the supported field will be set to the inclusive OR of zero or more bits from Table 21.1; each bit set indicates an optional Xkb extension device feature supported by the server implementation, and a client may modify the associated behavior.

If the XkbButtonActionsMask bit is set in which , the XkbDeviceInfoRec returned will have the button actions ( btn_acts field) filled in for all buttons.

If which includes one of the bits in XkbXI_IndicatorsMask, the feedback class of the indicators must be specified in ind_class, and the feedback ID of the indicators must be specified in ind_id. If the request does not include any of the bits in XkbXI_IndicatorsMask, the ind_class and ind_id parameters are ignored. The class and ID can be obtained via the input device extension XListInputDevices request.

If any of the XkbXI_IndicatorsMask bits are set in which , the XkbDeviceInfoRec returned will have filled in the portions of the leds structure corresponding to the indicator feedback identified by ind_class and ind_id . The leds vector of the XkbDeviceInfoRec is allocated if necessary and sz_leds and num_leds filled in. The led_class , led_id and phys_indicators fields of the leds entry corresponding to ind_class and ind_id are always filled in. If which contains XkbXI_IndicatorNamesMask , the names_present and names fields of the leds structure corresponding to ind_class and ind_id are returned. If which contains XkbXI_IndicatorStateMask , the corresponding state field is updated. If which contains XkbXI_IndicatorMapsMask , the maps_present and maps fields are updated.

Xkb provides convenience functions to request subsets of the information available via XkbGetDeviceInfo . These convenience functions mirror some of the mask bits. The functions all take an XkbDeviceInfoPtr as an input argument and operate on the X Input Extension device specified by the device_spec field of the structure. Only the parts of the structure indicated in the function description are updated. The XkbDeviceInfo Rec structure used in the function call can be obtained by calling XkbGetDeviceInfo or can be allocated by calling XkbAllocDeviceInfo (see section 21.3).

These convenience functions are described as follows.

To query the button actions associated with an X Input Extension device, use XkbGetDeviceButtonActions.

Status XkbGetDeviceButtonActions ( dpy, device_info, all_buttons, first_button, num_buttons )
Display * dpy ; /* connection to X server */
XkbDeviceInfoPtr device_info; /* structure to update with results */
Bool all_buttons ; /* True => get information for all buttons */
unsigned int first_button; /* number of first button for which info is desired */
unsigned int num_buttons; /* number of buttons for which info is desired */

XkbGetDeviceButtonActions queries the server for the desired button information for the device indicated by the device_spec field of device_info and waits for a reply. If successful, XkbGetDeviceButtonActions backfills the button actions ( btn_acts field of device_info ) for only the requested buttons, updates the name , type , supported , and unsupported fields, and returns Success .

all_buttons , first_button and num_buttons specify the device buttons for which actions should be returned. Setting all_buttons to True requests actions for all device buttons; if all_buttons is False , first_button and num_buttons specify a range of buttons for which actions are requested.

If a compatible version of Xkb is not available in the server or the Xkb extension has not been properly initialized, XkbGetDeviceButtonActions returns BadAccess . If allocation errors occur, a BadAlloc status is returned. If the specified device ( device_info -> device_spec ) is invalid, a BadKeyboard status is returned. If the device has no buttons, a Bad Match status is returned. If first_button and num_buttons specify illegal buttons, a Bad Value status is returned.

To query the indicator names, maps, and state associated with an LED feedback of an input extension device, use XkbGetDeviceLedInfo.

Status XkbGetDeviceLedInfo ( dpy, device_i nfo, led_class, led_id, which)
Display * dpy ; /* connection to X server */
XkbDeviceInfoPtr device_info; /* structure to update with results */
unsigned int led_class ; /* LED feedback class assigned by input extension */
unsigned int led_id; /* LED feedback ID assigned by input extension */
unsigned int which; /* mask indicating desired information */

XkbGetDeviceLedInfo queries the server for the desired LED information for the feedback specified by led_class and led_id for the X input extension device indicated by device_spec -> device_info and waits for a reply. If successful, XkbGetDeviceLedInfo backfills the relevant fields of device_info as determined by which with the results and returns Success . Valid values for which are the inclusive OR of any of XkbXI_IndicatorNamesMask , XkbXI_IndicatorMapsMask , and XkbXI_IndicatorStateMask .

The fields of device_info that are filled in when this request succeeds are name, type, supported , and unsupported , and portions of the leds structure corresponding to led_class and led_id as indicated by the bits set in which . The device_info->leds vector is allocated if necessary and sz_leds and num_leds filled in. The led_class , led_id and phys_indicators fields of the device_info -> leds entry corresponding to led_class and led_id are always filled in.

If which contains XkbXI_IndicatorNamesMask , the names_present and names fields of the device_info -> leds structure corresponding to led_class and led_id are updated, if which contains XkbXI_IndicatorStateMask , the corresponding state field is updated, and if which contains XkbXI_IndicatorMapsMask , the maps_present and maps fields are updated.

If a compatible version of Xkb is not available in the server or the Xkb extension has not been properly initialized, XkbGetDeviceLedInfo returns BadAccess . If allocation errors occur, a BadAlloc status is returned. If the device has no indicators, a BadMatch error is returned. If ledClass or ledID have illegal values, a Bad Value error is returned. If they have legal values but do not specify a feedback that contains LEDs and is associated with the specified device, a Bad Match error is returned.

## Allocating, Initializing, and Freeing the XkbDeviceInfoRec Structure

To obtain an XkbDeviceInfoRec structure, use XkbGetDeviceInfo or XkbAllocDeviceInfo.

XkbDeviceInfoPtr XkbAllocDeviceInfo (device_spec, n_buttons, sz_leds)
unsigned int device_spec; /* device ID with which structure will be used */
unsigned int n_buttons ; /* number of button actions to allocate space for*/
unsigned int sz_leds ; /* number of LED feedbacks to allocate space for */

XkbAllocDeviceInfo allocates space for an XkbDeviceInfoRec structure and initializes that structure’s device_spec field with the device ID specified by device_spec. If n_buttons is nonzero, n_buttons XkbActions are linked into the XkbDeviceInfoRec structure and initialized to zero. If sz_leds is nonzero, sz_leds XkbDeviceLedInfoRec structures are also allocated and linked into the XkbDeviceInfoRec structure. If you request XkbDeviceLedInfoRec structures be allocated using this request, you must initialize them explicitly.

To obtain an XkbDeviceLedInfoRec structure, use XkbAllocDeviceLedInfo.

Status XkbAllocDeviceLedInfo (devi, num_needed)
XkbDeviceInfoPtr device_info ; /* structure in which to allocate LED space */
int num_needed ; /* number of indicators to allocate space for */

XkbAllocDeviceLedInfo allocates space for an XkbDeviceLedInfoRec and places it in device_info . If num_needed is nonzero, num_needed XkbIndicatorMapRec structures are also allocated and linked into the XkbDeviceLedInfoRec structure. If you request XkbIndicatorMapRec structures be allocated using this request, you must initialize them explicitly. All other fields are initialized to zero.

To initialize an XkbDeviceLedInfoRec structure, use XkbAddDeviceLedInfo.

XkbDeviceLedInfoPtr XkbAddDeviceLedInfo (device_info, led_class, led_id)
XkbDeviceInfoPtr device_info; /* structure in which to add LED info */
unsigned int led_class ; /* input extension class for LED device of interest */
unsigned int led_id ; /* input extension ID for LED device of interest */

XkbAddDeviceLedInfo first checks to see whether an entry matching led_class and led_id already exists in the device_info->leds array. If it finds a matching entry, it returns a pointer to that entry. Otherwise, it checks to be sure there is at least one empty entry in device_info -> leds and extends it if there is not enough room. It then increments device_info -> num_leds and fills in the next available entry in device_info -> leds with led_class and led_id .

If successful, XkbAddDeviceLedInfo returns a pointer to the XkbDeviceLedInfoRec structure that was initialized. If unable to allocate sufficient storage, or if device_info points to an invalid XkbDeviceInfoRec structure, or if led_class or led_id are inappropriate, XkbAddDeviceLedInfo returns NULL .

To allocate additional space for button actions in an XkbDeviceInfoRec structure, use XkbResizeDeviceButtonActions.

Status XkbResizeDeviceButtonActions (device_info, new_total)
XkbDeviceInfoPtr device_info; /* structure in which to allocate button actions */
unsigned int new_total ; /* new total number of button actions needed */

XkbResizeDeviceButton reallocates space, if necessary, to make sure there is room for a total of new_total button actions in the device_info structure. Any new entries allocated are zeroed. If successful, XkbResizeDeviceButton returns Success. If new_total is zero, all button actions are deleted, device_info -> num_btns is set to zero, and device_info -> btn_acts is set to NULL . If device_info is invalid or new_total is greater than 255, BadValue is returned. If a memory allocation failure occurs, a BadAlloc is returned.

To free an XkbDeviceInfoRec structure, use XkbFreeDeviceInfo.

void XkbFreeDeviceInfo (device_info, which, free_all)
XkbDeviceInfoPtr device_info; /* pointer to XkbDeviceInfoRec in which to free items */
unsigned int which ; /* mask of components of device_info to free */
Bool free_all ; /* True => free everything, including device_info */

If free_all is True , the XkbFreeDeviceInfo frees all components of device_info and the XkbDeviceInfoRec structure pointed to by device_info itself. If free_all is False , the value of which determines which subcomponents are freed. which is an inclusive OR of one or more of the values from Table 21.1. If which contains XkbXI_ButtonActionsMask, all button actions associated with device_info are freed, device_info -> btn_acts is set to NULL , and device_info -> num_btns is set to zero. If which contains all bits in XkbXI_IndicatorsMask, all XkbDeviceLedInfoRec structures associated with device_info are freed, device_info -> leds is set to NULL , and device_info -> sz_leds and device_info -> num_leds are set to zero. If which contains XkbXI_IndicatorMapsMask, all indicator maps associated with device_info are cleared, but the number of LEDs and the leds structures themselves are preserved. If which contains XkbXI_IndicatorNamesMask, all indicator names associated with device_info are cleared, but the number of LEDs and the leds structures themselves are preserved. If which contains XkbXI_IndicatorStateMask, the indicator state associated with the device_info leds are set to zeros but the number of LEDs and the leds structures themselves are preserved.

## Setting Xkb Features for Non-KeyClass Input Extension Devices

The Xkb extension allows clients to assign any key action to either core pointer or input extension device buttons. This makes it possible to control the keyboard or generate keyboard key events from extension devices or from the core pointer.

Key actions assigned to core X pointer buttons or input extension device buttons cause key events to be generated as if they had originated from the core X keyboard.

Xkb implementations are required to support key actions for the buttons of the core pointer device, but support for actions on extension devices is optional. Implementations that do not support button actions for extension devices must not set the XkbXI_ButtonActionsMask bit in the supported field of an XkbDeviceInfoRec structure.

If a client attempts to modify valid characteristics of a device using an implementation that does not support modification of those characteristics, no protocol error is generated. Instead, the server reports a failure for the request; it also sends an XkbExtensionDeviceNotify event to the client that issued the request if the client has selected to receive these events.

To change characteristics of an X Input Extension device in the server, first modify a local copy of the device structure and then use either XkbSetDeviceInfo, or, to save network traffic, use an XkbDeviceChangesRec structure (see section 21.6) and call XkbChangeDeviceInfo to download the changes to the server.

To modify some or all of the characteristics of an X Input Extension device, use XkbSetDeviceInfo.

Bool XkbSetDeviceInfo ( dpy , which, device_info)
Display * dpy ; /* connection to X server */
unsigned int which ; /* mask indicating characteristics to modify */
XkbDeviceInfoPtr device_info; /* structure defining the device and modifications */

XkbSetDeviceInfo sends a request to the server to modify the characteristics of the device specified in the device_info structure. The particular characteristics modified are identified by the bits set in which and take their values from the relevant fields in device_info (see Table 21.1). XkbSetDeviceInfo returns True if the request was successfully sent to the server. If the X server implementation does not allow interaction between the X input extension and the Xkb Extension, the function does nothing and returns False .

The which parameter specifies which aspects of the device should be changed and is a bitmask composed of an inclusive OR or one or more of the following bits: XkbXI_ButtonActionsMask , XkbXI_IndicatorNamesMask , XkbXI_IndicatorMapsMask . If the features requested to be manipulated in which are valid for the device, but the server does not support assignment of one or more of them, that particular portion of the request is ignored.

If the device specified in device_info -> device_spec does not contain buttons and a request affecting buttons is made, or the device does not contain indicators and a request affecting indicators is made, a BadMatch protocol error results.

If the XkbXI_ButtonActionsMask bit is set in the supported mask returned by XkbGetDeviceInfo, the Xkb extension allows applications to assign key actions to buttons on input extension devices other than the core keyboard device. If the XkbXI_ButtonActionsMask is set in which , the actions for all buttons specified in device_info are set to the XkbAction s specified in device_info -> btn_acts . If the number of buttons requested to be updated is not valid for the device, XkbSetDeviceInfo returns False and a BadValue protocol error results.

If the XkbXI_IndicatorMaps and / or XkbXI_IndicatorNamesMask bit is set in the supported mask returned by XkbGetDeviceInfo, the Xkb extension allows applications to assign maps and / or names to the indicators of nonkeyboard extension devices. If supported, maps and / or names can be assigned to all extension device indicators, whether they are part of a keyboard feedback or part of an indicator feedback.

If the XkbXI_IndicatorMapsMask and / or XkbXI_IndicatorNamesMask flag is set in which , the indicator maps and / or names for all device_info -> num_leds indicator devices specified in device_info -> leds are set to the maps and / or names specified in device_info -> leds . device_info -> leds -> led_class and led_id specify the input extension class and device ID for each indicator device to modify; if they have invalid values, a BadValue protocol error results and XkbSetDeviceInfo returns False . If they have legal values but do not specify a keyboard or indicator class feedback for the device in question, a BadMatch error results. If any of the values in device_info -> leds -> names are not a valid Atom or None , a BadAtom protocol error results.

Xkb provides convenience functions to modify subsets of the information accessible via XkbSetDeviceInfo . Only the parts of the structure indicated in the function description are modified. These convenience functions are described as follows.

To change only the button actions for an input extension device, use XkbSetDeviceButtonActions.

Bool XkbSetDeviceButtonActions ( dpy , device, first_button, num_buttons, actions)
Display * dpy ; /* connection to X server */
XkbDeviceInfoPtr device_info; /* structure defining the device and modifications */
unsigned int first_button; /* number of first button to update, 0 relative */
unsigned int num_buttons; /* number of buttons to update */

XkbSetDeviceButtonActions assigns actions to the buttons of the device specified in device_info-> device_spec . Actions are assigned to num_buttons buttons beginning with first_button and are taken from the actions specified in device_info -> btn_acts .

If the server does not support assignment of Xkb actions to extension device buttons, XkbSetDeviceButtonActions has no effect and returns False . If the device has no buttons or if first_button or num_buttons specify buttons outside of the valid range as determined by device_info -> num_btns , the function has no effect and returns False . Otherwise, XkbSetDeviceButtonActions sends a request to the server to change the actions for the specified buttons and returns True .

If the actual request sent to the server involved illegal button numbers, a BadValue protocol error is generated. If an invalid device identifier is specified in device_info-> device_spec , a BadKeyboard protocol error results. If the actual device specified in device_info -> device_spec does not contain buttons and a request affecting buttons is made, a BadMatch protocol error is generated.

## XkbExtensionDeviceNotify Event

The Xkb extension generates XkbExtensionDeviceNotify events when the status of an input extension device changes or when an attempt is made to use an Xkb feature that is not supported by a particular device.

Events indicating an attempt to use an unsupported feature are delivered only to the client requesting the event.

To track changes to the status of input extension devices or attempts to use unsupported features of a device, select to receive XkbExtensionDeviceNotify events by calling either XkbSelectEvents or XkbSelectEventDetails (see section 4.3).

To receive XkbExtensionDeviceNotify events under all possible conditions, call XkbSelectEvents and pass XkbExtensionDeviceNotifyMask in both bits_to_change and values_for_bits .

The XkbExtensionDeviceNotify event has no event details. However, you can call XkbSelectEventDetails using XkbExtensionDeviceNotify as the event_type and specifying XkbAllExtensionDeviceMask in bits_to_change and values_for_bits. This has the same effect as a call to XkbSelectEvents .

The structure for XkbExtensionDeviceNotify 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;  /* XkbExtensionDeviceNotifyEvent */
          int      device;         /* Xkb device ID, will not be
                                      XkbUseCoreKbd */
          unsigned int   reason;   /* reason for the event */
          unsigned int   supported;  /* mask of supported features */
          unsigned int   unsupported;  /* unsupported features this client
                                          attempted to use */
          int      first_btn;      /* first button that changed */
          int      num_btns;       /* number of buttons that changed */
          unsigned int   leds_defined;  /* indicators with names or maps */
          unsigned int       led_state; /* current state of the indicators */
          int       led_class;          /* feedback class for LED changes */
          int       led_id;             /* feedback ID for LED changes */
    } XkbExtensionDeviceNotifyEvent;

The XkbExtensionDeviceNotify event has fields enabling it to report changes in the state (on/off) of all of the buttons for a device, but only for one LED feedback associated with a device. You will get multiple events when more than one LED feedback changes state or configuration.

## Tracking Changes to Extension Devices

Changes to an Xkb extension device may be tracked by listening to XkbDeviceExtensionNotify events and accumulating the changes in an XkbDeviceChangesRec structure. The changes noted in the structure may then be used in subsequent operations to update either a server configuration or a local copy of an Xkb extension device configuration. The changes structure is defined as follows:

    typedef struct _XkbDeviceChanges {
          unsigned int    changed;   /* bits indicating what has changed */
          unsigned short  first_btn; /* number of first button which changed,
                                        if any */
          unsigned short  num_btns;  /* number of buttons that have changed */
          XkbDeviceLedChangesRec leds;
    } XkbDeviceChangesRec,*XkbDeviceChangesPtr;

    typedef struct _XkbDeviceLedChanges {
          unsigned short  led_class; /* class of this indicator feedback bundle */
          unsigned short  led_id;    /* ID of this indicator feedback bundle */
          unsigned int    names;     /* bits indicating which names have changed */
          unsigned int    maps;      /* bits indicating which maps have changed */
          struct _XkbDeviceLedChanges *next; /* link to indicator change record
                                                for next set */
    } XkbDeviceLedChangesRec,*XkbDeviceLedChangesPtr;

A local description of the configuration and state of a device may be kept in an XkbDeviceInfoRec structure. The actual state or configuration of the device may change because of XkbSetDeviceInfo and XkbSetButtonActions requests made by clients or by user interaction with the device. The X server sends an XkbExtensionDeviceNotify event to all interested clients when the state of any buttons or indicators or the configuration of the buttons or indicators on the core keyboard or any input extension device changes. The event reports the state of indicators for a single indicator feedback, and the state of up to 128 buttons. If more than 128 buttons or more than one indicator feedback are changed, the additional buttons and indicator feedbacks are reported in subsequent events. Xkb provides functions with which you can track changes to input extension devices by noting the changes that were made and then requesting the changed information from the server.

To note device changes reported in an XkbExtensionDeviceNotify event, use XkbNoteDeviceChanges.

void XkbNoteDeviceChanges ( old, new, wanted )
XkbDeviceChangesPtr old ; /* structure tracking state changes */
XkbExtensionDeviceNotifyEvent * new ; /* event indicating state changes */
unsigned int wanted ; /* mask indicating changes to note */

The wanted field specifies the changes that should be noted in old , and is composed of the bitwise inclusive OR of one or more of the masks from Table 21.1 . The reason field of the event in new indicates the types of changes the event is reporting. XkbNoteDeviceChanges updates the XkbDeviceChangesRec specified by old with the changes that are both specified in wanted and contained in new -> reason .

To update a local copy of the state and configuration of an X input extension device with the changes previously noted in an XkbDeviceChangesRec structure, use XkbGetDeviceInfoChanges.

To query the changes that have occurred in the button actions or indicator names and indicator maps associated with an input extension device, use XkbGetDeviceInfoChanges.

Status XkbGetDeviceInfoChanges ( dpy , device_info , changes)
Display * dpy ; /* connection to X server */
XkbDeviceInfoPtr device_info; /* structure to update with results */
XkbDeviceChangesPtr changes ; /* contains notes of changes that have occurred */

The changes->changed field indicates which attributes of the device specified in changes -> device have changed. The parameters describing the changes are contained in the other fields of changes . XkbGetDeviceInfoChanges uses that information to call XkbGetDeviceInfo to obtain the current status of those attributes that have changed. It then updates the local description of the device in device_info with the new information.

To update the server’s description of a device with the changes noted in an XkbDeviceChangesRec, use XkbChangeDeviceInfo.

Bool XkbChangeDeviceInfo ( dpy, device_info, changes )
Display * dpy ; /* connection to X server */
XkbDeviceInfoPtr device_info ; /* local copy of device state and configuration */
XkbDeviceChangesPtr changes ; /* note specifying changes in device_info */

XkbChangeDeviceInfo updates the server’s description of the device specified in device_info -> device_spec with the changes specified in changes and contained in device_info . The update is made by an XkbSetDeviceInfo request.