ei_stylus

Stylus Object

Interface for stylus requests and events.

A stylus is an absolute pointing tool commonly used for writing, drawing, and other tasks traditionally accomplished with a pen or pencil. This interface represents the various semantics and properties common to these kinds of tools. An ei_device may use this interface alone or in combination with other interfaces to emulate tools with additional features. For example, a tool with physical buttons may be emulated by creating an ei_device that has both this and an ei_button interface.

When adding this interface to an ei_device, the server and client are required to negotiate capabilities. Negotiation is performed by the server sending ei_stylus.capabilities prior to ei_device.done and then the client responding with ei_stylus.bind_capabilities prior to ei_device.ready.

This interface may be used on both ei_device.device_type.virtual and ei_device.device_type.physical devices. As an interface with absolute motion, virtual devices must declare an arbitrary set of regions that are valid for motion events. For physical devices, the server must send ei_device.dimensions that reflects the size of the active area of the stylus’ digitizer. This size must not include any “out-of-bounds” margin that may exist (e.g. a digitizer with a 404 x 229 mm active area and 2mm margin on all sides should have a declared size of only 400 x 225 mm).

Implementations are free to decide how they handle multiple styli. For example, a sender that is capable of distinguishing two styli (e.g. by serial number) may choose to use a unique ei_device object for each stylus, making it possible for the receiver to keep track of which tool is in use. Senders are not obligated to do this; it is equally valid for them to discard any distinguishing information that they may (or may not) have and use a single ei_device for all styli. Similarly, receivers are free to choose whether to use or discard information about the source ei_device after processing.

This interface is only provided once per device and where a client requests ei_stylus.release the interface does not get re-initialized. An EIS implementation may adjust the behavior of the device (including removing the device) if the interface is released.

Note that for a client to receive objects of this type, it must announce support for the interface in ei_handshake.interface_version.

Protocol States

This protocol is stateful and relies on ei_device.frame to delimit state changes. Only those properties, axes, and other values that have changed from one frame to the next are required to be sent.

This documentation may use various phrases to describe the major proximity states of the protocol. For clarity, these phrases are defined below:

  • Out of proximity: Initial state of an ei_stylus object. This state indicates that a stylus tool is unable to be sensed by a digitizer. Its location and other properties are unknown and invalid in this state. This state can only be transitioned out of by sending a frame containing ei_stylus.proximity_in.

  • Entering proximity: State of the ei_stylus object for the duration of the frame containing ei_stylus.proximity_in. This state indicates that a stylus has just come near enough to a digitizer for its location and other properties to become known and valid. This is a transient state that automatically advances to “in proximity” once the frame has finished processing.

  • In proximity: State of the ei_stylus object during normal operation. This state indicates that the stylus is remaining near enough to its digitizer for location and other properties to remain valid. This state is transitioned out of by sending a frame containing ei_stylus.proximity_out.

  • Leaving proximity: State of the ei_stylus for the duration of the frame containing ei_stylus.proximity_out. This state indicates that the stylus has just moved far enough from its digitizer for its location and other properties to no longer be known or valid. This is a transient state that automatically advances to “out of proximity” once the frame has finished processing. Some stylus hardware/drivers may provide a final update of the last-known valid location and other properties as a stylus leaves proximity. This protocol allows such a final update to be sent in this state.

Logical Contact

This protocol uses the concept of “logical contact” to represent when a stylus is making intentional contact with its digitizer. Logical contact is a heuristic and often flagged by hardware drivers based on things like the state of a hardware “tip switch”, the level of pressure compared to a threshold, etc. It is important to note that physical contact does not necessarily imply logical contact; some physical contacts are unintentional and some imperfect tools may indicate physical contact even while hovering (e.g. by always sending some small non-zero pressure value).

Stylus Buttons

This protocol does not define notifications or events for the state of buttons that exist on it. Instead, it is expected that implementations ensure that the parent ei_device declares both an ei_stylus and an ei_button interface. Button requests should be routed through the button interface and be part of the same ei_device.frame that contains the coincident stylus requests.

Enums

Info

Enum names are shown here in uppercase. The exact name depends on the language bindings.

ei_stylus.tool_capability

This enum denotes capability types for the ei_stylus.

A capability describes a particular type of data that may be reported by a device or tool. Each capability is a bit flag that may be set in a mask describing a full set of capabilities.

