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 possible. Setting to−1 restores the default. Other negative values generate aValue error.If both auto_repeat_mode and key are specified, then theauto_repeat_mode of that key is changed, if possible. Ifonly auto_repeat_mode is specified, then the globalauto-repeat mode for the entire keyboard is changed, ifpossible, without affecting the per-key settings. It is aMatch error if a key is specified without anauto_repeat_mode.The order in which controls are verified and altered isserver-dependent. If an error is generated, a subset of thecontrols may have been altered.Those feedback controls equivalent to those of the corepointer are controlled by feedback class PtrFeedbackClassusing the PtrFeedbackControl structure. The members of thatstructure are as follows: The acceleration, expressed as a fraction, is a multiplierfor movement. For example, specifying 3/1 means the devicemoves three times as fast as normal. The fraction may berounded arbitrarily by the X server. Acceleration onlytakes effect if the device moves more than threshold pixelsat once and only applies to the amount beyond the value inthe threshold argument. Setting a value to -1 restores thedefault. The values of the do-accel and do-thresholdarguments must be nonzero for the device values to be set.Otherwise, the parameters will be unchanged. Negativevalues generate a Value error, as does a zero value for theaccel-denominator argument.Some devices are capable of displaying an integer. This isdone using feedback class IntegerFeedbackClass using theIntegerFeedbackControl structure. The members of thatstructure are as follows: Some devices are capable of displaying an string. This isdone using feedback class StringFeedbackClass using theStringFeedbackCtl structure. The members of that structureare as follows: Some devices contain a bell. This is done using feedbackclass BellFeedbackClass using the BellFeedbackControlstructure. The members of that structure are as follows: Some devices contain leds. These can be turned on and offusing the LedFeedbackControl structure. The members of thatstructure are as follows: Errors: Device, Match, Value2.20. Ringing a Bell on an Input DeviceTo ring a bell on an extension input device, use DeviceBell.DeviceBelldevice: DEVICEfeedbackclass: CARD8feedbackid: CARD8percent: INT8Errors: Device, ValueThis request is analogous to the core Bell request. Itrings the specified bell on the specified input devicefeedback, using the specified volume. The specified volumeis relative to the base volume for the feedback. If thevalue for the percent argument is not in the range -100 to100 inclusive, a Value error results. The volume at whichthe bell rings when the percent argument is nonnegative is:base - [(base * percent) / 100] + percentThe volume at which the bell rings when the percent argumentis negative is:base + [(base * percent) / 100]To change the base volume of the bell, useChangeFeedbackControl request.2.21. Controlling Device EncodingTo get the keyboard mapping of an extension device that haskeys, use GetDeviceKeyMapping.GetDeviceKeyMappingdevice: DEVICEfirst-keycode: KEYCODEcount: CARD8=> keysyms-per-keycode: CARD8keysyms: LISTofKEYSYMErrors: Device, Match, ValueThis request returns the symbols for the specified number ofkeycodes for the specified extension device, starting withthe specified keycode. The first-keycode must be greaterthan or equal to min-keycode as returned in the connectionsetup (else a Value error), andfirst-keycode + count − 1must be less than or equal to max-keycode as returned in theconnection setup (else a Value error). The number ofelements in the keysyms list iscount * keysyms-per-keycodeand KEYSYM number N (counting from zero) for keycode K hasan index (counting from zero) of(K − first-keycode) * keysyms-per-keycode + Nin keysyms. The keysyms-per-keycode value is chosenarbitrarily by the server to be large enough to report allrequested symbols. A special KEYSYM value of NoSymbol isused to fill in unused elements for individual keycodes.If the specified device has not first been opened by thisclient via OpenDevice, or if that device does not supportinput class Keys, this request will fail with a Deviceerror.To change the keyboard mapping of an extension device thathas keys, use ChangeDeviceKeyMapping.ChangeDeviceKeyMappingdevice: DEVICEfirst-keycode: KEYCODEkeysyms-per-keycode: CARD8keysyms: LISTofKEYSYMnum_codes: CARD8Errors: Device, Match, Value, AllocThis request is analogous to the core ChangeKeyMappingrequest. It defines the symbols for the specified number ofkeycodes for the specified extension device. If thespecified device has not first been opened by this clientvia OpenDevice, or if that device does not support inputclass Keys, this request will fail with a Device error.The number of elements in the keysyms list must be amultiple of keysyms_per_keycode. Otherwise,ChangeDeviceKeyMapping generates a Length error. Thespecified first_keycode must be greater than or equal to themin_keycode value returned by the ListInputDevices request,or this request will fail with a Value error. In addition,if the following expression is not less than the max_keycodevalue returned by the ListInputDevices request, the requestwill fail with a Value error:first_keycode + (num_codes / keysyms_per_keycode) - 1To obtain the keycodes that are used as modifiers on anextension device that has keys, useGetDeviceModifierMapping.GetDeviceModifierMappingdevice: DEVICE=> keycodes-per-modifier: CARD8keycodes: LISTofKEYCODEErrors: Device, MatchThis request is analogous to the core GetModifierMappingrequest. This request returns the keycodes of the keysbeing used as modifiers. The number of keycodes in the listis 8*keycodes-per-modifier. The keycodes are divided intoeight sets, with each set containing keycodes-per-modifierelements. The sets are assigned in order to the modifiersShift, Lock, Control, Mod1, Mod2, Mod3, Mod4, and Mod5. Thekeycodes-per-modifier value is chosen arbitrarily by theserver; zeroes are used to fill in unused elements withineach set. If only zero values are given in a set, the useof the corresponding modifier has been disabled. The orderof keycodes within each set is chosen arbitrarily by theserver.To set which keycodes that are to be used as modifiers foran extension device, use SetDeviceModifierMapping.SetDeviceModifierMappingdevice: DEVICEkeycodes-per-modifier: CARD8keycodes: LISTofKEYCODE=> status: {Success, Busy, Failed}Errors: Device, Match, Value, AllocThis request is analogous to the core SetModifierMappingrequest. This request specifies the keycodes (if any) ofthe keys to be used as modifiers. The number of keycodes inthe list must be 8*keycodes-per-modifier (else a Lengtherror). The keycodes are divided into eight sets, with thesets, with each set containing keycodes-per-modifierelements. The sets are assigned in order to the modifiersShift, Lock, Control, Mod1, Mod2, Mod3, Mod4, and Mod5.Only non-zero keycode values are used within each set; zerovalues are ignored. All of the non-zero keycodes must be inthe range specified by min-keycode and max-keycode in theListInputDevices request (else a Value error). The order ofkeycodes within a set does not matter. If no non-zerovalues are specified in a set, the use of the correspondingmodifier is disabled, and the modifier bit will always bezero. Otherwise, the modifier bit will be one whenever atleast one of the keys in the corresponding set is in thedown position.A server can impose restrictions on how modifiers can bechanged (for example, if certain keys do not generate uptransitions in hardware or if multiple keys per modifier arenot supported). The status reply is Failed if some suchrestriction is violated, and none of the modifiers arechanged.If the new non-zero keycodes specified for a modifier differfrom those currently defined, and any (current or new) keysfor that modifier are logically in the down state, then thestatus reply is Busy, and none of the modifiers are changed.This request generates a DeviceMappingNotify event on aSuccess status. The DeviceMappingNotify event will besent only to those clients that have expressed aninterest in receiving that event via theXSelectExtensionEvent request.A X server can impose restrictions on how modifiers can bechanged, for example, if certain keys do not generate uptransitions in hardware or if multiple modifier keys are notsupported. If some such restriction is violated, the statusreply is MappingFailed , and none of the modifiers arechanged. If the new keycodes specified for a modifierdiffer from those currently defined and any (current or new)keys for that modifier are in the logically down state, thestatus reply is MappingBusy, and none of the modifiers arechanged.2.22. Controlling Button MappingThese requests are analogous to the core GetPointerMappingand ChangePointerMapping requests. They allow a client todetermine the current mapping of buttons on an extensiondevice, and to change that mapping.To get the current button mapping for an extension device,use GetDeviceButtonMapping.GetDeviceButtonMappingdevice: DEVICEnmap: CARD8=> map_return: LISTofCARD8Errors: Device, MatchThe GetDeviceButtonMapping function returns the currentmapping of the buttons on the specified device. Elements ofthe list are indexed starting from one. The length of thelist indicates the number of physical buttons. The nominalmapping is the identity mapping map[i]=i.nmap indicates the number of elements in the map_returnarray. Only the first nmap entries will be copied by thelibrary into the map_return array.To set the button mapping for an extension device, useSetDeviceButtonMapping.SetDeviceButtonMappingdevice: DEVICEmap: LISTofCARD8nmap: CARD8=> status: CARD8Errors: Device, Match, ValueThe SetDeviceButtonMapping function sets the mapping of thespecified device and causes the X server to generate aDeviceMappingNotify event on a status of MappingSuccess.Elements of the list are indexed starting from one. Thelength of the list, specified in nmap, must be the same asGetDeviceButtonMapping would return. Otherwise,SetDeviceButtonMapping generates a Value error. A zeroelement disables a buttons, and elements are not restrictedin value by the number of physical buttons. However, no twoelements can have the same nonzero value. Otherwise, thisfunction generates a Value error. If any of the buttons tobe altered are in the down state, the status reply isMappingBusy and the mapping is not changed.2.23. Obtaining The State Of A DeviceTo obtain vectors that describe the state of the keys,buttons and valuators of an extension device, useQueryDeviceState.QueryDeviceStatedevice: DEVICE=> device-id: CARD8data: LISTofINPUTCLASSwhere Errors: DeviceThe QueryDeviceState request returns the current logicalstate of the buttons, keys, and valuators on the specifiedinput device. The buttons and keys arrays, byte N (from 0)contains the bits for key or button 8N to 8N+7 with theleast significant bit in the byte representing key or button8N.If the device has valuators, a bit in the mode fieldindicates whether the device is reporting Absolute orRelative data. If it is reporting Absolute data, thevaluators array will contain the current value of thevaluators. If it is reporting Relative data, the valuatorsarray will contain undefined data.If the device reports proximity information, a bit in themode field indicates whether the device is InProximity orOutOfProximity.3. EventsThe input extension creates input events analogous to thecore input events. These extension input events aregenerated by manipulating one of the extension inputdevices.3.1. Button, Key, and Motion EventsDeviceKeyPressDeviceKeyReleaseDeviceButtonPress,DeviceButtonReleaseDeviceMotionNotifydevice: CARD8root, event: WINDOWchild: Window or Nonesame-screen: BOOLroot-x, root-y, event-x, event-y: INT16detail: <see below>state: SETofKEYBUTMASKtime: TIMESTAMPThese events are generated when a key, button, or valuatorlogically changes state. The generation of these logicalchanges may lag the physical changes, if device eventprocessing is frozen. Note that DeviceKeyPress andDeviceKeyRelease are generated for all keys, even thosemapped to modifier bits. The ‘‘source’’ of the event is thewindow the pointer is in. The window with respect to whichthe event is normally reported is found by looking up thehierarchy (starting with the source window) for the firstwindow on which any client has selected interest in theevent. The actual window used for reporting can be modifiedby active grabs and by the focus window.The window the eventis reported with respect to is called the ‘‘event’’ window.The root is the root window of the ‘‘source’’ window, androot-x and root-y are the pointer coordinates relative toroot’s origin at the time of the event. Event is the‘‘event’’ window. If the event window is on the same screenas root, then event-x and event-y are the pointercoordinates relative to the event window’s origin.Otherwise, event-x and event-y are zero. If the sourcewindow is an inferior of the event window, then child is setto the child of the event window that is an ancestor of (oris) the source window. Otherwise, it is set to None. Thestate component gives the logical state of the buttons onthe core X pointer and modifier keys on the core X keyboardjust before the event. The detail component type varieswith the event type:Event ComponentDeviceKeyPress,DeviceKeyRelease KEYCODEDeviceButtonPress,DeviceButtonRelease BUTTONDeviceMotionNotify { Normal , Hint }The granularity of motion events is not guaranteed, but aclient selecting for motion events is guaranteed to get atleast one event when a valuator changes. If DeviceMotionHintis selected, the server is free to send only oneDeviceMotionNotify event (with detail Hint) to the clientfor the event window, until either a key or button changesstate, the pointer leaves the event window, or the clientissues a QueryDeviceState or GetDeviceMotionEvents request.3.2. DeviceValuator EventDeviceValuatordevice: CARD8device_state: SETofKEYBUTMASKnum_valuators: CARD8first_valuator: CARD8valuators: LISTofINT32DeviceValuator events are generated to contain valuatorinformation for which there is insufficient space inDeviceKey, DeviceButton, DeviceMotion, and Proximity wireevents. For events of these types, a second event of typeDeviceValuator follows immediately. The library combinesthese events into a single event that a client can receivevia XNextEvent. DeviceValuator events are not selected forby clients, they only exist to contain information that willnot fit into some event selected by clients.The device_state component gives the state of the buttonsand modifiers on the device generating the event.Extension motion devices may report motion data for avariable number of axes. The valuators array contains thevalues of all axes reported by the device. If more than 6axes are reported, more than one DeviceValuator event willbe sent by the server, and more than one DeviceKey,DeviceButton, DeviceMotion, or Proximity event will bereported by the library. Clients should examine thecorresponding fields of the event reported by the library todetermine the total number of axes reported, and the firstaxis reported in the current event. Axes are numberedbeginning with zero.For Button, Key and Motion events on a device reportingabsolute motion data the current value of the device’svaluators is reported. For devices that report relativedata, Button and Key events may be followed by aDeviceValuator event that contains 0s in the num_valuatorsfield. In this case, only the device_state component willhave meaning.3.3. Device Focus EventsDeviceFocusInDeviceFocusOutdevice: CARD8time: TIMESTAMPevent: WINDOWmode: { Normal, WhileGrabbed, Grab, Ungrab}detail: { Ancestor, Virtual, Inferior, Nonlinear,NonlinearVirtual, Pointer, PointerRoot, None}These events are generated when the input focus changes andare reported to clients selecting DeviceFocusChange for thespecified device and window. Events generated bySetDeviceFocus when the device is not grabbed have modeNormal. Events generated by SetDeviceFocus when the deviceis grabbed have mode WhileGrabbed. Events generated when adevice grab actives have mode Grab, and events generatedwhen a device grab deactivates have mode Ungrab.All DeviceFocusOut events caused by a window unmap aregenerated after any UnmapNotify event, but the ordering ofDeviceFocusOut with respect to generated EnterNotify,LeaveNotify, VisibilityNotify and Expose events is notconstrained.DeviceFocusIn and DeviceFocusOut events are generated forfocus changes of extension devices in the same manner asfocus events for the core devices are generated.3.4. Device State Notify EventDeviceStateNotifytime: TIMESTAMPdevice: CARD8num_keys: CARD8num_buttons: CARD8num_valuators: CARD8classes_reported: CARD8 {SetOfDeviceMode |SetOfInputClass}SetOfDeviceMode:#x80 ProximityState0 = InProxmity, 1 = OutOfProximity#x40 Device Mode(0 = Relative, 1 = Absolute)SetOfInputClass:#x04 reporting valuators#x02 reporting buttons#x01 reporting keysbuttons: LISTofCARD8keys: LISTofCARD8valuators: LISTofCARD32This event reports the state of the device just as in theQueryDeviceState request. This event is reported to clientsselecting DeviceStateNotify for the device and window and isgenerated immediately after every EnterNotify andDeviceFocusIn. If the device has no more than 32 buttons,no more than 32 keys, and no more than 3 valuators, Thisevent can report the state of the device. If the device hasmore than 32 buttons, the event will be immediately followedby a DeviceButtonStateNotify event. If the device has morethan 32 keys, the event will be followed by aDeviceKeyStateNotify event. If the device has more than 3valuators, the event will be followed by one or moreDeviceValuator events.3.5. Device KeyState and ButtonState Notify EventsDeviceKeyStateNotifydevice: CARD8keys: LISTofCARD8DeviceButtonStateNotifydevice: CARD8buttons: LISTofCARD8These events contain information about the state of keys andbuttons on a device that will not fit into theDeviceStateNotify wire event. These events are not selectedby clients, rather they may immediately follow aDeviceStateNotify wire event and be combined with it into asingle DeviceStateNotify client event that a client mayreceive via XNextEvent.3.6. DeviceMappingNotify EventDeviceMappingNotifytime: TIMESTAMPdevice: CARD8request: CARD8first_keycode: CARD8count: CARD8This event reports a change in the mapping of keys,modifiers, or buttons on an extension device. This event isreported to clients selecting DeviceMappingNotify for thedevice and window and is generated after every clientSetDeviceButtonMapping, ChangeDeviceKeyMapping, orChangeDeviceModifierMapping request.3.7. ChangeDeviceNotify EventChangeDeviceNotifydevice: CARD8time: TIMESTAMPrequest: CARD8This event reports a change in the physical device beingused as the core X keyboard or X pointer device.ChangeDeviceNotify events are reported to clients selectingChangeDeviceNotify for the device and window and isgenerated after every client ChangeKeyboardDevice orChangePointerDevice request.3.8. Proximity EventsProximityInProximityOutdevice: CARD8root, event: WINDOWchild: Window or Nonesame-screen: BOOLroot-x, root-y, event-x, event-y: INT16state: SETofKEYBUTMASKtime: TIMESTAMPdevice-state: SETofKEYBUTMASKaxis-count: CARD8first-axis: CARD8axis-data: LISTofINT32These events are generated by some devices (such as graphicstablets or touchscreens) to indicate that a stylus has movedinto or out of contact with a positional sensing surface.The ‘‘source’’ of the event is the window the pointer is in.The window with respect to which the event is normallyreported is found by looking up the hierarchy (starting withthe source window) for the first window on which any clienthas selected interest in the event. The actual window usedfor reporting can be modified by active grabs and by thefocus window.The window the event is reported with respectto is called the ‘‘event’’ window.The root is the root window of the ‘‘source’’ window, androot-x and root-y are the pointer coordinates relative toroot’s origin at the time of the event. Event is the‘‘event’’ window. If the event window is on the same screenas root, then event-x and event-y are the pointercoordinates relative to the event window’s origin.Otherwise, event-x and event-y are zero. If the sourcewindow is an inferior of the event window, then child is setto the child of the event window that is an ancestor of (oris) the source window. Otherwise, it is set to None. Thestate component gives the logical state of the buttons onthe core X pointer and modifier keys on the core X keyboardjust before the event. The device-state component gives thestate of the buttons and modifiers on the device generatingthe event. 1

