[gnome-games/wip/aplazas/781572-remove-vala-macro: 3/4] gamepad: Port GamepadMappingsManager to C
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games/wip/aplazas/781572-remove-vala-macro: 3/4] gamepad: Port GamepadMappingsManager to C
- Date: Tue, 2 May 2017 06:30:48 +0000 (UTC)
commit 5c0e3fc2d95c5964ab01ace2bf3e9177fbf2c363
Author: Adrien Plazas <kekun plazas laposte net>
Date: Sun Apr 30 09:21:02 2017 +0200
gamepad: Port GamepadMappingsManager to C
This will help to port part of the gamepad handling to C to avoid using
the Vala preprocessor.
src/Makefile.am | 4 +-
src/gamepad/gamepad-mappings-manager.c | 254 +++++++++++++++++++++++++++++
src/gamepad/gamepad-mappings-manager.h | 19 ++
src/gamepad/gamepad-mappings-manager.vala | 85 ----------
src/gamepad/gamepad-mappings-manager.vapi | 7 +
5 files changed, 283 insertions(+), 86 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 0cb9959..2f75f14 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -26,6 +26,7 @@ EXTRA_DIST = \
gamepad/gamepad-input-type.vapi \
gamepad/gamepad-mapping.vapi \
gamepad/gamepad-mapping-error.vapi \
+ gamepad/gamepad-mappings-manager.vapi \
gamepad/linux/linux-raw-gamepad-monitor.vapi \
gamepad/raw-gamepad.vapi \
gamepad/raw-gamepad-monitor.vapi \
@@ -80,7 +81,7 @@ gnome_games_SOURCES = \
gamepad/gamepad-mapped-event.c \
gamepad/gamepad-mapping.c \
gamepad/gamepad-mapping-error.c \
- gamepad/gamepad-mappings-manager.vala \
+ gamepad/gamepad-mappings-manager.c \
gamepad/gamepad-monitor.vala \
gamepad/raw-gamepad.c \
gamepad/raw-gamepad-monitor.c \
@@ -188,6 +189,7 @@ gnome_games_VALAFLAGS = \
--pkg gamepad-input-type \
--pkg gamepad-mapping \
--pkg gamepad-mapping-error \
+ --pkg gamepad-mappings-manager \
--pkg raw-gamepad \
--pkg raw-gamepad-monitor \
--pkg standard-gamepad-axis \
diff --git a/src/gamepad/gamepad-mappings-manager.c b/src/gamepad/gamepad-mappings-manager.c
new file mode 100644
index 0000000..a43e95e
--- /dev/null
+++ b/src/gamepad/gamepad-mappings-manager.c
@@ -0,0 +1,254 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+#include "gamepad-mappings-manager.h"
+
+#include <glib.h>
+#include <glib-object.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gio/gio.h>
+
+struct _GamesGamepadMappingsManager {
+ GObject parent_instance;
+
+ GHashTable *names;
+ GHashTable *mappings;
+};
+
+G_DEFINE_TYPE (GamesGamepadMappingsManager, games_gamepad_mappings_manager, G_TYPE_OBJECT);
+
+static GamesGamepadMappingsManager *instance = NULL;
+
+#define MAPPINGS_FILE_NAME "gamecontrollerdb.txt"
+
+// FIXME The gamepad module shouldn't have a hidden dependency on the
+// application.
+gchar *games_application_get_config_dir (void);
+
+/* Private */
+
+static void
+add_mapping (GamesGamepadMappingsManager *self,
+ const gchar *mapping_string)
+{
+ const gchar *platform;
+ gchar **split;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (mapping_string != NULL);
+
+ if (mapping_string[0] == '\0' || mapping_string[0] == '#')
+ return;
+
+ platform = g_strstr_len (mapping_string, -1, "platform");
+ if (platform != NULL && !g_str_has_prefix (platform, "platform:Linux"))
+ return;
+
+ split = g_strsplit (mapping_string, ",", 3);
+ g_hash_table_insert (self->names,
+ g_strdup (split[0]),
+ g_strdup (split[1]));
+ g_hash_table_insert (self->mappings,
+ g_strdup (split[0]),
+ g_strdup (split[2]));
+ g_strfreev (split);
+}
+
+static void
+add_from_input_stream (GamesGamepadMappingsManager *self,
+ GInputStream *input_stream,
+ GError **error)
+{
+ GDataInputStream *data_stream;
+ gchar *mapping_string;
+ GError *inner_error = NULL;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (input_stream != NULL);
+
+ data_stream = g_data_input_stream_new (input_stream);
+ while (TRUE) {
+ mapping_string = g_data_input_stream_read_line (data_stream,
+ NULL, NULL,
+ &inner_error);
+ if (G_UNLIKELY (inner_error != NULL)) {
+ g_assert (mapping_string == NULL);
+ g_propagate_error (error, inner_error);
+ g_object_unref (data_stream);
+
+ return;
+ }
+
+ if (mapping_string == NULL)
+ break;
+
+ add_mapping (self, mapping_string);
+ }
+ g_object_unref (data_stream);
+}
+
+static void
+add_from_resource (GamesGamepadMappingsManager *self,
+ const gchar *path,
+ GError **error)
+{
+ GInputStream *stream;
+ GError *inner_error = NULL;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (path != NULL);
+
+ stream = g_resources_open_stream (path,
+ G_RESOURCE_LOOKUP_FLAGS_NONE,
+ &inner_error);
+ if (G_UNLIKELY (inner_error != NULL)) {
+ g_propagate_error (error, inner_error);
+
+ return;
+ }
+
+ add_from_input_stream (self, G_INPUT_STREAM (stream), &inner_error);
+ if (G_UNLIKELY (inner_error != NULL)) {
+ g_propagate_error (error, inner_error);
+ g_object_unref (stream);
+
+ return;
+ }
+
+ g_object_unref (stream);
+}
+
+static void
+add_from_file (GamesGamepadMappingsManager *self,
+ const gchar *file_name,
+ GError **error)
+{
+ GFile *file;
+ GFileInputStream *stream;
+ GError *inner_error = NULL;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (file_name != NULL);
+
+ file = g_file_new_for_path (file_name);
+ stream = g_file_read (file, NULL, &inner_error);
+ if (G_UNLIKELY (inner_error != NULL)) {
+ g_propagate_error (error, inner_error);
+ g_object_unref (file);
+
+ return;
+ }
+
+ add_from_input_stream (self, G_INPUT_STREAM (stream), &inner_error);
+ if (G_UNLIKELY (inner_error != NULL)) {
+ g_propagate_error (error, inner_error);
+ g_object_unref (stream);
+ g_object_unref (file);
+
+ return;
+ }
+
+ g_object_unref (stream);
+ g_object_unref (file);
+}
+
+static GamesGamepadMappingsManager *
+games_gamepad_mappings_manager_new (void)
+{
+ GamesGamepadMappingsManager *self = NULL;
+ gchar *dir;
+ gchar *path;
+ GError *inner_error = NULL;
+
+ self = (GamesGamepadMappingsManager*) g_object_new (GAMES_TYPE_GAMEPAD_MAPPINGS_MANAGER, NULL);
+
+ if (self->names == NULL)
+ self->names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+ if (self->mappings == NULL)
+ self->mappings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+ add_from_resource (self,
+ "/org/gnome/Games/gamepads/gamecontrollerdb.txt",
+ &inner_error);
+ if (G_UNLIKELY (inner_error != NULL)) {
+ g_warning ("GamepadMappingsManager: Can’t find resource gamecontrollerdb.txt: %s",
+ inner_error->message);
+ g_clear_error (&inner_error);
+ }
+
+ // FIXME The gamepad module shouldn't have a hidden dependency on the
+ // application.
+ dir = games_application_get_config_dir ();
+ path = g_build_filename (dir, MAPPINGS_FILE_NAME, NULL);
+
+ g_free (dir);
+
+ if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
+ g_free (path);
+
+ return self;
+ }
+
+ add_from_file (self, path, &inner_error);
+ if (G_UNLIKELY (inner_error != NULL)) {
+ g_warning ("GamepadMappingsManager: Can’t add from user’s config dir’s %s: %s",
+ MAPPINGS_FILE_NAME,
+ inner_error->message);
+ g_clear_error (&inner_error);
+ }
+
+ g_free (path);
+
+ return self;
+}
+
+/* Public */
+
+GamesGamepadMappingsManager *
+games_gamepad_mappings_manager_get_instance (void)
+{
+ if (instance == NULL)
+ instance = games_gamepad_mappings_manager_new ();
+
+ return g_object_ref (instance);
+}
+
+gchar *
+games_gamepad_mappings_manager_get_mapping (GamesGamepadMappingsManager *self,
+ const gchar *guid)
+{
+ const gchar *mapping;
+
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (guid != NULL, NULL);
+
+ mapping = g_hash_table_lookup (self->mappings, guid);
+
+ return g_strdup (mapping);
+}
+
+/* Type */
+
+static void
+finalize (GObject *object)
+{
+ GamesGamepadMappingsManager *self = GAMES_GAMEPAD_MAPPINGS_MANAGER (object);
+
+ g_hash_table_unref (self->names);
+ g_hash_table_unref (self->mappings);
+
+ G_OBJECT_CLASS (games_gamepad_mappings_manager_parent_class)->finalize (object);
+}
+
+static void
+games_gamepad_mappings_manager_class_init (GamesGamepadMappingsManagerClass *klass)
+{
+ games_gamepad_mappings_manager_parent_class = g_type_class_peek_parent (klass);
+ G_OBJECT_CLASS (klass)->finalize = finalize;
+}
+
+static void
+games_gamepad_mappings_manager_init (GamesGamepadMappingsManager *self)
+{
+}
diff --git a/src/gamepad/gamepad-mappings-manager.h b/src/gamepad/gamepad-mappings-manager.h
new file mode 100644
index 0000000..c15be3b
--- /dev/null
+++ b/src/gamepad/gamepad-mappings-manager.h
@@ -0,0 +1,19 @@
+#ifndef GAMES_GAMEPAD_MAPPINGS_MANAGER_H
+#define GAMES_GAMEPAD_MAPPINGS_MANAGER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GAMES_TYPE_GAMEPAD_MAPPINGS_MANAGER (games_gamepad_mappings_manager_get_type())
+
+G_DECLARE_FINAL_TYPE (GamesGamepadMappingsManager, games_gamepad_mappings_manager, GAMES,
GAMEPAD_MAPPINGS_MANAGER, GObject)
+
+GamesGamepadMappingsManager *games_gamepad_mappings_manager_get_instance (void);
+gchar *games_gamepad_mappings_manager_get_mapping (GamesGamepadMappingsManager *self,
+ const gchar *guid);
+
+G_END_DECLS
+
+#endif /* GAMES_GAMEPAD_MAPPINGS_MANAGER_H */
+
diff --git a/src/gamepad/gamepad-mappings-manager.vapi b/src/gamepad/gamepad-mappings-manager.vapi
new file mode 100644
index 0000000..3d0abce
--- /dev/null
+++ b/src/gamepad/gamepad-mappings-manager.vapi
@@ -0,0 +1,7 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+[CCode (cheader_filename = "gamepad-mapping-manager.h")]
+private class Games.GamepadMappingsManager : GLib.Object {
+ public static GamepadMappingsManager get_instance ();
+ public string? get_mapping (string guid);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]