1.1. Input Extension OverviewThis document defines an extension to the X11 protocol tosupport input devices other than the core X keyboard andpointer. An accompanying document defines a correspondingextension to Xlib (similar extensions for languages otherthan C are anticipated). This first section gives anoverview of the input extension. The next section definesthe new protocol requests defined by the extension. Weconclude with a description of the new input eventsgenerated by the additional input devices.1.2. Design ApproachThe design approach of the extension is to define requestsand events analogous to the core requests and events. Thisallows extension input devices to be individuallydistinguishable from each other and from the core inputdevices. These requests and events make use of a deviceidentifier and support the reporting of n-dimensional motiondata as well as other data that is not reportable via thecore input events.1.3. Core Input DevicesThe X server core protocol supports two input devices: apointer and a keyboard. The pointer device has two majorfunctions. First, it may be used to generate motioninformation that client programs can detect. Second, it mayalso be used to indicate the current location and focus ofthe X keyboard. To accomplish this, the server echoes acursor at the current position of the X pointer. Unless theX keyboard has been explicitly focused, this cursor alsoshows the current location and focus of the X keyboard.The X keyboard is used to generate input that clientprograms can detect.The X keyboard and X pointer are referred to in thisdocument as the core devices, and the input events theygenerate (KeyPress, KeyRelease, ButtonPress, ButtonRelease,and MotionNotify) are known as the core input events. Allother input devices are referred to as extension inputdevices and the input events they generate are referred toas extension input events. NoteThis input extension does not change the behavioror functionality of the core input devices, coreevents, or core protocol requests, with theexception of the core grab requests. Theserequests may affect the synchronization of eventsfrom extension devices. See the explanation inthe section titled "Event Synchronization and CoreGrabs".Selection of the physical devices to be initially used bythe server as the core devices is leftimplementation-dependent. Requests are defined that allowclient programs to change which physical devices are used asthe core devices.1.4. Extension Input DevicesThe input extension controls access to input devices otherthan the X keyboard and X pointer. It allows clientprograms to select input from these devices independentlyfrom each other and independently from the core devices.A client that wishes to access a specific device must firstdetermine whether that device is connected to the X server.This is done through the ListInputDevices request, whichwill return a list of all devices that can be opened by theX server. A client can then open one or more of thesedevices using the OpenDevice request, specify what eventsthey are interested in receiving, and receive and processinput events from extension devices in the same way asevents from the X keyboard and X pointer. Input events fromthese devices are of extension types (DeviceKeyPress,DeviceKeyRelease, DeviceButtonPress, DeviceButtonRelease,DeviceMotionNotify, etc.) and contain a device identifier sothat events of the same type coming from different inputdevices can be distinguished.Any kind of input device may be used as an extension inputdevice. Extension input devices may have 0 or more keys, 0or more buttons, and may report 0 or more axes of motion.Motion may be reported as relative movements from a previousposition or as an absolute position. All valuatorsreporting motion information for a given extension inputdevice must report the same kind of motion information(absolute or relative).This extension is designed to accommodate new types of inputdevices that may be added in the future. The protocolrequests that refer to specific characteristics of inputdevices organize that information by input classes. Serverimplementors may add new classes of input devices withoutchanging the protocol requests. Input classes are uniquenumbers registered with the X Consortium. Each extensioninput device may support multiple input classes.All extension input devices are treated like the core Xkeyboard in determining their location and focus. Theserver does not track the location of these devices on anindividual basis, and therefore does not echo a cursor toindicate their current location. Instead, their location isdetermined by the location of the core X pointer. Like thecore X keyboard, some may be explicitly focused. If they arenot explicitly focused, their focus is determined by thelocation of the core X pointer.Input events reported by the server to a client are of fixedsize (32 bytes). In order to represent the change in stateof an input device the extension may need to generate asequence of input events. A client side library (such asXlib) will typically take these raw input events and formatthem into a form more convenient to the client.1.4.1. Event ClassesIn the core protocol a client registers interest inreceiving certain input events directed to a window bymodifying that window’s event-mask. Most of the bits in theevent mask are already used to specify interest in core Xevents. The input extension specifies a different mechanismby which a client can express interest in events generatedby this extension.When a client opens a extension input device via theOpenDevice request, an XDevice structure is returned.Macros are provided that extract 32-bit numbers called eventclasses from that structure, that a client can use toregister interest in extension events via theSelectExtensionEvent request. The event class combines thedesired event type and device id, and may be thought of asthe equivalent of core event masks.1.4.2. Input ClassesSome of the input extension requests divide input devicesinto classes based on their functionality. This is intendedto allow new classes of input devices to be defined at alater time without changing the semantics of these requests.The following input device classes are currently defined:KEY The device reports key events.BUTTONThe device reports button events.VALUATORThe device reports valuator data in motion events.PROXIMITYThe device reports proximity events.FOCUSThe device can be focused and reports focusevents.FEEDBACKThe device supports feedbacks.OTHERThe ChangeDeviceNotify, DeviceMappingNotify, andDeviceStateNotify macros may be invoked passingthe XDevice structure returned for this device.Each extension input device may support multiple inputclasses. Additional classes may be added in the future.Requests that support multiple input classes, such as theListInputDevices function that lists all available inputdevices, organize the data they return by input class.Client programs that use these requests should not accessdata unless it matches a class defined at the time thoseclients were compiled. In this way, new classes can beadded without forcing existing clients that use theserequests to be recompiled.2. RequestsExtension input devices are accessed by client programsthrough the use of new protocol requests. This sectionsummarizes the new requests defined by this extension. Thesyntax and type definitions used below follow the notationused for the X11 core protocol.2.1. Getting the Extension VersionThe GetExtensionVersion request returns version informationabout the input extension.GetExtensionVersionname: STRING=> present: BOOLprotocol-major-version: CARD16protocol-minor-version: CARD16The protocol version numbers returned indicate theversion of the input extension supported by the targetX server. The version numbers can be compared toconstants defined in the header file XI.h. Eachversion is a superset of the previous versions.2.2. Listing Available DevicesA client that wishes to access a specific device must firstdetermine whether that device is connected to the X server.This is done through the ListInputDevices request, whichwill return a list of all devices that can be opened by theX server.ListInputDevices=> input-devices: LISTofDEVICEINFOwhere                   Errors: NoneThis request returns a list of all devices that can beopened by the X server, including the core X keyboard and Xpointer. Some implementations may open all input devices aspart of X initialization, while others may not open an inputdevice until requested to do so by a client program.• The information returned for each device is as follows:The type field is of type Atom and indicates the nature ofthe device. Clients may determine device types by invokingthe XInternAtom request passing one of the names defined inthe header file XI.h. The following names have been definedto date:MOUSETABLETKEYBOARDTOUCHSCREENTOUCHPADBUTTONBOXBARCODEKNOB_BOXTRACKBALLQUADRATURESPACEBALLDATAGLOVEEYETRACKERCURSORKEYSFOOTMOUSEID_MODULEONE_KNOBNINE_KNOBThe id is a small cardinal value in the range 0-128 thatuniquely identifies the device. It is assigned to thedevice when it is initialized by the server. Someimplementations may not open an input device until requestedby a client program, and may close the device when the lastclient accessing it requests that it be closed. If a deviceis opened by a client program via XOpenDevice, then closedvia XCloseDevice, then opened again, it is not guaranteed tohave the same id after the second open request.The num_classes field is a small cardinal value in the range0-255 that specifies the number of input classes supportedby the device for which information is returned byListInputDevices. Some input classes, such as class Focusand class Proximity do not have any information to bereturned by ListInputDevices.The use field specifies how the device is currently beingused. If the value is IsXKeyboard, the device is currentlybeing used as the X keyboard. If the value is IsXPointer,the device is currently being used as the X pointer. If thevalue is IsXExtensionDevice, the device is available for useas an extension device.The name field contains a pointer to a null-terminatedstring that corresponds to one of the defined device types.• InputInfo is one of: KeyInfo, ButtonInfo or ValuatorInfo.The first two fields are common to all three:The class field is a cardinal value in the range 0-255. Ituniquely identifies the class of input for which informationis returned.The length field is a cardinal value in the range 0-255. Itspecifies the number of bytes of data that are contained inthis input class. The length includes the class and lengthfields.The remaining information returned for input class KEYCLASSis as follows:min_keycode is of type KEYCODE. It specifies the minimumkeycode that the device will report. The minimum keycodewill not be smaller than 8.max_keycode is of type KEYCODE. It specifies the maximumkeycode that the device will report. The maximum keycodewill not be larger than 255.num_keys is a cardinal value that specifies the number ofkeys that the device has.The remaining information returned for input classBUTTONCLASS is as follows:num_buttons is a cardinal value that specifies the number ofbuttons that the device has.The remaining information returned for input classVALUATORCLASS is as follows:mode is a constant that has one of the following values:Absolute or Relative. Some devices allow the mode to bechanged dynamically via the SetDeviceMode request.motion_buffer_size is a cardinal number that specifies thenumber of elements that can be contained in the motionhistory buffer for the device.The axes field contains a pointer to an AXISINFO struture.• The information returned for each axis reported by thedevice is:The resolution is a cardinal value in counts/meter.The min_val field is a cardinal value in that contains theminimum value the device reports for this axis. For deviceswhose mode is Relative, the min_val field will contain 0.The max_val field is a cardinal value in that contains themaximum value the device reports for this axis. For deviceswhose mode is Relative, the max_val field will contain 0.2.3. Enabling DevicesClient programs that wish to access an extension device mustrequest that the server open that device. This is done viathe OpenDevice request.OpenDeviceid: CARD8=>    Errors: DeviceThis request returns the event classes to be used by theclient to indicate which events the client program wishes toreceive. Each input class may report several event classes.For example, input class Keys reports DeviceKeyPress andDeviceKeyRelease event classes. Input classes are uniquenumbers registered with the X Consortium. Input class Otherexists to report event classes that are not specific to anyone input class, such as DeviceMappingNotify,ChangeDeviceNotify, and DeviceStateNotify.• The information returned for each device is as follows:The device_id is a number that uniquely identifies thedevice.The num_classes field contains the number of input classessupported by this device.• For each class of input supported by the device, theInputClassInfo structure contains the followinginformation:The input_class is a small cardinal number that identifiesthe class of input.The event_type_base is a small cardinal number thatspecifies the event type of one of the events reported bythis input class. This information is not directly used byclient programs. Instead, the Device is used by macros thatreturn extension event types and event classes. This isdescribed in the section of this document entitled"Selecting Extension Device Events".Before it exits, the client program should explicitlyrequest that the server close the device. This is done viathe CloseDevice request.A client may open the same extension device more than once.Requests after the first successful one return an additionalXDevice structure with the same information as the first,but otherwise have no effect. A single CloseDevice requestwill terminate that client’s access to the device.Closing a device releases any active or passive grabs therequesting client has established. If the device is frozenonly by an active grab of the requesting client, the queuedevents are released when the client terminates.If a client program terminates without closing a device, theserver will automatically close that device on behalf of theclient. This does not affect any other clients that may beaccessing that device.CloseDevicedevice: DEVICEErrors: Device2.4. Changing The Mode Of A DeviceSome devices are capable of reporting either relative orabsolute motion data. To change the mode of a device fromrelative to absolute, use the SetDeviceMode request. Thevalid values are Absolute or Relative.This request will fail and return DeviceBusy if anotherclient already has the device open with a different mode.It will fail and return AlreadyGrabbed if another client hasthe device grabbed. The request will fail with a BadMatcherror if the requested mode is not supported by the device.SetDeviceModedevice: DEVICEmode: {Absolute, Relative}Errors: Device, Match, Mode=> status: {Success, DeviceBusy, AlreadyGrabbed}2.5. Initializing Valuators on an Input DeviceSome devices that report absolute positional data can beinitialized to a starting value. Devices that are capableof reporting relative motion or absolute positional data mayrequire that their valuators be initialized to a startingvalue after the mode of the device is changed to Absolute.To initialize the valuators on such a device, use theSetDeviceValuators request.SetDeviceValuatorsdevice: DEVICEfirst_valuator: CARD8num_valuators: CARD8valuators: LISTOFINT32Errors: Length, Device, Match, Value=> status: {Success, AlreadyGrabbed}This request initializes the specified valuators on thespecified extension input device. Valuators are numberedbeginning with zero. Only the valuators in the rangespecified by first_valuator and num_valuators are set. Ifthe number of valuators supported by the device is less thanthe expression first_valuator + num_valuators, a Value errorwill result.If the request succeeds, Success is returned. If thespecifed device is grabbed by some other client, the requestwill fail and a status of AlreadyGrabbed will be returned.2.6. Getting Input Device ControlsGetDeviceControldevice: DEVICEcontrol: XIDErrors: Length, Device, Match, Value=> controlState: {DeviceState}whereErrors: Length, Device, Match, ValueThis request returns the current state of the specifieddevice control. The device control must be supported by thetarget server and device or an error will result.If the request is successful, a pointer to a genericDeviceState structure will be returned. The informationreturned varies according to the specified control and ismapped by a structure appropriate for that control.GetDeviceControl will fail with a BadValue error if theserver does not support the specified control. It will failwith a BadMatch error if the device does not support thespecified control.Supported device controls and the information returned forthem include:      This device control returns a list of valuators and therange of valid resolutions allowed for each. Valuators arenumbered beginning with 0. Resolutions for all valuators onthe device are returned. For each valuator i on the device,resolutions[i] returns the current setting of theresolution, min_resolutions[i] returns the minimum validsetting, and max_resolutions[i] returns the maximum validsetting.When this control is specified, XGetDeviceControl will failwith a BadMatch error if the specified device has novaluators.ChangeDeviceControldevice: DEVICEXID: controlIdcontrol: DeviceControlwhereErrors: Length, Device, Match, Value=> status: {Success, DeviceBusy, AlreadyGrabbed}ChangeDeviceControl changes the specifed device controlaccording to the values specified in the DeviceControlstructure. The device control must be supported by thetarget server and device or an error will result.The information passed with this request varies according tothe specified control and is mapped by a structureappropriate for that control.ChangeDeviceControl will fail with a BadValue error if theserver does not support the specified control. It will failwith a BadMatch error if the server supports the specifiedcontrol, but the requested device does not. The requestwill fail and return a status of DeviceBusy if anotherclient already has the device open with a device controlstate that conflicts with the one specified in the request.It will fail with a status of AlreadyGrabbed if some otherclient has grabbed the specified device. If the requestsucceeds, Success is returned. If it fails, the devicecontrol is left unchanged.Supported device controls and the information specified forthem include:     This device control changes the resolution of the specifiedvaluators on the specified extension input device.Valuators are numbered beginning with zero. Only thevaluators in the range specified by first_valuator andnum_valuators are set. A value of -1 in the resolutionslist indicates that the resolution for this valuator is notto be changed. num_valuators specifies the number ofvaluators in the resolutions list.When this control is specified, XChangeDeviceControl willfail with a BadMatch error if the specified device has novaluators. If a resolution is specified that is not withinthe range of valid values (as returned by XGetDeviceControl)the request will fail with a BadValue error. If the numberof valuators supported by the device is less than theexpression first_valuator + num_valuators, a BadValue errorwill result.If the request fails for any reason, none of the valuatorresolutions will be changed.2.7. Selecting Extension Device EventsExtension input events are selected using theSelectExtensionEvent request.SelectExtensionEventwindow: WINDOWinterest: LISTofEVENTCLASSErrors: Window, Class, AccessThis request specifies to the server the events within thespecified window which are of interest to the client. Aswith the core XSelectInput function, multiple clients canselect input on the same window.XSelectExtensionEvent requires a list of event classes. Anevent class is a 32-bit number that combines an event typeand device id, and is used to indicate which event a clientwishes to receive and from which device it wishes to receiveit. Macros are provided to obtain event classes from thedata returned by the XOpenDevice request. The names ofthese macros correspond to the desired events, i.e. theDeviceKeyPress is used to obtain the event class forDeviceKeyPress events. The syntax of the macro invocationis:DeviceKeyPress (device, event_type, event_class);device: DEVICEevent_type: INTevent_class: INTThe value returned in event_type is the value that will becontained in the event type field of theXDeviceKeyPressEvent when it is received by the client. Thevalue returned in event_class is the value that should bepassed in making an XSelectExtensionEvent request to receiveDeviceKeyPress events.For DeviceButtonPress events, the client may specify whetheror not an implicit passive grab should be done when thebutton is pressed. If the client wants to guarantee that itwill receive a DeviceButtonRelease event for eachDeviceButtonPress event it receives, it should specify theDeviceButtonPressGrab event class as well as theDeviceButtonPress event class. This restricts the client inthat only one client at a time may request DeviceButtonPressevents from the same device and window if any clientspecifies this class.If any client has specified the DeviceButtonPressGrab class,any requests by any other client that specify the samedevice and window and specify DeviceButtonPress orDeviceButtonPressGrab will cause an Access error to begenerated.If only the DeviceButtonPress class is specified, noimplicit passive grab will be done when a button is pressedon the device. Multiple clients may use this class tospecify the same device and window combination.A client may also specify the DeviceOwnerGrabButton class.If it has specified both the DeviceButtonPressGrab and theDeviceOwnerGrabButton classes, implicit passive grabs willactivate with owner_events set to True. If only theDeviceButtonPressGrab class is specified, implicit passivegrabs will activate with owner_events set to False.The client may select DeviceMotion events only when a buttonis down. It does this by specifying the event classesButton1Motion through Button5Motion, or ButtonMotion. Aninput device will only support as many button motion classesas it has buttons.2.8. Determining Selected EventsTo determine which extension events are currently selectedfrom a given window, use GetSelectedExtensionEvents.GetSelectedExtensionEventswindow: WINDOW=> this-client: LISTofEVENTCLASSall-clients: LISTofEVENTCLASSErrors: WindowThis request returns two lists specifying the eventsselected on the specified window. One list gives theextension events selected by this client from the specifiedwindow. The other list gives the extension events selectedby all clients from the specified window. This informationis equivalent to that returned by your-event-mask andall-event-masks in a GetWindowAttributes request.2.9. Controlling Event PropagationExtension events propagate up the window hierarchy in thesame manner as core events. If a window is not interestedin an extension event, it usually propagates to the closestancestor that is interested, unless the dont_propagate listprohibits it. Grabs of extension devices may alter the setof windows that receive a particular extension event.Client programs may control extension event propagationthrough the use of the following two requests.XChangeDeviceDontPropagateList adds an event to or deletesan event from the do_not_propagate list of extension eventsfor the specified window. This list is maintained for thelife of the window, and is not altered if the clientterminates.ChangeDeviceDontPropagateListwindow: WINDOWeventclass: LISTofEVENTCLASSmode: {AddToList, DeleteFromList}Errors: Window, Class, ModeThis function modifies the list specifying the events thatare not propagated to the ancestors of the specified window.You may use the modes AddToList or DeleteFromList.GetDeviceDontPropagateListwindow: WINDOWErrors: Window=> dont-propagate-list: LISTofEVENTCLASSThis function returns a list specifying the events that arenot propagated to the ancestors of the specified window.2.10. Sending Extension EventsOne client program may send an event to another via theXSendExtensionEvent function.The event in the XEvent structure must be one of the eventsdefined by the input extension, so that the X server cancorrectly byte swap the contents as necessary. The contentsof the event are otherwise unaltered and unchecked by the Xserver except to force send_event to True in the forwardedevent and to set the sequence number in the event correctly.XSendExtensionEvent returns zero if the conversion-to-wireprotocol failed, otherwise it returns nonzero.SendExtensionEventdevice: DEVICEdestination: WINDOWpropagate: BOOLeventclass: LISTofEVENTCLASSevent: XEVENTErrors: Device, Value, Class, Window2.11. Getting Motion HistoryGetDeviceMotionEventsdevice: DEVICEstart, stop: TIMESTAMP or CurrentTime=> nevents_return: CARD32mode_return: {Absolute, Relative}axis_count_return: CARD8events: LISTofDEVICETIMECOORDwhere  Errors: Device, MatchThis request returns all positions in the device’s motionhistory buffer that fall between the specified start andstop times inclusive. If the start time is in the future,or is later than the stop time, no positions are returned.The data field of the DEVICETIMECOORD structure is asequence of data items. Each item is of type INT32, andthere is one data item per axis of motion reported by thedevice. The number of axes reported by the device isreturned in the axis_count variable.The value of the data items depends on the mode of thedevice, which is returned in the mode variable. If the modeis Absolute, the data items are the raw values generated bythe device. These may be scaled by the client program usingthe maximum values that the device can generate for eachaxis of motion that it reports. The maximum and minimumvalues for each axis are reported by the ListInputDevicesrequest.If the mode is Relative, the data items are the relativevalues generated by the device. The client program mustchoose an initial position for the device and maintain acurrent position by accumulating these relative values.2.12. Changing The Core DevicesThese requests are provided to change which physical deviceis used as the X pointer or X keyboard.NoteUsing these requests may change thecharacteristics of the core devices. The newpointer device may have a different number ofbuttons than the old one did, or the new keyboarddevice may have a different number of keys orreport a different range of keycodes. Clientprograms may be running that depend on thosecharacteristics. For example, a client programcould allocate an array based on the number ofbuttons on the pointer device, and then use thebutton numbers received in button events asindicies into that array. Changing the coredevices could cause such client programs to behaveimproperly or abnormally terminate.These requests change the X keyboard or X pointer device andgenerate an ChangeDeviceNotify event and a MappingNotifyevent. The ChangeDeviceNotify event is sent only to thoseclients that have expressed an interest in receiving thatevent via the XSelectExtensionEvent request. The specifieddevice becomes the new X keyboard or X pointer device. Thelocation of the core device does not change as a result ofthis request.These requests fail and return AlreadyGrabbed if either thespecified device or the core device it would replace aregrabbed by some other client. They fail and returnGrabFrozen if either device is frozen by the active grab ofanother client.These requests fail with a BadDevice error if the specifieddevice is invalid, or has not previously been opened viaOpenDevice.To change the X keyboard device, use theChangeKeyboardDevice request. The specified device mustsupport input class Keys (as reported in theListInputDevices request) or the request will fail with aBadMatch error. Once the device has successfully replacedone of the core devices, it is treated as a core deviceuntil it is in turn replaced by another ChangeDevicerequest, or until the server terminates. The termination ofthe client that changed the device will not cause it tochange back. Attempts to use the CloseDevice request toclose the new core device will fail with a BadDevice error.The focus state of the new keyboard is the same as the focusstate of the old X keyboard. If the new keyboard was notinitialized with a FocusRec, one is added by theChangeKeyboardDevice request. The X keyboard is assumed tohave a KbdFeedbackClassRec. If the device was initializedwithout a KbdFeedbackClassRec, one will be added by thisrequest. The KbdFeedbackClassRec will specify a nullroutine as the control procedure and the bell procedure.ChangeKeyboardDevicedevice: DEVICEErrors: Device, Match=> status: Success, AlreadyGrabbed, FrozenTo change the X pointer device, use the ChangePointerDevicerequest. The specified device must support input classValuators (as reported in the ListInputDevices request) orthe request will fail with a BadMatch error. The valuatorsto be used as the x- and y-axes of the pointer device mustbe specified. Data from other valuators on the device willbe ignored.The X pointer device does not contain a FocusRec. If thenew pointer was initialized with a FocusRec, it is freed bythe ChangePointerDevice request. The X pointer is assumedto have a ButtonClassRec and a PtrFeedbackClassRec. If thedevice was initialized without a ButtonClassRec or aPtrFeedbackClassRec, one will be added by this request. TheButtonClassRec added will have no buttons, and thePtrFeedbackClassRec will specify a null routine as thecontrol procedure.If the specified device reports absolute positionalinformation, and the server implementation does not allowsuch a device to be used as the X pointer, the request willfail with a BadDevice error.Once the device has successfully replaced one of the coredevices, it is treated as a core device until it is in turnreplaced by another ChangeDevice request, or until theserver terminates. The termination of the client thatchanged the device will not cause it to change back.Attempts to use the CloseDevice request to close the newcore device will fail with a BadDevice error.ChangePointerDevicedevice: DEVICExaxis: CARD8yaxis: CARD8Errors: Device, Match=> status: Success, AlreadyGrabbed, Frozen2.13. Event Synchronization And Core GrabsImplementation of the input extension requires an extensionof the meaning of event synchronization for the core grabrequests. This is necessary in order to allow windowmanagers to freeze all input devices with a single request.The core grab requests require a pointer_mode andkeyboard_mode argument. The meaning of these modes ischanged by the input extension. For the XGrabPointer andXGrabButton requests, pointer_mode controls synchronizationof the pointer device, and keyboard_mode controls thesynchronization of all other input devices. For theXGrabKeyboard and XGrabKey requests, pointer_mode controlsthe synchronization of all input devices except the Xkeyboard, while keyboard_mode controls the synchronizationof the keyboard. When using one of the core grab requests,the synchronization of extension devices is controlled bythe mode specified for the device not being grabbed.2.14. Extension Active GrabsActive grabs of extension devices are supported via theGrabDevice request in the same way that core devices aregrabbed using the core GrabKeyboard request, except that aDevice is passed as a function parameter. A list of eventsthat the client wishes to receive is also passed. TheUngrabDevice request allows a previous active grab for anextension device to be released.To grab an extension device, use the GrabDevice request.The device must have previously been opened using theOpenDevice request.GrabDevicedevice: DEVICEgrab-window: WINDOWowner-events: BOOLevent-list: LISTofEVENTCLASSthis-device-mode: {Synchronous, Asynchronous}other-device-mode: {Synchronous, Asynchronous}time:TIMESTAMP or CurrentTime=> status: Success, AlreadyGrabbed, Frozen, InvalidTime,NotViewableErrors: Device, Window, ValueThis request actively grabs control of the specified inputdevice. Further input events from this device are reportedonly to the grabbing client. This request overrides anyprevious active grab by this client for this device.The event-list parameter is a pointer to a list of eventclasses. These are used to indicate which events the clientwishes to receive while the device is grabbed. Only eventclasses obtained from the grabbed device are valid.If owner-events is False, input events generated from thisdevice are reported with respect to grab-window, and areonly reported if selected by being included in theevent-list. If owner-events is True, then if a generatedevent would normally be reported to this client, it isreported normally, otherwise the event is reported withrespect to the grab-window, and is only reported if selectedby being included in the event-list. For either value ofowner-events, unreported events are discarded.If this-device-mode is Asynchronous, device event processingcontinues normally. If the device is currently frozen bythis client, then processing of device events is resumed.If this-device-mode is Synchronous, the state of the grabbeddevice (as seen by means of the protocol) appears to freeze,and no further device events are generated by the serveruntil the grabbing client issues a releasingAllowDeviceEvents request or until the device grab isreleased. Actual device input events are not lost while thedevice is frozen; they are simply queued for laterprocessing.If other-device-mode is Asynchronous, event processing isunaffected by activation of the grab. If other-device-modeis Synchronous, the state of all input devices except thegrabbed one (as seen by means of the protocol) appears tofreeze, and no further events are generated by the serveruntil the grabbing client issues a releasingAllowDeviceEvents request or until the device grab isreleased. Actual events are not lost while the devices arefrozen; they are simply queued for later processing.This request generates DeviceFocusIn and DeviceFocusOutevents.This request fails and returns:• AlreadyGrabbed If the device is actively grabbed by someother client.• NotViewable If grab-window is not viewable.• InvalidTime If the specified time is earlier than thelast-grab-time for the specified device or later than thecurrent X server time. Otherwise, the last-grab-time forthe specified device is set to the specified time andCurrentTime is replaced by the current X server time.• Frozen If the device is frozen by an active grab ofanother client.If a grabbed device is closed by a client while an activegrab by that client is in effect, that active grab will bereleased. Any passive grabs established by that client willbe released. If the device is frozen only by an active grabof the requesting client, it is thawed.To release a grab of an extension device, use UngrabDevice.UngrabDevicedevice: DEVICEtime: TIMESTAMP or CurrentTimeErrors: DeviceThis request releases the device if this client has itactively grabbed (from either GrabDevice or GrabDeviceKey)and releases any queued events. If any devices were frozenby the grab, UngrabDevice thaws them. The request has noeffect if the specified time is earlier than thelast-device-grab time or is later than the current servertime.This request generates DeviceFocusIn and DeviceFocusOutevents.An UngrabDevice is performed automatically if the eventwindow for an active device grab becomes not viewable.2.15. Passively Grabbing A KeyPassive grabs of buttons and keys on extension devices aresupported via the GrabDeviceButton and GrabDeviceKeyrequests. These passive grabs are released via theUngrabDeviceKey and UngrabDeviceButton requests.To passively grab a single key on an extension device, useGrabDeviceKey. That device must have previously been openedusing the OpenDevice request.GrabDeviceKeydevice: DEVICEkeycode: KEYCODE or AnyKeymodifiers: SETofKEYMASK or AnyModifiermodifier-device: DEVICE or NULLgrab-window: WINDOWowner-events: BOOLevent-list: LISTofEVENTCLASSthis-device-mode: {Synchronous, Asynchronous}other-device-mode: {Synchronous, Asynchronous}Errors: Device, Match, Access, Window, ValueThis request is analogous to the core GrabKey request. Itestablishes a passive grab on a device. Consequently, Inthe future:• IF the device is not grabbed and the specified key, whichitself can be a modifier key, is logically pressed whenthe specified modifier keys logically are down on thespecified modifier device (and no other keys are down),• AND no other modifier keys logically are down,• AND EITHER the grab window is an ancestor of (or is) thefocus window OR the grab window is a descendent of thefocus window and contains the pointer,• AND a passive grab on the same device and key combinationdoes not exist on any ancestor of the grab window,• THEN the device is actively grabbed, as for GrabDevice,the last-device-grab time is set to the time at which thekey was pressed (as transmitted in the DeviceKeyPressevent), and the DeviceKeyPress event is reported.The interpretation of the remaining arguments is as forGrabDevice. The active grab is terminated automaticallywhen logical state of the device has the specified keyreleased (independent of the logical state of the modifierkeys).Note that the logical state of a device (as seen by means ofthe X protocol) may lag the physical state if device eventprocessing is frozen.A modifier of AnyModifier is equivalent to issuing therequest for all possible modifier combinations (includingthe combination of no modifiers). It is not required thatall modifiers specified have currently assigned keycodes. Akey of AnyKey is equivalent to issuing the request for allpossible keycodes. Otherwise, the key must be in the rangespecified by min-keycode and max-keycode in theListInputDevices request. If it is not within that range,GrabDeviceKey generates a Value error.NULL may be passed for the modifier_device. If themodifier_device is NULL, the core X keyboard is used as themodifier_device.An Access error is generated if some other client has issueda GrabDeviceKey with the same device and key combination onthe same window. When using AnyModifier or AnyKey, therequest fails completely and the X server generates a Accesserror and no grabs are established if there is a conflictinggrab for any combination.This request cannot be used to grab a key on the X keyboarddevice. The core GrabKey request should be used for thatpurpose.To release a passive grab of a single key on an extensiondevice, use UngrabDeviceKey.UngrabDeviceKeydevice: DEVICEkeycode: KEYCODE or AnyKeymodifiers: SETofKEYMASK or AnyModifiermodifier-device: DEVICE or NULLgrab-window: WINDOWErrors: Device, Match, Window, Value, AllocThis request is analogous to the core UngrabKey request. Itreleases the key combination on the specified window if itwas grabbed by this client. A modifier of AnyModifier isequivalent to issuing the request for all possible modifiercombinations (including the combination of no modifiers). Akey of AnyKey is equivalent to issuing the request for allpossible keycodes. This request has no effect on an activegrab.NULL may be passed for the modifier_device. If themodifier_device is NULL, the core X keyboard is used as themodifier_device.2.16. Passively Grabbing A ButtonTo establish a passive grab for a single button on anextension device, use GrabDeviceButton.GrabDeviceButtondevice: DEVICEbutton: BUTTON or AnyButtonmodifiers: SETofKEYMASK or AnyModifiermodifier-device: DEVICE or NULLgrab-window: WINDOWowner-events: BOOLevent-list: LISTofEVENTCLASSthis-device-mode: {Synchronous, Asynchronous}other-device-mode: {Synchronous, Asynchronous}Errors: Device, Match, Window, Access, ValueThis request is analogous to the core GrabButton request.It establishes an explicit passive grab for a button on anextension input device. Since the server does not trackextension devices, no cursor is specified with this request.For the same reason, there is no confine-to parameter. Thedevice must have previously been opened using the OpenDevicerequest.The GrabDeviceButton request establishes a passive grab on adevice. Consequently, in the future,• IF the device is not grabbed and the specified button islogically pressed when the specified modifier keyslogically are down (and no other buttons or modifier keysare down),• AND the grab window contains the device,• AND a passive grab on the same device and button/ keycombination does not exist on any ancestor of the grabwindow,• THEN the device is actively grabbed, as for GrabDevice,the last-grab time is set to the time at which the buttonwas pressed (as transmitted in the DeviceButtonPressevent), and the DeviceButtonPress event is reported.The interpretation of the remaining arguments is as forGrabDevice. The active grab is terminated automaticallywhen logical state of the device has all buttons released(independent of the logical state of the modifier keys).Note that the logical state of a device (as seen by means ofthe X protocol) may lag the physical state if device eventprocessing is frozen.A modifier of AnyModifier is equivalent to issuing therequest for all possible modifier combinations (includingthe combination of no modifiers). It is not required thatall modifiers specified have currently assigned keycodes. Abutton of AnyButton is equivalent to issuing the request forall possible buttons. It is not required that the specifiedbutton be assigned to a physical button.NULL may be passed for the modifier_device. If themodifier_device is NULL, the core X keyboard is used as themodifier_device.An Access error is generated if some other client has issueda GrabDeviceButton with the same device and buttoncombination on the same window. When using AnyModifier orAnyButton, the request fails completely and the X servergenerates a Access error and no grabs are established ifthere is a conflicting grab for any combination. Therequest has no effect on an active grab.This request cannot be used to grab a button on the Xpointer device. The core GrabButton request should be usedfor that purpose.To release a passive grab of a button on an extensiondevice, use UngrabDeviceButton.UngrabDeviceButtondevice: DEVICEbutton: BUTTON or AnyButtonmodifiers: SETofKEYMASK or AnyModifiermodifier-device: DEVICE or NULLgrab-window: WINDOWErrors: Device, Match, Window, Value, AllocThis request is analogous to the core UngrabButton request.It releases the passive button/key combination on thespecified window if it was grabbed by the client. Amodifiers of AnyModifier is equivalent to issuing therequest for all possible modifier combinations (includingthe combination of no modifiers). A button of AnyButton isequivalent to issuing the request for all possible buttons.This request has no effect on an active grab. The devicemust have previously been opened using the OpenDevicerequest otherwise a Device error will be generated.NULL may be passed for the modifier_device. If themodifier_device is NULL, the core X keyboard is used as themodifier_device.This request cannot be used to ungrab a button on the Xpointer device. The core UngrabButton request should beused for that purpose.2.17. Thawing A DeviceTo allow further events to be processed when a device hasbeen frozen, use AllowDeviceEvents.AllowDeviceEventsdevice: DEVICEevent-mode: {AsyncThisDevice, SyncThisDevice,AsyncOtherDevices, ReplayThisdevice, AsyncAll, orSyncAll}time:TIMESTAMP or CurrentTimeErrors: Device, ValueThe AllowDeviceEvents request releases some queued events ifthe client has caused a device to freeze. The request hasno effect if the specified time is earlier than thelast-grab time of the most recent active grab for theclient, or if the specified time is later than the current Xserver time.The following describes the processing that occurs dependingon what constant you pass to the event-mode argument:• If the specified device is frozen by the client, eventprocessing for that device continues as usual. If thedevice is frozen multiple times by the client on behalfof multiple separate grabs, AsyncThisDevice thaws forall. AsyncThisDevice has no effect if the specifieddevice is not frozen by the client, but the device neednot be grabbed by the client.• If the specified device is frozen and actively grabbed bythe client, event processing for that device continuesnormally until the next button or key event is reportedto the client. At this time, the specified device againappears to freeze. However, if the reported event causesthe grab to be released, the specified device does notfreeze. SyncThisDevice has no effect if the specifieddevice is not frozen by the client or is not grabbed bythe client.• If the specified device is actively grabbed by the clientand is frozen as the result of an event having been sentto the client (either from the activation of aGrabDeviceButton or from a previous AllowDeviceEventswith mode SyncThisDevice, but not from a Grab), the grabis released and that event is completely reprocessed.This time, however, the request ignores any passive grabsat or above (towards the root) the grab-window of thegrab just released. The request has no effect if thespecified device is not grabbed by the client or if it isnot frozen as the result of an event.• If the remaining devices are frozen by the client, eventprocessing for them continues as usual. If the otherdevices are frozen multiple times by the client onbehalf of multiple separate grabs, AsyncOtherDevices‘‘thaws’’ for all. AsyncOtherDevices has no effect ifthe devices are not frozen by the client, but thosedevices need not be grabbed by the client.• If all devices are frozen by the client, event processing(for all devices) continues normally until the nextbutton or key event is reported to the client for agrabbed device (button event for the grabbed device, keyor motion event for the device), at which time thedevices again appear to freeze. However, if the reportedevent causes the grab to be released, then the devices donot freeze (but if any device is still grabbed, then asubsequent event for it will still cause all devices tofreeze). SyncAll has no effect unless all devices arefrozen by the client. If any device is frozen twice bythe client on behalf of two separate grabs, SyncAll"thaws" for both (but a subsequent freeze for SyncAllwill only freeze each device once).• If all devices are frozen by the client, event processing(for all devices) continues normally. If any device isfrozen multiple times by the client on behalf of multipleseparate grabs, AsyncAll "thaws" for all. AsyncAll hasno effect unless all devices are frozen by the client.AsyncThisDevice, SyncThisDevice, and ReplayThisDevice haveno effect on the processing of events from the remainingdevices. AsyncOtherDevices has no effect on the processingof events from the specified device. When the event_mode isSyncAll or AsyncAll, the device parameter is ignored.It is possible for several grabs of different devices (bythe same or different clients) to be active simultaneously.If a device is frozen on behalf of any grab, no eventprocessing is performed for the device. It is possible fora single device to be frozen because of several grabs. Inthis case, the freeze must be released on behalf of eachgrab before events can again be processed.2.18. Controlling Device FocusThe current focus window for an extension input device canbe determined using the GetDeviceFocus request. Extensiondevices are focused using the SetDeviceFocus request in thesame way that the keyboard is focused using theSetInputFocus request, except that a device is specified aspart of the request. One additional focus state,FollowKeyboard, is provided for extension devices.To get the current focus state, revert state, and focus timeof an extension device, use GetDeviceFocus.GetDeviceFocusdevice: DEVICE=> focus: WINDOW, PointerRoot, FollowKeyboard, or Nonerevert-to: Parent, PointerRoot, FollowKeyboard, or Nonefocus-time: TIMESTAMPErrors: Device, MatchThis request returns the current focus state, revert-tostate, and last-focus-time of an extension device.To set the focus of an extension device, use SetDeviceFocus.SetDeviceFocusdevice: DEVICEfocus: WINDOW, PointerRoot, FollowKeyboard, or Nonerevert-to: Parent, PointerRoot, FollowKeyboard, or Nonefocus-time: TIMESTAMPErrors: Device, Window, Value, MatchThis request changes the focus for an extension input deviceand the last-focus-change-time. The request has no effectif the specified time is earlier than thelast-focus-change-time or is later than the current X servertime. Otherwise, the last-focus-change-time is set to thespecified time, with CurrentTime replaced by the currentserver time.The action taken by the server when this request isrequested depends on the value of the focus argument:• If the focus argument is None, all input events from thisdevice will be discarded until a new focus window is set.In this case, the revert-to argument is ignored.• If a window ID is assigned to the focus argument, itbecomes the focus window of the device. If an inputevent from the device would normally be reported to thiswindow or to one of its inferiors, the event is reportednormally. Otherwise, the event is reported relative tothe focus window.• If you assign PointerRoot to the focus argument, thefocus window is dynamically taken to be the root windowof whatever screen the pointer is on at each input event.In this case, the revert-to argument is ignored.• If you assign FollowKeyboard to the focus argument, thefocus window is dynamically taken to be the same as thefocus of the X keyboard at each input event.The specified focus window must be viewable at the time ofthe request (else a Match error). If the focus window laterbecomes not viewable, the X server evaluates the revert-toargument to determine the new focus window.• If you assign RevertToParent to the revert-to argument,the focus reverts to the parent (or the closest viewableancestor), and the new revert-to value is taken to beRevertToNone.• If you assign RevertToPointerRoot,RevertToFollowKeyboard, or RevertToNone to the revert-toargument, the focus reverts to that value.When the focus reverts, the X server generates DeviceFocusInand DeviceFocusOut events, but the last-focus-change time isnot affected.This request causes the X server to generate DeviceFocusInand DeviceFocusOut events.2.19. Controlling Device FeedbackTo get the settings of feedbacks on an extension device, useGetFeedbackControl. This request provides functionalityequivalent to the core GetKeyboardControl andGetPointerControl functions. It also provides a way tocontrol displays associated with an input device that arecapable of displaying an integer or string.GetFeedbackControldevice: DEVICE=> num_feedbacks_return: CARD16return_value: LISTofFEEDBACKSTATEwhereFeedbacks are reported by class. Those feedbacks that arereported for the core keyboard device are in classKbdFeedback, and are returned in the KbdFeedbackStatestructure. The members of that structure are as follows:         Those feedbacks that are equivalent to those reported forthe core pointer are in feedback class PtrFeedback and arereported in the PtrFeedbackState structure. The members ofthat structure are:     Some input devices provide a means of displaying an integer.Those devices will support feedback class IntegerFeedback,which is reported in the IntegerFeedbackState structure.The members of that structure are:     Some input devices provide a means of displaying a string.Those devices will support feedback class StringFeedback,which is reported in the StringFeedbackState structure. Themembers of that structure are:     Some input devices contain a bell. Those devices willsupport feedback class BellFeedback, which is reported inthe BellFeedbackState structure. The members of thatstructure are:      The percent sets the base volume for the bell between 0(off) and 100 (loud) inclusive, if possible. Setting to −1restores the default. Other negative values generate aValue error.The pitch sets the pitch (specified in Hz) of the bell, ifpossible. Setting to −1 restores the default. Othernegative values generate a Value error.The duration sets the duration (specified in milliseconds)of the bell, if possible. Setting to −1 restores thedefault. Other negative values generate a Value error.A bell generator connected with the console but not directlyon the device is treated as if it were part of the device.Some input devices contain LEDs. Those devices will supportfeedback class Led, which is reported in theLedFeedbackState structure. The members of that structureare:     Each bit in led_mask indicates that the corresponding led issupported by the feedback. At most 32 LEDs per feedback aresupported. No standard interpretation of LEDs is defined.This function will fail with a BadMatch error if the devicespecified in the request does not support feedbacks.Errors: Device, MatchTo change the settings of a feedback on an extension device,use ChangeFeedbackControl.ChangeFeedbackControldevice: DEVICEfeedbackid: CARD8value-mask: BITMASKvalue: FEEDBACKCONTROLErrors: Device, Match, ValueFeedback controls are grouped by class. Those feedbacksthat are equivalent to those supported by the core keyboardare controlled by feedback class KbdFeedbackClass using theKbdFeedbackControl structure. The members of that structureare:             The key_click_percent sets the volume for key clicks between0 (off) and 100 (loud) inclusive, if possi