summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2023-01-02 23:02:12 +0100
committerGitHub <noreply@github.com>2023-01-02 23:02:12 +0100
commitf13f54e3db532fe308dfaee5a94bcc50fbd1e175 (patch)
treeb743deb84bd80fa4ac59031933f5b65544ffe0b2 /Source/Core/InputCommon
parent6d95aa5c129ca603db3a5d6e76ff07ed3d9efffe (diff)
parent288fa635f92760f71f638a5a411e63fafe9cb44e (diff)
Merge pull request #11363 from TheConfuZzledDude/xinput2-scroll-axis
InputCommon/XInput2: Added an axis output for the scroll wheel
Diffstat (limited to 'Source/Core/InputCommon')
-rw-r--r--Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp103
-rw-r--r--Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h8
2 files changed, 80 insertions, 31 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp
index 0c5f5ffb01..c0594b6662 100644
--- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp
+++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp
@@ -49,6 +49,13 @@
// more responsive. This might be useful as a user-customizable option.
#define MOUSE_AXIS_SMOOTHING 1.5f
+// The scroll axis value should decay a lot faster than the mouse axes since
+// it should ideally register each click of the scroll wheel. Decreasing this
+// value makes it more likely that a scroll wheel input is registered, but less
+// likely to differentiate between different inputs, while increasing it will
+// more cleanly separate each scroll wheel click, but risks dropping some inputs
+#define SCROLL_AXIS_DECAY 1.1f
+
namespace ciface::XInput2
{
// This function will add zero or more KeyboardMouse objects to devices.
@@ -74,6 +81,7 @@ void PopulateDevices(void* const hwnd)
XIDeviceInfo* all_masters;
XIDeviceInfo* current_master;
+ double scroll_increment = 1.0f;
int num_masters;
all_masters = XIQueryDevice(dpy, XIAllMasterDevices, &num_masters);
@@ -81,12 +89,26 @@ void PopulateDevices(void* const hwnd)
for (int i = 0; i < num_masters; i++)
{
current_master = &all_masters[i];
+
if (current_master->use == XIMasterPointer)
{
+ // We need to query the master for the scroll wheel's increment, since the increment used
+ // varies depending on what input driver is being used. For example, xf86-libinput uses 120.0.
+ for (int j = 0; j < current_master->num_classes; j++)
+ {
+ if (current_master->classes[j]->type == XIScrollClass)
+ {
+ XIScrollClassInfo* scroll_event =
+ reinterpret_cast<XIScrollClassInfo*>(current_master->classes[j]);
+ scroll_increment = scroll_event->increment;
+ break;
+ }
+ }
// Since current_master is a master pointer, its attachment must
// be a master keyboard.
- g_controller_interface.AddDevice(std::make_shared<KeyboardMouse>(
- (Window)hwnd, xi_opcode, current_master->deviceid, current_master->attachment));
+ g_controller_interface.AddDevice(
+ std::make_shared<KeyboardMouse>((Window)hwnd, xi_opcode, current_master->deviceid,
+ current_master->attachment, scroll_increment));
}
}
@@ -128,8 +150,10 @@ void KeyboardMouse::SelectEventsForDevice(XIEventMask* mask, int deviceid)
XIFreeDeviceInfo(all_slaves);
}
-KeyboardMouse::KeyboardMouse(Window window, int opcode, int pointer, int keyboard)
- : m_window(window), xi_opcode(opcode), pointer_deviceid(pointer), keyboard_deviceid(keyboard)
+KeyboardMouse::KeyboardMouse(Window window, int opcode, int pointer, int keyboard,
+ double scroll_increment)
+ : m_window(window), xi_opcode(opcode), pointer_deviceid(pointer), keyboard_deviceid(keyboard),
+ scroll_increment(scroll_increment)
{
// The cool thing about each KeyboardMouse object having its own Display
// is that each one gets its own separate copy of the X11 event stream,
@@ -195,14 +219,21 @@ KeyboardMouse::KeyboardMouse(Window window, int opcode, int pointer, int keyboar
for (int i = 0; i != 4; ++i)
AddInput(new Cursor(!!(i & 2), !!(i & 1), (i & 2) ? &m_state.cursor.y : &m_state.cursor.x));
- // Mouse Axis, X-/+ and Y-/+
- for (int i = 0; i != 4; ++i)
- AddInput(new Axis(!!(i & 2), !!(i & 1), (i & 2) ? &m_state.axis.y : &m_state.axis.x));
-
- // Relative Mouse, X-/+ and Y-/+
- for (int i = 0; i != 4; ++i)
- AddInput(new RelativeMouse(!!(i & 2), !!(i & 1),
- (i & 2) ? &m_state.relative_mouse.y : &m_state.relative_mouse.x));
+ // Mouse Axis, X-/+, Y-/+ and Z-/+
+ AddInput(new Axis(0, false, &m_state.axis.x));
+ AddInput(new Axis(0, true, &m_state.axis.x));
+ AddInput(new Axis(1, false, &m_state.axis.y));
+ AddInput(new Axis(1, true, &m_state.axis.y));
+ AddInput(new Axis(2, false, &m_state.axis.z));
+ AddInput(new Axis(2, true, &m_state.axis.z));
+
+ // Relative Mouse, X-/+, Y-/+ and Z-/+
+ AddInput(new RelativeMouse(0, false, &m_state.relative_mouse.x));
+ AddInput(new RelativeMouse(0, true, &m_state.relative_mouse.x));
+ AddInput(new RelativeMouse(1, false, &m_state.relative_mouse.y));
+ AddInput(new RelativeMouse(1, true, &m_state.relative_mouse.y));
+ AddInput(new RelativeMouse(2, false, &m_state.relative_mouse.z));
+ AddInput(new RelativeMouse(2, true, &m_state.relative_mouse.z));
}
KeyboardMouse::~KeyboardMouse()
@@ -256,7 +287,7 @@ void KeyboardMouse::UpdateInput()
XFlush(m_display);
// for the axis controls
- float delta_x = 0.0f, delta_y = 0.0f;
+ float delta_x = 0.0f, delta_y = 0.0f, delta_z = 0.0f;
double delta_delta;
bool mouse_moved = false;
@@ -293,26 +324,39 @@ void KeyboardMouse::UpdateInput()
m_state.keyboard[dev_event->detail / 8] &= ~(1 << (dev_event->detail % 8));
break;
case XI_RawMotion:
+ {
mouse_moved = true;
- // always safe because there is always at least one byte in
- // raw_event->valuators.mask, and if a bit is set in the mask,
- // then the value in raw_values is also available.
- if (XIMaskIsSet(raw_event->valuators.mask, 0))
- {
- delta_delta = raw_event->raw_values[0];
- // test for inf and nan
- if (delta_delta == delta_delta && 1 + delta_delta != delta_delta)
- delta_x += delta_delta;
- }
- if (XIMaskIsSet(raw_event->valuators.mask, 1))
+ float values[4] = {};
+ size_t value_idx = 0;
+
+ // We only care about the first 4 axes, which should always be available at minimum
+ for (int i = 0; i < 4; ++i)
{
- delta_delta = raw_event->raw_values[1];
- // test for inf and nan
- if (delta_delta == delta_delta && 1 + delta_delta != delta_delta)
- delta_y += delta_delta;
+ if (XIMaskIsSet(raw_event->valuators.mask, i))
+ {
+ values[i] = raw_event->raw_values[value_idx++];
+ }
}
+
+ delta_delta = values[0];
+ // test for inf and nan
+ if (delta_delta == delta_delta && 1 + delta_delta != delta_delta)
+ delta_x += delta_delta;
+
+ delta_delta = values[1];
+ // test for inf and nan
+ if (delta_delta == delta_delta && 1 + delta_delta != delta_delta)
+ delta_y += delta_delta;
+
+ // Scroll wheel input gets scaled to be similar to the mouse axes
+ delta_delta = values[3] * 8.0 / scroll_increment;
+ // test for inf and nan
+ if (delta_delta == delta_delta && 1 + delta_delta != delta_delta)
+ delta_z += delta_delta;
+
break;
+ }
case XI_FocusOut:
// Clear keyboard state on FocusOut as we will not be receiving KeyRelease events.
m_state.keyboard.fill(0);
@@ -324,6 +368,7 @@ void KeyboardMouse::UpdateInput()
m_state.relative_mouse.x = delta_x;
m_state.relative_mouse.y = delta_y;
+ m_state.relative_mouse.z = delta_z;
// apply axis smoothing
m_state.axis.x *= MOUSE_AXIS_SMOOTHING;
@@ -332,6 +377,8 @@ void KeyboardMouse::UpdateInput()
m_state.axis.y *= MOUSE_AXIS_SMOOTHING;
m_state.axis.y += delta_y;
m_state.axis.y /= MOUSE_AXIS_SMOOTHING + 1.0f;
+ m_state.axis.z += delta_z;
+ m_state.axis.z /= SCROLL_AXIS_DECAY;
// Get the absolute position of the mouse pointer
const bool should_center_mouse =
diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h
index b07f6325c7..ff2c787b1d 100644
--- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h
+++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h
@@ -28,8 +28,8 @@ private:
std::array<char, 32> keyboard;
unsigned int buttons;
Common::Vec2 cursor;
- Common::Vec2 axis;
- Common::Vec2 relative_mouse;
+ Common::Vec3 axis;
+ Common::Vec3 relative_mouse;
};
class Key : public Input
@@ -113,7 +113,8 @@ private:
public:
void UpdateInput() override;
- KeyboardMouse(Window window, int opcode, int pointer_deviceid, int keyboard_deviceid);
+ KeyboardMouse(Window window, int opcode, int pointer_deviceid, int keyboard_deviceid,
+ double scroll_increment);
~KeyboardMouse();
std::string GetName() const override;
@@ -126,6 +127,7 @@ private:
const int xi_opcode;
const int pointer_deviceid;
const int keyboard_deviceid;
+ const double scroll_increment;
std::string name;
};
} // namespace ciface::XInput2