WIP SDL3 compatibility

This commit is contained in:
Cameron Gutman 2025-01-31 01:13:17 -06:00
parent 5290305944
commit 231a67946d
34 changed files with 772 additions and 497 deletions

View File

@ -255,3 +255,66 @@ void SDLC_FlushWindowEvents(void)
{ {
SDL_FlushEvent(SDL_WINDOWEVENT); 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;
}
}

View File

@ -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. // Include this instead of SDL.h directly.
// //
@ -13,6 +13,43 @@
extern "C" { extern "C" {
#endif #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 // SDL_FRect wasn't added until 2.0.10
#if !SDL_VERSION_ATLEAST(2, 0, 10) #if !SDL_VERSION_ATLEAST(2, 0, 10)
typedef struct SDL_FRect typedef struct SDL_FRect
@ -24,6 +61,10 @@ typedef struct SDL_FRect
} SDL_FRect; } SDL_FRect;
#endif #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 #ifndef SDL_HINT_VIDEO_X11_FORCE_EGL
#define SDL_HINT_VIDEO_X11_FORCE_EGL "SDL_VIDEO_X11_FORCE_EGL" #define SDL_HINT_VIDEO_X11_FORCE_EGL "SDL_VIDEO_X11_FORCE_EGL"
#endif #endif
@ -72,39 +113,190 @@ typedef struct SDL_FRect
#define SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP "SDL_VIDEO_WAYLAND_EMULATE_MOUSE_WARP" #define SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP "SDL_VIDEO_WAYLAND_EMULATE_MOUSE_WARP"
#endif #endif
void* SDLC_Win32_GetHwnd(SDL_Window* window); // SDL3 renamed hints
void* SDLC_MacOS_GetWindow(SDL_Window* window); #define SDL_HINT_VIDEO_FORCE_EGL SDL_HINT_VIDEO_X11_FORCE_EGL
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 { // Events
SDLC_VIDEO_UNKNOWN, #define SDL_EVENT_QUIT SDL_QUIT
SDLC_VIDEO_WIN32, #define SDL_EVENT_CLIPBOARD_UPDATE SDL_CLIPBOARDUPDATE
SDLC_VIDEO_MACOS, #define SDL_EVENT_GAMEPAD_ADDED SDL_CONTROLLERDEVICEADDED
SDLC_VIDEO_X11, #define SDL_EVENT_GAMEPAD_REMAPPED SDL_CONTROLLERDEVICEREMAPPED
SDLC_VIDEO_WAYLAND, #define SDL_EVENT_GAMEPAD_REMOVED SDL_CONTROLLERDEVICEREMOVED
SDLC_VIDEO_KMSDRM, #define SDL_EVENT_GAMEPAD_SENSOR_UPDATE SDL_CONTROLLERSENSORUPDATE
} SDLC_VideoDriver; #define SDL_EVENT_GAMEPAD_BUTTON_DOWN SDL_CONTROLLERBUTTONDOWN
SDLC_VideoDriver SDLC_GetVideoDriver(); #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); #define SDL_EVENT_WINDOW_FOCUS_GAINED SDL_WINDOWEVENT_FOCUS_GAINED
bool SDLC_IsFullscreenExclusive(SDL_Window* window); #define SDL_EVENT_WINDOW_FOCUS_LOST SDL_WINDOWEVENT_FOCUS_LOST
bool SDLC_IsFullscreenDesktop(SDL_Window* window); #define SDL_EVENT_WINDOW_MOUSE_ENTER SDL_WINDOWEVENT_ENTER
void SDLC_EnterFullscreen(SDL_Window* window, bool exclusive); #define SDL_EVENT_WINDOW_MOUSE_LEAVE SDL_WINDOWEVENT_LEAVE
void SDLC_LeaveFullscreen(SDL_Window* window); #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, #define SDL_BUTTON_MASK(x) SDL_BUTTON(x)
int x, int y, int w, int h,
Uint32 requiredFlags,
Uint32 optionalFlags);
void SDLC_FlushWindowEvents(); #define gbutton cbutton
#define SDLC_SUCCESS(x) ((x) == 0) #define gaxis caxis
#define SDLC_FAILURE(x) ((x) != 0) #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 #ifdef __cplusplus
} }

View File

@ -197,15 +197,18 @@ void SystemProperties::refreshDisplaysInternal()
monitorNativeResolutions.clear(); monitorNativeResolutions.clear();
int numDisplays = 0;
SDL_DisplayID *displays = SDL_GetDisplays(&numDisplays);
SDL_DisplayMode bestMode; SDL_DisplayMode bestMode;
for (int displayIndex = 0; displayIndex < SDL_GetNumVideoDisplays(); displayIndex++) { for (int i = 0; i < numDisplays; i++) {
SDL_DisplayMode desktopMode; SDL_DisplayMode desktopMode;
SDL_Rect safeArea; SDL_Rect safeArea;
if (StreamUtils::getNativeDesktopMode(displayIndex, &desktopMode, &safeArea)) { if (StreamUtils::getNativeDesktopMode(displays[i], &desktopMode, &safeArea)) {
if (desktopMode.w <= 8192 && desktopMode.h <= 8192) { if (desktopMode.w <= 8192 && desktopMode.h <= 8192) {
monitorNativeResolutions.insert(displayIndex, QRect(0, 0, desktopMode.w, desktopMode.h)); monitorNativeResolutions.insert(i, QRect(0, 0, desktopMode.w, desktopMode.h));
monitorSafeAreaResolutions.insert(displayIndex, QRect(0, 0, safeArea.w, safeArea.h)); monitorSafeAreaResolutions.insert(i, QRect(0, 0, safeArea.w, safeArea.h));
} }
else { else {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
@ -215,9 +218,10 @@ void SystemProperties::refreshDisplaysInternal()
// Start at desktop mode and work our way up // Start at desktop mode and work our way up
bestMode = desktopMode; 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; 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.w == desktopMode.w && mode.h == desktopMode.h) {
if (mode.refresh_rate > bestMode.refresh_rate) { if (mode.refresh_rate > bestMode.refresh_rate) {
bestMode = mode; bestMode = mode;
@ -240,5 +244,6 @@ void SystemProperties::refreshDisplaysInternal()
} }
} }
SDL_free(displays);
SDL_QuitSubSystem(SDL_INIT_VIDEO); SDL_QuitSubSystem(SDL_INIT_VIDEO);
} }

View File

@ -37,7 +37,7 @@ void SdlGamepadKeyNavigation::enable()
// arrival events. Additionally, there's a race condition between // arrival events. Additionally, there's a race condition between
// our QML objects being destroyed and SDL being deinitialized that // our QML objects being destroyed and SDL being deinitialized that
// this solves too. // 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_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) failed: %s", "SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) failed: %s",
SDL_GetError()); SDL_GetError());
@ -52,18 +52,18 @@ void SdlGamepadKeyNavigation::enable()
// overlapping lifetimes of SdlGamepadKeyNavigation instances, so we // overlapping lifetimes of SdlGamepadKeyNavigation instances, so we
// will attach ourselves. // will attach ourselves.
SDL_PumpEvents(); SDL_PumpEvents();
SDL_FlushEvent(SDL_CONTROLLERDEVICEADDED); SDL_FlushEvent(SDL_EVENT_GAMEPAD_ADDED);
// Open all currently attached game controllers // Open all currently attached game controllers
int numJoysticks = SDL_NumJoysticks(); int numGamepads = 0;
for (int i = 0; i < numJoysticks; i++) { SDL_JoystickID* gamepads = SDL_GetGamepads(&numGamepads);
if (SDL_IsGameController(i)) { for (int i = 0; i < numGamepads; i++) {
SDL_GameController* gc = SDL_GameControllerOpen(i); SDL_Gamepad * gc = SDL_OpenGamepad(i);
if (gc != nullptr) { if (gc != nullptr) {
m_Gamepads.append(gc); m_Gamepads.append(gc);
}
} }
} }
SDL_free(gamepads);
m_Enabled = true; m_Enabled = true;
@ -82,11 +82,11 @@ void SdlGamepadKeyNavigation::disable()
Q_ASSERT(!m_PollingTimer->isActive()); Q_ASSERT(!m_PollingTimer->isActive());
while (!m_Gamepads.isEmpty()) { while (!m_Gamepads.isEmpty()) {
SDL_GameControllerClose(m_Gamepads[0]); SDL_CloseGamepad(m_Gamepads[0]);
m_Gamepads.removeAt(0); m_Gamepads.removeAt(0);
} }
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); SDL_QuitSubSystem(SDL_INIT_GAMEPAD);
} }
void SdlGamepadKeyNavigation::notifyWindowFocus(bool hasFocus) void SdlGamepadKeyNavigation::notifyWindowFocus(bool hasFocus)
@ -103,47 +103,47 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
// stale input data from the stream session (like the quit combo). // stale input data from the stream session (like the quit combo).
if (m_FirstPoll) { if (m_FirstPoll) {
SDL_PumpEvents(); SDL_PumpEvents();
SDL_FlushEvent(SDL_CONTROLLERBUTTONDOWN); SDL_FlushEvent(SDL_EVENT_GAMEPAD_BUTTON_DOWN);
SDL_FlushEvent(SDL_CONTROLLERBUTTONUP); SDL_FlushEvent(SDL_EVENT_GAMEPAD_BUTTON_UP);
m_FirstPoll = false; m_FirstPoll = false;
} }
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
switch (event.type) { switch (event.type) {
case SDL_QUIT: case SDL_EVENT_QUIT :
// SDL may send us a quit event since we initialize // SDL may send us a quit event since we initialize
// the video subsystem on startup. If we get one, // the video subsystem on startup. If we get one,
// forward it on for Qt to take care of. // forward it on for Qt to take care of.
QCoreApplication::instance()->quit(); QCoreApplication::instance()->quit();
break; break;
case SDL_CONTROLLERBUTTONDOWN: case SDL_EVENT_GAMEPAD_BUTTON_DOWN :
case SDL_CONTROLLERBUTTONUP: case SDL_EVENT_GAMEPAD_BUTTON_UP :
{ {
QEvent::Type type = QEvent::Type type =
event.type == SDL_CONTROLLERBUTTONDOWN ? event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN ?
QEvent::Type::KeyPress : QEvent::Type::KeyRelease; QEvent::Type::KeyPress : QEvent::Type::KeyRelease;
// Swap face buttons if needed // Swap face buttons if needed
if (m_Prefs->swapFaceButtons) { if (m_Prefs->swapFaceButtons) {
switch (event.cbutton.button) { switch (event.gbutton.button) {
case SDL_CONTROLLER_BUTTON_A: case SDL_GAMEPAD_BUTTON_SOUTH :
event.cbutton.button = SDL_CONTROLLER_BUTTON_B; event.gbutton.button = SDL_GAMEPAD_BUTTON_EAST;
break; break;
case SDL_CONTROLLER_BUTTON_B: case SDL_GAMEPAD_BUTTON_EAST :
event.cbutton.button = SDL_CONTROLLER_BUTTON_A; event.gbutton.button = SDL_GAMEPAD_BUTTON_SOUTH;
break; break;
case SDL_CONTROLLER_BUTTON_X: case SDL_GAMEPAD_BUTTON_WEST :
event.cbutton.button = SDL_CONTROLLER_BUTTON_Y; event.gbutton.button = SDL_GAMEPAD_BUTTON_NORTH;
break; break;
case SDL_CONTROLLER_BUTTON_Y: case SDL_GAMEPAD_BUTTON_NORTH :
event.cbutton.button = SDL_CONTROLLER_BUTTON_X; event.gbutton.button = SDL_GAMEPAD_BUTTON_WEST;
break; break;
} }
} }
switch (event.cbutton.button) { switch (event.gbutton.button) {
case SDL_CONTROLLER_BUTTON_DPAD_UP: case SDL_GAMEPAD_BUTTON_DPAD_UP :
if (m_UiNavMode) { if (m_UiNavMode) {
// Back-tab // Back-tab
sendKey(type, Qt::Key_Tab, Qt::ShiftModifier); sendKey(type, Qt::Key_Tab, Qt::ShiftModifier);
@ -152,7 +152,7 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
sendKey(type, Qt::Key_Up); sendKey(type, Qt::Key_Up);
} }
break; break;
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: case SDL_GAMEPAD_BUTTON_DPAD_DOWN :
if (m_UiNavMode) { if (m_UiNavMode) {
sendKey(type, Qt::Key_Tab); sendKey(type, Qt::Key_Tab);
} }
@ -160,13 +160,13 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
sendKey(type, Qt::Key_Down); sendKey(type, Qt::Key_Down);
} }
break; break;
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: case SDL_GAMEPAD_BUTTON_DPAD_LEFT :
sendKey(type, Qt::Key_Left); sendKey(type, Qt::Key_Left);
break; break;
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: case SDL_GAMEPAD_BUTTON_DPAD_RIGHT :
sendKey(type, Qt::Key_Right); sendKey(type, Qt::Key_Right);
break; break;
case SDL_CONTROLLER_BUTTON_A: case SDL_GAMEPAD_BUTTON_SOUTH :
if (m_UiNavMode) { if (m_UiNavMode) {
sendKey(type, Qt::Key_Space); sendKey(type, Qt::Key_Space);
} }
@ -174,14 +174,14 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
sendKey(type, Qt::Key_Return); sendKey(type, Qt::Key_Return);
} }
break; break;
case SDL_CONTROLLER_BUTTON_B: case SDL_GAMEPAD_BUTTON_EAST :
sendKey(type, Qt::Key_Escape); sendKey(type, Qt::Key_Escape);
break; break;
case SDL_CONTROLLER_BUTTON_X: case SDL_GAMEPAD_BUTTON_WEST :
sendKey(type, Qt::Key_Menu); sendKey(type, Qt::Key_Menu);
break; break;
case SDL_CONTROLLER_BUTTON_Y: case SDL_GAMEPAD_BUTTON_NORTH :
case SDL_CONTROLLER_BUTTON_START: case SDL_GAMEPAD_BUTTON_START :
// HACK: We use this keycode to inform main.qml // HACK: We use this keycode to inform main.qml
// to show the settings when Key_Menu is handled // to show the settings when Key_Menu is handled
// by the control in focus. // by the control in focus.
@ -192,11 +192,18 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
} }
break; break;
} }
case SDL_CONTROLLERDEVICEADDED: case SDL_EVENT_GAMEPAD_ADDED :
SDL_GameController* gc = SDL_GameControllerOpen(event.cdevice.which); #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) { if (gc != nullptr) {
// SDL_CONTROLLERDEVICEADDED can be reported multiple times for the same // 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 // the SDL_CONTROLLERDEVICEADDED event if an unopened gamepad disappears
// before we've processed the add event. // before we've processed the add event.
if (!m_Gamepads.contains(gc)) { if (!m_Gamepads.contains(gc)) {
@ -204,17 +211,18 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
} }
else { else {
// We already have this game controller open // We already have this game controller open
SDL_GameControllerClose(gc); SDL_CloseGamepad(gc);
} }
} }
#endif
break; break;
} }
} }
// Handle analog sticks by polling // Handle analog sticks by polling
for (auto gc : m_Gamepads) { for (auto gc : m_Gamepads) {
short leftX = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_LEFTX); short leftX = SDL_GetGamepadAxis(gc, SDL_GAMEPAD_AXIS_LEFTX);
short leftY = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_LEFTY); short leftY = SDL_GetGamepadAxis(gc, SDL_GAMEPAD_AXIS_LEFTY);
if (SDL_GetTicks() - m_LastAxisNavigationEventTime < AXIS_NAVIGATION_REPEAT_DELAY) { if (SDL_GetTicks() - m_LastAxisNavigationEventTime < AXIS_NAVIGATION_REPEAT_DELAY) {
// Do nothing // Do nothing
} }
@ -290,12 +298,6 @@ int SdlGamepadKeyNavigation::getConnectedGamepads()
Q_ASSERT(m_Enabled); Q_ASSERT(m_Enabled);
int count = 0; int count = 0;
int numJoysticks = SDL_NumJoysticks(); SDL_free(SDL_GetGamepads(&count));
for (int i = 0; i < numJoysticks; i++) {
if (SDL_IsGameController(i)) {
count++;
}
}
return count; return count;
} }