X11 Input Extension Protocol Specification

Version 1.0

X Consortium Standard

X Version 11, Release 6.4

Mark Patrick Ardent Computer

George Sachs Hewlett-Packard

Copyright © 1989, 1990, 1991 by Hewlett-Packard Company and Ardent Computer

Permission to use, copy, modify, and distribute this documentation for any purpose and without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. Ardent and Hewlett-Packard make no representations about the suitability for any purpose of the information in this document. It is provided "as is" without express or implied warranty.

Copyright © 1989, 1990, 1991, 1992 X Consortium

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘‘Software’’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED ‘‘AS IS’’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium.

X Window System is a trademark of X Consortium, Inc.

### 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 possible. Setting to−1 restores the default. Other negative values generate aValue error.If both auto_repeat_mode and key are specified, then theauto_repeat_mode of that key is changed, if possible. Ifonly auto_repeat_mode is specified, then the globalauto-repeat mode for the entire keyboard is changed, ifpossible, without affecting the per-key settings. It is aMatch error if a key is specified without anauto_repeat_mode.The order in which controls are verified and altered isserver-dependent. If an error is generated, a subset of thecontrols may have been altered.Those feedback controls equivalent to those of the corepointer are controlled by feedback class PtrFeedbackClassusing the PtrFeedbackControl structure. The members of thatstructure are as follows: The acceleration, expressed as a fraction, is a multiplierfor movement. For example, specifying 3/1 means the devicemoves three times as fast as normal. The fraction may berounded arbitrarily by the X server. Acceleration onlytakes effect if the device moves more than threshold pixelsat once and only applies to the amount beyond the value inthe threshold argument. Setting a value to -1 restores thedefault. The values of the do-accel and do-thresholdarguments must be nonzero for the device values to be set.Otherwise, the parameters will be unchanged. Negativevalues generate a Value error, as does a zero value for theaccel-denominator argument.Some devices are capable of displaying an integer. This isdone using feedback class IntegerFeedbackClass using theIntegerFeedbackControl structure. The members of thatstructure are as follows: Some devices are capable of displaying an string. This isdone using feedback class StringFeedbackClass using theStringFeedbackCtl structure. The members of that structureare as follows: Some devices contain a bell. This is done using feedbackclass BellFeedbackClass using the BellFeedbackControlstructure. The members of that structure are as follows: Some devices contain leds. These can be turned on and offusing the LedFeedbackControl structure. The members of thatstructure are as follows: Errors: Device, Match, Value2.20. Ringing a Bell on an Input DeviceTo ring a bell on an extension input device, use DeviceBell.DeviceBelldevice: DEVICEfeedbackclass: CARD8feedbackid: CARD8percent: INT8Errors: Device, ValueThis request is analogous to the core Bell request. Itrings the specified bell on the specified input devicefeedback, using the specified volume. The specified volumeis relative to the base volume for the feedback. If thevalue for the percent argument is not in the range -100 to100 inclusive, a Value error results. The volume at whichthe bell rings when the percent argument is nonnegative is:base - [(base * percent) / 100] + percentThe volume at which the bell rings when the percent argumentis negative is:base + [(base * percent) / 100]To change the base volume of the bell, useChangeFeedbackControl request.2.21. Controlling Device EncodingTo get the keyboard mapping of an extension device that haskeys, use GetDeviceKeyMapping.GetDeviceKeyMappingdevice: DEVICEfirst-keycode: KEYCODEcount: CARD8=> keysyms-per-keycode: CARD8keysyms: LISTofKEYSYMErrors: Device, Match, ValueThis request returns the symbols for the specified number ofkeycodes for the specified extension device, starting withthe specified keycode. The first-keycode must be greaterthan or equal to min-keycode as returned in the connectionsetup (else a Value error), andfirst-keycode + count − 1must be less than or equal to max-keycode as returned in theconnection setup (else a Value error). The number ofelements in the keysyms list iscount * keysyms-per-keycodeand KEYSYM number N (counting from zero) for keycode K hasan index (counting from zero) of(K − first-keycode) * keysyms-per-keycode + Nin keysyms. The keysyms-per-keycode value is chosenarbitrarily by the server to be large enough to report allrequested symbols. A special KEYSYM value of NoSymbol isused to fill in unused elements for individual keycodes.If the specified device has not first been opened by thisclient via OpenDevice, or if that device does not supportinput class Keys, this request will fail with a Deviceerror.To change the keyboard mapping of an extension device thathas keys, use ChangeDeviceKeyMapping.ChangeDeviceKeyMappingdevice: DEVICEfirst-keycode: KEYCODEkeysyms-per-keycode: CARD8keysyms: LISTofKEYSYMnum_codes: CARD8Errors: Device, Match, Value, AllocThis request is analogous to the core ChangeKeyMappingrequest. It defines the symbols for the specified number ofkeycodes for the specified extension device. If thespecified device has not first been opened by this clientvia OpenDevice, or if that device does not support inputclass Keys, this request will fail with a Device error.The number of elements in the keysyms list must be amultiple of keysyms_per_keycode. Otherwise,ChangeDeviceKeyMapping generates a Length error. Thespecified first_keycode must be greater than or equal to themin_keycode value returned by the ListInputDevices request,or this request will fail with a Value error. In addition,if the following expression is not less than the max_keycodevalue returned by the ListInputDevices request, the requestwill fail with a Value error:first_keycode + (num_codes / keysyms_per_keycode) - 1To obtain the keycodes that are used as modifiers on anextension device that has keys, useGetDeviceModifierMapping.GetDeviceModifierMappingdevice: DEVICE=> keycodes-per-modifier: CARD8keycodes: LISTofKEYCODEErrors: Device, MatchThis request is analogous to the core GetModifierMappingrequest. This request returns the keycodes of the keysbeing used as modifiers. The number of keycodes in the listis 8*keycodes-per-modifier. The keycodes are divided intoeight sets, with each set containing keycodes-per-modifierelements. The sets are assigned in order to the modifiersShift, Lock, Control, Mod1, Mod2, Mod3, Mod4, and Mod5. Thekeycodes-per-modifier value is chosen arbitrarily by theserver; zeroes are used to fill in unused elements withineach set. If only zero values are given in a set, the useof the corresponding modifier has been disabled. The orderof keycodes within each set is chosen arbitrarily by theserver.To set which keycodes that are to be used as modifiers foran extension device, use SetDeviceModifierMapping.SetDeviceModifierMappingdevice: DEVICEkeycodes-per-modifier: CARD8keycodes: LISTofKEYCODE=> status: {Success, Busy, Failed}Errors: Device, Match, Value, AllocThis request is analogous to the core SetModifierMappingrequest. This request specifies the keycodes (if any) ofthe keys to be used as modifiers. The number of keycodes inthe list must be 8*keycodes-per-modifier (else a Lengtherror). The keycodes are divided into eight sets, with thesets, with each set containing keycodes-per-modifierelements. The sets are assigned in order to the modifiersShift, Lock, Control, Mod1, Mod2, Mod3, Mod4, and Mod5.Only non-zero keycode values are used within each set; zerovalues are ignored. All of the non-zero keycodes must be inthe range specified by min-keycode and max-keycode in theListInputDevices request (else a Value error). The order ofkeycodes within a set does not matter. If no non-zerovalues are specified in a set, the use of the correspondingmodifier is disabled, and the modifier bit will always bezero. Otherwise, the modifier bit will be one whenever atleast one of the keys in the corresponding set is in thedown position.A server can impose restrictions on how modifiers can bechanged (for example, if certain keys do not generate uptransitions in hardware or if multiple keys per modifier arenot supported). The status reply is Failed if some suchrestriction is violated, and none of the modifiers arechanged.If the new non-zero keycodes specified for a modifier differfrom those currently defined, and any (current or new) keysfor that modifier are logically in the down state, then thestatus reply is Busy, and none of the modifiers are changed.This request generates a DeviceMappingNotify event on aSuccess status. The DeviceMappingNotify event will besent only to those clients that have expressed aninterest in receiving that event via theXSelectExtensionEvent request.A X server can impose restrictions on how modifiers can bechanged, for example, if certain keys do not generate uptransitions in hardware or if multiple modifier keys are notsupported. If some such restriction is violated, the statusreply is MappingFailed , and none of the modifiers arechanged. If the new keycodes specified for a modifierdiffer from those currently defined and any (current or new)keys for that modifier are in the logically down state, thestatus reply is MappingBusy, and none of the modifiers arechanged.2.22. Controlling Button MappingThese requests are analogous to the core GetPointerMappingand ChangePointerMapping requests. They allow a client todetermine the current mapping of buttons on an extensiondevice, and to change that mapping.To get the current button mapping for an extension device,use GetDeviceButtonMapping.GetDeviceButtonMappingdevice: DEVICEnmap: CARD8=> map_return: LISTofCARD8Errors: Device, MatchThe GetDeviceButtonMapping function returns the currentmapping of the buttons on the specified device. Elements ofthe list are indexed starting from one. The length of thelist indicates the number of physical buttons. The nominalmapping is the identity mapping map[i]=i.nmap indicates the number of elements in the map_returnarray. Only the first nmap entries will be copied by thelibrary into the map_return array.To set the button mapping for an extension device, useSetDeviceButtonMapping.SetDeviceButtonMappingdevice: DEVICEmap: LISTofCARD8nmap: CARD8=> status: CARD8Errors: Device, Match, ValueThe SetDeviceButtonMapping function sets the mapping of thespecified device and causes the X server to generate aDeviceMappingNotify event on a status of MappingSuccess.Elements of the list are indexed starting from one. Thelength of the list, specified in nmap, must be the same asGetDeviceButtonMapping would return. Otherwise,SetDeviceButtonMapping generates a Value error. A zeroelement disables a buttons, and elements are not restrictedin value by the number of physical buttons. However, no twoelements can have the same nonzero value. Otherwise, thisfunction generates a Value error. If any of the buttons tobe altered are in the down state, the status reply isMappingBusy and the mapping is not changed.2.23. Obtaining The State Of A DeviceTo obtain vectors that describe the state of the keys,buttons and valuators of an extension device, useQueryDeviceState.QueryDeviceStatedevice: DEVICE=> device-id: CARD8data: LISTofINPUTCLASSwhere Errors: DeviceThe QueryDeviceState request returns the current logicalstate of the buttons, keys, and valuators on the specifiedinput device. The buttons and keys arrays, byte N (from 0)contains the bits for key or button 8N to 8N+7 with theleast significant bit in the byte representing key or button8N.If the device has valuators, a bit in the mode fieldindicates whether the device is reporting Absolute orRelative data. If it is reporting Absolute data, thevaluators array will contain the current value of thevaluators. If it is reporting Relative data, the valuatorsarray will contain undefined data.If the device reports proximity information, a bit in themode field indicates whether the device is InProximity orOutOfProximity.3. EventsThe input extension creates input events analogous to thecore input events. These extension input events aregenerated by manipulating one of the extension inputdevices.3.1. Button, Key, and Motion EventsDeviceKeyPressDeviceKeyReleaseDeviceButtonPress,DeviceButtonReleaseDeviceMotionNotifydevice: CARD8root, event: WINDOWchild: Window or Nonesame-screen: BOOLroot-x, root-y, event-x, event-y: INT16detail: <see below>state: SETofKEYBUTMASKtime: TIMESTAMPThese events are generated when a key, button, or valuatorlogically changes state. The generation of these logicalchanges may lag the physical changes, if device eventprocessing is frozen. Note that DeviceKeyPress andDeviceKeyRelease are generated for all keys, even thosemapped to modifier bits. The ‘‘source’’ of the event is thewindow the pointer is in. The window with respect to whichthe event is normally reported is found by looking up thehierarchy (starting with the source window) for the firstwindow on which any client has selected interest in theevent. The actual window used for reporting can be modifiedby active grabs and by the focus window.The window the eventis reported with respect to is called the ‘‘event’’ window.The root is the root window of the ‘‘source’’ window, androot-x and root-y are the pointer coordinates relative toroot’s origin at the time of the event. Event is the‘‘event’’ window. If the event window is on the same screenas root, then event-x and event-y are the pointercoordinates relative to the event window’s origin.Otherwise, event-x and event-y are zero. If the sourcewindow is an inferior of the event window, then child is setto the child of the event window that is an ancestor of (oris) the source window. Otherwise, it is set to None. Thestate component gives the logical state of the buttons onthe core X pointer and modifier keys on the core X keyboardjust before the event. The detail component type varieswith the event type:Event ComponentDeviceKeyPress,DeviceKeyRelease KEYCODEDeviceButtonPress,DeviceButtonRelease BUTTONDeviceMotionNotify { Normal , Hint }The granularity of motion events is not guaranteed, but aclient selecting for motion events is guaranteed to get atleast one event when a valuator changes. If DeviceMotionHintis selected, the server is free to send only oneDeviceMotionNotify event (with detail Hint) to the clientfor the event window, until either a key or button changesstate, the pointer leaves the event window, or the clientissues a QueryDeviceState or GetDeviceMotionEvents request.3.2. DeviceValuator EventDeviceValuatordevice: CARD8device_state: SETofKEYBUTMASKnum_valuators: CARD8first_valuator: CARD8valuators: LISTofINT32DeviceValuator events are generated to contain valuatorinformation for which there is insufficient space inDeviceKey, DeviceButton, DeviceMotion, and Proximity wireevents. For events of these types, a second event of typeDeviceValuator follows immediately. The library combinesthese events into a single event that a client can receivevia XNextEvent. DeviceValuator events are not selected forby clients, they only exist to contain information that willnot fit into some event selected by clients.The device_state component gives the state of the buttonsand modifiers on the device generating the event.Extension motion devices may report motion data for avariable number of axes. The valuators array contains thevalues of all axes reported by the device. If more than 6axes are reported, more than one DeviceValuator event willbe sent by the server, and more than one DeviceKey,DeviceButton, DeviceMotion, or Proximity event will bereported by the library. Clients should examine thecorresponding fields of the event reported by the library todetermine the total number of axes reported, and the firstaxis reported in the current event. Axes are numberedbeginning with zero.For Button, Key and Motion events on a device reportingabsolute motion data the current value of the device’svaluators is reported. For devices that report relativedata, Button and Key events may be followed by aDeviceValuator event that contains 0s in the num_valuatorsfield. In this case, only the device_state component willhave meaning.3.3. Device Focus EventsDeviceFocusInDeviceFocusOutdevice: CARD8time: TIMESTAMPevent: WINDOWmode: { Normal, WhileGrabbed, Grab, Ungrab}detail: { Ancestor, Virtual, Inferior, Nonlinear,NonlinearVirtual, Pointer, PointerRoot, None}These events are generated when the input focus changes andare reported to clients selecting DeviceFocusChange for thespecified device and window. Events generated bySetDeviceFocus when the device is not grabbed have modeNormal. Events generated by SetDeviceFocus when the deviceis grabbed have mode WhileGrabbed. Events generated when adevice grab actives have mode Grab, and events generatedwhen a device grab deactivates have mode Ungrab.All DeviceFocusOut events caused by a window unmap aregenerated after any UnmapNotify event, but the ordering ofDeviceFocusOut with respect to generated EnterNotify,LeaveNotify, VisibilityNotify and Expose events is notconstrained.DeviceFocusIn and DeviceFocusOut events are generated forfocus changes of extension devices in the same manner asfocus events for the core devices are generated.3.4. Device State Notify EventDeviceStateNotifytime: TIMESTAMPdevice: CARD8num_keys: CARD8num_buttons: CARD8num_valuators: CARD8classes_reported: CARD8 {SetOfDeviceMode |SetOfInputClass}SetOfDeviceMode:#x80 ProximityState0 = InProxmity, 1 = OutOfProximity#x40 Device Mode(0 = Relative, 1 = Absolute)SetOfInputClass:#x04 reporting valuators#x02 reporting buttons#x01 reporting keysbuttons: LISTofCARD8keys: LISTofCARD8valuators: LISTofCARD32This event reports the state of the device just as in theQueryDeviceState request. This event is reported to clientsselecting DeviceStateNotify for the device and window and isgenerated immediately after every EnterNotify andDeviceFocusIn. If the device has no more than 32 buttons,no more than 32 keys, and no more than 3 valuators, Thisevent can report the state of the device. If the device hasmore than 32 buttons, the event will be immediately followedby a DeviceButtonStateNotify event. If the device has morethan 32 keys, the event will be followed by aDeviceKeyStateNotify event. If the device has more than 3valuators, the event will be followed by one or moreDeviceValuator events.3.5. Device KeyState and ButtonState Notify EventsDeviceKeyStateNotifydevice: CARD8keys: LISTofCARD8DeviceButtonStateNotifydevice: CARD8buttons: LISTofCARD8These events contain information about the state of keys andbuttons on a device that will not fit into theDeviceStateNotify wire event. These events are not selectedby clients, rather they may immediately follow aDeviceStateNotify wire event and be combined with it into asingle DeviceStateNotify client event that a client mayreceive via XNextEvent.3.6. DeviceMappingNotify EventDeviceMappingNotifytime: TIMESTAMPdevice: CARD8request: CARD8first_keycode: CARD8count: CARD8This event reports a change in the mapping of keys,modifiers, or buttons on an extension device. This event isreported to clients selecting DeviceMappingNotify for thedevice and window and is generated after every clientSetDeviceButtonMapping, ChangeDeviceKeyMapping, orChangeDeviceModifierMapping request.3.7. ChangeDeviceNotify EventChangeDeviceNotifydevice: CARD8time: TIMESTAMPrequest: CARD8This event reports a change in the physical device beingused as the core X keyboard or X pointer device.ChangeDeviceNotify events are reported to clients selectingChangeDeviceNotify for the device and window and isgenerated after every client ChangeKeyboardDevice orChangePointerDevice request.3.8. Proximity EventsProximityInProximityOutdevice: CARD8root, event: WINDOWchild: Window or Nonesame-screen: BOOLroot-x, root-y, event-x, event-y: INT16state: SETofKEYBUTMASKtime: TIMESTAMPdevice-state: SETofKEYBUTMASKaxis-count: CARD8first-axis: CARD8axis-data: LISTofINT32These events are generated by some devices (such as graphicstablets or touchscreens) to indicate that a stylus has movedinto or out of contact with a positional sensing surface.The ‘‘source’’ of the event is the window the pointer is in.The window with respect to which the event is normallyreported is found by looking up the hierarchy (starting withthe source window) for the first window on which any clienthas selected interest in the event. The actual window usedfor reporting can be modified by active grabs and by thefocus window.The window the event is reported with respectto is called the ‘‘event’’ window.The root is the root window of the ‘‘source’’ window, androot-x and root-y are the pointer coordinates relative toroot’s origin at the time of the event. Event is the‘‘event’’ window. If the event window is on the same screenas root, then event-x and event-y are the pointercoordinates relative to the event window’s origin.Otherwise, event-x and event-y are zero. If the sourcewindow is an inferior of the event window, then child is setto the child of the event window that is an ancestor of (oris) the source window. Otherwise, it is set to None. Thestate component gives the logical state of the buttons onthe core X pointer and modifier keys on the core X keyboardjust before the event. The device-state component gives thestate of the buttons and modifiers on the device generatingthe event. 1

