/* key-event-filter.c generated by valac 0.56.19, the Vala compiler
 * generated from key-event-filter.vala, do not modify */

/*
 * Copyright (C) 2011-2014 Daiki Ueno <ueno@gnu.org>
 * Copyright (C) 2011-2014 Red Hat, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "libkkc/libkkc.h"
#include <glib.h>
#include <glib-object.h>

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

enum  {
	KKC_KEY_EVENT_FILTER_0_PROPERTY,
	KKC_KEY_EVENT_FILTER_NUM_PROPERTIES
};
static GParamSpec* kkc_key_event_filter_properties[KKC_KEY_EVENT_FILTER_NUM_PROPERTIES];
enum  {
	KKC_KEY_EVENT_FILTER_FORWARDED_SIGNAL,
	KKC_KEY_EVENT_FILTER_NUM_SIGNALS
};
static guint kkc_key_event_filter_signals[KKC_KEY_EVENT_FILTER_NUM_SIGNALS] = {0};

#define KKC_TYPE_SIMPLE_KEY_EVENT_FILTER (kkc_simple_key_event_filter_get_type ())
#define KKC_SIMPLE_KEY_EVENT_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_SIMPLE_KEY_EVENT_FILTER, KkcSimpleKeyEventFilter))
#define KKC_SIMPLE_KEY_EVENT_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_SIMPLE_KEY_EVENT_FILTER, KkcSimpleKeyEventFilterClass))
#define KKC_IS_SIMPLE_KEY_EVENT_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_SIMPLE_KEY_EVENT_FILTER))
#define KKC_IS_SIMPLE_KEY_EVENT_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_SIMPLE_KEY_EVENT_FILTER))
#define KKC_SIMPLE_KEY_EVENT_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_SIMPLE_KEY_EVENT_FILTER, KkcSimpleKeyEventFilterClass))

typedef struct _KkcSimpleKeyEventFilter KkcSimpleKeyEventFilter;
typedef struct _KkcSimpleKeyEventFilterClass KkcSimpleKeyEventFilterClass;
typedef struct _KkcSimpleKeyEventFilterPrivate KkcSimpleKeyEventFilterPrivate;
enum  {
	KKC_SIMPLE_KEY_EVENT_FILTER_0_PROPERTY,
	KKC_SIMPLE_KEY_EVENT_FILTER_NUM_PROPERTIES
};
static GParamSpec* kkc_simple_key_event_filter_properties[KKC_SIMPLE_KEY_EVENT_FILTER_NUM_PROPERTIES];

#define KKC_TYPE_KANA_KEY_EVENT_FILTER (kkc_kana_key_event_filter_get_type ())
#define KKC_KANA_KEY_EVENT_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_KANA_KEY_EVENT_FILTER, KkcKanaKeyEventFilter))
#define KKC_KANA_KEY_EVENT_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_KANA_KEY_EVENT_FILTER, KkcKanaKeyEventFilterClass))
#define KKC_IS_KANA_KEY_EVENT_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_KANA_KEY_EVENT_FILTER))
#define KKC_IS_KANA_KEY_EVENT_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_KANA_KEY_EVENT_FILTER))
#define KKC_KANA_KEY_EVENT_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_KANA_KEY_EVENT_FILTER, KkcKanaKeyEventFilterClass))

typedef struct _KkcKanaKeyEventFilter KkcKanaKeyEventFilter;
typedef struct _KkcKanaKeyEventFilterClass KkcKanaKeyEventFilterClass;
typedef struct _KkcKanaKeyEventFilterPrivate KkcKanaKeyEventFilterPrivate;
enum  {
	KKC_KANA_KEY_EVENT_FILTER_0_PROPERTY,
	KKC_KANA_KEY_EVENT_FILTER_NUM_PROPERTIES
};
static GParamSpec* kkc_kana_key_event_filter_properties[KKC_KANA_KEY_EVENT_FILTER_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

struct _KkcSimpleKeyEventFilter {
	KkcKeyEventFilter parent_instance;
	KkcSimpleKeyEventFilterPrivate * priv;
};

struct _KkcSimpleKeyEventFilterClass {
	KkcKeyEventFilterClass parent_class;
};

struct _KkcKanaKeyEventFilter {
	KkcSimpleKeyEventFilter parent_instance;
	KkcKanaKeyEventFilterPrivate * priv;
};

struct _KkcKanaKeyEventFilterClass {
	KkcSimpleKeyEventFilterClass parent_class;
};

static gpointer kkc_key_event_filter_parent_class = NULL;
static gpointer kkc_simple_key_event_filter_parent_class = NULL;
static gpointer kkc_kana_key_event_filter_parent_class = NULL;

static KkcKeyEvent* kkc_key_event_filter_real_filter_key_event (KkcKeyEventFilter* self,
                                                         KkcKeyEvent* key);
static void kkc_key_event_filter_real_reset (KkcKeyEventFilter* self);
static GType kkc_key_event_filter_get_type_once (void);
VALA_EXTERN GType kkc_simple_key_event_filter_get_type (void) G_GNUC_CONST ;
static KkcKeyEvent* kkc_simple_key_event_filter_real_filter_key_event (KkcKeyEventFilter* base,
                                                                KkcKeyEvent* key);
static gboolean _vala_uint_array_contains (guint * stack,
                                    gssize stack_length,
                                    const guint needle);
VALA_EXTERN KkcSimpleKeyEventFilter* kkc_simple_key_event_filter_new (void);
VALA_EXTERN KkcSimpleKeyEventFilter* kkc_simple_key_event_filter_construct (GType object_type);
static GType kkc_simple_key_event_filter_get_type_once (void);
VALA_EXTERN GType kkc_kana_key_event_filter_get_type (void) G_GNUC_CONST ;
static KkcKeyEvent* kkc_kana_key_event_filter_real_filter_key_event (KkcKeyEventFilter* base,
                                                              KkcKeyEvent* key);
VALA_EXTERN KkcKanaKeyEventFilter* kkc_kana_key_event_filter_new (void);
VALA_EXTERN KkcKanaKeyEventFilter* kkc_kana_key_event_filter_construct (GType object_type);
static GType kkc_kana_key_event_filter_get_type_once (void);

static const guint KKC_SIMPLE_KEY_EVENT_FILTER_modifier_keyvals[12] = {KKC_KEYSYMS_Shift_L, KKC_KEYSYMS_Shift_R, KKC_KEYSYMS_Control_L, KKC_KEYSYMS_Control_R, KKC_KEYSYMS_Meta_L, KKC_KEYSYMS_Meta_R, KKC_KEYSYMS_Alt_L, KKC_KEYSYMS_Alt_R, KKC_KEYSYMS_Super_L, KKC_KEYSYMS_Super_R, KKC_KEYSYMS_Hyper_L, KKC_KEYSYMS_Hyper_R};

/**
         * Convert a key event to another.
         *
         * @param key a key event
         *
         * @return a KeyEvent or `null` if the result cannot be
         * fetched immediately
         */