View File

@ -37,7 +37,7 @@ private slots:
private: private:
StreamingPreferences* m_Prefs; StreamingPreferences* m_Prefs;
QTimer* m_PollingTimer; QTimer* m_PollingTimer;
QList<SDL_GameController*> m_Gamepads; QList<SDL_Gamepad*> m_Gamepads;
bool m_Enabled; bool m_Enabled;
bool m_UiNavMode; bool m_UiNavMode;
bool m_FirstPoll; bool m_FirstPoll;

View File

@ -16,6 +16,7 @@
// See masterhook_internal.c for details. // See masterhook_internal.c for details.
#include "SDL_compat.h" #include "SDL_compat.h"
#include <stdlib.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>

View File

@ -55,7 +55,7 @@ int getSdlFdEntryIndex(bool unused)
// Returns true if the final SDL FD was removed // Returns true if the final SDL FD was removed
bool removeSdlFd(int fd) bool removeSdlFd(int fd)
{ {
SDL_AtomicLock(&g_FdTableLock); SDL_LockSpinlock(&g_FdTableLock);
if (g_SdlDrmMasterFdCount != 0) { if (g_SdlDrmMasterFdCount != 0) {
// Clear the entry for this fd from the table // Clear the entry for this fd from the table
for (int i = 0; i < MAX_SDL_FD_COUNT; i++) { for (int i = 0; i < MAX_SDL_FD_COUNT; i++) {
@ -67,11 +67,11 @@ bool removeSdlFd(int fd)
} }
if (g_SdlDrmMasterFdCount == 0) { if (g_SdlDrmMasterFdCount == 0) {
SDL_AtomicUnlock(&g_FdTableLock); SDL_UnlockSpinlock(&g_FdTableLock);
return true; return true;
} }
} }
SDL_AtomicUnlock(&g_FdTableLock); SDL_UnlockSpinlock(&g_FdTableLock);
return false; return false;
} }
@ -82,12 +82,12 @@ int takeMasterFromSdlFd()
// Since all SDL FDs are actually dups of each other // Since all SDL FDs are actually dups of each other
// we can take master from any one of them. // we can take master from any one of them.
SDL_AtomicLock(&g_FdTableLock); SDL_LockSpinlock(&g_FdTableLock);
int fdIndex = getSdlFdEntryIndex(false); int fdIndex = getSdlFdEntryIndex(false);
if (fdIndex != -1) { if (fdIndex != -1) {
fd = g_SdlDrmMasterFds[fdIndex]; fd = g_SdlDrmMasterFds[fdIndex];
} }
SDL_AtomicUnlock(&g_FdTableLock); SDL_UnlockSpinlock(&g_FdTableLock);
if (fd >= 0 && drmDropMaster(fd) == 0) { if (fd >= 0 && drmDropMaster(fd) == 0) {
return fd; return fd;
@ -126,12 +126,12 @@ int openHook(const char *funcname, const char *pathname, int flags, va_list va)
int allocatedFdIndex; int allocatedFdIndex;
// It is our device. Time to do the magic! // 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 // Get a free index for us to put the new entry
freeFdIndex = getSdlFdEntryIndex(true); freeFdIndex = getSdlFdEntryIndex(true);
if (freeFdIndex < 0) { if (freeFdIndex < 0) {
SDL_AtomicUnlock(&g_FdTableLock); SDL_UnlockSpinlock(&g_FdTableLock);
SDL_assert(freeFdIndex >= 0); SDL_assert(freeFdIndex >= 0);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"No unused SDL FD table entries!"); "No unused SDL FD table entries!");
@ -151,7 +151,7 @@ int openHook(const char *funcname, const char *pathname, int flags, va_list va)
else { else {
// Drop master on Qt's FD so we can pick it up for SDL. // Drop master on Qt's FD so we can pick it up for SDL.
if (drmDropMaster(g_QtDrmMasterFd) < 0) { if (drmDropMaster(g_QtDrmMasterFd) < 0) {
SDL_AtomicUnlock(&g_FdTableLock); SDL_UnlockSpinlock(&g_FdTableLock);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to drop master on Qt DRM FD: %d", "Failed to drop master on Qt DRM FD: %d",
errno); errno);
@ -182,7 +182,7 @@ int openHook(const char *funcname, const char *pathname, int flags, va_list va)
g_SdlDrmMasterFdCount++; g_SdlDrmMasterFdCount++;
} }
SDL_AtomicUnlock(&g_FdTableLock); SDL_UnlockSpinlock(&g_FdTableLock);
} }
} }
} }

View File

@ -174,7 +174,7 @@ void Session::arDecodeAndPlaySample(char* sampleData, int sampleLength)
// of other threads due to severely restricted CPU time available, // of other threads due to severely restricted CPU time available,
// so we will skip it on that platform. // so we will skip it on that platform.
if (s_ActiveSession->m_AudioSampleCount == 0) { 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, SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Unable to set audio thread to high priority: %s", "Unable to set audio thread to high priority: %s",
SDL_GetError()); SDL_GetError());

View File

@ -22,7 +22,7 @@ bool SdlAudioRenderer::prepareForPlayback(const OPUS_MULTISTREAM_CONFIGURATION*
SDL_zero(want); SDL_zero(want);
want.freq = opusConfig->sampleRate; want.freq = opusConfig->sampleRate;
want.format = AUDIO_F32SYS; want.format = SDL_AUDIO_F32;
want.channels = opusConfig->channelCount; want.channels = opusConfig->channelCount;
// On PulseAudio systems, setting a value too small can cause underruns for other // 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()); SDL_GetCurrentAudioDriver());
// Start playback // Start playback
SDL_PauseAudioDevice(m_AudioDevice, 0); SDL_ResumeAudioDevice(m_AudioDevice);
return true; return true;
} }

View File