Name Value Summary
ERASE 1 the tool may act as an eraser
PRESSURE 2 pressure data may be reported
DISTANCE 4 distance data may be reported
TILT 8 tilt data may be reported
ROTATION 16 rotation data may be reported
AIRBRUSH_FLOW 32 airbrush_flow data may be reported

Requests

ei_stylus.release

Since Version1 Request Opcode0

ei_stylus.release()

Notification that the client is no longer interested in this stylus object. The EIS implementation will release any resources related to this object and send the ei_stylus.destroyed event once complete.

ei_stylus.bind_capabilities

Since Version1 Request Opcode1

ei_stylus.bind_capabilities(capabilities)
Argument Type Summary
capabilities uint32 A mask of ‘capability’ flags that the client wishes to handle
Note

This request is only available for clients of ei_handshake.context_type.sender.

Request to bind to a given set of capabilities. This is used by clients to describe which subset of server-supported capabilities may be sent by this particular stylus.

Clients are required to send this in response to the ei_stylus.capabilities event. It is required to be sent prior to the first ei_device.start_emulating request. It is a protocol violation to include capabilities that were not present in the server event.

If the client does not bind to any capability, any stylus events will be restricted to motion and tip (down/up) only.

It is a protocol violation to send requests or events for unbound capabilities.

ei_stylus.proximity_in

Since Version1 Request Opcode2

ei_stylus.proximity_in()
Note

This request is only available for clients of ei_handshake.context_type.sender.

Notification that a stylus is entering proximity of its digitizer. The stylus object transitions from an “out of proximity” state to “entering proximity” for the duration of the ei_device.frame that contains this request. After the frame has been processed, the object automatically transitions to an “in proximity” state.

The frame containing this request is required to also contain one ei_stylus.motion event and one corresponding event for each ei_stylus.tool_capability bound in ei_stylus.bind_capabilities.

It is a protocol violation to send this request while the stylus object is already in or entering proximity. It is a protocol violation to send ei_stylus.proximity_in and ei_stylus.proximity_out in the same frame.

ei_stylus.proximity_out

Since Version1 Request Opcode3

ei_stylus.proximity_out()
Note

This request is only available for clients of ei_handshake.context_type.sender.

Notification that the stylus is leaving proximity of its digitizer. The stylus object transitions from an “in proximity” state to “leaving proximity” for the duration of the ei_device.frame that contains this request. After the frame has been processed, the object automatically transitions to an “out of proximity” state.

Once a stylus is “out of proximity”, all other state information (e.g. tool type, up/down/erase state, axis values) is considered invalid and must be cleared on both the sending and receiving side.

The frame containing this request may contain updates of the stylus state (location, tilt, etc.) that represents its final known valid properties. It should not contain events that attempt to explicitly reset state.

It is a protocol violation to send this request while the stylus object is already leaving or out of proximity. It is a protocol violation to send ei_stylus.proximity_in and ei_stylus.proximity_out in the same frame.

ei_stylus.erase_start

Since Version1 Request Opcode4

ei_stylus.erase_start()
Note

This request is only available for clients of ei_handshake.context_type.sender.

Notification that the stylus’s eraser feature has been activated.

Physical styli often include some kind of eraser feature, activated by flipping the tool over or holding a button down. These button-activated tools in particular may start or stop erasing without ever leaving proximity.

The default state for tools is “not erasing”.

This request may only be sent while the stylus is entering or in proximity. It is a protocol violation to send this request at any other time. It is a protocol violation for ei_stylus.erase_start and ei_stylus.erase_stop to share the same ei_device.frame. It is a client bug to send this request when the ei_stylus.tool_capability.erase capability is not bound. The EIS implementation may ignore unbound requests and/or disconnect the client.

ei_stylus.erase_stop

Since Version1 Request Opcode5

ei_stylus.erase_stop()
Note

This request is only available for clients of ei_handshake.context_type.sender.

Notification that the stylus’s eraser feature has been deactivated.

Physical styli often include some kind of eraser feature, activated by flipping the tool over or holding a button down. These button-activated tools in particular may start or stop erasing without ever leaving proximity.

The default state for tools is “not erasing”.

This request may only be sent while the stylus is in or leaving proximity. It is a protocol violation to send this request at any other time. It is a protocol violation for ei_stylus.erase_start and ei_stylus.erase_stop to share the same ei_device.frame. It is a client bug to send this request when the ei_stylus.tool_capability.erase capability is not bound. The EIS implementation may ignore unbound requests and/or disconnect the client.

