Provide reference dimensions for mouse position data

This commit is contained in:
Cameron Gutman 2020-04-11 20:51:17 -07:00
parent bbbf4336cc
commit 247b1fe0e3
3 changed files with 52 additions and 33 deletions

View File

@ -25,15 +25,31 @@ typedef struct _NV_KEYBOARD_PACKET {
short zero2;
} NV_KEYBOARD_PACKET, *PNV_KEYBOARD_PACKET;
#define PACKET_TYPE_MOUSE_MOVE 0x08
#define MOUSE_MOVE_ABS_MAGIC 0x05
#define PACKET_TYPE_REL_MOUSE_MOVE 0x08
#define MOUSE_MOVE_REL_MAGIC 0x06
typedef struct _NV_MOUSE_MOVE_PACKET {
typedef struct _NV_REL_MOUSE_MOVE_PACKET {
NV_INPUT_HEADER header;
int magic;
short deltaX;
short deltaY;
} NV_MOUSE_MOVE_PACKET, *PNV_MOUSE_MOVE_PACKET;
} NV_REL_MOUSE_MOVE_PACKET, *PNV_REL_MOUSE_MOVE_PACKET;
#define PACKET_TYPE_ABS_MOUSE_MOVE 0x0e
#define MOUSE_MOVE_ABS_MAGIC 0x05
typedef struct _NV_ABS_MOUSE_MOVE_PACKET {
NV_INPUT_HEADER header;
int magic;
short x;
short y;
short unused;
// Used on the server-side as a reference to scale x and y
// to screen coordinates.
short width;
short height;
} NV_ABS_MOUSE_MOVE_PACKET, *PNV_ABS_MOUSE_MOVE_PACKET;
#define PACKET_TYPE_MOUSE_BUTTON 0x05
typedef struct _NV_MOUSE_BUTTON_PACKET {

View File

@ -25,7 +25,8 @@ typedef struct _PACKET_HOLDER {
int packetLength;
union {
NV_KEYBOARD_PACKET keyboard;
NV_MOUSE_MOVE_PACKET mouseMove;
NV_REL_MOUSE_MOVE_PACKET mouseMoveRel;
NV_ABS_MOUSE_MOVE_PACKET mouseMoveAbs;
NV_MOUSE_BUTTON_PACKET mouseButton;
NV_CONTROLLER_PACKET controller;
NV_MULTI_CONTROLLER_PACKET multiController;
@ -248,11 +249,11 @@ static void inputSendThreadProc(void* context) {
free(controllerBatchHolder);
}
}
// If it's a mouse move packet, we can also do batching
else if (holder->packet.mouseMove.header.packetType == htonl(PACKET_TYPE_MOUSE_MOVE)) {
// If it's a relative mouse move packet, we can also do batching
else if (holder->packet.mouseMoveRel.header.packetType == htonl(PACKET_TYPE_REL_MOUSE_MOVE)) {
PPACKET_HOLDER mouseBatchHolder;
int totalDeltaX = (short)htons(holder->packet.mouseMove.deltaX);
int totalDeltaY = (short)htons(holder->packet.mouseMove.deltaY);
int totalDeltaX = (short)htons(holder->packet.mouseMoveRel.deltaX);
int totalDeltaY = (short)htons(holder->packet.mouseMoveRel.deltaY);
for (;;) {
int partialDeltaX;
@ -264,12 +265,12 @@ static void inputSendThreadProc(void* context) {
}
// If it's not a mouse move packet, we're done
if (mouseBatchHolder->packet.mouseMove.header.packetType != htonl(PACKET_TYPE_MOUSE_MOVE)) {
if (mouseBatchHolder->packet.mouseMoveRel.header.packetType != htonl(PACKET_TYPE_REL_MOUSE_MOVE)) {
break;
}
partialDeltaX = (short)htons(mouseBatchHolder->packet.mouseMove.deltaX);
partialDeltaY = (short)htons(mouseBatchHolder->packet.mouseMove.deltaY);
partialDeltaX = (short)htons(mouseBatchHolder->packet.mouseMoveRel.deltaX);
partialDeltaY = (short)htons(mouseBatchHolder->packet.mouseMoveRel.deltaY);
// Check for overflow
if (partialDeltaX + totalDeltaX > INT16_MAX ||
@ -293,8 +294,8 @@ static void inputSendThreadProc(void* context) {
}
// Update the original packet
holder->packet.mouseMove.deltaX = htons((short)totalDeltaX);
holder->packet.mouseMove.deltaY = htons((short)totalDeltaY);
holder->packet.mouseMoveRel.deltaX = htons((short)totalDeltaX);
holder->packet.mouseMoveRel.deltaY = htons((short)totalDeltaY);
}
// Encrypt the message into the output buffer while leaving room for the length
@ -438,15 +439,15 @@ int LiSendMouseMoveEvent(short deltaX, short deltaY) {
return -1;
}
holder->packetLength = sizeof(NV_MOUSE_MOVE_PACKET);
holder->packet.mouseMove.header.packetType = htonl(PACKET_TYPE_MOUSE_MOVE);
holder->packet.mouseMove.magic = MOUSE_MOVE_REL_MAGIC;
holder->packetLength = sizeof(NV_REL_MOUSE_MOVE_PACKET);
holder->packet.mouseMoveRel.header.packetType = htonl(PACKET_TYPE_REL_MOUSE_MOVE);
holder->packet.mouseMoveRel.magic = MOUSE_MOVE_REL_MAGIC;
// On Gen 5 servers, the header code is incremented by one
if (AppVersionQuad[0] >= 5) {
holder->packet.mouseMove.magic++;
holder->packet.mouseMoveRel.magic++;
}
holder->packet.mouseMove.deltaX = htons(deltaX);
holder->packet.mouseMove.deltaY = htons(deltaY);
holder->packet.mouseMoveRel.deltaX = htons(deltaX);
holder->packet.mouseMoveRel.deltaY = htons(deltaY);
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
if (err != LBQ_SUCCESS) {
@ -457,7 +458,7 @@ int LiSendMouseMoveEvent(short deltaX, short deltaY) {
}
// Send a mouse position update to the streaming machine
int LiSendMousePositionEvent(short x, short y) {
int LiSendMousePositionEvent(short x, short y, short referenceWidth, short referenceHeight) {
PPACKET_HOLDER holder;
int err;
@ -475,11 +476,14 @@ int LiSendMousePositionEvent(short x, short y) {
return -1;
}
holder->packetLength = sizeof(NV_MOUSE_MOVE_PACKET);
holder->packet.mouseMove.header.packetType = htonl(PACKET_TYPE_MOUSE_MOVE);
holder->packet.mouseMove.magic = MOUSE_MOVE_ABS_MAGIC;
holder->packet.mouseMove.deltaX = htons(x);
holder->packet.mouseMove.deltaY = htons(y);
holder->packetLength = sizeof(NV_ABS_MOUSE_MOVE_PACKET);
holder->packet.mouseMoveAbs.header.packetType = htonl(PACKET_TYPE_ABS_MOUSE_MOVE);
holder->packet.mouseMoveAbs.magic = MOUSE_MOVE_ABS_MAGIC;
holder->packet.mouseMoveAbs.x = htons(x);
holder->packet.mouseMoveAbs.y = htons(y);
holder->packet.mouseMoveAbs.unused = 0;
holder->packet.mouseMoveAbs.width = htons(referenceWidth);
holder->packet.mouseMoveAbs.height = htons(referenceHeight);
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
if (err != LBQ_SUCCESS) {

View File

@ -429,14 +429,13 @@ int LiSendMouseMoveEvent(short deltaX, short deltaY);
// for mice when streaming. It may be desirable as the default touchscreen behavior if the
// touchscreen is not the primary input method.
//
// The x and y values are host screen coordinates (not video coordinates!), so the client must take
// care to scale the initial user input (likely in client window coordinates) before passing it to
// LiSendMousePositionEvent(). The /launch and /resume HTTPS responses include 'DisplayWidth' and
// 'DisplayHeight' XML elements which allow the client to scale properly from video coordinates
// to host screen cordinates.
// The x and y values are transformed to host coordinates as if they are from a plane which
// is referenceWidth by referenceHeight in size. This allows you to provide coordinates that
// are relative to an arbitrary plane, such as a window, screen, or scaled video view.
//
// There is no known way to be notified of a resolution change after the stream is launched.
int LiSendMousePositionEvent(short x, short y);
// For example, if you wanted to directly pass window coordinates as x and y, you would set
// referenceWidth and referenceHeight to your window width and height.
int LiSendMousePositionEvent(short x, short y, short referenceWidth, short referenceHeight);
// This function queues a mouse button event to be sent to the remote server.
#define BUTTON_ACTION_PRESS 0x07