@ -82,13 +82,13 @@ void SdlInputHandler::handleAbsoluteFingerEvent(SDL_TouchFingerEvent* event)
uint8_t eventType; uint8_t eventType;
switch (event->type) { switch (event->type) {
case SDL_FINGERDOWN: case SDL_EVENT_FINGER_DOWN :
eventType = LI_TOUCH_EVENT_DOWN; eventType = LI_TOUCH_EVENT_DOWN;
break; break;
case SDL_FINGERMOTION: case SDL_EVENT_FINGER_MOTION :
eventType = LI_TOUCH_EVENT_MOVE; eventType = LI_TOUCH_EVENT_MOVE;
break; break;
case SDL_FINGERUP: case SDL_EVENT_FINGER_UP :
eventType = LI_TOUCH_EVENT_UP; eventType = LI_TOUCH_EVENT_UP;
break; break;
default: default:
@ -98,16 +98,16 @@ void SdlInputHandler::handleAbsoluteFingerEvent(SDL_TouchFingerEvent* event)
uint32_t pointerId; uint32_t pointerId;
// If the pointer ID is larger than we can fit, just CRC it and use that as the ID. // 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) #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); pointerId = qChecksum(bav);
#else #else
pointerId = qChecksum((char*)&event->fingerId, sizeof(event->fingerId)); pointerId = qChecksum((char*)&event->fingerID, sizeof(event->fingerID));
#endif #endif
} }
else { 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 // 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(); int numTouchDevices = SDL_GetNumTouchDevices();
for (int i = 0; i < numTouchDevices; i++) { 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); const char* touchName = SDL_GetTouchName(i);
// SDL will report "pen" as the name of pen input devices on Windows. // 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. // dx and dy are deltas from the last touch event, not the first touch down.
// Ignore touch down events with more than one finger // 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; return;
} }
// Ignore touch move and touch up events from the non-primary finger // 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; 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. // 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 || 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) { 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 // 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); 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; m_LastTouchDownEvent = *event;
// Start/restart the long press timer // Start/restart the long press timer
@ -213,7 +213,7 @@ void SdlInputHandler::emulateAbsoluteFingerEvent(SDL_TouchFingerEvent* event)
// Left button down on finger down // Left button down on finger down
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT); LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
} }
else if (event->type == SDL_FINGERUP) { else if (event->type == SDL_EVENT_FINGER_UP) {
m_LastTouchUpEvent = *event; m_LastTouchUpEvent = *event;
// Cancel the long press timer // Cancel the long press timer

View File

@ -188,7 +188,7 @@ Uint32 SdlInputHandler::mouseEmulationTimerCallback(Uint32 interval, void *param
return interval; return interval;
} }
void SdlInputHandler::handleControllerAxisEvent(SDL_ControllerAxisEvent* event) void SdlInputHandler::handleControllerAxisEvent(SDL_GamepadAxisEvent * event)
{ {
SDL_JoystickID gameControllerId = event->which; SDL_JoystickID gameControllerId = event->which;
GamepadState* state = findStateForGamepad(gameControllerId); GamepadState* state = findStateForGamepad(gameControllerId);
@ -201,10 +201,10 @@ void SdlInputHandler::handleControllerAxisEvent(SDL_ControllerAxisEvent* event)
for (;;) { for (;;) {
switch (event->axis) switch (event->axis)
{ {
case SDL_CONTROLLER_AXIS_LEFTX: case SDL_GAMEPAD_AXIS_LEFTX :
state->lsX = event->value; state->lsX = event->value;
break; break;
case SDL_CONTROLLER_AXIS_LEFTY: case SDL_GAMEPAD_AXIS_LEFTY :
// Signed values have one more negative value than // Signed values have one more negative value than
// positive value, so inverting the sign on -32768 // positive value, so inverting the sign on -32768
// could actually cause the value to overflow and // could actually cause the value to overflow and
@ -212,16 +212,16 @@ void SdlInputHandler::handleControllerAxisEvent(SDL_ControllerAxisEvent* event)
// capping the value at 32767. // capping the value at 32767.
state->lsY = -qMax(event->value, (short)-32767); state->lsY = -qMax(event->value, (short)-32767);
break; break;
case SDL_CONTROLLER_AXIS_RIGHTX: case SDL_GAMEPAD_AXIS_RIGHTX :
state->rsX = event->value; state->rsX = event->value;
break; break;
case SDL_CONTROLLER_AXIS_RIGHTY: case SDL_GAMEPAD_AXIS_RIGHTY :
state->rsY = -qMax(event->value, (short)-32767); state->rsY = -qMax(event->value, (short)-32767);
break; break;
case SDL_CONTROLLER_AXIS_TRIGGERLEFT: case SDL_GAMEPAD_AXIS_LEFT_TRIGGER :
state->lt = (unsigned char)(event->value * 255UL / 32767); state->lt = (unsigned char)(event->value * 255UL / 32767);
break; break;
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER :
state->rt = (unsigned char)(event->value * 255UL / 32767); state->rt = (unsigned char)(event->value * 255UL / 32767);
break; break;
default: default:
@ -232,18 +232,18 @@ void SdlInputHandler::handleControllerAxisEvent(SDL_ControllerAxisEvent* event)
} }
// Check for another event to batch with // 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; break;
} }
event = &nextEvent.caxis; event = &nextEvent.gaxis;
if (event->which != gameControllerId) { if (event->which != gameControllerId) {
// Stop batching if a different gamepad interrupts us // Stop batching if a different gamepad interrupts us
break; break;
} }
// Remove the next event to batch // 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 // 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)) { if (event->button >= SDL_arraysize(k_ButtonMap)) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
@ -268,53 +268,53 @@ void SdlInputHandler::handleControllerButtonEvent(SDL_ControllerButtonEvent* eve
if (m_SwapFaceButtons) { if (m_SwapFaceButtons) {
switch (event->button) { switch (event->button) {
case SDL_CONTROLLER_BUTTON_A: case SDL_GAMEPAD_BUTTON_SOUTH :
event->button = SDL_CONTROLLER_BUTTON_B; event->button = SDL_GAMEPAD_BUTTON_EAST;
break; break;
case SDL_CONTROLLER_BUTTON_B: case SDL_GAMEPAD_BUTTON_EAST :
event->button = SDL_CONTROLLER_BUTTON_A; event->button = SDL_GAMEPAD_BUTTON_SOUTH;
break; break;
case SDL_CONTROLLER_BUTTON_X: case SDL_GAMEPAD_BUTTON_WEST :
event->button = SDL_CONTROLLER_BUTTON_Y; event->button = SDL_GAMEPAD_BUTTON_NORTH;
break; break;
case SDL_CONTROLLER_BUTTON_Y: case SDL_GAMEPAD_BUTTON_NORTH :
event->button = SDL_CONTROLLER_BUTTON_X; event->button = SDL_GAMEPAD_BUTTON_WEST;
break; break;
} }
} }
if (event->state == SDL_PRESSED) { if (event->state == true) {
state->buttons |= k_ButtonMap[event->button]; state->buttons |= k_ButtonMap[event->button];
if (event->button == SDL_CONTROLLER_BUTTON_START) { if (event->button == SDL_GAMEPAD_BUTTON_START) {
state->lastStartDownTime = SDL_GetTicks(); state->lastStartDownTime = SDL_GetTicks();
} }
else if (state->mouseEmulationTimer != 0) { 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); 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); 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); 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); 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); 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); LiSendScrollEvent(1);
} }
else if (event->button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) { else if (event->button == SDL_GAMEPAD_BUTTON_DPAD_DOWN) {
LiSendScrollEvent(-1); LiSendScrollEvent(-1);
} }
else if (event->button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT) { else if (event->button == SDL_GAMEPAD_BUTTON_DPAD_RIGHT) {
LiSendHScrollEvent(1); LiSendHScrollEvent(1);
} }
else if (event->button == SDL_CONTROLLER_BUTTON_DPAD_LEFT) { else if (event->button == SDL_GAMEPAD_BUTTON_DPAD_LEFT) {
LiSendHScrollEvent(-1); LiSendHScrollEvent(-1);
} }
} }
@ -322,7 +322,7 @@ void SdlInputHandler::handleControllerButtonEvent(SDL_ControllerButtonEvent* eve
else { else {
state->buttons &= ~k_ButtonMap[event->button]; 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 (SDL_GetTicks() - state->lastStartDownTime > MOUSE_EMULATION_LONG_PRESS_TIME) {
if (state->mouseEmulationTimer != 0) { if (state->mouseEmulationTimer != 0) {
SDL_RemoveTimer(state->mouseEmulationTimer); SDL_RemoveTimer(state->mouseEmulationTimer);
@ -345,19 +345,19 @@ void SdlInputHandler::handleControllerButtonEvent(SDL_ControllerButtonEvent* eve
} }
} }
else if (state->mouseEmulationTimer != 0) { 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); 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); 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); 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); 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); LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_X2);
} }
} }
@ -370,7 +370,7 @@ void SdlInputHandler::handleControllerButtonEvent(SDL_ControllerButtonEvent* eve
// Push a quit event to the main loop // Push a quit event to the main loop
SDL_Event event; SDL_Event event;
event.type = SDL_QUIT; event.type = SDL_EVENT_QUIT;
event.quit.timestamp = SDL_GetTicks(); event.quit.timestamp = SDL_GetTicks();
SDL_PushEvent(&event); SDL_PushEvent(&event);
@ -403,7 +403,7 @@ void SdlInputHandler::handleControllerButtonEvent(SDL_ControllerButtonEvent* eve
#if SDL_VERSION_ATLEAST(2, 0, 14) #if SDL_VERSION_ATLEAST(2, 0, 14)
void SdlInputHandler::handleControllerSensorEvent(SDL_ControllerSensorEvent* event) void SdlInputHandler::handleControllerSensorEvent(SDL_GamepadSensorEvent * event)
{ {
GamepadState* state = findStateForGamepad(event->which); GamepadState* state = findStateForGamepad(event->which);
if (state == NULL) { 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); GamepadState* state = findStateForGamepad(event->which);
if (state == NULL) { if (state == NULL) {
@ -447,13 +447,13 @@ void SdlInputHandler::handleControllerTouchpadEvent(SDL_ControllerTouchpadEvent*
uint8_t eventType; uint8_t eventType;
switch (event->type) { switch (event->type) {
case SDL_CONTROLLERTOUCHPADDOWN: case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN :
eventType = LI_TOUCH_EVENT_DOWN; eventType = LI_TOUCH_EVENT_DOWN;
break; break;
case SDL_CONTROLLERTOUCHPADUP: case SDL_EVENT_GAMEPAD_TOUCHPAD_UP :
eventType = LI_TOUCH_EVENT_UP; eventType = LI_TOUCH_EVENT_UP;
break; break;
case SDL_CONTROLLERTOUCHPADMOTION: case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION :
eventType = LI_TOUCH_EVENT_MOVE; eventType = LI_TOUCH_EVENT_MOVE;
break; break;
default: default:
@ -479,18 +479,21 @@ void SdlInputHandler::handleJoystickBatteryEvent(SDL_JoyBatteryEvent* event)
#endif #endif
void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* event) void SdlInputHandler::handleControllerDeviceEvent(SDL_GamepadDeviceEvent * event)
{ {
GamepadState* state; GamepadState* state;
if (event->type == SDL_CONTROLLERDEVICEADDED) { if (event->type == SDL_EVENT_GAMEPAD_ADDED) {
int i; int i;
const char* name; const char* name;
SDL_GameController* controller; SDL_Gamepad * controller;
const char* mapping; const char* mapping;
char guidStr[33]; char guidStr[33];
uint32_t hapticCaps; uint32_t hapticCaps;
#if SDL_VERSION_ATLEAST(3, 0, 0)
controller = SDL_OpenGamepad(event->which);
#else
controller = SDL_GameControllerOpen(event->which); controller = SDL_GameControllerOpen(event->which);
if (controller == NULL) { if (controller == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, 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 // 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 // the SDL_CONTROLLERDEVICEADDED event if an unopened gamepad disappears
// before we've processed the add event. // before we've processed the add event.
for (int i = 0; i < MAX_GAMEPADS; i++) { for (int i = 0; i < MAX_GAMEPADS; i++) {
@ -508,10 +511,11 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Received duplicate add event for controller index: %d", "Received duplicate add event for controller index: %d",
event->which); event->which);
SDL_GameControllerClose(controller); SDL_CloseGamepad(controller);
return; return;
} }
} }
#endif
// We used to use SDL_GameControllerGetPlayerIndex() here but that // We used to use SDL_GameControllerGetPlayerIndex() here but that
// can lead to strange issues due to bugs in Windows where an Xbox // 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) { if (i == MAX_GAMEPADS) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"No open gamepad slots found!"); "No open gamepad slots found!");
SDL_GameControllerClose(controller); SDL_CloseGamepad(controller);
return; return;
} }
SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(controller)), SDL_JoystickGetGUIDString(SDL_GetJoystickGUID(SDL_GetGamepadJoystick(controller)),
guidStr, sizeof(guidStr)); guidStr, sizeof(guidStr));
if (m_IgnoreDeviceGuids.contains(guidStr, Qt::CaseInsensitive)) if (m_IgnoreDeviceGuids.contains(guidStr, Qt::CaseInsensitive))
{ {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Skipping ignored device with GUID: %s", "Skipping ignored device with GUID: %s",
guidStr); guidStr);
SDL_GameControllerClose(controller); SDL_CloseGamepad(controller);
return; return;
} }
@ -554,7 +558,7 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve
// This will change indicators on the controller to show the assigned // This will change indicators on the controller to show the assigned
// player index. For Xbox 360 controllers, that means updating the LED // player index. For Xbox 360 controllers, that means updating the LED
// ring to light up the corresponding quadrant for this player. // ring to light up the corresponding quadrant for this player.
SDL_GameControllerSetPlayerIndex(controller, state->index); SDL_SetGamepadPlayerIndex(controller, state->index);
#endif #endif
} }
else { else {
@ -563,7 +567,7 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve
} }
state->controller = controller; state->controller = controller;
state->jsId = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(state->controller)); state->jsId = SDL_GetJoystickID(SDL_GetGamepadJoystick(state->controller));
hapticCaps = 0; hapticCaps = 0;
#if SDL_VERSION_ATLEAST(2, 0, 18) #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. // 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 // 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. // 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) #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 #endif
#else #else
state->haptic = SDL_HapticOpenFromJoystick(SDL_GameControllerGetJoystick(state->controller)); state->haptic = SDL_HapticOpenFromJoystick(SDL_GameControllerGetJoystick(state->controller));
@ -606,11 +610,11 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve
} }
#endif #endif
mapping = SDL_GameControllerMapping(state->controller); mapping = SDL_GetGamepadMapping(state->controller);
name = SDL_GameControllerName(state->controller); name = SDL_GetGamepadName(state->controller);
uint16_t vendorId = SDL_GameControllerGetVendor(state->controller); uint16_t vendorId = SDL_GetGamepadVendor(state->controller);
uint16_t productId = SDL_GameControllerGetProduct(state->controller); uint16_t productId = SDL_GetGamepadProduct(state->controller);
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, 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)", "Gamepad %d (player %d) is: %s (VID/PID: 0x%.4x/0x%.4x) (haptic capabilities: 0x%x) (mapping: %s -> %s)",
i, i,
@ -636,21 +640,21 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve
SDL_assert(m_GamepadMask == 0x1); 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) #if SDL_VERSION_ATLEAST(2, 0, 14)
// On SDL 2.0.14 and later, we can provide enhanced controller information to the host PC // 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. // for it to use as a hint for the type of controller to emulate.
uint32_t supportedButtonFlags = 0; uint32_t supportedButtonFlags = 0;
for (int i = 0; i < (int)SDL_arraysize(k_ButtonMap); i++) { 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]; supportedButtonFlags |= k_ButtonMap[i];
} }
} }
uint32_t capabilities = 0; uint32_t capabilities = 0;
if (SDL_GameControllerGetBindForAxis(state->controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT).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_CONTROLLER_AXIS_TRIGGERRIGHT).bindType == SDL_CONTROLLER_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 // We assume these are analog triggers if the binding is to an axis rather than a button
capabilities |= LI_CCAP_ANALOG_TRIGGERS; capabilities |= LI_CCAP_ANALOG_TRIGGERS;
} }
@ -660,13 +664,13 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve
if (hapticCaps & ML_HAPTIC_GC_TRIGGER_RUMBLE) { if (hapticCaps & ML_HAPTIC_GC_TRIGGER_RUMBLE) {
capabilities |= LI_CCAP_TRIGGER_RUMBLE; capabilities |= LI_CCAP_TRIGGER_RUMBLE;
} }
if (SDL_GameControllerGetNumTouchpads(state->controller) > 0) { if (SDL_GetNumGamepadTouchpads(state->controller) > 0) {
capabilities |= LI_CCAP_TOUCHPAD; capabilities |= LI_CCAP_TOUCHPAD;
} }
if (SDL_GameControllerHasSensor(state->controller, SDL_SENSOR_ACCEL)) { if (SDL_GamepadHasSensor(state->controller, SDL_SENSOR_ACCEL)) {
capabilities |= LI_CCAP_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; capabilities |= LI_CCAP_GYRO;
} }
if (powerLevel != SDL_JOYSTICK_POWER_UNKNOWN || SDL_VERSION_ATLEAST(2, 24, 0)) { 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; uint8_t type;
switch (SDL_GameControllerGetType(state->controller)) { switch (SDL_GetGamepadType(state->controller)) {
case SDL_CONTROLLER_TYPE_XBOX360: case SDL_GAMEPAD_TYPE_XBOX360 :
case SDL_CONTROLLER_TYPE_XBOXONE: case SDL_GAMEPAD_TYPE_XBOXONE :
type = LI_CTYPE_XBOX; type = LI_CTYPE_XBOX;
break; break;
case SDL_CONTROLLER_TYPE_PS3: case SDL_GAMEPAD_TYPE_PS3 :
case SDL_CONTROLLER_TYPE_PS4: case SDL_GAMEPAD_TYPE_PS4 :
case SDL_CONTROLLER_TYPE_PS5: case SDL_GAMEPAD_TYPE_PS5 :
type = LI_CTYPE_PS; type = LI_CTYPE_PS;
break; break;
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO :
#if SDL_VERSION_ATLEAST(2, 24, 0) #if SDL_VERSION_ATLEAST(2, 24, 0)
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT: case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT :
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT: case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT :
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR: case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR :
#endif #endif
type = LI_CTYPE_NINTENDO; type = LI_CTYPE_NINTENDO;
break; break;
@ -704,7 +708,7 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve
// we'll allow the Select+PS button combo to act as the touchpad. // we'll allow the Select+PS button combo to act as the touchpad.
state->clickpadButtonEmulationEnabled = state->clickpadButtonEmulationEnabled =
#if SDL_VERSION_ATLEAST(2, 0, 14) #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 #endif
type == LI_CTYPE_PS; type == LI_CTYPE_PS;
@ -720,7 +724,7 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve
sendGamepadBatteryState(state, powerLevel); sendGamepadBatteryState(state, powerLevel);
} }
} }
else if (event->type == SDL_CONTROLLERDEVICEREMOVED) { else if (event->type == SDL_EVENT_GAMEPAD_REMOVED) {
state = findStateForGamepad(event->which); state = findStateForGamepad(event->which);
if (state != NULL) { if (state != NULL) {
if (state->mouseEmulationTimer != 0) { if (state->mouseEmulationTimer != 0) {
@ -728,7 +732,7 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve
SDL_RemoveTimer(state->mouseEmulationTimer); SDL_RemoveTimer(state->mouseEmulationTimer);
} }
SDL_GameControllerClose(state->controller); SDL_CloseGamepad(state->controller);
#if !SDL_VERSION_ATLEAST(2, 0, 9) #if !SDL_VERSION_ATLEAST(2, 0, 9)
if (state->haptic != nullptr) { if (state->haptic != nullptr) {
@ -761,24 +765,23 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve
void SdlInputHandler::handleJoystickArrivalEvent(SDL_JoyDeviceEvent* event) 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)) { if (!SDL_IsGamepad(event->which)) {
char guidStr[33]; SDL_Joystick* joy = SDL_OpenJoystick(event->which);
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 : "<UNKNOWN>",
guidStr);
SDL_Joystick* joy = SDL_JoystickOpen(event->which);
if (joy != nullptr) { 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 : "<UNKNOWN>",
guidStr);
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Number of axes: %d | Number of buttons: %d | Number of hats: %d", "Number of axes: %d | Number of buttons: %d | Number of hats: %d",
SDL_JoystickNumAxes(joy), SDL_JoystickNumButtons(joy), SDL_GetNumJoystickAxes(joy), SDL_GetNumJoystickButtons(joy),
SDL_JoystickNumHats(joy)); SDL_GetNumJoystickHats(joy));
SDL_JoystickClose(joy); SDL_CloseJoystick(joy);
} }
else { else {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, 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 SDL_VERSION_ATLEAST(2, 0, 9)
if (m_GamepadState[controllerNumber].controller != nullptr) { 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 #else
// Check if the controller supports haptics (and if the controller exists at all) // 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 SDL_VERSION_ATLEAST(2, 0, 14)
if (m_GamepadState[controllerNumber].controller != nullptr) { 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 #endif
} }
@ -874,12 +877,12 @@ void SdlInputHandler::setMotionEventState(uint16_t controllerNumber, uint8_t mot
switch (motionType) { switch (motionType) {
case LI_MOTION_TYPE_ACCEL: case LI_MOTION_TYPE_ACCEL:
m_GamepadState[controllerNumber].accelReportPeriodMs = reportPeriodMs; 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; break;
case LI_MOTION_TYPE_GYRO: case LI_MOTION_TYPE_GYRO:
m_GamepadState[controllerNumber].gyroReportPeriodMs = reportPeriodMs; 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; break;
} }
} }
@ -895,7 +898,7 @@ void SdlInputHandler::setControllerLED(uint16_t controllerNumber, uint8_t r, uin
#if SDL_VERSION_ATLEAST(2, 0, 14) #if SDL_VERSION_ATLEAST(2, 0, 14)
if (m_GamepadState[controllerNumber].controller != nullptr) { 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 #endif
} }
@ -904,31 +907,32 @@ QString SdlInputHandler::getUnmappedGamepads()
{ {
QString ret; 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_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) failed: %s", "SDL_InitSubSystem(SDL_INIT_GAMEPAD) failed: %s",
SDL_GetError()); SDL_GetError());
} }
MappingManager mappingManager; MappingManager mappingManager;
mappingManager.applyMappings(); mappingManager.applyMappings();
int numJoysticks = SDL_NumJoysticks(); int numJoysticks = 0;
SDL_JoystickID* joysticks = SDL_GetJoysticks(&numJoysticks);
for (int i = 0; i < numJoysticks; i++) { for (int i = 0; i < numJoysticks; i++) {
if (!SDL_IsGameController(i)) { if (!SDL_IsGamepad(joysticks[i])) {
char guidStr[33]; SDL_Joystick* joy = SDL_OpenJoystick(joysticks[i]);
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 : "<UNKNOWN>",
guidStr);
SDL_Joystick* joy = SDL_JoystickOpen(i);
if (joy != nullptr) { if (joy != nullptr) {
int numButtons = SDL_JoystickNumButtons(joy); char guidStr[33];
int numHats = SDL_JoystickNumHats(joy); SDL_GUIDToString(SDL_JoystickGetGUID(joy), guidStr, sizeof(guidStr));
int numAxes = SDL_JoystickNumAxes(joy); const char* name = SDL_JoystickName(joy);
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Unmapped joystick: %s %s",
name ? name : "<UNKNOWN>",
guidStr);
int numButtons = SDL_GetNumJoystickButtons(joy);
int numHats = SDL_GetNumJoystickHats(joy);
int numAxes = SDL_GetNumJoystickAxes(joy);
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Number of axes: %d | Number of buttons: %d | Number of hats: %d", "Number of axes: %d | Number of buttons: %d | Number of hats: %d",
@ -944,7 +948,7 @@ QString SdlInputHandler::getUnmappedGamepads()
ret += name; ret += name;
} }
SDL_JoystickClose(joy); SDL_CloseJoystick(joy);
} }
else { else {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, 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 // Flush stale events so they aren't processed by the main session event loop
SDL_FlushEvents(SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED); SDL_FlushEvents(SDL_EVENT_JOYSTICK_ADDED, SDL_EVENT_JOYSTICK_REMOVED);
SDL_FlushEvents(SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMAPPED); SDL_FlushEvents(SDL_EVENT_GAMEPAD_ADDED, SDL_EVENT_GAMEPAD_REMAPPED);
return ret; return ret;
} }
@ -974,19 +979,17 @@ int SdlInputHandler::getAttachedGamepadMask()
} }
count = mask = 0; count = mask = 0;
int numJoysticks = SDL_NumJoysticks(); int numGamepads = 0;
for (int i = 0; i < numJoysticks; i++) { SDL_JoystickID *gamepads = SDL_GetGamepads(&numGamepads);
if (SDL_IsGameController(i)) { for (int i = 0; i < numGamepads; i++) {
char guidStr[33]; char guidStr[33];
SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(i), SDL_GUIDToString(SDL_GetJoystickGUIDForID(i), guidStr, sizeof(guidStr));
guidStr, sizeof(guidStr));
if (!m_IgnoreDeviceGuids.contains(guidStr, Qt::CaseInsensitive)) if (!m_IgnoreDeviceGuids.contains(guidStr, Qt::CaseInsensitive)) {
{ mask |= (1 << count++);
mask |= (1 << count++);
}
} }
} }
SDL_free(gamepads);
return mask; return mask;
} }