static KkcKeyEvent*
kkc_key_event_filter_real_filter_key_event (KkcKeyEventFilter* self,
                                            KkcKeyEvent* key)
{
	g_critical ("Type `%s' does not implement abstract method `kkc_key_event_filter_filter_key_event'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return NULL;
}

KkcKeyEvent*
kkc_key_event_filter_filter_key_event (KkcKeyEventFilter* self,
                                       KkcKeyEvent* key)
{
	KkcKeyEventFilterClass* _klass_;
	g_return_val_if_fail (self != NULL, NULL);
	_klass_ = KKC_KEY_EVENT_FILTER_GET_CLASS (self);
	if (_klass_->filter_key_event) {
		return _klass_->filter_key_event (self, key);
	}
	return NULL;
}

/**
         * Reset the filter.
         */
static void
kkc_key_event_filter_real_reset (KkcKeyEventFilter* self)
{
}

void
kkc_key_event_filter_reset (KkcKeyEventFilter* self)
{
	KkcKeyEventFilterClass* _klass_;
	g_return_if_fail (self != NULL);
	_klass_ = KKC_KEY_EVENT_FILTER_GET_CLASS (self);
	if (_klass_->reset) {
		_klass_->reset (self);
	}
}

KkcKeyEventFilter*
kkc_key_event_filter_construct (GType object_type)
{
	KkcKeyEventFilter * self = NULL;
	self = (KkcKeyEventFilter*) g_object_new (object_type, NULL);
	return self;
}

static void
kkc_key_event_filter_class_init (KkcKeyEventFilterClass * klass,
                                 gpointer klass_data)
{
	kkc_key_event_filter_parent_class = g_type_class_peek_parent (klass);
	((KkcKeyEventFilterClass *) klass)->filter_key_event = (KkcKeyEvent* (*) (KkcKeyEventFilter*, KkcKeyEvent*)) kkc_key_event_filter_real_filter_key_event;
	((KkcKeyEventFilterClass *) klass)->reset = (void (*) (KkcKeyEventFilter*)) kkc_key_event_filter_real_reset;
	/**
	         * Signal emitted when a new key event is generated in the filter.
	         *
	         * @param key a key event
	         */
	kkc_key_event_filter_signals[KKC_KEY_EVENT_FILTER_FORWARDED_SIGNAL] = g_signal_new ("forwarded", KKC_TYPE_KEY_EVENT_FILTER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, KKC_TYPE_KEY_EVENT);
}

static void
kkc_key_event_filter_instance_init (KkcKeyEventFilter * self,
                                    gpointer klass)
{
}

/**
     * Base class of a key event filter.
     */
static GType
kkc_key_event_filter_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (KkcKeyEventFilterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_key_event_filter_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcKeyEventFilter), 0, (GInstanceInitFunc) kkc_key_event_filter_instance_init, NULL };
	GType kkc_key_event_filter_type_id;
	kkc_key_event_filter_type_id = g_type_register_static (G_TYPE_OBJECT, "KkcKeyEventFilter", &g_define_type_info, G_TYPE_FLAG_ABSTRACT);
	return kkc_key_event_filter_type_id;
}