X Input Extension Protocol Specification X11, Release 6.4

Appendix A

Input Extension Protocol Encoding

Syntactic Conventions

All numbers are in decimal, unless prefixed with #x, in which case they are in hexadecimal (base 16).

The general syntax used to describe requests, replies, errors, events, and compound types is:

| NameofThing encode-form ... encode-form

Each encode-form describes a single component.

For components described in the protocol as:

| name: TYPE

the encode-form is:

| N |  | TYPE |
|  |  | name |

N is the number of bytes occupied in the data stream, and TYPE is the interpretation of those bytes. For example,

| depth: CARD8

becomes:

| 1 | CARD8 |  | depth

For components with a static numeric value the encode-form is:

| N | value |  | name

The value is always interpreted as an N-byte unsigned integer. For example, the first two bytes of a Window error are always zero (indicating an error in general) and three (indicating the Window error in particular):

| 1 |  | 0 |
|  |  | Error |
| 1 |  | 3 |
|  |  | code |

For components described in the protocol as:

| name: {Name1, ..., NameI}

the encode-form is:

| N |  |  |
|  |  | name |
|  |  | value1 Name1 |
|  |  | ... |
|  |  | valueI NameI |

The value is always interpreted as an N-byte unsigned integer. Note that the size of N is sometimes larger than that strictly required to encode the values. For example:

