diff --git a/platform/x11/detect.py b/platform/x11/detect.py index f49475a2d5a..6b147db130a 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -56,7 +56,7 @@ def get_opts(): ('use_sanitizer','Use llvm compiler sanitize address','no'), ('use_leak_sanitizer','Use llvm compiler sanitize memory leaks','no'), ('pulseaudio','Detect & Use pulseaudio','yes'), - ('gamepad','Gamepad support, requires libudev and libevdev','yes'), + ('udev','Use udev for gamepad connection callbacks','no'), ('new_wm_api', 'Use experimental window management API','no'), ('debug_release', 'Add debug symbols to release version','no'), ] @@ -156,20 +156,18 @@ def configure(env): else: print("ALSA libraries not found, disabling driver") - if (env["gamepad"]=="yes" and platform.system() == "Linux"): + if (platform.system() == "Linux"): + env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"]) + if (env["udev"]=="yes"): # pkg-config returns 0 when the lib exists... found_udev = not os.system("pkg-config --exists libudev") - + if (found_udev): - print("Enabling gamepad support with udev") - env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"]) + print("Enabling udev support") + env.Append(CPPFLAGS=["-DUDEV_ENABLED"]) env.ParseConfig('pkg-config libudev --cflags --libs') else: - print("libudev development libraries not found") - - print("Some libraries are missing for the required gamepad support, aborting!") - print("Install the mentioned libraries or build with 'gamepad=no' to disable gamepad support.") - sys.exit(255) + print("libudev development libraries not found, disabling udev support") if (env["pulseaudio"]=="yes"): if not os.system("pkg-config --exists libpulse-simple"): diff --git a/platform/x11/joystick_linux.cpp b/platform/x11/joystick_linux.cpp index ef866d5d3a4..9fd19a767ea 100644 --- a/platform/x11/joystick_linux.cpp +++ b/platform/x11/joystick_linux.cpp @@ -99,14 +99,18 @@ void joystick_linux::joy_thread_func(void *p_user) { } void joystick_linux::run_joystick_thread() { - +#ifdef UDEV_ENABLED udev *_udev = udev_new(); ERR_FAIL_COND(!_udev); enumerate_joysticks(_udev); monitor_joysticks(_udev); udev_unref(_udev); +#else + monitor_joysticks(); +#endif } +#ifdef UDEV_ENABLED void joystick_linux::enumerate_joysticks(udev *p_udev) { udev_enumerate *enumerate; @@ -192,6 +196,23 @@ void joystick_linux::monitor_joysticks(udev *p_udev) { //printf("exit udev\n"); udev_monitor_unref(mon); } +#endif + +void joystick_linux::monitor_joysticks() { + + while (!exit_udev) { + joy_mutex->lock(); + for (int i = 0; i < 32; i++) { + char fname[64]; + sprintf(fname, "/dev/input/event%d", i); + if (attached_devices.find(fname) == -1) { + open_joystick(fname); + } + } + joy_mutex->unlock(); + usleep(1000000); // 1s + } +} int joystick_linux::get_free_joy_slot() const { @@ -229,6 +250,7 @@ void joystick_linux::close_joystick(int p_id) { close(joy.fd); joy.fd = -1; + attached_devices.remove(attached_devices.find(joy.devpath)); input->joy_connection_changed(p_id, false, ""); }; }; @@ -302,6 +324,9 @@ void joystick_linux::open_joystick(const char *p_path) { unsigned long keybit[NBITS(KEY_MAX)] = { 0 }; unsigned long absbit[NBITS(ABS_MAX)] = { 0 }; + // add to attached devices so we don't try to open it again + attached_devices.push_back(String(p_path)); + if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) || (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) || (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0)) { @@ -446,6 +471,9 @@ uint32_t joystick_linux::process_joysticks(uint32_t p_event_id) { p_event_id = input->joy_axis(p_event_id, i, index, joy->curr_axis[index]); } } + if (len == 0 || (len < 0 && errno != EAGAIN)) { + close_joystick(i); + }; } joy_mutex->unlock(); return p_event_id; diff --git a/platform/x11/joystick_linux.h b/platform/x11/joystick_linux.h index 7f96e3451f1..e433f5e8e33 100644 --- a/platform/x11/joystick_linux.h +++ b/platform/x11/joystick_linux.h @@ -73,6 +73,7 @@ private: Thread *joy_thread; InputDefault *input; Joystick joysticks[JOYSTICKS_MAX]; + Vector attached_devices; static void joy_thread_func(void *p_user); @@ -81,8 +82,11 @@ private: void setup_joystick_properties(int p_id); void close_joystick(int p_id = -1); +#ifdef UDEV_ENABLED void enumerate_joysticks(struct udev *_udev); void monitor_joysticks(struct udev *_udev); +#endif + void monitor_joysticks(); void run_joystick_thread(); void open_joystick(const char* path);