16 #ifdef PHAVE_LINUX_INPUT_H
24 #include <linux/input.h>
27 #define BTN_DPAD_UP 0x220
28 #define BTN_DPAD_DOWN 0x221
29 #define BTN_DPAD_LEFT 0x222
30 #define BTN_DPAD_RIGHT 0x223
35 #ifndef BTN_TRIGGER_HAPPY
36 #define BTN_TRIGGER_HAPPY 0x2c0
37 #define BTN_TRIGGER_HAPPY1 0x2c0
38 #define BTN_TRIGGER_HAPPY2 0x2c1
39 #define BTN_TRIGGER_HAPPY3 0x2c2
40 #define BTN_TRIGGER_HAPPY4 0x2c3
43 #define test_bit(bit, array) ((array)[(bit)>>3] & (1<<((bit)&7)))
50 QB_centered_throttle = 2,
53 QB_reversed_throttle = 4,
56 QB_connect_if_nonzero = 8,
59 QB_rudder_from_throttle = 16,
64 QB_steam_controller = 32,
67 QB_right_axes_swapped = 64,
70 QB_no_analog_triggers = 128,
73 QB_alt_button_mapping = 256,
76 static const struct DeviceMapping {
77 unsigned short vendor;
78 unsigned short product;
79 InputDevice::DeviceClass device_class;
81 } mapping_presets[] = {
83 {0x0955, 0x7214, InputDevice::DeviceClass::gamepad, QB_rstick_from_z},
85 {0x044f, 0xb108, InputDevice::DeviceClass::flight_stick, QB_centered_throttle | QB_reversed_throttle | QB_rudder_from_throttle},
87 {0x045e, 0x0719, InputDevice::DeviceClass::gamepad, QB_connect_if_nonzero},
89 {0x28de, 0x1102, InputDevice::DeviceClass::unknown, QB_steam_controller},
91 {0x28de, 0x1142, InputDevice::DeviceClass::unknown, QB_steam_controller},
93 {0x0f30, 0x0111, InputDevice::DeviceClass::gamepad, QB_rstick_from_z | QB_right_axes_swapped},
95 {0x0079, 0x0006, InputDevice::DeviceClass::gamepad, QB_no_analog_triggers | QB_alt_button_mapping},
97 {0x2dc8, 0x9001, InputDevice::DeviceClass::gamepad, QB_rstick_from_z},
99 {0x0810, 0x0001, InputDevice::DeviceClass::gamepad, QB_no_analog_triggers | QB_alt_button_mapping | QB_rstick_from_z | QB_right_axes_swapped},
101 {0x0810, 0xe501, InputDevice::DeviceClass::gamepad, QB_no_analog_triggers | QB_alt_button_mapping},
103 {0x046d, 0xc623, InputDevice::DeviceClass::spatial_mouse, 0},
105 {0x046d, 0xc625, InputDevice::DeviceClass::spatial_mouse, 0},
107 {0x046d, 0xc626, InputDevice::DeviceClass::spatial_mouse, 0},
109 {0x046d, 0xc627, InputDevice::DeviceClass::spatial_mouse, 0},
111 {0x046d, 0xc628, InputDevice::DeviceClass::spatial_mouse, 0},
113 {0x046d, 0xc629, InputDevice::DeviceClass::spatial_mouse, 0},
115 {0x046d, 0xc62b, InputDevice::DeviceClass::spatial_mouse, 0},
125 EvdevInputDevice(LinuxInputDeviceManager *manager,
size_t index) :
136 _dpad_left_button(-1),
143 sprintf(path,
"/dev/input/event%zd", index);
145 _fd = open(path, O_RDWR | O_NONBLOCK);
150 _fd = open(path, O_RDONLY | O_NONBLOCK);
156 _is_connected =
false;
158 <<
"Opening raw input device: " << strerror(errno) <<
" " << path <<
"\n";
166 ~EvdevInputDevice() {
170 do_set_vibration(0, 0);
171 ioctl(_fd, EVIOCRMFF, _ff_id);
185 void EvdevInputDevice::
186 do_set_vibration(
double strong,
double weak) {
187 if (_fd == -1 || !_can_write) {
191 int strong_level = strong * 0xffff;
192 int weak_level = weak * 0xffff;
194 if (strong_level == _ff_strong && weak_level == _ff_weak) {
202 struct ff_effect effect;
203 effect.type = FF_RUMBLE;
205 effect.direction = 0;
206 effect.trigger.button = 0;
207 effect.trigger.interval = 0;
208 effect.replay.length = 0;
209 effect.replay.delay = 0;
210 effect.u.rumble.strong_magnitude = strong_level;
211 effect.u.rumble.weak_magnitude = weak_level;
213 if (ioctl(_fd, EVIOCSFF, &effect) < 0) {
217 _ff_strong = strong_level;
218 _ff_weak = weak_level;
226 struct input_event play;
231 if (write(_fd, &play,
sizeof(play)) < 0) {
233 <<
"Failed to write force-feedback event: " << strerror(errno) <<
"\n";
244 bool EvdevInputDevice::
245 reactivate_steam_controller() {
247 if (!_is_connected && (_quirks & QB_steam_controller) != 0) {
251 _is_connected =
true;
263 void EvdevInputDevice::
265 if (_fd != -1 && process_events()) {
266 while (process_events()) {}
269 if (!_is_connected && _fd != -1) {
270 _is_connected =
true;
271 if (_manager !=
nullptr) {
272 _manager->add_device(
this);
281 bool EvdevInputDevice::
285 nassertr(_fd >= 0,
false);
289 uint8_t evtypes[(EV_MAX + 8) >> 3] = {0};
291 if (ioctl(_fd, EVIOCGNAME(
sizeof(name)), name) < 0 ||
292 ioctl(_fd, EVIOCGBIT(0,
sizeof(evtypes)), evtypes) < 0) {
295 _is_connected =
false;
296 device_cat.error() <<
"Opening raw input device: ioctl failed\n";
304 if (ioctl(_fd, EVIOCGID, &
id) >= 0) {
305 _vendor_id =
id.vendor;
306 _product_id =
id.product;
309 bool all_values_zero =
true;
310 bool emulate_dpad =
true;
311 bool have_analog_triggers =
false;
313 bool has_keys =
false;
314 bool has_axes =
false;
316 uint8_t keys[(KEY_MAX + 8) >> 3] = {0};
317 if (test_bit(EV_KEY, evtypes)) {
319 ioctl(_fd, EVIOCGBIT(EV_KEY,
sizeof(keys)), keys);
322 if (test_bit(KEY_A, keys) && test_bit(KEY_Z, keys)) {
323 enable_feature(Feature::keyboard);
328 uint8_t axes[(ABS_MAX + 8) >> 3] = {0};
329 if (test_bit(EV_ABS, evtypes)) {
331 num_bits = ioctl(_fd, EVIOCGBIT(EV_ABS,
sizeof(axes)), axes) << 3;
337 const DeviceMapping *mapping = mapping_presets;
338 while (mapping->vendor != 0) {
339 if (_vendor_id == mapping->vendor && _product_id == mapping->product) {
340 _device_class = mapping->device_class;
341 quirks = mapping->quirks;
348 if (quirks & QB_steam_controller) {
349 if (test_bit(BTN_GAMEPAD, keys)) {
350 _device_class = DeviceClass::gamepad;
356 if (_manager->has_virtual_device(0x28de, 0x11ff)) {
358 <<
"Detected Steam virtual gamepad, disabling Steam Controller\n";
359 quirks |= QB_connect_if_nonzero;
366 if (_device_class == DeviceClass::unknown) {
367 int device_scores[(size_t)DeviceClass::digitizer + 1] = {0};
370 if (test_bit(BTN_GAMEPAD, keys) && test_bit(ABS_X, axes) && test_bit(ABS_RX, axes)) {
371 device_scores[(size_t)DeviceClass::gamepad] += 5;
372 device_scores[(size_t)DeviceClass::steering_wheel] += 5;
373 device_scores[(size_t)DeviceClass::flight_stick] += 5;
376 if (test_bit(ABS_WHEEL, axes) && test_bit(ABS_GAS, axes) && test_bit(ABS_BRAKE, axes)) {
377 device_scores[(size_t)DeviceClass::steering_wheel] += 10;
379 if (test_bit(BTN_GEAR_DOWN, keys) && test_bit(BTN_GEAR_UP, keys)) {
380 device_scores[(size_t)DeviceClass::steering_wheel] += 10;
382 if (test_bit(BTN_JOYSTICK, keys) && test_bit(ABS_X, axes)) {
383 device_scores[(size_t)DeviceClass::flight_stick] += 10;
385 if (test_bit(BTN_MOUSE, keys) && test_bit(EV_REL, evtypes)) {
386 device_scores[(size_t)DeviceClass::mouse] += 20;
388 if (test_bit(BTN_DIGI, keys) && test_bit(EV_ABS, evtypes)) {
389 device_scores[(size_t)DeviceClass::digitizer] += 20;
391 uint8_t unknown_keys[] = {KEY_POWER};
392 for (
int i = 0; i < 1; i++) {
393 if (test_bit(unknown_keys[i], keys)) {
394 if (unknown_keys[i] == KEY_POWER) {
396 device_scores[(size_t)DeviceClass::unknown] += 20;
399 if (_features & (
unsigned int)Feature::keyboard) {
400 device_scores[(size_t)DeviceClass::keyboard] += 20;
404 string lowercase_name = _name;
405 for(
size_t x = 0; x < _name.length(); ++x) {
406 lowercase_name[x] = tolower(lowercase_name[x]);
408 if (lowercase_name.find(
"gamepad") != string::npos) {
409 device_scores[(size_t)DeviceClass::gamepad] += 10;
411 if (lowercase_name.find(
"wheel") != string::npos) {
412 device_scores[(size_t)DeviceClass::steering_wheel] += 10;
414 if (lowercase_name.find(
"mouse") != string::npos || lowercase_name.find(
"touchpad") != string::npos) {
415 device_scores[(size_t)DeviceClass::mouse] += 10;
417 if (lowercase_name.find(
"keyboard") != string::npos) {
418 device_scores[(size_t)DeviceClass::keyboard] += 10;
421 string unknown_names[] = {
"video bus",
"power button",
"sleep button"};
422 for(
int i = 0; i < 3; i++) {
423 if (lowercase_name.find(unknown_names[i]) != string::npos) {
424 device_scores[(size_t)DeviceClass::unknown] += 20;
429 int highest_score = 0;
430 for (
size_t i = 0; i <= (size_t)DeviceClass::digitizer; i++) {
431 if (device_scores[i] > highest_score) {
432 highest_score = device_scores[i];
433 _device_class = (DeviceClass)i;
441 uint8_t states[(KEY_MAX + 8) >> 3] = {0};
442 ioctl(_fd, EVIOCGKEY(
sizeof(states)), states);
444 for (
int i = 0; i <= KEY_MAX; ++i) {
445 if (test_bit(i, keys)) {
447 button.handle = map_button(i, _device_class, quirks);
449 int button_index = (int)_buttons.size();
450 if (button.handle == ButtonHandle::none()) {
451 if (device_cat.is_debug()) {
452 device_cat.debug() <<
"Unmapped /dev/input/event" << _index
453 <<
" button " << button_index <<
": 0x" << std::hex << i << std::dec <<
"\n";
457 if (test_bit(i, states)) {
458 button._state = S_down;
459 all_values_zero =
false;
461 button._state = S_up;
463 if (button.handle == GamepadButton::dpad_left()) {
464 emulate_dpad =
false;
465 }
else if (button.handle == GamepadButton::ltrigger()) {
467 }
else if (button.handle == GamepadButton::rtrigger()) {
471 _buttons.push_back(button);
472 if ((
size_t)i >= _button_indices.size()) {
473 _button_indices.resize(i + 1, -1);
475 _button_indices[i] = button_index;
481 _axis_indices.resize(num_bits, -1);
483 for (
int i = 0; i < num_bits; ++i) {
484 if (test_bit(i, axes)) {
485 Axis axis = Axis::none;
488 if (_device_class == DeviceClass::gamepad) {
489 axis = InputDevice::Axis::left_x;
490 }
else if (_device_class == DeviceClass::flight_stick) {
491 axis = InputDevice::Axis::roll;
493 axis = InputDevice::Axis::x;
497 if (_device_class == DeviceClass::gamepad) {
498 axis = InputDevice::Axis::left_y;
499 }
else if (_device_class == DeviceClass::flight_stick) {
500 axis = InputDevice::Axis::pitch;
502 axis = InputDevice::Axis::y;
506 if (quirks & QB_rstick_from_z) {
507 if (quirks & QB_right_axes_swapped) {
508 axis = InputDevice::Axis::right_y;
510 axis = InputDevice::Axis::right_x;
512 }
else if (_device_class == DeviceClass::gamepad) {
513 if ((quirks & QB_no_analog_triggers) == 0) {
514 axis = InputDevice::Axis::left_trigger;
515 have_analog_triggers =
true;
517 }
else if (_device_class == DeviceClass::spatial_mouse) {
518 axis = InputDevice::Axis::z;
520 axis = InputDevice::Axis::throttle;
524 if (_device_class == DeviceClass::spatial_mouse) {
525 axis = InputDevice::Axis::pitch;
526 }
else if ((quirks & QB_rstick_from_z) == 0) {
527 axis = InputDevice::Axis::right_x;
531 if (_device_class == DeviceClass::spatial_mouse) {
532 axis = InputDevice::Axis::roll;
533 }
else if ((quirks & QB_rstick_from_z) == 0) {
534 axis = InputDevice::Axis::right_y;
538 if (quirks & QB_rstick_from_z) {
539 if (quirks & QB_right_axes_swapped) {
540 axis = InputDevice::Axis::right_x;
542 axis = InputDevice::Axis::right_y;
544 }
else if (_device_class == DeviceClass::gamepad) {
545 if ((quirks & QB_no_analog_triggers) == 0) {
546 axis = InputDevice::Axis::right_trigger;
547 have_analog_triggers =
true;
550 axis = InputDevice::Axis::right_y;
553 axis = InputDevice::Axis::yaw;
557 if (quirks & QB_rudder_from_throttle) {
558 axis = InputDevice::Axis::rudder;
560 axis = InputDevice::Axis::throttle;
564 axis = InputDevice::Axis::rudder;
567 axis = InputDevice::Axis::wheel;
570 if (_device_class == DeviceClass::gamepad) {
571 if ((quirks & QB_no_analog_triggers) == 0) {
572 axis = InputDevice::Axis::right_trigger;
573 have_analog_triggers =
true;
576 axis = InputDevice::Axis::accelerator;
580 if (_device_class == DeviceClass::gamepad) {
581 axis = InputDevice::Axis::left_trigger;
582 have_analog_triggers =
true;
584 axis = InputDevice::Axis::brake;
590 _dpad_left_button = (int)_buttons.size();
591 if (_device_class == DeviceClass::gamepad) {
592 _buttons.push_back(ButtonState(GamepadButton::dpad_left()));
593 _buttons.push_back(ButtonState(GamepadButton::dpad_right()));
595 _buttons.push_back(ButtonState(GamepadButton::hat_left()));
596 _buttons.push_back(ButtonState(GamepadButton::hat_right()));
598 _buttons[_dpad_left_button]._state = S_up;
599 _buttons[_dpad_left_button+1]._state = S_up;
605 _dpad_up_button = (int)_buttons.size();
606 if (_device_class == DeviceClass::gamepad) {
607 _buttons.push_back(ButtonState(GamepadButton::dpad_up()));
608 _buttons.push_back(ButtonState(GamepadButton::dpad_down()));
610 _buttons.push_back(ButtonState(GamepadButton::hat_up()));
611 _buttons.push_back(ButtonState(GamepadButton::hat_down()));
613 _buttons[_dpad_up_button]._state = S_up;
614 _buttons[_dpad_up_button+1]._state = S_up;
618 if (quirks & QB_steam_controller) {
619 axis = InputDevice::Axis::right_trigger;
620 have_analog_triggers =
true;
624 if (quirks & QB_steam_controller) {
625 axis = InputDevice::Axis::left_trigger;
626 have_analog_triggers =
true;
630 axis = InputDevice::Axis::pressure;
635 struct input_absinfo absinfo;
636 if (ioctl(_fd, EVIOCGABS(i), &absinfo) >= 0) {
641 if (axis == Axis::yaw || axis == Axis::rudder || axis == Axis::left_y || axis == Axis::right_y ||
642 (axis == Axis::throttle && (quirks & QB_reversed_throttle) != 0) ||
643 (_device_class == DeviceClass::spatial_mouse && (axis == Axis::y || axis == Axis::z || axis == Axis::roll)) ||
644 (_device_class == DeviceClass::digitizer && axis == Axis::y)) {
645 std::swap(absinfo.maximum, absinfo.minimum);
647 if (axis == Axis::throttle && (quirks & QB_centered_throttle) != 0) {
648 index = add_axis(axis, absinfo.minimum, absinfo.maximum,
true);
650 index = add_axis(axis, absinfo.minimum, absinfo.maximum);
652 axis_changed(index, absinfo.value);
653 _axis_indices[i] = index;
655 if (absinfo.value != 0) {
656 all_values_zero =
false;
663 if (test_bit(EV_REL, evtypes)) {
664 enable_feature(Feature::pointer);
665 add_pointer(PointerType::unknown, 0);
668 if (test_bit(EV_FF, evtypes)) {
669 uint8_t effects[(FF_MAX + 8) >> 3] = {0};
670 ioctl(_fd, EVIOCGBIT(EV_FF,
sizeof(effects)), effects);
672 if (test_bit(FF_RUMBLE, effects)) {
674 enable_feature(Feature::vibration);
678 <<
"/dev/input/event" << _index <<
" is not writable, vibration "
679 <<
"effects will be unavailable.\n";
684 if (_ltrigger_code >= 0 && _rtrigger_code >= 0 && !have_analog_triggers) {
686 _ltrigger_axis = (int)_axes.size();
687 add_axis(Axis::left_trigger, 0, 1,
false);
688 add_axis(Axis::right_trigger, 0, 1,
false);
696 const char *parent =
"";
697 sprintf(path,
"/sys/class/input/event%zd/device/device/../product", _index);
698 FILE *f = fopen(path,
"r");
701 sprintf(path,
"/sys/class/input/event%zd/device/device/%s../product", _index, parent);
702 f = fopen(path,
"r");
705 if (fgets(buffer,
sizeof(buffer), f) !=
nullptr) {
706 buffer[strcspn(buffer,
"\r\n")] = 0;
707 if (buffer[0] != 0) {
708 _name.assign(buffer);
713 sprintf(path,
"/sys/class/input/event%zd/device/device/%s../manufacturer", _index, parent);
714 f = fopen(path,
"r");
716 if (fgets(buffer,
sizeof(buffer), f) !=
nullptr) {
717 buffer[strcspn(buffer,
"\r\n")] = 0;
718 _manufacturer.assign(buffer);
722 sprintf(path,
"/sys/class/input/event%zd/device/device/%s../serial", _index, parent);
723 f = fopen(path,
"r");
725 if (fgets(buffer,
sizeof(buffer), f) !=
nullptr) {
726 buffer[strcspn(buffer,
"\r\n")] = 0;
727 _serial_number.assign(buffer);
735 if (all_values_zero && (quirks & QB_connect_if_nonzero) != 0) {
736 _is_connected =
false;
738 _is_connected =
true;
747 bool EvdevInputDevice::
750 struct input_event events[8];
752 int n_read = read(_fd, events,
sizeof(events));
754 if (errno == EAGAIN || errno == EWOULDBLOCK) {
757 }
else if (errno == ENODEV || errno == EINVAL) {
767 device_cat.error() <<
"read: " << strerror(errno) <<
"\n";
776 n_read /=
sizeof(
struct input_event);
785 if (n_read == 1 && events[0].code == EV_SYN) {
789 for (
int i = 0; i < n_read; ++i) {
790 int code = events[i].code;
792 switch (events[i].type) {
797 if (code == REL_X) rel_x += events[i].value;
798 if (code == REL_Y) rel_y += events[i].value;
802 if (code == _dpad_x_axis) {
803 button_changed(_dpad_left_button, events[i].value < 0);
804 button_changed(_dpad_left_button+1, events[i].value > 0);
805 }
else if (code == _dpad_y_axis) {
806 button_changed(_dpad_up_button, events[i].value < 0);
807 button_changed(_dpad_up_button+1, events[i].value > 0);
809 if (code >= 0 && (
size_t)code < _axis_indices.size()) {
810 index = _axis_indices[code];
812 axis_changed(index, events[i].value);
815 else if (device_cat.is_debug()) {
817 <<
"Ignoring EV_ABS event with unknown code " << code <<
"\n";
822 if (code >= 0 && (
size_t)code < _button_indices.size()) {
823 index = _button_indices[code];
825 button_changed(index, events[i].value != 0);
827 if (code == _ltrigger_code) {
828 axis_changed(_ltrigger_axis, events[i].value);
829 }
else if (code == _rtrigger_code) {
830 axis_changed(_ltrigger_axis + 1, events[i].value);
833 else if (device_cat.is_debug()) {
835 <<
"Ignoring EV_KEY event with unknown code " << code <<
"\n";
845 if (rel_x != 0 || rel_y != 0) {
846 pointer_moved(0, rel_x, rel_y, time);
856 map_button(
int code, DeviceClass device_class,
int quirks) {
857 if (code >= 0 && code < 0x80) {
860 ButtonHandle::none(),
861 KeyboardButton::escape(),
874 KeyboardButton::backspace(),
875 KeyboardButton::tab(),
888 KeyboardButton::enter(),
889 KeyboardButton::lcontrol(),
902 KeyboardButton::lshift(),
914 KeyboardButton::rshift(),
916 KeyboardButton::lalt(),
917 KeyboardButton::space(),
918 KeyboardButton::caps_lock(),
919 KeyboardButton::f1(),
920 KeyboardButton::f2(),
921 KeyboardButton::f3(),
922 KeyboardButton::f4(),
923 KeyboardButton::f5(),
924 KeyboardButton::f6(),
925 KeyboardButton::f7(),
926 KeyboardButton::f8(),
927 KeyboardButton::f9(),
928 KeyboardButton::f10(),
929 KeyboardButton::num_lock(),
930 KeyboardButton::scroll_lock(),
944 ButtonHandle::none(),
945 ButtonHandle::none(),
946 ButtonHandle::none(),
947 KeyboardButton::f11(),
948 KeyboardButton::f12(),
949 ButtonHandle::none(),
950 ButtonHandle::none(),
951 ButtonHandle::none(),
952 ButtonHandle::none(),
953 ButtonHandle::none(),
954 ButtonHandle::none(),
955 ButtonHandle::none(),
956 KeyboardButton::enter(),
957 KeyboardButton::rcontrol(),
959 KeyboardButton::print_screen(),
960 KeyboardButton::ralt(),
961 ButtonHandle::none(),
962 KeyboardButton::home(),
963 KeyboardButton::up(),
964 KeyboardButton::page_up(),
965 KeyboardButton::left(),
966 KeyboardButton::right(),
967 KeyboardButton::end(),
968 KeyboardButton::down(),
969 KeyboardButton::page_down(),
970 KeyboardButton::insert(),
971 KeyboardButton::del(),
972 ButtonHandle::none(),
973 ButtonHandle::none(),
974 ButtonHandle::none(),
975 ButtonHandle::none(),
976 ButtonHandle::none(),
977 ButtonHandle::none(),
978 ButtonHandle::none(),
979 KeyboardButton::pause(),
980 ButtonHandle::none(),
981 ButtonHandle::none(),
982 ButtonHandle::none(),
983 ButtonHandle::none(),
984 ButtonHandle::none(),
985 KeyboardButton::lmeta(),
986 KeyboardButton::rmeta(),
987 KeyboardButton::menu(),
989 return keyboard_map[code];
991 }
else if (code == KEY_BACK) {
993 return GamepadButton::back();
995 }
else if (code == KEY_SEARCH) {
997 return GamepadButton::guide();
999 }
else if (code < 0x100) {
1000 return ButtonHandle::none();
1002 }
else if ((code & 0xfff0) == BTN_MOUSE) {
1004 if (code == BTN_RIGHT) {
1006 }
else if (code == BTN_MIDDLE) {
1012 }
else if ((code & 0xfff0) == BTN_JOYSTICK) {
1013 if (quirks & QB_steam_controller) {
1015 return ButtonHandle::none();
1017 }
else if (device_class == DeviceClass::gamepad &&
1018 (quirks & QB_alt_button_mapping) != 0) {
1020 GamepadButton::face_y(),
1021 GamepadButton::face_b(),
1022 GamepadButton::face_a(),
1023 GamepadButton::face_x(),
1024 GamepadButton::lshoulder(),
1025 GamepadButton::rshoulder(),
1026 GamepadButton::ltrigger(),
1027 GamepadButton::rtrigger(),
1028 GamepadButton::back(),
1029 GamepadButton::start(),
1030 GamepadButton::lstick(),
1031 GamepadButton::rstick(),
1033 if ((code & 0xf) < 12) {
1034 return mapping[code & 0xf];
1037 }
else if (device_class == DeviceClass::gamepad) {
1040 GamepadButton::face_x(),
1041 GamepadButton::face_y(),
1042 GamepadButton::face_a(),
1043 GamepadButton::face_b(),
1044 GamepadButton::lshoulder(),
1045 GamepadButton::ltrigger(),
1046 GamepadButton::rshoulder(),
1047 GamepadButton::rtrigger(),
1048 GamepadButton::back(),
1049 GamepadButton::start(),
1050 GamepadButton::lstick(),
1051 GamepadButton::rstick(),
1053 if ((code & 0xf) < 12) {
1054 return mapping[code & 0xf];
1063 return GamepadButton::face_a();
1066 return GamepadButton::face_b();
1069 return GamepadButton::face_c();
1072 return GamepadButton::face_x();
1075 return GamepadButton::face_y();
1078 return GamepadButton::face_z();
1081 return GamepadButton::lshoulder();
1084 return GamepadButton::rshoulder();
1087 return GamepadButton::ltrigger();
1090 return GamepadButton::rtrigger();
1093 return GamepadButton::face_1();
1096 return GamepadButton::face_2();
1100 return GamepadButton::back();
1104 return GamepadButton::start();
1107 return GamepadButton::guide();
1110 return GamepadButton::lstick();
1113 return GamepadButton::rstick();
1116 case BTN_TRIGGER_HAPPY1:
1117 return GamepadButton::dpad_left();
1119 case BTN_DPAD_RIGHT:
1120 case BTN_TRIGGER_HAPPY2:
1121 return GamepadButton::dpad_right();
1124 case BTN_TRIGGER_HAPPY3:
1125 return GamepadButton::dpad_up();
1128 case BTN_TRIGGER_HAPPY4:
1129 return GamepadButton::dpad_down();
1133 return GamepadButton::lgrip();
1136 return GamepadButton::rgrip();
1139 return ButtonHandle::none();