This document defines an extension to the AIXwindows protocol to support input devices other than the core X keyboard and pointer. An accompanying document defines a corresponding extension to Xlib (similar extensions for languages other than C are anticipated). This first section gives an overview of the input extension. The next section defines the new protocol requests defined by the extension. This document concludes with a description of the new input events generated by the additional input devices.
The design approach of the extension is to define requests and events analogous to the core requests and events. This allows extension input devices to be individually distinguished from each other and from the core input devices. These requests and events make use of a device identifier and support the reporting of n-dimensional motion data as well as other data that is not reportable by way of the core input events.
The X server core protocol supports two input devices: a pointer and a keyboard. The pointer device has two major functions. First, it may be used to generate motion information that client programs can detect. Second, it may also be used to indicate the current location and focus of the X keyboard. To accomplish this, the server echoes a cursor at the current position of the X pointer. Unless the X keyboard has been explicitly focused, this cursor also shows the current location and focus of the X keyboard.
The X keyboard is used to generate input that client programs can detect.
The X keyboard and X pointer are referred to in this document as the core devices, and the input events they generate (KeyPress, KeyRelease, ButtonPress, ButtonRelease, and MotionNotify) are known as the core input events. All other input devices are referred to as extension input devices and the input events they generate are referred to as extension input events.
Note: This input extension does not change the behavior or functionality of the core input devices, core events, or core protocol requests, with the exception of the core grab requests. These requests may affect the synchronization of events from extension devices. See the explanation in the section titled "Event Synchronization and Core Grabs" .
Selection of the physical devices to be initially used by the server as the core devices is left implementation dependent. Requests are defined that allow client programs to change which physical devices are used as the core devices.
The input extension controls access to input devices other than the X keyboard and X pointer. It allows client programs to select input from these devices independently from each other and independently from the core devices.
A client that wishes to access a specific device must first determine whether that device is connected to the X server. This is done through the ListInputDevices request, which will return a list of all devices that can be opened by the X server. A client can then open one or more of these devices using the OpenDevice request, specify what events they are interested in receiving, and receive and process input events from extension devices in the same way as events from the X keyboard and X pointer. Input events from these devices are of extension types (DeviceKeyPress, DeviceKeyRelease, DeviceButtonPress, DeviceButtonRelease, DeviceMotionNotify, and so on) and contain a device identifier so that events of the same type coming from different input devices can be distinguished.
Any kind of input device may be used as an extension input device. Extension input devices may have zero or more keys, zero or more buttons, and may report zero or more axes of motion. Motion may be reported as relative movements from a previous position or as an absolute position. All valuators reporting motion information for a given extension input device must report the same kind of motion information (absolute or relative).
This extension is designed to accommodate new types of input devices that may be added in the future. The protocol requests that refer to specific characteristics of input devices organize that information by input classes. Server implementors may add new classes of input devices without changing the protocol requests. Input classes are unique numbers registered with the X Consortium. Each extension input device may support multiple input classes.
All extension input devices are treated like the core X keyboard in determining their location and focus. The server does not track the location of these devices on an individual basis, and therefore does not echo a cursor to indicate their current location. Instead, their location is determined by the location of the core X pointer. Like the core X keyboard, some may be explicitly focused. If they are not explicitly focused, their focus is determined by the location of the core X pointer.
Input events reported by the server to a client are of fixed size (32 bytes). In order to represent the change in state of an input device the extension may need to generate a sequence of input events. A client side library (such as Xlib) will typically take these raw input events and format them into a form more convenient to the client.
In the core protocol a client registers interest in receiving certain input events directed to a window by modifying that window's event mask. Most of the bits in the event mask are already used to specify interest in core X events. The input extension specifies a different mechanism by which a client can express interest in events generated by this extension.
When a client opens a extension input device by way of the OpenDevice request, an XDevice structure is returned. Macros are provided that extract 32-bit numbers called event classes from that structure, that a client can use to register interest in extension events by way of the SelectExtensionEvent request. The event class combines the desired event type and device ID, and may be thought of as the equivalent of core event masks.
Some of the input extension requests divide input devices into classes based on their functionality. This is intended to allow new classes of input devices to be defined at a later time without changing the semantics of these requests. The following input device classes are currently defined:
|KEY||Reports key events.|
|BUTTON||Reports button events.|
|VALUATOR||Reports valuator data in motion events.|
|PROXIMITY||Reports proximity events.|
|FOCUS||Can be focused and reports focus events.|
|OTHER||The ChangeDeviceNotify, DeviceMappingNotify, and DeviceStateNotify macros may be invoked passing the XDevice structure returned for this device.|
Each extension input device may support multiple input classes. Additional classes may be added in the future. Requests that support multiple input classes, such as the ListInputDevices function that lists all available input devices, organize the data they return by input class. Client programs that use these requests should not access data unless it matches a class defined at the time those clients were compiled. In this way, new classes can be added without forcing existing clients that use these requests to be recompiled.
Extension input devices are accessed by client programs through the use of new protocol requests. This section summarizes the new requests defined by this extension. The syntax and type definitions used below follow the notation used for the X11 core protocol.
The GetExtensionVersion request returns version information about the input extension.
A client that wishes to access a specific device must first determine whether that device is connected to the X server. This is done through the ListInputDevices request, which returns a list of all devices that can be opened by the X server.
Client programs that wish to access an extension device must request that the server open that device. This is done by way of the OpenDevice request. Before it exits, the client program should explicitly request that the server close the device. This is done by way of the CloseDevice request.
A client may open the same extension device more than once. Requests after the first successful one return an additional XDevice structure with the same information as the first, but otherwise have no effect. A single CloseDevice request will terminate that client's access to the device.
Some devices are capable of reporting either relative or absolute motion data. The mode of a device is changed from relative to absolute using the SetDeviceMode request. The valid values are Absolute or Relative.
Some devices that report absolute positional data can be initialized to a starting value. Devices that are capable of reporting relative motion or absolute positional data may require that their valuators be initialized to a starting value after the mode of the device is changed to Absolute. The SetDeviceValuators request is used to initialize the valuators on such a device.
The GetDeviceControl request returns the current state of the specified device control. The device control must be supported by the target server and device or an error will result.
The ChangeDeviceControl request changes the specified device control according to the values specified in the DeviceControl structure. The device control must be supported by the target server and device or an error will result.
Extension input events are selected using the SelectExtensionEvent request.
The GetSelectedExtensionEvents is used to determine which extension events are currently selected from a given window.
Extension events propagate up the window hierarchy in the same manner as core events. If a window is not interested in an extension event, it usually propagates to the closest ancestor that is interested, unless the dont_propagate list prohibits it. Grabs of extension devices may alter the set of windows that receive a particular extension event.
Client programs may control extension event propagation through the use of the ChangeDeviceDontPropagateList and GetDeviceDontPropagateList requests.
The XChangeDeviceDontPropagateList function adds an event to or deletes an event from the do_not_propagate list of extension events for the specified window. This list is maintained for the life of the window, and is not altered if the client terminates.
One client program may send an event to another by way of the XSendExtensionEvent function. The event in the XEvent structure must be one of the events defined by the input extension, so that the X server can correctly byte swap the contents as necessary. The contents of the event are otherwise unaltered and unchecked by the X server except to force SendEvent to True in the forwarded event and to set the sequence number in the event correctly. XSendExtensionEvent returns 0 (zero) if the conversion-to-wire protocol failed, otherwise it returns nonzero.
The GetDeviceMotionEvents request returns all positions in the device's motion history buffer that fall between the specified start and stop times inclusive. If the start time is in the future, or is later than the stop time, no positions are returned.
These ChangePointerDevice and ChangeKeyboardDevice requests are provided to change which physical device is used as the X pointer or X keyboard.
Note: Using these requests may change the characteristics of the core devices. The new pointer device may have a different number of buttons than the old one did, or the new keyboard device may have a different number of keys or report a different range of keycodes. Client programs may be running that depend on those characteristics. For example, a client program could allocate an array based on the number of buttons on the pointer device, and then use the button numbers received in button events as indices into that array. Changing the core devices could cause such client programs to behave improperly or abnormally terminate.
These requests change the X keyboard or X pointer device and generate an ChangeDeviceNotify event and a MappingNotify event. The ChangeDeviceNotify event is sent only to those clients that have expressed an interest in receiving that event by way of the XSelectExtensionEvent request. The specified device becomes the new X keyboard or X pointer device. The location of the core device does not change as a result of this request.
These requests fail and return AlreadyGrabbed if either the specified device or the core device it would replace are grabbed by some other client. They fail and return GrabFrozen if either device is frozen by the active grab of another client.
These requests fail with a BadDevice error if the specified device is invalid, or has not previously been opened by way of OpenDevice.
The ChangeKeyboardDevice request changes the X keyboard device. The specified device must support input class Keys (as reported in the ListInputDevices request) or the request fails with a BadMatch error. Once the device has successfully replaced one of the core devices, it is treated as a core device until it is in turn replaced by another ChangeDevice request, or until the server terminates. The termination of the client that changed the device will not cause it to change back. Attempts to use the CloseDevice request to close the new core device will fail with a BadDevice error.
The ChangePointerDevice request changes the X pointer device. The specified device must support input class Valuators (as reported in the ListInputDevices request) or the request fails with a BadMatch error. The valuators to be used as the x and y axes of the pointer device must be specified. Data from other valuators on the device are ignored.
Implementation of the input extension requires an extension of the meaning of event synchronization for the core grab requests. This is necessary in order to allow window managers to freeze all input devices with a single request.
The core grab requests require a PointerMode and KeyboardMode argument. The meaning of these modes is changed by the input extension. For the XGrabPointer and XGrabButton requests, PointerMode controls synchronization of the pointer device, and KeyboardMode controls the synchronization of all other input devices. For the XGrabKeyboard and XGrabKey requests, PointerMode controls the synchronization of all input devices except the X keyboard, while KeyboardMode controls the synchronization of the keyboard. When using one of the core grab requests, the synchronization of extension devices is controlled by the mode specified for the device not being grabbed.
Active grabs of extension devices are supported by way of the GrabDevice request in the same way that core devices are grabbed using the core GrabKeyboard request, except that a Device is passed as a function parameter. A list of events that the client wishes to receive is also passed. The UngrabDevice request allows a previous active grab for an extension device to be released. To grab an extension device, use the GrabDevice request. The device must have previously been opened using the OpenDevice request.
Passive grabs of buttons and keys on extension devices are supported by way of the GrabDeviceButton and GrabDeviceKey requests. These passive grabs are released by way of the UngrabDeviceKey and UngrabDeviceButton requests. To passively grab a single key on an extension device, use GrabDeviceKey. That device must have previously been opened using the OpenDevice request.
The AllowDeviceEvents request allows further events to be processed when a device has been frozen.
The current focus window for an extension input device can be determined using the GetDeviceFocus request. Extension devices are focused using the SetDeviceFocus request in the same way that the keyboard is focused using the SetInputFocus request, except that a device is specified as part of the request. One additional focus state, FollowKeyboard, is provided for extension devices.
The GetFeedbackControl request gets the settings of feedbacks on an extension device. This request provides functionality equivalent to the core GetKeyboardControl and GetPointerControl functions. It also provides a way to control displays associated with an input device that are capable of displaying an integer or string. The ChangeFeedbackControl request changes the settings of a feedback on an extension device.
The DeviceBell request rings a bell on an extension input device. The ChangeFeedbackControl request changes the base volume of the bell.
The GetDeviceKeyMapping request gets the keyboard mapping of an extension device that has keys. The ChangeDeviceKeyMapping request changes the keyboard mapping of an extension device that has keys.
The GetDeviceModifierMapping request obtains the keycodes that are used as modifiers on an extension device that has keys. The SetDeviceModifierMapping request sets which keycodes are to be used as modifiers for an extension device.
The GetDeviceButtonMapping request and the SetDeviceButtonMapping request are analogous to the core GetPointerMapping and ChangePointerMapping requests. They allow a client to determine the current mapping of buttons on an extension device, and to change that mapping. To get the current button mapping for an extension device, use GetDeviceButtonMapping. The SetDeviceButtonMapping request sets the button mapping for an extension device.
The QueryDeviceState request obtains vectors that describe the state of the keys, buttons and valuators of an extension device.
The input extension creates input events analogous to the core input events. These extension input events are generated by manipulating one of the extension input devices.
The DeviceKeyPress, DeviceKeyRelease, DeviceButtonPress, DeviceButtonRelease, and DeviceMotionNotify events are generated when a key, button, or valuator logically changes state. The generation of these logical changes may lag the physical changes, if device event processing is frozen. Note that DeviceKeyPress and DeviceKeyRelease are generated for all keys, even those mapped to modifier bits.
DeviceValuator events are generated to contain valuator information for which there is insufficient space in DeviceKey, DeviceButton, DeviceMotion, and Proximity wire events. For events of these types, a second event of type DeviceValuator follows immediately. The library combines these events into a single event that a client can receive by way of XNextEvent. DeviceValuator events are not selected for by clients, they only exist to contain information that will not fit into some event selected by clients.
The DeviceFocusIn and DeviceFocusOut events are generated when the input focus changes and are reported to clients selecting DeviceFocusChange for the specified device and window. Events generated by SetDeviceFocus when the device is not grabbed have Mode Normal. Events generated by SetDeviceFocus when the device is grabbed have Mode WhileGrabbed. Events generated when a device grab actives have Mode Grab, and events generated when a device grab deactivates have Mode Ungrab. All DeviceFocusOut events caused by a window unmap are generated after any UnmapNotify event, but the ordering of DeviceFocusOut with respect to generated EnterNotify, LeaveNotify, VisibilityNotify and Expose events is not constrained. DeviceFocusIn and DeviceFocusOut events are generated for focus changes of extension devices in the same manner as focus events for the core devices are generated.
The DeviceStateNotify event reports the state of the device just as in the QueryDeviceState request. This event is reported to clients selecting DeviceStateNotify for the device and window and is generated immediately after every EnterNotify and DeviceFocusIn. If the device has no more than 32 buttons, no more than 32 keys, and no more than 3 valuators, this event can report the state of the device. If the device has more than 32 buttons, the event will be immediately followed by a DeviceButtonStateNotify event. If the device has more than 32 keys, the event will be followed by a DeviceKeyStateNotify event. If the device has more than 3 valuators, the event will be followed by one or more DeviceValuator events.
The DeviceKeyStateNotify and the DeviceButtonStateNotify events contain information about the state of keys and buttons on a device that will not fit into the DeviceStateNotify wire event. These events are not selected by clients, rather they may immediately follow a DeviceStateNotify wire event and be combined with it into a single DeviceStateNotify client event that a client may receive by way of XNextEvent.
The DeviceMappingNotify event reports a change in the mapping of keys, modifiers, or buttons on an extension device. This event is reported to clients selecting DeviceMappingNotify for the device and window and is generated after every client SetDeviceButtonMapping, ChangeDeviceKeyMapping, or ChangeDeviceModifierMapping request.
The ChangeDeviceNotify event reports a change in the physical device being used as the core X keyboard or X pointer device. ChangeDeviceNotify events are reported to clients selecting ChangeDeviceNotify for the device and window and is generated after every client ChangeKeyboardDevice or ChangePointerDevice request.
The ProximityIn and ProximityOut events are generated by some devices (such as graphics tablets or touch screens) to indicate that a stylus has moved into or out of contact with a positional sensing surface.