| class: {InputOutput, InputOnly, CopyFromParent}

becomes:

| 2 |  |  |  |
|  |  |  |  | class
|  |  | 0 |  |
|  |  | CopyFromParent |  |
|  |  | 1 |  |
|  |  | InputOutput |  |
|  |  | 2 |  |
|  |  | InputOnly |  |

For components described in the protocol as:

| NAME: TYPE or Alternative1 ... or AlternativeI

the encode-form is:

| N |  | TYPE |  |  | NAME
|  |  | value1 |  | Alternative1 |
|  |  | ... |  |  |
|  |  | valueI |  | AlternativeI |

The alternative values are guaranteed not to conflict with the encoding of TYPE. For example:

| destination: WINDOW or PointerWindow or InputFocus

becomes:

| 4 |  | WINDOW | destination
|  |  | 0 |
|  |  | PointerWindow |
|  |  | 1 |
|  |  | InputFocus |

For components described in the protocol as:

| value-mask: BITMASK

the encode-form is:

| N | BITMASK |  |  |
|  |  |  |  | value-mask
|  | mask1 |  |  | mask-name1
|  | ... |  |  |
|  | maskI |  |  | mask-nameI

The individual bits in the mask are specified and named, and N is 2 or 4. The most-significant bit in a BITMASK is reserved for use in defining chained (multiword) bitmasks, as extensions augment existing core requests. The precise interpretation of this bit is not yet defined here, although a probable mechanism is that a 1-bit indicates that another N bytes of bitmask follows, with bits within the overall mask still interpreted from least-significant to most-significant with an N-byte unit, with N-byte units interpreted in stream order, and with the overall mask being byte-swapped in individual N-byte units.

For LISTofVALUE encodings, the request is followed by a section of the form:

| VALUEs encode-form ... encode-form

listing an encode-form for each VALUE. The NAME in each encode-form keys to the corresponding BITMASK bit. The encoding of a VALUE always occupies four bytes, but the number of bytes specified in the encoding-form indicates how many of the least-significant bytes are actually used; the remaining bytes are unused and their values do not matter.

In various cases, the number of bytes occupied by a component will be specified by a lowercase single-letter variable name instead of a specific numeric value, and often some other component will have its value specified as a simple numeric expression involving these variables. Components specified with such expressions are always interpreted as unsigned integers. The scope of such variables is always just the enclosing request, reply, error, event, or compound type structure. For example:

| 2 |  | 3+n |  |
|  |  |  |  | request length
| 4n |  | LISTofPOINT |  | points

For unused bytes (the values of the bytes are undefined and do not matter), the encode-form is:

| N |  |  |  | unused

If the number of unused bytes is variable, the encode-form typically is:

| p |  |  |  | unused, p=pad(E)

where E is some expression, and pad(E) is the number of bytes needed to round E up to a multiple of four.

| pad(E) = (4 - (E mod 4)) mod 4

Common Types

LISTofFOO

| In this document the LISTof notation strictly means some number of repetitions of the FOO encoding; the actual length of the list is encoded elsewhere.

SETofFOO

| A set is always represented by a bitmask, with a 1-bit indicating presence in the set.

BITMASK: CARD32

WINDOW: CARD32

BYTE: 8-bit value

INT8: 8-bit signed integer

INT16: 16-bit signed integer

INT32: 32-bit signed integer

CARD8: 8-bit unsigned integer

CARD16: 16-bit unsigned integer

CARD32: 32-bit unsigned integer

TIMESTAMP: CARD32

EVENTCLASS: CARD32

INPUTCLASS

| 0 | KeyClass
| 1 | ButtonClass
| 2 | ValuatorClass
| 3 | FeedbackClass
| 4 | ProximityClass
| 5 | FocusClass
| 6 | OtherClass

INPUTCLASS

| 0 | KbdFeedbackClass
| 1 | PtrFeedbackClass
| 2 | StringFeedbackClass
| 3 | IntegerFeedbackClass
| 4 | LedFeedbackClass
| 5 | BellFeedbackClass

INPUTINFO

| 0 | KEYINFO
| 1 | BUTTONINFO
| 2 | VALUATORINFO

DEVICEMODE

| 0 | Relative
| 1 | Absolute

PROXIMITYSTATE

| 0 | InProximity
| 1 | OutOfProximity

BOOL

| 0 | False
| 1 | True

KEYSYM: CARD32

KEYCODE: CARD8

BUTTON: CARD8

SETofKEYBUTMASK

| #x0001 | Shift
| #x0002 | Lock
| #x0004 | Control
| #x0008 | Mod1
| #x0010 | Mod2
| #x0020 | Mod3
| #x0040 | Mod4
| #x0080 | Mod5
| #x0100 | Button1
| #x0200 | Button2
| #x0400 | Button3
| #x0800 | Button4
| #x1000 | Button5
| #xe000 | unused but must be zero

SETofKEYMASK

| encodings are the same as for SETofKEYBUTMASK, except with |
| #xff00 | unused but must be zero

STRING8: LISTofCARD8

STR

| 1 | n |  | length of name in bytes
| n | STRING8 |  | name

Errors

Request

| 1 | 0 |  | Error
| 1 | 1 |  | code
| 2 | CARD16 |  | sequence number
| 4 |  |  | unused
| 2 | CARD16 |  | minor opcode
| 1 | CARD8 |  | major opcode
| 21 |  |  | unused

Value

| 1 | 0 |  | Error
| 1 | 2 |  | code
| 2 | CARD16 |  | sequence number
| 4 | <32-bits> |  | bad value
| 2 | CARD16 |  | minor opcode
| 1 | CARD8 |  | major opcode
| 21 |  |  | unused

Window

| 1 | 0 |  | Error
| 1 | 3 |  | code
| 2 | CARD16 |  | sequence number
| 4 | CARD32 |  | bad resource id
| 2 | CARD16 |  | minor opcode
| 1 | CARD8 |  | major opcode
| 21 |  |  | unused

Match

