/* gamepad-monitor.c generated by valac 0.35.5, the Vala compiler
 * generated from gamepad-monitor.vala, do not modify */

/* This file is part of GNOME Games. License: GPLv3*/

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.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;
typedef struct _GamesGamepadMonitorPrivate GamesGamepadMonitorPrivate;

#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 GAMES_TYPE_RAW_GAMEPAD_MONITOR (games_raw_gamepad_monitor_get_type ())
#define GAMES_RAW_GAMEPAD_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAMES_TYPE_RAW_GAMEPAD_MONITOR, GamesRawGamepadMonitor))
#define GAMES_IS_RAW_GAMEPAD_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAMES_TYPE_RAW_GAMEPAD_MONITOR))
#define GAMES_RAW_GAMEPAD_MONITOR_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GAMES_TYPE_RAW_GAMEPAD_MONITOR, GamesRawGamepadMonitorIface))

typedef struct _GamesRawGamepadMonitor GamesRawGamepadMonitor;
typedef struct _GamesRawGamepadMonitorIface GamesRawGamepadMonitorIface;

#define GAMES_TYPE_RAW_GAMEPAD (games_raw_gamepad_get_type ())
#define GAMES_RAW_GAMEPAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAMES_TYPE_RAW_GAMEPAD, GamesRawGamepad))
#define GAMES_IS_RAW_GAMEPAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAMES_TYPE_RAW_GAMEPAD))
#define GAMES_RAW_GAMEPAD_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GAMES_TYPE_RAW_GAMEPAD, GamesRawGamepadIface))

typedef struct _GamesRawGamepad GamesRawGamepad;
typedef struct _GamesRawGamepadIface GamesRawGamepadIface;
#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  {
	GAMES_GAMEPAD_MONITOR_GAMEPAD_PLUGGED_SIGNAL,
	GAMES_GAMEPAD_MONITOR_LAST_SIGNAL
};
static guint games_gamepad_monitor_signals[GAMES_GAMEPAD_MONITOR_LAST_SIGNAL] = {0};

struct _GamesGamepadMonitor {
	GObject parent_instance;
	GamesGamepadMonitorPrivate * priv;
};

struct _GamesGamepadMonitorClass {
	GObjectClass parent_class;
};

struct _GamesGamepadMonitorPrivate {
	GHashTable* gamepads;
};

struct _GamesRawGamepadIface {
	GTypeInterface parent_iface;
	const gchar* (*get_guid) (GamesRawGamepad* self);
};

typedef void (*GamesRawGamepadCallback) (GamesRawGamepad* raw_gamepad, void* user_data);
struct _GamesRawGamepadMonitorIface {
	GTypeInterface parent_iface;
	void (*foreach_gamepad) (GamesRawGamepadMonitor* self, GamesRawGamepadCallback callback, void* callback_target);
};

typedef void (*GamesGamepadCallback) (GamesGamepad* gamepad, void* user_data);
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* games_gamepad_monitor_instance;
static GamesGamepadMonitor* games_gamepad_monitor_instance = NULL;