ei_stylus.tip_down

Since Version1 Request Opcode6

ei_stylus.tip_down()
Note

This request is only available for clients of ei_handshake.context_type.sender.

Notification that the stylus has come into logical contact with its digitizer.

Senders are required to use this request to signal logical contact. Receivers are free to treat the stylus as “up” in the absence of this event, regardless of other axis values that may be present (e.g. pressure, distance).

This request may only be sent while the stylus is entering or in proximity. It is a protocol violation to send this request at any other time. It is a protocol violation for ei_stylus.tip_down and ei_stylus.tip_up to share the same ei_device.frame.

ei_stylus.tip_up

Since Version1 Request Opcode7

ei_stylus.tip_up()
Note

This request is only available for clients of ei_handshake.context_type.sender.

Notification that the stylus has left logical contact with its digitizer.

Senders are required to generate this request to signal the loss of logical contact. Receivers are free to treat the stylus as “down” in the absence of this event, regardless of other axis values that may be present (e.g. pressure, distance).

This request may only be sent while the stylus is in or leaving proximity. It is a protocol violation to send this request at any other time. It is a protocol violation for ei_stylus.tip_down and ei_stylus.tip_up to share the same ei_device.frame.

ei_stylus.motion

Since Version1 Request Opcode8

ei_stylus.motion(x, y)
Argument Type Summary
x float The x position of the stylus in mm or logical pixels.
y float The y position of the stylus in mm or logical pixels.
Note

This request is only available for clients of ei_handshake.context_type.sender.

Notification that the stylus has been moved to the given absolute coordinates. The interpretation of values depends on if the device is physical (mm) or virtual (pixels). Fractional pixels are allowed.

Valid (x, y) locations are those that exist inside of the ei_device.dimensions (for physical devices) or one of the device’s ei_device.region (for virtual devices). It is a client bug to send a location that exists outside of these locations. The EIS implementation may clamp out-of-range values and/or disconnect the client.

This request must be in the same frame as ei_stylus.proximity_in. It may also be sent while the stylus is in or leaving proximity. It is a protocol violation to send this request at any other time.

ei_stylus.pressure

Since Version1 Request Opcode9

ei_stylus.pressure(pressure)
Argument Type Summary
pressure float The tip pressure as a normalized value.
Note

This request is only available for clients of ei_handshake.context_type.sender.

Notification of the relative amount of pressure exerted on the stylus.

The valid range for pressure is 0.0 <= pressure <= 1.0. It is a client bug to send values outside of this range. The EIS implementation may clamp out-of-range values and/or disconnect the client.

The value pressure = 0.0 indicates the stylus is experiencing “minimum” or “no” pressure, and pressure = 1.0 indicates the stylus is measuring some arbitrary “maximum pressure”.

This request may only be sent while the stylus is entering, in, or leaving proximity. It is a protocol violation to send this request at any other time.

It is a client bug to send this request when the ei_stylus.tool_capability.pressure capability is not bound. The EIS implementation may ignore unbound requests and/or disconnect the client.

If the client has bound the ei_stylus.tool_capability.pressure capability, this request must be in the same frame as ei_stylus.proximity_in.

Important

Non-zero pressure does not imply logical contact, but logical contact does imply a non-zero pressure. If a client has bound the pressure capability, the pressure must be higher than 0.0 in the frame that contains ei_stylus.tip_down and any subsequent frames until ei_stylus.tip_up. The EIS implementation may correct illegal values and/or disconnect the client.

If both the pressure and distance capabilities are bound, a non-zero pressure value requires that the distance value in the same frame is 0.0. The EIS implementation may correct illegal values and/or disconnect the client.

ei_stylus.distance

Since Version1 Request Opcode10

ei_stylus.distance(distance)
Argument Type Summary
distance float The tip-to-digitizer distance as a normalized value.
Note

This request is only available for clients of ei_handshake.context_type.sender.

Notification of the relative distance between the stylus and its digitizer.

The valid range for distance is 0.0 <= distance <= 1.0. It is a client bug to send values outside of this range. The EIS implementation may clamp out-of-range values and/or disconnect the client.

The value distance = 0.0 indicates the stylus is in physical contact with the digitizer and distance = 1.0 indicates the stylus is at some arbitrary “maximum distance”.

