[gnome-games] gamepad: Add fallback support for gamepads without udev
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games] gamepad: Add fallback support for gamepads without udev
- Date: Tue, 16 Aug 2016 15:28:45 +0000 (UTC)
commit 6abbc5cba83d428ce8cc1d34ef5ffa630415cbcf
Author: Bastien Nocera <hadess hadess net>
Date: Mon Aug 15 01:14:23 2016 +0200
gamepad: Add fallback support for gamepads without udev
udev doesn't have a stable ABI/API, so is not available in
flatpak runtimes. Add a fallback implementation that loads
the joysticks available on startup.
The detection code comes from the input_id.c helper in
systemd/udev, ported to libevdev.
https://bugzilla.gnome.org/show_bug.cgi?id=769904
configure.ac | 9 +++-
src/Makefile.am | 19 +++++++-
.../linux/linux-raw-gamepad-monitor-fallback.vala | 53 ++++++++++++++++++++
src/gamepad/linux/linux-raw-gamepad-monitor.vala | 4 +-
src/gamepad/linux/linux-raw-gamepad.vala | 30 +++++++++++
5 files changed, 112 insertions(+), 3 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index d3c4c2e..26edb1a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -59,11 +59,18 @@ PKG_CHECK_MODULES(GNOME_GAMES, [
])
PKG_CHECK_MODULES(GAMEPADS, [
- gudev-1.0
libevdev
], [enable_gamepads=yes], [enable_gamepads=no])
AM_CONDITIONAL([ENABLE_GAMEPADS], [test x$enable_gamepads != xno])
+enable_udev=no
+if test x$enable_gamepads = xyes ; then
+ PKG_CHECK_MODULES(UDEV, [
+ gudev-1.0
+ ], [enable_udev=yes], [enable_udev=no])
+fi
+AM_CONDITIONAL([ENABLE_UDEV], [test x$enable_udev = xyes])
+
AC_CONFIG_FILES([
Makefile
data/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index 625455b..1164247 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -129,8 +129,17 @@ gnome_games_SOURCES = \
if ENABLE_GAMEPADS
gnome_games_SOURCES += \
gamepad/linux/linux-raw-gamepad.vala \
+ $(NULL)
+
+if ENABLE_UDEV
+gnome_games_SOURCES += \
gamepad/linux/linux-raw-gamepad-monitor.vala \
$(NULL)
+else
+gnome_games_SOURCES += \
+ gamepad/linux/linux-raw-gamepad-monitor-fallback.vala \
+ $(NULL)
+endif
endif
gnome_games_VALAFLAGS = \
@@ -153,15 +162,22 @@ gnome_games_VALAFLAGS = \
if ENABLE_GAMEPADS
gnome_games_VALAFLAGS += \
--vapidir=gamepad/linux/ \
- --pkg gudev-1.0 \
--pkg libevdev \
--define ENABLE_LINUX_GAMEPADS
$(NULL)
endif
+if ENABLE_UDEV
+gnome_games_VALAFLAGS += \
+ --vapidir=gamepad/linux/ \
+ --pkg gudev-1.0 \
+ --define ENABLE_UDEV
+endif
+
gnome_games_CFLAGS = \
$(GNOME_GAMES_CFLAGS) \
$(GAMEPADS_CFLAGS) \
+ $(UDEV_CFLAGS) \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
-DGAMES_PLUGINS_DIR=\"$(libdir)/gnome-games/plugins\" \
$(NULL)
@@ -174,6 +190,7 @@ gnome_games_CPPFLAGS = \
gnome_games_LDADD = \
$(GNOME_GAMES_LIBS) \
$(GAMEPADS_LIBS) \
+ $(UDEV_LIBS) \
$(NULL)
gnome_gamesincludedir = $(includedir)
diff --git a/src/gamepad/linux/linux-raw-gamepad-monitor-fallback.vala
b/src/gamepad/linux/linux-raw-gamepad-monitor-fallback.vala
new file mode 100644
index 0000000..9e331f7
--- /dev/null
+++ b/src/gamepad/linux/linux-raw-gamepad-monitor-fallback.vala
@@ -0,0 +1,53 @@
+// This file is part of GNOME Games. License: GPLv3
+
+// FIXME Workaround the autotools working poorly with Vala.
+#if ENABLE_LINUX_GAMEPADS
+#if !ENABLE_UDEV
+private class Games.LinuxRawGamepadMonitor : Object, RawGamepadMonitor {
+ private static LinuxRawGamepadMonitor instance;
+
+ private HashTable<string, RawGamepad> raw_gamepads;
+
+ private LinuxRawGamepadMonitor () {
+ raw_gamepads = new HashTable<string, RawGamepad> (str_hash, str_equal);
+
+ // Coldplug gamepads
+ try {
+ string directory = "/dev/input";
+ Dir dir = Dir.open (directory, 0);
+ string? name = null;
+ while ((name = dir.read_name ()) != null) {
+ string path = Path.build_filename (directory, name);
+ RawGamepad raw_gamepad;
+ try {
+ raw_gamepad = new LinuxRawGamepad (path);
+ }
+ catch (FileError e) {
+ if (!(e is FileError.NXIO))
+ debug ("Failed to open gamepad %s: %s\n", path, e.message);
+
+ continue;
+ }
+
+ raw_gamepads[name] = raw_gamepad;
+ gamepad_plugged (raw_gamepad);
+ }
+ } catch (FileError err) {
+ debug (err.message);
+ }
+ }
+
+ public static LinuxRawGamepadMonitor get_instance () {
+ if (instance == null)
+ instance = new LinuxRawGamepadMonitor ();
+
+ return instance;
+ }
+
+ public void foreach_gamepad (RawGamepadCallback callback) {
+ raw_gamepads.foreach((identifier, raw_gamepad) => callback (raw_gamepad));
+ }
+}
+
+#endif
+#endif
diff --git a/src/gamepad/linux/linux-raw-gamepad-monitor.vala
b/src/gamepad/linux/linux-raw-gamepad-monitor.vala
index 908ad5c..ecc7376 100644
--- a/src/gamepad/linux/linux-raw-gamepad-monitor.vala
+++ b/src/gamepad/linux/linux-raw-gamepad-monitor.vala
@@ -2,6 +2,7 @@
// FIXME Workaround the autotools working poorly with Vala.
#if ENABLE_LINUX_GAMEPADS
+#if ENABLE_UDEV
private class Games.LinuxRawGamepadMonitor : Object, RawGamepadMonitor {
private static LinuxRawGamepadMonitor instance;
@@ -15,7 +16,7 @@ private class Games.LinuxRawGamepadMonitor : Object, RawGamepadMonitor {
raw_gamepads = new HashTable<string, RawGamepad> (str_hash, str_equal);
- // Initialize initially plugged in gamepads
+ // Coldplug gamepads
var initial_devices_list = client.query_by_subsystem ("input");
foreach (var device in initial_devices_list) {
if (device.get_device_file () == null)
@@ -99,3 +100,4 @@ private class Games.LinuxRawGamepadMonitor : Object, RawGamepadMonitor {
}
#endif
+#endif
diff --git a/src/gamepad/linux/linux-raw-gamepad.vala b/src/gamepad/linux/linux-raw-gamepad.vala
index e83c0ce..8a6bfaf 100644
--- a/src/gamepad/linux/linux-raw-gamepad.vala
+++ b/src/gamepad/linux/linux-raw-gamepad.vala
@@ -45,6 +45,9 @@ private class Games.LinuxRawGamepad : Object, RawGamepad {
if (device.set_fd (fd) < 0)
throw new FileError.FAILED (_("Evdev is unable to open '%s': %s"), file_name,
Posix.strerror (Posix.errno));
+ if (!is_joystick ())
+ throw new FileError.NXIO ("'%s' is not a joystick", file_name);
+
// Poll the events in the default main loop
var channel = new IOChannel.unix_new (fd);
event_source_id = channel.add_watch (IOCondition.IN, poll_events);
@@ -95,6 +98,33 @@ private class Games.LinuxRawGamepad : Object, RawGamepad {
return true;
}
+ private bool has_key (uint code) {
+ return device.has_event_code (Linux.Input.EV_KEY, code);
+ }
+
+ private bool has_abs (uint code) {
+ return device.has_event_code (Linux.Input.EV_ABS, code);
+ }
+
+ private bool is_joystick () {
+ /* Same detection code as udev-builtin-input_id.c in systemd
+ * joysticks don't necessarily have buttons; e. g.
+ * rudders/pedals are joystick-like, but buttonless; they have
+ * other fancy axes */
+ bool has_joystick_axes_or_buttons = has_key (Linux.Input.BTN_TRIGGER) ||
+ has_key (Linux.Input.BTN_A) ||
+ has_key (Linux.Input.BTN_1) ||
+ has_abs (Linux.Input.ABS_RX) ||
+ has_abs (Linux.Input.ABS_RY) ||
+ has_abs (Linux.Input.ABS_RZ) ||
+ has_abs (Linux.Input.ABS_THROTTLE) ||
+ has_abs (Linux.Input.ABS_RUDDER) ||
+ has_abs (Linux.Input.ABS_WHEEL) ||
+ has_abs (Linux.Input.ABS_GAS) ||
+ has_abs (Linux.Input.ABS_BRAKE);
+ return has_joystick_axes_or_buttons;
+ }
+
private void handle_evdev_event () {
Linux.Input.Event event;
if (device.next_event (Libevdev.ReadFlag.NORMAL, out event) != 0)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]