mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 14:31:24 +12:00
gui/input: implement pad navigation for maxOs
This commit is contained in:
parent
2cd47c0415
commit
fc698a4df2
4 changed files with 102 additions and 2 deletions
|
@ -24,6 +24,8 @@
|
||||||
#include <linux/uinput.h>
|
#include <linux/uinput.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#define CHECK_IOCTRL_RET(res) if (res == -1) { gui_log.error("gui_pad_thread: ioctl failed (errno=%d=%s)", res, strerror(errno)); }
|
#define CHECK_IOCTRL_RET(res) if (res == -1) { gui_log.error("gui_pad_thread: ioctl failed (errno=%d=%s)", res, strerror(errno)); }
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
@ -349,6 +351,15 @@ void gui_pad_thread::process_input()
|
||||||
case pad_button::cross: key = KEY_ENTER; break;
|
case pad_button::cross: key = KEY_ENTER; break;
|
||||||
case pad_button::square: key = KEY_BACKSPACE; break;
|
case pad_button::square: key = KEY_BACKSPACE; break;
|
||||||
case pad_button::triangle: key = KEY_TAB; break;
|
case pad_button::triangle: key = KEY_TAB; break;
|
||||||
|
#elif defined (__APPLE__)
|
||||||
|
case pad_button::dpad_up: key = kVK_UpArrow; break;
|
||||||
|
case pad_button::dpad_down: key = kVK_DownArrow; break;
|
||||||
|
case pad_button::dpad_left: key = kVK_LeftArrow; break;
|
||||||
|
case pad_button::dpad_right: key = kVK_RightArrow; break;
|
||||||
|
case pad_button::circle: key = kVK_Escape; break;
|
||||||
|
case pad_button::cross: key = kVK_Return; break;
|
||||||
|
case pad_button::square: key = kVK_Delete; break;
|
||||||
|
case pad_button::triangle: key = kVK_Tab; break;
|
||||||
#endif
|
#endif
|
||||||
case pad_button::L1: btn = mouse_button::left; break;
|
case pad_button::L1: btn = mouse_button::left; break;
|
||||||
case pad_button::R1: btn = mouse_button::right; break;
|
case pad_button::R1: btn = mouse_button::right; break;
|
||||||
|
@ -614,6 +625,16 @@ void gui_pad_thread::send_key_event(u32 key, bool pressed)
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
emit_event(EV_KEY, key, pressed ? 1 : 0);
|
emit_event(EV_KEY, key, pressed ? 1 : 0);
|
||||||
emit_event(EV_SYN, SYN_REPORT, 0);
|
emit_event(EV_SYN, SYN_REPORT, 0);
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
CGEventRef ev = CGEventCreateKeyboardEvent(NULL, static_cast<CGKeyCode>(key), pressed);
|
||||||
|
if (!ev)
|
||||||
|
{
|
||||||
|
gui_log.error("gui_pad_thread: CGEventCreateKeyboardEvent() failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGEventPost(kCGHIDEventTap, ev);
|
||||||
|
CFRelease(ev);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,6 +671,36 @@ void gui_pad_thread::send_mouse_button_event(mouse_button btn, bool pressed)
|
||||||
|
|
||||||
emit_event(EV_KEY, key, pressed ? 1 : 0);
|
emit_event(EV_KEY, key, pressed ? 1 : 0);
|
||||||
emit_event(EV_SYN, SYN_REPORT, 0);
|
emit_event(EV_SYN, SYN_REPORT, 0);
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
CGEventType type{};
|
||||||
|
CGMouseButton mouse_btn{};
|
||||||
|
|
||||||
|
switch (btn)
|
||||||
|
{
|
||||||
|
case mouse_button::none: return;
|
||||||
|
case mouse_button::left:
|
||||||
|
type = pressed ? kCGEventLeftMouseDown : kCGEventLeftMouseUp;
|
||||||
|
mouse_btn = kCGMouseButtonLeft;
|
||||||
|
break;
|
||||||
|
case mouse_button::right:
|
||||||
|
type = pressed ? kCGEventRightMouseDown : kCGEventRightMouseUp;
|
||||||
|
mouse_btn = kCGMouseButtonRight;
|
||||||
|
break;
|
||||||
|
case mouse_button::middle:
|
||||||
|
type = pressed ? kCGEventOtherMouseDown : kCGEventOtherMouseUp;
|
||||||
|
mouse_btn = kCGMouseButtonCenter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGEventRef ev = CGEventCreateMouseEvent(NULL, type, CGPointMake(m_mouse_abs_x, m_mouse_abs_y), mouse_btn);
|
||||||
|
if (!ev)
|
||||||
|
{
|
||||||
|
gui_log.error("gui_pad_thread: CGEventCreateMouseEvent() failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGEventPost(kCGHIDEventTap, ev);
|
||||||
|
CFRelease(ev);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,6 +741,27 @@ void gui_pad_thread::send_mouse_wheel_event(mouse_wheel wheel, int delta)
|
||||||
|
|
||||||
emit_event(EV_REL, axis, delta);
|
emit_event(EV_REL, axis, delta);
|
||||||
emit_event(EV_SYN, SYN_REPORT, 0);
|
emit_event(EV_SYN, SYN_REPORT, 0);
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
int v_delta = 0;
|
||||||
|
int h_delta = 0;
|
||||||
|
|
||||||
|
switch (wheel)
|
||||||
|
{
|
||||||
|
case mouse_wheel::none: return;
|
||||||
|
case mouse_wheel::vertical: v_delta = delta; break;
|
||||||
|
case mouse_wheel::horizontal: h_delta = delta; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr u32 wheel_count = 2;
|
||||||
|
CGEventRef ev = CGEventCreateScrollWheelEvent(NULL, CGScrollEventUnit::pixel, wheel_count, v_delta, h_delta);
|
||||||
|
if (!ev)
|
||||||
|
{
|
||||||
|
gui_log.error("gui_pad_thread: CGEventCreateScrollWheelEvent() failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGEventPost(kCGHIDEventTap, ev);
|
||||||
|
CFRelease(ev);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,5 +789,29 @@ void gui_pad_thread::send_mouse_move_event(int delta_x, int delta_y)
|
||||||
if (delta_x) emit_event(EV_REL, REL_X, delta_x);
|
if (delta_x) emit_event(EV_REL, REL_X, delta_x);
|
||||||
if (delta_y) emit_event(EV_REL, REL_Y, delta_y);
|
if (delta_y) emit_event(EV_REL, REL_Y, delta_y);
|
||||||
emit_event(EV_SYN, SYN_REPORT, 0);
|
emit_event(EV_SYN, SYN_REPORT, 0);
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
CGDirectDisplayID display = CGMainDisplayID();
|
||||||
|
const usz width = CGDisplayPixelsWide(display);
|
||||||
|
const usz height = CGDisplayPixelsHigh(display);
|
||||||
|
const float mouse_abs_x = std::clamp(m_mouse_abs_x + delta_x, 0.0f, width - 1.0f);
|
||||||
|
const float mouse_abs_y = std::clamp(m_mouse_abs_y + delta_y, 0.0f, height - 1.0f);
|
||||||
|
|
||||||
|
if (m_mouse_abs_x == mouse_abs_x && m_mouse_abs_y == mouse_abs_y)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_mouse_abs_x = mouse_abs_x;
|
||||||
|
m_mouse_abs_y = mouse_abs_y;
|
||||||
|
|
||||||
|
CGEventRef ev = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, CGPointMake(m_mouse_abs_x, m_mouse_abs_y), {});
|
||||||
|
if (!ev)
|
||||||
|
{
|
||||||
|
gui_log.error("gui_pad_thread: CGEventCreateMouseEvent() failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGEventPost(kCGHIDEventTap, ev);
|
||||||
|
CFRelease(ev);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,4 +91,8 @@ protected:
|
||||||
bool m_boost_mouse = false;
|
bool m_boost_mouse = false;
|
||||||
float m_mouse_delta_x = 0.0f;
|
float m_mouse_delta_x = 0.0f;
|
||||||
float m_mouse_delta_y = 0.0f;
|
float m_mouse_delta_y = 0.0f;
|
||||||
|
#ifdef __APPLE__
|
||||||
|
float m_mouse_abs_x = 0.0f;
|
||||||
|
float m_mouse_abs_y = 0.0f;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -272,7 +272,7 @@ void main_window::update_gui_pad_thread()
|
||||||
|
|
||||||
if (enabled && Emu.IsStopped())
|
if (enabled && Emu.IsStopped())
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) || defined(__linux__)
|
#if defined(_WIN32) || defined(__linux__) || defined(__APPLE__)
|
||||||
if (!m_gui_pad_thread)
|
if (!m_gui_pad_thread)
|
||||||
{
|
{
|
||||||
m_gui_pad_thread = std::make_unique<gui_pad_thread>();
|
m_gui_pad_thread = std::make_unique<gui_pad_thread>();
|
||||||
|
|
|
@ -2081,7 +2081,7 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||||
SubscribeTooltip(ui->cb_global_pad_navigation, tooltips.settings.global_navigation);
|
SubscribeTooltip(ui->cb_global_pad_navigation, tooltips.settings.global_navigation);
|
||||||
ui->cb_pad_navigation->setChecked(m_gui_settings->GetValue(gui::nav_enabled).toBool());
|
ui->cb_pad_navigation->setChecked(m_gui_settings->GetValue(gui::nav_enabled).toBool());
|
||||||
ui->cb_global_pad_navigation->setChecked(m_gui_settings->GetValue(gui::nav_global).toBool());
|
ui->cb_global_pad_navigation->setChecked(m_gui_settings->GetValue(gui::nav_global).toBool());
|
||||||
#if defined(_WIN32) || defined(__linux__)
|
#if defined(_WIN32) || defined(__linux__) || defined(__APPLE__)
|
||||||
connect(ui->cb_pad_navigation, &QCheckBox::toggled, [this](bool checked)
|
connect(ui->cb_pad_navigation, &QCheckBox::toggled, [this](bool checked)
|
||||||
{
|
{
|
||||||
m_gui_settings->SetValue(gui::nav_enabled, checked);
|
m_gui_settings->SetValue(gui::nav_enabled, checked);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue