mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2025-08-18 01:15:46 +00:00
Provide reference dimensions for mouse position data
This commit is contained in:
parent
bbbf4336cc
commit
247b1fe0e3
24
src/Input.h
24
src/Input.h
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user