[gnome-games/wip/aplazas/781572-remove-vala-macro: 11/11] gamepad: Port GamepadMonitor to C
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games/wip/aplazas/781572-remove-vala-macro: 11/11] gamepad: Port GamepadMonitor to C
- Date: Thu, 27 Apr 2017 05:00:42 +0000 (UTC)
commit 6456b6556407bfb76dc78611324afd88dd03aea3
Author: Adrien Plazas <kekun plazas laposte net>
Date: Wed Apr 26 08:42:49 2017 +0200
gamepad: Port GamepadMonitor to C
This finishes porting part of the gamepad handling to C to avoid using
Vala macros.
src/Makefile.am | 4 +-
src/gamepad/gamepad-monitor.c | 255 +++++++++++++++++++++++++++++++++++++
src/gamepad/gamepad-monitor.h | 22 +++
src/gamepad/gamepad-monitor.vapi | 8 +
src/gamepad/raw-gamepad-monitor.h | 4 +-
5 files changed, 291 insertions(+), 2 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 604ff67..2124de7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,6 +23,7 @@ BUILT_SOURCES = \
EXTRA_DIST = \
$(gresource_file) \
+ gamepad/gamepad-monitor.vapi \
gamepad/linux/linux-raw-gamepad-monitor.vapi \
gamepad/raw-gamepad.vapi \
gamepad/raw-gamepad-monitor.vapi \
@@ -78,7 +79,7 @@ gnome_games_SOURCES = \
gamepad/gamepad-mapping.vala \
gamepad/gamepad-mapping-error.vala \
gamepad/gamepad-mappings-manager.vala \
- gamepad/gamepad-monitor.vala \
+ gamepad/gamepad-monitor.c \
gamepad/raw-gamepad.c \
gamepad/raw-gamepad-monitor.c \
gamepad/standard-gamepad-axis.c \
@@ -182,6 +183,7 @@ gnome_games_VALAFLAGS = \
--pkg retro-gtk-0.10 \
--pkg linux \
--pkg posix \
+ --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..273d1fd
--- /dev/null
+++ b/src/gamepad/gamepad-monitor.c
@@ -0,0 +1,255 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+#include "gamepad-monitor.h"
+
+#include "raw-gamepad-monitor.h"
+//#include "raw-gamepad.h"
+
+#define GAMES_TYPE_GAMEPAD_MONITOR (games_gamepad_monitor_get_type ())
+#define GAMES_GAMEPAD_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAMES_TYPE_GAMEPAD_MONITOR,
GamesGamepadMonitor))
+#define GAMES_GAMEPAD_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAMES_TYPE_GAMEPAD_MONITOR,
GamesGamepadMonitorClass))
+#define GAMES_IS_GAMEPAD_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAMES_TYPE_GAMEPAD_MONITOR))
+#define GAMES_IS_GAMEPAD_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAMES_TYPE_GAMEPAD_MONITOR))
+#define GAMES_GAMEPAD_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAMES_TYPE_GAMEPAD_MONITOR,
GamesGamepadMonitorClass))
+
+typedef struct _GamesGamepadMonitor GamesGamepadMonitor;
+typedef struct _GamesGamepadMonitorClass GamesGamepadMonitorClass;
+
+#define GAMES_TYPE_GAMEPAD (games_gamepad_get_type ())
+#define GAMES_GAMEPAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAMES_TYPE_GAMEPAD, GamesGamepad))
+#define GAMES_GAMEPAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAMES_TYPE_GAMEPAD, GamesGamepadClass))
+#define GAMES_IS_GAMEPAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAMES_TYPE_GAMEPAD))
+#define GAMES_IS_GAMEPAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAMES_TYPE_GAMEPAD))
+#define GAMES_GAMEPAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAMES_TYPE_GAMEPAD,
GamesGamepadClass))
+
+typedef struct _GamesGamepad GamesGamepad;
+typedef struct _GamesGamepadClass GamesGamepadClass;
+#define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL)))
+
+#define GAMES_TYPE_LINUX_RAW_GAMEPAD_MONITOR (games_linux_raw_gamepad_monitor_get_type ())
+#define GAMES_LINUX_RAW_GAMEPAD_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GAMES_TYPE_LINUX_RAW_GAMEPAD_MONITOR, GamesLinuxRawGamepadMonitor))
+#define GAMES_LINUX_RAW_GAMEPAD_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
GAMES_TYPE_LINUX_RAW_GAMEPAD_MONITOR, GamesLinuxRawGamepadMonitorClass))
+#define GAMES_IS_LINUX_RAW_GAMEPAD_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
GAMES_TYPE_LINUX_RAW_GAMEPAD_MONITOR))
+#define GAMES_IS_LINUX_RAW_GAMEPAD_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
GAMES_TYPE_LINUX_RAW_GAMEPAD_MONITOR))
+#define GAMES_LINUX_RAW_GAMEPAD_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
GAMES_TYPE_LINUX_RAW_GAMEPAD_MONITOR, GamesLinuxRawGamepadMonitorClass))
+
+typedef struct _GamesLinuxRawGamepadMonitor GamesLinuxRawGamepadMonitor;
+typedef struct _GamesLinuxRawGamepadMonitorClass GamesLinuxRawGamepadMonitorClass;
+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
+#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
+enum
+{
+ SIGNAL_PLUGGED,
+ LAST_SIGNAL,
+};
+static guint signals[LAST_SIGNAL] = { 0 };
+
+struct _GamesGamepadMonitor {
+ GObject parent_instance;
+ GHashTable *gamepads;
+};
+
+struct _GamesGamepadMonitorClass {
+ GObjectClass parent_class;
+};
+
+typedef enum {
+ GAMES_GAMEPAD_MAPPING_ERROR_NOT_A_MAPPING,
+} GamesGamepadMappingError;
+#define GAMES_GAMEPAD_MAPPING_ERROR games_gamepad_mapping_error_quark ()
+
+static gpointer games_gamepad_monitor_parent_class = NULL;
+static GamesGamepadMonitor *instance;
+static GamesGamepadMonitor *instance = NULL;
+
+GType games_gamepad_monitor_get_type (void) G_GNUC_CONST;
+GType games_gamepad_get_type (void) G_GNUC_CONST;
+
+static GamesGamepadMonitor *games_gamepad_monitor_new (void);
+static GamesGamepadMonitor *games_gamepad_monitor_construct (GType object_type);
+GType games_linux_raw_gamepad_monitor_get_type (void) G_GNUC_CONST;
+GamesLinuxRawGamepadMonitor *games_linux_raw_gamepad_monitor_get_instance (void);
+static void on_raw_gamepad_plugged (GamesGamepadMonitor *self, GamesRawGamepad *raw_gamepad);
+static void _on_raw_gamepad_plugged_games_raw_gamepad_monitor_gamepad_plugged (GamesRawGamepadMonitor
*_sender, GamesRawGamepad *raw_gamepad, gpointer self);
+static GamesGamepad *add_gamepad (GamesGamepadMonitor *self, GamesRawGamepad *raw_gamepad);
+static void foreach_raw_gamepad_do (GamesRawGamepad *raw_gamepad, gpointer self);
+GamesGamepadMonitor *games_gamepad_monitor_get_instance (void);
+void games_gamepad_monitor_foreach_gamepad (GamesGamepadMonitor *self, GamesGamepadCallback callback, void
*callback_target);
+GQuark games_gamepad_mapping_error_quark (void);
+GamesGamepad *games_gamepad_new (GamesRawGamepad *raw_gamepad, GError **error);
+GamesGamepad *games_gamepad_construct (GType object_type, GamesRawGamepad *raw_gamepad, GError **error);
+static void games_gamepad_monitor_finalize (GObject *obj);
+
+static void _on_raw_gamepad_plugged_games_raw_gamepad_monitor_gamepad_plugged (GamesRawGamepadMonitor
*_sender, GamesRawGamepad *raw_gamepad, gpointer self) {
+ on_raw_gamepad_plugged ((GamesGamepadMonitor*) self, raw_gamepad);
+}
+
+static void
+foreach_raw_gamepad_do (GamesRawGamepad *raw_gamepad, gpointer data)
+{
+ GamesGamepadMonitor *self;
+ GamesGamepad *gamepad;
+
+ self = GAMES_GAMEPAD_MONITOR (self);
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (raw_gamepad != NULL);
+
+ gamepad = add_gamepad (self, raw_gamepad);
+ if (gamepad != NULL)
+ g_object_unref (gamepad);
+}
+
+static GamesGamepadMonitor *
+games_gamepad_monitor_new (void)
+{
+ GamesGamepadMonitor *self = NULL;
+ GamesLinuxRawGamepadMonitor *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_linux_raw_gamepad_monitor_get_instance ();
+ g_signal_connect_object ((GamesRawGamepadMonitor*) raw_gamepad_monitor, "gamepad-plugged", (GCallback)
_on_raw_gamepad_plugged_games_raw_gamepad_monitor_gamepad_plugged, self, 0);
+ games_raw_gamepad_monitor_foreach_gamepad ((GamesRawGamepadMonitor*) raw_gamepad_monitor,
foreach_raw_gamepad_do, self);
+ g_object_unref (raw_gamepad_monitor);
+#endif / *ENABLE_LINUX_GAMEPADS */
+
+ return self;
+}
+
+static void
+remove_gamepad (GamesGamepadMonitor *self,
+ GamesGamepad *gamepad)
+{
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (gamepad != NULL);
+
+ g_hash_table_remove (self->gamepads, gamepad);
+}
+
+static void
+on_gamepad_unplugged (GamesGamepad *sender,
+ gpointer self)
+{
+ remove_gamepad (GAMES_GAMEPAD_MONITOR (self), 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_error_free (_inner_error_);
+ g_assert (gamepad == NULL);
+
+ return NULL;
+ }
+
+ g_assert (gamepad != 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 (GamesGamepadMonitor *self,
+ GamesRawGamepad *raw_gamepad)
+{
+ GamesGamepad *gamepad;
+
+ 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_PLUGGED], 0, gamepad);
+ g_object_unref (gamepad);
+ }
+}
+
+/* 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 callback_target)
+{
+ GHashTableIter iter = { 0 };
+ GamesGamepad *gamepad = NULL;
+
+ g_return_if_fail (self != NULL);
+
+ g_hash_table_iter_init (&iter, self->gamepads);
+ while (g_hash_table_iter_next (&iter, (gpointer *) &gamepad, NULL))
+ callback (gamepad, callback_target);
+}
+
+/* Type */
+
+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 = games_gamepad_monitor_finalize;
+ /**
+ * Emitted when a gamepad is plugged in.
+ * This would be emitted once even if RawGamepadMonitor emits it multiple
+ * times
+ * @param gamepad The gamepad
+ */
+ signals[SIGNAL_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 instance_init (GamesGamepadMonitor *self) {
+}
+
+static void games_gamepad_monitor_finalize (GObject *obj) {
+ GamesGamepadMonitor *self;
+ self = G_TYPE_CHECK_INSTANCE_CAST (obj, GAMES_TYPE_GAMEPAD_MONITOR, GamesGamepadMonitor);
+ _g_hash_table_unref0 (self->gamepads);
+ G_OBJECT_CLASS (games_gamepad_monitor_parent_class)->finalize (obj);
+}
+
+/**
+ * This class provides a way to the client to monitor gamepads
+ *
+ * The client interfaces with this class primarily
+ */
+GType games_gamepad_monitor_get_type (void) {
+ static volatile gsize games_gamepad_monitor_type_id__volatile = 0;
+ if (g_once_init_enter (&games_gamepad_monitor_type_id__volatile)) {
+ static const GTypeInfo g_define_type_info = { sizeof (GamesGamepadMonitorClass), (GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL, (GClassInitFunc) games_gamepad_monitor_class_init, (GClassFinalizeFunc) NULL, NULL,
sizeof (GamesGamepadMonitor), 0, (GInstanceInitFunc) instance_init, NULL };
+ GType games_gamepad_monitor_type_id;
+ games_gamepad_monitor_type_id = g_type_register_static (G_TYPE_OBJECT, "GamesGamepadMonitor",
&g_define_type_info, 0);
+ g_once_init_leave (&games_gamepad_monitor_type_id__volatile, games_gamepad_monitor_type_id);
+ }
+ return games_gamepad_monitor_type_id__volatile;
+}
diff --git a/src/gamepad/gamepad-monitor.h b/src/gamepad/gamepad-monitor.h
new file mode 100644
index 0000000..62efeb5
--- /dev/null
+++ b/src/gamepad/gamepad-monitor.h
@@ -0,0 +1,22 @@
+#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 user_data);
+
+#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 callback_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..027caae
--- /dev/null
+++ b/src/gamepad/gamepad-monitor.vapi
@@ -0,0 +1,8 @@
+// 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);
+}
diff --git a/src/gamepad/raw-gamepad-monitor.h b/src/gamepad/raw-gamepad-monitor.h
index 7ac4f19..c771e3a 100644
--- a/src/gamepad/raw-gamepad-monitor.h
+++ b/src/gamepad/raw-gamepad-monitor.h
@@ -27,7 +27,9 @@ struct _GamesRawGamepadMonitorInterface
// FIXME Remove this once every piece using it has been moved to C.
typedef struct _GamesRawGamepadMonitorInterface GamesRawGamepadMonitorIface;
-const gchar *games_raw_gamepad_monitor_get_guid (GamesRawGamepadMonitor *self);
+void games_raw_gamepad_monitor_foreach_gamepad (GamesRawGamepadMonitor *self,
+ GamesRawGamepadCallback callback,
+ gpointer data);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]