| 1 | 0 |  | Error
| 1 | 8 |  | code
| 2 | CARD16 |  | sequence number
| 4 |  |  | unused
| 2 | CARD16 |  | minor opcode
| 1 | CARD8 |  | major opcode
| 21 |  |  | unused

Access

| 1 | 0 |  | Error
| 1 | 10 |  | code
| 2 | CARD16 |  | sequence number
| 4 |  |  | unused
| 2 | CARD16 |  | minor opcode
| 1 | CARD8 |  | major opcode
| 21 |  |  | unused

Alloc

| 1 | 0 |  | Error
| 1 | 11 |  | code
| 2 | CARD16 |  | sequence number
| 4 |  |  | unused
| 2 | CARD16 |  | minor opcode
| 1 | CARD8 |  | major opcode
| 21 |  |  | unused

Name

| 1 | 0 |  | Error
| 1 | 15 |  | code
| 2 | CARD16 |  | sequence number
| 4 |  |  | unused
| 2 | CARD16 |  | minor opcode
| 1 | CARD8 |  | major opcode
| 21 |  |  | unused

Device

| 1 | 0 |  | Error
| 1 | CARD8 |  | code
| 2 | CARD16 |  | sequence number
| 4 |  |  | unused
| 2 | CARD16 |  | minor opcode
| 1 | CARD8 |  | major opcode
| 21 |  |  | unused

Event

| 1 | 0 |  | Error
| 1 | CARD8 |  | code
| 2 | CARD16 |  | sequence number
| 4 |  |  | unused
| 2 | CARD16 |  | minor opcode
| 1 | CARD8 |  | major opcode
| 21 |  |  | unused

Mode

| 1 | 0 |  | Error
| 1 | CARD8 |  | code
| 2 | CARD16 |  | sequence number
| 4 |  |  | unused
| 2 | CARD16 |  | minor opcode
| 1 | CARD8 |  | major opcode
| 21 |  |  | unused

Class

| 1 | 0 |  | Error
| 1 | CARD8 |  | code
| 2 | CARD16 |  | sequence number
| 4 |  |  | unused
| 2 | CARD16 |  | minor opcode
| 1 | CARD8 |  | major opcode
| 21 |  |  | unused

Keyboards

KEYCODE values are always greater than 7 (and less than 256).

KEYSYM values with the bit #x10000000 set are reserved as vendor-specific.

The names and encodings of the standard KEYSYM values are contained in appendix F.

Pointers

BUTTON values are numbered starting with one.

Requests

GetExtensionVersion

| 1 | CARD8 |  | input extension opcode
| 1 | 1 |  | GetExtensionVersion opcode
| 2 | 2+(n+p)/4 |  | request length
| 2 | n |  | length of name
| 2 |  |  | unused
| n | STRING8 |  | name
| p |  |  | unused, p=pad(n)

=>

| 1 | 1 |  | Reply
| 1 | 1 |  | GetExtensionVersion opcode
| 2 | CARD16 |  | sequence number
| 4 | 0 |  | reply length
| 2 | CARD16 |  | major version
| 2 | CARD16 |  | minor version
| 1 | BOOL |  | present
| 19 |  |  | unused

ListInputDevices

| 1 | CARD8 |  | input extension opcode
| 1 | 2 |  | ListInputDevices opcode
| 2 | 1 |  | request length

=>

| 1 | 1 |  | Reply
| 1 | 2 |  | ListInputDevices opcode
| 2 | CARD16 |  | sequence number
| 4 | (n+p)/4 |  | reply length
| 1 | CARD8 |  | number of input devices
| 23 |  |  | unused
| n | LISTofDEVICEINFO |  | info for each input device
| p |  |  | unused, p=pad(n)

DEVICEINFO

| 4 | CARD32 |  | device type
| 1 | CARD8 |  | device id
| 1 | CARD8 |  | number of input classes this device reports
| 1 | CARD8 |  | device use
|  |  | 0 | IsXPointer
|  |  | 1 | IsXKeyboard
|  |  | 2 | IsXExtensionDevice
| 1 |  |  | unused
| n | LISTofINPUTINFO |  | input info for each input class
| m | STR |  | name
| p |  |  | unused, p=pad(m) INPUTINFO
|  |  | KEYINFO or BUTTONINFO or VALUATORINFO |

KEYINFO

| 1 | 0 |  | class id
| 1 | 8 |  | length
| 1 | KEYCODE |  | minimum keycode
| 1 | KEYCODE |  | maximum keycode
| 2 | CARD16 |  | number of keys
| 2 |  |  | unused

BUTTONINFO

| 1 | 1 |  | class id
| 1 | 4 |  | length
| 2 | CARD16 |  | number of buttons

VALUATORINFO

| 1 | 2 |  | class id
| 1 | 8+12n |  | length
| 1 | n |  | number of axes
| 1 | SETofDEVICEMODE |  | mode
| 4 | CARD32 |  | size of motion buffer
| 12n | LISTofAXISINFO |  | valuator limits

AXISINFO

| 4 | CARD32 |  | resolution
| 4 | CARD32 |  | minimum value
| 4 | CARD32 |  | maximum value

OpenDevice

| 1 | CARD8 |  | input extension opcode
| 1 | 3 |  | OpenDevice opcode
| 2 | 2 |  | request length
| 1 | CARD8 |  | device id
| 3 |  |  | unused

=>

| 1 | 1 |  | Reply
| 1 | 3 |  | OpenDevice opcode
| 2 | CARD16 |  | sequence number
| 4 | (n+p)/4 |  | reply length
| 1 | CARD8 |  | number of input classes
| 23 |  |  | unused
| n | LISTofINPUTCLASSINFO |  | input class information
| p |  |  | unused, p=pad(n)

INPUTCLASSINFO

| 1 | CARD8 |  | input class id
|  | 0 | KEY |
|  | 1 | BUTTON |
|  | 2 | VALUATOR |
|  | 3 | FEEDBACK |
|  | 4 | PROXIMITY |
|  | 5 | FOCUS |
|  | 6 | OTHER |
| 1 | CARD8 |  | event type base code for this class

CloseDevice

| 1 | CARD8 |  | input extension opcode
| 1 | 4 |  | CloseDevice opcode
| 2 | 2 |  | request length
| 1 | CARD8 |  | device id
| 3 |  |  | unused

SetDeviceMode

| 1 | CARD8 |  | input extension opcode
| 1 | 5 |  | SetDeviceMode opcode
| 2 | 2 |  | request length
| 1 | CARD8 |  | device id
| 1 | CARD8 |  | mode
| 2 |  |  | unused

=>

| 1 | 1 |  | Reply
| 1 | 5 |  | SetDeviceMode opcode
| 2 | CARD16 |  | sequence number
| 4 | 0 |  | reply length
| 1 | CARD8 |  | status
|  | 0 |  | Success
|  |  | 1 | AlreadyGrabbed
|  | 3 + first_error |  | DeviceBusy
| 23 |  |  | unused

SelectExtensionEvent

| 1 | CARD8 |  | input extension opcode
| 1 | 6 |  | SelectExtensionEvent opcode
| 2 | 3+n |  | request length
| 4 | Window |  | event window
| 2 | CARD16 |  | count
| 2 |  |  | unused
| 4n | LISTofEVENTCLASS |  | desired events

GetSelectedExtensionEvents

| 1 | CARD8 |  | input extension opcode
| 1 | 7 |  | GetSelectedExtensionEvents opcode
| 2 | 2 |  | request length
| 4 | Window |  | event window

=>

| 1 | 1 |  | Reply
| 1 | 7 |  | GetSelecteExtensionEvents opcode
| 2 | CARD16 |  | sequence number
| 4 | n + m |  | reply length
| 2 | n |  | this client count
| 2 | m |  | all clients count
| 20 |  |  | unused
| 4n | LISTofEVENTCLASS |  | this client list
| 4m | LISTofEVENTCLASS |  | all clients list

ChangeDeviceDontPropagateList

| 1 | CARD8 |  | input extension opcode
| 1 | 8 |  | ChangeDeviceDontPropagateList opcode
| 2 | 3+n |  | request length
| 4 | Window |  | event window
| 2 | n |  | count of events
| 1 | mode |  |
|  | 0 | AddToList |
|  | 1 | DeleteFromList |
| 1 |  |  | unused
| 4n | LISTofEVENTCLASS |  | desired events

GetDeviceDontPropagateList

| 1 | CARD8 |  | input extension opcode
| 1 | 9 |  | GetDeviceDontPropagateList opcode
| 2 | 2 |  | request length
| 4 | Window |  | event window

=>

| 1 | 1 |  | Reply
| 1 | 9 |  | GetDeviceDontPropagateList opcode
| 2 | CARD16 |  | sequence number
| 4 | n |  | reply length
| 2 | n |  | count of events
| 22 |  |  | unused
| 4n | LISTofEVENTCLASS |  | don’t propagate list

GetDeviceMotionEvents

| 1 | CARD8 |  | input extension opcode
| 1 | 10 |  | GetDeviceMotionEvents opcode
| 2 | 4 |  | request length
| 4 | TIMESTAMP |  | start
|  | 0 | CurrentTime |
| 4 | TIMESTAMP |  | stop
|  | 0 | CurrentTime |
| 1 | CARD8 |  | device id
| 3 |  |  | unused

=>

| 1 |  | 1 | Reply
| 1 |  | 10 | GetDeviceMotionEvents opcode
| 2 |  | CARD16 | sequence number
| 4 |  | (m+1)n | reply length
| 4 |  | n | number of DEVICETIMECOORDs in events
| 1 |  | m | number of valuators per event
| 1 |  | CARD8 | mode of the device
|  |  | 0 | Absolute
|  |  | 1 | Relative
| 18 |  |  | unused
| (4m+4)n |  | LISTofDEVICETIMECOORDevents |

DEVICETIMECOORD

| 4 | TIMESTAMP |  | time
| 4m | LISTofINT32 |  | valuators

ChangeKeyboardDevice

| 1 | CARD8 |  | input extension opcode
| 1 | 11 |  | ChangeKeyboardDevice opcode
| 2 | 2 |  | request length
| 1 | CARD8 |  | device id
| 3 |  |  | unused

=>

| 1 | 1 |  | Reply
| 1 | 11 |  | ChangeKeyboardDevice opcode
| 2 | CARD16 |  | sequence number
| 4 | 0 |  | reply length
| 1 |  |  | status
|  | 0 | Success |
|  | 1 | AlreadyGrabbed |
|  | 2 | DeviceFrozen |
| 23 |  |  | unused

ChangePointerDevice

| 1 | CARD8 |  | input extension opcode
| 1 | 12 |  | ChangePointerDevice opcode
| 2 | 2 |  | request length
| 1 | CARD8 |  | x-axis
| 1 | CARD8 |  | y-axis
| 1 | CARD8 |  | device id
| 1 |  |  | unused

=>

| 1 | 1 |  | Reply
| 1 | 12 |  | ChangePointerDevice opcode
| 2 | CARD16 |  | sequence number
| 4 | 0 |  | reply length
| 1 |  |  | status
|  | 0 | Success |
|  | 1 | AlreadyGrabbed |
|  | 2 | DeviceFrozen |
| 23 |  |  | unused

GrabDevice

