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

/*
 * Copyright (C) 2011-2012 Daiki Ueno <ueno@unixuser.org>
 * Copyright (C) 2011-2012 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 <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gee.h>


#define SKK_TYPE_MODIFIER_TYPE (skk_modifier_type_get_type ())

#define SKK_TYPE_KEY_EVENT (skk_key_event_get_type ())
#define SKK_KEY_EVENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SKK_TYPE_KEY_EVENT, SkkKeyEvent))
#define SKK_KEY_EVENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SKK_TYPE_KEY_EVENT, SkkKeyEventClass))
#define SKK_IS_KEY_EVENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SKK_TYPE_KEY_EVENT))
#define SKK_IS_KEY_EVENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SKK_TYPE_KEY_EVENT))
#define SKK_KEY_EVENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SKK_TYPE_KEY_EVENT, SkkKeyEventClass))

typedef struct _SkkKeyEvent SkkKeyEvent;
typedef struct _SkkKeyEventClass SkkKeyEventClass;
typedef struct _SkkKeyEventPrivate SkkKeyEventPrivate;
#define _g_free0(var) (var = (g_free (var), NULL))

#define SKK_KEY_EVENT_TYPE_CODE_KEYVAL_ENTRY (skk_key_event_code_keyval_entry_get_type ())
typedef struct _SkkKeyEventCodeKeyvalEntry SkkKeyEventCodeKeyvalEntry;

#define SKK_KEY_EVENT_TYPE_NAME_KEYVAL_ENTRY (skk_key_event_name_keyval_entry_get_type ())
typedef struct _SkkKeyEventNameKeyvalEntry SkkKeyEventNameKeyvalEntry;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

typedef enum  {
	SKK_KEY_EVENT_FORMAT_ERROR_PARSE_FAILED,
	SKK_KEY_EVENT_FORMAT_ERROR_KEYSYM_NOT_FOUND
} SkkKeyEventFormatError;
#define SKK_KEY_EVENT_FORMAT_ERROR skk_key_event_format_error_quark ()
typedef enum  {
	SKK_MODIFIER_TYPE_NONE = 0,
	SKK_MODIFIER_TYPE_SHIFT_MASK = 1 << 0,
	SKK_MODIFIER_TYPE_LOCK_MASK = 1 << 1,
	SKK_MODIFIER_TYPE_CONTROL_MASK = 1 << 2,
	SKK_MODIFIER_TYPE_MOD1_MASK = 1 << 3,
	SKK_MODIFIER_TYPE_MOD2_MASK = 1 << 4,
	SKK_MODIFIER_TYPE_MOD3_MASK = 1 << 5,
	SKK_MODIFIER_TYPE_MOD4_MASK = 1 << 6,
	SKK_MODIFIER_TYPE_MOD5_MASK = 1 << 7,
	SKK_MODIFIER_TYPE_LSHIFT_MASK = 1 << 22,
	SKK_MODIFIER_TYPE_RSHIFT_MASK = 1 << 23,
	SKK_MODIFIER_TYPE_USLEEP_MASK = 1 << 24,
	SKK_MODIFIER_TYPE_SUPER_MASK = 1 << 26,
	SKK_MODIFIER_TYPE_HYPER_MASK = 1 << 27,
	SKK_MODIFIER_TYPE_META_MASK = 1 << 28,
	SKK_MODIFIER_TYPE_RELEASE_MASK = 1 << 30
} SkkModifierType;

struct _SkkKeyEvent {
	GObject parent_instance;
	SkkKeyEventPrivate * priv;
};

struct _SkkKeyEventClass {
	GObjectClass parent_class;
};

struct _SkkKeyEventPrivate {
	gchar* _name;
	gunichar _code;
	SkkModifierType _modifiers;
};

struct _SkkKeyEventCodeKeyvalEntry {
	guint key;
	gunichar value;
};

struct _SkkKeyEventNameKeyvalEntry {
	guint key;
	gchar* value;
};


static gpointer skk_key_event_parent_class = NULL;

GQuark skk_key_event_format_error_quark (void);
GType skk_modifier_type_get_type (void) G_GNUC_CONST;
GType skk_key_event_get_type (void) G_GNUC_CONST;
#define SKK_KEY_EVENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SKK_TYPE_KEY_EVENT, SkkKeyEventPrivate))
enum  {
	SKK_KEY_EVENT_DUMMY_PROPERTY,
	SKK_KEY_EVENT_NAME,
	SKK_KEY_EVENT_CODE,
	SKK_KEY_EVENT_MODIFIERS
};
static GType skk_key_event_code_keyval_entry_get_type (void) G_GNUC_CONST G_GNUC_UNUSED;
static SkkKeyEventCodeKeyvalEntry* skk_key_event_code_keyval_entry_dup (const SkkKeyEventCodeKeyvalEntry* self);
static void skk_key_event_code_keyval_entry_free (SkkKeyEventCodeKeyvalEntry* self);
#define SKK_KEYSYMS_Tab ((guint) 0xff09)
#define SKK_KEYSYMS_Return ((guint) 0xff0d)
#define SKK_KEYSYMS_BackSpace ((guint) 0xff08)
static GType skk_key_event_name_keyval_entry_get_type (void) G_GNUC_CONST G_GNUC_UNUSED;
static SkkKeyEventNameKeyvalEntry* skk_key_event_name_keyval_entry_dup (const SkkKeyEventNameKeyvalEntry* self);
static void skk_key_event_name_keyval_entry_free (SkkKeyEventNameKeyvalEntry* self);
static void skk_key_event_name_keyval_entry_copy (const SkkKeyEventNameKeyvalEntry* self, SkkKeyEventNameKeyvalEntry* dest);
static void skk_key_event_name_keyval_entry_destroy (SkkKeyEventNameKeyvalEntry* self);
#define SKK_KEYSYMS_Up ((guint) 0xff52)
#define SKK_KEYSYMS_Down ((guint) 0xff54)
#define SKK_KEYSYMS_Left ((guint) 0xff51)
#define SKK_KEYSYMS_Right ((guint) 0xff53)
#define SKK_KEYSYMS_Page_Up ((guint) 0xff55)
#define SKK_KEYSYMS_KP_Page_Up ((guint) 0xff9a)
#define SKK_KEYSYMS_Page_Down ((guint) 0xff56)
#define SKK_KEYSYMS_KP_Page_Down ((guint) 0xff9b)
#define SKK_KEYSYMS_Muhenkan ((guint) 0xff22)
#define SKK_KEYSYMS_Henkan ((guint) 0xff23)
SkkKeyEvent* skk_key_event_new (const gchar* name, gunichar code, SkkModifierType modifiers);
SkkKeyEvent* skk_key_event_construct (GType object_type, const gchar* name, gunichar code, SkkModifierType modifiers);
static void skk_key_event_set_name (SkkKeyEvent* self, const gchar* value);
static void skk_key_event_set_code (SkkKeyEvent* self, gunichar value);
void skk_key_event_set_modifiers (SkkKeyEvent* self, SkkModifierType value);
SkkKeyEvent* skk_key_event_copy (SkkKeyEvent* self);
const gchar* skk_key_event_get_name (SkkKeyEvent* self);
gunichar skk_key_event_get_code (SkkKeyEvent* self);
SkkModifierType skk_key_event_get_modifiers (SkkKeyEvent* self);
SkkKeyEvent* skk_key_event_new_from_string (const gchar* key, GError** error);
SkkKeyEvent* skk_key_event_construct_from_string (GType object_type, const gchar* key, GError** error);
gchar* skk_key_event_to_string (SkkKeyEvent* self);
SkkKeyEvent* skk_key_event_new_from_x_keysym (guint keyval, SkkModifierType modifiers, GError** error);
SkkKeyEvent* skk_key_event_construct_from_x_keysym (GType object_type, guint keyval, SkkModifierType modifiers, GError** error);
gboolean skk_key_event_base_equal (SkkKeyEvent* self, SkkKeyEvent* key);
static void skk_key_event_finalize (GObject* obj);
static void _vala_skk_key_event_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
static void _vala_skk_key_event_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec);
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func);
static gint _vala_array_length (gpointer array);

static const SkkKeyEventCodeKeyvalEntry SKK_KEY_EVENT_CODE_KEYVALS[3] = {{SKK_KEYSYMS_Tab, (gunichar) '\t'}, {SKK_KEYSYMS_Return, (gunichar) '\n'}, {SKK_KEYSYMS_BackSpace, (gunichar) '\b'}};
static const SkkKeyEventNameKeyvalEntry SKK_KEY_EVENT_NAME_KEYVALS[10] = {{SKK_KEYSYMS_Up, "Up"}, {SKK_KEYSYMS_Down, "Down"}, {SKK_KEYSYMS_Left, "Left"}, {SKK_KEYSYMS_Right, "Right"}, {SKK_KEYSYMS_Page_Up, "Page_Up"}, {SKK_KEYSYMS_KP_Page_Up, "Page_Up"}, {SKK_KEYSYMS_Page_Down, "Page_Down"}, {SKK_KEYSYMS_KP_Page_Down, "Page_Down"}, {SKK_KEYSYMS_Muhenkan, "lshift"}, {SKK_KEYSYMS_Henkan, "rshift"}};

GQuark skk_key_event_format_error_quark (void) {
	return g_quark_from_static_string ("skk_key_event_format_error-quark");
}


/**
     * A set of bit-flags to indicate the state of modifier keys.
     */
