From 46540ea42babe23a6579d231dd3ea180b1fa39ad Mon Sep 17 00:00:00 2001 From: Jeffrey Bosboom Date: Sat, 15 Apr 2023 02:13:01 -0700 Subject: [PATCH] XInput2: Request XInput 2.1 We need XInput 2.1 to get raw events on the root window even while another client has a grab. We currently use raw events for relative mouse input, and upcoming commits will use raw events for buttons and keys. --- .../ControllerInterface/Xlib/XInput2.cpp | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp index db7052996c..4f93509f15 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp @@ -5,12 +5,14 @@ #include +#include #include #include #include #include +#include "Common/Logging/Log.h" #include "Common/StringUtil.h" #include "Core/Host.h" @@ -54,6 +56,14 @@ // more cleanly separate each scroll wheel click, but risks dropping some inputs #define SCROLL_AXIS_DECAY 1.1f +namespace +{ +// We need XInput 2.1 to get raw events on the root window even while another +// client has a grab. If we request 2.2 or later, the server will not generate +// emulated button presses from touch events, so we want exactly 2.1. +constexpr int XINPUT_MAJOR = 2, XINPUT_MINOR = 1; +} // namespace + namespace ciface::XInput2 { // This function will add zero or more KeyboardMouse objects to devices. @@ -67,13 +77,18 @@ void PopulateDevices(void* const hwnd) // verify that the XInput extension is available if (!XQueryExtension(dpy, "XInputExtension", &xi_opcode, &event, &error)) + { + WARN_LOG_FMT(CONTROLLERINTERFACE, "XInput extension not available (XQueryExtension)"); return; + } - // verify that the XInput extension is at at least version 2.0 - int major = 2, minor = 0; - - if (XIQueryVersion(dpy, &major, &minor) != Success) + int major = XINPUT_MAJOR, minor = XINPUT_MINOR; + if (XIQueryVersion(dpy, &major, &minor) != Success || major < XINPUT_MAJOR || + (major == XINPUT_MAJOR && minor < XINPUT_MINOR)) + { + WARN_LOG_FMT(CONTROLLERINTERFACE, "XInput extension not available (XIQueryVersion)"); return; + } // register all master devices with Dolphin @@ -160,6 +175,9 @@ KeyboardMouse::KeyboardMouse(Window window, int opcode, int pointer, int keyboar // "context." m_display = XOpenDisplay(nullptr); + int major = XINPUT_MAJOR, minor = XINPUT_MINOR; + XIQueryVersion(m_display, &major, &minor); + // should always be 1 int unused; XIDeviceInfo* const pointer_device = XIQueryDevice(m_display, pointer_deviceid, &unused);