View File

@ -165,10 +165,10 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, int streamWidth, i
// We need to reinit this each time, since you only get // We need to reinit this each time, since you only get
// an initial set of gamepad arrival events once per init. // an initial set of gamepad arrival events once per init.
SDL_assert(!SDL_WasInit(SDL_INIT_GAMECONTROLLER)); SDL_assert(!SDL_WasInit(SDL_INIT_GAMEPAD));
if (SDLC_FAILURE(SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER))) { if (SDLC_FAILURE(SDL_InitSubSystem(SDL_INIT_GAMEPAD))) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) failed: %s", "SDL_InitSubSystem(SDL_INIT_GAMEPAD) failed: %s",
SDL_GetError()); SDL_GetError());
} }
@ -219,8 +219,8 @@ SdlInputHandler::~SdlInputHandler()
SDL_assert(!SDL_WasInit(SDL_INIT_HAPTIC)); SDL_assert(!SDL_WasInit(SDL_INIT_HAPTIC));
#endif #endif
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); SDL_QuitSubSystem(SDL_INIT_GAMEPAD);
SDL_assert(!SDL_WasInit(SDL_INIT_GAMECONTROLLER)); SDL_assert(!SDL_WasInit(SDL_INIT_GAMEPAD));
SDL_QuitSubSystem(SDL_INIT_JOYSTICK); SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
SDL_assert(!SDL_WasInit(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 // NB: Not using SDL_GetGlobalMouseState() because we want our state not the system's
Uint32 mouseState = SDL_GetMouseState(nullptr, nullptr); Uint32 mouseState = SDL_GetMouseState(nullptr, nullptr);
for (Uint32 button = SDL_BUTTON_LEFT; button <= SDL_BUTTON_X2; button++) { 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); SDL_CaptureMouse(SDL_TRUE);
break; break;
} }
@ -388,7 +388,7 @@ void SdlInputHandler::setCaptureActive(bool active)
if (isMouseInVideoRegion(mouseX, mouseY)) { if (isMouseInVideoRegion(mouseX, mouseY)) {
// Synthesize a mouse event to synchronize the cursor // Synthesize a mouse event to synchronize the cursor
SDL_MouseMotionEvent motionEvent = {}; SDL_MouseMotionEvent motionEvent = {};
motionEvent.type = SDL_MOUSEMOTION; motionEvent.type = SDL_EVENT_MOUSE_MOTION;
motionEvent.timestamp = SDL_GetTicks(); motionEvent.timestamp = SDL_GetTicks();
motionEvent.windowID = SDL_GetWindowID(m_Window); motionEvent.windowID = SDL_GetWindowID(m_Window);
motionEvent.x = mouseX; motionEvent.x = mouseX;
@ -418,7 +418,7 @@ void SdlInputHandler::setCaptureActive(bool active)
void SdlInputHandler::handleTouchFingerEvent(SDL_TouchFingerEvent* event) void SdlInputHandler::handleTouchFingerEvent(SDL_TouchFingerEvent* event)
{ {
#if SDL_VERSION_ATLEAST(2, 0, 10) #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 // Ignore anything that isn't a touchscreen. We may get callbacks
// for trackpads, but we want to handle those in the mouse path. // for trackpads, but we want to handle those in the mouse path.
return; return;

View File

@ -6,7 +6,7 @@
#include "SDL_compat.h" #include "SDL_compat.h"
struct GamepadState { struct GamepadState {
SDL_GameController* controller; SDL_Gamepad * controller;
SDL_JoystickID jsId; SDL_JoystickID jsId;
short index; short index;
@ -24,11 +24,11 @@ struct GamepadState {
#if SDL_VERSION_ATLEAST(2, 0, 14) #if SDL_VERSION_ATLEAST(2, 0, 14)
uint8_t gyroReportPeriodMs; uint8_t gyroReportPeriodMs;
float lastGyroEventData[SDL_arraysize(SDL_ControllerSensorEvent::data)]; float lastGyroEventData[SDL_arraysize(SDL_GamepadSensorEvent::data)];
uint32_t lastGyroEventTime; uint32_t lastGyroEventTime;
uint8_t accelReportPeriodMs; uint8_t accelReportPeriodMs;
float lastAccelEventData[SDL_arraysize(SDL_ControllerSensorEvent::data)]; float lastAccelEventData[SDL_arraysize(SDL_GamepadSensorEvent::data)];
uint32_t lastAccelEventTime; uint32_t lastAccelEventTime;
#endif #endif
@ -67,16 +67,16 @@ public:
void handleMouseWheelEvent(SDL_MouseWheelEvent* event); 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) #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 #endif
#if SDL_VERSION_ATLEAST(2, 24, 0) #if SDL_VERSION_ATLEAST(2, 24, 0)

View File

@ -1,6 +1,7 @@
#include "streaming/session.h" #include "streaming/session.h"
#include <Limelight.h> #include <Limelight.h>
#include "SDL_compat.h" #include "SDL_compat.h"
#define VK_0 0x30 #define VK_0 0x30
@ -22,7 +23,7 @@ void SdlInputHandler::performSpecialKeyCombo(KeyCombo combo)
// Push a quit event to the main loop // Push a quit event to the main loop
SDL_Event event; SDL_Event event;
event.type = SDL_QUIT; event.type = SDL_EVENT_QUIT;
event.quit.timestamp = SDL_GetTicks(); event.quit.timestamp = SDL_GetTicks();
SDL_PushEvent(&event); SDL_PushEvent(&event);
break; break;
@ -151,15 +152,15 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
if (event->repeat) { if (event->repeat) {
// Ignore repeat key down events // Ignore repeat key down events
SDL_assert(event->state == SDL_PRESSED); SDL_assert(event->state == true);
return; return;
} }
// Check for our special key combos // Check for our special key combos
if ((event->state == SDL_PRESSED) && if ((event->state == true) &&
(event->keysym.mod & KMOD_CTRL) && (KEY_MOD(event) & SDL_KMOD_CTRL) &&
(event->keysym.mod & KMOD_ALT) && (KEY_MOD(event) & SDL_KMOD_ALT) &&
(event->keysym.mod & KMOD_SHIFT)) { (KEY_MOD(event) & SDL_KMOD_SHIFT)) {
// First we test the SDLK combos for matches, // First we test the SDLK combos for matches,
// that way we ensure that latin keyboard users // that way we ensure that latin keyboard users
// can match to the key they see on their keyboards. // can match to the key they see on their keyboards.
@ -172,14 +173,14 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
// the scancode of another. // the scancode of another.
for (int i = 0; i < KeyComboMax; i++) { 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); performSpecialKeyCombo(m_SpecialKeyCombos[i].keyCombo);
return; return;
} }
} }
for (int i = 0; i < KeyComboMax; i++) { 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); performSpecialKeyCombo(m_SpecialKeyCombos[i].keyCombo);
return; return;
} }
@ -188,16 +189,16 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
// Set modifier flags // Set modifier flags
modifiers = 0; modifiers = 0;
if (event->keysym.mod & KMOD_CTRL) { if (KEY_MOD(event) & SDL_KMOD_CTRL) {
modifiers |= MODIFIER_CTRL; modifiers |= MODIFIER_CTRL;
} }
if (event->keysym.mod & KMOD_ALT) { if (KEY_MOD(event) & SDL_KMOD_ALT) {
modifiers |= MODIFIER_ALT; modifiers |= MODIFIER_ALT;
} }
if (event->keysym.mod & KMOD_SHIFT) { if (KEY_MOD(event) & SDL_KMOD_SHIFT) {
modifiers |= MODIFIER_SHIFT; modifiers |= MODIFIER_SHIFT;
} }
if (event->keysym.mod & KMOD_GUI) { if (KEY_MOD(event) & SDL_KMOD_GUI) {
if (isSystemKeyCaptureActive()) { if (isSystemKeyCaptureActive()) {
modifiers |= MODIFIER_META; 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 // 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 // for AZERTY layouts on the host but it depends on receiving VK_ values matching
// a QWERTY layout to work. // 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 // 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) { else if (KEY_SCANCODE(event) >= SDL_SCANCODE_A && KEY_SCANCODE(event) <= SDL_SCANCODE_Z) {
keyCode = (event->keysym.scancode - SDL_SCANCODE_A) + VK_A; keyCode = (KEY_SCANCODE(event) - SDL_SCANCODE_A) + VK_A;
} }
else if (event->keysym.scancode >= SDL_SCANCODE_F1 && event->keysym.scancode <= SDL_SCANCODE_F12) { else if (KEY_SCANCODE(event) >= SDL_SCANCODE_F1 && KEY_SCANCODE(event) <= SDL_SCANCODE_F12) {
keyCode = (event->keysym.scancode - SDL_SCANCODE_F1) + VK_F1; keyCode = (KEY_SCANCODE(event) - SDL_SCANCODE_F1) + VK_F1;
} }
else if (event->keysym.scancode >= SDL_SCANCODE_F13 && event->keysym.scancode <= SDL_SCANCODE_F24) { else if (KEY_SCANCODE(event) >= SDL_SCANCODE_F13 && KEY_SCANCODE(event) <= SDL_SCANCODE_F24) {
keyCode = (event->keysym.scancode - SDL_SCANCODE_F13) + VK_F13; 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 // 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 { else {
switch (event->keysym.scancode) { switch (KEY_SCANCODE(event)) {
case SDL_SCANCODE_BACKSPACE: case SDL_SCANCODE_BACKSPACE:
keyCode = 0x08; keyCode = 0x08;
break; break;
@ -417,13 +418,13 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
default: default:
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Unhandled button event: %d", "Unhandled button event: %d",
event->keysym.scancode); KEY_SCANCODE(event));
return; return;
} }
} }
// Track the key state so we always know which keys are down // 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); m_KeysDown.insert(keyCode);
} }
else { else {
@ -431,7 +432,7 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
} }
LiSendKeyboardEvent(0x8000 | keyCode, LiSendKeyboardEvent(0x8000 | keyCode,
event->state == SDL_PRESSED ? event->state == true ?
KEY_ACTION_DOWN : KEY_ACTION_UP, KEY_ACTION_DOWN : KEY_ACTION_UP,
modifiers); modifiers);
} }

View File

