/* input.c generated by valac 0.36.1.17-97a62, the Vala compiler
 * generated from input.vala, do not modify */

/* This file is part of retro-gtk. License: GPL-3.0+.*/

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gdk/gdk.h>


#define RETRO_TYPE_INPUT (retro_input_get_type ())
#define RETRO_INPUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RETRO_TYPE_INPUT, RetroInput))
#define RETRO_IS_INPUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RETRO_TYPE_INPUT))
#define RETRO_INPUT_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), RETRO_TYPE_INPUT, RetroInputIface))

typedef struct _RetroInput RetroInput;
typedef struct _RetroInputIface RetroInputIface;

#define RETRO_TYPE_DEVICE_TYPE (retro_device_type_get_type ())

#define RETRO_TYPE_INPUT_DESCRIPTOR (retro_input_descriptor_get_type ())
typedef struct _RetroInputDescriptor RetroInputDescriptor;

#define RETRO_TYPE_INPUT_DEVICE (retro_input_device_get_type ())
#define RETRO_INPUT_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RETRO_TYPE_INPUT_DEVICE, RetroInputDevice))
#define RETRO_IS_INPUT_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RETRO_TYPE_INPUT_DEVICE))
#define RETRO_INPUT_DEVICE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), RETRO_TYPE_INPUT_DEVICE, RetroInputDeviceIface))

typedef struct _RetroInputDevice RetroInputDevice;
typedef struct _RetroInputDeviceIface RetroInputDeviceIface;
enum  {
	RETRO_INPUT_CONTROLLER_CONNECTED_SIGNAL,
	RETRO_INPUT_CONTROLLER_DISCONNECTED_SIGNAL,
	RETRO_INPUT_KEY_EVENT_SIGNAL,
	RETRO_INPUT_LAST_SIGNAL
};
static guint retro_input_signals[RETRO_INPUT_LAST_SIGNAL] = {0};

typedef enum  {
	RETRO_DEVICE_TYPE_TYPE_MASK = 0xff,
	RETRO_DEVICE_TYPE_NONE = 0,
	RETRO_DEVICE_TYPE_JOYPAD = 1,
	RETRO_DEVICE_TYPE_MOUSE = 2,
	RETRO_DEVICE_TYPE_KEYBOARD = 3,
	RETRO_DEVICE_TYPE_LIGHTGUN = 4,
	RETRO_DEVICE_TYPE_ANALOG = 5,
	RETRO_DEVICE_TYPE_POINTER = 6
} RetroDeviceType;

struct _RetroInputDescriptor {
	guint port;
	RetroDeviceType device;
	guint index;
	guint id;
	gchar* description;
};

struct _RetroInputDeviceIface {
	GTypeInterface parent_iface;
	void (*poll) (RetroInputDevice* self);
	gint16 (*get_input_state) (RetroInputDevice* self, RetroDeviceType device, guint index, guint id);
	RetroDeviceType (*get_device_type) (RetroInputDevice* self);
	guint64 (*get_device_capabilities) (RetroInputDevice* self);
};

typedef void (*RetroInputControllerCallback) (guint port, RetroInputDevice* device, void* user_data);
struct _RetroInputIface {
	GTypeInterface parent_iface;
	void (*poll) (RetroInput* self);
	gint16 (*get_state) (RetroInput* self, guint port, RetroDeviceType device, guint index, guint id);
	void (*set_descriptors) (RetroInput* self, RetroInputDescriptor* input_descriptors, int input_descriptors_length1);
	guint64 (*get_device_capabilities) (RetroInput* self);
	void (*foreach_controller) (RetroInput* self, RetroInputControllerCallback callback, void* callback_target);
};



GType retro_device_type_get_type (void) G_GNUC_CONST;
GType retro_input_descriptor_get_type (void) G_GNUC_CONST;
RetroInputDescriptor* retro_input_descriptor_dup (const RetroInputDescriptor* self);
void retro_input_descriptor_free (RetroInputDescriptor* self);
void retro_input_descriptor_copy (const RetroInputDescriptor* self, RetroInputDescriptor* dest);
void retro_input_descriptor_destroy (RetroInputDescriptor* self);
GType retro_input_device_get_type (void) G_GNUC_CONST;
GType retro_input_get_type (void) G_GNUC_CONST;
void retro_input_poll (RetroInput* self);
gint16 retro_input_get_state (RetroInput* self, guint port, RetroDeviceType device, guint index, guint id);
void retro_input_set_descriptors (RetroInput* self, RetroInputDescriptor* input_descriptors, int input_descriptors_length1);
guint64 retro_input_get_device_capabilities (RetroInput* self);
void retro_input_foreach_controller (RetroInput* self, RetroInputControllerCallback callback, void* callback_target);
static void g_cclosure_user_marshal_VOID__UINT_OBJECT (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data);
static void g_cclosure_user_marshal_BOOLEAN__BOXED (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data);


