Add LiSendMouseMoveAsMousePositionEvent() function

This is a useful option for Android and iOS where mouse acceleration
is always enabled and mouse capture is the only feasible way to get
mouse input. It can avoid double-acceleration when being used for
remote desktop mouse mode.
This commit is contained in:
Cameron Gutman
2022-05-28 14:58:34 -05:00
parent e62dc56047
commit d247873ade
2 changed files with 45 additions and 0 deletions

View File

@@ -12,6 +12,11 @@ static LINKED_BLOCKING_QUEUE packetQueue;
static LINKED_BLOCKING_QUEUE packetHolderFreeList;
static PLT_THREAD inputSendThread;
static float absCurrentPosX;
static float absCurrentPosY;
#define CLAMP(val, min, max) (((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)))
#define MAX_INPUT_PACKET_SIZE 128
#define INPUT_STREAM_TIMEOUT_SEC 10
@@ -62,6 +67,9 @@ int initializeInputStream(void) {
// GFE 3.15.0.164 seems to be the first release using NVVHCI for mouse/keyboard
needsBatchedScroll = APP_VERSION_AT_LEAST(7, 1, 409);
batchedScrollDelta = 0;
// Start with the virtual mouse centered
absCurrentPosX = absCurrentPosY = 0.5f;
return 0;
}
@@ -610,9 +618,27 @@ int LiSendMousePositionEvent(short x, short y, short referenceWidth, short refer
freePacketHolder(holder);
}
// This is not thread safe, but it's not a big deal because callers that want to
// use LiSendRelativeMotionAsMousePositionEvent() must not mix these function
// without synchronization (otherwise the state of the cursor on the host is
// undefined anyway).
absCurrentPosX = CLAMP(x, 0, referenceWidth - 1) / (float)(referenceWidth - 1);
absCurrentPosY = CLAMP(y, 0, referenceHeight - 1) / (float)(referenceHeight - 1);
return err;
}
// Send a relative motion event using absolute position to the streaming machine
int LiSendMouseMoveAsMousePositionEvent(short deltaX, short deltaY, short referenceWidth, short referenceHeight) {
// Convert the current position to be relative to the provided reference dimensions
short oldPositionX = (short)(absCurrentPosX * referenceWidth);
short oldPositionY = (short)(absCurrentPosY * referenceHeight);
return LiSendMousePositionEvent(CLAMP(oldPositionX + deltaX, 0, referenceWidth),
CLAMP(oldPositionY + deltaY, 0, referenceHeight),
referenceWidth, referenceHeight);
}
// Send a mouse button event to the streaming machine
int LiSendMouseButtonEvent(char action, int button) {
PPACKET_HOLDER holder;

View File

@@ -509,6 +509,25 @@ int LiSendMouseMoveEvent(short deltaX, short deltaY);
// referenceWidth and referenceHeight to your window width and height.
int LiSendMousePositionEvent(short x, short y, short referenceWidth, short referenceHeight);
// This function queues a mouse position update event to be sent to the remote server, so
// all of the limitations of LiSendMousePositionEvent() mentioned above apply here too!
//
// This function behaves like a combination of LiSendMouseMoveEvent() and LiSendMousePositionEvent()
// in that it sends a relative motion event, however it sends this data as an absolute position
// based on the computed position of a virtual client cursor which is "moved" any time that
// LiSendMousePositionEvent() or LiSendMouseMoveAsMousePositionEvent() is called. As a result
// of this internal virtual cursor state, callers must ensure LiSendMousePositionEvent() and
// LiSendMouseMoveAsMousePositionEvent() are not called concurrently!
//
// The big advantage of this function is that it allows callers to avoid mouse acceleration that
// would otherwise affect motion when using LiSendMouseMoveEvent(). The downside is that it has the
// same game compatibility issues as LiSendMousePositionEvent().
//
// This function can be useful when mouse capture is the only feasible way to receive mouse input,
// like on Android or iOS, and the OS cannot provide raw unaccelerated mouse motion when capturing.
// Using this function avoids double-acceleration in cases when the client motion is also accelerated.
int LiSendMouseMoveAsMousePositionEvent(short deltaX, short deltaY, short referenceWidth, short referenceHeight);
// This function queues a mouse button event to be sent to the remote server.
#define BUTTON_ACTION_PRESS 0x07
#define BUTTON_ACTION_RELEASE 0x08