[gnome-games/wip/aplazas/781572-remove-vala-macro: 2/2] gamepad: Port GamepadMonitor to C



commit 0f57d0c804830aeb47645088e39eee1504c9a33c
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Tue May 2 12:50:19 2017 +0200

    gamepad: Port GamepadMonitor to C
    
    Also port GamepadCallback to C.
    
    This finishes porting the gamepad handling to C and, by extenstion,
    stops using the Vala preprocessor.

 src/Makefile.am                    |    5 +-
 src/gamepad/gamepad-callbacks.vala |    5 -
 src/gamepad/gamepad-monitor.c      |  211 ++++++++++++++++++++++++++++++++++++
 src/gamepad/gamepad-monitor.h      |   26 +++++
 src/gamepad/gamepad-monitor.vala   |   68 ------------
 src/gamepad/gamepad-monitor.vapi   |   11 ++
 6 files changed, 251 insertions(+), 75 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index d3f0fcd..e13b1b2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,6 +29,7 @@ EXTRA_DIST = \
        gamepad/gamepad-mapping.vapi \
        gamepad/gamepad-mapping-error.vapi \
        gamepad/gamepad-mappings-manager.vapi \
+       gamepad/gamepad-monitor.vapi \
        gamepad/linux/linux-raw-gamepad-monitor.vapi \
        gamepad/raw-gamepad.vapi \
        gamepad/raw-gamepad-monitor.vapi \
@@ -77,14 +78,13 @@ gnome_games_SOURCES = \
        gameinfo/gameinfo-disc-id-input-capabilities.vala \
        \
        gamepad/gamepad.c \
-       gamepad/gamepad-callbacks.vala \
        gamepad/gamepad-dpad.c \
        gamepad/gamepad-input-type.c \
        gamepad/gamepad-mapped-event.c \
        gamepad/gamepad-mapping.c \
        gamepad/gamepad-mapping-error.c \
        gamepad/gamepad-mappings-manager.c \
-       gamepad/gamepad-monitor.vala \
+       gamepad/gamepad-monitor.c \
        gamepad/raw-gamepad.c \
        gamepad/raw-gamepad-monitor.c \
        gamepad/standard-gamepad-axis.c \
@@ -194,6 +194,7 @@ gnome_games_VALAFLAGS = \
        --pkg gamepad-mapping \
        --pkg gamepad-mapping-error \
        --pkg gamepad-mappings-manager \
+       --pkg gamepad-monitor \
        --pkg raw-gamepad \
        --pkg raw-gamepad-monitor \
        --pkg standard-gamepad-axis \