/**
 * Asks the frontend to poll inputs.
 */
void retro_input_poll (RetroInput* self) {
	g_return_if_fail (self != NULL);
	RETRO_INPUT_GET_INTERFACE (self)->poll (self);
}


/**
 * Gets the state of a specific input.
 *
 * @param port the port of the controller to check the input state from
 * @param device the type of the device to check the input state from
 * @param index the index of given input (left or right stick)
 * @param id the specific input to get (button or axis)
 * @return the value of the given state
 */
gint16 retro_input_get_state (RetroInput* self, guint port, RetroDeviceType device, guint index, guint id) {
	g_return_val_if_fail (self != NULL, 0);
	return RETRO_INPUT_GET_INTERFACE (self)->get_state (self, port, device, index, id);
}


/**
 * Sets how the {@link core} handles the inputs in a human-readable way.
 *
 * @param input_descriptors the descriptors of the inputs used by the
 * {@link core}
 */
void retro_input_set_descriptors (RetroInput* self, RetroInputDescriptor* input_descriptors, int input_descriptors_length1) {
	g_return_if_fail (self != NULL);
	RETRO_INPUT_GET_INTERFACE (self)->set_descriptors (self, input_descriptors, input_descriptors_length1);
}


/**
 * Gets the flags of the devices implemented by the frontend.
 *
 * @return flags of the devices implemented by the frontend
 */
guint64 retro_input_get_device_capabilities (RetroInput* self) {
	g_return_val_if_fail (self != NULL, 0ULL);
	return RETRO_INPUT_GET_INTERFACE (self)->get_device_capabilities (self);
}


void retro_input_foreach_controller (RetroInput* self, RetroInputControllerCallback callback, void* callback_target) {
	g_return_if_fail (self != NULL);
	RETRO_INPUT_GET_INTERFACE (self)->foreach_controller (self, callback, callback_target);
}


static void g_cclosure_user_marshal_VOID__UINT_OBJECT (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) {
	typedef void (*GMarshalFunc_VOID__UINT_OBJECT) (gpointer data1, guint arg_1, gpointer arg_2, gpointer data2);
	register GMarshalFunc_VOID__UINT_OBJECT callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__UINT_OBJECT) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_uint (param_values + 1), g_value_get_object (param_values + 2), data2);
}


static void g_cclosure_user_marshal_BOOLEAN__BOXED (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) {
	typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED) (gpointer data1, gpointer arg_1, gpointer data2);
	register GMarshalFunc_BOOLEAN__BOXED callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	gboolean v_return;
	cc = (GCClosure *) closure;
	g_return_if_fail (return_value != NULL);
	g_return_if_fail (n_param_values == 2);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_BOOLEAN__BOXED) (marshal_data ? marshal_data : cc->callback);
	v_return = callback (data1, g_value_get_boxed (param_values + 1), data2);
	g_value_set_boolean (return_value, v_return);
}


static void retro_input_base_init (RetroInputIface * iface) {
	static gboolean initialized = FALSE;
	if (!initialized) {
		initialized = TRUE;
		retro_input_signals[RETRO_INPUT_CONTROLLER_CONNECTED_SIGNAL] = g_signal_new ("controller_connected", RETRO_TYPE_INPUT, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__UINT_OBJECT, G_TYPE_NONE, 2, G_TYPE_UINT, RETRO_TYPE_INPUT_DEVICE);
		retro_input_signals[RETRO_INPUT_CONTROLLER_DISCONNECTED_SIGNAL] = g_signal_new ("controller_disconnected", RETRO_TYPE_INPUT, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
		retro_input_signals[RETRO_INPUT_KEY_EVENT_SIGNAL] = g_signal_new ("key_event", RETRO_TYPE_INPUT, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_BOOLEAN__BOXED, G_TYPE_BOOLEAN, 1, gdk_event_get_type ());
	}
}


/**
 * An interface to render a {@link Core}'s inputs.
 */
GType retro_input_get_type (void) {
	static volatile gsize retro_input_type_id__volatile = 0;
	if (g_once_init_enter (&retro_input_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (RetroInputIface), (GBaseInitFunc) retro_input_base_init, (GBaseFinalizeFunc) NULL, (GClassInitFunc) NULL, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
		GType retro_input_type_id;
		retro_input_type_id = g_type_register_static (G_TYPE_INTERFACE, "RetroInput", &g_define_type_info, 0);
		g_type_interface_add_prerequisite (retro_input_type_id, G_TYPE_OBJECT);
		g_once_init_leave (&retro_input_type_id__volatile, retro_input_type_id);
	}
	return retro_input_type_id__volatile;
}



