summaryrefslogtreecommitdiff
path: root/platform/linuxbsd/joypad_linux.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linuxbsd/joypad_linux.cpp')
-rw-r--r--platform/linuxbsd/joypad_linux.cpp91
1 files changed, 27 insertions, 64 deletions
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index 5ceea788e0..291ca49585 100644
--- a/platform/linuxbsd/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -49,17 +49,7 @@
static const char *ignore_str = "/dev/input/js";
#endif
-JoypadLinux::Joypad::Joypad() {
- fd = -1;
- dpad = 0;
- devpath = "";
- for (int i = 0; i < MAX_ABS; i++) {
- abs_info[i] = nullptr;
- }
-}
-
JoypadLinux::Joypad::~Joypad() {
-
for (int i = 0; i < MAX_ABS; i++) {
if (abs_info[i]) {
memdelete(abs_info[i]);
@@ -94,7 +84,6 @@ JoypadLinux::~JoypadLinux() {
}
void JoypadLinux::joy_thread_func(void *p_user) {
-
if (p_user) {
JoypadLinux *joy = (JoypadLinux *)p_user;
joy->run_joypad_thread();
@@ -115,7 +104,6 @@ void JoypadLinux::run_joypad_thread() {
#ifdef UDEV_ENABLED
void JoypadLinux::enumerate_joypads(udev *p_udev) {
-
udev_enumerate *enumerate;
udev_list_entry *devices, *dev_list_entry;
udev_device *dev;
@@ -126,13 +114,11 @@ void JoypadLinux::enumerate_joypads(udev *p_udev) {
udev_enumerate_scan_devices(enumerate);
devices = udev_enumerate_get_list_entry(enumerate);
udev_list_entry_foreach(dev_list_entry, devices) {
-
const char *path = udev_list_entry_get_name(dev_list_entry);
dev = udev_device_new_from_syspath(p_udev, path);
const char *devnode = udev_device_get_devnode(dev);
if (devnode) {
-
String devnode_str = devnode;
if (devnode_str.find(ignore_str) == -1) {
MutexLock lock(joy_mutex);
@@ -145,7 +131,6 @@ void JoypadLinux::enumerate_joypads(udev *p_udev) {
}
void JoypadLinux::monitor_joypads(udev *p_udev) {
-
udev_device *dev = nullptr;
udev_monitor *mon = udev_monitor_new_from_netlink(p_udev, "udev");
udev_monitor_filter_add_match_subsystem_devtype(mon, "input", nullptr);
@@ -153,7 +138,6 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
int fd = udev_monitor_get_fd(mon);
while (!exit_udev) {
-
fd_set fds;
struct timeval tv;
int ret;
@@ -172,15 +156,12 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
dev = udev_monitor_receive_device(mon);
if (dev && udev_device_get_devnode(dev) != 0) {
-
MutexLock lock(joy_mutex);
String action = udev_device_get_action(dev);
const char *devnode = udev_device_get_devnode(dev);
if (devnode) {
-
String devnode_str = devnode;
if (devnode_str.find(ignore_str) == -1) {
-
if (action == "add")
open_joypad(devnode);
else if (String(action) == "remove")
@@ -198,7 +179,6 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
#endif
void JoypadLinux::monitor_joypads() {
-
while (!exit_udev) {
{
MutexLock lock(joy_mutex);
@@ -216,9 +196,7 @@ void JoypadLinux::monitor_joypads() {
}
int JoypadLinux::get_joy_from_path(String p_path) const {
-
for (int i = 0; i < JOYPADS_MAX; i++) {
-
if (joypads[i].devpath == p_path) {
return i;
}
@@ -229,17 +207,16 @@ int JoypadLinux::get_joy_from_path(String p_path) const {
void JoypadLinux::close_joypad(int p_id) {
if (p_id == -1) {
for (int i = 0; i < JOYPADS_MAX; i++) {
-
close_joypad(i);
};
return;
- } else if (p_id < 0)
+ } else if (p_id < 0) {
return;
+ }
Joypad &joy = joypads[p_id];
if (joy.fd != -1) {
-
close(joy.fd);
joy.fd = -1;
attached_devices.remove(attached_devices.find(joy.devpath));
@@ -248,7 +225,6 @@ void JoypadLinux::close_joypad(int p_id) {
}
static String _hex_str(uint8_t p_byte) {
-
static const char *dict = "0123456789abcdef";
char ret[3];
ret[2] = 0;
@@ -260,7 +236,6 @@ static String _hex_str(uint8_t p_byte) {
}
void JoypadLinux::setup_joypad_properties(int p_id) {
-
Joypad *joy = &joypads[p_id];
unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
@@ -274,16 +249,12 @@ void JoypadLinux::setup_joypad_properties(int p_id) {
return;
}
for (int i = BTN_JOYSTICK; i < KEY_MAX; ++i) {
-
if (test_bit(i, keybit)) {
-
joy->key_map[i] = num_buttons++;
}
}
for (int i = BTN_MISC; i < BTN_JOYSTICK; ++i) {
-
if (test_bit(i, keybit)) {
-
joy->key_map[i] = num_buttons++;
}
}
@@ -294,7 +265,6 @@ void JoypadLinux::setup_joypad_properties(int p_id) {
continue;
}
if (test_bit(i, absbit)) {
-
joy->abs_map[i] = num_axes++;
joy->abs_info[i] = memnew(input_absinfo);
if (ioctl(joy->fd, EVIOCGABS(i), joy->abs_info[i]) < 0) {
@@ -315,11 +285,9 @@ void JoypadLinux::setup_joypad_properties(int p_id) {
}
void JoypadLinux::open_joypad(const char *p_path) {
-
int joy_num = input->get_unused_joy_id();
int fd = open(p_path, O_RDWR | O_NONBLOCK);
if (fd != -1 && joy_num != -1) {
-
unsigned long evbit[NBITS(EV_MAX)] = { 0 };
unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
@@ -334,16 +302,9 @@ void JoypadLinux::open_joypad(const char *p_path) {
return;
}
- //check if the device supports basic gamepad events, prevents certain keyboards from
- //being detected as joypads
+ // Check if the device supports basic gamepad events
if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) &&
- (test_bit(ABS_X, absbit) || test_bit(ABS_Y, absbit) || test_bit(ABS_HAT0X, absbit) ||
- test_bit(ABS_GAS, absbit) || test_bit(ABS_RUDDER, absbit)) &&
- (test_bit(BTN_A, keybit) || test_bit(BTN_THUMBL, keybit) ||
- test_bit(BTN_TRIGGER, keybit) || test_bit(BTN_1, keybit))) &&
- !(test_bit(EV_ABS, evbit) &&
- test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit) &&
- test_bit(ABS_RX, absbit) && test_bit(ABS_RY, absbit))) {
+ test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit))) {
close(fd);
return;
}
@@ -369,7 +330,6 @@ void JoypadLinux::open_joypad(const char *p_path) {
setup_joypad_properties(joy_num);
sprintf(uid, "%04x%04x", BSWAP16(inpid.bustype), 0);
if (inpid.vendor && inpid.product && inpid.version) {
-
uint16_t vendor = BSWAP16(inpid.vendor);
uint16_t product = BSWAP16(inpid.product);
uint16_t version = BSWAP16(inpid.version);
@@ -380,7 +340,6 @@ void JoypadLinux::open_joypad(const char *p_path) {
String uidname = uid;
int uidlen = MIN(name.length(), 11);
for (int i = 0; i < uidlen; i++) {
-
uidname = uidname + _hex_str(name[i]);
}
uidname += "00";
@@ -437,7 +396,6 @@ void JoypadLinux::joypad_vibration_stop(int p_id, uint64_t p_timestamp) {
}
Input::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int p_value) const {
-
int min = p_abs->minimum;
int max = p_abs->maximum;
Input::JoyAxis jx;
@@ -457,13 +415,13 @@ Input::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int p_value
}
void JoypadLinux::process_joypads() {
-
if (joy_mutex.try_lock() != OK) {
return;
}
for (int i = 0; i < JOYPADS_MAX; i++) {
-
- if (joypads[i].fd == -1) continue;
+ if (joypads[i].fd == -1) {
+ continue;
+ }
input_event events[32];
Joypad *joy = &joypads[i];
@@ -473,13 +431,13 @@ void JoypadLinux::process_joypads() {
while ((len = read(joy->fd, events, (sizeof events))) > 0) {
len /= sizeof(events[0]);
for (int j = 0; j < len; j++) {
-
input_event &ev = events[j];
// ev may be tainted and out of MAX_KEY range, which will cause
// joy->key_map[ev.code] to crash
- if (ev.code >= MAX_KEY)
+ if (ev.code >= MAX_KEY) {
return;
+ }
switch (ev.type) {
case EV_KEY:
@@ -491,31 +449,36 @@ void JoypadLinux::process_joypads() {
switch (ev.code) {
case ABS_HAT0X:
if (ev.value != 0) {
- if (ev.value < 0)
- joy->dpad |= Input::HAT_MASK_LEFT;
- else
- joy->dpad |= Input::HAT_MASK_RIGHT;
- } else
+ if (ev.value < 0) {
+ joy->dpad = (joy->dpad | Input::HAT_MASK_LEFT) & ~Input::HAT_MASK_RIGHT;
+ } else {
+ joy->dpad = (joy->dpad | Input::HAT_MASK_RIGHT) & ~Input::HAT_MASK_LEFT;
+ }
+ } else {
joy->dpad &= ~(Input::HAT_MASK_LEFT | Input::HAT_MASK_RIGHT);
+ }
input->joy_hat(i, joy->dpad);
break;
case ABS_HAT0Y:
if (ev.value != 0) {
- if (ev.value < 0)
- joy->dpad |= Input::HAT_MASK_UP;
- else
- joy->dpad |= Input::HAT_MASK_DOWN;
- } else
+ if (ev.value < 0) {
+ joy->dpad = (joy->dpad | Input::HAT_MASK_UP) & ~Input::HAT_MASK_DOWN;
+ } else {
+ joy->dpad = (joy->dpad | Input::HAT_MASK_DOWN) & ~Input::HAT_MASK_UP;
+ }
+ } else {
joy->dpad &= ~(Input::HAT_MASK_UP | Input::HAT_MASK_DOWN);
+ }
input->joy_hat(i, joy->dpad);
break;
default:
- if (ev.code >= MAX_ABS)
+ if (ev.code >= MAX_ABS) {
return;
+ }
if (joy->abs_map[ev.code] != -1 && joy->abs_info[ev.code]) {
Input::JoyAxis value = axis_correct(joy->abs_info[ev.code], ev.value);
joy->curr_axis[joy->abs_map[ev.code]] = value;