@ -13,7 +13,7 @@ void SdlInputHandler::handleMouseButtonEvent(SDL_MouseButtonEvent* event)
return; return;
} }
else if (!isCaptureActive()) { 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)) { isMouseInVideoRegion(event->x, event->y)) {
// Capture the mouse again if clicked when unbound. // Capture the mouse again if clicked when unbound.
// We start capture on left button released instead of // We start capture on left button released instead of
@ -26,7 +26,7 @@ void SdlInputHandler::handleMouseButtonEvent(SDL_MouseButtonEvent* event)
// Not capturing // Not capturing
return; 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 // Ignore button presses outside the video region, but allow button releases
return; return;
} }
@ -62,7 +62,7 @@ void SdlInputHandler::handleMouseButtonEvent(SDL_MouseButtonEvent* event)
button = BUTTON_RIGHT; button = BUTTON_RIGHT;
} }
LiSendMouseButtonEvent(event->state == SDL_PRESSED ? LiSendMouseButtonEvent(event->state == true ?
BUTTON_ACTION_PRESS : BUTTON_ACTION_PRESS :
BUTTON_ACTION_RELEASE, BUTTON_ACTION_RELEASE,
button); button);
@ -82,7 +82,7 @@ void SdlInputHandler::handleMouseMotionEvent(SDL_MouseMotionEvent* event)
// Batch all pending mouse motion events to save CPU time // Batch all pending mouse motion events to save CPU time
Sint32 x = event->x, y = event->y, xrel = event->xrel, yrel = event->yrel; Sint32 x = event->x, y = event->y, xrel = event->xrel, yrel = event->yrel;
SDL_Event nextEvent; 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; event = &nextEvent.motion;
// Ignore synthetic mouse events // Ignore synthetic mouse events
@ -175,34 +175,34 @@ void SdlInputHandler::handleMouseWheelEvent(SDL_MouseWheelEvent* event)
} }
#if SDL_VERSION_ATLEAST(2, 0, 18) #if SDL_VERSION_ATLEAST(2, 0, 18)
if (event->preciseY != 0.0f) { if (event->y != 0.0f) {
// Invert the scroll direction if needed // Invert the scroll direction if needed
if (m_ReverseScrollDirection) { if (m_ReverseScrollDirection) {
event->preciseY = -event->preciseY; event->y = -event->y;
} }
#ifdef Q_OS_DARWIN #ifdef Q_OS_DARWIN
// HACK: Clamp the scroll values on macOS to prevent OS scroll acceleration // HACK: Clamp the scroll values on macOS to prevent OS scroll acceleration
// from generating wild scroll deltas when scrolling quickly. // 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 #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 // Invert the scroll direction if needed
if (m_ReverseScrollDirection) { if (m_ReverseScrollDirection) {
event->preciseX = -event->preciseY; event->x = -event->y;
} }
#ifdef Q_OS_DARWIN #ifdef Q_OS_DARWIN
// HACK: Clamp the scroll values on macOS to prevent OS scroll acceleration // HACK: Clamp the scroll values on macOS to prevent OS scroll acceleration
// from generating wild scroll deltas when scrolling quickly. // 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 #endif
LiSendHighResHScrollEvent((short)(event->preciseX * 120)); // WHEEL_DELTA LiSendHighResHScrollEvent((short)(event->x * 120)); // WHEEL_DELTA
} }
#else #else
if (event->y != 0) { if (event->y != 0) {

View File

@ -59,9 +59,9 @@ void SdlInputHandler::handleRelativeFingerEvent(SDL_TouchFingerEvent* event)
// This is also required to handle finger up which // This is also required to handle finger up which
// where the finger will not be in SDL_GetTouchFinger() // where the finger will not be in SDL_GetTouchFinger()
// anymore. // anymore.
if (event->type != SDL_FINGERDOWN) { if (event->type != SDL_EVENT_FINGER_DOWN) {
for (int i = 0; i < MAX_FINGERS; i++) { for (int i = 0; i < MAX_FINGERS; i++) {
if (event->fingerId == m_TouchDownEvent[i].fingerId) { if (event->fingerID == m_TouchDownEvent[i].fingerID) {
fingerIndex = i; fingerIndex = i;
break; break;
} }
@ -70,12 +70,12 @@ void SdlInputHandler::handleRelativeFingerEvent(SDL_TouchFingerEvent* event)
else { else {
// Resolve the new finger by determining the ID of each // Resolve the new finger by determining the ID of each
// finger on the display. // finger on the display.
int numTouchFingers = SDL_GetNumTouchFingers(event->touchId); int numTouchFingers = SDL_GetNumTouchFingers(event->touchID);
for (int i = 0; i < numTouchFingers; i++) { 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); SDL_assert(finger != nullptr);
if (finger != nullptr) { if (finger != nullptr) {
if (finger->id == event->fingerId) { if (finger->id == event->fingerID) {
fingerIndex = i; fingerIndex = i;
break; break;
} }
@ -106,7 +106,7 @@ void SdlInputHandler::handleRelativeFingerEvent(SDL_TouchFingerEvent* event)
// Start a drag timer when primary or secondary // Start a drag timer when primary or secondary
// fingers go down // fingers go down
if (event->type == SDL_FINGERDOWN && if (event->type == SDL_EVENT_FINGER_DOWN &&
(fingerIndex == 0 || fingerIndex == 1)) { (fingerIndex == 0 || fingerIndex == 1)) {
SDL_RemoveTimer(m_DragTimer); SDL_RemoveTimer(m_DragTimer);
m_DragTimer = SDL_AddTimer(DRAG_ACTIVATION_DELAY, m_DragTimer = SDL_AddTimer(DRAG_ACTIVATION_DELAY,
@ -114,7 +114,7 @@ void SdlInputHandler::handleRelativeFingerEvent(SDL_TouchFingerEvent* event)
this); 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 it's outside the deadzone delta, cancel drags and taps
if (qSqrt(qPow(event->x - m_TouchDownEvent[fingerIndex].x, 2) + if (qSqrt(qPow(event->x - m_TouchDownEvent[fingerIndex].x, 2) +
qPow(event->y - m_TouchDownEvent[fingerIndex].y, 2)) > DEAD_ZONE_DELTA) { 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 // Cancel the drag timer on finger up
SDL_RemoveTimer(m_DragTimer); SDL_RemoveTimer(m_DragTimer);
m_DragTimer = 0; 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; m_TouchDownEvent[fingerIndex] = *event;
} }
else if (event->type == SDL_FINGERUP) { else if (event->type == SDL_EVENT_FINGER_UP) {
m_TouchDownEvent[fingerIndex] = {}; m_TouchDownEvent[fingerIndex] = {};
} }
} }

View File

@ -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 // with the removal of game controllers that could result in our game controller
// going away during this callback. // going away during this callback.
SDL_Event rumbleEvent = {}; SDL_Event rumbleEvent = {};
rumbleEvent.type = SDL_USEREVENT; rumbleEvent.type = SDL_EVENT_USER;
rumbleEvent.user.code = SDL_CODE_GAMECONTROLLER_RUMBLE; rumbleEvent.user.code = SDL_CODE_GAMECONTROLLER_RUMBLE;
rumbleEvent.user.data1 = (void*)(uintptr_t)controllerNumber; rumbleEvent.user.data1 = (void*)(uintptr_t)controllerNumber;
rumbleEvent.user.data2 = (void*)(uintptr_t)((lowFreqMotor << 16) | highFreqMotor); 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 // 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 // this callback, we'll drop it. The main thread will make the
// callback when it finishes creating the new decoder. // 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; IVideoDecoder* decoder = s_ActiveSession->m_VideoDecoder;
if (decoder != nullptr) { if (decoder != nullptr) {
decoder->setHdrMode(enabled); 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 // with the removal of game controllers that could result in our game controller
// going away during this callback. // going away during this callback.
SDL_Event rumbleEvent = {}; SDL_Event rumbleEvent = {};
rumbleEvent.type = SDL_USEREVENT; rumbleEvent.type = SDL_EVENT_USER;
rumbleEvent.user.code = SDL_CODE_GAMECONTROLLER_RUMBLE_TRIGGERS; rumbleEvent.user.code = SDL_CODE_GAMECONTROLLER_RUMBLE_TRIGGERS;
rumbleEvent.user.data1 = (void*)(uintptr_t)controllerNumber; rumbleEvent.user.data1 = (void*)(uintptr_t)controllerNumber;
rumbleEvent.user.data2 = (void*)(uintptr_t)((leftTrigger << 16) | rightTrigger); 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 // with the removal of game controllers that could result in our game controller
// going away during this callback. // going away during this callback.
SDL_Event setMotionEventStateEvent = {}; SDL_Event setMotionEventStateEvent = {};
setMotionEventStateEvent.type = SDL_USEREVENT; setMotionEventStateEvent.type = SDL_EVENT_USER;
setMotionEventStateEvent.user.code = SDL_CODE_GAMECONTROLLER_SET_MOTION_EVENT_STATE; setMotionEventStateEvent.user.code = SDL_CODE_GAMECONTROLLER_SET_MOTION_EVENT_STATE;
setMotionEventStateEvent.user.data1 = (void*)(uintptr_t)controllerNumber; setMotionEventStateEvent.user.data1 = (void*)(uintptr_t)controllerNumber;
setMotionEventStateEvent.user.data2 = (void*)(uintptr_t)((motionType << 16) | reportRateHz); 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 // with the removal of game controllers that could result in our game controller
// going away during this callback. // going away during this callback.
SDL_Event setControllerLEDEvent = {}; SDL_Event setControllerLEDEvent = {};
setControllerLEDEvent.type = SDL_USEREVENT; setControllerLEDEvent.type = SDL_EVENT_USER;
setControllerLEDEvent.user.code = SDL_CODE_GAMECONTROLLER_SET_CONTROLLER_LED; setControllerLEDEvent.user.code = SDL_CODE_GAMECONTROLLER_SET_CONTROLLER_LED;
setControllerLEDEvent.user.data1 = (void*)(uintptr_t)controllerNumber; setControllerLEDEvent.user.data1 = (void*)(uintptr_t)controllerNumber;
setControllerLEDEvent.user.data2 = (void*)(uintptr_t)(r << 16 | g << 8 | b); 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 // safely return DR_OK and wait for the IDR frame request by
// the decoder reinitialization code. // the decoder reinitialization code.
if (SDL_AtomicTryLock(&s_ActiveSession->m_DecoderLock)) { if (SDL_TryLockSpinlock(&s_ActiveSession->m_DecoderLock)) {
IVideoDecoder* decoder = s_ActiveSession->m_VideoDecoder; IVideoDecoder* decoder = s_ActiveSession->m_VideoDecoder;
if (decoder != nullptr) { if (decoder != nullptr) {
int ret = decoder->submitDecodeUnit(du); int ret = decoder->submitDecodeUnit(du);
SDL_AtomicUnlock(&s_ActiveSession->m_DecoderLock); SDL_UnlockSpinlock(&s_ActiveSession->m_DecoderLock);
return ret; return ret;
} }
else { else {
SDL_AtomicUnlock(&s_ActiveSession->m_DecoderLock); SDL_UnlockSpinlock(&s_ActiveSession->m_DecoderLock);
return DR_OK; return DR_OK;
} }
} }
@ -550,7 +550,7 @@ Session::Session(NvComputer* computer, NvApp& app, StreamingPreferences *prefere
m_InputHandler(nullptr), m_InputHandler(nullptr),
m_MouseEmulationRefCount(0), m_MouseEmulationRefCount(0),
m_FlushingWindowEventsRef(0), m_FlushingWindowEventsRef(0),
m_CurrentDisplayIndex(-1), m_CurrentDisplay(-1),
m_NeedsFirstEnterCapture(false), m_NeedsFirstEnterCapture(false),
m_NeedsPostDecoderCreationCapture(false), m_NeedsPostDecoderCreationCapture(false),
m_AsyncConnectionSuccess(false), m_AsyncConnectionSuccess(false),
@ -1261,11 +1261,10 @@ private:
void Session::getWindowDimensions(int& x, int& y, void Session::getWindowDimensions(int& x, int& y,
int& width, int& height) int& width, int& height)
{ {
int displayIndex = 0; SDL_DisplayID display = SDL_GetPrimaryDisplay();
if (m_Window != nullptr) { if (m_Window != nullptr) {
displayIndex = SDL_GetWindowDisplayIndex(m_Window); display = SDL_GetDisplayForWindow(m_Window);
SDL_assert(displayIndex >= 0);
} }
// Create our window on the same display that Qt's UI // Create our window on the same display that Qt's UI
// was being displayed on. // was being displayed on.
@ -1279,25 +1278,28 @@ void Session::getWindowDimensions(int& x, int& y,
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Qt UI screen is at (%d,%d)", "Qt UI screen is at (%d,%d)",
displayRect.x(), displayRect.y()); 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; SDL_Rect displayBounds;
if (SDLC_SUCCESS(SDL_GetDisplayBounds(i, &displayBounds))) { if (SDLC_SUCCESS(SDL_GetDisplayBounds(displays[i], &displayBounds))) {
if (displayBounds.x == displayRect.x() && if (displayBounds.x == displayRect.x() &&
displayBounds.y == displayRect.y()) { displayBounds.y == displayRect.y()) {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"SDL found matching display %d", "SDL found matching display %d",
i); displays[i]);
displayIndex = i; display = displays[i];
break; break;
} }
} }
else { else {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"SDL_GetDisplayBounds(%d) failed: %s", "SDL_GetDisplayBounds(%d) failed: %s",
i, SDL_GetError()); displays[i], SDL_GetError());
} }
} }
SDL_free(displays);
} }
else { else {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
@ -1307,7 +1309,7 @@ void Session::getWindowDimensions(int& x, int& y,
} }
SDL_Rect usableBounds; 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 // 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 // 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). // 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; height = m_StreamConfig.height;
} }
x = y = SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex); x = y = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
} }
void Session::updateOptimalWindowDisplayMode() void Session::updateOptimalWindowDisplayMode()
@ -1355,13 +1357,13 @@ void Session::updateOptimalWindowDisplayMode()
// Try the current display mode first. On macOS, this will be the normal // Try the current display mode first. On macOS, this will be the normal
// scaled desktop resolution setting. // scaled desktop resolution setting.
int displayIndex = SDL_GetWindowDisplayIndex(m_Window); SDL_DisplayID display = SDL_GetDisplayForWindow(m_Window);
if (SDL_GetDesktopDisplayMode(displayIndex, &desktopMode) == 0) { if (SDL_GetDesktopDisplayMode(display, &desktopMode) == 0) {
// If this doesn't fit the selected resolution, use the native // If this doesn't fit the selected resolution, use the native
// resolution of the panel (unscaled). // resolution of the panel (unscaled).
if (desktopMode.w < m_ActiveVideoWidth || desktopMode.h < m_ActiveVideoHeight) { if (desktopMode.w < m_ActiveVideoWidth || desktopMode.h < m_ActiveVideoHeight) {
SDL_Rect safeArea; SDL_Rect safeArea;
if (!StreamUtils::getNativeDesktopMode(displayIndex, &desktopMode, &safeArea)) { if (!StreamUtils::getNativeDesktopMode(display, &desktopMode, &safeArea)) {
return; return;
} }
} }
@ -1377,15 +1379,18 @@ void Session::updateOptimalWindowDisplayMode()
// the highest refresh rate that our stream FPS evenly divides. // the highest refresh rate that our stream FPS evenly divides.
bestMode = desktopMode; bestMode = desktopMode;
bestMode.refresh_rate = 0; bestMode.refresh_rate = 0;
for (int i = 0; i < SDL_GetNumDisplayModes(displayIndex); i++) { {
if (SDL_GetDisplayMode(displayIndex, i, &mode) == 0) { int numDisplayModes = SDL_GetNumDisplayModes(display);
if (mode.w == desktopMode.w && mode.h == desktopMode.h && 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) { mode.refresh_rate % m_StreamConfig.fps == 0) {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Found display mode with desktop resolution: %dx%dx%d", "Found display mode with desktop resolution: %dx%dx%d",
mode.w, mode.h, mode.refresh_rate); mode.w, mode.h, mode.refresh_rate);
if (mode.refresh_rate > bestMode.refresh_rate) { if (mode.refresh_rate > bestMode.refresh_rate) {
bestMode = mode; bestMode = mode;
}
} }
} }
} }
@ -1399,8 +1404,9 @@ void Session::updateOptimalWindowDisplayMode()
if (bestMode.refresh_rate == 0) { if (bestMode.refresh_rate == 0) {
float bestModeAspectRatio = 0; float bestModeAspectRatio = 0;
float videoAspectRatio = (float)m_ActiveVideoWidth / (float)m_ActiveVideoHeight; float videoAspectRatio = (float)m_ActiveVideoWidth / (float)m_ActiveVideoHeight;
for (int i = 0; i < SDL_GetNumDisplayModes(displayIndex); i++) { int numDisplayModes = SDL_GetNumDisplayModes(display);
if (SDL_GetDisplayMode(displayIndex, i, &mode) == 0) { for (int i = 0; i < numDisplayModes; i++) {
if (SDL_GetDisplayMode(display, i, &mode) == 0) {
float modeAspectRatio = (float)mode.w / (float)mode.h; float modeAspectRatio = (float)mode.w / (float)mode.h;
if (mode.w >= m_ActiveVideoWidth && mode.h >= m_ActiveVideoHeight && if (mode.w >= m_ActiveVideoWidth && mode.h >= m_ActiveVideoHeight &&
mode.refresh_rate % m_StreamConfig.fps == 0) { mode.refresh_rate % m_StreamConfig.fps == 0) {
@ -1435,7 +1441,7 @@ void Session::updateOptimalWindowDisplayMode()
bestMode.w, bestMode.h, bestMode.refresh_rate); bestMode.w, bestMode.h, bestMode.refresh_rate);
} }
SDL_SetWindowDisplayMode(m_Window, &bestMode); SDL_SetWindowFullscreenMode(m_Window, &bestMode);
} }
void Session::toggleFullscreen() void Session::toggleFullscreen()
@ -1451,10 +1457,10 @@ void Session::toggleFullscreen()
// On Apple Silicon Macs, the AVSampleBufferDisplayLayer may cause WindowServer // On Apple Silicon Macs, the AVSampleBufferDisplayLayer may cause WindowServer
// to deadlock when transitioning out of fullscreen. Destroy the decoder before // to deadlock when transitioning out of fullscreen. Destroy the decoder before
// exiting fullscreen as a workaround. See issue #973. // exiting fullscreen as a workaround. See issue #973.
SDL_AtomicLock(&m_DecoderLock); SDL_LockSpinlock(&m_DecoderLock);
delete m_VideoDecoder; delete m_VideoDecoder;
m_VideoDecoder = nullptr; m_VideoDecoder = nullptr;
SDL_AtomicUnlock(&m_DecoderLock); SDL_UnlockSpinlock(&m_DecoderLock);
#endif #endif
// Actually enter/leave fullscreen // Actually enter/leave fullscreen
@ -1673,7 +1679,7 @@ void Session::flushWindowEvents()
// This event will cause us to set m_FlushingWindowEvents back to false. // This event will cause us to set m_FlushingWindowEvents back to false.
SDL_Event flushEvent = {}; SDL_Event flushEvent = {};
flushEvent.type = SDL_USEREVENT; flushEvent.type = SDL_EVENT_USER;
flushEvent.user.code = SDL_CODE_FLUSH_WINDOW_EVENT_BARRIER; flushEvent.user.code = SDL_CODE_FLUSH_WINDOW_EVENT_BARRIER;
SDL_PushEvent(&flushEvent); SDL_PushEvent(&flushEvent);
} }
@ -1682,24 +1688,24 @@ bool Session::handleWindowEvent(SDL_WindowEvent* event)
{ {
// Early handling of some events // Early handling of some events
switch (event->event) { switch (event->event) {
case SDL_WINDOWEVENT_FOCUS_LOST: case SDL_EVENT_WINDOW_FOCUS_LOST :
if (m_Preferences->muteOnFocusLoss) { if (m_Preferences->muteOnFocusLoss) {
m_AudioMuted = true; m_AudioMuted = true;
} }
m_InputHandler->notifyFocusLost(); m_InputHandler->notifyFocusLost();
break; break;
case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_EVENT_WINDOW_FOCUS_GAINED :
if (m_Preferences->muteOnFocusLoss) { if (m_Preferences->muteOnFocusLoss) {
m_AudioMuted = false; m_AudioMuted = false;
} }
break; break;
case SDL_WINDOWEVENT_LEAVE: case SDL_EVENT_WINDOW_MOUSE_LEAVE :
m_InputHandler->notifyMouseLeave(); m_InputHandler->notifyMouseLeave();
break; break;
} }
// Capture the mouse on SDL_WINDOWEVENT_ENTER if needed // 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_InputHandler->setCaptureActive(true);
m_NeedsFirstEnterCapture = false; 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 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 // 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. // seem to fire when switching from windowed to full-screen on X11.
if (event->event != SDL_WINDOWEVENT_SIZE_CHANGED && if (event->event != SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED &&
(event->event != SDL_WINDOWEVENT_SHOWN || m_VideoDecoder != nullptr)) { (event->event != SDL_EVENT_WINDOW_SHOWN || m_VideoDecoder != nullptr)) {
// Check that the window display hasn't changed. If it has, we want // 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. // to recreate the decoder to allow it to adapt to the new display.
// This will allow Pacer to pull the new display refresh rate. // This will allow Pacer to pull the new display refresh rate.
#if SDL_VERSION_ATLEAST(2, 0, 18) #if SDL_VERSION_ATLEAST(2, 0, 18)
// On SDL 2.0.18+, there's an event for this specific situation // 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; return true;
} }
#else #else
// Prior to SDL 2.0.18, we must check the display index for each window event // 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; return true;
} }
#endif #endif
@ -1751,26 +1757,26 @@ bool Session::handleWindowEvent(SDL_WindowEvent* event)
WINDOW_STATE_CHANGE_INFO windowChangeInfo = {}; WINDOW_STATE_CHANGE_INFO windowChangeInfo = {};
windowChangeInfo.window = m_Window; 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.stateChangeFlags |= WINDOW_STATE_CHANGE_SIZE;
windowChangeInfo.width = event->data1; windowChangeInfo.width = event->data1;
windowChangeInfo.height = event->data2; windowChangeInfo.height = event->data2;
} }
int newDisplayIndex = SDL_GetWindowDisplayIndex(m_Window); SDL_DisplayID newDisplay = SDL_GetDisplayForWindow(m_Window);
if (newDisplayIndex != m_CurrentDisplayIndex) { if (newDisplay != m_CurrentDisplay) {
windowChangeInfo.stateChangeFlags |= WINDOW_STATE_CHANGE_DISPLAY; 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 // 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 // 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 // and that we apply any V-Sync disablement rules that may be needed for
// this display. // this display.
SDL_DisplayMode oldMode, newMode; SDL_DisplayMode oldMode, newMode;
if (SDL_GetCurrentDisplayMode(m_CurrentDisplayIndex, &oldMode) < 0 || if (SDL_GetCurrentDisplayMode(m_CurrentDisplay, &oldMode) < 0 ||
SDL_GetCurrentDisplayMode(newDisplayIndex, &newMode) < 0 || SDL_GetCurrentDisplayMode(newDisplay, &newMode) < 0 ||
oldMode.refresh_rate != newMode.refresh_rate) { oldMode.refresh_rate != newMode.refresh_rate) {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Forcing renderer recreation due to refresh rate change between displays"); "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)) { if (!forceRecreation && m_VideoDecoder->notifyWindowChanged(&windowChangeInfo)) {
// Update the window display mode based on our current monitor // Update the window display mode based on our current monitor
// NB: Avoid a useless modeset by only doing this if it changed. // NB: Avoid a useless modeset by only doing this if it changed.
if (newDisplayIndex != m_CurrentDisplayIndex) { if (newDisplay != m_CurrentDisplay) {
m_CurrentDisplayIndex = newDisplayIndex; m_CurrentDisplay = newDisplay;
updateOptimalWindowDisplayMode(); updateOptimalWindowDisplayMode();
} }
@ -1807,7 +1813,7 @@ bool Session::handleWindowEvent(SDL_WindowEvent* event)
bool Session::recreateRenderer() bool Session::recreateRenderer()
{ {
SDL_AtomicLock(&m_DecoderLock); SDL_LockSpinlock(&m_DecoderLock);
// Destroy the old decoder // Destroy the old decoder
delete m_VideoDecoder; delete m_VideoDecoder;
@ -1820,8 +1826,8 @@ bool Session::recreateRenderer()
// Update the window display mode based on our current monitor // Update the window display mode based on our current monitor
// NB: Avoid a useless modeset by only doing this if it changed. // NB: Avoid a useless modeset by only doing this if it changed.
if (m_CurrentDisplayIndex != SDL_GetWindowDisplayIndex(m_Window)) { if (m_CurrentDisplay != SDL_GetDisplayForWindow(m_Window)) {
m_CurrentDisplayIndex = SDL_GetWindowDisplayIndex(m_Window); m_CurrentDisplay = SDL_GetDisplayForWindow(m_Window);
updateOptimalWindowDisplayMode(); updateOptimalWindowDisplayMode();
} }
@ -1829,8 +1835,8 @@ bool Session::recreateRenderer()
// have queued to reset itself (if this reset was the result // have queued to reset itself (if this reset was the result
// of state loss). // of state loss).
SDL_PumpEvents(); SDL_PumpEvents();
SDL_FlushEvent(SDL_RENDER_DEVICE_RESET); SDL_FlushEvent(SDL_EVENT_RENDER_DEVICE_RESET);
SDL_FlushEvent(SDL_RENDER_TARGETS_RESET); SDL_FlushEvent(SDL_EVENT_RENDER_TARGETS_RESET);
{ {
// If the stream exceeds the display refresh rate (plus some slack), // If the stream exceeds the display refresh rate (plus some slack),
@ -1853,7 +1859,7 @@ bool Session::recreateRenderer()
enableVsync && m_Preferences->framePacing, enableVsync && m_Preferences->framePacing,
false, false,
s_ActiveSession->m_VideoDecoder)) { s_ActiveSession->m_VideoDecoder)) {
SDL_AtomicUnlock(&m_DecoderLock); SDL_UnlockSpinlock(&m_DecoderLock);
return false; return false;
} }
@ -1876,7 +1882,7 @@ bool Session::recreateRenderer()
// After a window resize, we need to reset the pointer lock region // After a window resize, we need to reset the pointer lock region
m_InputHandler->updatePointerRegionLock(); m_InputHandler->updatePointerRegionLock();
SDL_AtomicUnlock(&m_DecoderLock); SDL_UnlockSpinlock(&m_DecoderLock);
return true; return true;
} }
@ -2002,7 +2008,7 @@ void Session::execInternal()
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
// We always want a resizable window with High DPI enabled // 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 // If we're starting in windowed mode and the Moonlight GUI is maximized or
// minimized, match that with the streaming window. // minimized, match that with the streaming window.
@ -2090,12 +2096,7 @@ void Session::execInternal()
QPainter svgPainter(&svgImage); QPainter svgPainter(&svgImage);
svgIconRenderer.render(&svgPainter); svgIconRenderer.render(&svgPainter);
SDL_Surface* iconSurface = SDL_CreateRGBSurfaceWithFormatFrom((void*)svgImage.constBits(), SDL_Surface* iconSurface = SDL_CreateSurfaceFrom(svgImage.width(), svgImage.height(), SDL_PIXELFORMAT_RGBA32, (void *)svgImage.constBits(), 4 * svgImage.width());
svgImage.width(),
svgImage.height(),
32,
4 * svgImage.width(),
SDL_PIXELFORMAT_RGBA32);
#ifndef Q_OS_DARWIN #ifndef Q_OS_DARWIN
// Other platforms seem to preserve our Qt icon when creating a new window. // Other platforms seem to preserve our Qt icon when creating a new window.
if (iconSurface != nullptr) { if (iconSurface != nullptr) {
@ -2147,7 +2148,7 @@ void Session::execInternal()
// sleep precision and more accurate callback timing. // sleep precision and more accurate callback timing.
SDL_SetHint(SDL_HINT_TIMER_RESOLUTION, "1"); 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 // Now that we're about to stream, any SDL_QUIT event is expected
// unless it comes from the connection termination callback where // unless it comes from the connection termination callback where
@ -2205,12 +2206,12 @@ void Session::execInternal()
} }
switch (event.type) { switch (event.type) {
case SDL_QUIT: case SDL_EVENT_QUIT :
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Quit event received"); "Quit event received");
goto DispatchDeferredCleanup; goto DispatchDeferredCleanup;
case SDL_USEREVENT: case SDL_EVENT_USER :
switch (event.user.code) { switch (event.user.code) {
case SDL_CODE_FRAME_READY: case SDL_CODE_FRAME_READY:
if (m_VideoDecoder != nullptr) { if (m_VideoDecoder != nullptr) {
@ -2245,8 +2246,8 @@ void Session::execInternal()
SDL_assert(false); SDL_assert(false);
} }
break; break;
case SDL_RENDER_DEVICE_RESET: case SDL_EVENT_RENDER_DEVICE_RESET :
case SDL_RENDER_TARGETS_RESET: case SDL_EVENT_RENDER_TARGETS_RESET :
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Recreating renderer by internal request: %d", "Recreating renderer by internal request: %d",
event.type); event.type);
@ -2259,55 +2260,55 @@ void Session::execInternal()
} }
break; break;
case SDL_KEYUP: case SDL_EVENT_KEY_UP :
case SDL_KEYDOWN: case SDL_EVENT_KEY_DOWN :
presence.runCallbacks(); presence.runCallbacks();
m_InputHandler->handleKeyEvent(&event.key); m_InputHandler->handleKeyEvent(&event.key);
break; break;
case SDL_MOUSEBUTTONDOWN: case SDL_EVENT_MOUSE_BUTTON_DOWN :
case SDL_MOUSEBUTTONUP: case SDL_EVENT_MOUSE_BUTTON_UP :
presence.runCallbacks(); presence.runCallbacks();
m_InputHandler->handleMouseButtonEvent(&event.button); m_InputHandler->handleMouseButtonEvent(&event.button);
break; break;
case SDL_MOUSEMOTION: case SDL_EVENT_MOUSE_MOTION :
m_InputHandler->handleMouseMotionEvent(&event.motion); m_InputHandler->handleMouseMotionEvent(&event.motion);
break; break;
case SDL_MOUSEWHEEL: case SDL_EVENT_MOUSE_WHEEL :
m_InputHandler->handleMouseWheelEvent(&event.wheel); m_InputHandler->handleMouseWheelEvent(&event.wheel);
break; break;
case SDL_CONTROLLERAXISMOTION: case SDL_EVENT_GAMEPAD_AXIS_MOTION :
m_InputHandler->handleControllerAxisEvent(&event.caxis); m_InputHandler->handleControllerAxisEvent(&event.gaxis);
break; break;
case SDL_CONTROLLERBUTTONDOWN: case SDL_EVENT_GAMEPAD_BUTTON_DOWN :
case SDL_CONTROLLERBUTTONUP: case SDL_EVENT_GAMEPAD_BUTTON_UP :
presence.runCallbacks(); presence.runCallbacks();
m_InputHandler->handleControllerButtonEvent(&event.cbutton); m_InputHandler->handleControllerButtonEvent(&event.gbutton);
break; break;
#if SDL_VERSION_ATLEAST(2, 0, 14) #if SDL_VERSION_ATLEAST(2, 0, 14)
case SDL_CONTROLLERSENSORUPDATE: case SDL_EVENT_GAMEPAD_SENSOR_UPDATE :
m_InputHandler->handleControllerSensorEvent(&event.csensor); m_InputHandler->handleControllerSensorEvent(&event.gsensor);
break; break;
case SDL_CONTROLLERTOUCHPADDOWN: case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN :
case SDL_CONTROLLERTOUCHPADUP: case SDL_EVENT_GAMEPAD_TOUCHPAD_UP :
case SDL_CONTROLLERTOUCHPADMOTION: case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION :
m_InputHandler->handleControllerTouchpadEvent(&event.ctouchpad); m_InputHandler->handleControllerTouchpadEvent(&event.gtouchpad);
break; break;
#endif #endif
#if SDL_VERSION_ATLEAST(2, 24, 0) #if SDL_VERSION_ATLEAST(2, 24, 0)
case SDL_JOYBATTERYUPDATED: case SDL_EVENT_JOYSTICK_BATTERY_UPDATED :
m_InputHandler->handleJoystickBatteryEvent(&event.jbattery); m_InputHandler->handleJoystickBatteryEvent(&event.jbattery);
break; break;
#endif #endif
case SDL_CONTROLLERDEVICEADDED: case SDL_EVENT_GAMEPAD_ADDED :
case SDL_CONTROLLERDEVICEREMOVED: case SDL_EVENT_GAMEPAD_REMOVED :
m_InputHandler->handleControllerDeviceEvent(&event.cdevice); m_InputHandler->handleControllerDeviceEvent(&event.gdevice);
break; break;
case SDL_JOYDEVICEADDED: case SDL_EVENT_JOYSTICK_ADDED :
m_InputHandler->handleJoystickArrivalEvent(&event.jdevice); m_InputHandler->handleJoystickArrivalEvent(&event.jdevice);
break; break;
case SDL_FINGERDOWN: case SDL_EVENT_FINGER_DOWN :
case SDL_FINGERMOTION: case SDL_EVENT_FINGER_MOTION :
case SDL_FINGERUP: case SDL_EVENT_FINGER_UP :
m_InputHandler->handleTouchFingerEvent(&event.tfinger); m_InputHandler->handleTouchFingerEvent(&event.tfinger);
break; break;
} }
@ -2335,10 +2336,10 @@ DispatchDeferredCleanup:
// Destroy the decoder, since this must be done on the main thread // Destroy the decoder, since this must be done on the main thread
// NB: This must happen before LiStopConnection() for pull-based // NB: This must happen before LiStopConnection() for pull-based
// decoders. // decoders.
SDL_AtomicLock(&m_DecoderLock); SDL_LockSpinlock(&m_DecoderLock);
delete m_VideoDecoder; delete m_VideoDecoder;
m_VideoDecoder = nullptr; m_VideoDecoder = nullptr;
SDL_AtomicUnlock(&m_DecoderLock); SDL_UnlockSpinlock(&m_DecoderLock);
// Propagate state changes from the SDL window back to the Qt window // Propagate state changes from the SDL window back to the Qt window
// //
@ -2370,7 +2371,7 @@ DispatchDeferredCleanup:
SDL_DestroyWindow(m_Window); SDL_DestroyWindow(m_Window);
if (iconSurface != nullptr) { if (iconSurface != nullptr) {
SDL_FreeSurface(iconSurface); SDL_DestroySurface(iconSurface);
} }
SDL_QuitSubSystem(SDL_INIT_VIDEO); SDL_QuitSubSystem(SDL_INIT_VIDEO);

View File

@ -266,7 +266,7 @@ private:
int m_FlushingWindowEventsRef; int m_FlushingWindowEventsRef;
QList<QString> m_LaunchWarnings; QList<QString> m_LaunchWarnings;
int m_CurrentDisplayIndex; SDL_DisplayID m_CurrentDisplay;
bool m_NeedsFirstEnterCapture; bool m_NeedsFirstEnterCapture;
bool m_NeedsPostDecoderCreationCapture; bool m_NeedsPostDecoderCreationCapture;

View File

@ -111,31 +111,22 @@ void StreamUtils::screenSpaceToNormalizedDeviceCoords(SDL_Rect* src, SDL_FRect*
int StreamUtils::getDisplayRefreshRate(SDL_Window* window) 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; SDL_DisplayMode mode;
if (SDLC_IsFullscreenExclusive(window)) { if (SDLC_IsFullscreenExclusive(window)) {
// Use the window display mode for full-screen exclusive mode // 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_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_GetWindowDisplayMode() failed: %s", "SDL_GetWindowFullscreenMode() failed: %s",
SDL_GetError()); SDL_GetError());
// Assume 60 Hz
return 60;
} }
} }
else { else {
// Use the current display mode for windowed and borderless // 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_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_GetCurrentDisplayMode() failed: %s", "SDL_GetCurrentDisplayMode() failed: %s",
SDL_GetError()); SDL_GetError());
@ -199,7 +190,7 @@ bool StreamUtils::hasFastAes()
#endif #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 #ifdef Q_OS_DARWIN
#define MAX_DISPLAYS 16 #define MAX_DISPLAYS 16
@ -277,17 +268,13 @@ bool StreamUtils::getNativeDesktopMode(int displayIndex, SDL_DisplayMode* mode,
#else #else
SDL_assert(SDL_WasInit(SDL_INIT_VIDEO)); 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). // 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. // 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 // 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 // the first mode on Wayland will get the native resolution without the scaling factor
// (and macOS is handled in the #ifdef above). // (and macOS is handled in the #ifdef above).
if (!strcmp(SDL_GetCurrentVideoDriver(), "wayland")) { 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_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_GetDisplayMode() failed: %s", "SDL_GetDisplayMode() failed: %s",
SDL_GetError()); SDL_GetError());
@ -295,7 +282,7 @@ bool StreamUtils::getNativeDesktopMode(int displayIndex, SDL_DisplayMode* mode,
} }
} }
else { else {
if (SDL_GetDesktopDisplayMode(displayIndex, mode) != 0) { if (SDL_GetDesktopDisplayMode(display, mode) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_GetDesktopDisplayMode() failed: %s", "SDL_GetDesktopDisplayMode() failed: %s",
SDL_GetError()); SDL_GetError());

View File

@ -18,7 +18,7 @@ public:
void screenSpaceToNormalizedDeviceCoords(SDL_Rect* src, SDL_FRect* dst, int viewportWidth, int viewportHeight); void screenSpaceToNormalizedDeviceCoords(SDL_Rect* src, SDL_FRect* dst, int viewportWidth, int viewportHeight);
static static
bool getNativeDesktopMode(int displayIndex, SDL_DisplayMode* mode, SDL_Rect* safeArea); bool getNativeDesktopMode(SDL_DisplayID display, SDL_DisplayMode* mode, SDL_Rect* safeArea);
static static
int getDisplayRefreshRate(SDL_Window* window); int getDisplayRefreshRate(SDL_Window* window);

View File

@ -666,7 +666,7 @@ void D3D11VARenderer::renderFrame(AVFrame* frame)
// The card may have been removed or crashed. Reset the decoder. // The card may have been removed or crashed. Reset the decoder.
SDL_Event event; SDL_Event event;
event.type = SDL_RENDER_TARGETS_RESET; event.type = SDL_EVENT_RENDER_TARGETS_RESET;
SDL_PushEvent(&event); SDL_PushEvent(&event);
return; return;
} }