GType skk_modifier_type_get_type (void) {
	static volatile gsize skk_modifier_type_type_id__volatile = 0;
	if (g_once_init_enter (&skk_modifier_type_type_id__volatile)) {
		static const GEnumValue values[] = {{SKK_MODIFIER_TYPE_NONE, "SKK_MODIFIER_TYPE_NONE", "none"}, {SKK_MODIFIER_TYPE_SHIFT_MASK, "SKK_MODIFIER_TYPE_SHIFT_MASK", "shift-mask"}, {SKK_MODIFIER_TYPE_LOCK_MASK, "SKK_MODIFIER_TYPE_LOCK_MASK", "lock-mask"}, {SKK_MODIFIER_TYPE_CONTROL_MASK, "SKK_MODIFIER_TYPE_CONTROL_MASK", "control-mask"}, {SKK_MODIFIER_TYPE_MOD1_MASK, "SKK_MODIFIER_TYPE_MOD1_MASK", "mod1-mask"}, {SKK_MODIFIER_TYPE_MOD2_MASK, "SKK_MODIFIER_TYPE_MOD2_MASK", "mod2-mask"}, {SKK_MODIFIER_TYPE_MOD3_MASK, "SKK_MODIFIER_TYPE_MOD3_MASK", "mod3-mask"}, {SKK_MODIFIER_TYPE_MOD4_MASK, "SKK_MODIFIER_TYPE_MOD4_MASK", "mod4-mask"}, {SKK_MODIFIER_TYPE_MOD5_MASK, "SKK_MODIFIER_TYPE_MOD5_MASK", "mod5-mask"}, {SKK_MODIFIER_TYPE_LSHIFT_MASK, "SKK_MODIFIER_TYPE_LSHIFT_MASK", "lshift-mask"}, {SKK_MODIFIER_TYPE_RSHIFT_MASK, "SKK_MODIFIER_TYPE_RSHIFT_MASK", "rshift-mask"}, {SKK_MODIFIER_TYPE_USLEEP_MASK, "SKK_MODIFIER_TYPE_USLEEP_MASK", "usleep-mask"}, {SKK_MODIFIER_TYPE_SUPER_MASK, "SKK_MODIFIER_TYPE_SUPER_MASK", "super-mask"}, {SKK_MODIFIER_TYPE_HYPER_MASK, "SKK_MODIFIER_TYPE_HYPER_MASK", "hyper-mask"}, {SKK_MODIFIER_TYPE_META_MASK, "SKK_MODIFIER_TYPE_META_MASK", "meta-mask"}, {SKK_MODIFIER_TYPE_RELEASE_MASK, "SKK_MODIFIER_TYPE_RELEASE_MASK", "release-mask"}, {0, NULL, NULL}};
		GType skk_modifier_type_type_id;
		skk_modifier_type_type_id = g_enum_register_static ("SkkModifierType", values);
		g_once_init_leave (&skk_modifier_type_type_id__volatile, skk_modifier_type_type_id);
	}
	return skk_modifier_type_type_id__volatile;
}


/**
         * Create a key event.
         *
         * @param name a key name
         * @param code a character code
         * @param modifiers state of modifier keys
         *
         * @return a new KeyEvent
         */
SkkKeyEvent* skk_key_event_construct (GType object_type, const gchar* name, gunichar code, SkkModifierType modifiers) {
	SkkKeyEvent * self = NULL;
	const gchar* _tmp0_;
	gunichar _tmp1_;
	SkkModifierType _tmp2_;
	self = (SkkKeyEvent*) g_object_new (object_type, NULL);
	_tmp0_ = name;
	skk_key_event_set_name (self, _tmp0_);
	_tmp1_ = code;
	skk_key_event_set_code (self, _tmp1_);
	_tmp2_ = modifiers;
	skk_key_event_set_modifiers (self, _tmp2_);
	return self;
}


SkkKeyEvent* skk_key_event_new (const gchar* name, gunichar code, SkkModifierType modifiers) {
	return skk_key_event_construct (SKK_TYPE_KEY_EVENT, name, code, modifiers);
}


/**
         * Create a copy of the key event.
         *
         * @return a new KeyEvent
         */
SkkKeyEvent* skk_key_event_copy (SkkKeyEvent* self) {
	SkkKeyEvent* result = NULL;
	const gchar* _tmp0_;
	gunichar _tmp1_;
	SkkModifierType _tmp2_;
	SkkKeyEvent* _tmp3_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_name;
	_tmp1_ = self->priv->_code;
	_tmp2_ = self->priv->_modifiers;
	_tmp3_ = skk_key_event_new (_tmp0_, _tmp1_, _tmp2_);
	result = _tmp3_;
	return result;
}


/**
         * Create a key event from string.
         *
         * @param key a string representation of a key event
         *
         * @return a new KeyEvent
         */