GType
kkc_key_event_filter_get_type (void)
{
	static volatile gsize kkc_key_event_filter_type_id__once = 0;
	if (g_once_init_enter (&kkc_key_event_filter_type_id__once)) {
		GType kkc_key_event_filter_type_id;
		kkc_key_event_filter_type_id = kkc_key_event_filter_get_type_once ();
		g_once_init_leave (&kkc_key_event_filter_type_id__once, kkc_key_event_filter_type_id);
	}
	return kkc_key_event_filter_type_id__once;
}

/**
         * {@inheritDoc}
         */
static gboolean
_vala_uint_array_contains (guint * stack,
                           gssize stack_length,
                           const guint needle)
{
	gssize i;
	for (i = 0; i < stack_length; i++) {
		if (needle == stack[i]) {
			return TRUE;
		}
	}
	return FALSE;
}

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

static KkcKeyEvent*
kkc_simple_key_event_filter_real_filter_key_event (KkcKeyEventFilter* base,
                                                   KkcKeyEvent* key)
{
	KkcSimpleKeyEventFilter * self;
	guint _tmp0_;
	guint _tmp1_;
	KkcModifierType _tmp2_;
	KkcModifierType _tmp3_;
	KkcKeyEvent* _tmp4_;
	KkcKeyEvent* result;
	self = (KkcSimpleKeyEventFilter*) base;
	g_return_val_if_fail (key != NULL, NULL);
	_tmp0_ = kkc_key_event_get_keyval (key);
	_tmp1_ = _tmp0_;
	if (_vala_uint_array_contains (KKC_SIMPLE_KEY_EVENT_FILTER_modifier_keyvals, G_N_ELEMENTS (KKC_SIMPLE_KEY_EVENT_FILTER_modifier_keyvals), _tmp1_)) {
		result = NULL;
		return result;
	}
	_tmp2_ = kkc_key_event_get_modifiers (key);
	_tmp3_ = _tmp2_;
	if ((_tmp3_ & KKC_MODIFIER_TYPE_RELEASE_MASK) != 0) {
		result = NULL;
		return result;
	}
	_tmp4_ = _g_object_ref0 (key);
	result = _tmp4_;
	return result;
}