This request may only be sent while the stylus is entering, in, or leaving proximity. It is a protocol violation to send this request at any other time.

It is a client bug to send this request when the ei_stylus.tool_capability.distance capability is not bound. The EIS implementation may ignore unbound requests and/or disconnect the client.

If the client has bound the ei_stylus.tool_capability.distance capability, this request must be in the same frame as ei_stylus.proximity_in.

Important

Physical contact does not imply logical contact, but logical contact does imply physical contact. If a client has bound the distance capability, the distance must be 0.0 in the frame that contains ei_stylus.tip_down and any subsequent frames until ei_stylus.tip_up. The EIS implementation may correct illegal values and/or disconnect the client.

If both the pressure and distance capabilities are bound, a non-zero distance value requires that the pressure value in the same frame is 0.0. The EIS implementation may correct illegal values and/or disconnect the client.

ei_stylus.tilt

Since Version1 Request Opcode11

ei_stylus.tilt(tilt_x, tilt_y)
Argument Type Summary
tilt_x float The angle in degrees of the stylus along the digitizer X axis.
tilt_y float The angle in degrees of the stylus along the digitizer Y axis.
Note

This request is only available for clients of ei_handshake.context_type.sender.

Notification of the stylus’s tilt angles in degrees.

The valid range for each tilt angle is -90.0 <= tilt_[xy] <= +90.0. It is a client bug to send values outside of this range. The EIS implementation may clamp out-of-range values and/or disconnect the client.

Each tilt angle is measured relative to the digitizer’s Z axis. The pair (tilt_x = 0, tilt_y = 0) indicates the stylus is being held parallel to the Z axis, while (tilt_x = 90, tilt_y = 0) and (tilt_x = 0, tilt_y = 90) indicate the stylus parallel to the +X and +Y axes, respectively.

This request may only be sent while the stylus is entering, in, or leaving proximity. It is a protocol violation to send this request at any other time.

It is a client bug to send this request when the ei_stylus.tool_capability.tilt capability is not bound. The EIS implementation may ignore unbound requests and/or disconnect the client.

If the client has bound the ei_stylus.tool_capability.tilt capability, this request must be in the same frame as ei_stylus.proximity_in.

ei_stylus.rotation

Since Version1 Request Opcode12

ei_stylus.rotation(rotation)
Argument Type Summary
rotation float The angle in degrees of the stylus about its own Z axis.
Note

This request is only available for clients of ei_handshake.context_type.sender.

Notification of the stylus’s barrel rotation angle in degrees.

The valid range for barrel rotation is 0.0 <= rotation < 360.0. It is a client bug to send values outside of this range. The EIS implementation may reduce out-of-range values modulo 360 and/or disconnect the client.

The value rotation = 0.0 indicates the stylus is being held at its neutral rotation angle. Angles increase in value as the stylus is rotated clockwise while held.

This request may only be sent while the stylus is entering, in, or leaving proximity. It is a protocol violation to send this request at any other time.

It is a client bug to send this request when the ei_stylus.tool_capability.rotation capability is not bound. The EIS implementation may ignore unbound requests and/or disconnect the client.

If the client has bound the ei_stylus.tool_capability.rotation capability, this request must be in the same frame as ei_stylus.proximity_in.

ei_stylus.airbrush_flow

Since Version1 Request Opcode13

ei_stylus.airbrush_flow(flow)
Argument Type Summary
flow float The position of an airbrush flow control present on the tool, as a normalized value.
Note

This request is only available for clients of ei_handshake.context_type.sender.

Notification of the relative position of an airbrush stylus’s flow control.

The valid range for airbrush flow is 0.0 <= flow <= 1.0. It is a client bug to send values outside of this range. The EIS implementation may clamp out-of-range values and/or disconnect the client.

The value flow = 0.0 indicates the airbrush flow control is fully “off” and flow = 1.0 indicates the control is fully “on”.

This request may only be sent while the stylus is entering, in, or leaving proximity. It is a protocol violation to send this request at any other time.

It is a client bug to send this request when the ei_stylus.tool_capability.airbrush_flow capability is not bound. The EIS implementation may ignore unbound requests and/or disconnect the client.

If the client has bound the ei_stylus.tool_capability.airbrush_flow capability, this request must be in the same frame as ei_stylus.proximity_in.

Important