static gchar* string_slice (const gchar* self, glong start, glong end) {
	gchar* result = NULL;
	gint _tmp0_;
	gint _tmp1_;
	glong string_length;
	glong _tmp2_;
	glong _tmp5_;
	gboolean _tmp8_ = FALSE;
	glong _tmp9_;
	gboolean _tmp12_;
	gboolean _tmp13_ = FALSE;
	glong _tmp14_;
	gboolean _tmp17_;
	glong _tmp18_;
	glong _tmp19_;
	glong _tmp20_;
	glong _tmp21_;
	glong _tmp22_;
	gchar* _tmp23_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = strlen (self);
	_tmp1_ = _tmp0_;
	string_length = (glong) _tmp1_;
	_tmp2_ = start;
	if (_tmp2_ < ((glong) 0)) {
		glong _tmp3_;
		glong _tmp4_;
		_tmp3_ = string_length;
		_tmp4_ = start;
		start = _tmp3_ + _tmp4_;
	}
	_tmp5_ = end;
	if (_tmp5_ < ((glong) 0)) {
		glong _tmp6_;
		glong _tmp7_;
		_tmp6_ = string_length;
		_tmp7_ = end;
		end = _tmp6_ + _tmp7_;
	}
	_tmp9_ = start;
	if (_tmp9_ >= ((glong) 0)) {
		glong _tmp10_;
		glong _tmp11_;
		_tmp10_ = start;
		_tmp11_ = string_length;
		_tmp8_ = _tmp10_ <= _tmp11_;
	} else {
		_tmp8_ = FALSE;
	}
	_tmp12_ = _tmp8_;
	g_return_val_if_fail (_tmp12_, NULL);
	_tmp14_ = end;
	if (_tmp14_ >= ((glong) 0)) {
		glong _tmp15_;
		glong _tmp16_;
		_tmp15_ = end;
		_tmp16_ = string_length;
		_tmp13_ = _tmp15_ <= _tmp16_;
	} else {
		_tmp13_ = FALSE;
	}
	_tmp17_ = _tmp13_;
	g_return_val_if_fail (_tmp17_, NULL);
	_tmp18_ = start;
	_tmp19_ = end;
	g_return_val_if_fail (_tmp18_ <= _tmp19_, NULL);
	_tmp20_ = start;
	_tmp21_ = end;
	_tmp22_ = start;
	_tmp23_ = g_strndup (((gchar*) self) + _tmp20_, (gsize) (_tmp21_ - _tmp22_));
	result = _tmp23_;
	return result;
}


static gunichar string_get_char (const gchar* self, glong index) {
	gunichar result = 0U;
	glong _tmp0_;
	gunichar _tmp1_ = 0U;
	g_return_val_if_fail (self != NULL, 0U);
	_tmp0_ = index;
	_tmp1_ = g_utf8_get_char (((gchar*) self) + _tmp0_);
	result = _tmp1_;
	return result;
}


static gint string_last_index_of (const gchar* self, const gchar* needle, gint start_index) {
	gint result = 0;
	gint _tmp0_;
	const gchar* _tmp1_;
	gchar* _tmp2_ = NULL;
	gchar* _result_;
	gchar* _tmp3_;
	g_return_val_if_fail (self != NULL, 0);
	g_return_val_if_fail (needle != NULL, 0);
	_tmp0_ = start_index;
	_tmp1_ = needle;
	_tmp2_ = g_strrstr (((gchar*) self) + _tmp0_, (gchar*) _tmp1_);
	_result_ = _tmp2_;
	_tmp3_ = _result_;
	if (_tmp3_ != NULL) {
		gchar* _tmp4_;
		_tmp4_ = _result_;
		result = (gint) (_tmp4_ - ((gchar*) self));
		return result;
	} else {
		result = -1;
		return result;
	}
}


static glong string_strnlen (gchar* str, glong maxlen) {
	glong result = 0L;
	gchar* _tmp0_;
	glong _tmp1_;
	gchar* _tmp2_ = NULL;
	gchar* end;
	gchar* _tmp3_;
	_tmp0_ = str;
	_tmp1_ = maxlen;
	_tmp2_ = memchr (_tmp0_, 0, (gsize) _tmp1_);
	end = _tmp2_;
	_tmp3_ = end;
	if (_tmp3_ == NULL) {
		glong _tmp4_;
		_tmp4_ = maxlen;
		result = _tmp4_;
		return result;
	} else {
		gchar* _tmp5_;
		gchar* _tmp6_;
		_tmp5_ = end;
		_tmp6_ = str;
		result = (glong) (_tmp5_ - _tmp6_);
		return result;
	}
}


static gchar* string_substring (const gchar* self, glong offset, glong len) {
	gchar* result = NULL;
	glong string_length = 0L;
	gboolean _tmp0_ = FALSE;
	glong _tmp1_;
	gboolean _tmp3_;
	glong _tmp9_;
	glong _tmp15_;
	glong _tmp18_;
	glong _tmp19_;
	glong _tmp20_;
	glong _tmp21_;
	glong _tmp22_;
	gchar* _tmp23_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = offset;
	if (_tmp1_ >= ((glong) 0)) {
		glong _tmp2_;
		_tmp2_ = len;
		_tmp0_ = _tmp2_ >= ((glong) 0);
	} else {
		_tmp0_ = FALSE;
	}
	_tmp3_ = _tmp0_;
	if (_tmp3_) {
		glong _tmp4_;
		glong _tmp5_;
		glong _tmp6_ = 0L;
		_tmp4_ = offset;
		_tmp5_ = len;
		_tmp6_ = string_strnlen ((gchar*) self, _tmp4_ + _tmp5_);
		string_length = _tmp6_;
	} else {
		gint _tmp7_;
		gint _tmp8_;
		_tmp7_ = strlen (self);
		_tmp8_ = _tmp7_;
		string_length = (glong) _tmp8_;
	}
	_tmp9_ = offset;
	if (_tmp9_ < ((glong) 0)) {
		glong _tmp10_;
		glong _tmp11_;
		glong _tmp12_;
		_tmp10_ = string_length;
		_tmp11_ = offset;
		offset = _tmp10_ + _tmp11_;
		_tmp12_ = offset;
		g_return_val_if_fail (_tmp12_ >= ((glong) 0), NULL);
	} else {
		glong _tmp13_;
		glong _tmp14_;
		_tmp13_ = offset;
		_tmp14_ = string_length;
		g_return_val_if_fail (_tmp13_ <= _tmp14_, NULL);
	}
	_tmp15_ = len;
	if (_tmp15_ < ((glong) 0)) {
		glong _tmp16_;
		glong _tmp17_;
		_tmp16_ = string_length;
		_tmp17_ = offset;
		len = _tmp16_ - _tmp17_;
	}
	_tmp18_ = offset;
	_tmp19_ = len;
	_tmp20_ = string_length;
	g_return_val_if_fail ((_tmp18_ + _tmp19_) <= _tmp20_, NULL);
	_tmp21_ = offset;
	_tmp22_ = len;
	_tmp23_ = g_strndup (((gchar*) self) + _tmp21_, (gsize) _tmp22_);
	result = _tmp23_;
	return result;
}