KkcSimpleKeyEventFilter*
kkc_simple_key_event_filter_construct (GType object_type)
{
	KkcSimpleKeyEventFilter * self = NULL;
	self = (KkcSimpleKeyEventFilter*) kkc_key_event_filter_construct (object_type);
	return self;
}

KkcSimpleKeyEventFilter*
kkc_simple_key_event_filter_new (void)
{
	return kkc_simple_key_event_filter_construct (KKC_TYPE_SIMPLE_KEY_EVENT_FILTER);
}

static void
kkc_simple_key_event_filter_class_init (KkcSimpleKeyEventFilterClass * klass,
                                        gpointer klass_data)
{
	kkc_simple_key_event_filter_parent_class = g_type_class_peek_parent (klass);
	((KkcKeyEventFilterClass *) klass)->filter_key_event = (KkcKeyEvent* (*) (KkcKeyEventFilter*, KkcKeyEvent*)) kkc_simple_key_event_filter_real_filter_key_event;
}

static void
kkc_simple_key_event_filter_instance_init (KkcSimpleKeyEventFilter * self,
                                           gpointer klass)
{
}

/**
     * Simple implementation of a key event filter.
     *
     * This class is rarely used in programs but specified as "filter"
     * property in rule metadata.
     *
     * @see Rule
     */
static GType
kkc_simple_key_event_filter_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (KkcSimpleKeyEventFilterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_simple_key_event_filter_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcSimpleKeyEventFilter), 0, (GInstanceInitFunc) kkc_simple_key_event_filter_instance_init, NULL };
	GType kkc_simple_key_event_filter_type_id;
	kkc_simple_key_event_filter_type_id = g_type_register_static (KKC_TYPE_KEY_EVENT_FILTER, "KkcSimpleKeyEventFilter", &g_define_type_info, 0);
	return kkc_simple_key_event_filter_type_id;
}

GType
kkc_simple_key_event_filter_get_type (void)
{
	static volatile gsize kkc_simple_key_event_filter_type_id__once = 0;
	if (g_once_init_enter (&kkc_simple_key_event_filter_type_id__once)) {
		GType kkc_simple_key_event_filter_type_id;
		kkc_simple_key_event_filter_type_id = kkc_simple_key_event_filter_get_type_once ();
		g_once_init_leave (&kkc_simple_key_event_filter_type_id__once, kkc_simple_key_event_filter_type_id);
	}
	return kkc_simple_key_event_filter_type_id__once;
}

/**
         * {@inheritDoc}
         */