| 1 | CARD8 |  | input extension opcode
| 1 | 13 |  | GrabDevice opcode
| 2 | 5+n |  | request length
| 4 | WINDOW |  | grab-window
| 4 | TIMESTAMP |  | time
|  | 0 | CurrentTime |
| 2 | n |  | count of events
| 1 |  |  | this-device-mode
|  | 0 | Synchronous |
|  | 1 | Asynchronous |
| 1 |  |  | other-devices-mode
|  | 0 | Synchronous |
|  | 1 | Asynchronous |
| 1 | BOOL |  | owner-events
| 1 | CARD8 |  | device id
| 2 |  |  | unused
| 4n | LISTofEVENTCLASS |  | event list

=>

| 1 | 1 |  | Reply
| 1 | 13 |  | GrabDevice opcode
| 2 | CARD16 |  | sequence number
| 4 | 0 |  | reply length
| 1 |  |  | status
|  | 0 | Success |
|  | 1 | AlreadyGrabbed |
|  | 2 | InvalidTime |
|  | 3 | NotViewable |
|  | 4 | Frozen |
| 23 |  |  | unused

UngrabDevice

| 1 | CARD8 |  | input extension opcode
| 1 | 14 |  | UngrabDevice opcode
| 2 | 3 |  | request length
| 4 | TIMESTAMP |  | time
|  | 0 | CurrentTime |
| 1 | CARD8 |  | device id
| 3 |  |  | unused

GrabDeviceKey

| 1 | CARD8 |  | input extension opcode
| 1 | 15 |  | GrabDeviceKey opcode
| 2 | 5+n |  | request length
| 4 | WINDOW |  | grab-window
| 2 | n |  | count of events
| 2 | SETofKEYMASK |  | modifiers
|  | #x8000 | AnyModifier |
| 1 | CARD8 |  | modifier device
|  | #x0FF | UseXKeyboard |
| 1 | CARD8 |  | grabbed device
| 1 | KEYCODE |  | key
|  | 0 | AnyKey |
| 1 |  |  | this-device-mode
|  | 0 | Synchronous |
|  | 1 | Asynchronous |
| 1 |  |  | other-devices-mode
|  | 0 | Synchronous |
|  | 1 | Asynchronous |
| 1 | BOOL |  | owner-events
| 2 |  |  | unused
| 4n | LISTofEVENTCLASS |  | event list

UngrabDeviceKey

| 1 | CARD8 |  | input extension opcode
| 1 | 16 |  | UngrabDeviceKey opcode
| 2 | 4 |  | request length
| 4 | WINDOW |  | grab-window
| 2 | SETofKEYMASK |  | modifiers
|  | #x8000 | AnyModifier |
| 1 | CARD8 |  | modifier device
|  | #x0FF | UseXKeyboard |
| 1 | KEYCODE |  | key
|  | 0 | AnyKey |
| 1 | CARD8 |  | grabbed device
| 3 |  |  | unused

GrabDeviceButton

| 1 | CARD8 |  | input extension opcode
| 1 | 17 |  | GrabDeviceButton opcode
| 2 | 5+n |  | request length
| 4 | WINDOW |  | grab-window
| 1 | CARD8 |  | grabbed device
| 1 | CARD8 |  | modifier device
|  | #x0FF | UseXKeyboard |
| 2 | n |  | count of desired events
| 2 | SETofKEYMASK |  | modifiers
| 1 |  |  | this-device-mode
|  | 0 | Synchronous |
|  | 1 | Asynchronous |
| 1 |  |  | other-device-mode
|  | 0 | Synchronous |
|  | 1 | Asynchronous |
| 1 | BUTTON |  | button
|  | 0 | AnyButton |
| 1 | BOOL |  | owner-events
|  | #x8000 | AnyModifier |
| 2 |  |  | unused
| 4n | LISTofEVENTCLASS |  | event list

UngrabDeviceButton

| 1 | CARD8 |  | input extension opcode
| 1 | 18 |  | UngrabDeviceButton opcode
| 2 | 4 |  | request length
| 4 | WINDOW |  | grab-window
| 2 | SETofKEYMASK |  | modifiers
|  | #x8000 | AnyModifier |
| 1 | CARD8 |  | modifier device
|  | #x0FF | UseXKeyboard |
| 1 | BUTTON |  | button
|  | 0 | AnyButton |
| 1 | CARD8 |  | grabbed device
| 3 |  |  | unused

AllowDeviceEvents

| 1 | CARD8 |  | input extension opcode
| 1 | 19 |  | AllowDeviceEvents opcode
| 2 | 3 |  | request length
| 4 | TIMESTAMP |  | time
|  | 0 | CurrentTime |
| 1 |  |  | mode
|  | 0 | AsyncThisDevice |
|  | 1 | SyncThisDevice |
|  | 2 | ReplayThisDevice |
|  | 3 | AsyncOtherDevices |
|  | 4 | AsyncAll |
|  | 5 | SyncAll |
| 1 | CARD8 |  | device id
| 2 |  |  | unused

GetDeviceFocus

| 1 | CARD8 |  | input extension opcode
| 1 | 20 |  | GetDeviceFocus opcode
| 2 | 2 |  | request length
| 1 | CARD8 |  | device
| 3 |  |  | unused

=>

| 1 | 1 |  | Reply
| 1 | 20 |  | GetDeviceFocus opcode
| 2 | CARD16 |  | sequence number
| 4 | 0 |  | reply length
| 4 | WINDOW |  | focus
|  | 0 | None |
|  | 1 | PointerRoot |
|  | 3 | FollowKeyboard |
| 4 | TIMESTAMP | focus time |
| 1 |  |  | revert-to
|  | 0 | None |
|  | 1 | PointerRoot |
|  | 2 | Parent |
|  | 3 | FollowKeyboard |
| 15 |  |  | unused

SetDeviceFocus

| 1 | CARD8 |  | input extension opcode
| 1 | 21 |  | SetDeviceFocus opcode
| 2 | 4 |  | request length
| 4 | WINDOW |  | focus
|  | 0 | None |
|  | 1 | PointerRoot |
|  | 3 | FollowKeyboard |
| 4 | TIMESTAMP |  | time
|  | 0 | CurrentTime |
| 1 |  |  | revert-to
|  | 0 | None |
|  | 1 | PointerRoot |
|  | 2 | Parent |
|  | 3 | FollowKeyboard |
| 1 | CARD8 |  | device
| 2 |  |  | unused

GetFeedbackControl

| 1 | CARD8 |  | input extension opcode
| 1 | 22 |  | GetFeedbackControl opcode
| 2 | 2 |  | request length
| 1 | CARD8 |  | device id
| 3 |  |  | unused

=>

| 1 | 1 |  | Reply
| 1 | 22 |  | GetFeedbackControl opcode
| 2 | CARD16 |  | sequence number
| 4 | m/4 |  | reply length
| 2 | n |  | number of feedbacks supported
| 22 |  |  | unused
| m | LISTofFEEDBACKSTATE |  | feedbacks FEEDBACKSTATE
|  |  |  | KBDFEEDBACKSTATE, PTRFEEDBACKSTATE, INTEGERFEEDBACKSTATE,

STRINGFEEDBACKSTATE, BELLFEEDBACKSTATE, or LEDFEEDBACKSTATE

KBDFEEDBACKSTATE

| 1 | 0 |  | feedback class id
| 1 | CARD8 |  | id of this feedback
| 2 | 20 |  | length
| 2 | CARD16 |  | pitch
| 2 | CARD16 |  | duration
| 4 | CARD32 |  | led_mask
| 4 | CARD32 |  | led_values
| 1 |  |  | global_auto_repeat
|  | 0 | Off |
|  | 1 | On |
| 1 | CARD8 |  | click
| 1 | CARD8 |  | percent
| 1 |  |  | unused
| 32 | LISTofCARD8 |  | auto_repeats

PTRFEEDBACKSTATE

| 1 | 0 |  | feedback class id
| 1 | CARD8 |  | id of this feedback
| 2 | 12 |  | length
| 2 |  |  | unused
| 2 | CARD16 |  | acceleration-numerator
| 2 | CARD16 |  | acceleration-denominator
| 2 | CARD16 |  | threshold

INTEGERFEEDBACKSTATE

| 1 | 0 |  | feedback class id
| 1 | CARD8 |  | id of this feedback
| 2 | 16 |  | length
| 4 | CARD32 |  | resolution
| 4 | INT32 |  | minimum value
| 4 | INT32 |  | maximum value

STRINGFEEDBACKSTATE

| 1 | 1 |  | feedback class id
| 1 | CARD8 |  | id of this feedback
| 2 | 4n+8 |  | length
| 2 | CARD16 |  | max_symbols
| 2 | n |  | number of keysyms supported
| 4n | LISTofKEYSYM |  | key symbols supported

BELLFEEDBACKSTATE

| 1 | 1 |  | feedback class id
| 1 | CARD8 |  | id of this feedback
| 2 | 12 |  | length
| 1 | CARD8 |  | percent
| 3 |  |  | unused
| 2 | CARD16 |  | pitch
| 2 | CARD16 |  | duration

LEDFEEDBACKSTATE

| 1 | 1 |  | feedback class id
| 1 | CARD8 |  | id of this feedback
| 2 | 12 |  | length
| 4 | CARD32 |  | led_mask
| 4 | BITMASK |  | led_values
|  | #x0001 | On |
|  | #x0002 | Off |

ChangeFeedbackControl

| 1 | CARD8 |  | input extension opcode
| 1 | 23 |  | ChangeFeedbackControl opcode
| 2 | 3+n/4 |  | request length
| 4 | BITMASK |  | value-mask (has n bits set to 1)
|  | #x0001 | keyclick-percent |
|  | #x0002 | bell-percent |
|  | #x0004 | bell-pitch |
|  | #x0008 | bell-duration |
|  | #x0010 | led |
|  | #x0020 | led-mode |
|  | #x0040 | key |
|  | #x0080 | auto-repeat-mode |
|  | #x0001 | string |
|  | #x0001 | integer |
|  | #x0001 | acceleration-numerator |
|  | #x0002 | acceleration-denominator |
|  | #x0004 | acceleration-threshold |
| 1 | CARD8 |  | device id
| 1 | CARD8 |  | feedback class id
| 2 |  |  | unused
| n | FEEDBACKCLASS FEEDBACKCLASS |  | KBDFEEDBACKCTL, PTRFEEDBACKCTL, INTEGERFEEDBACKCTL,

STRINGFEEDBACKCTL, BELLFEEDBACKCTL, or LEDFEEDBACKCTL

KBDFEEDBACKCTL

| 1 | 0 |  | feedback class id
| 1 | CARD8 |  | id of this feedback
| 2 | 20 |  | length
| 1 | KEYCODE |  | key
| 1 |  |  | auto-repeat-mode
|  | 0 | Off |
|  | 1 | On |
|  | 2 | Default |
| 1 | INT8 |  | key-click-percent
| 1 | INT8 |  | bell-percent
| 2 | INT16 |  | bell-pitch
| 2 | INT16 |  | bell-duration
| 4 | CARD32 |  | led_mask
| 4 | CARD32 |  | led_values

PTRFEEDBACKCTL

| 1 | 1 |  | feedback class id
| 1 | CARD8 |  | id of this feedback
| 2 | 12 |  | length
| 2 |  |  | unused
| 2 | INT16 |  | numerator
| 2 | INT16 |  | denominator
| 2 | INT16 |  | threshold

