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

View File

@@ -3,6 +3,7 @@
#include "streaming/session.h"
#include "settings/mappingmanager.h"
#include "path.h"
#include "streamutils.h"
#include <QtGlobal>
#include <QtMath>
@@ -65,7 +66,8 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer*, int s
m_DragButton(0),
m_NumFingersDown(0),
m_StreamWidth(streamWidth),
m_StreamHeight(streamHeight)
m_StreamHeight(streamHeight),
m_AbsoluteMouseMode(false)
{
// Allow gamepad input when the app doesn't have focus
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
@@ -250,6 +252,21 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
raiseAllKeys();
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") {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Detected full-screen toggle combo (SDLK)");
@@ -310,6 +327,21 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
raiseAllKeys();
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) {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Detected stats toggle combo (scancode)");
@@ -633,7 +665,7 @@ void SdlInputHandler::handleMouseButtonEvent(SDL_MouseButtonEvent* event)
button);
}
void SdlInputHandler::handleMouseMotionEvent(SDL_MouseMotionEvent* event)
void SdlInputHandler::handleMouseMotionEvent(SDL_Window* window, SDL_MouseMotionEvent* event)
{
if (!isCaptureActive()) {
// Not capturing
@@ -644,10 +676,36 @@ void SdlInputHandler::handleMouseMotionEvent(SDL_MouseMotionEvent* event)
return;
}
// 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);
if (m_AbsoluteMouseMode) {
SDL_Rect src, dst;
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)
@@ -1196,7 +1254,7 @@ void SdlInputHandler::rumble(unsigned short controllerNumber, unsigned short low
#endif
}
void SdlInputHandler::handleTouchFingerEvent(SDL_TouchFingerEvent* event)
void SdlInputHandler::handleTouchFingerEvent(SDL_Window*, SDL_TouchFingerEvent* event)
{
int fingerIndex = -1;
@@ -1396,8 +1454,8 @@ bool SdlInputHandler::isCaptureActive()
void SdlInputHandler::setCaptureActive(bool active)
{
if (active) {
// Try to activate SDL's relative mouse mode
if (SDL_SetRelativeMouseMode(SDL_TRUE) < 0) {
// If we're in relative mode, try to activate SDL's relative mouse mode
if (m_AbsoluteMouseMode || SDL_SetRelativeMouseMode(SDL_TRUE) < 0) {
// Relative mouse mode didn't work, so we'll use fake capture
SDL_ShowCursor(SDL_DISABLE);
m_FakeCaptureActive = true;

View File

@@ -47,7 +47,7 @@ public:
void handleMouseButtonEvent(SDL_MouseButtonEvent* event);
void handleMouseMotionEvent(SDL_MouseMotionEvent* event);
void handleMouseMotionEvent(SDL_Window* window, SDL_MouseMotionEvent* event);
void handleMouseWheelEvent(SDL_MouseWheelEvent* event);
@@ -61,7 +61,7 @@ public:
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();
@@ -114,6 +114,7 @@ private:
int m_NumFingersDown;
int m_StreamWidth;
int m_StreamHeight;
bool m_AbsoluteMouseMode;
static const int k_ButtonMap[];
};

View File

@@ -1318,7 +1318,7 @@ void Session::exec(int displayOriginX, int displayOriginY)
m_InputHandler->handleMouseButtonEvent(&event.button);
break;
case SDL_MOUSEMOTION:
m_InputHandler->handleMouseMotionEvent(&event.motion);
m_InputHandler->handleMouseMotionEvent(m_Window, &event.motion);
break;
case SDL_MOUSEWHEEL:
m_InputHandler->handleMouseWheelEvent(&event.wheel);
@@ -1340,7 +1340,7 @@ void Session::exec(int displayOriginX, int displayOriginY)
case SDL_FINGERDOWN:
case SDL_FINGERMOTION:
case SDL_FINGERUP:
m_InputHandler->handleTouchFingerEvent(&event.tfinger);
m_InputHandler->handleTouchFingerEvent(m_Window, &event.tfinger);
break;
}
}