Add basic support for absolute mouse input

This commit is contained in:
Cameron Gutman
2020-04-11 16:12:18 -07:00
parent 3840ee8ee7
commit ef6dfa6d91
4 changed files with 73 additions and 14 deletions
+67 -9
View File
@@ -3,6 +3,7 @@
#include "streaming/session.h" #include "streaming/session.h"
#include "settings/mappingmanager.h" #include "settings/mappingmanager.h"
#include "path.h" #include "path.h"
#include "streamutils.h"
#include <QtGlobal> #include <QtGlobal>
#include <QtMath> #include <QtMath>
@@ -65,7 +66,8 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer*, int s
m_DragButton(0), m_DragButton(0),
m_NumFingersDown(0), m_NumFingersDown(0),
m_StreamWidth(streamWidth), m_StreamWidth(streamWidth),
m_StreamHeight(streamHeight) m_StreamHeight(streamHeight),
m_AbsoluteMouseMode(false)
{ {
// Allow gamepad input when the app doesn't have focus // Allow gamepad input when the app doesn't have focus
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
@@ -250,6 +252,21 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
raiseAllKeys(); raiseAllKeys();
return; return;
} }
// Check for the mouse mode combo (Ctrl+Alt+Shift+M) unless on EGLFS which has no window manager
else if (event->keysym.sym == SDLK_m && QGuiApplication::platformName() != "eglfs") {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Detected mouse mode toggle combo (SDLK)");
// Uncapture input
setCaptureActive(false);
// Toggle mouse mode
m_AbsoluteMouseMode = !m_AbsoluteMouseMode;
// Recapture input
setCaptureActive(true);
return;
}
else if (event->keysym.sym == SDLK_x && QGuiApplication::platformName() != "eglfs") { else if (event->keysym.sym == SDLK_x && QGuiApplication::platformName() != "eglfs") {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Detected full-screen toggle combo (SDLK)"); "Detected full-screen toggle combo (SDLK)");
@@ -310,6 +327,21 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
raiseAllKeys(); raiseAllKeys();
return; return;
} }
// Check for the mouse mode toggle combo (Ctrl+Alt+Shift+M) unless on EGLFS which has no window manager
else if (event->keysym.scancode == SDL_SCANCODE_M && QGuiApplication::platformName() != "eglfs") {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Detected mouse mode toggle combo (scancode)");
// Uncapture input
setCaptureActive(false);
// Toggle mouse mode
m_AbsoluteMouseMode = !m_AbsoluteMouseMode;
// Recapture input
setCaptureActive(true);
return;
}
else if (event->keysym.scancode == SDL_SCANCODE_S) { else if (event->keysym.scancode == SDL_SCANCODE_S) {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Detected stats toggle combo (scancode)"); "Detected stats toggle combo (scancode)");
@@ -633,7 +665,7 @@ void SdlInputHandler::handleMouseButtonEvent(SDL_MouseButtonEvent* event)
button); button);
} }
void SdlInputHandler::handleMouseMotionEvent(SDL_MouseMotionEvent* event) void SdlInputHandler::handleMouseMotionEvent(SDL_Window* window, SDL_MouseMotionEvent* event)
{ {
if (!isCaptureActive()) { if (!isCaptureActive()) {
// Not capturing // Not capturing
@@ -644,10 +676,36 @@ void SdlInputHandler::handleMouseMotionEvent(SDL_MouseMotionEvent* event)
return; return;
} }
// Batch until the next mouse polling window or we'll get awful if (m_AbsoluteMouseMode) {
// input lag everything except GFE 3.14 and 3.15. SDL_Rect src, dst;
SDL_AtomicAdd(&m_MouseDeltaX, event->xrel);
SDL_AtomicAdd(&m_MouseDeltaY, event->yrel); src.x = src.y = 0;
src.w = m_StreamWidth;
src.h = m_StreamHeight;
dst.x = dst.y = 0;
SDL_GetWindowSize(window, &dst.w, &dst.h);
// Use the stream and window sizes to determine the video region
StreamUtils::scaleSourceToDestinationSurface(&src, &dst);
// Ignore motion outside the video region
if (event->x < dst.x || event->y < dst.y ||
event->x > dst.x + dst.w || event->y > dst.y + dst.h) {
return;
}
// Send the mouse position update with coordinates relative to
// the video region.
LiSendMousePositionEvent(event->x - dst.x, event->y - dst.y,
dst.w, dst.h);
}
else {
// Batch until the next mouse polling window or we'll get awful
// input lag everything except GFE 3.14 and 3.15.
SDL_AtomicAdd(&m_MouseDeltaX, event->xrel);
SDL_AtomicAdd(&m_MouseDeltaY, event->yrel);
}
} }
void SdlInputHandler::handleMouseWheelEvent(SDL_MouseWheelEvent* event) void SdlInputHandler::handleMouseWheelEvent(SDL_MouseWheelEvent* event)
@@ -1196,7 +1254,7 @@ void SdlInputHandler::rumble(unsigned short controllerNumber, unsigned short low
#endif #endif
} }
void SdlInputHandler::handleTouchFingerEvent(SDL_TouchFingerEvent* event) void SdlInputHandler::handleTouchFingerEvent(SDL_Window*, SDL_TouchFingerEvent* event)
{ {
int fingerIndex = -1; int fingerIndex = -1;
@@ -1396,8 +1454,8 @@ bool SdlInputHandler::isCaptureActive()
void SdlInputHandler::setCaptureActive(bool active) void SdlInputHandler::setCaptureActive(bool active)
{ {
if (active) { if (active) {
// Try to activate SDL's relative mouse mode // If we're in relative mode, try to activate SDL's relative mouse mode
if (SDL_SetRelativeMouseMode(SDL_TRUE) < 0) { if (m_AbsoluteMouseMode || SDL_SetRelativeMouseMode(SDL_TRUE) < 0) {
// Relative mouse mode didn't work, so we'll use fake capture // Relative mouse mode didn't work, so we'll use fake capture
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
m_FakeCaptureActive = true; m_FakeCaptureActive = true;
+3 -2
View File
@@ -47,7 +47,7 @@ public:
void handleMouseButtonEvent(SDL_MouseButtonEvent* event); void handleMouseButtonEvent(SDL_MouseButtonEvent* event);
void handleMouseMotionEvent(SDL_MouseMotionEvent* event); void handleMouseMotionEvent(SDL_Window* window, SDL_MouseMotionEvent* event);
void handleMouseWheelEvent(SDL_MouseWheelEvent* event); void handleMouseWheelEvent(SDL_MouseWheelEvent* event);
@@ -61,7 +61,7 @@ public:
void rumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor); void rumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor);
void handleTouchFingerEvent(SDL_TouchFingerEvent* event); void handleTouchFingerEvent(SDL_Window* window, SDL_TouchFingerEvent* event);
int getAttachedGamepadMask(); int getAttachedGamepadMask();
@@ -114,6 +114,7 @@ private:
int m_NumFingersDown; int m_NumFingersDown;
int m_StreamWidth; int m_StreamWidth;
int m_StreamHeight; int m_StreamHeight;
bool m_AbsoluteMouseMode;
static const int k_ButtonMap[]; static const int k_ButtonMap[];
}; };
+2 -2
View File
@@ -1318,7 +1318,7 @@ void Session::exec(int displayOriginX, int displayOriginY)
m_InputHandler->handleMouseButtonEvent(&event.button); m_InputHandler->handleMouseButtonEvent(&event.button);
break; break;
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
m_InputHandler->handleMouseMotionEvent(&event.motion); m_InputHandler->handleMouseMotionEvent(m_Window, &event.motion);
break; break;
case SDL_MOUSEWHEEL: case SDL_MOUSEWHEEL:
m_InputHandler->handleMouseWheelEvent(&event.wheel); m_InputHandler->handleMouseWheelEvent(&event.wheel);
@@ -1340,7 +1340,7 @@ void Session::exec(int displayOriginX, int displayOriginY)
case SDL_FINGERDOWN: case SDL_FINGERDOWN:
case SDL_FINGERMOTION: case SDL_FINGERMOTION:
case SDL_FINGERUP: case SDL_FINGERUP:
m_InputHandler->handleTouchFingerEvent(&event.tfinger); m_InputHandler->handleTouchFingerEvent(m_Window, &event.tfinger);
break; break;
} }
} }