View File

@ -264,7 +264,7 @@ void DrmRenderer::prepareToRender()
// operation that the KMSDRM backend keeps pending until the next // operation that the KMSDRM backend keeps pending until the next
// time we swap buffers. We have to do this before we enumerate // time we swap buffers. We have to do this before we enumerate
// CRTC modes below. // 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) { if (renderer != nullptr) {
// SDL_CreateRenderer() can end up having to recreate our window (SDL_RecreateWindow()) // 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 // to ensure it's compatible with the renderer's OpenGL context. If that happens, we

View File

@ -1112,7 +1112,7 @@ void DXVA2Renderer::renderFrame(AVFrame *frame)
"Clear() failed: %x", "Clear() failed: %x",
hr); hr);
SDL_Event event; SDL_Event event;
event.type = SDL_RENDER_TARGETS_RESET; event.type = SDL_EVENT_RENDER_TARGETS_RESET;
SDL_PushEvent(&event); SDL_PushEvent(&event);
return; return;
} }
@ -1123,7 +1123,7 @@ void DXVA2Renderer::renderFrame(AVFrame *frame)
"BeginScene() failed: %x", "BeginScene() failed: %x",
hr); hr);
SDL_Event event; SDL_Event event;
event.type = SDL_RENDER_TARGETS_RESET; event.type = SDL_EVENT_RENDER_TARGETS_RESET;
SDL_PushEvent(&event); SDL_PushEvent(&event);
return; return;
} }
@ -1149,7 +1149,7 @@ void DXVA2Renderer::renderFrame(AVFrame *frame)
"StretchRect() failed: %x", "StretchRect() failed: %x",
hr); hr);
SDL_Event event; SDL_Event event;
event.type = SDL_RENDER_TARGETS_RESET; event.type = SDL_EVENT_RENDER_TARGETS_RESET;
SDL_PushEvent(&event); SDL_PushEvent(&event);
return; return;
} }
@ -1166,7 +1166,7 @@ void DXVA2Renderer::renderFrame(AVFrame *frame)
"EndScene() failed: %x", "EndScene() failed: %x",
hr); hr);
SDL_Event event; SDL_Event event;
event.type = SDL_RENDER_TARGETS_RESET; event.type = SDL_EVENT_RENDER_TARGETS_RESET;
SDL_PushEvent(&event); SDL_PushEvent(&event);
return; return;
} }
@ -1184,7 +1184,7 @@ void DXVA2Renderer::renderFrame(AVFrame *frame)
"PresentEx() failed: %x", "PresentEx() failed: %x",
hr); hr);
SDL_Event event; SDL_Event event;
event.type = SDL_RENDER_TARGETS_RESET; event.type = SDL_EVENT_RENDER_TARGETS_RESET;
SDL_PushEvent(&event); SDL_PushEvent(&event);
return; return;
} }