STRINGCTL

| 1 | 2 |  | feedback class id
| 1 | CARD8 |  | id of this feedback
| 2 | 4n+8 |  | length
| 2 |  |  | unused
| 2 | n |  | number of keysyms to display
| 4n | LISTofKEYSYM |  | list of key symbols to display

INTEGERCTL

| 1 | 3 |  | feedback class id
| 1 | CARD8 |  | id of this feedback
| 2 | 8 |  | length
| 4 | INT32 |  | integer to display

LEDCTL

| 1 | 4 |  | feedback class id
| 1 | CARD8 |  | id of this feedback
| 2 | 12 |  | length
| 4 | CARD32 |  | led_mask
| 4 | BITMASK |  | led_values
|  | #x0001 | On |
|  | #x0002 | Off |

BELLCTL

| 1 | 5 |  | feedback class id
| 1 | CARD8 |  | id of this feedback
| 2 | 8 |  | length
| 1 | INT8 |  | percent
| 3 |  |  | unused
| 2 | INT16 |  | pitch
| 2 | INT16 |  | duration

GetDeviceKeyMapping

| 1 | CARD8 |  | input extension opcode
| 1 | 24 |  | GetDeviceKeyMapping opcode
| 2 | 2 |  | request length
| 1 | CARD8 |  | device
| 1 | KEYCODE |  | first-keycode
| 1 | CARD8 |  | count
| 1 |  |  | unused

=>

| 1 | 1 |  | Reply
| 1 | 24 |  | GetDeviceKeyMapping opcode
| 2 | CARD16 |  | sequence number
| 4 | nm |  | reply length (m = count field from the request)
| 1 | n |  | keysyms-per-keycode
| 23 |  |  | unused
| 4nm | LISTofKEYSYM |  | keysyms

ChangeDeviceKeyMapping

| 1 | CARD8 |  | input extension opcode
| 1 | 25 |  | ChangeDeviceKeyMapping opcode
| 2 | 2+nm |  | request length
| 1 | CARD8 |  | device
| 1 | KEYCODE |  | first-keycode
| 1 | m |  | keysyms-per-keycode
| 1 | n |  | keycode-count
| 4nm | LISTofKEYSYM |  | keysyms

GetDeviceModifierMapping

| 1 | CARD8 |  | input extension opcode
| 1 | 26 |  | GetDeviceModifierMapping opcode
| 2 | 2 |  | request length
| 1 | CARD8 |  | device
| 3 |  |  | unused

=>

| 1 | 1 |  | Reply
| 1 | 26 |  | GetDeviceModifierMapping opcode
| 2 | CARD16 |  | sequence number
| 4 | 2n |  | reply length
| 1 | n |  | keycodes-per-modifier
| 23 |  |  | unused
| 8n | LISTofKEYCODE |  | keycodes

SetDeviceModifierMapping

| 1 | CARD8 |  | input extension opcode
| 1 | 27 |  | SetDeviceModifier opcode
| 2 | 2+2n |  | request length
| 1 | CARD8 |  | device
| 1 | n |  | keycodes-per-modifier
| 2 |  |  | unused
| 8n | LISTofKEYCODE |  | keycodes

=>

| 1 | 1 |  | Reply
| 1 | 27 |  | SetDeviceModifierMapping opcode
| 2 | CARD16 |  | sequence number
| 4 | 0 |  | reply length
| 1 |  |  | status
|  | 0 | Success |
|  | 1 | Busy |
|  | 2 | Failed |
| 23 |  |  | unused

GetDeviceButtonMapping

| 1 | CARD8 |  | input extension opcode
| 1 | 28 |  | GetDeviceButtonMapping opcode
| 2 | 2 |  | request length
| 1 | CARD8 |  | device
| 3 |  |  | unused

=>

| 1 | 1 |  | Reply
| 1 | 28 |  | GetDeviceButtonMapping opcode
| 2 | CARD16 |  | sequence number
| 4 | (n+p)/4 |  | reply length
| 1 | n |  | number of elements in map list
| 23 |  |  | unused
| n | LISTofCARD8 |  | map
| p |  |  | unused, p=pad(n)

SetDeviceButtonMapping

| 1 | CARD8 |  | input extension opcode
| 1 | 29 |  | SetDeviceButtonMapping opcode
| 2 | 2+(n+p)/4 |  | request length
| 1 | CARD8 |  | device
| 1 | n |  | length of map
| 2 |  |  | unused
| n | LISTofCARD8 |  | map
| p |  |  | unused, p=pad(n)

=>

| 1 | 1 |  | Reply
| 1 | 29 |  | SetDeviceButtonMapping opcode
| 2 | CARD16 |  | sequence number
| 4 | 0 |  | reply length
| 1 |  |  | status
|  | 0 | Success |
|  | 1 | Busy |
| 23 |  |  | unused

QueryDeviceState

| 1 | CARD8 |  | input extension opcode
| 1 | 30 |  | QueryDeviceState opcode
| 2 | 2 |  | request length
| 1 | CARD8 |  | device
| 3 |  |  | unused

=>

| 1 | 1 |  | Reply
| 1 | 30 |  | QueryDeviceState opcode
| 2 | CARD16 |  | sequence number
| 4 | m/4 |  | reply length
| 1 | n |  | number of input classes
| 23 |  |  | unused
| m | LISTofINPUTSTATE INPUTSTATE | KEYSTATE or BUTTONSTATE or VALUATORSTATE |

KEYSTATE

| 1 | CARD8 |  | key input class id
| 1 | 36 |  | length
| 1 | CARD8 |  | num_keys
| 1 |  |  | unused
| 32 | LISTofCARD8 |  | status of keys

BUTTONSTATE

| 1 | CARD8 |  | button input class id
| 1 | 36 |  | length
| 1 | CARD8 |  | num_buttons
| 1 |  |  | unused
| 32 | LISTofCARD8 |  | status of buttons

VALUATORSTATE

| 1 | CARD8 |  | valuator input class id
| 1 | 4n + 4 |  | length
| 1 | n |  | number of valuators
| 1 |  |  | mode
|  | #x01 | DeviceMode (0 = Relative, 1 = Absolute) |
|  | #x02 | ProximityState (0 = InProximity, 1 = OutOfProximity) |
| 4n | LISTofCARD32 |  | status of valuators

SendExtensionEvent

| 1 | CARD8 |  | input extension opcode
| 1 | 31 |  | SendExtensionEvent opcode
| 2 | 4 + 8n + m |  | request length
| 4 | WINDOW |  | destination
| 1 | CARD8 |  | device
| 1 | BOOL |  | propagate
| 2 | CARD16 |  | eventclass count
| 1 | CARD8 |  | num_events
| 3 |  |  | unused
| 32n |  | LISTofEVENTSevents to send |
| 4m | LISTofEVENTCLASS |  | desired events

DeviceBell

| 1 | CARD8 |  | input extension opcode
| 1 | 32 |  | DeviceBell opcode
| 2 | 2 |  | request length
| 1 | CARD8 |  | device id
| 1 | CARD8 |  | feedback id
| 1 | CARD8 |  | feedback class
| 1 | INT8 |  | percent

SetDeviceValuators

| 1 | CARD8 |  | input extension opcode
| 1 | 33 |  | SetDeviceValuators opcode
| 2 | 2 + n |  | request length
| 1 | CARD8 |  | device id
| 1 | CARD8 |  | first valuator
| 1 | n |  | number of valuators
| 1 |  |  | unused
| 4n | LISTofINT32 |  | valuator values to set

=>

| 1 | 1 |  | Reply
| 1 | 33 |  | SetDeviceValuators opcode
| 2 | CARD16 |  | sequence number
| 4 | 0 |  | reply length
| 1 | CARD8 |  | status
|  | 0 | Success |
|  | 1 | AlreadyGrabbed |
| 23 |  |  | unused

GetDeviceControl

| 1 | CARD8 |  | input extension opcode
| 1 | 34 |  | GetDeviceControl opcode
| 2 | 2 |  | request length
| 2 | CARD16 |  | device control type
| 1 | CARD8 |  | device id
| 1 |  |  | unused

=>

| 1 | 1 |  | Reply
| 1 | 34 |  | GetDeviceControl opcode
| 2 | CARD16 |  | sequence number
| 4 | n/4 |  | reply length
| 1 | CARD8 |  | status
|  | 0 |  | Success
|  | 1 |  | AlreadyGrabbed
|  | 3 + first_error |  | DeviceBusy
| 23 |  |  | unused
| n |  |  | DEVICESTATE

DEVICESTATE |  |  | DEVICERESOLUTIONSTATE

DEVICERESOLUTIONSTATE

| 2 | 0 |  | control type
| 2 | 8 + 12n |  | length
| 4 | n |  | num_valuators
| 4n | LISTOfCARD32 |  | resolution values
| 4n | LISTOfCARD32 |  | resolution min_values
| 4n | LISTOfCARD32 |  | resolution max_values

ChangeDeviceControl

| 1 | CARD8 |  | input extension opcode
| 1 | 35 |  | ChangeDeviceControl opcode
| 2 | 2+n/4 |  | request length
| 2 | CARD16 |  | control type
| 1 | CARD8 |  | device id
| 1 |  |  | unused
| n |  |  | DEVICECONTROL
DEVICECONTROL |  |  |  | DEVICERESOLUTIONCTL

DEVICERESOLUTIONCTL

| 2 | 1 |  | control type
| 2 | 8 + 4n |  | length
| 1 | CARD8 |  | first_valuator
| 1 | n |  | num_valuators
| 2 |  |  | unused
| 4n | LISTOfCARD32 |  | resolution values

=>

| 1 | 1 |  | Reply
| 1 | 35 |  | ChangeDeviceControl opcode
| 2 | CARD16 |  | sequence number
| 4 | 0 |  | reply length
| 1 | CARD8 |  | status
|  | 0 |  | Success
|  | 1 |  | AlreadyGrabbed
|  | 3 + first_error |  | DeviceBusy
| 23 |  |  | unused

Events

DeviceKeyPress, DeviceKeyRelease, DeviceButtonPress, DeviceButtonRelease, ProximityIn, ProximityOut, and DeviceStateNotify events may be followed by zero or more DeviceValuator events. DeviceMotionNotify events will be followed by one or more DeviceValuator events.

DeviceValuator

| 1 | CARD8 |  | code
| 1 | CARD8 |  | device id
| 2 | CARD16 |  | sequence number
| 2 | SETofKEYBUTMASK |  | state
| 1 | n |  | number of valuators this device reports
| 1 | m |  | number of first valuator in this event
| 24 | LISTofINT32 |  | valuators

DeviceKeyPress

| 1 | CARD8 |  | code
| 1 | KEYCODE |  | detail
| 2 | CARD16 |  | sequence number
| 4 | TIMESTAMP |  | time
| 4 | WINDOW |  | root
| 4 | WINDOW |  | event
| 4 | WINDOW |  | child
|  | 0 | None |
| 2 | INT16 |  | root-x
| 2 | INT16 |  | root-y
| 2 | INT16 |  | event-x
| 2 | INT16 |  | event-y
| 2 | SETofKEYBUTMASK |  | state
| 1 | BOOL |  | same-screen
| 1 | CARD8 |  | device id
|  | #x80 |  | MORE_EVENTS follow

DeviceKeyRelease

