From 231a67946d35fb50db06aa8ece2cf171b3152e0d Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 31 Jan 2025 01:13:17 -0600 Subject: [PATCH] WIP SDL3 compatibility --- app/SDL_compat.c | 63 +++++ app/SDL_compat.h | 252 +++++++++++++++-- app/backend/systemproperties.cpp | 17 +- app/gui/sdlgamepadkeynavigation.cpp | 100 +++---- app/gui/sdlgamepadkeynavigation.h | 2 +- app/masterhook.c | 1 + app/masterhook_internal.c | 18 +- app/streaming/audio/audio.cpp | 2 +- app/streaming/audio/renderers/sdlaud.cpp | 4 +- app/streaming/input/abstouch.cpp | 26 +- app/streaming/input/gamepad.cpp | 257 +++++++++--------- app/streaming/input/input.cpp | 16 +- app/streaming/input/input.h | 16 +- app/streaming/input/keyboard.cpp | 55 ++-- app/streaming/input/mouse.cpp | 24 +- app/streaming/input/reltouch.cpp | 22 +- app/streaming/session.cpp | 201 +++++++------- app/streaming/session.h | 2 +- app/streaming/streamutils.cpp | 33 +-- app/streaming/streamutils.h | 2 +- .../video/ffmpeg-renderers/d3d11va.cpp | 2 +- app/streaming/video/ffmpeg-renderers/drm.cpp | 2 +- .../video/ffmpeg-renderers/dxva2.cpp | 10 +- .../video/ffmpeg-renderers/eglvid.cpp | 22 +- app/streaming/video/ffmpeg-renderers/mmal.cpp | 2 +- .../video/ffmpeg-renderers/pacer/pacer.cpp | 10 +- app/streaming/video/ffmpeg-renderers/plvk.cpp | 34 ++- .../video/ffmpeg-renderers/sdlvid.cpp | 8 +- .../video/ffmpeg-renderers/vaapi.cpp | 10 +- .../video/ffmpeg-renderers/vdpau.cpp | 10 +- app/streaming/video/ffmpeg.cpp | 20 +- app/streaming/video/overlaymanager.cpp | 8 +- app/streaming/video/slvid.cpp | 6 +- app/wm.cpp | 12 +- 34 files changed, 772 insertions(+), 497 deletions(-) diff --git a/app/SDL_compat.c b/app/SDL_compat.c index 1c1f8cac..80aea122 100644 --- a/app/SDL_compat.c +++ b/app/SDL_compat.c @@ -255,3 +255,66 @@ void SDLC_FlushWindowEvents(void) { SDL_FlushEvent(SDL_WINDOWEVENT); } + +SDL_JoystickID* SDL_GetGamepads(int *count) +{ + int numJoysticks = SDL_NumJoysticks(); + SDL_JoystickID* ids = SDL_calloc(numJoysticks + 1, sizeof(SDL_JoystickID)); + + int numGamepads = 0; + for (int i = 0; i < numJoysticks; i++) { + if (SDL_IsGameController(i)) { + ids[numGamepads++] = i; + } + } + + if (count != NULL) { + *count = numGamepads; + } + + return ids; +} + +SDL_JoystickID* SDL_GetJoysticks(int *count) +{ + int numJoysticks = SDL_NumJoysticks(); + SDL_JoystickID* ids = SDL_calloc(numJoysticks + 1, sizeof(SDL_JoystickID)); + + for (int i = 0; i < numJoysticks; i++) { + ids[i] = i; + } + + if (count != NULL) { + *count = numJoysticks; + } + + return ids; +} + +SDL_DisplayID * SDL_GetDisplays(int *count) +{ + int numDisplays = SDL_GetNumVideoDisplays(); + SDL_DisplayID* ids = SDL_calloc(numDisplays + 1, sizeof(SDL_DisplayID)); + + for (int i = 0; i < numDisplays; i++) { + ids[i] = i; + } + + if (count != NULL) { + *count = numDisplays; + } + + return ids; +} + +const SDL_DisplayMode * SDL_GetWindowFullscreenMode(SDL_Window *window) +{ + static SDL_DisplayMode mode; + + if (SDL_GetWindowDisplayMode(window, &mode) == 0) { + return &mode; + } + else { + return NULL; + } +} diff --git a/app/SDL_compat.h b/app/SDL_compat.h index 672e3989..87d68a4d 100644 --- a/app/SDL_compat.h +++ b/app/SDL_compat.h @@ -1,5 +1,5 @@ // -// Compatibility header for older version of SDL. +// Compatibility header for older versions of SDL. // Include this instead of SDL.h directly. // @@ -13,6 +13,43 @@ extern "C" { #endif +// These SLDC_* functions and constants are special SDL-like things +// used to abstract certain SDL2 vs SDL3 differences. +void* SDLC_Win32_GetHwnd(SDL_Window* window); +void* SDLC_MacOS_GetWindow(SDL_Window* window); +void* SDLC_X11_GetDisplay(SDL_Window* window); +unsigned long SDLC_X11_GetWindow(SDL_Window* window); +void* SDLC_Wayland_GetDisplay(SDL_Window* window); +void* SDLC_Wayland_GetSurface(SDL_Window* window); +int SDLC_KMSDRM_GetFd(SDL_Window* window); +int SDLC_KMSDRM_GetDevIndex(SDL_Window* window); + +typedef enum { + SDLC_VIDEO_UNKNOWN, + SDLC_VIDEO_WIN32, + SDLC_VIDEO_MACOS, + SDLC_VIDEO_X11, + SDLC_VIDEO_WAYLAND, + SDLC_VIDEO_KMSDRM, +} SDLC_VideoDriver; +SDLC_VideoDriver SDLC_GetVideoDriver(); + +bool SDLC_IsFullscreen(SDL_Window* window); +bool SDLC_IsFullscreenExclusive(SDL_Window* window); +bool SDLC_IsFullscreenDesktop(SDL_Window* window); +void SDLC_EnterFullscreen(SDL_Window* window, bool exclusive); +void SDLC_LeaveFullscreen(SDL_Window* window); + +SDL_Window* SDLC_CreateWindowWithFallback(const char *title, + int x, int y, int w, int h, + Uint32 requiredFlags, + Uint32 optionalFlags); + +void SDLC_FlushWindowEvents(); + +#define SDLC_SUCCESS(x) ((x) == 0) +#define SDLC_FAILURE(x) ((x) != 0) + // SDL_FRect wasn't added until 2.0.10 #if !SDL_VERSION_ATLEAST(2, 0, 10) typedef struct SDL_FRect @@ -24,6 +61,10 @@ typedef struct SDL_FRect } SDL_FRect; #endif +#ifndef SDL_THREAD_PRIORITY_TIME_CRITICAL +#define SDL_THREAD_PRIORITY_TIME_CRITICAL SDL_THREAD_PRIORITY_HIGH +#endif + #ifndef SDL_HINT_VIDEO_X11_FORCE_EGL #define SDL_HINT_VIDEO_X11_FORCE_EGL "SDL_VIDEO_X11_FORCE_EGL" #endif @@ -72,39 +113,190 @@ typedef struct SDL_FRect #define SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP "SDL_VIDEO_WAYLAND_EMULATE_MOUSE_WARP" #endif -void* SDLC_Win32_GetHwnd(SDL_Window* window); -void* SDLC_MacOS_GetWindow(SDL_Window* window); -void* SDLC_X11_GetDisplay(SDL_Window* window); -unsigned long SDLC_X11_GetWindow(SDL_Window* window); -void* SDLC_Wayland_GetDisplay(SDL_Window* window); -void* SDLC_Wayland_GetSurface(SDL_Window* window); -int SDLC_KMSDRM_GetFd(SDL_Window* window); -int SDLC_KMSDRM_GetDevIndex(SDL_Window* window); +// SDL3 renamed hints +#define SDL_HINT_VIDEO_FORCE_EGL SDL_HINT_VIDEO_X11_FORCE_EGL -typedef enum { - SDLC_VIDEO_UNKNOWN, - SDLC_VIDEO_WIN32, - SDLC_VIDEO_MACOS, - SDLC_VIDEO_X11, - SDLC_VIDEO_WAYLAND, - SDLC_VIDEO_KMSDRM, -} SDLC_VideoDriver; -SDLC_VideoDriver SDLC_GetVideoDriver(); +// Events +#define SDL_EVENT_QUIT SDL_QUIT +#define SDL_EVENT_CLIPBOARD_UPDATE SDL_CLIPBOARDUPDATE +#define SDL_EVENT_GAMEPAD_ADDED SDL_CONTROLLERDEVICEADDED +#define SDL_EVENT_GAMEPAD_REMAPPED SDL_CONTROLLERDEVICEREMAPPED +#define SDL_EVENT_GAMEPAD_REMOVED SDL_CONTROLLERDEVICEREMOVED +#define SDL_EVENT_GAMEPAD_SENSOR_UPDATE SDL_CONTROLLERSENSORUPDATE +#define SDL_EVENT_GAMEPAD_BUTTON_DOWN SDL_CONTROLLERBUTTONDOWN +#define SDL_EVENT_GAMEPAD_BUTTON_UP SDL_CONTROLLERBUTTONUP +#define SDL_EVENT_GAMEPAD_AXIS_MOTION SDL_CONTROLLERAXISMOTION +#define SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN SDL_CONTROLLERTOUCHPADDOWN +#define SDL_EVENT_GAMEPAD_TOUCHPAD_UP SDL_CONTROLLERTOUCHPADUP +#define SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION SDL_CONTROLLERTOUCHPADMOTION +#define SDL_EVENT_JOYSTICK_ADDED SDL_JOYDEVICEADDED +#define SDL_EVENT_JOYSTICK_REMOVED SDL_JOYDEVICEREMOVED +#define SDL_EVENT_JOYSTICK_BATTERY_UPDATED SDL_JOYBATTERYUPDATED +#define SDL_EVENT_FINGER_DOWN SDL_FINGERDOWN +#define SDL_EVENT_FINGER_MOTION SDL_FINGERMOTION +#define SDL_EVENT_FINGER_UP SDL_FINGERUP +#define SDL_EVENT_KEY_DOWN SDL_KEYDOWN +#define SDL_EVENT_KEY_UP SDL_KEYUP +#define SDL_EVENT_MOUSE_BUTTON_DOWN SDL_MOUSEBUTTONDOWN +#define SDL_EVENT_MOUSE_BUTTON_UP SDL_MOUSEBUTTONUP +#define SDL_EVENT_MOUSE_MOTION SDL_MOUSEMOTION +#define SDL_EVENT_MOUSE_WHEEL SDL_MOUSEWHEEL +#define SDL_EVENT_RENDER_DEVICE_RESET SDL_RENDER_DEVICE_RESET +#define SDL_EVENT_RENDER_TARGETS_RESET SDL_RENDER_TARGETS_RESET +#define SDL_EVENT_USER SDL_USEREVENT -bool SDLC_IsFullscreen(SDL_Window* window); -bool SDLC_IsFullscreenExclusive(SDL_Window* window); -bool SDLC_IsFullscreenDesktop(SDL_Window* window); -void SDLC_EnterFullscreen(SDL_Window* window, bool exclusive); -void SDLC_LeaveFullscreen(SDL_Window* window); +#define SDL_EVENT_WINDOW_FOCUS_GAINED SDL_WINDOWEVENT_FOCUS_GAINED +#define SDL_EVENT_WINDOW_FOCUS_LOST SDL_WINDOWEVENT_FOCUS_LOST +#define SDL_EVENT_WINDOW_MOUSE_ENTER SDL_WINDOWEVENT_ENTER +#define SDL_EVENT_WINDOW_MOUSE_LEAVE SDL_WINDOWEVENT_LEAVE +#define SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED SDL_WINDOWEVENT_SIZE_CHANGED +#define SDL_EVENT_WINDOW_SHOWN SDL_WINDOWEVENT_SHOWN +#define SDL_EVENT_WINDOW_DISPLAY_CHANGED SDL_WINDOWEVENT_DISPLAY_CHANGED -SDL_Window* SDLC_CreateWindowWithFallback(const char *title, - int x, int y, int w, int h, - Uint32 requiredFlags, - Uint32 optionalFlags); +#define SDL_BUTTON_MASK(x) SDL_BUTTON(x) -void SDLC_FlushWindowEvents(); -#define SDLC_SUCCESS(x) ((x) == 0) -#define SDLC_FAILURE(x) ((x) != 0) +#define gbutton cbutton +#define gaxis caxis +#define gdevice cdevice +#define gsensor csensor +#define gtouchpad ctouchpad + +#define fingerID fingerId +#define touchID touchId + +#define KEY_DOWN(x) ((x)->state == SDL_PRESSED) +#define KEY_KEY(x) ((x)->keysym.sym) +#define KEY_MOD(x) ((x)->keysym.mod) +#define KEY_SCANCODE(x) ((x)->keysym.scancode) + +// Gamepad +#define SDL_INIT_GAMEPAD SDL_INIT_GAMECONTROLLER + +#define SDL_GAMEPAD_BUTTON_SOUTH SDL_CONTROLLER_BUTTON_A +#define SDL_GAMEPAD_BUTTON_EAST SDL_CONTROLLER_BUTTON_B +#define SDL_GAMEPAD_BUTTON_WEST SDL_CONTROLLER_BUTTON_X +#define SDL_GAMEPAD_BUTTON_NORTH SDL_CONTROLLER_BUTTON_Y +#define SDL_GAMEPAD_BUTTON_LEFT_SHOULDER SDL_CONTROLLER_BUTTON_LEFTSHOULDER +#define SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER SDL_CONTROLLER_BUTTON_RIGHTSHOULDER +#define SDL_GAMEPAD_BUTTON_DPAD_UP SDL_CONTROLLER_BUTTON_DPAD_UP +#define SDL_GAMEPAD_BUTTON_DPAD_DOWN SDL_CONTROLLER_BUTTON_DPAD_DOWN +#define SDL_GAMEPAD_BUTTON_DPAD_LEFT SDL_CONTROLLER_BUTTON_DPAD_LEFT +#define SDL_GAMEPAD_BUTTON_DPAD_RIGHT SDL_CONTROLLER_BUTTON_DPAD_RIGHT +#define SDL_GAMEPAD_BUTTON_START SDL_CONTROLLER_BUTTON_START +#define SDL_GAMEPAD_BUTTON_TOUCHPAD SDL_CONTROLLER_BUTTON_TOUCHPAD + +#define SDL_GAMEPAD_BINDTYPE_AXIS SDL_CONTROLLER_BINDTYPE_AXIS +#define SDL_GAMEPAD_BINDTYPE_BUTTON SDL_CONTROLLER_BINDTYPE_BUTTON +#define SDL_GAMEPAD_BINDTYPE_HAT SDL_CONTROLLER_BINDTYPE_HAT +#define SDL_GAMEPAD_BINDTYPE_NONE SDL_CONTROLLER_BINDTYPE_NONE + +#define SDL_GAMEPAD_AXIS_LEFTX SDL_CONTROLLER_AXIS_LEFTX +#define SDL_GAMEPAD_AXIS_LEFTY SDL_CONTROLLER_AXIS_LEFTY +#define SDL_GAMEPAD_AXIS_RIGHTX SDL_CONTROLLER_AXIS_RIGHTX +#define SDL_GAMEPAD_AXIS_RIGHTY SDL_CONTROLLER_AXIS_RIGHTY +#define SDL_GAMEPAD_AXIS_LEFT_TRIGGER SDL_CONTROLLER_AXIS_TRIGGERLEFT +#define SDL_GAMEPAD_AXIS_RIGHT_TRIGGER SDL_CONTROLLER_AXIS_TRIGGERRIGHT + +// SDL_OpenGamepad() not defined due to differing semantics +SDL_JoystickID* SDL_GetGamepads(int *count); +#define SDL_OpenGamepad(x) SDL_GameControllerOpen(x) +#define SDL_CloseGamepad(x) SDL_GameControllerClose(x) +#define SDL_GetGamepadMapping(x) SDL_GameControllerMapping(x) +#define SDL_GetGamepadName(x) SDL_GameControllerName(x) +#define SDL_GetGamepadVendor(x) SDL_GameControllerGetVendor(x) +#define SDL_GetGamepadProduct(x) SDL_GameControllerGetProduct(x) +#define SDL_GetGamepadJoystick(x) SDL_GameControllerGetJoystick(x) +#define SDL_GamepadHasButton(x, y) SDL_GameControllerHasButton(x, y) +#define SDL_GamepadHasSensor(x, y) SDL_GameControllerHasSensor(x, y) +#define SDL_SetGamepadPlayerIndex(x, y) SDL_GameControllerSetPlayerIndex(x, y) +#define SDL_GamepadSensorEnabled(x, y) SDL_GameControllerIsSensorEnabled(x, y) +#define SDL_SetGamepadSensorEnabled(x, y, z) SDL_GameControllerSetSensorEnabled(x, y, z) +#define SDL_GetNumGamepadTouchpads(x) SDL_GameControllerGetNumTouchpads(x) +#define SDL_SetGamepadLED(x, r, g, b) SDL_GameControllerSetLED(x, r, g, b) +#define SDL_RumbleGamepad(x, y, z, w) SDL_GameControllerRumble(x, y, z, w) +#define SDL_RumbleGamepadTriggers(x, y, z, w) SDL_GameControllerRumbleTriggers(x, y, z, w) +#define SDL_GetGamepadAxis(x, y) SDL_GameControllerGetAxis(x, y) +#define SDL_GetGamepadType(x) SDL_GameControllerGetType(x) +#define SDL_IsGamepad(x) SDL_IsGameController(x) + +#define SDL_GAMEPAD_TYPE_STANDARD SDL_CONTROLLER_TYPE_UNKNOWN +#define SDL_GAMEPAD_TYPE_VIRTUAL SDL_CONTROLLER_TYPE_VIRTUAL +#define SDL_GAMEPAD_TYPE_XBOX360 SDL_CONTROLLER_TYPE_XBOX360 +#define SDL_GAMEPAD_TYPE_XBOXONE SDL_CONTROLLER_TYPE_XBOXONE +#define SDL_GAMEPAD_TYPE_PS3 SDL_CONTROLLER_TYPE_PS3 +#define SDL_GAMEPAD_TYPE_PS4 SDL_CONTROLLER_TYPE_PS4 +#define SDL_GAMEPAD_TYPE_PS5 SDL_CONTROLLER_TYPE_PS5 +#define SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT +#define SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR +#define SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT +#define SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO + +// SDL_OpenGamepad() not defined due to differing semantics +SDL_JoystickID* SDL_GetJoysticks(int *count); +#define SDL_OpenJoystick(x) SDL_JoystickOpen(x) +#define SDL_CloseJoystick(x) SDL_JoystickClose(x) +#define SDL_GetJoystickID(x) SDL_JoystickInstanceID(x) +#define SDL_GetJoystickGUID(x) SDL_JoystickGetGUID(x) +#define SDL_GetJoystickPowerLevel(x) SDL_JoystickCurrentPowerLevel(x) +#define SDL_GetNumJoystickAxes(x) SDL_JoystickNumAxes(x) +#define SDL_GetNumJoystickBalls(x) SDL_JoystickNumBalls(x) +#define SDL_GetNumJoystickButtons(x) SDL_JoystickNumButtons(x) +#define SDL_GetNumJoystickHats(x) SDL_JoystickNumHats(x) +#define SDL_GetJoystickGUIDForID(x) SDL_JoystickGetDeviceGUID(x) + +typedef SDL_ControllerAxisEvent SDL_GamepadAxisEvent; +typedef SDL_ControllerButtonEvent SDL_GamepadButtonEvent; +typedef SDL_ControllerSensorEvent SDL_GamepadSensorEvent; +typedef SDL_ControllerTouchpadEvent SDL_GamepadTouchpadEvent; +typedef SDL_ControllerDeviceEvent SDL_GamepadDeviceEvent; +typedef SDL_GameController SDL_Gamepad; +typedef SDL_GameControllerButton SDL_GamepadButton; + +// Audio +#define SDL_AUDIO_F32 AUDIO_F32SYS + +#define SDL_ResumeAudioDevice(x) SDL_PauseAudioDevice(x, 0) + +// Atomics +#define SDL_GetAtomicInt(x) SDL_AtomicGet(x) +#define SDL_SetAtomicInt(x, y) SDL_AtomicSet(x, y) +#define SDL_GetAtomicPointer(x) SDL_AtomicGetPtr(x) +#define SDL_SetAtomicPointer(x, y) SDL_AtomicSetPtr(x, y) + +#define SDL_LockSpinlock(x) SDL_AtomicLock(x) +#define SDL_TryLockSpinlock(x) SDL_AtomicTryLock(x) +#define SDL_UnlockSpinlock(x) SDL_AtomicUnlock(x) + +typedef SDL_atomic_t SDL_AtomicInt; + +// Video +#define SDL_KMOD_CTRL KMOD_CTRL +#define SDL_KMOD_ALT KMOD_ALT +#define SDL_KMOD_SHIFT KMOD_SHIFT +#define SDL_KMOD_GUI KMOD_GUI + +#define SDL_WINDOW_HIGH_PIXEL_DENSITY SDL_WINDOW_ALLOW_HIGHDPI + +#define SDL_SetWindowFullscreenMode(x, y) SDL_SetWindowDisplayMode(x, y) +#define SDL_GetDisplayForWindow(x) SDL_GetWindowDisplayIndex(x) +#define SDL_GetRenderViewport(x, y) SDL_RenderGetViewport(x, y) +#define SDL_DestroySurface(x) SDL_FreeSurface(x) +#define SDL_RenderTexture(x, y, z, w) SDL_RenderCopy(x, y, z, w) +#define SDL_GetPrimaryDisplay() (0) + +#define SDL_CreateSurfaceFrom(w, h, fmt, pixels, pitch) SDL_CreateRGBSurfaceWithFormatFrom(pixels, w, h, SDL_BITSPERPIXEL(fmt), pitch, fmt) + +#define SDLC_DEFAULT_RENDER_DRIVER -1 + +typedef int SDL_DisplayID; +SDL_DisplayID * SDL_GetDisplays(int *count); +const SDL_DisplayMode * SDL_GetWindowFullscreenMode(SDL_Window *window); + +// Misc +#define SDL_GetNumLogicalCPUCores() SDL_GetCPUCount() +#define SDL_IOFromConstMem(x, y) SDL_RWFromConstMem(x, y) +#define SDL_SetCurrentThreadPriority(x) SDL_SetThreadPriority(x) +#define SDL_GUIDToString(x, y, z) SDL_JoystickGetGUIDString(x, y, z) #ifdef __cplusplus } diff --git a/app/backend/systemproperties.cpp b/app/backend/systemproperties.cpp index e4877957..eb5d69fa 100644 --- a/app/backend/systemproperties.cpp +++ b/app/backend/systemproperties.cpp @@ -197,15 +197,18 @@ void SystemProperties::refreshDisplaysInternal() monitorNativeResolutions.clear(); + int numDisplays = 0; + SDL_DisplayID *displays = SDL_GetDisplays(&numDisplays); + SDL_DisplayMode bestMode; - for (int displayIndex = 0; displayIndex < SDL_GetNumVideoDisplays(); displayIndex++) { + for (int i = 0; i < numDisplays; i++) { SDL_DisplayMode desktopMode; SDL_Rect safeArea; - if (StreamUtils::getNativeDesktopMode(displayIndex, &desktopMode, &safeArea)) { + if (StreamUtils::getNativeDesktopMode(displays[i], &desktopMode, &safeArea)) { if (desktopMode.w <= 8192 && desktopMode.h <= 8192) { - monitorNativeResolutions.insert(displayIndex, QRect(0, 0, desktopMode.w, desktopMode.h)); - monitorSafeAreaResolutions.insert(displayIndex, QRect(0, 0, safeArea.w, safeArea.h)); + monitorNativeResolutions.insert(i, QRect(0, 0, desktopMode.w, desktopMode.h)); + monitorSafeAreaResolutions.insert(i, QRect(0, 0, safeArea.w, safeArea.h)); } else { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, @@ -215,9 +218,10 @@ void SystemProperties::refreshDisplaysInternal() // Start at desktop mode and work our way up bestMode = desktopMode; - for (int i = 0; i < SDL_GetNumDisplayModes(displayIndex); i++) { + int numDisplayModes = SDL_GetNumDisplayModes(displays[i]); + for (int i = 0; i < numDisplayModes; i++) { SDL_DisplayMode mode; - if (SDL_GetDisplayMode(displayIndex, i, &mode) == 0) { + if (SDL_GetDisplayMode(displays[i], i, &mode) == 0) { if (mode.w == desktopMode.w && mode.h == desktopMode.h) { if (mode.refresh_rate > bestMode.refresh_rate) { bestMode = mode; @@ -240,5 +244,6 @@ void SystemProperties::refreshDisplaysInternal() } } + SDL_free(displays); SDL_QuitSubSystem(SDL_INIT_VIDEO); } diff --git a/app/gui/sdlgamepadkeynavigation.cpp b/app/gui/sdlgamepadkeynavigation.cpp index d95e4caa..769c4899 100644 --- a/app/gui/sdlgamepadkeynavigation.cpp +++ b/app/gui/sdlgamepadkeynavigation.cpp @@ -37,7 +37,7 @@ void SdlGamepadKeyNavigation::enable() // arrival events. Additionally, there's a race condition between // our QML objects being destroyed and SDL being deinitialized that // this solves too. - if (SDLC_FAILURE(SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER))) { + if (SDLC_FAILURE(SDL_InitSubSystem(SDL_INIT_GAMEPAD))) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) failed: %s", SDL_GetError()); @@ -52,18 +52,18 @@ void SdlGamepadKeyNavigation::enable() // overlapping lifetimes of SdlGamepadKeyNavigation instances, so we // will attach ourselves. SDL_PumpEvents(); - SDL_FlushEvent(SDL_CONTROLLERDEVICEADDED); + SDL_FlushEvent(SDL_EVENT_GAMEPAD_ADDED); // Open all currently attached game controllers - int numJoysticks = SDL_NumJoysticks(); - for (int i = 0; i < numJoysticks; i++) { - if (SDL_IsGameController(i)) { - SDL_GameController* gc = SDL_GameControllerOpen(i); - if (gc != nullptr) { - m_Gamepads.append(gc); - } + int numGamepads = 0; + SDL_JoystickID* gamepads = SDL_GetGamepads(&numGamepads); + for (int i = 0; i < numGamepads; i++) { + SDL_Gamepad * gc = SDL_OpenGamepad(i); + if (gc != nullptr) { + m_Gamepads.append(gc); } } + SDL_free(gamepads); m_Enabled = true; @@ -82,11 +82,11 @@ void SdlGamepadKeyNavigation::disable() Q_ASSERT(!m_PollingTimer->isActive()); while (!m_Gamepads.isEmpty()) { - SDL_GameControllerClose(m_Gamepads[0]); + SDL_CloseGamepad(m_Gamepads[0]); m_Gamepads.removeAt(0); } - SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); + SDL_QuitSubSystem(SDL_INIT_GAMEPAD); } void SdlGamepadKeyNavigation::notifyWindowFocus(bool hasFocus) @@ -103,47 +103,47 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() // stale input data from the stream session (like the quit combo). if (m_FirstPoll) { SDL_PumpEvents(); - SDL_FlushEvent(SDL_CONTROLLERBUTTONDOWN); - SDL_FlushEvent(SDL_CONTROLLERBUTTONUP); + SDL_FlushEvent(SDL_EVENT_GAMEPAD_BUTTON_DOWN); + SDL_FlushEvent(SDL_EVENT_GAMEPAD_BUTTON_UP); m_FirstPoll = false; } while (SDL_PollEvent(&event)) { switch (event.type) { - case SDL_QUIT: + case SDL_EVENT_QUIT : // SDL may send us a quit event since we initialize // the video subsystem on startup. If we get one, // forward it on for Qt to take care of. QCoreApplication::instance()->quit(); break; - case SDL_CONTROLLERBUTTONDOWN: - case SDL_CONTROLLERBUTTONUP: + case SDL_EVENT_GAMEPAD_BUTTON_DOWN : + case SDL_EVENT_GAMEPAD_BUTTON_UP : { QEvent::Type type = - event.type == SDL_CONTROLLERBUTTONDOWN ? + event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN ? QEvent::Type::KeyPress : QEvent::Type::KeyRelease; // Swap face buttons if needed if (m_Prefs->swapFaceButtons) { - switch (event.cbutton.button) { - case SDL_CONTROLLER_BUTTON_A: - event.cbutton.button = SDL_CONTROLLER_BUTTON_B; + switch (event.gbutton.button) { + case SDL_GAMEPAD_BUTTON_SOUTH : + event.gbutton.button = SDL_GAMEPAD_BUTTON_EAST; break; - case SDL_CONTROLLER_BUTTON_B: - event.cbutton.button = SDL_CONTROLLER_BUTTON_A; + case SDL_GAMEPAD_BUTTON_EAST : + event.gbutton.button = SDL_GAMEPAD_BUTTON_SOUTH; break; - case SDL_CONTROLLER_BUTTON_X: - event.cbutton.button = SDL_CONTROLLER_BUTTON_Y; + case SDL_GAMEPAD_BUTTON_WEST : + event.gbutton.button = SDL_GAMEPAD_BUTTON_NORTH; break; - case SDL_CONTROLLER_BUTTON_Y: - event.cbutton.button = SDL_CONTROLLER_BUTTON_X; + case SDL_GAMEPAD_BUTTON_NORTH : + event.gbutton.button = SDL_GAMEPAD_BUTTON_WEST; break; } } - switch (event.cbutton.button) { - case SDL_CONTROLLER_BUTTON_DPAD_UP: + switch (event.gbutton.button) { + case SDL_GAMEPAD_BUTTON_DPAD_UP : if (m_UiNavMode) { // Back-tab sendKey(type, Qt::Key_Tab, Qt::ShiftModifier); @@ -152,7 +152,7 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() sendKey(type, Qt::Key_Up); } break; - case SDL_CONTROLLER_BUTTON_DPAD_DOWN: + case SDL_GAMEPAD_BUTTON_DPAD_DOWN : if (m_UiNavMode) { sendKey(type, Qt::Key_Tab); } @@ -160,13 +160,13 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() sendKey(type, Qt::Key_Down); } break; - case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + case SDL_GAMEPAD_BUTTON_DPAD_LEFT : sendKey(type, Qt::Key_Left); break; - case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + case SDL_GAMEPAD_BUTTON_DPAD_RIGHT : sendKey(type, Qt::Key_Right); break; - case SDL_CONTROLLER_BUTTON_A: + case SDL_GAMEPAD_BUTTON_SOUTH : if (m_UiNavMode) { sendKey(type, Qt::Key_Space); } @@ -174,14 +174,14 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() sendKey(type, Qt::Key_Return); } break; - case SDL_CONTROLLER_BUTTON_B: + case SDL_GAMEPAD_BUTTON_EAST : sendKey(type, Qt::Key_Escape); break; - case SDL_CONTROLLER_BUTTON_X: + case SDL_GAMEPAD_BUTTON_WEST : sendKey(type, Qt::Key_Menu); break; - case SDL_CONTROLLER_BUTTON_Y: - case SDL_CONTROLLER_BUTTON_START: + case SDL_GAMEPAD_BUTTON_NORTH : + case SDL_GAMEPAD_BUTTON_START : // HACK: We use this keycode to inform main.qml // to show the settings when Key_Menu is handled // by the control in focus. @@ -192,11 +192,18 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() } break; } - case SDL_CONTROLLERDEVICEADDED: - SDL_GameController* gc = SDL_GameControllerOpen(event.cdevice.which); + case SDL_EVENT_GAMEPAD_ADDED : +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_Gamepad* gc = SDL_OpenGamepad(event.gdevice.which); + if (gc != nullptr) { + SDL_assert(!m_Gamepads.contains(gc)); + m_Gamepads.append(gc); + } +#else + SDL_Gamepad* gc = SDL_GameControllerOpen(event.cdevice.which); if (gc != nullptr) { // SDL_CONTROLLERDEVICEADDED can be reported multiple times for the same - // gamepad in rare cases, because SDL doesn't fixup the device index in + // gamepad in rare cases, because SDL2 doesn't fixup the device index in // the SDL_CONTROLLERDEVICEADDED event if an unopened gamepad disappears // before we've processed the add event. if (!m_Gamepads.contains(gc)) { @@ -204,17 +211,18 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() } else { // We already have this game controller open - SDL_GameControllerClose(gc); + SDL_CloseGamepad(gc); } } +#endif break; } } // Handle analog sticks by polling for (auto gc : m_Gamepads) { - short leftX = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_LEFTX); - short leftY = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_LEFTY); + short leftX = SDL_GetGamepadAxis(gc, SDL_GAMEPAD_AXIS_LEFTX); + short leftY = SDL_GetGamepadAxis(gc, SDL_GAMEPAD_AXIS_LEFTY); if (SDL_GetTicks() - m_LastAxisNavigationEventTime < AXIS_NAVIGATION_REPEAT_DELAY) { // Do nothing } @@ -290,12 +298,6 @@ int SdlGamepadKeyNavigation::getConnectedGamepads() Q_ASSERT(m_Enabled); int count = 0; - int numJoysticks = SDL_NumJoysticks(); - for (int i = 0; i < numJoysticks; i++) { - if (SDL_IsGameController(i)) { - count++; - } - } - + SDL_free(SDL_GetGamepads(&count)); return count; } diff --git a/app/gui/sdlgamepadkeynavigation.h b/app/gui/sdlgamepadkeynavigation.h index 3d2feecd..13b57843 100644 --- a/app/gui/sdlgamepadkeynavigation.h +++ b/app/gui/sdlgamepadkeynavigation.h @@ -37,7 +37,7 @@ private slots: private: StreamingPreferences* m_Prefs; QTimer* m_PollingTimer; - QList m_Gamepads; + QList m_Gamepads; bool m_Enabled; bool m_UiNavMode; bool m_FirstPoll; diff --git a/app/masterhook.c b/app/masterhook.c index 6b17380f..b518a7d2 100644 --- a/app/masterhook.c +++ b/app/masterhook.c @@ -16,6 +16,7 @@ // See masterhook_internal.c for details. #include "SDL_compat.h" +#include #include #include #include diff --git a/app/masterhook_internal.c b/app/masterhook_internal.c index 1c516f94..fc9c7d0b 100644 --- a/app/masterhook_internal.c +++ b/app/masterhook_internal.c @@ -55,7 +55,7 @@ int getSdlFdEntryIndex(bool unused) // Returns true if the final SDL FD was removed bool removeSdlFd(int fd) { - SDL_AtomicLock(&g_FdTableLock); + SDL_LockSpinlock(&g_FdTableLock); if (g_SdlDrmMasterFdCount != 0) { // Clear the entry for this fd from the table for (int i = 0; i < MAX_SDL_FD_COUNT; i++) { @@ -67,11 +67,11 @@ bool removeSdlFd(int fd) } if (g_SdlDrmMasterFdCount == 0) { - SDL_AtomicUnlock(&g_FdTableLock); + SDL_UnlockSpinlock(&g_FdTableLock); return true; } } - SDL_AtomicUnlock(&g_FdTableLock); + SDL_UnlockSpinlock(&g_FdTableLock); return false; } @@ -82,12 +82,12 @@ int takeMasterFromSdlFd() // Since all SDL FDs are actually dups of each other // we can take master from any one of them. - SDL_AtomicLock(&g_FdTableLock); + SDL_LockSpinlock(&g_FdTableLock); int fdIndex = getSdlFdEntryIndex(false); if (fdIndex != -1) { fd = g_SdlDrmMasterFds[fdIndex]; } - SDL_AtomicUnlock(&g_FdTableLock); + SDL_UnlockSpinlock(&g_FdTableLock); if (fd >= 0 && drmDropMaster(fd) == 0) { return fd; @@ -126,12 +126,12 @@ int openHook(const char *funcname, const char *pathname, int flags, va_list va) int allocatedFdIndex; // It is our device. Time to do the magic! - SDL_AtomicLock(&g_FdTableLock); + SDL_LockSpinlock(&g_FdTableLock); // Get a free index for us to put the new entry freeFdIndex = getSdlFdEntryIndex(true); if (freeFdIndex < 0) { - SDL_AtomicUnlock(&g_FdTableLock); + SDL_UnlockSpinlock(&g_FdTableLock); SDL_assert(freeFdIndex >= 0); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No unused SDL FD table entries!"); @@ -151,7 +151,7 @@ int openHook(const char *funcname, const char *pathname, int flags, va_list va) else { // Drop master on Qt's FD so we can pick it up for SDL. if (drmDropMaster(g_QtDrmMasterFd) < 0) { - SDL_AtomicUnlock(&g_FdTableLock); + SDL_UnlockSpinlock(&g_FdTableLock); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to drop master on Qt DRM FD: %d", errno); @@ -182,7 +182,7 @@ int openHook(const char *funcname, const char *pathname, int flags, va_list va) g_SdlDrmMasterFdCount++; } - SDL_AtomicUnlock(&g_FdTableLock); + SDL_UnlockSpinlock(&g_FdTableLock); } } } diff --git a/app/streaming/audio/audio.cpp b/app/streaming/audio/audio.cpp index cb60d6db..f02dae82 100644 --- a/app/streaming/audio/audio.cpp +++ b/app/streaming/audio/audio.cpp @@ -174,7 +174,7 @@ void Session::arDecodeAndPlaySample(char* sampleData, int sampleLength) // of other threads due to severely restricted CPU time available, // so we will skip it on that platform. if (s_ActiveSession->m_AudioSampleCount == 0) { - if (SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH) < 0) { + if (SDLC_FAILURE(SDL_SetCurrentThreadPriority(SDL_THREAD_PRIORITY_HIGH))) { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Unable to set audio thread to high priority: %s", SDL_GetError()); diff --git a/app/streaming/audio/renderers/sdlaud.cpp b/app/streaming/audio/renderers/sdlaud.cpp index 21e5db0c..0a6732b6 100644 --- a/app/streaming/audio/renderers/sdlaud.cpp +++ b/app/streaming/audio/renderers/sdlaud.cpp @@ -22,7 +22,7 @@ bool SdlAudioRenderer::prepareForPlayback(const OPUS_MULTISTREAM_CONFIGURATION* SDL_zero(want); want.freq = opusConfig->sampleRate; - want.format = AUDIO_F32SYS; + want.format = SDL_AUDIO_F32; want.channels = opusConfig->channelCount; // On PulseAudio systems, setting a value too small can cause underruns for other @@ -73,7 +73,7 @@ bool SdlAudioRenderer::prepareForPlayback(const OPUS_MULTISTREAM_CONFIGURATION* SDL_GetCurrentAudioDriver()); // Start playback - SDL_PauseAudioDevice(m_AudioDevice, 0); + SDL_ResumeAudioDevice(m_AudioDevice); return true; } diff --git a/app/streaming/input/abstouch.cpp b/app/streaming/input/abstouch.cpp index bd80acb3..3f1fcc8d 100644 --- a/app/streaming/input/abstouch.cpp +++ b/app/streaming/input/abstouch.cpp @@ -82,13 +82,13 @@ void SdlInputHandler::handleAbsoluteFingerEvent(SDL_TouchFingerEvent* event) uint8_t eventType; switch (event->type) { - case SDL_FINGERDOWN: + case SDL_EVENT_FINGER_DOWN : eventType = LI_TOUCH_EVENT_DOWN; break; - case SDL_FINGERMOTION: + case SDL_EVENT_FINGER_MOTION : eventType = LI_TOUCH_EVENT_MOVE; break; - case SDL_FINGERUP: + case SDL_EVENT_FINGER_UP : eventType = LI_TOUCH_EVENT_UP; break; default: @@ -98,16 +98,16 @@ void SdlInputHandler::handleAbsoluteFingerEvent(SDL_TouchFingerEvent* event) uint32_t pointerId; // If the pointer ID is larger than we can fit, just CRC it and use that as the ID. - if ((uint64_t)event->fingerId > UINT32_MAX) { + if ((uint64_t) event->fingerID > UINT32_MAX) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - QByteArrayView bav((char*)&event->fingerId, sizeof(event->fingerId)); + QByteArrayView bav((char*)&event->fingerID, sizeof(event->fingerID)); pointerId = qChecksum(bav); #else - pointerId = qChecksum((char*)&event->fingerId, sizeof(event->fingerId)); + pointerId = qChecksum((char*)&event->fingerID, sizeof(event->fingerID)); #endif } else { - pointerId = (uint32_t)event->fingerId; + pointerId = (uint32_t) event->fingerID; } // Try to send it as a native pen/touch event, otherwise fall back to our touch emulation @@ -117,7 +117,7 @@ void SdlInputHandler::handleAbsoluteFingerEvent(SDL_TouchFingerEvent* event) int numTouchDevices = SDL_GetNumTouchDevices(); for (int i = 0; i < numTouchDevices; i++) { - if (event->touchId == SDL_GetTouchDevice(i)) { + if (event->touchID == SDL_GetTouchDevice(i)) { const char* touchName = SDL_GetTouchName(i); // SDL will report "pen" as the name of pen input devices on Windows. @@ -158,12 +158,12 @@ void SdlInputHandler::emulateAbsoluteFingerEvent(SDL_TouchFingerEvent* event) // dx and dy are deltas from the last touch event, not the first touch down. // Ignore touch down events with more than one finger - if (event->type == SDL_FINGERDOWN && SDL_GetNumTouchFingers(event->touchId) > 1) { + if (event->type == SDL_EVENT_FINGER_DOWN && SDL_GetNumTouchFingers(event->touchID) > 1) { return; } // Ignore touch move and touch up events from the non-primary finger - if (event->type != SDL_FINGERDOWN && event->fingerId != m_LastTouchDownEvent.fingerId) { + if (event->type != SDL_EVENT_FINGER_DOWN && event->fingerID != m_LastTouchDownEvent.fingerID) { return; } @@ -190,7 +190,7 @@ void SdlInputHandler::emulateAbsoluteFingerEvent(SDL_TouchFingerEvent* event) } // Don't reposition for finger down events within the deadzone. This makes double-clicking easier. - if (event->type != SDL_FINGERDOWN || + if (event->type != SDL_EVENT_FINGER_DOWN || event->timestamp - m_LastTouchUpEvent.timestamp > DOUBLE_TAP_DEAD_ZONE_DELAY || qSqrt(qPow(event->x - m_LastTouchUpEvent.x, 2) + qPow(event->y - m_LastTouchUpEvent.y, 2)) > DOUBLE_TAP_DEAD_ZONE_DELTA) { // Scale window-relative events to be video-relative and clamp to video region @@ -201,7 +201,7 @@ void SdlInputHandler::emulateAbsoluteFingerEvent(SDL_TouchFingerEvent* event) LiSendMousePositionEvent(x - dst.x, y - dst.y, dst.w, dst.h); } - if (event->type == SDL_FINGERDOWN) { + if (event->type == SDL_EVENT_FINGER_DOWN) { m_LastTouchDownEvent = *event; // Start/restart the long press timer @@ -213,7 +213,7 @@ void SdlInputHandler::emulateAbsoluteFingerEvent(SDL_TouchFingerEvent* event) // Left button down on finger down LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT); } - else if (event->type == SDL_FINGERUP) { + else if (event->type == SDL_EVENT_FINGER_UP) { m_LastTouchUpEvent = *event; // Cancel the long press timer diff --git a/app/streaming/input/gamepad.cpp b/app/streaming/input/gamepad.cpp index 5aca28d5..0c2225ed 100644 --- a/app/streaming/input/gamepad.cpp +++ b/app/streaming/input/gamepad.cpp @@ -188,7 +188,7 @@ Uint32 SdlInputHandler::mouseEmulationTimerCallback(Uint32 interval, void *param return interval; } -void SdlInputHandler::handleControllerAxisEvent(SDL_ControllerAxisEvent* event) +void SdlInputHandler::handleControllerAxisEvent(SDL_GamepadAxisEvent * event) { SDL_JoystickID gameControllerId = event->which; GamepadState* state = findStateForGamepad(gameControllerId); @@ -201,10 +201,10 @@ void SdlInputHandler::handleControllerAxisEvent(SDL_ControllerAxisEvent* event) for (;;) { switch (event->axis) { - case SDL_CONTROLLER_AXIS_LEFTX: + case SDL_GAMEPAD_AXIS_LEFTX : state->lsX = event->value; break; - case SDL_CONTROLLER_AXIS_LEFTY: + case SDL_GAMEPAD_AXIS_LEFTY : // Signed values have one more negative value than // positive value, so inverting the sign on -32768 // could actually cause the value to overflow and @@ -212,16 +212,16 @@ void SdlInputHandler::handleControllerAxisEvent(SDL_ControllerAxisEvent* event) // capping the value at 32767. state->lsY = -qMax(event->value, (short)-32767); break; - case SDL_CONTROLLER_AXIS_RIGHTX: + case SDL_GAMEPAD_AXIS_RIGHTX : state->rsX = event->value; break; - case SDL_CONTROLLER_AXIS_RIGHTY: + case SDL_GAMEPAD_AXIS_RIGHTY : state->rsY = -qMax(event->value, (short)-32767); break; - case SDL_CONTROLLER_AXIS_TRIGGERLEFT: + case SDL_GAMEPAD_AXIS_LEFT_TRIGGER : state->lt = (unsigned char)(event->value * 255UL / 32767); break; - case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: + case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER : state->rt = (unsigned char)(event->value * 255UL / 32767); break; default: @@ -232,18 +232,18 @@ void SdlInputHandler::handleControllerAxisEvent(SDL_ControllerAxisEvent* event) } // Check for another event to batch with - if (SDL_PeepEvents(&nextEvent, 1, SDL_PEEKEVENT, SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERAXISMOTION) <= 0) { + if (SDL_PeepEvents(&nextEvent, 1, SDL_PEEKEVENT, SDL_EVENT_GAMEPAD_AXIS_MOTION, SDL_EVENT_GAMEPAD_AXIS_MOTION) <= 0) { break; } - event = &nextEvent.caxis; + event = &nextEvent.gaxis; if (event->which != gameControllerId) { // Stop batching if a different gamepad interrupts us break; } // Remove the next event to batch - SDL_PeepEvents(&nextEvent, 1, SDL_GETEVENT, SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERAXISMOTION); + SDL_PeepEvents(&nextEvent, 1, SDL_GETEVENT, SDL_EVENT_GAMEPAD_AXIS_MOTION, SDL_EVENT_GAMEPAD_AXIS_MOTION); } // Only send the gamepad state to the host if it's not in mouse emulation mode @@ -252,7 +252,7 @@ void SdlInputHandler::handleControllerAxisEvent(SDL_ControllerAxisEvent* event) } } -void SdlInputHandler::handleControllerButtonEvent(SDL_ControllerButtonEvent* event) +void SdlInputHandler::handleControllerButtonEvent(SDL_GamepadButtonEvent * event) { if (event->button >= SDL_arraysize(k_ButtonMap)) { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, @@ -268,53 +268,53 @@ void SdlInputHandler::handleControllerButtonEvent(SDL_ControllerButtonEvent* eve if (m_SwapFaceButtons) { switch (event->button) { - case SDL_CONTROLLER_BUTTON_A: - event->button = SDL_CONTROLLER_BUTTON_B; + case SDL_GAMEPAD_BUTTON_SOUTH : + event->button = SDL_GAMEPAD_BUTTON_EAST; break; - case SDL_CONTROLLER_BUTTON_B: - event->button = SDL_CONTROLLER_BUTTON_A; + case SDL_GAMEPAD_BUTTON_EAST : + event->button = SDL_GAMEPAD_BUTTON_SOUTH; break; - case SDL_CONTROLLER_BUTTON_X: - event->button = SDL_CONTROLLER_BUTTON_Y; + case SDL_GAMEPAD_BUTTON_WEST : + event->button = SDL_GAMEPAD_BUTTON_NORTH; break; - case SDL_CONTROLLER_BUTTON_Y: - event->button = SDL_CONTROLLER_BUTTON_X; + case SDL_GAMEPAD_BUTTON_NORTH : + event->button = SDL_GAMEPAD_BUTTON_WEST; break; } } - if (event->state == SDL_PRESSED) { + if (event->state == true) { state->buttons |= k_ButtonMap[event->button]; - if (event->button == SDL_CONTROLLER_BUTTON_START) { + if (event->button == SDL_GAMEPAD_BUTTON_START) { state->lastStartDownTime = SDL_GetTicks(); } else if (state->mouseEmulationTimer != 0) { - if (event->button == SDL_CONTROLLER_BUTTON_A) { + if (event->button == SDL_GAMEPAD_BUTTON_SOUTH) { LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT); } - else if (event->button == SDL_CONTROLLER_BUTTON_B) { + else if (event->button == SDL_GAMEPAD_BUTTON_EAST) { LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT); } - else if (event->button == SDL_CONTROLLER_BUTTON_X) { + else if (event->button == SDL_GAMEPAD_BUTTON_WEST) { LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_MIDDLE); } - else if (event->button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER) { + else if (event->button == SDL_GAMEPAD_BUTTON_LEFT_SHOULDER) { LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_X1); } - else if (event->button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER) { + else if (event->button == SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER) { LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_X2); } - else if (event->button == SDL_CONTROLLER_BUTTON_DPAD_UP) { + else if (event->button == SDL_GAMEPAD_BUTTON_DPAD_UP) { LiSendScrollEvent(1); } - else if (event->button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) { + else if (event->button == SDL_GAMEPAD_BUTTON_DPAD_DOWN) { LiSendScrollEvent(-1); } - else if (event->button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT) { + else if (event->button == SDL_GAMEPAD_BUTTON_DPAD_RIGHT) { LiSendHScrollEvent(1); } - else if (event->button == SDL_CONTROLLER_BUTTON_DPAD_LEFT) { + else if (event->button == SDL_GAMEPAD_BUTTON_DPAD_LEFT) { LiSendHScrollEvent(-1); } } @@ -322,7 +322,7 @@ void SdlInputHandler::handleControllerButtonEvent(SDL_ControllerButtonEvent* eve else { state->buttons &= ~k_ButtonMap[event->button]; - if (event->button == SDL_CONTROLLER_BUTTON_START) { + if (event->button == SDL_GAMEPAD_BUTTON_START) { if (SDL_GetTicks() - state->lastStartDownTime > MOUSE_EMULATION_LONG_PRESS_TIME) { if (state->mouseEmulationTimer != 0) { SDL_RemoveTimer(state->mouseEmulationTimer); @@ -345,19 +345,19 @@ void SdlInputHandler::handleControllerButtonEvent(SDL_ControllerButtonEvent* eve } } else if (state->mouseEmulationTimer != 0) { - if (event->button == SDL_CONTROLLER_BUTTON_A) { + if (event->button == SDL_GAMEPAD_BUTTON_SOUTH) { LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT); } - else if (event->button == SDL_CONTROLLER_BUTTON_B) { + else if (event->button == SDL_GAMEPAD_BUTTON_EAST) { LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT); } - else if (event->button == SDL_CONTROLLER_BUTTON_X) { + else if (event->button == SDL_GAMEPAD_BUTTON_WEST) { LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_MIDDLE); } - else if (event->button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER) { + else if (event->button == SDL_GAMEPAD_BUTTON_LEFT_SHOULDER) { LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_X1); } - else if (event->button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER) { + else if (event->button == SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER) { LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_X2); } } @@ -370,7 +370,7 @@ void SdlInputHandler::handleControllerButtonEvent(SDL_ControllerButtonEvent* eve // Push a quit event to the main loop SDL_Event event; - event.type = SDL_QUIT; + event.type = SDL_EVENT_QUIT; event.quit.timestamp = SDL_GetTicks(); SDL_PushEvent(&event); @@ -403,7 +403,7 @@ void SdlInputHandler::handleControllerButtonEvent(SDL_ControllerButtonEvent* eve #if SDL_VERSION_ATLEAST(2, 0, 14) -void SdlInputHandler::handleControllerSensorEvent(SDL_ControllerSensorEvent* event) +void SdlInputHandler::handleControllerSensorEvent(SDL_GamepadSensorEvent * event) { GamepadState* state = findStateForGamepad(event->which); if (state == NULL) { @@ -438,7 +438,7 @@ void SdlInputHandler::handleControllerSensorEvent(SDL_ControllerSensorEvent* eve } } -void SdlInputHandler::handleControllerTouchpadEvent(SDL_ControllerTouchpadEvent* event) +void SdlInputHandler::handleControllerTouchpadEvent(SDL_GamepadTouchpadEvent * event) { GamepadState* state = findStateForGamepad(event->which); if (state == NULL) { @@ -447,13 +447,13 @@ void SdlInputHandler::handleControllerTouchpadEvent(SDL_ControllerTouchpadEvent* uint8_t eventType; switch (event->type) { - case SDL_CONTROLLERTOUCHPADDOWN: + case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN : eventType = LI_TOUCH_EVENT_DOWN; break; - case SDL_CONTROLLERTOUCHPADUP: + case SDL_EVENT_GAMEPAD_TOUCHPAD_UP : eventType = LI_TOUCH_EVENT_UP; break; - case SDL_CONTROLLERTOUCHPADMOTION: + case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION : eventType = LI_TOUCH_EVENT_MOVE; break; default: @@ -479,18 +479,21 @@ void SdlInputHandler::handleJoystickBatteryEvent(SDL_JoyBatteryEvent* event) #endif -void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* event) +void SdlInputHandler::handleControllerDeviceEvent(SDL_GamepadDeviceEvent * event) { GamepadState* state; - if (event->type == SDL_CONTROLLERDEVICEADDED) { + if (event->type == SDL_EVENT_GAMEPAD_ADDED) { int i; const char* name; - SDL_GameController* controller; + SDL_Gamepad * controller; const char* mapping; char guidStr[33]; uint32_t hapticCaps; +#if SDL_VERSION_ATLEAST(3, 0, 0) + controller = SDL_OpenGamepad(event->which); +#else controller = SDL_GameControllerOpen(event->which); if (controller == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, @@ -500,7 +503,7 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve } // SDL_CONTROLLERDEVICEADDED can be reported multiple times for the same - // gamepad in rare cases, because SDL doesn't fixup the device index in + // gamepad in rare cases, because SDL2 doesn't fixup the device index in // the SDL_CONTROLLERDEVICEADDED event if an unopened gamepad disappears // before we've processed the add event. for (int i = 0; i < MAX_GAMEPADS; i++) { @@ -508,10 +511,11 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Received duplicate add event for controller index: %d", event->which); - SDL_GameControllerClose(controller); + SDL_CloseGamepad(controller); return; } } +#endif // We used to use SDL_GameControllerGetPlayerIndex() here but that // can lead to strange issues due to bugs in Windows where an Xbox @@ -531,18 +535,18 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve if (i == MAX_GAMEPADS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No open gamepad slots found!"); - SDL_GameControllerClose(controller); + SDL_CloseGamepad(controller); return; } - SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(controller)), + SDL_JoystickGetGUIDString(SDL_GetJoystickGUID(SDL_GetGamepadJoystick(controller)), guidStr, sizeof(guidStr)); if (m_IgnoreDeviceGuids.contains(guidStr, Qt::CaseInsensitive)) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Skipping ignored device with GUID: %s", guidStr); - SDL_GameControllerClose(controller); + SDL_CloseGamepad(controller); return; } @@ -554,7 +558,7 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve // This will change indicators on the controller to show the assigned // player index. For Xbox 360 controllers, that means updating the LED // ring to light up the corresponding quadrant for this player. - SDL_GameControllerSetPlayerIndex(controller, state->index); + SDL_SetGamepadPlayerIndex(controller, state->index); #endif } else { @@ -563,7 +567,7 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve } state->controller = controller; - state->jsId = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(state->controller)); + state->jsId = SDL_GetJoystickID(SDL_GetGamepadJoystick(state->controller)); hapticCaps = 0; #if SDL_VERSION_ATLEAST(2, 0, 18) @@ -573,9 +577,9 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve // Perform a tiny rumbles to see if haptics are supported. // NB: We cannot use zeros for rumble intensity or SDL will not actually call the JS driver // and we'll get a (potentially false) success value returned. - hapticCaps |= SDL_GameControllerRumble(controller, 1, 1, 1) == 0 ? ML_HAPTIC_GC_RUMBLE : 0; + hapticCaps |= SDL_RumbleGamepad(controller, 1, 1, 1) ? ML_HAPTIC_GC_RUMBLE : 0; #if SDL_VERSION_ATLEAST(2, 0, 14) - hapticCaps |= SDL_GameControllerRumbleTriggers(controller, 1, 1, 1) == 0 ? ML_HAPTIC_GC_TRIGGER_RUMBLE : 0; + hapticCaps |= SDL_RumbleGamepadTriggers(controller, 1, 1, 1) ? ML_HAPTIC_GC_TRIGGER_RUMBLE : 0; #endif #else state->haptic = SDL_HapticOpenFromJoystick(SDL_GameControllerGetJoystick(state->controller)); @@ -606,11 +610,11 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve } #endif - mapping = SDL_GameControllerMapping(state->controller); - name = SDL_GameControllerName(state->controller); + mapping = SDL_GetGamepadMapping(state->controller); + name = SDL_GetGamepadName(state->controller); - uint16_t vendorId = SDL_GameControllerGetVendor(state->controller); - uint16_t productId = SDL_GameControllerGetProduct(state->controller); + uint16_t vendorId = SDL_GetGamepadVendor(state->controller); + uint16_t productId = SDL_GetGamepadProduct(state->controller); SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Gamepad %d (player %d) is: %s (VID/PID: 0x%.4x/0x%.4x) (haptic capabilities: 0x%x) (mapping: %s -> %s)", i, @@ -636,21 +640,21 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve SDL_assert(m_GamepadMask == 0x1); } - SDL_JoystickPowerLevel powerLevel = SDL_JoystickCurrentPowerLevel(SDL_GameControllerGetJoystick(state->controller)); + SDL_JoystickPowerLevel powerLevel = SDL_GetJoystickPowerLevel(SDL_GetGamepadJoystick(state->controller)); #if SDL_VERSION_ATLEAST(2, 0, 14) // On SDL 2.0.14 and later, we can provide enhanced controller information to the host PC // for it to use as a hint for the type of controller to emulate. uint32_t supportedButtonFlags = 0; for (int i = 0; i < (int)SDL_arraysize(k_ButtonMap); i++) { - if (SDL_GameControllerHasButton(state->controller, (SDL_GameControllerButton)i)) { + if (SDL_GamepadHasButton(state->controller, (SDL_GamepadButton)i)) { supportedButtonFlags |= k_ButtonMap[i]; } } uint32_t capabilities = 0; - if (SDL_GameControllerGetBindForAxis(state->controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT).bindType == SDL_CONTROLLER_BINDTYPE_AXIS || - SDL_GameControllerGetBindForAxis(state->controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT).bindType == SDL_CONTROLLER_BINDTYPE_AXIS) { + if (SDL_GameControllerGetBindForAxis(state->controller, SDL_GAMEPAD_AXIS_LEFT_TRIGGER).bindType == SDL_GAMEPAD_BINDTYPE_AXIS || + SDL_GameControllerGetBindForAxis(state->controller, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER).bindType == SDL_GAMEPAD_BINDTYPE_AXIS) { // We assume these are analog triggers if the binding is to an axis rather than a button capabilities |= LI_CCAP_ANALOG_TRIGGERS; } @@ -660,13 +664,13 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve if (hapticCaps & ML_HAPTIC_GC_TRIGGER_RUMBLE) { capabilities |= LI_CCAP_TRIGGER_RUMBLE; } - if (SDL_GameControllerGetNumTouchpads(state->controller) > 0) { + if (SDL_GetNumGamepadTouchpads(state->controller) > 0) { capabilities |= LI_CCAP_TOUCHPAD; } - if (SDL_GameControllerHasSensor(state->controller, SDL_SENSOR_ACCEL)) { + if (SDL_GamepadHasSensor(state->controller, SDL_SENSOR_ACCEL)) { capabilities |= LI_CCAP_ACCEL; } - if (SDL_GameControllerHasSensor(state->controller, SDL_SENSOR_GYRO)) { + if (SDL_GamepadHasSensor(state->controller, SDL_SENSOR_GYRO)) { capabilities |= LI_CCAP_GYRO; } if (powerLevel != SDL_JOYSTICK_POWER_UNKNOWN || SDL_VERSION_ATLEAST(2, 24, 0)) { @@ -677,21 +681,21 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve } uint8_t type; - switch (SDL_GameControllerGetType(state->controller)) { - case SDL_CONTROLLER_TYPE_XBOX360: - case SDL_CONTROLLER_TYPE_XBOXONE: + switch (SDL_GetGamepadType(state->controller)) { + case SDL_GAMEPAD_TYPE_XBOX360 : + case SDL_GAMEPAD_TYPE_XBOXONE : type = LI_CTYPE_XBOX; break; - case SDL_CONTROLLER_TYPE_PS3: - case SDL_CONTROLLER_TYPE_PS4: - case SDL_CONTROLLER_TYPE_PS5: + case SDL_GAMEPAD_TYPE_PS3 : + case SDL_GAMEPAD_TYPE_PS4 : + case SDL_GAMEPAD_TYPE_PS5 : type = LI_CTYPE_PS; break; - case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: + case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO : #if SDL_VERSION_ATLEAST(2, 24, 0) - case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT: - case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT: - case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR: + case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT : + case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT : + case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR : #endif type = LI_CTYPE_NINTENDO; break; @@ -704,7 +708,7 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve // we'll allow the Select+PS button combo to act as the touchpad. state->clickpadButtonEmulationEnabled = #if SDL_VERSION_ATLEAST(2, 0, 14) - SDL_GameControllerGetBindForButton(state->controller, SDL_CONTROLLER_BUTTON_TOUCHPAD).bindType == SDL_CONTROLLER_BINDTYPE_NONE && + SDL_GameControllerGetBindForButton(state->controller, SDL_GAMEPAD_BUTTON_TOUCHPAD).bindType == SDL_GAMEPAD_BINDTYPE_NONE && #endif type == LI_CTYPE_PS; @@ -720,7 +724,7 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve sendGamepadBatteryState(state, powerLevel); } } - else if (event->type == SDL_CONTROLLERDEVICEREMOVED) { + else if (event->type == SDL_EVENT_GAMEPAD_REMOVED) { state = findStateForGamepad(event->which); if (state != NULL) { if (state->mouseEmulationTimer != 0) { @@ -728,7 +732,7 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve SDL_RemoveTimer(state->mouseEmulationTimer); } - SDL_GameControllerClose(state->controller); + SDL_CloseGamepad(state->controller); #if !SDL_VERSION_ATLEAST(2, 0, 9) if (state->haptic != nullptr) { @@ -761,24 +765,23 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve void SdlInputHandler::handleJoystickArrivalEvent(SDL_JoyDeviceEvent* event) { - SDL_assert(event->type == SDL_JOYDEVICEADDED); + SDL_assert(event->type == SDL_EVENT_JOYSTICK_ADDED); - if (!SDL_IsGameController(event->which)) { - char guidStr[33]; - SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(event->which), - guidStr, sizeof(guidStr)); - const char* name = SDL_JoystickNameForIndex(event->which); - SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, - "Joystick discovered with no mapping: %s %s", - name ? name : "", - guidStr); - SDL_Joystick* joy = SDL_JoystickOpen(event->which); + if (!SDL_IsGamepad(event->which)) { + SDL_Joystick* joy = SDL_OpenJoystick(event->which); if (joy != nullptr) { + char guidStr[33]; + SDL_GUIDToString(SDL_JoystickGetGUID(joy), guidStr, sizeof(guidStr)); + const char* name = SDL_JoystickName(joy); + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, + "Unmapped joystick: %s %s", + name ? name : "", + guidStr); SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Number of axes: %d | Number of buttons: %d | Number of hats: %d", - SDL_JoystickNumAxes(joy), SDL_JoystickNumButtons(joy), - SDL_JoystickNumHats(joy)); - SDL_JoystickClose(joy); + SDL_GetNumJoystickAxes(joy), SDL_GetNumJoystickButtons(joy), + SDL_GetNumJoystickHats(joy)); + SDL_CloseJoystick(joy); } else { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, @@ -797,7 +800,7 @@ void SdlInputHandler::rumble(unsigned short controllerNumber, unsigned short low #if SDL_VERSION_ATLEAST(2, 0, 9) if (m_GamepadState[controllerNumber].controller != nullptr) { - SDL_GameControllerRumble(m_GamepadState[controllerNumber].controller, lowFreqMotor, highFreqMotor, 30000); + SDL_RumbleGamepad(m_GamepadState[controllerNumber].controller, lowFreqMotor, highFreqMotor, 30000); } #else // Check if the controller supports haptics (and if the controller exists at all) @@ -855,7 +858,7 @@ void SdlInputHandler::rumbleTriggers(uint16_t controllerNumber, uint16_t leftTri #if SDL_VERSION_ATLEAST(2, 0, 14) if (m_GamepadState[controllerNumber].controller != nullptr) { - SDL_GameControllerRumbleTriggers(m_GamepadState[controllerNumber].controller, leftTrigger, rightTrigger, 30000); + SDL_RumbleGamepadTriggers(m_GamepadState[controllerNumber].controller, leftTrigger, rightTrigger, 30000); } #endif } @@ -874,12 +877,12 @@ void SdlInputHandler::setMotionEventState(uint16_t controllerNumber, uint8_t mot switch (motionType) { case LI_MOTION_TYPE_ACCEL: m_GamepadState[controllerNumber].accelReportPeriodMs = reportPeriodMs; - SDL_GameControllerSetSensorEnabled(m_GamepadState[controllerNumber].controller, SDL_SENSOR_ACCEL, reportRateHz ? SDL_TRUE : SDL_FALSE); + SDL_SetGamepadSensorEnabled(m_GamepadState[controllerNumber].controller, SDL_SENSOR_ACCEL, reportRateHz ? SDL_TRUE : SDL_FALSE); break; case LI_MOTION_TYPE_GYRO: m_GamepadState[controllerNumber].gyroReportPeriodMs = reportPeriodMs; - SDL_GameControllerSetSensorEnabled(m_GamepadState[controllerNumber].controller, SDL_SENSOR_GYRO, reportRateHz ? SDL_TRUE : SDL_FALSE); + SDL_SetGamepadSensorEnabled(m_GamepadState[controllerNumber].controller, SDL_SENSOR_GYRO, reportRateHz ? SDL_TRUE : SDL_FALSE); break; } } @@ -895,7 +898,7 @@ void SdlInputHandler::setControllerLED(uint16_t controllerNumber, uint8_t r, uin #if SDL_VERSION_ATLEAST(2, 0, 14) if (m_GamepadState[controllerNumber].controller != nullptr) { - SDL_GameControllerSetLED(m_GamepadState[controllerNumber].controller, r, g, b); + SDL_SetGamepadLED(m_GamepadState[controllerNumber].controller, r, g, b); } #endif } @@ -904,31 +907,32 @@ QString SdlInputHandler::getUnmappedGamepads() { QString ret; - if (SDLC_FAILURE(SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER))) { + if (SDLC_FAILURE(SDL_InitSubSystem(SDL_INIT_GAMEPAD))) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) failed: %s", + "SDL_InitSubSystem(SDL_INIT_GAMEPAD) failed: %s", SDL_GetError()); } MappingManager mappingManager; mappingManager.applyMappings(); - int numJoysticks = SDL_NumJoysticks(); + int numJoysticks = 0; + SDL_JoystickID* joysticks = SDL_GetJoysticks(&numJoysticks); for (int i = 0; i < numJoysticks; i++) { - if (!SDL_IsGameController(i)) { - char guidStr[33]; - SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(i), - guidStr, sizeof(guidStr)); - const char* name = SDL_JoystickNameForIndex(i); - SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, - "Unmapped joystick: %s %s", - name ? name : "", - guidStr); - SDL_Joystick* joy = SDL_JoystickOpen(i); + if (!SDL_IsGamepad(joysticks[i])) { + SDL_Joystick* joy = SDL_OpenJoystick(joysticks[i]); if (joy != nullptr) { - int numButtons = SDL_JoystickNumButtons(joy); - int numHats = SDL_JoystickNumHats(joy); - int numAxes = SDL_JoystickNumAxes(joy); + char guidStr[33]; + SDL_GUIDToString(SDL_JoystickGetGUID(joy), guidStr, sizeof(guidStr)); + const char* name = SDL_JoystickName(joy); + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, + "Unmapped joystick: %s %s", + name ? name : "", + guidStr); + + int numButtons = SDL_GetNumJoystickButtons(joy); + int numHats = SDL_GetNumJoystickHats(joy); + int numAxes = SDL_GetNumJoystickAxes(joy); SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Number of axes: %d | Number of buttons: %d | Number of hats: %d", @@ -944,7 +948,7 @@ QString SdlInputHandler::getUnmappedGamepads() ret += name; } - SDL_JoystickClose(joy); + SDL_CloseJoystick(joy); } else { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, @@ -953,12 +957,13 @@ QString SdlInputHandler::getUnmappedGamepads() } } } + SDL_free(joysticks); - SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); + SDL_QuitSubSystem(SDL_INIT_GAMEPAD); // Flush stale events so they aren't processed by the main session event loop - SDL_FlushEvents(SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED); - SDL_FlushEvents(SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMAPPED); + SDL_FlushEvents(SDL_EVENT_JOYSTICK_ADDED, SDL_EVENT_JOYSTICK_REMOVED); + SDL_FlushEvents(SDL_EVENT_GAMEPAD_ADDED, SDL_EVENT_GAMEPAD_REMAPPED); return ret; } @@ -974,19 +979,17 @@ int SdlInputHandler::getAttachedGamepadMask() } count = mask = 0; - int numJoysticks = SDL_NumJoysticks(); - for (int i = 0; i < numJoysticks; i++) { - if (SDL_IsGameController(i)) { - char guidStr[33]; - SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(i), - guidStr, sizeof(guidStr)); + int numGamepads = 0; + SDL_JoystickID *gamepads = SDL_GetGamepads(&numGamepads); + for (int i = 0; i < numGamepads; i++) { + char guidStr[33]; + SDL_GUIDToString(SDL_GetJoystickGUIDForID(i), guidStr, sizeof(guidStr)); - if (!m_IgnoreDeviceGuids.contains(guidStr, Qt::CaseInsensitive)) - { - mask |= (1 << count++); - } + if (!m_IgnoreDeviceGuids.contains(guidStr, Qt::CaseInsensitive)) { + mask |= (1 << count++); } } + SDL_free(gamepads); return mask; } diff --git a/app/streaming/input/input.cpp b/app/streaming/input/input.cpp index db2bdf2b..07a1bc21 100644 --- a/app/streaming/input/input.cpp +++ b/app/streaming/input/input.cpp @@ -165,10 +165,10 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, int streamWidth, i // We need to reinit this each time, since you only get // an initial set of gamepad arrival events once per init. - SDL_assert(!SDL_WasInit(SDL_INIT_GAMECONTROLLER)); - if (SDLC_FAILURE(SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER))) { + SDL_assert(!SDL_WasInit(SDL_INIT_GAMEPAD)); + if (SDLC_FAILURE(SDL_InitSubSystem(SDL_INIT_GAMEPAD))) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) failed: %s", + "SDL_InitSubSystem(SDL_INIT_GAMEPAD) failed: %s", SDL_GetError()); } @@ -219,8 +219,8 @@ SdlInputHandler::~SdlInputHandler() SDL_assert(!SDL_WasInit(SDL_INIT_HAPTIC)); #endif - SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); - SDL_assert(!SDL_WasInit(SDL_INIT_GAMECONTROLLER)); + SDL_QuitSubSystem(SDL_INIT_GAMEPAD); + SDL_assert(!SDL_WasInit(SDL_INIT_GAMEPAD)); SDL_QuitSubSystem(SDL_INIT_JOYSTICK); SDL_assert(!SDL_WasInit(SDL_INIT_JOYSTICK)); @@ -275,7 +275,7 @@ void SdlInputHandler::notifyMouseLeave() // NB: Not using SDL_GetGlobalMouseState() because we want our state not the system's Uint32 mouseState = SDL_GetMouseState(nullptr, nullptr); for (Uint32 button = SDL_BUTTON_LEFT; button <= SDL_BUTTON_X2; button++) { - if (mouseState & SDL_BUTTON(button)) { + if (mouseState & SDL_BUTTON_MASK(button)) { SDL_CaptureMouse(SDL_TRUE); break; } @@ -388,7 +388,7 @@ void SdlInputHandler::setCaptureActive(bool active) if (isMouseInVideoRegion(mouseX, mouseY)) { // Synthesize a mouse event to synchronize the cursor SDL_MouseMotionEvent motionEvent = {}; - motionEvent.type = SDL_MOUSEMOTION; + motionEvent.type = SDL_EVENT_MOUSE_MOTION; motionEvent.timestamp = SDL_GetTicks(); motionEvent.windowID = SDL_GetWindowID(m_Window); motionEvent.x = mouseX; @@ -418,7 +418,7 @@ void SdlInputHandler::setCaptureActive(bool active) void SdlInputHandler::handleTouchFingerEvent(SDL_TouchFingerEvent* event) { #if SDL_VERSION_ATLEAST(2, 0, 10) - if (SDL_GetTouchDeviceType(event->touchId) != SDL_TOUCH_DEVICE_DIRECT) { + if (SDL_GetTouchDeviceType(event->touchID) != SDL_TOUCH_DEVICE_DIRECT) { // Ignore anything that isn't a touchscreen. We may get callbacks // for trackpads, but we want to handle those in the mouse path. return; diff --git a/app/streaming/input/input.h b/app/streaming/input/input.h index 701e19cf..5a05ac66 100644 --- a/app/streaming/input/input.h +++ b/app/streaming/input/input.h @@ -6,7 +6,7 @@ #include "SDL_compat.h" struct GamepadState { - SDL_GameController* controller; + SDL_Gamepad * controller; SDL_JoystickID jsId; short index; @@ -24,11 +24,11 @@ struct GamepadState { #if SDL_VERSION_ATLEAST(2, 0, 14) uint8_t gyroReportPeriodMs; - float lastGyroEventData[SDL_arraysize(SDL_ControllerSensorEvent::data)]; + float lastGyroEventData[SDL_arraysize(SDL_GamepadSensorEvent::data)]; uint32_t lastGyroEventTime; uint8_t accelReportPeriodMs; - float lastAccelEventData[SDL_arraysize(SDL_ControllerSensorEvent::data)]; + float lastAccelEventData[SDL_arraysize(SDL_GamepadSensorEvent::data)]; uint32_t lastAccelEventTime; #endif @@ -67,16 +67,16 @@ public: void handleMouseWheelEvent(SDL_MouseWheelEvent* event); - void handleControllerAxisEvent(SDL_ControllerAxisEvent* event); + void handleControllerAxisEvent(SDL_GamepadAxisEvent* event); - void handleControllerButtonEvent(SDL_ControllerButtonEvent* event); + void handleControllerButtonEvent(SDL_GamepadButtonEvent* event); - void handleControllerDeviceEvent(SDL_ControllerDeviceEvent* event); + void handleControllerDeviceEvent(SDL_GamepadDeviceEvent* event); #if SDL_VERSION_ATLEAST(2, 0, 14) - void handleControllerSensorEvent(SDL_ControllerSensorEvent* event); + void handleControllerSensorEvent(SDL_GamepadSensorEvent* event); - void handleControllerTouchpadEvent(SDL_ControllerTouchpadEvent* event); + void handleControllerTouchpadEvent(SDL_GamepadTouchpadEvent* event); #endif #if SDL_VERSION_ATLEAST(2, 24, 0) diff --git a/app/streaming/input/keyboard.cpp b/app/streaming/input/keyboard.cpp index b574caf9..97f224a4 100644 --- a/app/streaming/input/keyboard.cpp +++ b/app/streaming/input/keyboard.cpp @@ -1,6 +1,7 @@ #include "streaming/session.h" #include + #include "SDL_compat.h" #define VK_0 0x30 @@ -22,7 +23,7 @@ void SdlInputHandler::performSpecialKeyCombo(KeyCombo combo) // Push a quit event to the main loop SDL_Event event; - event.type = SDL_QUIT; + event.type = SDL_EVENT_QUIT; event.quit.timestamp = SDL_GetTicks(); SDL_PushEvent(&event); break; @@ -151,15 +152,15 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event) if (event->repeat) { // Ignore repeat key down events - SDL_assert(event->state == SDL_PRESSED); + SDL_assert(event->state == true); return; } // Check for our special key combos - if ((event->state == SDL_PRESSED) && - (event->keysym.mod & KMOD_CTRL) && - (event->keysym.mod & KMOD_ALT) && - (event->keysym.mod & KMOD_SHIFT)) { + if ((event->state == true) && + (KEY_MOD(event) & SDL_KMOD_CTRL) && + (KEY_MOD(event) & SDL_KMOD_ALT) && + (KEY_MOD(event) & SDL_KMOD_SHIFT)) { // First we test the SDLK combos for matches, // that way we ensure that latin keyboard users // can match to the key they see on their keyboards. @@ -172,14 +173,14 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event) // the scancode of another. for (int i = 0; i < KeyComboMax; i++) { - if (m_SpecialKeyCombos[i].enabled && event->keysym.sym == m_SpecialKeyCombos[i].keyCode) { + if (m_SpecialKeyCombos[i].enabled && KEY_KEY(event) == m_SpecialKeyCombos[i].keyCode) { performSpecialKeyCombo(m_SpecialKeyCombos[i].keyCombo); return; } } for (int i = 0; i < KeyComboMax; i++) { - if (m_SpecialKeyCombos[i].enabled && event->keysym.scancode == m_SpecialKeyCombos[i].scanCode) { + if (m_SpecialKeyCombos[i].enabled && KEY_SCANCODE(event) == m_SpecialKeyCombos[i].scanCode) { performSpecialKeyCombo(m_SpecialKeyCombos[i].keyCombo); return; } @@ -188,16 +189,16 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event) // Set modifier flags modifiers = 0; - if (event->keysym.mod & KMOD_CTRL) { + if (KEY_MOD(event) & SDL_KMOD_CTRL) { modifiers |= MODIFIER_CTRL; } - if (event->keysym.mod & KMOD_ALT) { + if (KEY_MOD(event) & SDL_KMOD_ALT) { modifiers |= MODIFIER_ALT; } - if (event->keysym.mod & KMOD_SHIFT) { + if (KEY_MOD(event) & SDL_KMOD_SHIFT) { modifiers |= MODIFIER_SHIFT; } - if (event->keysym.mod & KMOD_GUI) { + if (KEY_MOD(event) & SDL_KMOD_GUI) { if (isSystemKeyCaptureActive()) { modifiers |= MODIFIER_META; } @@ -206,25 +207,25 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event) // Set keycode. We explicitly use scancode here because GFE will try to correct // for AZERTY layouts on the host but it depends on receiving VK_ values matching // a QWERTY layout to work. - if (event->keysym.scancode >= SDL_SCANCODE_1 && event->keysym.scancode <= SDL_SCANCODE_9) { + if (KEY_SCANCODE(event) >= SDL_SCANCODE_1 && KEY_SCANCODE(event) <= SDL_SCANCODE_9) { // SDL defines SDL_SCANCODE_0 > SDL_SCANCODE_9, so we need to handle that manually - keyCode = (event->keysym.scancode - SDL_SCANCODE_1) + VK_0 + 1; + keyCode = (KEY_SCANCODE(event) - SDL_SCANCODE_1) + VK_0 + 1; } - else if (event->keysym.scancode >= SDL_SCANCODE_A && event->keysym.scancode <= SDL_SCANCODE_Z) { - keyCode = (event->keysym.scancode - SDL_SCANCODE_A) + VK_A; + else if (KEY_SCANCODE(event) >= SDL_SCANCODE_A && KEY_SCANCODE(event) <= SDL_SCANCODE_Z) { + keyCode = (KEY_SCANCODE(event) - SDL_SCANCODE_A) + VK_A; } - else if (event->keysym.scancode >= SDL_SCANCODE_F1 && event->keysym.scancode <= SDL_SCANCODE_F12) { - keyCode = (event->keysym.scancode - SDL_SCANCODE_F1) + VK_F1; + else if (KEY_SCANCODE(event) >= SDL_SCANCODE_F1 && KEY_SCANCODE(event) <= SDL_SCANCODE_F12) { + keyCode = (KEY_SCANCODE(event) - SDL_SCANCODE_F1) + VK_F1; } - else if (event->keysym.scancode >= SDL_SCANCODE_F13 && event->keysym.scancode <= SDL_SCANCODE_F24) { - keyCode = (event->keysym.scancode - SDL_SCANCODE_F13) + VK_F13; + else if (KEY_SCANCODE(event) >= SDL_SCANCODE_F13 && KEY_SCANCODE(event) <= SDL_SCANCODE_F24) { + keyCode = (KEY_SCANCODE(event) - SDL_SCANCODE_F13) + VK_F13; } - else if (event->keysym.scancode >= SDL_SCANCODE_KP_1 && event->keysym.scancode <= SDL_SCANCODE_KP_9) { + else if (KEY_SCANCODE(event) >= SDL_SCANCODE_KP_1 && KEY_SCANCODE(event) <= SDL_SCANCODE_KP_9) { // SDL defines SDL_SCANCODE_KP_0 > SDL_SCANCODE_KP_9, so we need to handle that manually - keyCode = (event->keysym.scancode - SDL_SCANCODE_KP_1) + VK_NUMPAD0 + 1; + keyCode = (KEY_SCANCODE(event) - SDL_SCANCODE_KP_1) + VK_NUMPAD0 + 1; } else { - switch (event->keysym.scancode) { + switch (KEY_SCANCODE(event)) { case SDL_SCANCODE_BACKSPACE: keyCode = 0x08; break; @@ -417,13 +418,13 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event) default: SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Unhandled button event: %d", - event->keysym.scancode); + KEY_SCANCODE(event)); return; } } // Track the key state so we always know which keys are down - if (event->state == SDL_PRESSED) { + if (event->state == true) { m_KeysDown.insert(keyCode); } else { @@ -431,7 +432,7 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event) } LiSendKeyboardEvent(0x8000 | keyCode, - event->state == SDL_PRESSED ? - KEY_ACTION_DOWN : KEY_ACTION_UP, + event->state == true ? + KEY_ACTION_DOWN : KEY_ACTION_UP, modifiers); } diff --git a/app/streaming/input/mouse.cpp b/app/streaming/input/mouse.cpp index ef9b0d20..15c50c99 100644 --- a/app/streaming/input/mouse.cpp +++ b/app/streaming/input/mouse.cpp @@ -13,7 +13,7 @@ void SdlInputHandler::handleMouseButtonEvent(SDL_MouseButtonEvent* event) return; } else if (!isCaptureActive()) { - if (event->button == SDL_BUTTON_LEFT && event->state == SDL_RELEASED && + if (event->button == SDL_BUTTON_LEFT && event->state == false && isMouseInVideoRegion(event->x, event->y)) { // Capture the mouse again if clicked when unbound. // We start capture on left button released instead of @@ -26,7 +26,7 @@ void SdlInputHandler::handleMouseButtonEvent(SDL_MouseButtonEvent* event) // Not capturing return; } - else if (m_AbsoluteMouseMode && !isMouseInVideoRegion(event->x, event->y) && event->state == SDL_PRESSED) { + else if (m_AbsoluteMouseMode && !isMouseInVideoRegion(event->x, event->y) && event->state == true) { // Ignore button presses outside the video region, but allow button releases return; } @@ -62,7 +62,7 @@ void SdlInputHandler::handleMouseButtonEvent(SDL_MouseButtonEvent* event) button = BUTTON_RIGHT; } - LiSendMouseButtonEvent(event->state == SDL_PRESSED ? + LiSendMouseButtonEvent(event->state == true ? BUTTON_ACTION_PRESS : BUTTON_ACTION_RELEASE, button); @@ -82,7 +82,7 @@ void SdlInputHandler::handleMouseMotionEvent(SDL_MouseMotionEvent* event) // Batch all pending mouse motion events to save CPU time Sint32 x = event->x, y = event->y, xrel = event->xrel, yrel = event->yrel; SDL_Event nextEvent; - while (SDL_PeepEvents(&nextEvent, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION) > 0) { + while (SDL_PeepEvents(&nextEvent, 1, SDL_GETEVENT, SDL_EVENT_MOUSE_MOTION, SDL_EVENT_MOUSE_MOTION) > 0) { event = &nextEvent.motion; // Ignore synthetic mouse events @@ -175,34 +175,34 @@ void SdlInputHandler::handleMouseWheelEvent(SDL_MouseWheelEvent* event) } #if SDL_VERSION_ATLEAST(2, 0, 18) - if (event->preciseY != 0.0f) { + if (event->y != 0.0f) { // Invert the scroll direction if needed if (m_ReverseScrollDirection) { - event->preciseY = -event->preciseY; + event->y = -event->y; } #ifdef Q_OS_DARWIN // HACK: Clamp the scroll values on macOS to prevent OS scroll acceleration // from generating wild scroll deltas when scrolling quickly. - event->preciseY = SDL_clamp(event->preciseY, -1.0f, 1.0f); + event->y = SDL_clamp(event->y, -1.0f, 1.0f); #endif - LiSendHighResScrollEvent((short)(event->preciseY * 120)); // WHEEL_DELTA + LiSendHighResScrollEvent((short)(event->y * 120)); // WHEEL_DELTA } - if (event->preciseX != 0.0f) { + if (event->x != 0.0f) { // Invert the scroll direction if needed if (m_ReverseScrollDirection) { - event->preciseX = -event->preciseY; + event->x = -event->y; } #ifdef Q_OS_DARWIN // HACK: Clamp the scroll values on macOS to prevent OS scroll acceleration // from generating wild scroll deltas when scrolling quickly. - event->preciseX = SDL_clamp(event->preciseX, -1.0f, 1.0f); + event->x = SDL_clamp(event->x, -1.0f, 1.0f); #endif - LiSendHighResHScrollEvent((short)(event->preciseX * 120)); // WHEEL_DELTA + LiSendHighResHScrollEvent((short)(event->x * 120)); // WHEEL_DELTA } #else if (event->y != 0) { diff --git a/app/streaming/input/reltouch.cpp b/app/streaming/input/reltouch.cpp index 0ddc778a..8f2844ec 100644 --- a/app/streaming/input/reltouch.cpp +++ b/app/streaming/input/reltouch.cpp @@ -59,9 +59,9 @@ void SdlInputHandler::handleRelativeFingerEvent(SDL_TouchFingerEvent* event) // This is also required to handle finger up which // where the finger will not be in SDL_GetTouchFinger() // anymore. - if (event->type != SDL_FINGERDOWN) { + if (event->type != SDL_EVENT_FINGER_DOWN) { for (int i = 0; i < MAX_FINGERS; i++) { - if (event->fingerId == m_TouchDownEvent[i].fingerId) { + if (event->fingerID == m_TouchDownEvent[i].fingerID) { fingerIndex = i; break; } @@ -70,12 +70,12 @@ void SdlInputHandler::handleRelativeFingerEvent(SDL_TouchFingerEvent* event) else { // Resolve the new finger by determining the ID of each // finger on the display. - int numTouchFingers = SDL_GetNumTouchFingers(event->touchId); + int numTouchFingers = SDL_GetNumTouchFingers(event->touchID); for (int i = 0; i < numTouchFingers; i++) { - SDL_Finger* finger = SDL_GetTouchFinger(event->touchId, i); + SDL_Finger* finger = SDL_GetTouchFinger(event->touchID, i); SDL_assert(finger != nullptr); if (finger != nullptr) { - if (finger->id == event->fingerId) { + if (finger->id == event->fingerID) { fingerIndex = i; break; } @@ -106,7 +106,7 @@ void SdlInputHandler::handleRelativeFingerEvent(SDL_TouchFingerEvent* event) // Start a drag timer when primary or secondary // fingers go down - if (event->type == SDL_FINGERDOWN && + if (event->type == SDL_EVENT_FINGER_DOWN && (fingerIndex == 0 || fingerIndex == 1)) { SDL_RemoveTimer(m_DragTimer); m_DragTimer = SDL_AddTimer(DRAG_ACTIVATION_DELAY, @@ -114,7 +114,7 @@ void SdlInputHandler::handleRelativeFingerEvent(SDL_TouchFingerEvent* event) this); } - if (event->type == SDL_FINGERMOTION) { + if (event->type == SDL_EVENT_FINGER_MOTION) { // If it's outside the deadzone delta, cancel drags and taps if (qSqrt(qPow(event->x - m_TouchDownEvent[fingerIndex].x, 2) + qPow(event->y - m_TouchDownEvent[fingerIndex].y, 2)) > DEAD_ZONE_DELTA) { @@ -126,7 +126,7 @@ void SdlInputHandler::handleRelativeFingerEvent(SDL_TouchFingerEvent* event) } } - if (event->type == SDL_FINGERUP) { + if (event->type == SDL_EVENT_FINGER_UP) { // Cancel the drag timer on finger up SDL_RemoveTimer(m_DragTimer); m_DragTimer = 0; @@ -164,12 +164,12 @@ void SdlInputHandler::handleRelativeFingerEvent(SDL_TouchFingerEvent* event) } } - m_NumFingersDown = SDL_GetNumTouchFingers(event->touchId); + m_NumFingersDown = SDL_GetNumTouchFingers(event->touchID); - if (event->type == SDL_FINGERDOWN) { + if (event->type == SDL_EVENT_FINGER_DOWN) { m_TouchDownEvent[fingerIndex] = *event; } - else if (event->type == SDL_FINGERUP) { + else if (event->type == SDL_EVENT_FINGER_UP) { m_TouchDownEvent[fingerIndex] = {}; } } diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index a175cb3f..4efc66e0 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -169,7 +169,7 @@ void Session::clRumble(unsigned short controllerNumber, unsigned short lowFreqMo // with the removal of game controllers that could result in our game controller // going away during this callback. SDL_Event rumbleEvent = {}; - rumbleEvent.type = SDL_USEREVENT; + rumbleEvent.type = SDL_EVENT_USER; rumbleEvent.user.code = SDL_CODE_GAMECONTROLLER_RUMBLE; rumbleEvent.user.data1 = (void*)(uintptr_t)controllerNumber; rumbleEvent.user.data2 = (void*)(uintptr_t)((lowFreqMotor << 16) | highFreqMotor); @@ -210,12 +210,12 @@ void Session::clSetHdrMode(bool enabled) // If we're in the process of recreating our decoder when we get // this callback, we'll drop it. The main thread will make the // callback when it finishes creating the new decoder. - if (SDL_AtomicTryLock(&s_ActiveSession->m_DecoderLock)) { + if (SDL_TryLockSpinlock(&s_ActiveSession->m_DecoderLock)) { IVideoDecoder* decoder = s_ActiveSession->m_VideoDecoder; if (decoder != nullptr) { decoder->setHdrMode(enabled); } - SDL_AtomicUnlock(&s_ActiveSession->m_DecoderLock); + SDL_UnlockSpinlock(&s_ActiveSession->m_DecoderLock); } } @@ -225,7 +225,7 @@ void Session::clRumbleTriggers(uint16_t controllerNumber, uint16_t leftTrigger, // with the removal of game controllers that could result in our game controller // going away during this callback. SDL_Event rumbleEvent = {}; - rumbleEvent.type = SDL_USEREVENT; + rumbleEvent.type = SDL_EVENT_USER; rumbleEvent.user.code = SDL_CODE_GAMECONTROLLER_RUMBLE_TRIGGERS; rumbleEvent.user.data1 = (void*)(uintptr_t)controllerNumber; rumbleEvent.user.data2 = (void*)(uintptr_t)((leftTrigger << 16) | rightTrigger); @@ -238,7 +238,7 @@ void Session::clSetMotionEventState(uint16_t controllerNumber, uint8_t motionTyp // with the removal of game controllers that could result in our game controller // going away during this callback. SDL_Event setMotionEventStateEvent = {}; - setMotionEventStateEvent.type = SDL_USEREVENT; + setMotionEventStateEvent.type = SDL_EVENT_USER; setMotionEventStateEvent.user.code = SDL_CODE_GAMECONTROLLER_SET_MOTION_EVENT_STATE; setMotionEventStateEvent.user.data1 = (void*)(uintptr_t)controllerNumber; setMotionEventStateEvent.user.data2 = (void*)(uintptr_t)((motionType << 16) | reportRateHz); @@ -251,7 +251,7 @@ void Session::clSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g // with the removal of game controllers that could result in our game controller // going away during this callback. SDL_Event setControllerLEDEvent = {}; - setControllerLEDEvent.type = SDL_USEREVENT; + setControllerLEDEvent.type = SDL_EVENT_USER; setControllerLEDEvent.user.code = SDL_CODE_GAMECONTROLLER_SET_CONTROLLER_LED; setControllerLEDEvent.user.data1 = (void*)(uintptr_t)controllerNumber; setControllerLEDEvent.user.data2 = (void*)(uintptr_t)(r << 16 | g << 8 | b); @@ -348,15 +348,15 @@ int Session::drSubmitDecodeUnit(PDECODE_UNIT du) // safely return DR_OK and wait for the IDR frame request by // the decoder reinitialization code. - if (SDL_AtomicTryLock(&s_ActiveSession->m_DecoderLock)) { + if (SDL_TryLockSpinlock(&s_ActiveSession->m_DecoderLock)) { IVideoDecoder* decoder = s_ActiveSession->m_VideoDecoder; if (decoder != nullptr) { int ret = decoder->submitDecodeUnit(du); - SDL_AtomicUnlock(&s_ActiveSession->m_DecoderLock); + SDL_UnlockSpinlock(&s_ActiveSession->m_DecoderLock); return ret; } else { - SDL_AtomicUnlock(&s_ActiveSession->m_DecoderLock); + SDL_UnlockSpinlock(&s_ActiveSession->m_DecoderLock); return DR_OK; } } @@ -550,7 +550,7 @@ Session::Session(NvComputer* computer, NvApp& app, StreamingPreferences *prefere m_InputHandler(nullptr), m_MouseEmulationRefCount(0), m_FlushingWindowEventsRef(0), - m_CurrentDisplayIndex(-1), + m_CurrentDisplay(-1), m_NeedsFirstEnterCapture(false), m_NeedsPostDecoderCreationCapture(false), m_AsyncConnectionSuccess(false), @@ -1261,11 +1261,10 @@ private: void Session::getWindowDimensions(int& x, int& y, int& width, int& height) { - int displayIndex = 0; + SDL_DisplayID display = SDL_GetPrimaryDisplay(); if (m_Window != nullptr) { - displayIndex = SDL_GetWindowDisplayIndex(m_Window); - SDL_assert(displayIndex >= 0); + display = SDL_GetDisplayForWindow(m_Window); } // Create our window on the same display that Qt's UI // was being displayed on. @@ -1279,25 +1278,28 @@ void Session::getWindowDimensions(int& x, int& y, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Qt UI screen is at (%d,%d)", displayRect.x(), displayRect.y()); - for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) { + int numDisplays = 0; + SDL_DisplayID* displays = SDL_GetDisplays(&numDisplays); + for (int i = 0; i < numDisplays; i++) { SDL_Rect displayBounds; - if (SDLC_SUCCESS(SDL_GetDisplayBounds(i, &displayBounds))) { + if (SDLC_SUCCESS(SDL_GetDisplayBounds(displays[i], &displayBounds))) { if (displayBounds.x == displayRect.x() && displayBounds.y == displayRect.y()) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "SDL found matching display %d", - i); - displayIndex = i; + displays[i]); + display = displays[i]; break; } } else { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "SDL_GetDisplayBounds(%d) failed: %s", - i, SDL_GetError()); + displays[i], SDL_GetError()); } } + SDL_free(displays); } else { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, @@ -1307,7 +1309,7 @@ void Session::getWindowDimensions(int& x, int& y, } SDL_Rect usableBounds; - if (SDLC_SUCCESS(SDL_GetDisplayUsableBounds(displayIndex, &usableBounds))) { + if (SDLC_SUCCESS(SDL_GetDisplayUsableBounds(display, &usableBounds))) { // Don't use more than 80% of the display to leave room for system UI // and ensure the target size is not odd (otherwise one of the sides // of the image will have a one-pixel black bar next to it). @@ -1341,7 +1343,7 @@ void Session::getWindowDimensions(int& x, int& y, height = m_StreamConfig.height; } - x = y = SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex); + x = y = SDL_WINDOWPOS_CENTERED_DISPLAY(display); } void Session::updateOptimalWindowDisplayMode() @@ -1355,13 +1357,13 @@ void Session::updateOptimalWindowDisplayMode() // Try the current display mode first. On macOS, this will be the normal // scaled desktop resolution setting. - int displayIndex = SDL_GetWindowDisplayIndex(m_Window); - if (SDL_GetDesktopDisplayMode(displayIndex, &desktopMode) == 0) { + SDL_DisplayID display = SDL_GetDisplayForWindow(m_Window); + if (SDL_GetDesktopDisplayMode(display, &desktopMode) == 0) { // If this doesn't fit the selected resolution, use the native // resolution of the panel (unscaled). if (desktopMode.w < m_ActiveVideoWidth || desktopMode.h < m_ActiveVideoHeight) { SDL_Rect safeArea; - if (!StreamUtils::getNativeDesktopMode(displayIndex, &desktopMode, &safeArea)) { + if (!StreamUtils::getNativeDesktopMode(display, &desktopMode, &safeArea)) { return; } } @@ -1377,15 +1379,18 @@ void Session::updateOptimalWindowDisplayMode() // the highest refresh rate that our stream FPS evenly divides. bestMode = desktopMode; bestMode.refresh_rate = 0; - for (int i = 0; i < SDL_GetNumDisplayModes(displayIndex); i++) { - if (SDL_GetDisplayMode(displayIndex, i, &mode) == 0) { - if (mode.w == desktopMode.w && mode.h == desktopMode.h && + { + int numDisplayModes = SDL_GetNumDisplayModes(display); + for (int i = 0; i < numDisplayModes; i++) { + if (SDL_GetDisplayMode(display, i, &mode) == 0) { + if (mode.w == desktopMode.w && mode.h == desktopMode.h && mode.refresh_rate % m_StreamConfig.fps == 0) { - SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, - "Found display mode with desktop resolution: %dx%dx%d", - mode.w, mode.h, mode.refresh_rate); - if (mode.refresh_rate > bestMode.refresh_rate) { - bestMode = mode; + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, + "Found display mode with desktop resolution: %dx%dx%d", + mode.w, mode.h, mode.refresh_rate); + if (mode.refresh_rate > bestMode.refresh_rate) { + bestMode = mode; + } } } } @@ -1399,8 +1404,9 @@ void Session::updateOptimalWindowDisplayMode() if (bestMode.refresh_rate == 0) { float bestModeAspectRatio = 0; float videoAspectRatio = (float)m_ActiveVideoWidth / (float)m_ActiveVideoHeight; - for (int i = 0; i < SDL_GetNumDisplayModes(displayIndex); i++) { - if (SDL_GetDisplayMode(displayIndex, i, &mode) == 0) { + int numDisplayModes = SDL_GetNumDisplayModes(display); + for (int i = 0; i < numDisplayModes; i++) { + if (SDL_GetDisplayMode(display, i, &mode) == 0) { float modeAspectRatio = (float)mode.w / (float)mode.h; if (mode.w >= m_ActiveVideoWidth && mode.h >= m_ActiveVideoHeight && mode.refresh_rate % m_StreamConfig.fps == 0) { @@ -1435,7 +1441,7 @@ void Session::updateOptimalWindowDisplayMode() bestMode.w, bestMode.h, bestMode.refresh_rate); } - SDL_SetWindowDisplayMode(m_Window, &bestMode); + SDL_SetWindowFullscreenMode(m_Window, &bestMode); } void Session::toggleFullscreen() @@ -1451,10 +1457,10 @@ void Session::toggleFullscreen() // On Apple Silicon Macs, the AVSampleBufferDisplayLayer may cause WindowServer // to deadlock when transitioning out of fullscreen. Destroy the decoder before // exiting fullscreen as a workaround. See issue #973. - SDL_AtomicLock(&m_DecoderLock); + SDL_LockSpinlock(&m_DecoderLock); delete m_VideoDecoder; m_VideoDecoder = nullptr; - SDL_AtomicUnlock(&m_DecoderLock); + SDL_UnlockSpinlock(&m_DecoderLock); #endif // Actually enter/leave fullscreen @@ -1673,7 +1679,7 @@ void Session::flushWindowEvents() // This event will cause us to set m_FlushingWindowEvents back to false. SDL_Event flushEvent = {}; - flushEvent.type = SDL_USEREVENT; + flushEvent.type = SDL_EVENT_USER; flushEvent.user.code = SDL_CODE_FLUSH_WINDOW_EVENT_BARRIER; SDL_PushEvent(&flushEvent); } @@ -1682,24 +1688,24 @@ bool Session::handleWindowEvent(SDL_WindowEvent* event) { // Early handling of some events switch (event->event) { - case SDL_WINDOWEVENT_FOCUS_LOST: + case SDL_EVENT_WINDOW_FOCUS_LOST : if (m_Preferences->muteOnFocusLoss) { m_AudioMuted = true; } m_InputHandler->notifyFocusLost(); break; - case SDL_WINDOWEVENT_FOCUS_GAINED: + case SDL_EVENT_WINDOW_FOCUS_GAINED : if (m_Preferences->muteOnFocusLoss) { m_AudioMuted = false; } break; - case SDL_WINDOWEVENT_LEAVE: + case SDL_EVENT_WINDOW_MOUSE_LEAVE : m_InputHandler->notifyMouseLeave(); break; } // Capture the mouse on SDL_WINDOWEVENT_ENTER if needed - if (m_NeedsFirstEnterCapture && event->event == SDL_WINDOWEVENT_ENTER) { + if (m_NeedsFirstEnterCapture && event->event == SDL_EVENT_WINDOW_MOUSE_ENTER) { m_InputHandler->setCaptureActive(true); m_NeedsFirstEnterCapture = false; } @@ -1707,19 +1713,19 @@ bool Session::handleWindowEvent(SDL_WindowEvent* event) // We want to recreate the decoder for resizes (full-screen toggles) and the initial shown event. // We use SDL_WINDOWEVENT_SIZE_CHANGED rather than SDL_WINDOWEVENT_RESIZED because the latter doesn't // seem to fire when switching from windowed to full-screen on X11. - if (event->event != SDL_WINDOWEVENT_SIZE_CHANGED && - (event->event != SDL_WINDOWEVENT_SHOWN || m_VideoDecoder != nullptr)) { + if (event->event != SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED && + (event->event != SDL_EVENT_WINDOW_SHOWN || m_VideoDecoder != nullptr)) { // Check that the window display hasn't changed. If it has, we want // to recreate the decoder to allow it to adapt to the new display. // This will allow Pacer to pull the new display refresh rate. #if SDL_VERSION_ATLEAST(2, 0, 18) // On SDL 2.0.18+, there's an event for this specific situation - if (event->event != SDL_WINDOWEVENT_DISPLAY_CHANGED) { + if (event->event != SDL_EVENT_WINDOW_DISPLAY_CHANGED) { return true; } #else // Prior to SDL 2.0.18, we must check the display index for each window event - if (SDL_GetWindowDisplayIndex(m_Window) == currentDisplayIndex) { + if (SDL_GetDisplayForWindow(m_Window) == m_CurrentDisplay) { return true; } #endif @@ -1751,26 +1757,26 @@ bool Session::handleWindowEvent(SDL_WindowEvent* event) WINDOW_STATE_CHANGE_INFO windowChangeInfo = {}; windowChangeInfo.window = m_Window; - if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) { + if (event->event == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) { windowChangeInfo.stateChangeFlags |= WINDOW_STATE_CHANGE_SIZE; windowChangeInfo.width = event->data1; windowChangeInfo.height = event->data2; } - int newDisplayIndex = SDL_GetWindowDisplayIndex(m_Window); - if (newDisplayIndex != m_CurrentDisplayIndex) { + SDL_DisplayID newDisplay = SDL_GetDisplayForWindow(m_Window); + if (newDisplay != m_CurrentDisplay) { windowChangeInfo.stateChangeFlags |= WINDOW_STATE_CHANGE_DISPLAY; - windowChangeInfo.displayIndex = newDisplayIndex; + windowChangeInfo.displayIndex = newDisplay; // If the refresh rates have changed, we will need to go through the full // decoder recreation path to ensure Pacer is switched to the new display // and that we apply any V-Sync disablement rules that may be needed for // this display. SDL_DisplayMode oldMode, newMode; - if (SDL_GetCurrentDisplayMode(m_CurrentDisplayIndex, &oldMode) < 0 || - SDL_GetCurrentDisplayMode(newDisplayIndex, &newMode) < 0 || + if (SDL_GetCurrentDisplayMode(m_CurrentDisplay, &oldMode) < 0 || + SDL_GetCurrentDisplayMode(newDisplay, &newMode) < 0 || oldMode.refresh_rate != newMode.refresh_rate) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Forcing renderer recreation due to refresh rate change between displays"); @@ -1781,8 +1787,8 @@ bool Session::handleWindowEvent(SDL_WindowEvent* event) if (!forceRecreation && m_VideoDecoder->notifyWindowChanged(&windowChangeInfo)) { // Update the window display mode based on our current monitor // NB: Avoid a useless modeset by only doing this if it changed. - if (newDisplayIndex != m_CurrentDisplayIndex) { - m_CurrentDisplayIndex = newDisplayIndex; + if (newDisplay != m_CurrentDisplay) { + m_CurrentDisplay = newDisplay; updateOptimalWindowDisplayMode(); } @@ -1807,7 +1813,7 @@ bool Session::handleWindowEvent(SDL_WindowEvent* event) bool Session::recreateRenderer() { - SDL_AtomicLock(&m_DecoderLock); + SDL_LockSpinlock(&m_DecoderLock); // Destroy the old decoder delete m_VideoDecoder; @@ -1820,8 +1826,8 @@ bool Session::recreateRenderer() // Update the window display mode based on our current monitor // NB: Avoid a useless modeset by only doing this if it changed. - if (m_CurrentDisplayIndex != SDL_GetWindowDisplayIndex(m_Window)) { - m_CurrentDisplayIndex = SDL_GetWindowDisplayIndex(m_Window); + if (m_CurrentDisplay != SDL_GetDisplayForWindow(m_Window)) { + m_CurrentDisplay = SDL_GetDisplayForWindow(m_Window); updateOptimalWindowDisplayMode(); } @@ -1829,8 +1835,8 @@ bool Session::recreateRenderer() // have queued to reset itself (if this reset was the result // of state loss). SDL_PumpEvents(); - SDL_FlushEvent(SDL_RENDER_DEVICE_RESET); - SDL_FlushEvent(SDL_RENDER_TARGETS_RESET); + SDL_FlushEvent(SDL_EVENT_RENDER_DEVICE_RESET); + SDL_FlushEvent(SDL_EVENT_RENDER_TARGETS_RESET); { // If the stream exceeds the display refresh rate (plus some slack), @@ -1853,7 +1859,7 @@ bool Session::recreateRenderer() enableVsync && m_Preferences->framePacing, false, s_ActiveSession->m_VideoDecoder)) { - SDL_AtomicUnlock(&m_DecoderLock); + SDL_UnlockSpinlock(&m_DecoderLock); return false; } @@ -1876,7 +1882,7 @@ bool Session::recreateRenderer() // After a window resize, we need to reset the pointer lock region m_InputHandler->updatePointerRegionLock(); - SDL_AtomicUnlock(&m_DecoderLock); + SDL_UnlockSpinlock(&m_DecoderLock); return true; } @@ -2002,7 +2008,7 @@ void Session::execInternal() SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); // We always want a resizable window with High DPI enabled - Uint32 defaultWindowFlags = SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE; + Uint32 defaultWindowFlags = SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_RESIZABLE; // If we're starting in windowed mode and the Moonlight GUI is maximized or // minimized, match that with the streaming window. @@ -2090,12 +2096,7 @@ void Session::execInternal() QPainter svgPainter(&svgImage); svgIconRenderer.render(&svgPainter); - SDL_Surface* iconSurface = SDL_CreateRGBSurfaceWithFormatFrom((void*)svgImage.constBits(), - svgImage.width(), - svgImage.height(), - 32, - 4 * svgImage.width(), - SDL_PIXELFORMAT_RGBA32); + SDL_Surface* iconSurface = SDL_CreateSurfaceFrom(svgImage.width(), svgImage.height(), SDL_PIXELFORMAT_RGBA32, (void *)svgImage.constBits(), 4 * svgImage.width()); #ifndef Q_OS_DARWIN // Other platforms seem to preserve our Qt icon when creating a new window. if (iconSurface != nullptr) { @@ -2147,7 +2148,7 @@ void Session::execInternal() // sleep precision and more accurate callback timing. SDL_SetHint(SDL_HINT_TIMER_RESOLUTION, "1"); - m_CurrentDisplayIndex = SDL_GetWindowDisplayIndex(m_Window); + m_CurrentDisplay = SDL_GetDisplayForWindow(m_Window); // Now that we're about to stream, any SDL_QUIT event is expected // unless it comes from the connection termination callback where @@ -2205,12 +2206,12 @@ void Session::execInternal() } switch (event.type) { - case SDL_QUIT: + case SDL_EVENT_QUIT : SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Quit event received"); goto DispatchDeferredCleanup; - case SDL_USEREVENT: + case SDL_EVENT_USER : switch (event.user.code) { case SDL_CODE_FRAME_READY: if (m_VideoDecoder != nullptr) { @@ -2245,8 +2246,8 @@ void Session::execInternal() SDL_assert(false); } break; - case SDL_RENDER_DEVICE_RESET: - case SDL_RENDER_TARGETS_RESET: + case SDL_EVENT_RENDER_DEVICE_RESET : + case SDL_EVENT_RENDER_TARGETS_RESET : SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Recreating renderer by internal request: %d", event.type); @@ -2259,55 +2260,55 @@ void Session::execInternal() } break; - case SDL_KEYUP: - case SDL_KEYDOWN: + case SDL_EVENT_KEY_UP : + case SDL_EVENT_KEY_DOWN : presence.runCallbacks(); m_InputHandler->handleKeyEvent(&event.key); break; - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: + case SDL_EVENT_MOUSE_BUTTON_DOWN : + case SDL_EVENT_MOUSE_BUTTON_UP : presence.runCallbacks(); m_InputHandler->handleMouseButtonEvent(&event.button); break; - case SDL_MOUSEMOTION: + case SDL_EVENT_MOUSE_MOTION : m_InputHandler->handleMouseMotionEvent(&event.motion); break; - case SDL_MOUSEWHEEL: + case SDL_EVENT_MOUSE_WHEEL : m_InputHandler->handleMouseWheelEvent(&event.wheel); break; - case SDL_CONTROLLERAXISMOTION: - m_InputHandler->handleControllerAxisEvent(&event.caxis); + case SDL_EVENT_GAMEPAD_AXIS_MOTION : + m_InputHandler->handleControllerAxisEvent(&event.gaxis); break; - case SDL_CONTROLLERBUTTONDOWN: - case SDL_CONTROLLERBUTTONUP: + case SDL_EVENT_GAMEPAD_BUTTON_DOWN : + case SDL_EVENT_GAMEPAD_BUTTON_UP : presence.runCallbacks(); - m_InputHandler->handleControllerButtonEvent(&event.cbutton); + m_InputHandler->handleControllerButtonEvent(&event.gbutton); break; #if SDL_VERSION_ATLEAST(2, 0, 14) - case SDL_CONTROLLERSENSORUPDATE: - m_InputHandler->handleControllerSensorEvent(&event.csensor); + case SDL_EVENT_GAMEPAD_SENSOR_UPDATE : + m_InputHandler->handleControllerSensorEvent(&event.gsensor); break; - case SDL_CONTROLLERTOUCHPADDOWN: - case SDL_CONTROLLERTOUCHPADUP: - case SDL_CONTROLLERTOUCHPADMOTION: - m_InputHandler->handleControllerTouchpadEvent(&event.ctouchpad); + case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN : + case SDL_EVENT_GAMEPAD_TOUCHPAD_UP : + case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION : + m_InputHandler->handleControllerTouchpadEvent(&event.gtouchpad); break; #endif #if SDL_VERSION_ATLEAST(2, 24, 0) - case SDL_JOYBATTERYUPDATED: + case SDL_EVENT_JOYSTICK_BATTERY_UPDATED : m_InputHandler->handleJoystickBatteryEvent(&event.jbattery); break; #endif - case SDL_CONTROLLERDEVICEADDED: - case SDL_CONTROLLERDEVICEREMOVED: - m_InputHandler->handleControllerDeviceEvent(&event.cdevice); + case SDL_EVENT_GAMEPAD_ADDED : + case SDL_EVENT_GAMEPAD_REMOVED : + m_InputHandler->handleControllerDeviceEvent(&event.gdevice); break; - case SDL_JOYDEVICEADDED: + case SDL_EVENT_JOYSTICK_ADDED : m_InputHandler->handleJoystickArrivalEvent(&event.jdevice); break; - case SDL_FINGERDOWN: - case SDL_FINGERMOTION: - case SDL_FINGERUP: + case SDL_EVENT_FINGER_DOWN : + case SDL_EVENT_FINGER_MOTION : + case SDL_EVENT_FINGER_UP : m_InputHandler->handleTouchFingerEvent(&event.tfinger); break; } @@ -2335,10 +2336,10 @@ DispatchDeferredCleanup: // Destroy the decoder, since this must be done on the main thread // NB: This must happen before LiStopConnection() for pull-based // decoders. - SDL_AtomicLock(&m_DecoderLock); + SDL_LockSpinlock(&m_DecoderLock); delete m_VideoDecoder; m_VideoDecoder = nullptr; - SDL_AtomicUnlock(&m_DecoderLock); + SDL_UnlockSpinlock(&m_DecoderLock); // Propagate state changes from the SDL window back to the Qt window // @@ -2370,7 +2371,7 @@ DispatchDeferredCleanup: SDL_DestroyWindow(m_Window); if (iconSurface != nullptr) { - SDL_FreeSurface(iconSurface); + SDL_DestroySurface(iconSurface); } SDL_QuitSubSystem(SDL_INIT_VIDEO); diff --git a/app/streaming/session.h b/app/streaming/session.h index 2bfac441..e624c117 100644 --- a/app/streaming/session.h +++ b/app/streaming/session.h @@ -266,7 +266,7 @@ private: int m_FlushingWindowEventsRef; QList m_LaunchWarnings; - int m_CurrentDisplayIndex; + SDL_DisplayID m_CurrentDisplay; bool m_NeedsFirstEnterCapture; bool m_NeedsPostDecoderCreationCapture; diff --git a/app/streaming/streamutils.cpp b/app/streaming/streamutils.cpp index c8e46fa9..a42b2fcf 100644 --- a/app/streaming/streamutils.cpp +++ b/app/streaming/streamutils.cpp @@ -111,31 +111,22 @@ void StreamUtils::screenSpaceToNormalizedDeviceCoords(SDL_Rect* src, SDL_FRect* int StreamUtils::getDisplayRefreshRate(SDL_Window* window) { - int displayIndex = SDL_GetWindowDisplayIndex(window); - if (displayIndex < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Failed to get current display: %s", - SDL_GetError()); - - // Assume display 0 if it fails - displayIndex = 0; - } - SDL_DisplayMode mode; if (SDLC_IsFullscreenExclusive(window)) { // Use the window display mode for full-screen exclusive mode - if (SDL_GetWindowDisplayMode(window, &mode) != 0) { + const SDL_DisplayMode *fsMode = SDL_GetWindowFullscreenMode(window); + if (fsMode) { + mode = *fsMode; + } + else { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "SDL_GetWindowDisplayMode() failed: %s", + "SDL_GetWindowFullscreenMode() failed: %s", SDL_GetError()); - - // Assume 60 Hz - return 60; } } else { // Use the current display mode for windowed and borderless - if (SDL_GetCurrentDisplayMode(displayIndex, &mode) != 0) { + if (SDL_GetCurrentDisplayMode(SDL_GetDisplayForWindow(window), &mode) != 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GetCurrentDisplayMode() failed: %s", SDL_GetError()); @@ -199,7 +190,7 @@ bool StreamUtils::hasFastAes() #endif } -bool StreamUtils::getNativeDesktopMode(int displayIndex, SDL_DisplayMode* mode, SDL_Rect* safeArea) +bool StreamUtils::getNativeDesktopMode(SDL_DisplayID display, SDL_DisplayMode* mode, SDL_Rect* safeArea) { #ifdef Q_OS_DARWIN #define MAX_DISPLAYS 16 @@ -277,17 +268,13 @@ bool StreamUtils::getNativeDesktopMode(int displayIndex, SDL_DisplayMode* mode, #else SDL_assert(SDL_WasInit(SDL_INIT_VIDEO)); - if (displayIndex >= SDL_GetNumVideoDisplays()) { - return false; - } - // We need to get the true display resolution without DPI scaling (since we use High DPI). // Windows returns the real display resolution here, even if DPI scaling is enabled. // macOS and Wayland report a resolution that includes the DPI scaling factor. Picking // the first mode on Wayland will get the native resolution without the scaling factor // (and macOS is handled in the #ifdef above). if (!strcmp(SDL_GetCurrentVideoDriver(), "wayland")) { - if (SDL_GetDisplayMode(displayIndex, 0, mode) != 0) { + if (SDL_GetDisplayMode(display, 0, mode) != 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GetDisplayMode() failed: %s", SDL_GetError()); @@ -295,7 +282,7 @@ bool StreamUtils::getNativeDesktopMode(int displayIndex, SDL_DisplayMode* mode, } } else { - if (SDL_GetDesktopDisplayMode(displayIndex, mode) != 0) { + if (SDL_GetDesktopDisplayMode(display, mode) != 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GetDesktopDisplayMode() failed: %s", SDL_GetError()); diff --git a/app/streaming/streamutils.h b/app/streaming/streamutils.h index 671ce24c..29c703d9 100644 --- a/app/streaming/streamutils.h +++ b/app/streaming/streamutils.h @@ -18,7 +18,7 @@ public: void screenSpaceToNormalizedDeviceCoords(SDL_Rect* src, SDL_FRect* dst, int viewportWidth, int viewportHeight); static - bool getNativeDesktopMode(int displayIndex, SDL_DisplayMode* mode, SDL_Rect* safeArea); + bool getNativeDesktopMode(SDL_DisplayID display, SDL_DisplayMode* mode, SDL_Rect* safeArea); static int getDisplayRefreshRate(SDL_Window* window); diff --git a/app/streaming/video/ffmpeg-renderers/d3d11va.cpp b/app/streaming/video/ffmpeg-renderers/d3d11va.cpp index 8432b5b0..170b0e54 100644 --- a/app/streaming/video/ffmpeg-renderers/d3d11va.cpp +++ b/app/streaming/video/ffmpeg-renderers/d3d11va.cpp @@ -666,7 +666,7 @@ void D3D11VARenderer::renderFrame(AVFrame* frame) // The card may have been removed or crashed. Reset the decoder. SDL_Event event; - event.type = SDL_RENDER_TARGETS_RESET; + event.type = SDL_EVENT_RENDER_TARGETS_RESET; SDL_PushEvent(&event); return; } diff --git a/app/streaming/video/ffmpeg-renderers/drm.cpp b/app/streaming/video/ffmpeg-renderers/drm.cpp index 814699b6..438d40fe 100644 --- a/app/streaming/video/ffmpeg-renderers/drm.cpp +++ b/app/streaming/video/ffmpeg-renderers/drm.cpp @@ -264,7 +264,7 @@ void DrmRenderer::prepareToRender() // operation that the KMSDRM backend keeps pending until the next // time we swap buffers. We have to do this before we enumerate // CRTC modes below. - SDL_Renderer* renderer = SDL_CreateRenderer(m_Window, -1, SDL_RENDERER_SOFTWARE); + SDL_Renderer* renderer = SDL_CreateRenderer(m_Window, SDLC_DEFAULT_RENDER_DRIVER, SDL_RENDERER_SOFTWARE); if (renderer != nullptr) { // SDL_CreateRenderer() can end up having to recreate our window (SDL_RecreateWindow()) // to ensure it's compatible with the renderer's OpenGL context. If that happens, we diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.cpp b/app/streaming/video/ffmpeg-renderers/dxva2.cpp index 7885b8be..28eb5066 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.cpp +++ b/app/streaming/video/ffmpeg-renderers/dxva2.cpp @@ -1112,7 +1112,7 @@ void DXVA2Renderer::renderFrame(AVFrame *frame) "Clear() failed: %x", hr); SDL_Event event; - event.type = SDL_RENDER_TARGETS_RESET; + event.type = SDL_EVENT_RENDER_TARGETS_RESET; SDL_PushEvent(&event); return; } @@ -1123,7 +1123,7 @@ void DXVA2Renderer::renderFrame(AVFrame *frame) "BeginScene() failed: %x", hr); SDL_Event event; - event.type = SDL_RENDER_TARGETS_RESET; + event.type = SDL_EVENT_RENDER_TARGETS_RESET; SDL_PushEvent(&event); return; } @@ -1149,7 +1149,7 @@ void DXVA2Renderer::renderFrame(AVFrame *frame) "StretchRect() failed: %x", hr); SDL_Event event; - event.type = SDL_RENDER_TARGETS_RESET; + event.type = SDL_EVENT_RENDER_TARGETS_RESET; SDL_PushEvent(&event); return; } @@ -1166,7 +1166,7 @@ void DXVA2Renderer::renderFrame(AVFrame *frame) "EndScene() failed: %x", hr); SDL_Event event; - event.type = SDL_RENDER_TARGETS_RESET; + event.type = SDL_EVENT_RENDER_TARGETS_RESET; SDL_PushEvent(&event); return; } @@ -1184,7 +1184,7 @@ void DXVA2Renderer::renderFrame(AVFrame *frame) "PresentEx() failed: %x", hr); SDL_Event event; - event.type = SDL_RENDER_TARGETS_RESET; + event.type = SDL_EVENT_RENDER_TARGETS_RESET; SDL_PushEvent(&event); return; } diff --git a/app/streaming/video/ffmpeg-renderers/eglvid.cpp b/app/streaming/video/ffmpeg-renderers/eglvid.cpp index d40d2c85..270c2e70 100644 --- a/app/streaming/video/ffmpeg-renderers/eglvid.cpp +++ b/app/streaming/video/ffmpeg-renderers/eglvid.cpp @@ -162,7 +162,7 @@ void EGLRenderer::notifyOverlayUpdated(Overlay::OverlayType type) if (!Session::get()->getOverlayManager().isOverlayEnabled(type)) { // If the overlay has been disabled, mark the data as invalid/stale. - SDL_AtomicSet(&m_OverlayHasValidData[type], 0); + SDL_SetAtomicInt(&m_OverlayHasValidData[type], 0); return; } } @@ -211,7 +211,7 @@ void EGLRenderer::renderOverlay(Overlay::OverlayType type, int viewportWidth, in // we must allocate a tightly packed buffer and copy our pixels there. packedPixelData = malloc(newSurface->w * newSurface->h * newSurface->format->BytesPerPixel); if (!packedPixelData) { - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); return; } @@ -247,7 +247,7 @@ void EGLRenderer::renderOverlay(Overlay::OverlayType type, int viewportWidth, in overlayRect.w = newSurface->w; overlayRect.h = newSurface->h; - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); // Convert screen space to normalized device coordinates StreamUtils::screenSpaceToNormalizedDeviceCoords(&overlayRect, viewportWidth, viewportHeight); @@ -265,10 +265,10 @@ void EGLRenderer::renderOverlay(Overlay::OverlayType type, int viewportWidth, in glBindBuffer(GL_ARRAY_BUFFER, m_OverlayVbos[type]); glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); - SDL_AtomicSet(&m_OverlayHasValidData[type], 1); + SDL_SetAtomicInt(&m_OverlayHasValidData[type], 1); } - if (!SDL_AtomicGet(&m_OverlayHasValidData[type])) { + if (!SDL_GetAtomicInt(&m_OverlayHasValidData[type])) { // If the overlay is not populated yet or is stale, don't render it. return; } @@ -435,6 +435,9 @@ bool EGLRenderer::initialize(PDECODER_PARAMETERS params) SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); +#if SDL_VERSION_ATLEAST(3, 0, 0) + m_DummyRenderer = SDL_CreateRenderer(m_Window, "opengles2", SDL_RENDERER_ACCELERATED); +#else int renderIndex; int maxRenderers = SDL_GetNumRenderDrivers(); SDL_assert(maxRenderers >= 0); @@ -454,6 +457,7 @@ bool EGLRenderer::initialize(PDECODER_PARAMETERS params) } m_DummyRenderer = SDL_CreateRenderer(m_Window, renderIndex, SDL_RENDERER_ACCELERATED); +#endif if (!m_DummyRenderer) { // Print the error here (before it gets clobbered), but ensure that we flush window // events just in case SDL re-created the window before eventually failing. @@ -638,7 +642,7 @@ bool EGLRenderer::initialize(PDECODER_PARAMETERS params) // If we got a working GL implementation via EGL, avoid using GLX from now on. // GLX will cause problems if we later want to use EGL again on this window. SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "EGL passed preflight checks. Using EGL for GL context creation."); - SDL_SetHint(SDL_HINT_VIDEO_X11_FORCE_EGL, "1"); + SDL_SetHint(SDL_HINT_VIDEO_FORCE_EGL, "1"); } return err == GL_NO_ERROR; @@ -822,7 +826,7 @@ void EGLRenderer::renderFrame(AVFrame* frame) // XWayland. Other strategies like calling glGetError() don't seem // to be able to detect this situation for some reason. SDL_Event event; - event.type = SDL_RENDER_TARGETS_RESET; + event.type = SDL_EVENT_RENDER_TARGETS_RESET; SDL_PushEvent(&event); return; @@ -841,7 +845,11 @@ void EGLRenderer::renderFrame(AVFrame* frame) glClear(GL_COLOR_BUFFER_BIT); int drawableWidth, drawableHeight; +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_GetWindowSizeInPixels(m_Window, &drawableWidth, &drawableHeight); +#else SDL_GL_GetDrawableSize(m_Window, &drawableWidth, &drawableHeight); +#endif // Set the viewport to the size of the aspect-ratio-scaled video SDL_Rect src, dst; diff --git a/app/streaming/video/ffmpeg-renderers/mmal.cpp b/app/streaming/video/ffmpeg-renderers/mmal.cpp index ea8fb650..d66880b2 100644 --- a/app/streaming/video/ffmpeg-renderers/mmal.cpp +++ b/app/streaming/video/ffmpeg-renderers/mmal.cpp @@ -56,7 +56,7 @@ void MmalRenderer::prepareToRender() { // Create a renderer and draw a black background for the area not covered by the MMAL overlay. // On the KMSDRM backend, this triggers the modeset that puts the CRTC into the mode we selected. - m_BackgroundRenderer = SDL_CreateRenderer(m_Window, -1, SDL_RENDERER_SOFTWARE); + m_BackgroundRenderer = SDL_CreateRenderer(m_Window, SDLC_DEFAULT_RENDER_DRIVER, SDL_RENDERER_SOFTWARE); if (m_BackgroundRenderer == nullptr) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateRenderer() failed: %s", diff --git a/app/streaming/video/ffmpeg-renderers/pacer/pacer.cpp b/app/streaming/video/ffmpeg-renderers/pacer/pacer.cpp index 29684e98..490c008a 100644 --- a/app/streaming/video/ffmpeg-renderers/pacer/pacer.cpp +++ b/app/streaming/video/ffmpeg-renderers/pacer/pacer.cpp @@ -98,11 +98,7 @@ int Pacer::vsyncThread(void *context) { Pacer* me = reinterpret_cast(context); -#if SDL_VERSION_ATLEAST(2, 0, 9) - SDL_SetThreadPriority(SDL_THREAD_PRIORITY_TIME_CRITICAL); -#else - SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); -#endif + SDL_SetCurrentThreadPriority(SDL_THREAD_PRIORITY_TIME_CRITICAL); bool async = me->m_VsyncSource->isAsync(); while (!me->m_Stopping) { @@ -131,7 +127,7 @@ int Pacer::renderThread(void* context) { Pacer* me = reinterpret_cast(context); - if (SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH) < 0) { + if (!SDL_SetCurrentThreadPriority(SDL_THREAD_PRIORITY_HIGH)) { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Unable to set render thread to high priority: %s", SDL_GetError()); @@ -183,7 +179,7 @@ void Pacer::enqueueFrameForRenderingAndUnlock(AVFrame *frame) SDL_Event event; // For main thread rendering, we'll push an event to trigger a callback - event.type = SDL_USEREVENT; + event.type = SDL_EVENT_USER; event.user.code = SDL_CODE_FRAME_READY; SDL_PushEvent(&event); } diff --git a/app/streaming/video/ffmpeg-renderers/plvk.cpp b/app/streaming/video/ffmpeg-renderers/plvk.cpp index 4546be7c..c41a9514 100644 --- a/app/streaming/video/ffmpeg-renderers/plvk.cpp +++ b/app/streaming/video/ffmpeg-renderers/plvk.cpp @@ -95,7 +95,7 @@ void PlVkRenderer::unlockQueue(struct AVHWDeviceContext *dev_ctx, uint32_t queue void PlVkRenderer::overlayUploadComplete(void* opaque) { - SDL_FreeSurface((SDL_Surface*)opaque); + SDL_DestroySurface((SDL_Surface*)opaque); } PlVkRenderer::PlVkRenderer(bool hwaccel, IFFmpegRenderer *backendRenderer) : @@ -362,7 +362,11 @@ bool PlVkRenderer::initialize(PDECODER_PARAMETERS params) m_Window = params->window; unsigned int instanceExtensionCount = 0; +#if SDL_VERSION_ATLEAST(3, 0, 0) + if (!SDL_Vulkan_GetInstanceExtensions(&instanceExtensionCount, nullptr)) { +#else if (!SDL_Vulkan_GetInstanceExtensions(params->window, &instanceExtensionCount, nullptr)) { +#endif SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_GetInstanceExtensions() #1 failed: %s", SDL_GetError()); @@ -370,7 +374,11 @@ bool PlVkRenderer::initialize(PDECODER_PARAMETERS params) } std::vector instanceExtensions(instanceExtensionCount); +#if SDL_VERSION_ATLEAST(3, 0, 0) + if (!SDL_Vulkan_GetInstanceExtensions(&instanceExtensionCount, instanceExtensions.data())) { +#else if (!SDL_Vulkan_GetInstanceExtensions(params->window, &instanceExtensionCount, instanceExtensions.data())) { +#endif SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_GetInstanceExtensions() #2 failed: %s", SDL_GetError()); @@ -402,7 +410,11 @@ bool PlVkRenderer::initialize(PDECODER_PARAMETERS params) POPULATE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR); POPULATE_FUNCTION(vkEnumerateDeviceExtensionProperties); +#if SDL_VERSION_ATLEAST(3, 0, 0) + if (!SDL_Vulkan_CreateSurface(params->window, m_PlVkInstance->instance, NULL, &m_VkSurface)) { +#else if (!SDL_Vulkan_CreateSurface(params->window, m_PlVkInstance->instance, &m_VkSurface)) { +#endif SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_CreateSurface() failed: %s", SDL_GetError()); @@ -703,7 +715,7 @@ void PlVkRenderer::waitToRender() SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "GPU is in failed state. Recreating renderer."); SDL_Event event; - event.type = SDL_RENDER_DEVICE_RESET; + event.type = SDL_EVENT_RENDER_DEVICE_RESET; SDL_PushEvent(&event); return; } @@ -721,7 +733,11 @@ void PlVkRenderer::waitToRender() // Handle the swapchain being resized int vkDrawableW, vkDrawableH; +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_GetWindowSizeInPixels(m_Window, &vkDrawableW, &vkDrawableH); +#else SDL_Vulkan_GetDrawableSize(m_Window, &vkDrawableW, &vkDrawableH); +#endif if (!pl_swapchain_resize(m_Swapchain, &vkDrawableW, &vkDrawableH)) { // Swapchain (re)creation can fail if the window is occluded return; @@ -905,12 +921,12 @@ void PlVkRenderer::notifyOverlayUpdated(Overlay::OverlayType type) return; } - SDL_AtomicLock(&m_OverlayLock); + SDL_LockSpinlock(&m_OverlayLock); // We want to clear the staging overlay flag even if a staging overlay is still present, // since this ensures the render thread will not read from a partially initialized pl_tex // as we modify or recreate the staging overlay texture outside the overlay lock. m_Overlays[type].hasStagingOverlay = false; - SDL_AtomicUnlock(&m_OverlayLock); + SDL_UnlockSpinlock(&m_OverlayLock); // If there's no new staging overlay, free the old staging overlay texture. // NB: This is safe to do outside the overlay lock because we're guaranteed @@ -925,7 +941,7 @@ void PlVkRenderer::notifyOverlayUpdated(Overlay::OverlayType type) SDL_assert(newSurface->format->format == SDL_PIXELFORMAT_ARGB8888); pl_fmt texFormat = pl_find_named_fmt(m_Vulkan->gpu, "bgra8"); if (!texFormat) { - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "pl_find_named_fmt(bgra8) failed"); return; @@ -945,7 +961,7 @@ void PlVkRenderer::notifyOverlayUpdated(Overlay::OverlayType type) if (!pl_tex_recreate(m_Vulkan->gpu, &m_Overlays[type].stagingOverlay.tex, &texParams)) { pl_tex_destroy(m_Vulkan->gpu, &m_Overlays[type].stagingOverlay.tex); SDL_zero(m_Overlays[type].stagingOverlay); - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "pl_tex_recreate() failed"); return; @@ -962,7 +978,7 @@ void PlVkRenderer::notifyOverlayUpdated(Overlay::OverlayType type) if (!pl_tex_upload(m_Vulkan->gpu, &xferParams)) { pl_tex_destroy(m_Vulkan->gpu, &m_Overlays[type].stagingOverlay.tex); SDL_zero(m_Overlays[type].stagingOverlay); - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "pl_tex_upload() failed"); return; @@ -978,10 +994,10 @@ void PlVkRenderer::notifyOverlayUpdated(Overlay::OverlayType type) m_Overlays[type].stagingOverlay.color = pl_color_space_srgb; // Make this staging overlay visible to the render thread - SDL_AtomicLock(&m_OverlayLock); + SDL_LockSpinlock(&m_OverlayLock); SDL_assert(!m_Overlays[type].hasStagingOverlay); m_Overlays[type].hasStagingOverlay = true; - SDL_AtomicUnlock(&m_OverlayLock); + SDL_UnlockSpinlock(&m_OverlayLock); } bool PlVkRenderer::notifyWindowChanged(PWINDOW_STATE_CHANGE_INFO info) diff --git a/app/streaming/video/ffmpeg-renderers/sdlvid.cpp b/app/streaming/video/ffmpeg-renderers/sdlvid.cpp index c94f8889..67c6da03 100644 --- a/app/streaming/video/ffmpeg-renderers/sdlvid.cpp +++ b/app/streaming/video/ffmpeg-renderers/sdlvid.cpp @@ -169,7 +169,7 @@ bool SdlRenderer::initialize(PDECODER_PARAMETERS params) SDL_SetHintWithPriority(SDL_HINT_RENDER_DIRECT3D_THREADSAFE, "1", SDL_HINT_OVERRIDE); #endif - m_Renderer = SDL_CreateRenderer(params->window, -1, rendererFlags); + m_Renderer = SDL_CreateRenderer(params->window, SDLC_DEFAULT_RENDER_DRIVER, rendererFlags); if (!m_Renderer) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateRenderer() failed: %s", @@ -221,7 +221,7 @@ void SdlRenderer::renderOverlay(Overlay::OverlayType type) if (type == Overlay::OverlayStatusUpdate) { // Bottom Left SDL_Rect viewportRect; - SDL_RenderGetViewport(m_Renderer, &viewportRect); + SDL_GetRenderViewport(m_Renderer, &viewportRect); m_OverlayRects[type].x = 0; m_OverlayRects[type].y = viewportRect.h - newSurface->h; } @@ -235,12 +235,12 @@ void SdlRenderer::renderOverlay(Overlay::OverlayType type) m_OverlayRects[type].h = newSurface->h; m_OverlayTextures[type] = SDL_CreateTextureFromSurface(m_Renderer, newSurface); - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); } // If we have an overlay texture, render it too if (m_OverlayTextures[type] != nullptr) { - SDL_RenderCopy(m_Renderer, m_OverlayTextures[type], nullptr, &m_OverlayRects[type]); + SDL_RenderTexture(m_Renderer, m_OverlayTextures[type], nullptr, &m_OverlayRects[type]); } } } diff --git a/app/streaming/video/ffmpeg-renderers/vaapi.cpp b/app/streaming/video/ffmpeg-renderers/vaapi.cpp index e73bd441..cd2f9caa 100644 --- a/app/streaming/video/ffmpeg-renderers/vaapi.cpp +++ b/app/streaming/video/ffmpeg-renderers/vaapi.cpp @@ -659,7 +659,7 @@ void VAAPIRenderer::notifyOverlayUpdated(Overlay::OverlayType type) } if (!overlayEnabled) { - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); return; } @@ -673,7 +673,7 @@ void VAAPIRenderer::notifyOverlayUpdated(Overlay::OverlayType type) SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vaCreateImage() failed: %d", status); - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); return; } @@ -683,7 +683,7 @@ void VAAPIRenderer::notifyOverlayUpdated(Overlay::OverlayType type) SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vaMapBuffer() failed: %d", status); - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); vaDestroyImage(vaDeviceContext->display, newImage.image_id); return; } @@ -698,7 +698,7 @@ void VAAPIRenderer::notifyOverlayUpdated(Overlay::OverlayType type) SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vaUnmapBuffer() failed: %d", status); - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); vaDestroyImage(vaDeviceContext->display, newImage.image_id); return; } @@ -720,7 +720,7 @@ void VAAPIRenderer::notifyOverlayUpdated(Overlay::OverlayType type) overlayRect.h = newSurface->h; // Surface data is no longer needed - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); VASubpictureID newSubpicture; status = vaCreateSubpicture(vaDeviceContext->display, newImage.image_id, &newSubpicture); diff --git a/app/streaming/video/ffmpeg-renderers/vdpau.cpp b/app/streaming/video/ffmpeg-renderers/vdpau.cpp index c6e13374..cab54201 100644 --- a/app/streaming/video/ffmpeg-renderers/vdpau.cpp +++ b/app/streaming/video/ffmpeg-renderers/vdpau.cpp @@ -374,7 +374,7 @@ void VDPAURenderer::notifyOverlayUpdated(Overlay::OverlayType type) } if (!overlayEnabled) { - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); return; } @@ -393,7 +393,7 @@ void VDPAURenderer::notifyOverlayUpdated(Overlay::OverlayType type) SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "VdpBitmapSurfaceCreate() failed: %s", m_VdpGetErrorString(status)); - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); return; } @@ -406,7 +406,7 @@ void VDPAURenderer::notifyOverlayUpdated(Overlay::OverlayType type) "VdpBitmapSurfacePutBitsNative() failed: %s", m_VdpGetErrorString(status)); m_VdpBitmapSurfaceDestroy(newBitmapSurface); - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); return; } @@ -427,7 +427,7 @@ void VDPAURenderer::notifyOverlayUpdated(Overlay::OverlayType type) overlayRect.y1 = overlayRect.y0 + newSurface->h; // Surface data is no longer needed - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); SDL_LockMutex(m_OverlayMutex); m_OverlaySurface[type] = newBitmapSurface; @@ -467,7 +467,7 @@ void VDPAURenderer::renderOverlay(VdpOutputSurface destination, Overlay::Overlay return; } - if (SDL_TryLockMutex(m_OverlayMutex) != 0) { + if (!SDL_TryLockMutex(m_OverlayMutex)) { // If the overlay is currently being updated, skip rendering it this frame. return; } diff --git a/app/streaming/video/ffmpeg.cpp b/app/streaming/video/ffmpeg.cpp index c17487e9..b8fe1ef9 100644 --- a/app/streaming/video/ffmpeg.cpp +++ b/app/streaming/video/ffmpeg.cpp @@ -123,7 +123,7 @@ int FFmpegVideoDecoder::getDecoderCapabilities() if (!isHardwareAccelerated()) { // Slice up to 4 times for parallel CPU decoding, once slice per core - int slices = qMin(MAX_SLICES, SDL_GetCPUCount()); + int slices = qMin(MAX_SLICES, SDL_GetNumLogicalCPUCores()); SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Encoder configured for %d slices per frame", slices); @@ -269,10 +269,10 @@ void FFmpegVideoDecoder::reset() // Terminate the decoder thread before doing anything else. // It might be touching things we're about to free. if (m_DecoderThread != nullptr) { - SDL_AtomicSet(&m_DecoderThreadShouldQuit, 1); + SDL_SetAtomicInt(&m_DecoderThreadShouldQuit, 1); LiWakeWaitForVideoFrame(); SDL_WaitThread(m_DecoderThread, NULL); - SDL_AtomicSet(&m_DecoderThreadShouldQuit, 0); + SDL_SetAtomicInt(&m_DecoderThreadShouldQuit, 0); m_DecoderThread = nullptr; } @@ -484,7 +484,7 @@ bool FFmpegVideoDecoder::completeInitialization(const AVCodec* decoder, enum AVP // Enable slice multi-threading for software decoding if (!isHardwareAccelerated()) { m_VideoDecoderCtx->thread_type = FF_THREAD_SLICE; - m_VideoDecoderCtx->thread_count = qMin(MAX_SLICES, SDL_GetCPUCount()); + m_VideoDecoderCtx->thread_count = qMin(MAX_SLICES, SDL_GetNumLogicalCPUCores()); } else { // No threading for HW decode @@ -1608,7 +1608,7 @@ int FFmpegVideoDecoder::decoderThreadProcThunk(void *context) void FFmpegVideoDecoder::decoderThreadProc() { - while (!SDL_AtomicGet(&m_DecoderThreadShouldQuit)) { + while (!SDL_GetAtomicInt(&m_DecoderThreadShouldQuit)) { if (m_FramesIn == m_FramesOut) { VIDEO_FRAME_HANDLE handle; PDECODE_UNIT du; @@ -1736,18 +1736,18 @@ void FFmpegVideoDecoder::decoderThreadProc() "Resetting decoder due to consistent failure"); SDL_Event event; - event.type = SDL_RENDER_DEVICE_RESET; + event.type = SDL_EVENT_RENDER_DEVICE_RESET; SDL_PushEvent(&event); // Don't consume any additional data - SDL_AtomicSet(&m_DecoderThreadShouldQuit, 1); + SDL_SetAtomicInt(&m_DecoderThreadShouldQuit, 1); } // Just in case the error resulted in the loss of the frame, // request an IDR frame to reset our decoder state. LiRequestIdrFrame(); } - } while (err == AVERROR(EAGAIN) && !SDL_AtomicGet(&m_DecoderThreadShouldQuit)); + } while (err == AVERROR(EAGAIN) && !SDL_GetAtomicInt(&m_DecoderThreadShouldQuit)); if (err != 0) { // Free the frame if we failed to submit it @@ -1862,11 +1862,11 @@ int FFmpegVideoDecoder::submitDecodeUnit(PDECODE_UNIT du) "Resetting decoder due to consistent failure"); SDL_Event event; - event.type = SDL_RENDER_DEVICE_RESET; + event.type = SDL_EVENT_RENDER_DEVICE_RESET; SDL_PushEvent(&event); // Don't consume any additional data - SDL_AtomicSet(&m_DecoderThreadShouldQuit, 1); + SDL_SetAtomicInt(&m_DecoderThreadShouldQuit, 1); } return DR_NEED_IDR; diff --git a/app/streaming/video/overlaymanager.cpp b/app/streaming/video/overlaymanager.cpp index 168e5233..5f3e97ae 100644 --- a/app/streaming/video/overlaymanager.cpp +++ b/app/streaming/video/overlaymanager.cpp @@ -133,7 +133,7 @@ void OverlayManager::notifyOverlayUpdated(OverlayType type) } // m_FontData must stay around until the font is closed - m_Overlays[type].font = TTF_OpenFontRW(SDL_RWFromConstMem(m_FontData.constData(), m_FontData.size()), + m_Overlays[type].font = TTF_OpenFontRW(SDL_IOFromConstMem(m_FontData.constData(), m_FontData.size()), 1, m_Overlays[type].fontSize); if (m_Overlays[type].font == nullptr) { @@ -146,11 +146,11 @@ void OverlayManager::notifyOverlayUpdated(OverlayType type) } } - SDL_Surface* oldSurface = (SDL_Surface*)SDL_AtomicSetPtr((void**)&m_Overlays[type].surface, nullptr); + SDL_Surface* oldSurface = (SDL_Surface*) SDL_SetAtomicPointer((void**)&m_Overlays[type].surface, nullptr); // Free the old surface if (oldSurface != nullptr) { - SDL_FreeSurface(oldSurface); + SDL_DestroySurface(oldSurface); } if (m_Overlays[type].enabled) { @@ -159,7 +159,7 @@ void OverlayManager::notifyOverlayUpdated(OverlayType type) m_Overlays[type].text, m_Overlays[type].color, 1024); - SDL_AtomicSetPtr((void**)&m_Overlays[type].surface, surface); + SDL_SetAtomicPointer((void**)&m_Overlays[type].surface, surface); } // Notify the renderer diff --git a/app/streaming/video/slvid.cpp b/app/streaming/video/slvid.cpp index 30829e6f..ea225a79 100644 --- a/app/streaming/video/slvid.cpp +++ b/app/streaming/video/slvid.cpp @@ -195,7 +195,7 @@ void SLVideoDecoder::notifyOverlayUpdated(Overlay::OverlayType type) } if (!overlayEnabled) { - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); return; } @@ -203,7 +203,7 @@ void SLVideoDecoder::notifyOverlayUpdated(Overlay::OverlayType type) if (m_Overlay == nullptr) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SLVideo_CreateOverlay() failed"); - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); return; } @@ -221,7 +221,7 @@ void SLVideoDecoder::notifyOverlayUpdated(Overlay::OverlayType type) SLVideo_SetOverlayDisplayArea(m_Overlay, 0.0f, 1.0f - flHeight, flWidth, flHeight); // We're done with the surface now - SDL_FreeSurface(newSurface); + SDL_DestroySurface(newSurface); // Show the overlay SLVideo_ShowOverlay(m_Overlay); diff --git a/app/wm.cpp b/app/wm.cpp index 68f26d0f..41270495 100644 --- a/app/wm.cpp +++ b/app/wm.cpp @@ -24,10 +24,10 @@ bool WMUtils::isRunningX11() { #ifdef HAS_X11 - static SDL_atomic_t isRunningOnX11; + static SDL_AtomicInt isRunningOnX11; // If the value is not set yet, populate it now. - int val = SDL_AtomicGet(&isRunningOnX11); + int val = SDL_GetAtomicInt(&isRunningOnX11); if (!(val & VALUE_SET)) { Display* display = XOpenDisplay(nullptr); if (display != nullptr) { @@ -38,7 +38,7 @@ bool WMUtils::isRunningX11() // This can race with another thread populating the same data, // but that's no big deal. val = VALUE_SET | ((display != nullptr) ? VALUE_TRUE : 0); - SDL_AtomicSet(&isRunningOnX11, val); + SDL_SetAtomicInt(&isRunningOnX11, val); } return !!(val & VALUE_TRUE); @@ -50,10 +50,10 @@ bool WMUtils::isRunningX11() bool WMUtils::isRunningWayland() { #ifdef HAS_WAYLAND - static SDL_atomic_t isRunningOnWayland; + static SDL_AtomicInt isRunningOnWayland; // If the value is not set yet, populate it now. - int val = SDL_AtomicGet(&isRunningOnWayland); + int val = SDL_GetAtomicInt(&isRunningOnWayland); if (!(val & VALUE_SET)) { struct wl_display* display = wl_display_connect(nullptr); if (display != nullptr) { @@ -64,7 +64,7 @@ bool WMUtils::isRunningWayland() // This can race with another thread populating the same data, // but that's no big deal. val = VALUE_SET | ((display != nullptr) ? VALUE_TRUE : 0); - SDL_AtomicSet(&isRunningOnWayland, val); + SDL_SetAtomicInt(&isRunningOnWayland, val); } return !!(val & VALUE_TRUE);