XlInputExtension.mesa
Copyright Ó 1991, 1992 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, December 30, 1991 1:59 pm PST
Christian Jacobi, March 27, 1992 10:27 am PST
Supports the input extension for the X Window system (X11).
General Types
Atom or name for this extension is $XInputExtension
Int32Sequence:
TYPE ~
RECORD[
SEQUENCE leng:
NAT
OF
INT32];
InputClass:
TYPE ~
MACHINE
DEPENDENT {keyClass(0), buttonClass(1), valuatorClass(2), feedbackClass(3), proximityClass(4), focusClass(5), otherClass(6), (255)};
May be extended by future versions of the input extension protocol
DeviceId:
TYPE ~ DeviceIdBase[0..128);
Representation of used input extension device.
DeviceIdBase: TYPE = [0..256); --Used to be able to hold special input values, and, sometimes to allocate the right number of bits.
General Requests
GetExtensionVersion:
PROC [c: Xl.Connection, name: Rope.
ROPE]
RETURNS [present:
BOOL, majorVersion, minorVersion:
INT];
Difference to protocol: available: is true when the extension is available and the version number allows usage of the reminder of this interface. This procedure may be used independently whether the connection supports the input extension or not.
ListInputDevices:
PROC [c: Xl.Connection]
RETURNS [
LIST
OF DeviceInfo];
Lists available devices. This procedure may be used independently whether the connection supports the input extension or not.
DeviceInfo:
TYPE ~
RECORD [
type: Xl.XAtom, --nature of device; defined types listed below
id: DeviceId, --uniquely identifies device
numClasses: BYTE,
use: CurrentUse, --describes current use
info: LIST OF REF InputInfo,
name: Rope.ROPE --one of the defined types
];
CurrentUse: TYPE = {isXPointer, isXKeyboard, isExtensionDevice};
InputInfo:
TYPE ~
RECORD [
class: InputClass,
info:
SELECT type: InfoSelector
FROM
keyInfo => [
min: BYTE,
max: BYTE,
number: CARD16],
buttonInfo => [
number: CARD16],
valuatorInfo => [
supportsRelative: BOOL,
supportsAbsolute: BOOL,
motionBufferSize: CARD32,
axisInfo: SEQUENCE numberOfAxis: BYTE OF AxisInfo],
ENDCASE
];
InfoSelector: TYPE ~ {keyInfo, buttonInfo, valuatorInfo};
AxisInfo:
TYPE ~
RECORD [
resolution: CARD32,
min: CARD32,
max: CARD32
];
Typical extension types: MOUSE, TABLET, KEYBOARD, TOUCHSCREEN, TOUCHPAD, BUTTONBOX, BARCODE, KNOB𡤋OX, TRACKBALL, QUADRATURE, SPACEBALL, DATAGLOVE, EYETRACKER, CURSORKEYS, FOOTMOUSE, ID←MODULE, ONE←KNOB, NINE←KNOB
OpenDevice:
PROC [c: Xl.Connection, id: DeviceId]
RETURNS [
REF OpenDeviceRec];
Opens a device; use id from ListInputDevices.
OpenDeviceRec:
TYPE ~
RECORD [
id: DeviceId, --same id
classes: SEQUENCE numClasses: INT OF InputClassInfo
];
InputClassInfo:
TYPE ~
PACKED
RECORD [
inputClass: InputClass,
eventTypeBase: BYTE --this is used to compose values for EventClass
];
A client may open a device multiple times. However, a single CloseDevice closes all open instances of that device.
CloseDevice:
PROC [c: Xl.Connection, deviceId: DeviceId, details: Xl.Details ¬
NIL];
Closes all open instances of that device for this connection.
SetDeviceMode:
PROC [c: Xl.Connection, deviceId: DeviceId, relativeMode:
BOOL]
RETURNS [status: DeviceStatus];
Choose between absolute and relative mode.
DeviceStatus: TYPE ~ MACHINE DEPENDENT {success, alreadyGrabbed, deviceBusy};
SetDeviceValuators:
PROC [c: Xl.Connection, deviceId: DeviceId, first:
INT, values:
LIST
OF
INT]
RETURNS [status: ValuatorStatus];
Initialize valuators. Necessary e.g. when device is switched to absolute mode.
ValuatorStatus: TYPE ~ MACHINE DEPENDENT {success, alreadyGrabbed};
GetDeviceMotionEvents:
PROC [c: Xl.Connection, deviceId: DeviceId, start, stop: Xl.TimeStamp ¬ Xl.currentTime]
RETURNS [
REF DeviceTimeCoords];
Returns positions in devices motion history buffer. The actual content is received through access functions to reduce the number of necessary allocations.
DeviceTimeCoords: TYPE;
IsAbsolute: PROC [dtc: REF DeviceTimeCoords] RETURNS [BOOL];
AxisCount: PROC [dtc: REF DeviceTimeCoords] RETURNS [NAT];
NumberOfEvents: PROC [dtc: REF DeviceTimeCoords] RETURNS [NAT];
TimeOfEvent: PROC [dtc: REF DeviceTimeCoords, eventNum: NAT] RETURNS [Xl.TimeStamp];
ValuatorOfEvent: PROC [dtc: REF DeviceTimeCoords, eventNum: NAT, valuatorNum: NAT] RETURNS [CARD32];
QueryDeviceState:
PROC [c: Xl.Connection, deviceId: DeviceId]
RETURNS [InputStates];
Returns current logical state of device.
InputStates:
TYPE ~
RECORD [
numberOfClasses: BYTE,
states: LIST OF REF InputState
];
InputState:
TYPE ~
RECORD [
number: BYTE,
s:
SELECT class: InputClass
FROM
keyClass => [
keys: PACKED ARRAY [0..31] OF BYTE
],
buttonClass => [
buttons: PACKED ARRAY [0..31] OF BYTE
],
valuatorClass => [
relativeMode: BOOL,
inProximity: BOOL,
valuators: REF Int32Sequence ¬ NIL
],
ENDCASE
];
Requesting Events
EventClass:
TYPE ~
CARD32;
A wierd encoding on what kind of events should be generated. XlInputExtension uses the identical representation which is used by the protocol.
EventClasses:
TYPE ~
REF Xl.Card32Sequence;
Type used for returned EventClass'es.
MakeEventClass:
PROC [od:
REF
READONLY OpenDeviceRec, request: RequestableEvent]
RETURNS [EventClass];
This is used to be able to specify what kind of events are desired.
It implements the "MACRO" as advertized in the protocol and found in the C library, just using a simpler input specification.
RequestableEvent:
TYPE =
MACHINE
DEPENDENT {
devicePointerMotionHint, deviceButton1Motion, deviceButton2Motion, deviceButton3Motion, deviceButton4Motion, deviceButton5Motion, deviceButtonMotion, deviceButtonGrab, deviceOwnerGrabButton, noExtensionEvent,
deviceKeyPress, deviceKeyRelease, deviceButtonPress, deviceButtonRelease, deviceMotionNotify, deviceFocusIn, deviceFocusOut, proximityIn, proximityOut, deviceStateNotify, deviceMappingNotify, changeDeviceNotify,
(255)};
This RequestableEvent type is conveniantly made up to denote input for MakeEventClass; it has no direct aequivalent in the protocol. (Implementor warning: the values have well defined order useful for some arithmetic operations.)
For deviceButtonPress use also deviceButtonGrab to imply grabs. Usage then is exclusive. Otherwise no implicite grab is hold. Similar, add deviceOwnerGrabButton, deviceButtonMotion to modify other specification.
SelectExtensionEvents:
PROC [c: Xl.Connection, window: Xl.Window, interest:
LIST
OF EventClass, details: Xl.Details ¬
NIL];
Requests server to send events
GetSelectedExtensionEvents:
PROC [c: Xl.Connection, window: Xl.Window]
RETURNS [thisClient: EventClasses, allClients: EventClasses];
Query which events currently are selected.
ChangeDeviceDontPropagateList:
PROC [c: Xl.Connection, window: Xl.Window, eventClass:
LIST
OF EventClass, mode: ListModifierMode, details: Xl.Details ¬
NIL];
Specify whether events shall be propagated up the window hierarchy until an ancestor is found that is interested.
ListModifierMode: TYPE = MACHINE DEPENDENT {addToList, deleteFromList};
GetDeviceDontPropagateList:
PROC [c: Xl.Connection, window: Xl.Window]
RETURNS [dontPropagateList: EventClasses];
Returns which events are not propagated up the window hierarchy.
Changing Core devices
ChangeReply: TYPE ~ MACHINE DEPENDENT {success, alreadyGrabbed, deviceFrozen};
ChangePointerDevice:
PROC [c: Xl.Connection, deviceId: DeviceId, xaxis, yaxis:
BYTE]
RETURNS [ChangeReply];
Changes which physical device is used as the X pointer.
Focus
DeviceFocusReversion: TYPE ~ MACHINE DEPENDENT {none, pointerRoot, parent, followKeyboard}; --like FocusReversion but additional value followKeyboard
focusNone: Xl.Window ~ [[0]];
focusPointerRoot: Xl.Window ~ [[1]];
focusFollowKeyboard: Xl.Window ~ [[3]];
DeviceFocusRec:
TYPE ~
RECORD [
window: Xl.Window ¬ Xl.nullWindow,
revertTo: DeviceFocusReversion ¬ none,
time: Xl.TimeStamp ¬ Xl.currentTime
];
GetDeviceFocus: PROC [c: Xl.Connection, deviceId: DeviceId] RETURNS [DeviceFocusRec];
SetDeviceFocus:
PROC [c: Xl.Connection, deviceId: DeviceId, dfr: DeviceFocusRec ¬ [], details: Xl.Details ¬
NIL];
Control destination window of events from this device.
Events
deviceKeyPressKey, deviceKeyReleaseKey, deviceButtonPressKey, deviceButtonReleaseKey, deviceMotionNotifyKey, deviceFocusInKey, deviceFocusOutKey, proximityInKey, proximityOutKey, deviceStateNotifyKey, deviceMappingNotifyKey, changeDeviceNotifyKey:
READONLY
REF
ANY;
Keys to enable matching of events.
Example usage: Xl.FullCreateEventFilter[extensions: LIST[XlInputExtension.deviceKeyPressKey]]
Some events, (deviceValuator, deviceKeyStateNotify, deviceButtonStateNotify) are generated only when the original event does not carry enough bits for the information; these events are collected by XlInputExtensionImpl and returned together with the original even. They can not be matched explicitely by clients.
EventOffset:
TYPE ~
MACHINE
DEPENDENT {deviceValuator(0), deviceKeyPress(1), deviceKeyRelease(2), deviceButtonPress(3), deviceButtonRelease(4), deviceMotionNotify(5), deviceFocusIn(6), deviceFocusOut(7), proximityIn(8), proximityOut(9), deviceStateNotify(10), deviceMappingNotify(11), changeDeviceNotify(12), deviceKeyStateNotify(13), deviceButtonStateNotify(14)};
Offsets for distingushing different event types as defined by the protocol.
EventDataType:
TYPE ~ {deviceBase, deviceFocus, deviceState, deviceMapping, deviceChange};
Tags for different types in event data-structure.
ExtEvent: TYPE ~ REF READONLY ExtEventRep;
ExtEventRep:
TYPE ~
RECORD [
--This is the thing where the "decoded" field of an Xl.EventRep.extension points to.
eventOffset: EventOffset,
seq: Xl.SequenceNo ¬ 0,
time: Xl.TimeStamp,
deviceId: DeviceId,
details:
SELECT type: EventDataType
FROM
deviceBase => [
--deviceKeyPress, deviceKeyRelease, deviceButtonPress, deviceButtonRelease, deviceMotionNotify, proximityIn, proximityOut
--(hidden deviceValuator)
rootWindow: Xl.Window,
eventWindow: Xl.Window,
childWindow: Xl.Window, -- ¬ nullWindow,
sameScreen: BOOL,
rootPos: Xl.Point,
eventPos: Xl.Point, --of core pointer (even if device itself points somewhere else)
state: Xl.SetOfKeyButMask, --of core buttons and modifiers (just before event)
detail:
--For deviceKeyPress, deviceKeyRelease
keyCode: Xl.KeyCode ¬ VAL[0],
--For deviceButtonPress, deviceButtonRelease
button: BYTE ¬ 0,
--For deviceMotionNotify
-- BTW: granularity of motion not defined
normalHint: Xl.NormalHint ¬ normal,
--For proximityIn, proximityOut
--
deviceState: Xl.SetOfKeyButMask, --set only if valuators are reported
valuators: REF READONLY Int32Sequence ¬ NIL
],
deviceFocus => [
--deviceFocusIn, deviceFocusOut
detail: Xl.FocusDetail,
eventWindow: Xl.Window,
mode: Xl.GrabMode
],
deviceState => [
--DeviceStateNotify
--(hidden deviceKeyStateNotify, deviceButtonStateNotify)
numKeys: BYTE,
numButtons: BYTE,
numValuators: BYTE,
relativeMode: BOOL,
inProximity: BOOL,
keys: REF READONLY PACKED ARRAY [0..31] OF BYTE ¬ NIL,
buttons: REF READONLY PACKED ARRAY [0..31] OF BYTE ¬ NIL,
valuators: REF READONLY Int32Sequence ¬ NIL
],
deviceMapping => [
--deviceMapping
request: Xl.MappingNotifyKind,
firstKeycode: BYTE,
count: BYTE
],
deviceChange => [
--changeDeviceNotify
newWhat: {newPointer, newKeyboard}
],
ENDCASE
];
Warning about events sent from other clients using SendExtensionEvent:
The fields are carefully read from the connection; bad data will not cause a crash of XlInputExtensionImpl. However, in such a case some data could be truncated, or, events could be discarded.