diff --git a/src/Input.h b/src/Input.h index 29ab0b9..b07b3b9 100644 --- a/src/Input.h +++ b/src/Input.h @@ -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 diff --git a/src/InputStream.c b/src/InputStream.c index 3bc75a2..4855965 100644 --- a/src/InputStream.c +++ b/src/InputStream.c @@ -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) { diff --git a/src/Limelight.h b/src/Limelight.h index a658b82..e890dbe 100644 --- a/src/Limelight.h +++ b/src/Limelight.h @@ -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.