| 1 | CARD8 |  | code
| 1 | KEYCODE |  | detail
| 2 | CARD16 |  | sequence number
| 4 | TIMESTAMP |  | time
| 4 | WINDOW |  | root
| 4 | WINDOW |  | event
| 4 | WINDOW |  | child
|  | 0 | None |
| 2 | INT16 |  | root-x
| 2 | INT16 |  | root-y
| 2 | INT16 |  | event-x
| 2 | INT16 |  | event-y
| 2 | SETofKEYBUTMASK |  | state
| 1 | BOOL |  | same-screen
| 1 | CARD8 |  | device id
|  | #x80 |  | MORE_EVENTS follow

DeviceButtonPress

| 1 | CARD8 |  | code
| 1 | BUTTON |  | detail
| 2 | CARD16 |  | sequence number
| 4 | TIMESTAMP |  | time
| 4 | WINDOW |  | root
| 4 | WINDOW |  | event
| 4 | WINDOW |  | child
|  | 0 | None |
| 2 | INT16 |  | root-x
| 2 | INT16 |  | root-y
| 2 | INT16 |  | event-x
| 2 | INT16 |  | event-y
| 2 | SETofKEYBUTMASK |  | state
| 1 | BOOL |  | same-screen
| 1 | CARD8 |  | device id
|  | #x80 |  | MORE_EVENTS follow

DeviceButtonRelease

| 1 | CARD8 |  | code
| 1 | BUTTON |  | detail
| 2 | CARD16 |  | sequence number
| 4 | TIMESTAMP |  | time
| 4 | WINDOW |  | root
| 4 | WINDOW |  | event
| 4 | WINDOW |  | child
|  | 0 | None |
| 2 | INT16 |  | root-x
| 2 | INT16 |  | root-y
| 2 | INT16 |  | event-x
| 2 | INT16 |  | event-y
| 2 | SETofKEYBUTMASK |  | state
| 1 | BOOL |  | same-screen
| 1 | CARD8 |  | device id
|  | #x80 |  | MORE_EVENTS follow

DeviceMotionNotify

| 1 | CARD8 |  | code
| 1 |  |  | detail
|  | 0 | Normal |
|  | 1 | Hint |
| 2 | CARD16 |  | sequence number
| 4 | TIMESTAMP |  | time
| 4 | WINDOW |  | root
| 4 | WINDOW |  | event
| 4 | WINDOW |  | child
|  | 0 | None |
| 2 | INT16 |  | root-x
| 2 | INT16 |  | root-y
| 2 | INT16 |  | event-x
| 2 | INT16 |  | event-y
| 2 | SETofKEYBUTMASK |  | state
| 1 | BOOL |  | same-screen
| 1 | CARD8 |  | device id
|  | #x80 |  | MORE_EVENTS follow

DeviceFocusIn

| 1 | CARD8 |  | code
| 1 |  |  | detail
|  | 0 | Ancestor |
|  | 1 | Virtual |
|  | 2 | Inferior |
|  | 3 | Nonlinear |
|  | 4 | NonlinearVirtual |
|  | 5 | Pointer |
|  | 6 | PointerRoot |
|  | 7 | None |
| 2 | CARD16 |  | sequence number
| 4 | TIMESTAMP |  | time
| 4 | WINDOW |  | event
| 1 |  |  | mode
|  | 0 | Normal |
|  | 1 | Grab |
|  | 2 | Ungrab |
|  | 3 | WhileGrabbed |
| 1 | CARD8 |  | device id
| 18 |  |  | unused

DeviceFocusOut

| 1 | CARD8 |  | code
| 1 |  |  | detail
|  | 0 | Ancestor |
|  | 1 | Virtual |
|  | 2 | Inferior |
|  | 3 | Nonlinear |
|  | 4 | NonlinearVirtual |
|  | 5 | Pointer |
|  | 6 | PointerRoot |
|  | 7 | None |
| 2 | CARD16 |  | sequence number
| 4 | TIMESTAMP |  | time
| 4 | WINDOW |  | event
| 1 |  |  | mode
|  | 0 | Normal |
|  | 1 | Grab |
|  | 2 | Ungrab |
|  | 3 | WhileGrabbed |
| 1 | CARD8 |  | device id
| 18 |  |  | unused

ProximityIn

| 1 | CARD8 |  | code
| 1 |  |  | unused
| 2 | CARD16 |  | sequence number
| 4 | TIMESTAMP |  | time
| 4 | WINDOW |  | root
| 4 | WINDOW |  | event
| 4 | WINDOW |  | child
|  | 0 | None |
| 2 | INT16 |  | root-x
| 2 | INT16 |  | root-y
| 2 | INT16 |  | event-x
| 2 | INT16 |  | event-y
| 2 | SETofKEYBUTMASK |  | state
| 1 | BOOL |  | same-screen
| 1 | CARD8 |  | device id
|  | #x80 |  | MORE_EVENTS follow

ProximityOut

| 1 | CARD8 |  | code
| 1 |  |  | unused
| 2 | CARD16 |  | sequence number
| 4 | TIMESTAMP |  | time
| 4 | WINDOW |  | root
| 4 | WINDOW |  | event
| 4 | WINDOW |  | child
|  | 0 | None |
| 2 | INT16 |  | root-x
| 2 | INT16 |  | root-y
| 2 | INT16 |  | event-x
| 2 | INT16 |  | event-y
| 2 | SETofKEYBUTMASK |  | state
| 1 | BOOL |  | same-screen
| 1 | CARD8 |  | device id
|  | #x80 |  | MORE_EVENTS follow

DeviceStateNotify events may be immediately followed by zero or one DeviceKeyStateNotify and/ or zero or more DeviceValuator events.

DeviceStateNotify

| 1 | CARD8 |  | code
| 1 | CARD8 |  | device id
|  | #x80 |  | MORE_EVENTS follow
| 2 | CARD16 |  | sequence number
| 4 | TIMESTAMP |  | time
| 1 | CARD8 |  | num_keys
| 1 | CARD8 |  | num_buttons
| 1 | CARD8 |  | num_valuators
| 1 | CARD8 |  | valuator mode and input classes reported
|  | #x01 | reporting keys |
|  | #x02 | reporting buttons |
|  | #x04 | reporting valuators |
|  | #x40 | device mode (0 = Relative, 1 = Absolute) |
|  | #x80 | proximity state (0 = InProximity, 1 = OutOfProximity) |
| 4 | LISTofCARD8 |  | first 32 keys (if reported)
| 4 | LISTofCARD8 |  | first 32 buttons (if reported)
| 12 | LISTofCARD32 |  | first 3 valuators (if reported)

DeviceKeyStateNotify

| 1 | CARD8 |  | code
| 1 | CARD8 |  | device id
|  | #x80 |  | MORE_EVENTS follow
| 2 | CARD16 |  | sequence number
| 28 | LISTofCARD8 |  | state of keys 33-255

DeviceButtonStateNotify

| 1 | CARD8 |  | code
| 1 | CARD8 |  | device id
|  | #x80 |  | MORE_EVENTS follow
| 2 | CARD16 |  | sequence number
| 28 | LISTofCARD8 |  | state of buttons 33-255

DeviceValuator

| 1 | CARD8 |  | code
| 1 | CARD8 |  | device id
| 2 | CARD16 |  | sequence number
| 2 | SETofKEYBUTMASK |  | state
| 1 | n |  | number of valuators this device reports
| 1 | n |  | number of first valuator in this event
| 24 | LISTofINT32 |  | valuators

DeviceMappingNotify

| 1 | CARD8 |  | code
| 1 | CARD8 |  | device id
| 2 | CARD16 |  | sequence number
| 1 |  |  | request
|  | 0 | MappingModifier |
|  | 1 | MappingKeyboard |
|  | 2 | MappingPointer |
| 1 | KEYCODE |  | first-keycode
| 1 | CARD8 |  | count
| 1 |  |  | unused
| 4 | TIMESTAMP |  | time
| 20 |  |  | unused

ChangeDeviceNotify

| 1 | CARD8 |  | code
| 1 | CARD8 |  | id of device specified on change request
| 2 | CARD16 |  | sequence number
| 4 | TIMESTAMP |  | time
| 1 |  |  | request
|  | 0 | NewPointer |
|  | 1 | NewKeyboard |
| 23 |  |  | unused

2

Table of Contents

1.1. Input Extension Overview |

. . . . . . . . . . . . .
1

1.2. Design Approach |

. . . . . . . . . . . . . . . . . .
1

1.3. Core Input Devices |

. . . . . . . . . . . . . . . .
1

1.4. Extension Input Devices |

. . . . . . . . . . . . . .
1

1.4.1. Event Classes |

. . . . . . . . . . . . . . . . . .
1

1.4.2. Input Classes |

. . . . . . . . . . . . . . . . . .
1

2. Requests |

. . . . . . . . . . . . . . . . . . . . . .
1

2.1. Getting the Extension Version |

. . . . . . . . . . .
1

2.2. Listing Available Devices |

. . . . . . . . . . . . .
1

2.3. Enabling Devices |

. . . . . . . . . . . . . . . . .
1

2.4. Changing The Mode Of A Device |

. . . . . . . . . . .
1

2.5. Initializing Valuators on an Input Device |

. . . . .
1

2.6. Getting Input Device Controls |

. . . . . . . . . . .
1

2.7. Selecting Extension Device Events |

. . . . . . . . .
1

2.8. Determining Selected Events |

. . . . . . . . . . . .
1

2.9. Controlling Event Propagation |

. . . . . . . . . . .
1

2.10. Sending Extension Events |

. . . . . . . . . . . . .
1

2.11. Getting Motion History |

. . . . . . . . . . . . . .
1

2.12. Changing The Core Devices |

. . . . . . . . . . . .
1

2.13. Event Synchronization And Core Grabs |

. . . . . . .
1

2.14. Extension Active Grabs |

. . . . . . . . . . . . . .
1

2.15. Passively Grabbing A Key |

. . . . . . . . . . . . .
1

2.16. Passively Grabbing A Button |

. . . . . . . . . . .
1

2.17. Thawing A Device |

. . . . . . . . . . . . . . . . .
1

2.18. Controlling Device Focus |

. . . . . . . . . . . . .
1

2.19. Controlling Device Feedback |

. . . . . . . . . . .
1

2.20. Ringing a Bell on an Input Device |

. . . . . . . .
1

2.21. Controlling Device Encoding |

. . . . . . . . . . .
1

2.22. Controlling Button Mapping |

. . . . . . . . . . . .
1

2.23. Obtaining The State Of A Device |

. . . . . . . . .
1

3. Events |

. . . . . . . . . . . . . . . . . . . . . . .
1

3.1. Button, Key, and Motion Events |

. . . . . . . . . .
1

3.2. DeviceValuator Event |

. . . . . . . . . . . . . . .
1

3.3. Device Focus Events |

. . . . . . . . . . . . . . . .
1

3.4. Device State Notify Event |

. . . . . . . . . . . . .
1

3.5. Device KeyState and ButtonState Notify Events |

. . .
1

3.6. DeviceMappingNotify Event |

. . . . . . . . . . . . .
1

3.7. ChangeDeviceNotify Event |

. . . . . . . . . . . . .
1

3.8. Proximity Events |

. . . . . . . . . . . . . . . . .
1

Appendix A − Input Extension Protocol Encoding |

. . . . .
2

i