Extend pen/touch APIs with contact area and orientation

This commit is contained in:
Cameron Gutman 2023-07-22 15:01:03 -05:00
parent 6f4f2607b3
commit 70a2e305bc
3 changed files with 39 additions and 13 deletions

View File

@ -127,11 +127,14 @@ typedef struct _SS_HSCROLL_PACKET {
typedef struct _SS_TOUCH_PACKET {
NV_INPUT_HEADER header;
uint8_t eventType;
uint8_t zero[3]; // Alignment/reserved
uint8_t zero[1]; // Alignment/reserved
uint16_t rotation;
uint32_t pointerId;
netfloat x;
netfloat y;
netfloat pressureOrDistance;
netfloat contactAreaMajor;
netfloat contactAreaMinor;
} SS_TOUCH_PACKET, *PSS_TOUCH_PACKET;
#define SS_PEN_MAGIC 0x55000003
@ -147,6 +150,8 @@ typedef struct _SS_PEN_PACKET {
uint16_t rotation;
uint8_t tilt;
uint8_t zero2[1];
netfloat contactAreaMajor;
netfloat contactAreaMinor;
} SS_PEN_PACKET, *PSS_PEN_PACKET;
#define SS_CONTROLLER_ARRIVAL_MAGIC 0x55000004

View File

@ -1216,7 +1216,8 @@ int LiSendHScrollEvent(signed char scrollClicks) {
return LiSendHighResHScrollEvent(scrollClicks * LI_WHEEL_DELTA);
}
int LiSendTouchEvent(uint8_t eventType, uint32_t pointerId, float x, float y, float pressureOrDistance) {
int LiSendTouchEvent(uint8_t eventType, uint32_t pointerId, float x, float y, float pressureOrDistance,
float contactAreaMajor, float contactAreaMinor, uint16_t rotation) {
PPACKET_HOLDER holder;
int err;
@ -1244,10 +1245,13 @@ int LiSendTouchEvent(uint8_t eventType, uint32_t pointerId, float x, float y, fl
holder->packet.touch.header.magic = LE32(SS_TOUCH_MAGIC);
holder->packet.touch.eventType = eventType;
holder->packet.touch.pointerId = LE32(pointerId);
holder->packet.touch.rotation = LE16(rotation);
memset(holder->packet.touch.zero, 0, sizeof(holder->packet.touch.zero));
floatToNetfloat(x, holder->packet.touch.x);
floatToNetfloat(y, holder->packet.touch.y);
floatToNetfloat(pressureOrDistance, holder->packet.touch.pressureOrDistance);
floatToNetfloat(contactAreaMajor, holder->packet.touch.contactAreaMajor);
floatToNetfloat(contactAreaMinor, holder->packet.touch.contactAreaMinor);
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
if (err != LBQ_SUCCESS) {
@ -1261,6 +1265,7 @@ int LiSendTouchEvent(uint8_t eventType, uint32_t pointerId, float x, float y, fl
int LiSendPenEvent(uint8_t eventType, uint8_t toolType, uint8_t penButtons,
float x, float y, float pressureOrDistance,
float contactAreaMajor, float contactAreaMinor,
uint16_t rotation, uint8_t tilt) {
PPACKET_HOLDER holder;
int err;
@ -1298,6 +1303,8 @@ int LiSendPenEvent(uint8_t eventType, uint8_t toolType, uint8_t penButtons,
holder->packet.pen.rotation = LE16(rotation);
holder->packet.pen.tilt = tilt;
memset(holder->packet.pen.zero2, 0, sizeof(holder->packet.pen.zero2));
floatToNetfloat(contactAreaMajor, holder->packet.pen.contactAreaMajor);
floatToNetfloat(contactAreaMinor, holder->packet.pen.contactAreaMinor);
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
if (err != LBQ_SUCCESS) {

View File

@ -593,17 +593,30 @@ int LiSendMouseMoveAsMousePositionEvent(short deltaX, short deltaY, short refere
// This function allows multi-touch input to be sent directly to Sunshine hosts. The x and y values
// are normalized device coordinates stretching top-left corner (0.0, 0.0) to bottom-right corner
// (1.0, 1.0) of the video area. Pressure is a 0.0 to 1.0 range value from min to max pressure.
// (1.0, 1.0) of the video area.
//
// Sending a down/move event with a pressure of 0.0 indicates the actual pressure is unknown.
// Pointer ID is an opaque ID that must uniquely identify each active touch on screen. It must
// remain constant through any down/up/move/cancel events involved in a single touch interaction.
//
// Rotation is in degrees from vertical in Y dimension (parallel to screen, 0..360). If rotation is
// unknown, pass LI_ROT_UNKNOWN.
//
// Pressure is a 0.0 to 1.0 range value from min to max pressure. Sending a down/move event with
// a pressure of 0.0 indicates the actual pressure is unknown.
//
// For hover events, the pressure value is treated as a 1.0 to 0.0 range of distance from the touch
// surface where 1.0 is the farthest measurable distance and 0.0 is actually touching the display
// (which is invalid for a hover event). Reporting distance 0.0 for a hover event indicates the
// actual distance is unknown.
//
// Pointer ID is an opaque ID that must uniquely identify each active touch on screen. It must
// remain constant through any down/up/move/cancel events involved in a single touch interaction.
// Contact area is modelled as an ellipse with major and minor axis values in normalized device
// coordinates. If contact area is unknown, report 0.0 for both contact area axis parameters.
// For circular contact areas or if a minor axis value is not available, pass the same value
// for major and minor axes. For APIs or devices, that don't report contact area as an ellipse,
// approximations can be used such as: https://docs.kernel.org/input/multi-touch-protocol.html#event-computation
//
// For hover events, the "contact area" is the size of the hovering finger/tool. If unavailable,
// pass 0.0 for both contact area parameters.
//
// If unsupported by the host, this will return LI_ERR_UNSUPPORTED and the caller should consider
// falling back to other functions to send this input (such as LiSendMousePositionEvent()).
@ -614,25 +627,26 @@ int LiSendMouseMoveAsMousePositionEvent(short deltaX, short deltaY, short refere
#define LI_TOUCH_EVENT_CANCEL 0x04
#define LI_TOUCH_EVENT_BUTTON_ONLY 0x05
#define LI_TOUCH_EVENT_HOVER_LEAVE 0x06
int LiSendTouchEvent(uint8_t eventType, uint32_t pointerId, float x, float y, float pressureOrDistance);
#define LI_ROT_UNKNOWN 0xFFFF
int LiSendTouchEvent(uint8_t eventType, uint32_t pointerId, float x, float y, float pressureOrDistance,
float contactAreaMajor, float contactAreaMinor, uint16_t rotation);
// This function is similar to LiSendTouchEvent() but allows additional parameters relevant for pen
// input, including rotation, tilt, and buttons. Rotation is in degrees from vertical in Y dimension
// (parallel to screen, 0..360) and tilt is in degrees from vertical in Z dimension (perpendicular
// to screen, 0..90).
// input, including tilt and buttons. Tilt is in degrees from vertical in Z dimension (perpendicular
// to screen, 0..90). See LiSendTouchEvent() for detailed documentation on other parameters.
//
// x, y, pressure, rotation, and tilt are ignored for LI_TOUCH_EVENT_BUTTON_ONLY events. If one of
// those changes, send LI_TOUCH_EVENT_MOVE or LI_TOUCH_EVENT_HOVER instead.
// x, y, pressure, rotation, contact area, and tilt are ignored for LI_TOUCH_EVENT_BUTTON_ONLY events.
// If one of those changes, send LI_TOUCH_EVENT_MOVE or LI_TOUCH_EVENT_HOVER instead.
#define LI_TOOL_TYPE_UNKNOWN 0x00
#define LI_TOOL_TYPE_PEN 0x01
#define LI_TOOL_TYPE_ERASER 0x02
#define LI_PEN_BUTTON_PRIMARY 0x01
#define LI_PEN_BUTTON_SECONDARY 0x02
#define LI_PEN_BUTTON_TERTIARY 0x04
#define LI_ROT_UNKNOWN 0xFFFF
#define LI_TILT_UNKNOWN 0xFF
int LiSendPenEvent(uint8_t eventType, uint8_t toolType, uint8_t penButtons,
float x, float y, float pressureOrDistance,
float contactAreaMajor, float contactAreaMinor,
uint16_t rotation, uint8_t tilt);
// This function queues a mouse button event to be sent to the remote server.