SkkKeyEvent* skk_key_event_construct_from_string (GType object_type, const gchar* key, GError** error) {
	SkkKeyEvent * self = NULL;
	gboolean _tmp0_ = FALSE;
	const gchar* _tmp1_;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp5_;
	GError * _inner_error_ = NULL;
	g_return_val_if_fail (key != NULL, NULL);
	self = (SkkKeyEvent*) g_object_new (object_type, NULL);
	_tmp1_ = key;
	_tmp2_ = g_str_has_prefix (_tmp1_, "(");
	if (_tmp2_) {
		const gchar* _tmp3_;
		gboolean _tmp4_ = FALSE;
		_tmp3_ = key;
		_tmp4_ = g_str_has_suffix (_tmp3_, ")");
		_tmp0_ = _tmp4_;
	} else {
		_tmp0_ = FALSE;
	}
	_tmp5_ = _tmp0_;
	if (_tmp5_) {
		const gchar* _tmp6_;
		gchar* _tmp7_ = NULL;
		gchar* _tmp8_;
		gchar** _tmp9_;
		gchar** _tmp10_ = NULL;
		gchar** _tmp11_;
		gint _tmp11__length1;
		gchar** strv;
		gint strv_length1;
		gint _strv_size_;
		gint index;
		gchar** _tmp57_;
		gint _tmp57__length1;
		gint _tmp58_;
		const gchar* _tmp59_;
		gunichar _tmp60_ = 0U;
		const gchar* _tmp61_;
		gint _tmp62_ = 0;
		gunichar _tmp65_;
		_tmp6_ = key;
		_tmp7_ = string_slice (_tmp6_, (glong) 1, (glong) (-1));
		_tmp8_ = _tmp7_;
		_tmp10_ = _tmp9_ = g_strsplit (_tmp8_, " ", 0);
		_tmp11_ = _tmp10_;
		_tmp11__length1 = _vala_array_length (_tmp9_);
		_g_free0 (_tmp8_);
		strv = _tmp11_;
		strv_length1 = _tmp11__length1;
		_strv_size_ = strv_length1;
		index = 0;
		{
			gboolean _tmp12_;
			_tmp12_ = TRUE;
			while (TRUE) {
				gboolean _tmp13_;
				gint _tmp15_;
				gchar** _tmp16_;
				gint _tmp16__length1;
				gchar** _tmp17_;
				gint _tmp17__length1;
				gint _tmp18_;
				const gchar* _tmp19_;
				_tmp13_ = _tmp12_;
				if (!_tmp13_) {
					gint _tmp14_;
					_tmp14_ = index;
					index = _tmp14_ + 1;
				}
				_tmp12_ = FALSE;
				_tmp15_ = index;
				_tmp16_ = strv;
				_tmp16__length1 = strv_length1;
				if (!(_tmp15_ < (_tmp16__length1 - 1))) {
					break;
				}
				_tmp17_ = strv;
				_tmp17__length1 = strv_length1;
				_tmp18_ = index;
				_tmp19_ = _tmp17_[_tmp18_];
				if (g_strcmp0 (_tmp19_, "control") == 0) {
					SkkModifierType _tmp20_;
					_tmp20_ = self->priv->_modifiers;
					skk_key_event_set_modifiers (self, _tmp20_ | SKK_MODIFIER_TYPE_CONTROL_MASK);
				} else {
					gchar** _tmp21_;
					gint _tmp21__length1;
					gint _tmp22_;
					const gchar* _tmp23_;
					_tmp21_ = strv;
					_tmp21__length1 = strv_length1;
					_tmp22_ = index;
					_tmp23_ = _tmp21_[_tmp22_];
					if (g_strcmp0 (_tmp23_, "meta") == 0) {
						SkkModifierType _tmp24_;
						_tmp24_ = self->priv->_modifiers;
						skk_key_event_set_modifiers (self, _tmp24_ | SKK_MODIFIER_TYPE_META_MASK);
					} else {
						gchar** _tmp25_;
						gint _tmp25__length1;
						gint _tmp26_;
						const gchar* _tmp27_;
						_tmp25_ = strv;
						_tmp25__length1 = strv_length1;
						_tmp26_ = index;
						_tmp27_ = _tmp25_[_tmp26_];
						if (g_strcmp0 (_tmp27_, "hyper") == 0) {
							SkkModifierType _tmp28_;
							_tmp28_ = self->priv->_modifiers;
							skk_key_event_set_modifiers (self, _tmp28_ | SKK_MODIFIER_TYPE_HYPER_MASK);
						} else {
							gchar** _tmp29_;
							gint _tmp29__length1;
							gint _tmp30_;
							const gchar* _tmp31_;
							_tmp29_ = strv;
							_tmp29__length1 = strv_length1;
							_tmp30_ = index;
							_tmp31_ = _tmp29_[_tmp30_];
							if (g_strcmp0 (_tmp31_, "super") == 0) {
								SkkModifierType _tmp32_;
								_tmp32_ = self->priv->_modifiers;
								skk_key_event_set_modifiers (self, _tmp32_ | SKK_MODIFIER_TYPE_SUPER_MASK);
							} else {
								gchar** _tmp33_;
								gint _tmp33__length1;
								gint _tmp34_;
								const gchar* _tmp35_;
								_tmp33_ = strv;
								_tmp33__length1 = strv_length1;
								_tmp34_ = index;
								_tmp35_ = _tmp33_[_tmp34_];
								if (g_strcmp0 (_tmp35_, "alt") == 0) {
									SkkModifierType _tmp36_;
									_tmp36_ = self->priv->_modifiers;
									skk_key_event_set_modifiers (self, _tmp36_ | SKK_MODIFIER_TYPE_MOD1_MASK);
								} else {
									gchar** _tmp37_;
									gint _tmp37__length1;
									gint _tmp38_;
									const gchar* _tmp39_;
									_tmp37_ = strv;
									_tmp37__length1 = strv_length1;
									_tmp38_ = index;
									_tmp39_ = _tmp37_[_tmp38_];
									if (g_strcmp0 (_tmp39_, "lshift") == 0) {
										SkkModifierType _tmp40_;
										_tmp40_ = self->priv->_modifiers;
										skk_key_event_set_modifiers (self, _tmp40_ | SKK_MODIFIER_TYPE_LSHIFT_MASK);
									} else {
										gchar** _tmp41_;
										gint _tmp41__length1;
										gint _tmp42_;
										const gchar* _tmp43_;
										_tmp41_ = strv;
										_tmp41__length1 = strv_length1;
										_tmp42_ = index;
										_tmp43_ = _tmp41_[_tmp42_];
										if (g_strcmp0 (_tmp43_, "rshift") == 0) {
											SkkModifierType _tmp44_;
											_tmp44_ = self->priv->_modifiers;
											skk_key_event_set_modifiers (self, _tmp44_ | SKK_MODIFIER_TYPE_RSHIFT_MASK);
										} else {
											gchar** _tmp45_;
											gint _tmp45__length1;
											gint _tmp46_;
											const gchar* _tmp47_;
											_tmp45_ = strv;
											_tmp45__length1 = strv_length1;
											_tmp46_ = index;
											_tmp47_ = _tmp45_[_tmp46_];
											if (g_strcmp0 (_tmp47_, "usleep") == 0) {
												SkkModifierType _tmp48_;
												_tmp48_ = self->priv->_modifiers;
												skk_key_event_set_modifiers (self, _tmp48_ | SKK_MODIFIER_TYPE_USLEEP_MASK);
											} else {
												gchar** _tmp49_;
												gint _tmp49__length1;
												gint _tmp50_;
												const gchar* _tmp51_;
												_tmp49_ = strv;
												_tmp49__length1 = strv_length1;
												_tmp50_ = index;
												_tmp51_ = _tmp49_[_tmp50_];
												if (g_strcmp0 (_tmp51_, "release") == 0) {
													SkkModifierType _tmp52_;
													_tmp52_ = self->priv->_modifiers;
													skk_key_event_set_modifiers (self, _tmp52_ | SKK_MODIFIER_TYPE_RELEASE_MASK);
												} else {
													gchar** _tmp53_;
													gint _tmp53__length1;
													gint _tmp54_;
													const gchar* _tmp55_;
													GError* _tmp56_;
													_tmp53_ = strv;
													_tmp53__length1 = strv_length1;
													_tmp54_ = index;
													_tmp55_ = _tmp53_[_tmp54_];
													_tmp56_ = g_error_new (SKK_KEY_EVENT_FORMAT_ERROR, SKK_KEY_EVENT_FORMAT_ERROR_PARSE_FAILED, "unknown modifier %s", _tmp55_);
													_inner_error_ = _tmp56_;
													if (_inner_error_->domain == SKK_KEY_EVENT_FORMAT_ERROR) {
														g_propagate_error (error, _inner_error_);
														strv = (_vala_array_free (strv, strv_length1, (GDestroyNotify) g_free), NULL);
														_g_object_unref0 (self);
														return NULL;
													} else {
														strv = (_vala_array_free (strv, strv_length1, (GDestroyNotify) g_free), NULL);
														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;
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
		_tmp57_ = strv;
		_tmp57__length1 = strv_length1;
		_tmp58_ = index;
		_tmp59_ = _tmp57_[_tmp58_];
		skk_key_event_set_name (self, _tmp59_);
		_tmp61_ = self->priv->_name;
		_tmp62_ = g_utf8_strlen (_tmp61_, (gssize) (-1));
		if (_tmp62_ == 1) {
			const gchar* _tmp63_;
			gunichar _tmp64_ = 0U;
			_tmp63_ = self->priv->_name;
			_tmp64_ = string_get_char (_tmp63_, (glong) 0);
			_tmp60_ = _tmp64_;
		} else {
			_tmp60_ = (gunichar) '\0';
		}
		_tmp65_ = _tmp60_;
		skk_key_event_set_code (self, _tmp65_);
		strv = (_vala_array_free (strv, strv_length1, (GDestroyNotify) g_free), NULL);
	} else {
		const gchar* _tmp66_;
		gint _tmp67_ = 0;
		gint index;
		gint _tmp68_;
		_tmp66_ = key;
		_tmp67_ = string_last_index_of (_tmp66_, "-", 0);
		index = _tmp67_;
		_tmp68_ = index;
		if (_tmp68_ > 0) {
			const gchar* _tmp69_;
			gint _tmp70_;
			gchar* _tmp71_ = NULL;
			gchar* _tmp72_;
			gchar** _tmp73_;
			gchar** _tmp74_ = NULL;
			gchar** _tmp75_;
			gint _tmp75__length1;
			gchar** mods;
			gint mods_length1;
			gint _mods_size_;
			gchar** _tmp76_;
			gint _tmp76__length1;
			const gchar* _tmp86_;
			gint _tmp87_;
			gchar* _tmp88_ = NULL;
			gchar* _tmp89_;
			gunichar _tmp90_ = 0U;
			const gchar* _tmp91_;
			gint _tmp92_ = 0;
			gunichar _tmp95_;
			_tmp69_ = key;
			_tmp70_ = index;
			_tmp71_ = string_substring (_tmp69_, (glong) 0, (glong) _tmp70_);
			_tmp72_ = _tmp71_;
			_tmp74_ = _tmp73_ = g_strsplit (_tmp72_, "-", 0);
			_tmp75_ = _tmp74_;
			_tmp75__length1 = _vala_array_length (_tmp73_);
			_g_free0 (_tmp72_);
			mods = _tmp75_;
			mods_length1 = _tmp75__length1;
			_mods_size_ = mods_length1;
			_tmp76_ = mods;
			_tmp76__length1 = mods_length1;
			{
				gchar** mod_collection = NULL;
				gint mod_collection_length1 = 0;
				gint _mod_collection_size_ = 0;
				gint mod_it = 0;
				mod_collection = _tmp76_;
				mod_collection_length1 = _tmp76__length1;
				for (mod_it = 0; mod_it < _tmp76__length1; mod_it = mod_it + 1) {
					gchar* _tmp77_;
					gchar* mod = NULL;
					_tmp77_ = g_strdup (mod_collection[mod_it]);
					mod = _tmp77_;
					{
						const gchar* _tmp78_;
						_tmp78_ = mod;
						if (g_strcmp0 (_tmp78_, "C") == 0) {
							SkkModifierType _tmp79_;
							_tmp79_ = self->priv->_modifiers;
							skk_key_event_set_modifiers (self, _tmp79_ | SKK_MODIFIER_TYPE_CONTROL_MASK);
						} else {
							const gchar* _tmp80_;
							_tmp80_ = mod;
							if (g_strcmp0 (_tmp80_, "A") == 0) {
								SkkModifierType _tmp81_;
								_tmp81_ = self->priv->_modifiers;
								skk_key_event_set_modifiers (self, _tmp81_ | SKK_MODIFIER_TYPE_MOD1_MASK);
							} else {
								const gchar* _tmp82_;
								_tmp82_ = mod;
								if (g_strcmp0 (_tmp82_, "M") == 0) {
									SkkModifierType _tmp83_;
									_tmp83_ = self->priv->_modifiers;
									skk_key_event_set_modifiers (self, _tmp83_ | SKK_MODIFIER_TYPE_META_MASK);
								} else {
									const gchar* _tmp84_;
									_tmp84_ = mod;
									if (g_strcmp0 (_tmp84_, "G") == 0) {
										SkkModifierType _tmp85_;
										_tmp85_ = self->priv->_modifiers;
										skk_key_event_set_modifiers (self, _tmp85_ | SKK_MODIFIER_TYPE_MOD5_MASK);
									}
								}
							}
						}
						_g_free0 (mod);
					}
				}
			}
			_tmp86_ = key;
			_tmp87_ = index;
			_tmp88_ = string_substring (_tmp86_, (glong) (_tmp87_ + 1), (glong) (-1));
			_tmp89_ = _tmp88_;
			skk_key_event_set_name (self, _tmp89_);
			_g_free0 (_tmp89_);
			_tmp91_ = self->priv->_name;
			_tmp92_ = g_utf8_strlen (_tmp91_, (gssize) (-1));
			if (_tmp92_ == 1) {
				const gchar* _tmp93_;
				gunichar _tmp94_ = 0U;
				_tmp93_ = self->priv->_name;
				_tmp94_ = string_get_char (_tmp93_, (glong) 0);
				_tmp90_ = _tmp94_;
			} else {
				_tmp90_ = (gunichar) '\0';
			}
			_tmp95_ = _tmp90_;
			skk_key_event_set_code (self, _tmp95_);
			mods = (_vala_array_free (mods, mods_length1, (GDestroyNotify) g_free), NULL);
		} else {
			const gchar* _tmp96_;
			gunichar _tmp97_ = 0U;
			const gchar* _tmp98_;
			gint _tmp99_ = 0;
			gunichar _tmp102_;
			skk_key_event_set_modifiers (self, SKK_MODIFIER_TYPE_NONE);
			_tmp96_ = key;
			skk_key_event_set_name (self, _tmp96_);
			_tmp98_ = self->priv->_name;
			_tmp99_ = g_utf8_strlen (_tmp98_, (gssize) (-1));
			if (_tmp99_ == 1) {
				const gchar* _tmp100_;
				gunichar _tmp101_ = 0U;
				_tmp100_ = self->priv->_name;
				_tmp101_ = string_get_char (_tmp100_, (glong) 0);
				_tmp97_ = _tmp101_;
			} else {
				_tmp97_ = (gunichar) '\0';
			}
			_tmp102_ = _tmp97_;
			skk_key_event_set_code (self, _tmp102_);
		}
	}
	return self;
}


SkkKeyEvent* skk_key_event_new_from_string (const gchar* key, GError** error) {
	return skk_key_event_construct_from_string (SKK_TYPE_KEY_EVENT, key, error);
}


/**
         * Convert the KeyEvent to string.
         *
         * @return a string representing the KeyEvent
         */
static gchar* g_unichar_to_string (gunichar self) {
	gchar* result = NULL;
	gchar* _tmp0_ = NULL;
	gchar* str;
	const gchar* _tmp1_;
	_tmp0_ = g_new0 (gchar, 7);
	str = (gchar*) _tmp0_;
	_tmp1_ = str;
	g_unichar_to_utf8 (self, _tmp1_);
	result = str;
	return result;
}


gchar* skk_key_event_to_string (SkkKeyEvent* self) {
	gchar* result = NULL;
	gchar* _tmp0_ = NULL;
	const gchar* _tmp1_;
	const gchar* _tmp6_;
	gchar* _tmp7_;
	gchar* _base;
	SkkModifierType _tmp8_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = self->priv->_name;
	if (_tmp1_ != NULL) {
		const gchar* _tmp2_;
		gchar* _tmp3_;
		_tmp2_ = self->priv->_name;
		_tmp3_ = g_strdup (_tmp2_);
		_g_free0 (_tmp0_);
		_tmp0_ = _tmp3_;
	} else {
		gunichar _tmp4_;
		gchar* _tmp5_ = NULL;
		_tmp4_ = self->priv->_code;
		_tmp5_ = g_unichar_to_string (_tmp4_);
		_g_free0 (_tmp0_);
		_tmp0_ = _tmp5_;
	}
	_tmp6_ = _tmp0_;
	_tmp7_ = g_strdup (_tmp6_);
	_base = _tmp7_;
	_tmp8_ = self->priv->_modifiers;
	if (_tmp8_ != 0) {
		GeeArrayList* _tmp9_;
		GeeArrayList* elements;
		SkkModifierType _tmp10_;
		SkkModifierType _tmp12_;
		SkkModifierType _tmp14_;
		SkkModifierType _tmp16_;
		SkkModifierType _tmp18_;
		SkkModifierType _tmp20_;
		SkkModifierType _tmp22_;
		SkkModifierType _tmp24_;
		SkkModifierType _tmp26_;
		GeeArrayList* _tmp28_;
		const gchar* _tmp29_;
		GeeArrayList* _tmp30_;
		GeeArrayList* _tmp31_;
		gint _tmp32_ = 0;
		gpointer* _tmp33_ = NULL;
		gchar** _tmp34_;
		gint _tmp34__length1;
		gchar* _tmp35_ = NULL;
		gchar* _tmp36_;
		gchar* _tmp37_;
		gchar* _tmp38_;
		gchar* _tmp39_;
		gchar* _tmp40_;
		_tmp9_ = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL);
		elements = _tmp9_;
		_tmp10_ = self->priv->_modifiers;
		if ((_tmp10_ & SKK_MODIFIER_TYPE_CONTROL_MASK) != 0) {
			GeeArrayList* _tmp11_;
			_tmp11_ = elements;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp11_, "control");
		}
		_tmp12_ = self->priv->_modifiers;
		if ((_tmp12_ & SKK_MODIFIER_TYPE_META_MASK) != 0) {
			GeeArrayList* _tmp13_;
			_tmp13_ = elements;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp13_, "meta");
		}
		_tmp14_ = self->priv->_modifiers;
		if ((_tmp14_ & SKK_MODIFIER_TYPE_HYPER_MASK) != 0) {
			GeeArrayList* _tmp15_;
			_tmp15_ = elements;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp15_, "hyper");
		}
		_tmp16_ = self->priv->_modifiers;
		if ((_tmp16_ & SKK_MODIFIER_TYPE_SUPER_MASK) != 0) {
			GeeArrayList* _tmp17_;
			_tmp17_ = elements;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp17_, "super");
		}
		_tmp18_ = self->priv->_modifiers;
		if ((_tmp18_ & SKK_MODIFIER_TYPE_MOD1_MASK) != 0) {
			GeeArrayList* _tmp19_;
			_tmp19_ = elements;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp19_, "alt");
		}
		_tmp20_ = self->priv->_modifiers;
		if ((_tmp20_ & SKK_MODIFIER_TYPE_LSHIFT_MASK) != 0) {
			GeeArrayList* _tmp21_;
			_tmp21_ = elements;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp21_, "lshift");
		}
		_tmp22_ = self->priv->_modifiers;
		if ((_tmp22_ & SKK_MODIFIER_TYPE_RSHIFT_MASK) != 0) {
			GeeArrayList* _tmp23_;
			_tmp23_ = elements;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp23_, "rshift");
		}
		_tmp24_ = self->priv->_modifiers;
		if ((_tmp24_ & SKK_MODIFIER_TYPE_USLEEP_MASK) != 0) {
			GeeArrayList* _tmp25_;
			_tmp25_ = elements;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp25_, "usleep");
		}
		_tmp26_ = self->priv->_modifiers;
		if ((_tmp26_ & SKK_MODIFIER_TYPE_RELEASE_MASK) != 0) {
			GeeArrayList* _tmp27_;
			_tmp27_ = elements;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp27_, "release");
		}
		_tmp28_ = elements;
		_tmp29_ = _base;
		gee_abstract_collection_add ((GeeAbstractCollection*) _tmp28_, _tmp29_);
		_tmp30_ = elements;
		gee_abstract_collection_add ((GeeAbstractCollection*) _tmp30_, NULL);
		_tmp31_ = elements;
		_tmp33_ = gee_abstract_collection_to_array ((GeeAbstractCollection*) _tmp31_, &_tmp32_);
		_tmp34_ = _tmp33_;
		_tmp34__length1 = _tmp32_;
		_tmp35_ = g_strjoinv (" ", _tmp34_);
		_tmp36_ = _tmp35_;
		_tmp37_ = g_strconcat ("(", _tmp36_, NULL);
		_tmp38_ = _tmp37_;
		_tmp39_ = g_strconcat (_tmp38_, ")", NULL);
		_tmp40_ = _tmp39_;
		_g_free0 (_tmp38_);
		_g_free0 (_tmp36_);
		_tmp34_ = (_vala_array_free (_tmp34_, _tmp34__length1, (GDestroyNotify) g_free), NULL);
		result = _tmp40_;
		_g_object_unref0 (elements);
		_g_free0 (_base);
		_g_free0 (_tmp0_);
		return result;
	} else {
		result = _base;
		_g_free0 (_tmp0_);
		return result;
	}
	_g_free0 (_base);
	_g_free0 (_tmp0_);
}


/**
         * Create a key event from an X keysym and modifiers.
         *
         * @param keyval an X keysym
         * @param modifiers modifier mask
         *
         * @return a new KeyEvent
         */
SkkKeyEvent* skk_key_event_construct_from_x_keysym (GType object_type, guint keyval, SkkModifierType modifiers, GError** error) {
	SkkKeyEvent * self = NULL;
	gboolean _tmp10_ = FALSE;
	const gchar* _tmp11_;
	gboolean _tmp13_;
	gboolean _tmp14_ = FALSE;
	const gchar* _tmp15_;
	gboolean _tmp17_;
	SkkModifierType _tmp25_;
	GError * _inner_error_ = NULL;
	self = (SkkKeyEvent*) g_object_new (object_type, NULL);
	{
		SkkKeyEventNameKeyvalEntry* entry_collection = NULL;
		gint entry_collection_length1 = 0;
		gint _entry_collection_size_ = 0;
		gint entry_it = 0;
		entry_collection = SKK_KEY_EVENT_NAME_KEYVALS;
		entry_collection_length1 = G_N_ELEMENTS (SKK_KEY_EVENT_NAME_KEYVALS);
		for (entry_it = 0; entry_it < G_N_ELEMENTS (SKK_KEY_EVENT_NAME_KEYVALS); entry_it = entry_it + 1) {
			SkkKeyEventNameKeyvalEntry entry = {0};
			entry = entry_collection[entry_it];
			{
				SkkKeyEventNameKeyvalEntry _tmp0_;
				guint _tmp1_;
				guint _tmp2_;
				_tmp0_ = entry;
				_tmp1_ = _tmp0_.key;
				_tmp2_ = keyval;
				if (_tmp1_ == _tmp2_) {
					SkkKeyEventNameKeyvalEntry _tmp3_;
					const gchar* _tmp4_;
					_tmp3_ = entry;
					_tmp4_ = _tmp3_.value;
					skk_key_event_set_name (self, _tmp4_);
					break;
				}
			}
		}
	}
	{
		SkkKeyEventCodeKeyvalEntry* entry_collection = NULL;
		gint entry_collection_length1 = 0;
		gint _entry_collection_size_ = 0;
		gint entry_it = 0;
		entry_collection = SKK_KEY_EVENT_CODE_KEYVALS;
		entry_collection_length1 = G_N_ELEMENTS (SKK_KEY_EVENT_CODE_KEYVALS);
		for (entry_it = 0; entry_it < G_N_ELEMENTS (SKK_KEY_EVENT_CODE_KEYVALS); entry_it = entry_it + 1) {
			SkkKeyEventCodeKeyvalEntry entry = {0};
			entry = entry_collection[entry_it];
			{
				SkkKeyEventCodeKeyvalEntry _tmp5_;
				guint _tmp6_;
				guint _tmp7_;
				_tmp5_ = entry;
				_tmp6_ = _tmp5_.key;
				_tmp7_ = keyval;
				if (_tmp6_ == _tmp7_) {
					SkkKeyEventCodeKeyvalEntry _tmp8_;
					gunichar _tmp9_;
					_tmp8_ = entry;
					_tmp9_ = _tmp8_.value;
					skk_key_event_set_code (self, _tmp9_);
					break;
				}
			}
		}
	}
	_tmp11_ = self->priv->_name;
	if (_tmp11_ == NULL) {
		_tmp10_ = TRUE;
	} else {
		gunichar _tmp12_;
		_tmp12_ = self->priv->_code;
		_tmp10_ = _tmp12_ == ((gunichar) '\0');
	}
	_tmp13_ = _tmp10_;
	_vala_assert (_tmp13_, "name == null || code == '\\0'");
	_tmp15_ = self->priv->_name;
	if (_tmp15_ == NULL) {
		gunichar _tmp16_;
		_tmp16_ = self->priv->_code;
		_tmp14_ = _tmp16_ == ((gunichar) '\0');
	} else {
		_tmp14_ = FALSE;
	}
	_tmp17_ = _tmp14_;
	if (_tmp17_) {
		gboolean _tmp18_ = FALSE;
		guint _tmp19_;
		gboolean _tmp21_;
		_tmp19_ = keyval;
		if (((guint) 0x20) <= _tmp19_) {
			guint _tmp20_;
			_tmp20_ = keyval;
			_tmp18_ = _tmp20_ < ((guint) 0x7F);
		} else {
			_tmp18_ = FALSE;
		}
		_tmp21_ = _tmp18_;
		if (_tmp21_) {
			guint _tmp22_;
			_tmp22_ = keyval;
			skk_key_event_set_code (self, (gunichar) _tmp22_);
		} else {
			guint _tmp23_;
			GError* _tmp24_;
			_tmp23_ = keyval;
			_tmp24_ = g_error_new (SKK_KEY_EVENT_FORMAT_ERROR, SKK_KEY_EVENT_FORMAT_ERROR_KEYSYM_NOT_FOUND, "unknown keysym %u", _tmp23_);
			_inner_error_ = _tmp24_;
			if (_inner_error_->domain == SKK_KEY_EVENT_FORMAT_ERROR) {
				g_propagate_error (error, _inner_error_);
				_g_object_unref0 (self);
				return NULL;
			} else {
				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;
			}
		}
	}
	_tmp25_ = modifiers;
	skk_key_event_set_modifiers (self, _tmp25_);
	return self;
}


SkkKeyEvent* skk_key_event_new_from_x_keysym (guint keyval, SkkModifierType modifiers, GError** error) {
	return skk_key_event_construct_from_x_keysym (SKK_TYPE_KEY_EVENT, keyval, modifiers, error);
}


/**
         * Compare two key events ignoring modifiers.
         *
         * @param key a KeyEvent
         *
         * @return `true` if those base components are equal, `false` otherwise
         */
gboolean skk_key_event_base_equal (SkkKeyEvent* self, SkkKeyEvent* key) {
	gboolean result = FALSE;
	gboolean _tmp0_ = FALSE;
	gunichar _tmp1_;
	SkkKeyEvent* _tmp2_;
	gunichar _tmp3_;
	gboolean _tmp7_;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (key != NULL, FALSE);
	_tmp1_ = self->priv->_code;
	_tmp2_ = key;
	_tmp3_ = _tmp2_->priv->_code;
	if (_tmp1_ == _tmp3_) {
		const gchar* _tmp4_;
		SkkKeyEvent* _tmp5_;
		const gchar* _tmp6_;
		_tmp4_ = self->priv->_name;
		_tmp5_ = key;
		_tmp6_ = _tmp5_->priv->_name;
		_tmp0_ = g_strcmp0 (_tmp4_, _tmp6_) == 0;
	} else {
		_tmp0_ = FALSE;
	}
	_tmp7_ = _tmp0_;
	result = _tmp7_;
	return result;
}


const gchar* skk_key_event_get_name (SkkKeyEvent* self) {
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_name;
	result = _tmp0_;
	return result;
}


static void skk_key_event_set_name (SkkKeyEvent* self, const gchar* value) {
	const gchar* _tmp0_;
	gchar* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = value;
	_tmp1_ = g_strdup (_tmp0_);
	_g_free0 (self->priv->_name);
	self->priv->_name = _tmp1_;
	g_object_notify ((GObject *) self, "name");
}


gunichar skk_key_event_get_code (SkkKeyEvent* self) {
	gunichar result;
	gunichar _tmp0_;
	g_return_val_if_fail (self != NULL, 0U);
	_tmp0_ = self->priv->_code;
	result = _tmp0_;
	return result;
}


static void skk_key_event_set_code (SkkKeyEvent* self, gunichar value) {
	gunichar _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = value;
	self->priv->_code = _tmp0_;
	g_object_notify ((GObject *) self, "code");
}


SkkModifierType skk_key_event_get_modifiers (SkkKeyEvent* self) {
	SkkModifierType result;
	SkkModifierType _tmp0_;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = self->priv->_modifiers;
	result = _tmp0_;
	return result;
}


void skk_key_event_set_modifiers (SkkKeyEvent* self, SkkModifierType value) {
	SkkModifierType _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = value;
	self->priv->_modifiers = _tmp0_;
	g_object_notify ((GObject *) self, "modifiers");
}


static SkkKeyEventCodeKeyvalEntry* skk_key_event_code_keyval_entry_dup (const SkkKeyEventCodeKeyvalEntry* self) {
	SkkKeyEventCodeKeyvalEntry* dup;
	dup = g_new0 (SkkKeyEventCodeKeyvalEntry, 1);
	memcpy (dup, self, sizeof (SkkKeyEventCodeKeyvalEntry));
	return dup;
}


static void skk_key_event_code_keyval_entry_free (SkkKeyEventCodeKeyvalEntry* self) {
	g_free (self);
}


static GType skk_key_event_code_keyval_entry_get_type (void) {
	static volatile gsize skk_key_event_code_keyval_entry_type_id__volatile = 0;
	if (g_once_init_enter (&skk_key_event_code_keyval_entry_type_id__volatile)) {
		GType skk_key_event_code_keyval_entry_type_id;
		skk_key_event_code_keyval_entry_type_id = g_boxed_type_register_static ("SkkKeyEventCodeKeyvalEntry", (GBoxedCopyFunc) skk_key_event_code_keyval_entry_dup, (GBoxedFreeFunc) skk_key_event_code_keyval_entry_free);
		g_once_init_leave (&skk_key_event_code_keyval_entry_type_id__volatile, skk_key_event_code_keyval_entry_type_id);
	}
	return skk_key_event_code_keyval_entry_type_id__volatile;
}


static void skk_key_event_name_keyval_entry_copy (const SkkKeyEventNameKeyvalEntry* self, SkkKeyEventNameKeyvalEntry* dest) {
	guint _tmp0_;
	const gchar* _tmp1_;
	gchar* _tmp2_;
	_tmp0_ = (*self).key;
	(*dest).key = _tmp0_;
	_tmp1_ = (*self).value;
	_tmp2_ = g_strdup (_tmp1_);
	_g_free0 ((*dest).value);
	(*dest).value = _tmp2_;
}


static void skk_key_event_name_keyval_entry_destroy (SkkKeyEventNameKeyvalEntry* self) {
	_g_free0 ((*self).value);
}


static SkkKeyEventNameKeyvalEntry* skk_key_event_name_keyval_entry_dup (const SkkKeyEventNameKeyvalEntry* self) {
	SkkKeyEventNameKeyvalEntry* dup;
	dup = g_new0 (SkkKeyEventNameKeyvalEntry, 1);
	skk_key_event_name_keyval_entry_copy (self, dup);
	return dup;
}


static void skk_key_event_name_keyval_entry_free (SkkKeyEventNameKeyvalEntry* self) {
	skk_key_event_name_keyval_entry_destroy (self);
	g_free (self);
}


static GType skk_key_event_name_keyval_entry_get_type (void) {
	static volatile gsize skk_key_event_name_keyval_entry_type_id__volatile = 0;
	if (g_once_init_enter (&skk_key_event_name_keyval_entry_type_id__volatile)) {
		GType skk_key_event_name_keyval_entry_type_id;
		skk_key_event_name_keyval_entry_type_id = g_boxed_type_register_static ("SkkKeyEventNameKeyvalEntry", (GBoxedCopyFunc) skk_key_event_name_keyval_entry_dup, (GBoxedFreeFunc) skk_key_event_name_keyval_entry_free);
		g_once_init_leave (&skk_key_event_name_keyval_entry_type_id__volatile, skk_key_event_name_keyval_entry_type_id);
	}
	return skk_key_event_name_keyval_entry_type_id__volatile;
}


static void skk_key_event_class_init (SkkKeyEventClass * klass) {
	skk_key_event_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (SkkKeyEventPrivate));
	G_OBJECT_CLASS (klass)->get_property = _vala_skk_key_event_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_skk_key_event_set_property;
	G_OBJECT_CLASS (klass)->finalize = skk_key_event_finalize;
	/**
	         * The base name of the KeyEvent.
	         *
	         * This is exclusive to {@link code}.
	         */
	g_object_class_install_property (G_OBJECT_CLASS (klass), SKK_KEY_EVENT_NAME, g_param_spec_string ("name", "name", "name", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
	/**
	         * The base code of the KeyEvent.
	         *
	         * This is exclusive to {@link name}.
	         */
	g_object_class_install_property (G_OBJECT_CLASS (klass), SKK_KEY_EVENT_CODE, g_param_spec_uint ("code", "code", "code", 0, G_MAXUINT, 0U, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
	/**
	         * Modifier mask.
	         */
	g_object_class_install_property (G_OBJECT_CLASS (klass), SKK_KEY_EVENT_MODIFIERS, g_param_spec_enum ("modifiers", "modifiers", "modifiers", SKK_TYPE_MODIFIER_TYPE, 0, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
}


static void skk_key_event_instance_init (SkkKeyEvent * self) {
	self->priv = SKK_KEY_EVENT_GET_PRIVATE (self);
}


static void skk_key_event_finalize (GObject* obj) {
	SkkKeyEvent * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, SKK_TYPE_KEY_EVENT, SkkKeyEvent);
	_g_free0 (self->priv->_name);
	G_OBJECT_CLASS (skk_key_event_parent_class)->finalize (obj);
}


/**
     * Object representing a key event.
     */
GType skk_key_event_get_type (void) {
	static volatile gsize skk_key_event_type_id__volatile = 0;
	if (g_once_init_enter (&skk_key_event_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (SkkKeyEventClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) skk_key_event_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SkkKeyEvent), 0, (GInstanceInitFunc) skk_key_event_instance_init, NULL };
		GType skk_key_event_type_id;
		skk_key_event_type_id = g_type_register_static (G_TYPE_OBJECT, "SkkKeyEvent", &g_define_type_info, 0);
		g_once_init_leave (&skk_key_event_type_id__volatile, skk_key_event_type_id);
	}
	return skk_key_event_type_id__volatile;
}


static void _vala_skk_key_event_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
	SkkKeyEvent * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, SKK_TYPE_KEY_EVENT, SkkKeyEvent);
	switch (property_id) {
		case SKK_KEY_EVENT_NAME:
		g_value_set_string (value, skk_key_event_get_name (self));
		break;
		case SKK_KEY_EVENT_CODE:
		g_value_set_uint (value, skk_key_event_get_code (self));
		break;
		case SKK_KEY_EVENT_MODIFIERS:
		g_value_set_enum (value, skk_key_event_get_modifiers (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}


static void _vala_skk_key_event_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
	SkkKeyEvent * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, SKK_TYPE_KEY_EVENT, SkkKeyEvent);
	switch (property_id) {
		case SKK_KEY_EVENT_NAME:
		skk_key_event_set_name (self, g_value_get_string (value));
		break;
		case SKK_KEY_EVENT_CODE:
		skk_key_event_set_code (self, g_value_get_uint (value));
		break;
		case SKK_KEY_EVENT_MODIFIERS:
		skk_key_event_set_modifiers (self, g_value_get_enum (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}


static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	if ((array != NULL) && (destroy_func != NULL)) {
		int i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}


static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}


static gint _vala_array_length (gpointer array) {
	int length;
	length = 0;
	if (array) {
		while (((gpointer*) array)[length]) {
			length++;
		}
	}
	return length;
}