static KkcKeyEvent*
kkc_kana_key_event_filter_real_filter_key_event (KkcKeyEventFilter* base,
                                                 KkcKeyEvent* key)
{
	KkcKanaKeyEventFilter * self;
	KkcKeyEvent* _key = NULL;
	KkcKeyEvent* _tmp0_;
	KkcKeyEvent* _tmp1_;
	gboolean _tmp2_ = FALSE;
	KkcKeyEvent* _tmp3_;
	guint _tmp4_;
	guint _tmp5_;
	KkcKeyEvent* result;
	self = (KkcKanaKeyEventFilter*) base;
	g_return_val_if_fail (key != NULL, NULL);
	_tmp0_ = KKC_KEY_EVENT_FILTER_CLASS (kkc_kana_key_event_filter_parent_class)->filter_key_event ((KkcKeyEventFilter*) G_TYPE_CHECK_INSTANCE_CAST (self, KKC_TYPE_SIMPLE_KEY_EVENT_FILTER, KkcSimpleKeyEventFilter), key);
	_key = _tmp0_;
	_tmp1_ = _key;
	if (_tmp1_ == NULL) {
		result = NULL;
		_g_object_unref0 (_key);
		return result;
	}
	_tmp3_ = _key;
	_tmp4_ = kkc_key_event_get_keyval (_tmp3_);
	_tmp5_ = _tmp4_;
	if (_tmp5_ == KKC_KEYSYMS_backslash) {
		KkcKeyEvent* _tmp6_;
		guint _tmp7_;
		guint _tmp8_;
		_tmp6_ = _key;
		_tmp7_ = kkc_key_event_get_keycode (_tmp6_);
		_tmp8_ = _tmp7_;
		_tmp2_ = _tmp8_ == ((guint) 124);
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		KkcKeyEvent* _tmp9_;
		guint _tmp10_;
		guint _tmp11_;
		KkcKeyEvent* _tmp12_;
		KkcModifierType _tmp13_;
		KkcModifierType _tmp14_;
		KkcKeyEvent* _tmp15_;
		_tmp9_ = _key;
		_tmp10_ = kkc_key_event_get_keycode (_tmp9_);
		_tmp11_ = _tmp10_;
		_tmp12_ = _key;
		_tmp13_ = kkc_key_event_get_modifiers (_tmp12_);
		_tmp14_ = _tmp13_;
		_tmp15_ = kkc_key_event_new_from_x_event (KKC_KEYSYMS_yen, _tmp11_, _tmp14_);
		result = _tmp15_;
		_g_object_unref0 (_key);
		return result;
	}
	result = _key;
	return result;
}

KkcKanaKeyEventFilter*
kkc_kana_key_event_filter_construct (GType object_type)
{
	KkcKanaKeyEventFilter * self = NULL;
	self = (KkcKanaKeyEventFilter*) kkc_simple_key_event_filter_construct (object_type);
	return self;
}

KkcKanaKeyEventFilter*
kkc_kana_key_event_filter_new (void)
{
	return kkc_kana_key_event_filter_construct (KKC_TYPE_KANA_KEY_EVENT_FILTER);
}

static void
kkc_kana_key_event_filter_class_init (KkcKanaKeyEventFilterClass * klass,
                                      gpointer klass_data)
{
	kkc_kana_key_event_filter_parent_class = g_type_class_peek_parent (klass);
	((KkcKeyEventFilterClass *) klass)->filter_key_event = (KkcKeyEvent* (*) (KkcKeyEventFilter*, KkcKeyEvent*)) kkc_kana_key_event_filter_real_filter_key_event;
}

static void
kkc_kana_key_event_filter_instance_init (KkcKanaKeyEventFilter * self,
                                         gpointer klass)
{
}

/**
     * Key event filter for Kana typing rule.
     *
     * This class is rarely used in programs but specified as "filter"
     * property in rule metadata.
     *
     * @see Rule
     */
static GType
kkc_kana_key_event_filter_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (KkcKanaKeyEventFilterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_kana_key_event_filter_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcKanaKeyEventFilter), 0, (GInstanceInitFunc) kkc_kana_key_event_filter_instance_init, NULL };
	GType kkc_kana_key_event_filter_type_id;
	kkc_kana_key_event_filter_type_id = g_type_register_static (KKC_TYPE_SIMPLE_KEY_EVENT_FILTER, "KkcKanaKeyEventFilter", &g_define_type_info, 0);
	return kkc_kana_key_event_filter_type_id;
}

GType
kkc_kana_key_event_filter_get_type (void)
{
	static volatile gsize kkc_kana_key_event_filter_type_id__once = 0;
	if (g_once_init_enter (&kkc_kana_key_event_filter_type_id__once)) {
		GType kkc_kana_key_event_filter_type_id;
		kkc_kana_key_event_filter_type_id = kkc_kana_key_event_filter_get_type_once ();
		g_once_init_leave (&kkc_kana_key_event_filter_type_id__once, kkc_kana_key_event_filter_type_id);
	}
	return kkc_kana_key_event_filter_type_id__once;
}