GType games_gamepad_monitor_get_type (void) G_GNUC_CONST;
GType games_gamepad_get_type (void) G_GNUC_CONST;
#define GAMES_GAMEPAD_MONITOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GAMES_TYPE_GAMEPAD_MONITOR, GamesGamepadMonitorPrivate))
enum  {
	GAMES_GAMEPAD_MONITOR_DUMMY_PROPERTY
};
static GamesGamepadMonitor* games_gamepad_monitor_new (void);
static GamesGamepadMonitor* games_gamepad_monitor_construct (GType object_type);
static void _g_object_unref0_ (gpointer var);
GType games_linux_raw_gamepad_monitor_get_type (void) G_GNUC_CONST;
GamesLinuxRawGamepadMonitor* games_linux_raw_gamepad_monitor_get_instance (void);
GType games_raw_gamepad_get_type (void) G_GNUC_CONST;
GType games_raw_gamepad_monitor_get_type (void) G_GNUC_CONST;
static void games_gamepad_monitor_on_raw_gamepad_plugged (GamesGamepadMonitor* self, GamesRawGamepad* raw_gamepad);
static void _games_gamepad_monitor_on_raw_gamepad_plugged_games_raw_gamepad_monitor_gamepad_plugged (GamesRawGamepadMonitor* _sender, GamesRawGamepad* raw_gamepad, gpointer self);
void games_raw_gamepad_monitor_foreach_gamepad (GamesRawGamepadMonitor* self, GamesRawGamepadCallback callback, void* callback_target);
static void __lambda19_ (GamesGamepadMonitor* self, GamesRawGamepad* raw_gamepad);
static GamesGamepad* games_gamepad_monitor_add_gamepad (GamesGamepadMonitor* self, GamesRawGamepad* raw_gamepad);
static void ___lambda19__games_raw_gamepad_callback (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_remove_gamepad (GamesGamepadMonitor* self, GamesGamepad* gamepad);
static void _games_gamepad_monitor_remove_gamepad_games_gamepad_unplugged (GamesGamepad* _sender, gpointer self);
static void games_gamepad_monitor_finalize (GObject * obj);


static void _g_object_unref0_ (gpointer var) {
	(var == NULL) ? NULL : (var = (g_object_unref (var), NULL));
}


static void _games_gamepad_monitor_on_raw_gamepad_plugged_games_raw_gamepad_monitor_gamepad_plugged (GamesRawGamepadMonitor* _sender, GamesRawGamepad* raw_gamepad, gpointer self) {
	games_gamepad_monitor_on_raw_gamepad_plugged ((GamesGamepadMonitor*) self, raw_gamepad);
}


static void __lambda19_ (GamesGamepadMonitor* self, GamesRawGamepad* raw_gamepad) {
	GamesRawGamepad* _tmp0_;
	GamesGamepad* _tmp1_;
	GamesGamepad* _tmp2_;
	g_return_if_fail (raw_gamepad != NULL);
	_tmp0_ = raw_gamepad;
	_tmp1_ = games_gamepad_monitor_add_gamepad (self, _tmp0_);
	_tmp2_ = _tmp1_;
	_g_object_unref0 (_tmp2_);
}


static void ___lambda19__games_raw_gamepad_callback (GamesRawGamepad* raw_gamepad, gpointer self) {
	__lambda19_ ((GamesGamepadMonitor*) self, raw_gamepad);
}


static GamesGamepadMonitor* games_gamepad_monitor_construct (GType object_type) {
	GamesGamepadMonitor * self = NULL;
	GHashFunc _tmp0_;
	GEqualFunc _tmp1_;
	GHashTable* _tmp2_;
	GamesLinuxRawGamepadMonitor* raw_gamepad_monitor;
	GamesLinuxRawGamepadMonitor* _tmp3_;
	self = (GamesGamepadMonitor*) g_object_new (object_type, NULL);
	_tmp0_ = g_direct_hash;
	_tmp1_ = g_direct_equal;
	_tmp2_ = g_hash_table_new_full (_tmp0_, _tmp1_, NULL, _g_object_unref0_);
	_g_hash_table_unref0 (self->priv->gamepads);
	self->priv->gamepads = _tmp2_;
	_tmp3_ = games_linux_raw_gamepad_monitor_get_instance ();
	raw_gamepad_monitor = _tmp3_;
	g_signal_connect_object ((GamesRawGamepadMonitor*) raw_gamepad_monitor, "gamepad-plugged", (GCallback) _games_gamepad_monitor_on_raw_gamepad_plugged_games_raw_gamepad_monitor_gamepad_plugged, self, 0);
	games_raw_gamepad_monitor_foreach_gamepad ((GamesRawGamepadMonitor*) raw_gamepad_monitor, ___lambda19__games_raw_gamepad_callback, self);
	_g_object_unref0 (raw_gamepad_monitor);
	return self;
}


static GamesGamepadMonitor* games_gamepad_monitor_new (void) {
	return games_gamepad_monitor_construct (GAMES_TYPE_GAMEPAD_MONITOR);
}


static gpointer _g_object_ref0 (gpointer self) {
	return self ? g_object_ref (self) : NULL;
}


GamesGamepadMonitor* games_gamepad_monitor_get_instance (void) {
	GamesGamepadMonitor* result = NULL;
	GamesGamepadMonitor* _tmp0_;
	GamesGamepadMonitor* _tmp2_;
	GamesGamepadMonitor* _tmp3_;
	_tmp0_ = games_gamepad_monitor_instance;
	if (_tmp0_ == NULL) {
		GamesGamepadMonitor* _tmp1_;
		_tmp1_ = games_gamepad_monitor_new ();
		_g_object_unref0 (games_gamepad_monitor_instance);
		games_gamepad_monitor_instance = _tmp1_;
	}
	_tmp2_ = games_gamepad_monitor_instance;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	result = _tmp3_;
	return result;
}


static gconstpointer _vala_hash_set_next_value (GHashTableIter *self) {
	gconstpointer result = NULL;
	void* vi;
	GHashTableIter* htp;
	void* _tmp0_;
	gconstpointer value = NULL;
	gconstpointer _tmp1_ = NULL;
	gconstpointer _tmp2_ = NULL;
	gboolean _tmp3_;
	vi = &(*self);
	_tmp0_ = vi;
	htp = _tmp0_;
	_tmp3_ = g_hash_table_iter_next (htp, (gpointer*) (&_tmp2_), (gpointer*) NULL);
	value = _tmp2_;
	if (_tmp3_) {
		gconstpointer _tmp4_;
		_tmp4_ = value;
		_tmp1_ = _tmp4_;
	} else {
		_tmp1_ = NULL;
	}
	result = _tmp1_;
	return result;
}


void games_gamepad_monitor_foreach_gamepad (GamesGamepadMonitor* self, GamesGamepadCallback callback, void* callback_target) {
	g_return_if_fail (self != NULL);
	{
		GHashTableIter _gamepad_it;
		GHashTable* _tmp0_;
		GHashTableIter _tmp1_ = {0};
		GamesGamepad* gamepad = NULL;
		_tmp0_ = self->priv->gamepads;
		g_hash_table_iter_init (&_tmp1_, _tmp0_);
		_gamepad_it = _tmp1_;
		while (TRUE) {
			gconstpointer _tmp2_;
			GamesGamepad* _tmp3_;
			GamesGamepadCallback _tmp4_;
			void* _tmp4__target;
			GamesGamepad* _tmp5_;
			_tmp2_ = _vala_hash_set_next_value (&_gamepad_it);
			gamepad = (GamesGamepad*) _tmp2_;
			_tmp3_ = gamepad;
			if (!(_tmp3_ != NULL)) {
				break;
			}
			_tmp4_ = callback;
			_tmp4__target = callback_target;
			_tmp5_ = gamepad;
			_tmp4_ (_tmp5_, _tmp4__target);
		}
	}
}


static void _games_gamepad_monitor_remove_gamepad_games_gamepad_unplugged (GamesGamepad* _sender, gpointer self) {
	games_gamepad_monitor_remove_gamepad ((GamesGamepadMonitor*) self, _sender);
}


static GamesGamepad* games_gamepad_monitor_add_gamepad (GamesGamepadMonitor* self, GamesRawGamepad* raw_gamepad) {
	GamesGamepad* result = NULL;
	GamesGamepad* gamepad = NULL;
	GHashTable* _tmp4_;
	GamesGamepad* _tmp5_;
	GamesGamepad* _tmp6_;
	GamesGamepad* _tmp7_;
	GError * _inner_error_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (raw_gamepad != NULL, NULL);
	{
		GamesGamepad* _tmp0_;
		GamesRawGamepad* _tmp1_;
		GamesGamepad* _tmp2_;
		GamesGamepad* _tmp3_;
		_tmp1_ = raw_gamepad;
		_tmp2_ = games_gamepad_new (_tmp1_, &_inner_error_);
		_tmp0_ = _tmp2_;
		if (G_UNLIKELY (_inner_error_ != NULL)) {
			if (_inner_error_->domain == GAMES_GAMEPAD_MAPPING_ERROR) {
				goto __catch7_games_gamepad_mapping_error;
			}
			_g_object_unref0 (gamepad);
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
			g_clear_error (&_inner_error_);
			return NULL;
		}
		_tmp3_ = _tmp0_;
		_tmp0_ = NULL;
		_g_object_unref0 (gamepad);
		gamepad = _tmp3_;
		_g_object_unref0 (_tmp0_);
	}
	goto __finally7;
	__catch7_games_gamepad_mapping_error:
	{
		GError* e = NULL;
		e = _inner_error_;
		_inner_error_ = NULL;
		result = NULL;
		_g_error_free0 (e);
		_g_object_unref0 (gamepad);
		return result;
	}
	__finally7:
	if (G_UNLIKELY (_inner_error_ != NULL)) {
		_g_object_unref0 (gamepad);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
		g_clear_error (&_inner_error_);
		return NULL;
	}
	_tmp4_ = self->priv->gamepads;
	_tmp5_ = gamepad;
	_tmp6_ = _g_object_ref0 (_tmp5_);
	g_hash_table_add (_tmp4_, _tmp6_);
	_tmp7_ = gamepad;
	g_signal_connect_object (_tmp7_, "unplugged", (GCallback) _games_gamepad_monitor_remove_gamepad_games_gamepad_unplugged, self, 0);
	result = gamepad;
	return result;
}


static void games_gamepad_monitor_on_raw_gamepad_plugged (GamesGamepadMonitor* self, GamesRawGamepad* raw_gamepad) {
	GamesGamepad* gamepad;
	GamesRawGamepad* _tmp0_;
	GamesGamepad* _tmp1_;
	GamesGamepad* _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (raw_gamepad != NULL);
	_tmp0_ = raw_gamepad;
	_tmp1_ = games_gamepad_monitor_add_gamepad (self, _tmp0_);
	gamepad = _tmp1_;
	_tmp2_ = gamepad;
	if (_tmp2_ != NULL) {
		GamesGamepad* _tmp3_;
		_tmp3_ = gamepad;
		g_signal_emit (self, games_gamepad_monitor_signals[GAMES_GAMEPAD_MONITOR_GAMEPAD_PLUGGED_SIGNAL], 0, _tmp3_);
	}
	_g_object_unref0 (gamepad);
}


static void games_gamepad_monitor_remove_gamepad (GamesGamepadMonitor* self, GamesGamepad* gamepad) {
	GHashTable* _tmp0_;
	GamesGamepad* _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (gamepad != NULL);
	_tmp0_ = self->priv->gamepads;
	_tmp1_ = gamepad;
	g_hash_table_remove (_tmp0_, _tmp1_);
}


static void games_gamepad_monitor_class_init (GamesGamepadMonitorClass * klass) {
	games_gamepad_monitor_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (GamesGamepadMonitorPrivate));
	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
	 */
	games_gamepad_monitor_signals[GAMES_GAMEPAD_MONITOR_GAMEPAD_PLUGGED_SIGNAL] = 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_instance_init (GamesGamepadMonitor * self) {
	self->priv = GAMES_GAMEPAD_MONITOR_GET_PRIVATE (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->priv->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) games_gamepad_monitor_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;
}