View File

@ -162,7 +162,7 @@ void EGLRenderer::notifyOverlayUpdated(Overlay::OverlayType type)
if (!Session::get()->getOverlayManager().isOverlayEnabled(type)) { if (!Session::get()->getOverlayManager().isOverlayEnabled(type)) {
// If the overlay has been disabled, mark the data as invalid/stale. // 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; 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. // we must allocate a tightly packed buffer and copy our pixels there.
packedPixelData = malloc(newSurface->w * newSurface->h * newSurface->format->BytesPerPixel); packedPixelData = malloc(newSurface->w * newSurface->h * newSurface->format->BytesPerPixel);
if (!packedPixelData) { if (!packedPixelData) {
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
return; return;
} }
@ -247,7 +247,7 @@ void EGLRenderer::renderOverlay(Overlay::OverlayType type, int viewportWidth, in
overlayRect.w = newSurface->w; overlayRect.w = newSurface->w;
overlayRect.h = newSurface->h; overlayRect.h = newSurface->h;
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
// Convert screen space to normalized device coordinates // Convert screen space to normalized device coordinates
StreamUtils::screenSpaceToNormalizedDeviceCoords(&overlayRect, viewportWidth, viewportHeight); 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]); glBindBuffer(GL_ARRAY_BUFFER, m_OverlayVbos[type]);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); 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. // If the overlay is not populated yet or is stale, don't render it.
return; 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_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); 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 renderIndex;
int maxRenderers = SDL_GetNumRenderDrivers(); int maxRenderers = SDL_GetNumRenderDrivers();
SDL_assert(maxRenderers >= 0); SDL_assert(maxRenderers >= 0);
@ -454,6 +457,7 @@ bool EGLRenderer::initialize(PDECODER_PARAMETERS params)
} }
m_DummyRenderer = SDL_CreateRenderer(m_Window, renderIndex, SDL_RENDERER_ACCELERATED); m_DummyRenderer = SDL_CreateRenderer(m_Window, renderIndex, SDL_RENDERER_ACCELERATED);
#endif
if (!m_DummyRenderer) { if (!m_DummyRenderer) {
// Print the error here (before it gets clobbered), but ensure that we flush window // 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. // 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. // 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. // 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_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; return err == GL_NO_ERROR;
@ -822,7 +826,7 @@ void EGLRenderer::renderFrame(AVFrame* frame)
// XWayland. Other strategies like calling glGetError() don't seem // XWayland. Other strategies like calling glGetError() don't seem
// to be able to detect this situation for some reason. // to be able to detect this situation for some reason.
SDL_Event event; SDL_Event event;
event.type = SDL_RENDER_TARGETS_RESET; event.type = SDL_EVENT_RENDER_TARGETS_RESET;
SDL_PushEvent(&event); SDL_PushEvent(&event);
return; return;
@ -841,7 +845,11 @@ void EGLRenderer::renderFrame(AVFrame* frame)
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
int drawableWidth, drawableHeight; int drawableWidth, drawableHeight;
#if SDL_VERSION_ATLEAST(3, 0, 0)
SDL_GetWindowSizeInPixels(m_Window, &drawableWidth, &drawableHeight);
#else
SDL_GL_GetDrawableSize(m_Window, &drawableWidth, &drawableHeight); SDL_GL_GetDrawableSize(m_Window, &drawableWidth, &drawableHeight);
#endif
// Set the viewport to the size of the aspect-ratio-scaled video // Set the viewport to the size of the aspect-ratio-scaled video
SDL_Rect src, dst; SDL_Rect src, dst;

View File

@ -56,7 +56,7 @@ void MmalRenderer::prepareToRender()
{ {
// Create a renderer and draw a black background for the area not covered by the MMAL overlay. // 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. // 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) { if (m_BackgroundRenderer == nullptr) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_CreateRenderer() failed: %s", "SDL_CreateRenderer() failed: %s",

View File

@ -98,11 +98,7 @@ int Pacer::vsyncThread(void *context)
{ {
Pacer* me = reinterpret_cast<Pacer*>(context); Pacer* me = reinterpret_cast<Pacer*>(context);
#if SDL_VERSION_ATLEAST(2, 0, 9) SDL_SetCurrentThreadPriority(SDL_THREAD_PRIORITY_TIME_CRITICAL);
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_TIME_CRITICAL);
#else
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
#endif
bool async = me->m_VsyncSource->isAsync(); bool async = me->m_VsyncSource->isAsync();
while (!me->m_Stopping) { while (!me->m_Stopping) {
@ -131,7 +127,7 @@ int Pacer::renderThread(void* context)
{ {
Pacer* me = reinterpret_cast<Pacer*>(context); Pacer* me = reinterpret_cast<Pacer*>(context);
if (SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH) < 0) { if (!SDL_SetCurrentThreadPriority(SDL_THREAD_PRIORITY_HIGH)) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Unable to set render thread to high priority: %s", "Unable to set render thread to high priority: %s",
SDL_GetError()); SDL_GetError());
@ -183,7 +179,7 @@ void Pacer::enqueueFrameForRenderingAndUnlock(AVFrame *frame)
SDL_Event event; SDL_Event event;
// For main thread rendering, we'll push an event to trigger a callback // 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; event.user.code = SDL_CODE_FRAME_READY;
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }

View File

@ -95,7 +95,7 @@ void PlVkRenderer::unlockQueue(struct AVHWDeviceContext *dev_ctx, uint32_t queue
void PlVkRenderer::overlayUploadComplete(void* opaque) void PlVkRenderer::overlayUploadComplete(void* opaque)
{ {
SDL_FreeSurface((SDL_Surface*)opaque); SDL_DestroySurface((SDL_Surface*)opaque);
} }
PlVkRenderer::PlVkRenderer(bool hwaccel, IFFmpegRenderer *backendRenderer) : PlVkRenderer::PlVkRenderer(bool hwaccel, IFFmpegRenderer *backendRenderer) :
@ -362,7 +362,11 @@ bool PlVkRenderer::initialize(PDECODER_PARAMETERS params)
m_Window = params->window; m_Window = params->window;
unsigned int instanceExtensionCount = 0; 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)) { if (!SDL_Vulkan_GetInstanceExtensions(params->window, &instanceExtensionCount, nullptr)) {
#endif
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_Vulkan_GetInstanceExtensions() #1 failed: %s", "SDL_Vulkan_GetInstanceExtensions() #1 failed: %s",
SDL_GetError()); SDL_GetError());
@ -370,7 +374,11 @@ bool PlVkRenderer::initialize(PDECODER_PARAMETERS params)
} }
std::vector<const char*> instanceExtensions(instanceExtensionCount); std::vector<const char*> 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())) { if (!SDL_Vulkan_GetInstanceExtensions(params->window, &instanceExtensionCount, instanceExtensions.data())) {
#endif
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_Vulkan_GetInstanceExtensions() #2 failed: %s", "SDL_Vulkan_GetInstanceExtensions() #2 failed: %s",
SDL_GetError()); SDL_GetError());
@ -402,7 +410,11 @@ bool PlVkRenderer::initialize(PDECODER_PARAMETERS params)
POPULATE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR); POPULATE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR);
POPULATE_FUNCTION(vkEnumerateDeviceExtensionProperties); 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)) { if (!SDL_Vulkan_CreateSurface(params->window, m_PlVkInstance->instance, &m_VkSurface)) {
#endif
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_Vulkan_CreateSurface() failed: %s", "SDL_Vulkan_CreateSurface() failed: %s",
SDL_GetError()); SDL_GetError());
@ -703,7 +715,7 @@ void PlVkRenderer::waitToRender()
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"GPU is in failed state. Recreating renderer."); "GPU is in failed state. Recreating renderer.");
SDL_Event event; SDL_Event event;
event.type = SDL_RENDER_DEVICE_RESET; event.type = SDL_EVENT_RENDER_DEVICE_RESET;
SDL_PushEvent(&event); SDL_PushEvent(&event);
return; return;
} }
@ -721,7 +733,11 @@ void PlVkRenderer::waitToRender()
// Handle the swapchain being resized // Handle the swapchain being resized
int vkDrawableW, vkDrawableH; int vkDrawableW, vkDrawableH;
#if SDL_VERSION_ATLEAST(3, 0, 0)
SDL_GetWindowSizeInPixels(m_Window, &vkDrawableW, &vkDrawableH);
#else
SDL_Vulkan_GetDrawableSize(m_Window, &vkDrawableW, &vkDrawableH); SDL_Vulkan_GetDrawableSize(m_Window, &vkDrawableW, &vkDrawableH);
#endif
if (!pl_swapchain_resize(m_Swapchain, &vkDrawableW, &vkDrawableH)) { if (!pl_swapchain_resize(m_Swapchain, &vkDrawableW, &vkDrawableH)) {
// Swapchain (re)creation can fail if the window is occluded // Swapchain (re)creation can fail if the window is occluded
return; return;
@ -905,12 +921,12 @@ void PlVkRenderer::notifyOverlayUpdated(Overlay::OverlayType type)
return; 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, // 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 // 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. // as we modify or recreate the staging overlay texture outside the overlay lock.
m_Overlays[type].hasStagingOverlay = false; 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. // 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 // 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); SDL_assert(newSurface->format->format == SDL_PIXELFORMAT_ARGB8888);
pl_fmt texFormat = pl_find_named_fmt(m_Vulkan->gpu, "bgra8"); pl_fmt texFormat = pl_find_named_fmt(m_Vulkan->gpu, "bgra8");
if (!texFormat) { if (!texFormat) {
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"pl_find_named_fmt(bgra8) failed"); "pl_find_named_fmt(bgra8) failed");
return; return;
@ -945,7 +961,7 @@ void PlVkRenderer::notifyOverlayUpdated(Overlay::OverlayType type)
if (!pl_tex_recreate(m_Vulkan->gpu, &m_Overlays[type].stagingOverlay.tex, &texParams)) { if (!pl_tex_recreate(m_Vulkan->gpu, &m_Overlays[type].stagingOverlay.tex, &texParams)) {
pl_tex_destroy(m_Vulkan->gpu, &m_Overlays[type].stagingOverlay.tex); pl_tex_destroy(m_Vulkan->gpu, &m_Overlays[type].stagingOverlay.tex);
SDL_zero(m_Overlays[type].stagingOverlay); SDL_zero(m_Overlays[type].stagingOverlay);
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"pl_tex_recreate() failed"); "pl_tex_recreate() failed");
return; return;
@ -962,7 +978,7 @@ void PlVkRenderer::notifyOverlayUpdated(Overlay::OverlayType type)
if (!pl_tex_upload(m_Vulkan->gpu, &xferParams)) { if (!pl_tex_upload(m_Vulkan->gpu, &xferParams)) {
pl_tex_destroy(m_Vulkan->gpu, &m_Overlays[type].stagingOverlay.tex); pl_tex_destroy(m_Vulkan->gpu, &m_Overlays[type].stagingOverlay.tex);
SDL_zero(m_Overlays[type].stagingOverlay); SDL_zero(m_Overlays[type].stagingOverlay);
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"pl_tex_upload() failed"); "pl_tex_upload() failed");
return; return;
@ -978,10 +994,10 @@ void PlVkRenderer::notifyOverlayUpdated(Overlay::OverlayType type)
m_Overlays[type].stagingOverlay.color = pl_color_space_srgb; m_Overlays[type].stagingOverlay.color = pl_color_space_srgb;
// Make this staging overlay visible to the render thread // Make this staging overlay visible to the render thread
SDL_AtomicLock(&m_OverlayLock); SDL_LockSpinlock(&m_OverlayLock);
SDL_assert(!m_Overlays[type].hasStagingOverlay); SDL_assert(!m_Overlays[type].hasStagingOverlay);
m_Overlays[type].hasStagingOverlay = true; m_Overlays[type].hasStagingOverlay = true;
SDL_AtomicUnlock(&m_OverlayLock); SDL_UnlockSpinlock(&m_OverlayLock);
} }
bool PlVkRenderer::notifyWindowChanged(PWINDOW_STATE_CHANGE_INFO info) bool PlVkRenderer::notifyWindowChanged(PWINDOW_STATE_CHANGE_INFO info)

