[gnome-games] gamepad: Add LinuxRawGamepadMonitor



commit 500c470b4b831149b279f3cb80588ac37882c24a
Author: Megh Parikh <meghprkh gmail com>
Date:   Mon Jul 18 21:29:00 2016 +0530

    gamepad: Add LinuxRawGamepadMonitor
    
    This class implements RawGamepadMonitor and uses GUDev allowing us to
    listen to plugin events and iterating through the RawGamepads
    
    This is part of a series of commits to add gamepad support.

 configure.ac                                     |    1 +
 src/Makefile.am                                  |    2 +
 src/gamepad/linux/linux-raw-gamepad-monitor.vala |   96 ++++++++++++++++++++++
 3 files changed, 99 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 9e0a185..aaf044e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,6 +51,7 @@ PKG_CHECK_MODULES(GNOME_GAMES, [
        glib-2.0 >= $GLIB_MIN_VERSION
        grilo-0.3
        gtk+-3.0
+       gudev-1.0
        libevdev
        retro-gobject-0.6
        retro-gtk-0.6
diff --git a/src/Makefile.am b/src/Makefile.am
index ba4a5e3..2a8b529 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -55,6 +55,7 @@ gnome_games_SOURCES = \
        \
        gamepad/gamepad-callbacks.vala \
        gamepad/linux/linux-raw-gamepad.vala \
+       gamepad/linux/linux-raw-gamepad-monitor.vala \
        gamepad/raw-gamepad.vala \
        gamepad/raw-gamepad-monitor.vala \
        \
@@ -112,6 +113,7 @@ gnome_games_VALAFLAGS = \
        --pkg tracker-sparql-1.0 \
        --pkg retro-gobject-0.6 \
        --pkg retro-gtk-0.6 \
+       --pkg gudev-1.0 \
        --pkg libevdev \
        --pkg linux \
        --pkg posix \
diff --git a/src/gamepad/linux/linux-raw-gamepad-monitor.vala 
b/src/gamepad/linux/linux-raw-gamepad-monitor.vala
new file mode 100644
index 0000000..aaebf31
--- /dev/null
+++ b/src/gamepad/linux/linux-raw-gamepad-monitor.vala
@@ -0,0 +1,96 @@
+// This file is part of GNOME Games. License: GPLv3
+
+private class Games.LinuxRawGamepadMonitor : Object, RawGamepadMonitor {
+       private static LinuxRawGamepadMonitor instance;
+
+       private GUdev.Client client;
+       private HashTable<string, RawGamepad> raw_gamepads;
+
+       private LinuxRawGamepadMonitor () {
+               client = new GUdev.Client ({"input"});
+               client.uevent.connect (handle_udev_client_callback);
+
+               raw_gamepads = new HashTable<string, RawGamepad> (str_hash, str_equal);
+
+               // Initialize initially plugged in gamepads
+               var initial_devices_list = client.query_by_subsystem ("input");
+               foreach (var device in initial_devices_list) {
+                       if (device.get_device_file () == null)
+                               continue;
+
+                       if (!is_gamepad (device))
+                               continue;
+
+                       add_gamepad (device);
+               }
+       }
+
+       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));
+       }
+
+       private void handle_udev_client_callback (string action, GUdev.Device device) {
+               if (device.get_device_file () == null)
+                       return;
+
+               if (!is_gamepad (device))
+                       return;
+
+               switch (action) {
+               case "add":
+                       var raw_gamepad = add_gamepad (device);
+                       if (raw_gamepad != null)
+                               gamepad_plugged (raw_gamepad);
+
+                       break;
+               case "remove":
+                       var raw_gamepad = remove_gamepad (device);
+                       if (raw_gamepad != null)
+                               // This signal is emitted from here to simplify the code
+                               raw_gamepad.unplugged ();
+
+                       break;
+               }
+       }
+
+       private RawGamepad? add_gamepad (GUdev.Device device) {
+               var identifier = device.get_device_file ();
+               RawGamepad raw_gamepad;
+               try {
+                       raw_gamepad = new LinuxRawGamepad (identifier);
+               }
+               catch (FileError e) {
+                       return null;
+               }
+
+               if (raw_gamepads.contains (identifier))
+                       return null;
+
+               raw_gamepads[identifier] = raw_gamepad;
+
+               return raw_gamepad;
+       }
+
+       private RawGamepad? remove_gamepad (GUdev.Device device) {
+               var identifier = device.get_device_file ();
+               if (!raw_gamepads.contains (identifier))
+                       return null;
+
+               var raw_gamepad = raw_gamepads[identifier];
+               raw_gamepads.remove (identifier);
+
+               return raw_gamepad;
+       }
+
+       private static bool is_gamepad (GUdev.Device device) {
+               return ((device.has_property ("ID_INPUT_JOYSTICK") && device.get_property 
("ID_INPUT_JOYSTICK") == "1") ||
+                       (device.has_property (".INPUT_CLASS") && device.get_property (".INPUT_CLASS") == 
"joystick"));
+       }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]