Many platforms report the airbrush flow control through a generic “tangential pressure” or “slider” property. These generic properties may contain other types of data when non-airbrush tools are in use. Developers should take care to not report other types of data with this request.

Events

ei_stylus.destroyed

Since Version1 Event Opcode0

ei_stylus.destroyed(serial)
Argument Type Summary
serial uint32 This event’s serial number.
Destructor

Immediately after sending this request, the object is considered destroyed by the EIS implementation. It must no longer be used by the client.

This object has been removed and a client should release all associated resources.

This object will be destroyed by the EIS implementation immediately after this event is sent and as such the client must not attempt to use it after that point.

ei_stylus.capabilities

Since Version1 Event Opcode1

ei_stylus.capabilities(capabilities)
Argument Type Summary
capabilities uint32 A mask of ‘capability’ flags for the events available through this interface

See the ei_stylus.bind_capabilities request for more details.

The server sends this event after announcing the ei_stylus interface to an ei_device. This event describes the set of capabilities that the stylus supports. For sender contexts, the client must confirm (and optionally narrow down) the capabilities with the ei_stylus.bind_capabilities request before the device will send events.

ei_stylus.proximity_in

Since Version1 Event Opcode2

ei_stylus.proximity_in()
Note

This event is only available for clients of ei_handshake.context_type.receiver.

See the ei_stylus.proximity_in request for more details.

ei_stylus.proximity_out

Since Version1 Event Opcode3

ei_stylus.proximity_out()
Note

This event is only available for clients of ei_handshake.context_type.receiver.

See the ei_stylus.proximity_out request for more details.

ei_stylus.erase_start

Since Version1 Event Opcode4

ei_stylus.erase_start()
Note

This event is only available for clients of ei_handshake.context_type.receiver.

See the ei_stylus.erase_start request for more details.

ei_stylus.erase_stop

Since Version1 Event Opcode5

ei_stylus.erase_stop()
Note

This event is only available for clients of ei_handshake.context_type.receiver.

See the ei_stylus.erase_stop request for more details.

ei_stylus.tip_down

Since Version1 Event Opcode6

ei_stylus.tip_down()
Note

This event is only available for clients of ei_handshake.context_type.receiver.

See the ei_stylus.tip_down request for more details.

ei_stylus.tip_up

Since Version1 Event Opcode7

ei_stylus.tip_up()
Note

This event is only available for clients of ei_handshake.context_type.receiver.

See the ei_stylus.tip_up request for more details.

ei_stylus.motion

Since Version1 Event Opcode8

ei_stylus.motion(x, y)
Argument Type Summary
x float The x position of the stylus in mm or logical pixels.
y float The y position of the stylus in mm or logical pixels.
Note

This event is only available for clients of ei_handshake.context_type.receiver.

See the ei_stylus.motion request for more details.

ei_stylus.pressure

Since Version1 Event Opcode9

ei_stylus.pressure(pressure)
Argument Type Summary
pressure float The tip pressure as a normalized value.
Note

This event is only available for clients of ei_handshake.context_type.receiver.

See the ei_stylus.pressure request for more details.

ei_stylus.distance

Since Version1 Event Opcode10

ei_stylus.distance(distance)
Argument Type Summary
distance float The tip-to-digitizer distance as a normalized value.
Note

This event is only available for clients of ei_handshake.context_type.receiver.

See the ei_stylus.distance request for more details.

ei_stylus.tilt

Since Version1 Event Opcode11

ei_stylus.tilt(tilt_x, tilt_y)
Argument Type Summary
tilt_x float The angle in degrees of the stylus along the digitizer X axis.
tilt_y float The angle in degrees of the stylus along the digitizer Y axis.
Note

This event is only available for clients of ei_handshake.context_type.receiver.

See the ei_stylus.tilt request for more details.

ei_stylus.rotation

Since Version1 Event Opcode12

ei_stylus.rotation(rotation)
Argument Type Summary
rotation float The angle in degrees of the stylus about its own Z axis.
Note

This event is only available for clients of ei_handshake.context_type.receiver.

See the ei_stylus.rotation request for more details.

ei_stylus.airbrush_flow

Since Version1 Event Opcode13

ei_stylus.airbrush_flow(flow)
Argument Type Summary
flow float The position of an airbrush flow control present on the tool, as a normalized value.
Note

This event is only available for clients of ei_handshake.context_type.receiver.

See the ei_stylus.airbrush_flow request for more details.