View File

@ -169,7 +169,7 @@ bool SdlRenderer::initialize(PDECODER_PARAMETERS params)
SDL_SetHintWithPriority(SDL_HINT_RENDER_DIRECT3D_THREADSAFE, "1", SDL_HINT_OVERRIDE); SDL_SetHintWithPriority(SDL_HINT_RENDER_DIRECT3D_THREADSAFE, "1", SDL_HINT_OVERRIDE);
#endif #endif
m_Renderer = SDL_CreateRenderer(params->window, -1, rendererFlags); m_Renderer = SDL_CreateRenderer(params->window, SDLC_DEFAULT_RENDER_DRIVER, rendererFlags);
if (!m_Renderer) { if (!m_Renderer) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_CreateRenderer() failed: %s", "SDL_CreateRenderer() failed: %s",
@ -221,7 +221,7 @@ void SdlRenderer::renderOverlay(Overlay::OverlayType type)
if (type == Overlay::OverlayStatusUpdate) { if (type == Overlay::OverlayStatusUpdate) {
// Bottom Left // Bottom Left
SDL_Rect viewportRect; SDL_Rect viewportRect;
SDL_RenderGetViewport(m_Renderer, &viewportRect); SDL_GetRenderViewport(m_Renderer, &viewportRect);
m_OverlayRects[type].x = 0; m_OverlayRects[type].x = 0;
m_OverlayRects[type].y = viewportRect.h - newSurface->h; 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_OverlayRects[type].h = newSurface->h;
m_OverlayTextures[type] = SDL_CreateTextureFromSurface(m_Renderer, newSurface); m_OverlayTextures[type] = SDL_CreateTextureFromSurface(m_Renderer, newSurface);
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
} }
// If we have an overlay texture, render it too // If we have an overlay texture, render it too
if (m_OverlayTextures[type] != nullptr) { 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]);
} }
} }
} }

View File

@ -659,7 +659,7 @@ void VAAPIRenderer::notifyOverlayUpdated(Overlay::OverlayType type)
} }
if (!overlayEnabled) { if (!overlayEnabled) {
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
return; return;
} }
@ -673,7 +673,7 @@ void VAAPIRenderer::notifyOverlayUpdated(Overlay::OverlayType type)
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"vaCreateImage() failed: %d", "vaCreateImage() failed: %d",
status); status);
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
return; return;
} }
@ -683,7 +683,7 @@ void VAAPIRenderer::notifyOverlayUpdated(Overlay::OverlayType type)
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"vaMapBuffer() failed: %d", "vaMapBuffer() failed: %d",
status); status);
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
vaDestroyImage(vaDeviceContext->display, newImage.image_id); vaDestroyImage(vaDeviceContext->display, newImage.image_id);
return; return;
} }
@ -698,7 +698,7 @@ void VAAPIRenderer::notifyOverlayUpdated(Overlay::OverlayType type)
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"vaUnmapBuffer() failed: %d", "vaUnmapBuffer() failed: %d",
status); status);
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
vaDestroyImage(vaDeviceContext->display, newImage.image_id); vaDestroyImage(vaDeviceContext->display, newImage.image_id);
return; return;
} }
@ -720,7 +720,7 @@ void VAAPIRenderer::notifyOverlayUpdated(Overlay::OverlayType type)
overlayRect.h = newSurface->h; overlayRect.h = newSurface->h;
// Surface data is no longer needed // Surface data is no longer needed
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
VASubpictureID newSubpicture; VASubpictureID newSubpicture;
status = vaCreateSubpicture(vaDeviceContext->display, newImage.image_id, &newSubpicture); status = vaCreateSubpicture(vaDeviceContext->display, newImage.image_id, &newSubpicture);

View File

@ -374,7 +374,7 @@ void VDPAURenderer::notifyOverlayUpdated(Overlay::OverlayType type)
} }
if (!overlayEnabled) { if (!overlayEnabled) {
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
return; return;
} }
@ -393,7 +393,7 @@ void VDPAURenderer::notifyOverlayUpdated(Overlay::OverlayType type)
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"VdpBitmapSurfaceCreate() failed: %s", "VdpBitmapSurfaceCreate() failed: %s",
m_VdpGetErrorString(status)); m_VdpGetErrorString(status));
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
return; return;
} }
@ -406,7 +406,7 @@ void VDPAURenderer::notifyOverlayUpdated(Overlay::OverlayType type)
"VdpBitmapSurfacePutBitsNative() failed: %s", "VdpBitmapSurfacePutBitsNative() failed: %s",
m_VdpGetErrorString(status)); m_VdpGetErrorString(status));
m_VdpBitmapSurfaceDestroy(newBitmapSurface); m_VdpBitmapSurfaceDestroy(newBitmapSurface);
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
return; return;
} }
@ -427,7 +427,7 @@ void VDPAURenderer::notifyOverlayUpdated(Overlay::OverlayType type)
overlayRect.y1 = overlayRect.y0 + newSurface->h; overlayRect.y1 = overlayRect.y0 + newSurface->h;
// Surface data is no longer needed // Surface data is no longer needed
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
SDL_LockMutex(m_OverlayMutex); SDL_LockMutex(m_OverlayMutex);
m_OverlaySurface[type] = newBitmapSurface; m_OverlaySurface[type] = newBitmapSurface;
@ -467,7 +467,7 @@ void VDPAURenderer::renderOverlay(VdpOutputSurface destination, Overlay::Overlay
return; return;
} }
if (SDL_TryLockMutex(m_OverlayMutex) != 0) { if (!SDL_TryLockMutex(m_OverlayMutex)) {
// If the overlay is currently being updated, skip rendering it this frame. // If the overlay is currently being updated, skip rendering it this frame.
return; return;
} }

View File

@ -123,7 +123,7 @@ int FFmpegVideoDecoder::getDecoderCapabilities()
if (!isHardwareAccelerated()) { if (!isHardwareAccelerated()) {
// Slice up to 4 times for parallel CPU decoding, once slice per core // 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, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Encoder configured for %d slices per frame", "Encoder configured for %d slices per frame",
slices); slices);
@ -269,10 +269,10 @@ void FFmpegVideoDecoder::reset()
// Terminate the decoder thread before doing anything else. // Terminate the decoder thread before doing anything else.
// It might be touching things we're about to free. // It might be touching things we're about to free.
if (m_DecoderThread != nullptr) { if (m_DecoderThread != nullptr) {
SDL_AtomicSet(&m_DecoderThreadShouldQuit, 1); SDL_SetAtomicInt(&m_DecoderThreadShouldQuit, 1);
LiWakeWaitForVideoFrame(); LiWakeWaitForVideoFrame();
SDL_WaitThread(m_DecoderThread, NULL); SDL_WaitThread(m_DecoderThread, NULL);
SDL_AtomicSet(&m_DecoderThreadShouldQuit, 0); SDL_SetAtomicInt(&m_DecoderThreadShouldQuit, 0);
m_DecoderThread = nullptr; m_DecoderThread = nullptr;
} }
@ -484,7 +484,7 @@ bool FFmpegVideoDecoder::completeInitialization(const AVCodec* decoder, enum AVP
// Enable slice multi-threading for software decoding // Enable slice multi-threading for software decoding
if (!isHardwareAccelerated()) { if (!isHardwareAccelerated()) {
m_VideoDecoderCtx->thread_type = FF_THREAD_SLICE; 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 { else {
// No threading for HW decode // No threading for HW decode
@ -1608,7 +1608,7 @@ int FFmpegVideoDecoder::decoderThreadProcThunk(void *context)
void FFmpegVideoDecoder::decoderThreadProc() void FFmpegVideoDecoder::decoderThreadProc()
{ {
while (!SDL_AtomicGet(&m_DecoderThreadShouldQuit)) { while (!SDL_GetAtomicInt(&m_DecoderThreadShouldQuit)) {
if (m_FramesIn == m_FramesOut) { if (m_FramesIn == m_FramesOut) {
VIDEO_FRAME_HANDLE handle; VIDEO_FRAME_HANDLE handle;
PDECODE_UNIT du; PDECODE_UNIT du;
@ -1736,18 +1736,18 @@ void FFmpegVideoDecoder::decoderThreadProc()
"Resetting decoder due to consistent failure"); "Resetting decoder due to consistent failure");
SDL_Event event; SDL_Event event;
event.type = SDL_RENDER_DEVICE_RESET; event.type = SDL_EVENT_RENDER_DEVICE_RESET;
SDL_PushEvent(&event); SDL_PushEvent(&event);
// Don't consume any additional data // 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, // Just in case the error resulted in the loss of the frame,
// request an IDR frame to reset our decoder state. // request an IDR frame to reset our decoder state.
LiRequestIdrFrame(); LiRequestIdrFrame();
} }
} while (err == AVERROR(EAGAIN) && !SDL_AtomicGet(&m_DecoderThreadShouldQuit)); } while (err == AVERROR(EAGAIN) && !SDL_GetAtomicInt(&m_DecoderThreadShouldQuit));
if (err != 0) { if (err != 0) {
// Free the frame if we failed to submit it // 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"); "Resetting decoder due to consistent failure");
SDL_Event event; SDL_Event event;
event.type = SDL_RENDER_DEVICE_RESET; event.type = SDL_EVENT_RENDER_DEVICE_RESET;
SDL_PushEvent(&event); SDL_PushEvent(&event);
// Don't consume any additional data // Don't consume any additional data
SDL_AtomicSet(&m_DecoderThreadShouldQuit, 1); SDL_SetAtomicInt(&m_DecoderThreadShouldQuit, 1);
} }
return DR_NEED_IDR; return DR_NEED_IDR;

View File

@ -133,7 +133,7 @@ void OverlayManager::notifyOverlayUpdated(OverlayType type)
} }
// m_FontData must stay around until the font is closed // 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, 1,
m_Overlays[type].fontSize); m_Overlays[type].fontSize);
if (m_Overlays[type].font == nullptr) { 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 // Free the old surface
if (oldSurface != nullptr) { if (oldSurface != nullptr) {
SDL_FreeSurface(oldSurface); SDL_DestroySurface(oldSurface);
} }
if (m_Overlays[type].enabled) { if (m_Overlays[type].enabled) {
@ -159,7 +159,7 @@ void OverlayManager::notifyOverlayUpdated(OverlayType type)
m_Overlays[type].text, m_Overlays[type].text,
m_Overlays[type].color, m_Overlays[type].color,
1024); 1024);
SDL_AtomicSetPtr((void**)&m_Overlays[type].surface, surface); SDL_SetAtomicPointer((void**)&m_Overlays[type].surface, surface);
} }
// Notify the renderer // Notify the renderer

View File

@ -195,7 +195,7 @@ void SLVideoDecoder::notifyOverlayUpdated(Overlay::OverlayType type)
} }
if (!overlayEnabled) { if (!overlayEnabled) {
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
return; return;
} }
@ -203,7 +203,7 @@ void SLVideoDecoder::notifyOverlayUpdated(Overlay::OverlayType type)
if (m_Overlay == nullptr) { if (m_Overlay == nullptr) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SLVideo_CreateOverlay() failed"); "SLVideo_CreateOverlay() failed");
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
return; return;
} }
@ -221,7 +221,7 @@ void SLVideoDecoder::notifyOverlayUpdated(Overlay::OverlayType type)
SLVideo_SetOverlayDisplayArea(m_Overlay, 0.0f, 1.0f - flHeight, flWidth, flHeight); SLVideo_SetOverlayDisplayArea(m_Overlay, 0.0f, 1.0f - flHeight, flWidth, flHeight);
// We're done with the surface now // We're done with the surface now
SDL_FreeSurface(newSurface); SDL_DestroySurface(newSurface);
// Show the overlay // Show the overlay
SLVideo_ShowOverlay(m_Overlay); SLVideo_ShowOverlay(m_Overlay);

View File

@ -24,10 +24,10 @@
bool WMUtils::isRunningX11() bool WMUtils::isRunningX11()
{ {
#ifdef HAS_X11 #ifdef HAS_X11
static SDL_atomic_t isRunningOnX11; static SDL_AtomicInt isRunningOnX11;
// If the value is not set yet, populate it now. // If the value is not set yet, populate it now.
int val = SDL_AtomicGet(&isRunningOnX11); int val = SDL_GetAtomicInt(&isRunningOnX11);
if (!(val & VALUE_SET)) { if (!(val & VALUE_SET)) {
Display* display = XOpenDisplay(nullptr); Display* display = XOpenDisplay(nullptr);
if (display != nullptr) { if (display != nullptr) {
@ -38,7 +38,7 @@ bool WMUtils::isRunningX11()
// This can race with another thread populating the same data, // This can race with another thread populating the same data,
// but that's no big deal. // but that's no big deal.
val = VALUE_SET | ((display != nullptr) ? VALUE_TRUE : 0); val = VALUE_SET | ((display != nullptr) ? VALUE_TRUE : 0);
SDL_AtomicSet(&isRunningOnX11, val); SDL_SetAtomicInt(&isRunningOnX11, val);
} }
return !!(val & VALUE_TRUE); return !!(val & VALUE_TRUE);
@ -50,10 +50,10 @@ bool WMUtils::isRunningX11()
bool WMUtils::isRunningWayland() bool WMUtils::isRunningWayland()
{ {
#ifdef HAS_WAYLAND #ifdef HAS_WAYLAND
static SDL_atomic_t isRunningOnWayland; static SDL_AtomicInt isRunningOnWayland;
// If the value is not set yet, populate it now. // If the value is not set yet, populate it now.
int val = SDL_AtomicGet(&isRunningOnWayland); int val = SDL_GetAtomicInt(&isRunningOnWayland);
if (!(val & VALUE_SET)) { if (!(val & VALUE_SET)) {
struct wl_display* display = wl_display_connect(nullptr); struct wl_display* display = wl_display_connect(nullptr);
if (display != nullptr) { if (display != nullptr) {
@ -64,7 +64,7 @@ bool WMUtils::isRunningWayland()
// This can race with another thread populating the same data, // This can race with another thread populating the same data,
// but that's no big deal. // but that's no big deal.
val = VALUE_SET | ((display != nullptr) ? VALUE_TRUE : 0); val = VALUE_SET | ((display != nullptr) ? VALUE_TRUE : 0);
SDL_AtomicSet(&isRunningOnWayland, val); SDL_SetAtomicInt(&isRunningOnWayland, val);
} }
return !!(val & VALUE_TRUE); return !!(val & VALUE_TRUE);