Skip to content

Commit

Permalink
SDLInputSource: Support forwarding touchpad to pointer
Browse files Browse the repository at this point in the history
  • Loading branch information
stenzek committed Jan 7, 2025
1 parent 2b7b3d8 commit 0a124ee
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/util/input_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,11 @@ void InputManager::UpdateHostMouseMode()
Host::SetMouseMode(wanted_relative_mouse_mode, wanted_hide_host_mouse_cursor);
}

bool InputManager::IsRelativeMouseModeActive()
{
return s_relative_mouse_mode_active;
}

bool InputManager::IsUsingRawInput()
{
#if defined(_WIN32)
Expand All @@ -1409,6 +1414,11 @@ void InputManager::SetDisplayWindowSize(float width, float height)
s_window_size[1] = height;
}

std::pair<float, float> InputManager::GetDisplayWindowSize()
{
return std::make_pair(s_window_size[0], s_window_size[1]);
}

void InputManager::SetDefaultSourceConfig(SettingsInterface& si)
{
si.ClearSection("InputSources");
Expand Down
2 changes: 2 additions & 0 deletions src/util/input_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ void UpdatePointerRelativeDelta(u32 index, InputPointerAxis axis, float d, bool
/// Updates host mouse mode (relative/cursor hiding).
void UpdateRelativeMouseMode();
void UpdateHostMouseMode();
bool IsRelativeMouseModeActive();

/// Sets the state of the specified macro button.
void SetMacroButtonState(u32 pad, u32 index, bool state);
Expand All @@ -359,6 +360,7 @@ bool IsUsingRawInput();

/// Updates InputManager's view of the window size, used for clamping raw input coordinates.
void SetDisplayWindowSize(float width, float height);
std::pair<float, float> GetDisplayWindowSize();

/// Restores default configuration.
void SetDefaultSourceConfig(SettingsInterface& si);
Expand Down
63 changes: 63 additions & 0 deletions src/util/sdl_input_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ void SDLInputSource::LoadSettings(const SettingsInterface& si)

m_controller_enhanced_mode = si.GetBoolValue("InputSources", "SDLControllerEnhancedMode", false);
m_controller_ps5_player_led = si.GetBoolValue("InputSources", "SDLPS5PlayerLED", false);
m_controller_touchpad_as_pointer = si.GetBoolValue("InputSources", "SDLTouchpadAsPointer", false);
m_sdl_hints = si.GetKeyValueList("SDLHints");

#ifdef __APPLE__
Expand Down Expand Up @@ -588,6 +589,9 @@ bool SDLInputSource::IsHandledInputEvent(const SDL_Event* ev)
case SDL_CONTROLLERAXISMOTION:
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
case SDL_CONTROLLERTOUCHPADDOWN:
case SDL_CONTROLLERTOUCHPADUP:
case SDL_CONTROLLERTOUCHPADMOTION:
case SDL_JOYAXISMOTION:
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
Expand Down Expand Up @@ -647,6 +651,11 @@ bool SDLInputSource::ProcessSDLEvent(const SDL_Event* event)
case SDL_CONTROLLERBUTTONUP:
return HandleControllerButtonEvent(&event->cbutton);

case SDL_CONTROLLERTOUCHPADDOWN:
case SDL_CONTROLLERTOUCHPADUP:
case SDL_CONTROLLERTOUCHPADMOTION:
return HandleControllerTouchpadEvent(&event->ctouchpad);

case SDL_JOYAXISMOTION:
return HandleJoystickAxisEvent(&event->jaxis);

Expand Down Expand Up @@ -755,6 +764,8 @@ bool SDLInputSource::OpenDevice(int index, bool is_gamecontroller)
cd.haptic_left_right_effect = -1;
cd.game_controller = gcontroller;
cd.joystick = joystick;
cd.last_touch_x = 0.0f;
cd.last_touch_y = 0.0f;

if (gcontroller)
{
Expand Down Expand Up @@ -896,6 +907,58 @@ bool SDLInputSource::HandleControllerButtonEvent(const SDL_ControllerButtonEvent
return true;
}

bool SDLInputSource::HandleControllerTouchpadEvent(const SDL_ControllerTouchpadEvent* ev)
{
// More than one touchpad?
if (ev->touchpad != 0 || !m_controller_touchpad_as_pointer)
return false;

auto it = GetControllerDataForJoystickId(ev->which);
if (it == m_controllers.end())
return false;

// Limited by InputManager pointers.
const u32 pointer_index = static_cast<u32>(it->player_id);
if (pointer_index >= InputManager::MAX_POINTER_DEVICES)
return false;

// Only looking at the first finger for motion for now.
if (ev->finger == 0)
{
// If down event, reset the position.
if (ev->type == SDL_CONTROLLERTOUCHPADDOWN)
{
it->last_touch_x = ev->x;
it->last_touch_y = ev->y;
}

const auto& [win_width, win_height] = InputManager::GetDisplayWindowSize();
const float rel_x = (ev->x - std::exchange(it->last_touch_x, ev->x)) * win_width;
const float rel_y = (ev->y - std::exchange(it->last_touch_y, ev->y)) * win_height;
if (!InputManager::IsRelativeMouseModeActive())
{
const auto& [current_x, current_y] = InputManager::GetPointerAbsolutePosition(pointer_index);
InputManager::UpdatePointerAbsolutePosition(pointer_index, current_x + rel_x, current_y + rel_y);
}
else
{
if (rel_x != 0.0f)
InputManager::UpdatePointerRelativeDelta(pointer_index, InputPointerAxis::X, rel_x);
if (rel_y != 0.0f)
InputManager::UpdatePointerRelativeDelta(pointer_index, InputPointerAxis::Y, rel_y);
}
}

// If down/up event, fire the clicked handler.
if (ev->type == SDL_CONTROLLERTOUCHPADDOWN || ev->type == SDL_CONTROLLERTOUCHPADUP)
{
const InputBindingKey key(InputManager::MakePointerButtonKey(pointer_index, static_cast<u32>(ev->finger)));
InputManager::InvokeEvents(key, (ev->type == SDL_CONTROLLERTOUCHPADUP) ? 0.0f : ev->pressure);
}

return true;
}

bool SDLInputSource::HandleJoystickAxisEvent(const SDL_JoyAxisEvent* ev)
{
auto it = GetControllerDataForJoystickId(ev->which);
Expand Down
4 changes: 4 additions & 0 deletions src/util/sdl_input_source.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class SDLInputSource final : public InputSource
int haptic_left_right_effect;
int joystick_id;
int player_id;
float last_touch_x;
float last_touch_y;
bool use_game_controller_rumble;

// Used to disable Joystick controls that are used in GameController inputs so we don't get double events
Expand All @@ -87,6 +89,7 @@ class SDLInputSource final : public InputSource
bool CloseDevice(int joystick_index);
bool HandleControllerAxisEvent(const SDL_ControllerAxisEvent* ev);
bool HandleControllerButtonEvent(const SDL_ControllerButtonEvent* ev);
bool HandleControllerTouchpadEvent(const SDL_ControllerTouchpadEvent* ev);
bool HandleJoystickAxisEvent(const SDL_JoyAxisEvent* ev);
bool HandleJoystickButtonEvent(const SDL_JoyButtonEvent* ev);
bool HandleJoystickHatEvent(const SDL_JoyHatEvent* ev);
Expand All @@ -100,6 +103,7 @@ class SDLInputSource final : public InputSource
bool m_sdl_subsystem_initialized = false;
bool m_controller_enhanced_mode = false;
bool m_controller_ps5_player_led = false;
bool m_controller_touchpad_as_pointer = false;

#ifdef __APPLE__
bool m_enable_iokit_driver = false;
Expand Down

0 comments on commit 0a124ee

Please sign in to comment.