diff --git a/src/gamepad/gamepad-monitor.c b/src/gamepad/gamepad-monitor.c
new file mode 100644
index 0000000..cfa3000
--- /dev/null
+++ b/src/gamepad/gamepad-monitor.c
@@ -0,0 +1,211 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+#include "gamepad-monitor.h"
+
+#include <glib.h>
+#include <glib-object.h>
+#include <linux-raw-gamepad-monitor.h>
+#include <raw-gamepad-monitor.h>
+#include <raw-gamepad.h>
+#include <gamepad-mapping-error.h>
+
+struct _GamesGamepadMonitor {
+  GObject parent_instance;
+
+  GHashTable *gamepads;
+};
+
+G_DEFINE_TYPE (GamesGamepadMonitor, games_gamepad_monitor, G_TYPE_OBJECT)
+
+enum {
+  SIGNAL_GAMEPAD_PLUGGED,
+  LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static GamesGamepadMonitor *instance = NULL;
+
+typedef struct {
+  GamesGamepadCallback callback;
+  gpointer target;
+} ForeachGamepadData;
+
+/* Private */
+
+static void
+on_gamepad_unplugged (GamesGamepad *sender,
+                      gpointer data)
+{
+  GamesGamepadMonitor *self;
+
+  self = GAMES_GAMEPAD_MONITOR (data);
+
+  g_return_if_fail (self != NULL);
+  g_return_if_fail (sender != NULL);
+
+  g_hash_table_remove (self->gamepads, sender);
+}
+
+static GamesGamepad *
+add_gamepad (GamesGamepadMonitor *self,
+             GamesRawGamepad     *raw_gamepad)
+{
+  GamesGamepad *gamepad = NULL;
+  GError *inner_error = NULL;
+
+  g_return_val_if_fail (self != NULL, NULL);
+  g_return_val_if_fail (raw_gamepad != NULL, NULL);
+
+  gamepad = games_gamepad_new (raw_gamepad, &inner_error);
+  if (G_UNLIKELY (inner_error != NULL)) {
+    g_clear_error (&inner_error);
+
+    return NULL;
+  }
+
+  g_hash_table_add (self->gamepads, g_object_ref (gamepad));
+  g_signal_connect_object (gamepad,
+                           "unplugged",
+                           (GCallback) on_gamepad_unplugged,
+                           self,
+                           0);
+
+  return gamepad;
+}
+
+static void
+on_raw_gamepad_plugged (GamesRawGamepadMonitor *sender,
+                        GamesRawGamepad        *raw_gamepad,
+                        gpointer                target)
+{
+  GamesGamepadMonitor *self;
+  GamesGamepad *gamepad;
+
+  self = GAMES_GAMEPAD_MONITOR (target);
+
+  g_return_if_fail (self != NULL);
+  g_return_if_fail (raw_gamepad != NULL);
+
+  gamepad = add_gamepad (self, raw_gamepad);
+  if (gamepad != NULL) {
+    g_signal_emit (self, signals[SIGNAL_GAMEPAD_PLUGGED], 0, gamepad);
+    g_object_unref (gamepad);
+  }
+}
+
+static void
+add_raw_gamepad (GamesRawGamepad *raw_gamepad,
+                 gpointer         target)
+{
+  GamesGamepadMonitor *self;
+  GamesGamepad *gamepad;
+
+  self = GAMES_GAMEPAD_MONITOR (target);
+
+  g_return_if_fail (self != NULL);
+  g_return_if_fail (raw_gamepad != NULL);
+
+  g_object_unref (add_gamepad (self, raw_gamepad));
+}
+
+static void
+foreach_gamepad_do (gpointer key,
+                    gpointer value,
+                    gpointer data)
+{
+  ForeachGamepadData *callback_data;
+  GamesGamepad *gamepad;
+
+  callback_data = (ForeachGamepadData *) data;
+  gamepad = (GamesGamepad *) value;
+
+  g_return_if_fail (gamepad != NULL);
+
+  callback_data->callback (gamepad, callback_data->target);
+}
+
+static GamesGamepadMonitor *
+games_gamepad_monitor_new (void)
+{
+  GamesGamepadMonitor *self = NULL;
+  GamesRawGamepadMonitor *raw_gamepad_monitor;
+
+  self = (GamesGamepadMonitor*) g_object_new (GAMES_TYPE_GAMEPAD_MONITOR, NULL);
+  self->gamepads = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
+
+#if ENABLE_LINUX_GAMEPADS
+  raw_gamepad_monitor = GAMES_RAW_GAMEPAD_MONITOR (games_linux_raw_gamepad_monitor_get_instance ());
+  g_signal_connect_object (raw_gamepad_monitor,
+                           "gamepad-plugged",
+                           (GCallback) on_raw_gamepad_plugged,
+                           self,
+                           0);
+  games_raw_gamepad_monitor_foreach_gamepad (raw_gamepad_monitor,
+                                             add_raw_gamepad,
+                                             self);
+  g_object_unref (raw_gamepad_monitor);
+#endif /* ENABLE_LINUX_GAMEPADS */
+
+  return self;
+}
+
+/* Public */
+
+GamesGamepadMonitor *games_gamepad_monitor_get_instance (void) {
+  if (instance == NULL)
+    instance = games_gamepad_monitor_new ();
+
+  return g_object_ref (instance);
+}
+
+void
+games_gamepad_monitor_foreach_gamepad (GamesGamepadMonitor  *self,
+                                       GamesGamepadCallback  callback,
+                                       gpointer              target)
+{
+  ForeachGamepadData data;
+
+  g_return_if_fail (self != NULL);
+  g_return_if_fail (callback != NULL);
+
+  data.callback = callback;
+  data.target = target;
+  g_hash_table_foreach (self->gamepads, foreach_gamepad_do, &data);
+}
+
+/* Type */
+
+static void
+finalize (GObject *object)
+{
+  GamesGamepadMonitor *self = GAMES_GAMEPAD_MONITOR (object);
+
+  g_hash_table_unref (self->gamepads);
+
+  G_OBJECT_CLASS (games_gamepad_monitor_parent_class)->finalize (object);
+}
+
+static void games_gamepad_monitor_class_init (GamesGamepadMonitorClass *klass) {
+  games_gamepad_monitor_parent_class = g_type_class_peek_parent (klass);
+  G_OBJECT_CLASS (klass)->finalize = finalize;
+
+  /**
+   * GamesGamepad::unplugged:
+   *
+   * Emitted when the gamepad is unplugged.
+   */
+  signals[SIGNAL_GAMEPAD_PLUGGED] =
+    g_signal_new ("gamepad_plugged",
+                  GAMES_TYPE_GAMEPAD_MONITOR,
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  g_cclosure_marshal_VOID__OBJECT,
+                  G_TYPE_NONE, 1,
+                  GAMES_TYPE_GAMEPAD);
+}
+
+static void
+games_gamepad_monitor_init (GamesGamepadMonitor *self)
+{
+}
diff --git a/src/gamepad/gamepad-monitor.h b/src/gamepad/gamepad-monitor.h
new file mode 100644
index 0000000..b77dbe5
--- /dev/null
+++ b/src/gamepad/gamepad-monitor.h
@@ -0,0 +1,26 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+#ifndef GAMES_GAMEPAD_MONITOR_H
+#define GAMES_GAMEPAD_MONITOR_H
+
+#include <glib-object.h>
+#include "gamepad.h"
+
+G_BEGIN_DECLS
+
+typedef void (*GamesGamepadCallback) (GamesGamepad *gamepad,
+                                      gpointer      target);
+
+#define GAMES_TYPE_GAMEPAD_MONITOR (games_gamepad_monitor_get_type())
+
+G_DECLARE_FINAL_TYPE (GamesGamepadMonitor, games_gamepad_monitor, GAMES, GAMEPAD_MONITOR, GObject)
+
+GamesGamepadMonitor *games_gamepad_monitor_get_instance (void);
+void games_gamepad_monitor_foreach_gamepad (GamesGamepadMonitor *self,
+                                            GamesGamepadCallback callback,
+                                            gpointer target);
+
+G_END_DECLS
+
+#endif /* GAMES_GAMEPAD_MONITOR_H */
+
diff --git a/src/gamepad/gamepad-monitor.vapi b/src/gamepad/gamepad-monitor.vapi
new file mode 100644
index 0000000..ec61c08
--- /dev/null
+++ b/src/gamepad/gamepad-monitor.vapi
@@ -0,0 +1,11 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+[CCode (cheader_filename = "gamepad-monitor.h")]
+private class Games.GamepadMonitor : GLib.Object {
+       public signal void gamepad_plugged (Gamepad gamepad);
+       public static GamepadMonitor get_instance ();
+       public void foreach_gamepad (GamepadCallback callback);
+}
+
+[CCode (cheader_filename = "gamepad-monitor.h")]
+private delegate void Games.GamepadCallback (Games.Gamepad gamepad);


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