2020-12-05 13:08:24 +01:00
|
|
|
#pragma once
|
2019-09-20 16:28:55 +02:00
|
|
|
#ifdef HAVE_LIBEVDEV
|
2017-07-26 20:03:06 +02:00
|
|
|
|
2020-12-22 09:42:57 +01:00
|
|
|
#include "util/types.hpp"
|
2025-04-08 18:46:57 +02:00
|
|
|
#include "util/File.h"
|
2017-07-26 20:03:06 +02:00
|
|
|
#include "Emu/Io/PadHandler.h"
|
|
|
|
|
#include <libevdev/libevdev.h>
|
2020-12-22 09:42:57 +01:00
|
|
|
#include <memory>
|
|
|
|
|
#include <unordered_map>
|
2022-08-13 09:56:04 +02:00
|
|
|
#include <array>
|
2017-07-26 20:03:06 +02:00
|
|
|
#include <vector>
|
2017-12-03 19:16:41 +01:00
|
|
|
#include <ctime>
|
2017-07-26 20:03:06 +02:00
|
|
|
|
2017-12-23 12:28:10 +01:00
|
|
|
struct positive_axis : cfg::node
|
|
|
|
|
{
|
|
|
|
|
const std::string cfg_name = fs::get_config_dir() + "/evdev_positive_axis.yml";
|
|
|
|
|
|
2025-04-05 21:50:45 +02:00
|
|
|
cfg::_bool abs_x{this, "ABS_X", false};
|
|
|
|
|
cfg::_bool abs_y{this, "ABS_Y", false};
|
|
|
|
|
cfg::_bool abs_z{this, "ABS_Z", false};
|
|
|
|
|
cfg::_bool abs_rx{this, "ABS_RX", false};
|
|
|
|
|
cfg::_bool abs_ry{this, "ABS_RY", false};
|
|
|
|
|
cfg::_bool abs_rz{this, "ABS_RZ", false};
|
|
|
|
|
cfg::_bool abs_throttle{this, "ABS_THROTTLE", false};
|
|
|
|
|
cfg::_bool abs_rudder{this, "ABS_RUDDER", false};
|
|
|
|
|
cfg::_bool abs_wheel{this, "ABS_WHEEL", false};
|
|
|
|
|
cfg::_bool abs_gas{this, "ABS_GAS", false};
|
|
|
|
|
cfg::_bool abs_brake{this, "ABS_BRAKE", false};
|
|
|
|
|
cfg::_bool abs_hat0x{this, "ABS_HAT0X", false};
|
|
|
|
|
cfg::_bool abs_hat0y{this, "ABS_HAT0Y", false};
|
|
|
|
|
cfg::_bool abs_hat1x{this, "ABS_HAT1X", false};
|
|
|
|
|
cfg::_bool abs_hat1y{this, "ABS_HAT1Y", false};
|
|
|
|
|
cfg::_bool abs_hat2x{this, "ABS_HAT2X", false};
|
|
|
|
|
cfg::_bool abs_hat2y{this, "ABS_HAT2Y", false};
|
|
|
|
|
cfg::_bool abs_hat3x{this, "ABS_HAT3X", false};
|
|
|
|
|
cfg::_bool abs_hat3y{this, "ABS_HAT3Y", false};
|
|
|
|
|
cfg::_bool abs_pressure{this, "ABS_PRESSURE", false};
|
|
|
|
|
cfg::_bool abs_distance{this, "ABS_DISTANCE", false};
|
|
|
|
|
cfg::_bool abs_tilt_x{this, "ABS_TILT_X", false};
|
|
|
|
|
cfg::_bool abs_tilt_y{this, "ABS_TILT_Y", false};
|
|
|
|
|
cfg::_bool abs_tool_width{this, "ABS_TOOL_WIDTH", false};
|
|
|
|
|
cfg::_bool abs_volume{this, "ABS_VOLUME", false};
|
|
|
|
|
cfg::_bool abs_misc{this, "ABS_MISC", false};
|
|
|
|
|
cfg::_bool abs_mt_slot{this, "ABS_MT_SLOT", false};
|
|
|
|
|
cfg::_bool abs_mt_touch_major{this, "ABS_MT_TOUCH_MAJOR", false};
|
|
|
|
|
cfg::_bool abs_mt_touch_minor{this, "ABS_MT_TOUCH_MINOR", false};
|
|
|
|
|
cfg::_bool abs_mt_width_major{this, "ABS_MT_WIDTH_MAJOR", false};
|
|
|
|
|
cfg::_bool abs_mt_width_minor{this, "ABS_MT_WIDTH_MINOR", false};
|
|
|
|
|
cfg::_bool abs_mt_orientation{this, "ABS_MT_ORIENTATION", false};
|
|
|
|
|
cfg::_bool abs_mt_position_x{this, "ABS_MT_POSITION_X", false};
|
|
|
|
|
cfg::_bool abs_mt_position_y{this, "ABS_MT_POSITION_Y", false};
|
|
|
|
|
cfg::_bool abs_mt_tool_type{this, "ABS_MT_TOOL_TYPE", false};
|
|
|
|
|
cfg::_bool abs_mt_blob_id{this, "ABS_MT_BLOB_ID", false};
|
|
|
|
|
cfg::_bool abs_mt_tracking_id{this, "ABS_MT_TRACKING_ID", false};
|
|
|
|
|
cfg::_bool abs_mt_pressure{this, "ABS_MT_PRESSURE", false};
|
|
|
|
|
cfg::_bool abs_mt_distance{this, "ABS_MT_DISTANCE", false};
|
|
|
|
|
cfg::_bool abs_mt_tool_x{this, "ABS_MT_TOOL_X", false};
|
|
|
|
|
cfg::_bool abs_mt_tool_y{this, "ABS_MT_TOOL_Y", false};
|
2017-12-23 12:28:10 +01:00
|
|
|
|
|
|
|
|
bool load()
|
|
|
|
|
{
|
2025-04-05 21:50:45 +02:00
|
|
|
if (fs::file cfg_file{cfg_name, fs::read})
|
2017-12-23 12:28:10 +01:00
|
|
|
{
|
|
|
|
|
return from_string(cfg_file.to_string());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void save()
|
|
|
|
|
{
|
2024-06-10 10:49:00 +02:00
|
|
|
fs::pending_file file(cfg_name);
|
|
|
|
|
|
|
|
|
|
if (file.file)
|
|
|
|
|
{
|
|
|
|
|
file.file.write(to_string());
|
|
|
|
|
file.commit();
|
|
|
|
|
}
|
2017-12-23 12:28:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool exist()
|
|
|
|
|
{
|
|
|
|
|
return fs::is_file(cfg_name);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2017-11-27 22:31:15 +01:00
|
|
|
class evdev_joystick_handler final : public PadHandlerBase
|
2017-07-26 20:03:06 +02:00
|
|
|
{
|
2021-08-08 16:45:45 +02:00
|
|
|
static constexpr u32 NO_BUTTON = u32{umax}; // Some event code that doesn't exist in evdev (code type is U16)
|
|
|
|
|
|
2017-11-27 22:31:15 +01:00
|
|
|
// Unique button names for the config files and our pad settings dialog
|
|
|
|
|
const std::unordered_map<u32, std::string> button_list =
|
2025-04-05 21:50:45 +02:00
|
|
|
{
|
|
|
|
|
{NO_BUTTON, ""},
|
|
|
|
|
// Xbox One S Controller returns some buttons as key when connected through bluetooth
|
|
|
|
|
{KEY_BACK, "Back Key"},
|
|
|
|
|
{KEY_HOMEPAGE, "Homepage Key"},
|
|
|
|
|
// Wii/Wii U Controller drivers use the following few keys
|
|
|
|
|
{KEY_UP, "Up Key"},
|
|
|
|
|
{KEY_LEFT, "Left Key"},
|
|
|
|
|
{KEY_RIGHT, "Right Key"},
|
|
|
|
|
{KEY_DOWN, "Down Key"},
|
|
|
|
|
{KEY_NEXT, "Next Key"},
|
|
|
|
|
{KEY_PREVIOUS, "Previous Key"},
|
|
|
|
|
//{ BTN_MISC , "Misc" }, same as BTN_0
|
|
|
|
|
{BTN_0, "0"},
|
|
|
|
|
{BTN_1, "1"},
|
|
|
|
|
{BTN_2, "2"},
|
|
|
|
|
{BTN_3, "3"},
|
|
|
|
|
{BTN_4, "4"},
|
|
|
|
|
{BTN_5, "5"},
|
|
|
|
|
{BTN_6, "6"},
|
|
|
|
|
{BTN_7, "7"},
|
|
|
|
|
{BTN_8, "8"},
|
|
|
|
|
{BTN_9, "9"},
|
|
|
|
|
{0x10a, "0x10a"},
|
|
|
|
|
{0x10b, "0x10b"},
|
|
|
|
|
{0x10c, "0x10c"},
|
|
|
|
|
{0x10d, "0x10d"},
|
|
|
|
|
{0x10e, "0x10e"},
|
|
|
|
|
{0x10f, "0x10f"},
|
|
|
|
|
//{ BTN_MOUSE , "Mouse" }, same as BTN_LEFT
|
|
|
|
|
{BTN_LEFT, "Left"},
|
|
|
|
|
{BTN_RIGHT, "Right"},
|
|
|
|
|
{BTN_MIDDLE, "Middle"},
|
|
|
|
|
{BTN_SIDE, "Side"},
|
|
|
|
|
{BTN_EXTRA, "Extra"},
|
|
|
|
|
{BTN_FORWARD, "Forward"},
|
|
|
|
|
{BTN_BACK, "Back"},
|
|
|
|
|
{BTN_TASK, "Task"},
|
|
|
|
|
{0x118, "0x118"},
|
|
|
|
|
{0x119, "0x119"},
|
|
|
|
|
{0x11a, "0x11a"},
|
|
|
|
|
{0x11b, "0x11b"},
|
|
|
|
|
{0x11c, "0x11c"},
|
|
|
|
|
{0x11d, "0x11d"},
|
|
|
|
|
{0x11e, "0x11e"},
|
|
|
|
|
{0x11f, "0x11f"},
|
|
|
|
|
//{ BTN_JOYSTICK , "Joystick" }, same as BTN_TRIGGER
|
|
|
|
|
{BTN_TRIGGER, "Trigger"},
|
|
|
|
|
{BTN_THUMB, "Thumb"},
|
|
|
|
|
{BTN_THUMB2, "Thumb 2"},
|
|
|
|
|
{BTN_TOP, "Top"},
|
|
|
|
|
{BTN_TOP2, "Top 2"},
|
|
|
|
|
{BTN_PINKIE, "Pinkie"},
|
|
|
|
|
{BTN_BASE, "Base"},
|
|
|
|
|
{BTN_BASE2, "Base 2"},
|
|
|
|
|
{BTN_BASE3, "Base 3"},
|
|
|
|
|
{BTN_BASE4, "Base 4"},
|
|
|
|
|
{BTN_BASE5, "Base 5"},
|
|
|
|
|
{BTN_BASE6, "Base 6"},
|
|
|
|
|
{0x12c, "0x12c"},
|
|
|
|
|
{0x12d, "0x12d"},
|
|
|
|
|
{0x12e, "0x12e"},
|
|
|
|
|
{BTN_DEAD, "Dead"},
|
|
|
|
|
//{ BTN_GAMEPAD , "Gamepad" }, same as BTN_A
|
|
|
|
|
//{ BTN_SOUTH , "South" }, same as BTN_A
|
|
|
|
|
{BTN_A, "A"},
|
|
|
|
|
//{ BTN_EAST , "South" }, same as BTN_B
|
|
|
|
|
{BTN_B, "B"},
|
|
|
|
|
{BTN_C, "C"},
|
|
|
|
|
//{ BTN_NORTH , "North" }, same as BTN_X
|
|
|
|
|
{BTN_X, "X"},
|
|
|
|
|
//{ BTN_WEST , "West" }, same as BTN_Y
|
|
|
|
|
{BTN_Y, "Y"},
|
|
|
|
|
{BTN_Z, "Z"},
|
|
|
|
|
{BTN_TL, "TL"},
|
|
|
|
|
{BTN_TR, "TR"},
|
|
|
|
|
{BTN_TL2, "TL 2"},
|
|
|
|
|
{BTN_TR2, "TR 2"},
|
|
|
|
|
{BTN_SELECT, "Select"},
|
|
|
|
|
{BTN_START, "Start"},
|
|
|
|
|
{BTN_MODE, "Mode"},
|
|
|
|
|
{BTN_THUMBL, "Thumb L"},
|
|
|
|
|
{BTN_THUMBR, "Thumb R"},
|
|
|
|
|
{0x13f, "0x13f"},
|
|
|
|
|
//{ BTN_DIGI , "Digi" }, same as BTN_TOOL_PEN
|
|
|
|
|
{BTN_TOOL_PEN, "Pen"},
|
|
|
|
|
{BTN_TOOL_RUBBER, "Rubber"},
|
|
|
|
|
{BTN_TOOL_BRUSH, "Brush"},
|
|
|
|
|
{BTN_TOOL_PENCIL, "Pencil"},
|
|
|
|
|
{BTN_TOOL_AIRBRUSH, "Airbrush"},
|
|
|
|
|
{BTN_TOOL_FINGER, "Finger"},
|
|
|
|
|
{BTN_TOOL_MOUSE, "Mouse"},
|
|
|
|
|
{BTN_TOOL_LENS, "Lense"},
|
|
|
|
|
{BTN_TOOL_QUINTTAP, "Quinttap"},
|
|
|
|
|
{0x149, "0x149"},
|
|
|
|
|
{BTN_TOUCH, "Touch"},
|
|
|
|
|
{BTN_STYLUS, "Stylus"},
|
|
|
|
|
{BTN_STYLUS2, "Stylus 2"},
|
|
|
|
|
{BTN_TOOL_DOUBLETAP, "Doubletap"},
|
|
|
|
|
{BTN_TOOL_TRIPLETAP, "Tripletap"},
|
|
|
|
|
{BTN_TOOL_QUADTAP, "Quadtap"},
|
|
|
|
|
//{ BTN_WHEEL , "Wheel" }, same as BTN_GEAR_DOWN
|
|
|
|
|
{BTN_GEAR_DOWN, "Gear Up"},
|
|
|
|
|
{BTN_GEAR_UP, "Gear Down"},
|
|
|
|
|
{BTN_DPAD_UP, "D-Pad Up"},
|
|
|
|
|
{BTN_DPAD_DOWN, "D-Pad Down"},
|
|
|
|
|
{BTN_DPAD_LEFT, "D-Pad Left"},
|
|
|
|
|
{BTN_DPAD_RIGHT, "D-Pad Right"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY, "Happy"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY1, "Happy 1"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY2, "Happy 2"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY3, "Happy 3"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY4, "Happy 4"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY5, "Happy 5"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY6, "Happy 6"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY7, "Happy 7"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY8, "Happy 8"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY9, "Happy 9"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY10, "Happy 10"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY11, "Happy 11"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY12, "Happy 12"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY13, "Happy 13"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY14, "Happy 14"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY15, "Happy 15"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY16, "Happy 16"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY17, "Happy 17"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY18, "Happy 18"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY19, "Happy 19"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY20, "Happy 20"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY21, "Happy 21"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY22, "Happy 22"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY23, "Happy 23"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY24, "Happy 24"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY25, "Happy 25"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY26, "Happy 26"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY27, "Happy 27"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY28, "Happy 28"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY29, "Happy 29"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY30, "Happy 30"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY31, "Happy 31"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY32, "Happy 32"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY33, "Happy 33"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY34, "Happy 34"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY35, "Happy 35"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY36, "Happy 36"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY37, "Happy 37"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY38, "Happy 38"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY39, "Happy 39"},
|
|
|
|
|
{BTN_TRIGGER_HAPPY40, "Happy 40"}};
|
2017-07-26 20:03:06 +02:00
|
|
|
|
2017-11-27 22:31:15 +01:00
|
|
|
// Unique positive axis names for the config files and our pad settings dialog
|
|
|
|
|
const std::unordered_map<u32, std::string> axis_list =
|
2025-04-05 21:50:45 +02:00
|
|
|
{
|
|
|
|
|
{ABS_X, "LX+"},
|
|
|
|
|
{ABS_Y, "LY+"},
|
|
|
|
|
{ABS_Z, "LZ+"},
|
|
|
|
|
{ABS_RX, "RX+"},
|
|
|
|
|
{ABS_RY, "RY+"},
|
|
|
|
|
{ABS_RZ, "RZ+"},
|
|
|
|
|
{ABS_THROTTLE, "Throttle+"},
|
|
|
|
|
{ABS_RUDDER, "Rudder+"},
|
|
|
|
|
{ABS_WHEEL, "Wheel+"},
|
|
|
|
|
{ABS_GAS, "Gas+"},
|
|
|
|
|
{ABS_BRAKE, "Brake+"},
|
|
|
|
|
{ABS_HAT0X, "Hat0 X+"},
|
|
|
|
|
{ABS_HAT0Y, "Hat0 Y+"},
|
|
|
|
|
{ABS_HAT1X, "Hat1 X+"},
|
|
|
|
|
{ABS_HAT1Y, "Hat1 Y+"},
|
|
|
|
|
{ABS_HAT2X, "Hat2 X+"},
|
|
|
|
|
{ABS_HAT2Y, "Hat2 Y+"},
|
|
|
|
|
{ABS_HAT3X, "Hat3 X+"},
|
|
|
|
|
{ABS_HAT3Y, "Hat3 Y+"},
|
|
|
|
|
{ABS_PRESSURE, "Pressure+"},
|
|
|
|
|
{ABS_DISTANCE, "Distance+"},
|
|
|
|
|
{ABS_TILT_X, "Tilt X+"},
|
|
|
|
|
{ABS_TILT_Y, "Tilt Y+"},
|
|
|
|
|
{ABS_TOOL_WIDTH, "Width+"},
|
|
|
|
|
{ABS_VOLUME, "Volume+"},
|
|
|
|
|
{ABS_MISC, "Misc+"},
|
|
|
|
|
{ABS_MT_SLOT, "Slot+"},
|
|
|
|
|
{ABS_MT_TOUCH_MAJOR, "MT TMaj+"},
|
|
|
|
|
{ABS_MT_TOUCH_MINOR, "MT TMin+"},
|
|
|
|
|
{ABS_MT_WIDTH_MAJOR, "MT WMaj+"},
|
|
|
|
|
{ABS_MT_WIDTH_MINOR, "MT WMin+"},
|
|
|
|
|
{ABS_MT_ORIENTATION, "MT Orient+"},
|
|
|
|
|
{ABS_MT_POSITION_X, "MT PosX+"},
|
|
|
|
|
{ABS_MT_POSITION_Y, "MT PosY+"},
|
|
|
|
|
{ABS_MT_TOOL_TYPE, "MT TType+"},
|
|
|
|
|
{ABS_MT_BLOB_ID, "MT Blob ID+"},
|
|
|
|
|
{ABS_MT_TRACKING_ID, "MT Track ID+"},
|
|
|
|
|
{ABS_MT_PRESSURE, "MT Pressure+"},
|
|
|
|
|
{ABS_MT_DISTANCE, "MT Distance+"},
|
|
|
|
|
{ABS_MT_TOOL_X, "MT Tool X+"},
|
|
|
|
|
{ABS_MT_TOOL_Y, "MT Tool Y+"},
|
|
|
|
|
};
|
2017-07-26 20:03:06 +02:00
|
|
|
|
2017-11-27 22:31:15 +01:00
|
|
|
// Unique negative axis names for the config files and our pad settings dialog
|
|
|
|
|
const std::unordered_map<u32, std::string> rev_axis_list =
|
2025-04-05 21:50:45 +02:00
|
|
|
{
|
|
|
|
|
{ABS_X, "LX-"},
|
|
|
|
|
{ABS_Y, "LY-"},
|
|
|
|
|
{ABS_Z, "LZ-"},
|
|
|
|
|
{ABS_RX, "RX-"},
|
|
|
|
|
{ABS_RY, "RY-"},
|
|
|
|
|
{ABS_RZ, "RZ-"},
|
|
|
|
|
{ABS_THROTTLE, "Throttle-"},
|
|
|
|
|
{ABS_RUDDER, "Rudder-"},
|
|
|
|
|
{ABS_WHEEL, "Wheel-"},
|
|
|
|
|
{ABS_GAS, "Gas-"},
|
|
|
|
|
{ABS_BRAKE, "Brake-"},
|
|
|
|
|
{ABS_HAT0X, "Hat0 X-"},
|
|
|
|
|
{ABS_HAT0Y, "Hat0 Y-"},
|
|
|
|
|
{ABS_HAT1X, "Hat1 X-"},
|
|
|
|
|
{ABS_HAT1Y, "Hat1 Y-"},
|
|
|
|
|
{ABS_HAT2X, "Hat2 X-"},
|
|
|
|
|
{ABS_HAT2Y, "Hat2 Y-"},
|
|
|
|
|
{ABS_HAT3X, "Hat3 X-"},
|
|
|
|
|
{ABS_HAT3Y, "Hat3 Y-"},
|
|
|
|
|
{ABS_PRESSURE, "Pressure-"},
|
|
|
|
|
{ABS_DISTANCE, "Distance-"},
|
|
|
|
|
{ABS_TILT_X, "Tilt X-"},
|
|
|
|
|
{ABS_TILT_Y, "Tilt Y-"},
|
|
|
|
|
{ABS_TOOL_WIDTH, "Width-"},
|
|
|
|
|
{ABS_VOLUME, "Volume-"},
|
|
|
|
|
{ABS_MISC, "Misc-"},
|
|
|
|
|
{ABS_MT_SLOT, "Slot-"},
|
|
|
|
|
{ABS_MT_TOUCH_MAJOR, "MT TMaj-"},
|
|
|
|
|
{ABS_MT_TOUCH_MINOR, "MT TMin-"},
|
|
|
|
|
{ABS_MT_WIDTH_MAJOR, "MT WMaj-"},
|
|
|
|
|
{ABS_MT_WIDTH_MINOR, "MT WMin-"},
|
|
|
|
|
{ABS_MT_ORIENTATION, "MT Orient-"},
|
|
|
|
|
{ABS_MT_POSITION_X, "MT PosX-"},
|
|
|
|
|
{ABS_MT_POSITION_Y, "MT PosY-"},
|
|
|
|
|
{ABS_MT_TOOL_TYPE, "MT TType-"},
|
|
|
|
|
{ABS_MT_BLOB_ID, "MT Blob ID-"},
|
|
|
|
|
{ABS_MT_TRACKING_ID, "MT Track ID-"},
|
|
|
|
|
{ABS_MT_PRESSURE, "MT Pressure-"},
|
|
|
|
|
{ABS_MT_DISTANCE, "MT Distance-"},
|
|
|
|
|
{ABS_MT_TOOL_X, "MT Tool X-"},
|
|
|
|
|
{ABS_MT_TOOL_Y, "MT Tool Y-"},
|
|
|
|
|
};
|
2017-07-26 20:03:06 +02:00
|
|
|
|
2022-08-13 09:56:04 +02:00
|
|
|
// Unique motion axis names for the config files and our pad settings dialog
|
|
|
|
|
const std::unordered_map<u32, std::string> motion_axis_list =
|
2025-04-05 21:50:45 +02:00
|
|
|
{
|
|
|
|
|
{ABS_X, "X"},
|
|
|
|
|
{ABS_Y, "Y"},
|
|
|
|
|
{ABS_Z, "Z"},
|
|
|
|
|
{ABS_RX, "RX"},
|
|
|
|
|
{ABS_RY, "RY"},
|
|
|
|
|
{ABS_RZ, "RZ"},
|
|
|
|
|
};
|
2022-08-13 09:56:04 +02:00
|
|
|
|
2017-12-01 16:03:17 +01:00
|
|
|
struct EvdevButton
|
|
|
|
|
{
|
2023-06-13 01:19:32 +02:00
|
|
|
u32 code = 0; // key code of our button or axis
|
|
|
|
|
int dir = 0; // dir is -1 in case of a button, 0 in case of a regular axis and 1 in case of a reverse axis
|
|
|
|
|
int type = 0; // EV_KEY or EV_ABS
|
2022-08-13 09:56:04 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct evdev_sensor : public EvdevButton
|
|
|
|
|
{
|
|
|
|
|
bool mirrored = false;
|
|
|
|
|
s32 shift = 0;
|
2017-12-01 16:03:17 +01:00
|
|
|
};
|
|
|
|
|
|
2023-06-14 20:57:30 +02:00
|
|
|
struct input_event_wrapper
|
|
|
|
|
{
|
|
|
|
|
int type{}; // EV_KEY or EV_ABS
|
|
|
|
|
bool is_initialized{};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct key_event_wrapper : public input_event_wrapper
|
|
|
|
|
{
|
2025-04-05 21:50:45 +02:00
|
|
|
key_event_wrapper()
|
|
|
|
|
{
|
|
|
|
|
type = EV_KEY;
|
|
|
|
|
}
|
2023-06-14 20:57:30 +02:00
|
|
|
u16 value{};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct axis_event_wrapper : public input_event_wrapper
|
|
|
|
|
{
|
2025-04-05 21:50:45 +02:00
|
|
|
axis_event_wrapper()
|
|
|
|
|
{
|
|
|
|
|
type = EV_ABS;
|
|
|
|
|
}
|
2023-06-14 20:57:30 +02:00
|
|
|
std::map<bool, u16> values{}; // direction (negative = true)
|
|
|
|
|
bool is_trigger{};
|
|
|
|
|
int min{};
|
|
|
|
|
int max{};
|
2023-12-11 22:03:40 +01:00
|
|
|
int flat{};
|
2023-06-14 20:57:30 +02:00
|
|
|
};
|
|
|
|
|
|
2019-09-20 16:28:55 +02:00
|
|
|
struct EvdevDevice : public PadDevice
|
2017-11-27 22:31:15 +01:00
|
|
|
{
|
2025-04-05 21:50:45 +02:00
|
|
|
libevdev* device{nullptr};
|
2017-11-27 22:31:15 +01:00
|
|
|
std::string path;
|
2023-06-13 01:19:32 +02:00
|
|
|
std::vector<EvdevButton> all_buttons;
|
|
|
|
|
std::set<u32> trigger_left{};
|
|
|
|
|
std::set<u32> trigger_right{};
|
|
|
|
|
std::array<std::set<u32>, 4> axis_left{};
|
|
|
|
|
std::array<std::set<u32>, 4> axis_right{};
|
2022-08-13 09:56:04 +02:00
|
|
|
std::array<evdev_sensor, 4> axis_motion{};
|
2023-06-14 20:57:30 +02:00
|
|
|
std::map<u32, std::shared_ptr<input_event_wrapper>> events_by_code;
|
2017-12-01 16:03:17 +01:00
|
|
|
int cur_dir = 0;
|
|
|
|
|
int cur_type = 0;
|
2017-12-02 11:45:58 +01:00
|
|
|
int effect_id = -1;
|
|
|
|
|
bool has_rumble = false;
|
2022-08-13 09:56:04 +02:00
|
|
|
bool has_motion = false;
|
2017-11-27 22:31:15 +01:00
|
|
|
};
|
2017-07-26 20:03:06 +02:00
|
|
|
|
|
|
|
|
public:
|
2024-06-11 22:30:16 +02:00
|
|
|
evdev_joystick_handler();
|
2017-11-27 22:31:15 +01:00
|
|
|
~evdev_joystick_handler();
|
2017-07-26 20:03:06 +02:00
|
|
|
|
2021-08-10 21:45:26 +02:00
|
|
|
void init_config(cfg_pad* cfg) override;
|
2017-11-27 22:31:15 +01:00
|
|
|
bool Init() override;
|
2022-08-28 15:28:14 +02:00
|
|
|
std::vector<pad_list_entry> list_devices() override;
|
2024-07-06 18:41:41 +02:00
|
|
|
bool bindPadToDevice(std::shared_ptr<Pad> pad) override;
|
2024-08-09 20:39:56 +02:00
|
|
|
connection get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, gui_call_type call_type, const std::vector<std::string>& buttons) override;
|
2022-08-13 09:56:04 +02:00
|
|
|
void get_motion_sensors(const std::string& padId, const motion_callback& callback, const motion_fail_callback& fail_callback, motion_preview_values preview_values, const std::array<AnalogSensor, 4>& sensors) override;
|
|
|
|
|
std::unordered_map<u32, std::string> get_motion_axis_list() const override;
|
2022-10-21 22:35:31 +02:00
|
|
|
void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override;
|
2017-07-26 20:03:06 +02:00
|
|
|
|
|
|
|
|
private:
|
2022-08-13 09:56:04 +02:00
|
|
|
void close_devices();
|
2019-09-20 16:28:55 +02:00
|
|
|
std::shared_ptr<EvdevDevice> get_evdev_device(const std::string& device);
|
2018-01-27 15:13:39 +01:00
|
|
|
std::string get_device_name(const libevdev* dev);
|
2019-09-20 16:28:55 +02:00
|
|
|
bool update_device(const std::shared_ptr<PadDevice>& device);
|
2022-08-13 09:56:04 +02:00
|
|
|
std::shared_ptr<evdev_joystick_handler::EvdevDevice> add_device(const std::string& device, bool in_settings = false);
|
|
|
|
|
std::shared_ptr<evdev_joystick_handler::EvdevDevice> add_motion_device(const std::string& device, bool in_settings);
|
2019-09-20 16:28:55 +02:00
|
|
|
std::unordered_map<u64, std::pair<u16, bool>> GetButtonValues(const std::shared_ptr<EvdevDevice>& device);
|
2022-10-21 22:35:31 +02:00
|
|
|
void SetRumble(EvdevDevice* device, u8 large, u8 small);
|
2017-11-27 22:31:15 +01:00
|
|
|
|
2017-12-23 12:28:10 +01:00
|
|
|
positive_axis m_pos_axis_config;
|
2023-06-14 20:57:30 +02:00
|
|
|
std::set<u32> m_positive_axis;
|
|
|
|
|
std::set<std::string> m_blacklist;
|
2024-08-08 03:04:21 +02:00
|
|
|
std::unordered_map<std::string, u16> m_min_button_values;
|
2022-08-13 09:56:04 +02:00
|
|
|
std::unordered_map<std::string, std::shared_ptr<evdev_joystick_handler::EvdevDevice>> m_settings_added;
|
|
|
|
|
std::unordered_map<std::string, std::shared_ptr<evdev_joystick_handler::EvdevDevice>> m_motion_settings_added;
|
2019-09-20 16:28:55 +02:00
|
|
|
std::shared_ptr<EvdevDevice> m_dev;
|
|
|
|
|
|
2023-06-13 01:19:32 +02:00
|
|
|
bool check_button_set(const std::set<u32>& indices, const u32 code);
|
|
|
|
|
bool check_button_sets(const std::array<std::set<u32>, 4>& sets, const u32 code);
|
2019-09-20 16:28:55 +02:00
|
|
|
|
2023-06-14 20:57:30 +02:00
|
|
|
void apply_input_events(const std::shared_ptr<Pad>& pad);
|
2022-03-20 00:19:44 +01:00
|
|
|
|
2022-08-13 09:56:04 +02:00
|
|
|
u16 get_sensor_value(const libevdev* dev, const AnalogSensor& sensor, const input_event& evt) const;
|
|
|
|
|
|
2019-09-20 16:28:55 +02:00
|
|
|
protected:
|
|
|
|
|
PadHandlerBase::connection update_connection(const std::shared_ptr<PadDevice>& device) override;
|
2022-08-13 09:56:04 +02:00
|
|
|
void get_mapping(const pad_ensemble& binding) override;
|
|
|
|
|
void get_extended_info(const pad_ensemble& binding) override;
|
|
|
|
|
void apply_pad_data(const pad_ensemble& binding) override;
|
2022-10-15 12:41:21 +02:00
|
|
|
bool get_is_left_trigger(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
|
|
|
|
bool get_is_right_trigger(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
|
|
|
|
bool get_is_left_stick(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
|
|
|
|
bool get_is_right_stick(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
2017-07-26 20:03:06 +02:00
|
|
|
};
|
2019-09-20 16:28:55 +02:00
|
|
|
|
|
|
|
|
#endif
|