/* xadapter.c generated by valac 0.32.0.49-00a57, the Vala compiler
 * generated from xadapter.vala, do not modify */


#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/Xregion.h>
#include <X11/XKBlib.h>
#include <libxklavier/xklavier.h>
#include <gee.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <X11/extensions/XTest.h>
#include <gobject/gvaluecollector.h>


#define CARIBOU_TYPE_DISPLAY_ADAPTER (caribou_display_adapter_get_type ())
#define CARIBOU_DISPLAY_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CARIBOU_TYPE_DISPLAY_ADAPTER, CaribouDisplayAdapter))
#define CARIBOU_DISPLAY_ADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CARIBOU_TYPE_DISPLAY_ADAPTER, CaribouDisplayAdapterClass))
#define CARIBOU_IS_DISPLAY_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CARIBOU_TYPE_DISPLAY_ADAPTER))
#define CARIBOU_IS_DISPLAY_ADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CARIBOU_TYPE_DISPLAY_ADAPTER))
#define CARIBOU_DISPLAY_ADAPTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CARIBOU_TYPE_DISPLAY_ADAPTER, CaribouDisplayAdapterClass))

typedef struct _CaribouDisplayAdapter CaribouDisplayAdapter;
typedef struct _CaribouDisplayAdapterClass CaribouDisplayAdapterClass;
typedef struct _CaribouDisplayAdapterPrivate CaribouDisplayAdapterPrivate;

#define CARIBOU_TYPE_XADAPTER (caribou_xadapter_get_type ())
#define CARIBOU_XADAPTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CARIBOU_TYPE_XADAPTER, CaribouXAdapter))
#define CARIBOU_XADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CARIBOU_TYPE_XADAPTER, CaribouXAdapterClass))
#define CARIBOU_IS_XADAPTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CARIBOU_TYPE_XADAPTER))
#define CARIBOU_IS_XADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CARIBOU_TYPE_XADAPTER))
#define CARIBOU_XADAPTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CARIBOU_TYPE_XADAPTER, CaribouXAdapterClass))

typedef struct _CaribouXAdapter CaribouXAdapter;
typedef struct _CaribouXAdapterClass CaribouXAdapterClass;
typedef struct _CaribouXAdapterPrivate CaribouXAdapterPrivate;

#define CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER (caribou_xadapter_key_button_handler_get_type ())
#define CARIBOU_XADAPTER_KEY_BUTTON_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER, CaribouXAdapterKeyButtonHandler))
#define CARIBOU_XADAPTER_KEY_BUTTON_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER, CaribouXAdapterKeyButtonHandlerClass))
#define CARIBOU_XADAPTER_IS_KEY_BUTTON_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER))
#define CARIBOU_XADAPTER_IS_KEY_BUTTON_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER))
#define CARIBOU_XADAPTER_KEY_BUTTON_HANDLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER, CaribouXAdapterKeyButtonHandlerClass))

typedef struct _CaribouXAdapterKeyButtonHandler CaribouXAdapterKeyButtonHandler;
typedef struct _CaribouXAdapterKeyButtonHandlerClass CaribouXAdapterKeyButtonHandlerClass;
#define _0(var) ((var == NULL) ? NULL : (var = ( (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _caribou_xadapter_key_button_handler_unref0(var) ((var == NULL) ? NULL : (var = (caribou_xadapter_key_button_handler_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _CaribouXAdapterKeyButtonHandlerPrivate CaribouXAdapterKeyButtonHandlerPrivate;
typedef struct _CaribouXAdapterParamSpecKeyButtonHandler CaribouXAdapterParamSpecKeyButtonHandler;

typedef void (*CaribouKeyButtonCallback) (guint keybuttoncode, gboolean pressed, void* user_data);
struct _CaribouDisplayAdapter {
	GObject parent_instance;
	CaribouDisplayAdapterPrivate * priv;
};

struct _CaribouDisplayAdapterClass {
	GObjectClass parent_class;
	void (*keyval_press) (CaribouDisplayAdapter* self, guint keyval);
	void (*keyval_release) (CaribouDisplayAdapter* self, guint keyval);
	void (*mod_lock) (CaribouDisplayAdapter* self, guint mask);
	void (*mod_unlock) (CaribouDisplayAdapter* self, guint mask);
	void (*mod_latch) (CaribouDisplayAdapter* self, guint mask);
	void (*mod_unlatch) (CaribouDisplayAdapter* self, guint mask);
	guint (*get_current_group) (CaribouDisplayAdapter* self, gchar** group_name, gchar** variant_name);
	void (*get_groups) (CaribouDisplayAdapter* self, gchar*** group_names, int* group_names_length1, gchar*** variant_names, int* variant_names_length1);
	void (*register_key_func) (CaribouDisplayAdapter* self, guint keyval, CaribouKeyButtonCallback func, void* func_target);
	void (*register_button_func) (CaribouDisplayAdapter* self, guint button, CaribouKeyButtonCallback func, void* func_target);
};

struct _CaribouXAdapter {
	CaribouDisplayAdapter parent_instance;
	CaribouXAdapterPrivate * priv;
};

struct _CaribouXAdapterClass {
	CaribouDisplayAdapterClass parent_class;
};

struct _CaribouXAdapterPrivate {
	Display* xdisplay;
	XID xid;
	XkbDescRec* xkbdesc;
	XklEngine* xkl_engine;
	guint reserved_keysym;
	guchar reserved_keycode;
	guchar modifiers;
	guchar group;
	guint* level_switch_modifiers;
	gint level_switch_modifiers_length1;
	gint _level_switch_modifiers_size_;
	GeeHashMap* button_funcs;
	GeeHashMap* key_funcs;
};

struct _CaribouXAdapterKeyButtonHandler {
	GTypeInstance parent_instance;
	volatile int ref_count;
	CaribouXAdapterKeyButtonHandlerPrivate * priv;
};

struct _CaribouXAdapterKeyButtonHandlerClass {
	GTypeClass parent_class;
	void (*finalize) (CaribouXAdapterKeyButtonHandler *self);
};

struct _CaribouXAdapterKeyButtonHandlerPrivate {
	CaribouKeyButtonCallback _cb;
	gpointer _cb_target;
};

struct _CaribouXAdapterParamSpecKeyButtonHandler {
	GParamSpec parent_instance;
};


static gpointer caribou_xadapter_parent_class = NULL;
static gpointer caribou_xadapter_key_button_handler_parent_class = NULL;

GType caribou_display_adapter_get_type (void) G_GNUC_CONST;
GType caribou_xadapter_get_type (void) G_GNUC_CONST;
static gpointer caribou_xadapter_key_button_handler_ref (gpointer instance);
static void caribou_xadapter_key_button_handler_unref (gpointer instance);
static GParamSpec* caribou_xadapter_param_spec_key_button_handler (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) G_GNUC_UNUSED;
static void caribou_xadapter_value_set_key_button_handler (GValue* value, gpointer v_object) G_GNUC_UNUSED;
static void caribou_xadapter_value_take_key_button_handler (GValue* value, gpointer v_object) G_GNUC_UNUSED;
static gpointer caribou_xadapter_value_get_key_button_handler (const GValue* value) G_GNUC_UNUSED;
static GType caribou_xadapter_key_button_handler_get_type (void) G_GNUC_CONST G_GNUC_UNUSED;
#define CARIBOU_XADAPTER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CARIBOU_TYPE_XADAPTER, CaribouXAdapterPrivate))
enum  {
	CARIBOU_XADAPTER_DUMMY_PROPERTY
};
static gboolean caribou_xadapter_set_slowkeys_enabled (CaribouXAdapter* self, gboolean enable);
static GdkFilterReturn caribou_xadapter_x_event_filter (CaribouXAdapter* self, GdkXEvent* xevent, GdkEvent* event);
static CaribouKeyButtonCallback caribou_xadapter_key_button_handler_get_cb (CaribouXAdapterKeyButtonHandler* self, gpointer* result_target);
static void caribou_xadapter_xkl_state_changed (CaribouXAdapter* self, gint type, gint group, gboolean restore);
guint caribou_display_adapter_get_current_group (CaribouDisplayAdapter* self, gchar** group_name, gchar** variant_name);
static void caribou_xadapter_xkl_config_changed (CaribouXAdapter* self);
static guchar caribou_xadapter_keysym_to_modifier (CaribouXAdapter* self, guint keyval);
static guchar caribou_xadapter_get_reserved_keycode (CaribouXAdapter* self);
static void caribou_xadapter_replace_keycode (CaribouXAdapter* self, guint keysym);
static gboolean caribou_xadapter_reset_reserved (CaribouXAdapter* self);
static gboolean _caribou_xadapter_reset_reserved_gsource_func (gpointer self);
static gboolean caribou_xadapter_best_keycode_keyval_match (CaribouXAdapter* self, guint keyval, guchar* keycode, guint* modmask);
static GdkKeymapKey* _gdk_keymap_key_dup (GdkKeymapKey* self);
static guchar caribou_xadapter_keycode_for_keyval (CaribouXAdapter* self, guint keyval, guint* modmask);
static void caribou_xadapter_real_keyval_press (CaribouDisplayAdapter* base, guint keyval);
void caribou_display_adapter_mod_latch (CaribouDisplayAdapter* self, guint mask);
static void caribou_xadapter_real_keyval_release (CaribouDisplayAdapter* base, guint keyval);
static void caribou_xadapter_real_mod_lock (CaribouDisplayAdapter* base, guint mask);
static void caribou_xadapter_real_mod_unlock (CaribouDisplayAdapter* base, guint mask);
static void caribou_xadapter_real_mod_latch (CaribouDisplayAdapter* base, guint mask);
static void caribou_xadapter_real_mod_unlatch (CaribouDisplayAdapter* base, guint mask);
static guint caribou_xadapter_real_get_current_group (CaribouDisplayAdapter* base, gchar** group_name, gchar** variant_name);
static void caribou_xadapter_real_get_groups (CaribouDisplayAdapter* base, gchar*** group_names, int* group_names_length1, gchar*** variant_names, int* variant_names_length1);
static void caribou_xadapter_real_register_key_func (CaribouDisplayAdapter* base, guint keyval, CaribouKeyButtonCallback func, void* func_target);
static CaribouXAdapterKeyButtonHandler* caribou_xadapter_key_button_handler_new (CaribouKeyButtonCallback cb, void* cb_target);
static CaribouXAdapterKeyButtonHandler* caribou_xadapter_key_button_handler_construct (GType object_type, CaribouKeyButtonCallback cb, void* cb_target);
static void caribou_xadapter_real_register_button_func (CaribouDisplayAdapter* base, guint button, CaribouKeyButtonCallback func, void* func_target);
CaribouXAdapter* caribou_xadapter_new (void);
CaribouXAdapter* caribou_xadapter_construct (GType object_type);
CaribouDisplayAdapter* caribou_display_adapter_construct (GType object_type);
static GObject * caribou_xadapter_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties);
static void _caribou_xadapter_xkl_state_changed_xkl_engine_X_state_changed (XklEngine* _sender, gint p0, gint p1, gboolean p2, gpointer self);
static void _caribou_xadapter_xkl_config_changed_xkl_engine_X_config_changed (XklEngine* _sender, gpointer self);
static void _vala_array_add1 (guint** array, int* length, int* size, guint value);
static void _vala_array_add2 (guint** array, int* length, int* size, guint value);
static GdkFilterReturn _caribou_xadapter_x_event_filter_gdk_filter_func (GdkXEvent* xevent, GdkEvent* event, gpointer self);
#define CARIBOU_XADAPTER_KEY_BUTTON_HANDLER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER, CaribouXAdapterKeyButtonHandlerPrivate))
enum  {
	CARIBOU_XADAPTER_KEY_BUTTON_HANDLER_DUMMY_PROPERTY
};
static void caribou_xadapter_key_button_handler_set_cb (CaribouXAdapterKeyButtonHandler* self, CaribouKeyButtonCallback value, gpointer value_target);
static void caribou_xadapter_key_button_handler_finalize (CaribouXAdapterKeyButtonHandler* obj);
static void caribou_xadapter_finalize (GObject* obj);
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 gboolean caribou_xadapter_set_slowkeys_enabled (CaribouXAdapter* self, gboolean enable) {
	gboolean result = FALSE;
	Display* _tmp0_ = NULL;
	gint _tmp1_ = 0;
	XkbDescRec* _tmp2_ = NULL;
	gboolean previous = FALSE;
	XkbDescRec* _tmp3_ = NULL;
	XkbControlsRec* _tmp4_ = NULL;
	guint _tmp5_ = 0U;
	gint _tmp6_ = 0;
	gboolean _tmp7_ = FALSE;
	Display* _tmp20_ = NULL;
	gint _tmp21_ = 0;
	gint _tmp22_ = 0;
	XkbDescRec* _tmp23_ = NULL;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->xdisplay;
	_tmp1_ = XkbAllControlsMask;
	_tmp2_ = self->priv->xkbdesc;
	XkbGetControls (_tmp0_, (guint) _tmp1_, _tmp2_);
	_tmp3_ = self->priv->xkbdesc;
	_tmp4_ = _tmp3_->ctrls;
	_tmp5_ = _tmp4_->enabled_ctrls;
	_tmp6_ = XkbSlowKeysMask;
	previous = (_tmp5_ & _tmp6_) != ((guint) 0);
	_tmp7_ = enable;
	if (_tmp7_) {
		XkbDescRec* _tmp8_ = NULL;
		XkbControlsRec* _tmp9_ = NULL;
		XkbDescRec* _tmp10_ = NULL;
		XkbControlsRec* _tmp11_ = NULL;
		guint _tmp12_ = 0U;
		gint _tmp13_ = 0;
		_tmp8_ = self->priv->xkbdesc;
		_tmp9_ = _tmp8_->ctrls;
		_tmp10_ = self->priv->xkbdesc;
		_tmp11_ = _tmp10_->ctrls;
		_tmp12_ = _tmp11_->enabled_ctrls;
		_tmp13_ = XkbSlowKeysMask;
		_tmp11_->enabled_ctrls = _tmp12_ | _tmp13_;
	} else {
		XkbDescRec* _tmp14_ = NULL;
		XkbControlsRec* _tmp15_ = NULL;
		XkbDescRec* _tmp16_ = NULL;
		XkbControlsRec* _tmp17_ = NULL;
		guint _tmp18_ = 0U;
		gint _tmp19_ = 0;
		_tmp14_ = self->priv->xkbdesc;
		_tmp15_ = _tmp14_->ctrls;
		_tmp16_ = self->priv->xkbdesc;
		_tmp17_ = _tmp16_->ctrls;
		_tmp18_ = _tmp17_->enabled_ctrls;
		_tmp19_ = XkbSlowKeysMask;
		_tmp17_->enabled_ctrls = _tmp18_ & (~_tmp19_);
	}
	_tmp20_ = self->priv->xdisplay;
	_tmp21_ = XkbSlowKeysMask;
	_tmp22_ = XkbControlsEnabledMask;
	_tmp23_ = self->priv->xkbdesc;
	XkbSetControls (_tmp20_, (guint) (_tmp21_ | _tmp22_), _tmp23_);
	result = previous;
	return result;
}


static GdkFilterReturn caribou_xadapter_x_event_filter (CaribouXAdapter* self, GdkXEvent* xevent, GdkEvent* event) {
	GdkFilterReturn result = 0;
	void* pointer = NULL;
	GdkXEvent* _tmp0_ = NULL;
	XkbEvent* xkbev = NULL;
	void* _tmp1_ = NULL;
	XEvent* xev = NULL;
	void* _tmp2_ = NULL;
	XklEngine* _tmp3_ = NULL;
	XEvent* _tmp4_ = NULL;
	gboolean _tmp5_ = FALSE;
	XEvent* _tmp6_ = NULL;
	gint _tmp7_ = 0;
	g_return_val_if_fail (self != NULL, 0);
	g_return_val_if_fail (xevent != NULL, 0);
	g_return_val_if_fail (event != NULL, 0);
	_tmp0_ = xevent;
	pointer = _tmp0_;
	_tmp1_ = pointer;
	xkbev = (XkbEvent*) _tmp1_;
	_tmp2_ = pointer;
	xev = (XEvent*) _tmp2_;
	_tmp3_ = self->priv->xkl_engine;
	_tmp4_ = xev;
	xkl_engine_filter_events (_tmp3_, _tmp4_);
	_tmp6_ = xev;
	_tmp7_ = (*_tmp6_).type;
	if (_tmp7_ == ((gint) ButtonPress)) {
		_tmp5_ = TRUE;
	} else {
		XEvent* _tmp8_ = NULL;
		gint _tmp9_ = 0;
		_tmp8_ = xev;
		_tmp9_ = (*_tmp8_).type;
		_tmp5_ = _tmp9_ == ((gint) ButtonRelease);
	}
	if (_tmp5_) {
		CaribouXAdapterKeyButtonHandler* handler = NULL;
		GeeHashMap* _tmp10_ = NULL;
		XEvent* _tmp11_ = NULL;
		XButtonEvent _tmp12_ = {0};
		guint _tmp13_ = 0U;
		gpointer _tmp14_ = NULL;
		CaribouXAdapterKeyButtonHandler* _tmp15_ = NULL;
		_tmp10_ = self->priv->button_funcs;
		_tmp11_ = xev;
		_tmp12_ = (*_tmp11_).xbutton;
		_tmp13_ = _tmp12_.button;
		_tmp14_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp10_, (gpointer) ((guintptr) _tmp13_));
		handler = G_TYPE_CHECK_INSTANCE_CAST ((CaribouXAdapterKeyButtonHandler*) _tmp14_, CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER, CaribouXAdapterKeyButtonHandler);
		_tmp15_ = handler;
		if (_tmp15_ != NULL) {
			CaribouXAdapterKeyButtonHandler* _tmp16_ = NULL;
			CaribouKeyButtonCallback _tmp17_ = NULL;
			void* _tmp17__target = NULL;
			CaribouKeyButtonCallback _tmp18_ = NULL;
			void* _tmp18__target = NULL;
			XEvent* _tmp19_ = NULL;
			XButtonEvent _tmp20_ = {0};
			guint _tmp21_ = 0U;
			XEvent* _tmp22_ = NULL;
			gint _tmp23_ = 0;
			_tmp16_ = handler;
			_tmp17_ = caribou_xadapter_key_button_handler_get_cb (_tmp16_, &_tmp17__target);
			_tmp18_ = _tmp17_;
			_tmp18__target = _tmp17__target;
			_tmp19_ = xev;
			_tmp20_ = (*_tmp19_).xbutton;
			_tmp21_ = _tmp20_.button;
			_tmp22_ = xev;
			_tmp23_ = (*_tmp22_).type;
			_tmp18_ (_tmp21_, _tmp23_ == ((gint) ButtonPress), _tmp18__target);
		}
		_caribou_xadapter_key_button_handler_unref0 (handler);
	} else {
		gboolean _tmp24_ = FALSE;
		XEvent* _tmp25_ = NULL;
		gint _tmp26_ = 0;
		_tmp25_ = xev;
		_tmp26_ = (*_tmp25_).type;
		if (_tmp26_ == ((gint) KeyPress)) {
			_tmp24_ = TRUE;
		} else {
			XEvent* _tmp27_ = NULL;
			gint _tmp28_ = 0;
			_tmp27_ = xev;
			_tmp28_ = (*_tmp27_).type;
			_tmp24_ = _tmp28_ == ((gint) KeyRelease);
		}
		if (_tmp24_) {
			CaribouXAdapterKeyButtonHandler* handler = NULL;
			GeeHashMap* _tmp29_ = NULL;
			XEvent* _tmp30_ = NULL;
			XKeyEvent _tmp31_ = {0};
			guint _tmp32_ = 0U;
			gpointer _tmp33_ = NULL;
			CaribouXAdapterKeyButtonHandler* _tmp34_ = NULL;
			_tmp29_ = self->priv->key_funcs;
			_tmp30_ = xev;
			_tmp31_ = (*_tmp30_).xkey;
			_tmp32_ = _tmp31_.keycode;
			_tmp33_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp29_, (gpointer) ((guintptr) _tmp32_));
			handler = G_TYPE_CHECK_INSTANCE_CAST ((CaribouXAdapterKeyButtonHandler*) _tmp33_, CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER, CaribouXAdapterKeyButtonHandler);
			_tmp34_ = handler;
			if (_tmp34_ != NULL) {
				CaribouXAdapterKeyButtonHandler* _tmp35_ = NULL;
				CaribouKeyButtonCallback _tmp36_ = NULL;
				void* _tmp36__target = NULL;
				CaribouKeyButtonCallback _tmp37_ = NULL;
				void* _tmp37__target = NULL;
				XEvent* _tmp38_ = NULL;
				XKeyEvent _tmp39_ = {0};
				guint _tmp40_ = 0U;
				XEvent* _tmp41_ = NULL;
				gint _tmp42_ = 0;
				_tmp35_ = handler;
				_tmp36_ = caribou_xadapter_key_button_handler_get_cb (_tmp35_, &_tmp36__target);
				_tmp37_ = _tmp36_;
				_tmp37__target = _tmp36__target;
				_tmp38_ = xev;
				_tmp39_ = (*_tmp38_).xkey;
				_tmp40_ = _tmp39_.keycode;
				_tmp41_ = xev;
				_tmp42_ = (*_tmp41_).type;
				_tmp37_ (_tmp40_, _tmp42_ == ((gint) KeyPress), _tmp37__target);
			}
			_caribou_xadapter_key_button_handler_unref0 (handler);
		} else {
			XkbEvent* _tmp43_ = NULL;
			XkbAnyEvent _tmp44_ = {0};
			gint _tmp45_ = 0;
			gint _tmp46_ = 0;
			_tmp43_ = xkbev;
			_tmp44_ = (*_tmp43_).any;
			_tmp45_ = _tmp44_.xkb_type;
			_tmp46_ = XkbStateNotify;
			if (_tmp45_ == _tmp46_) {
				XkbStateNotifyEvent* sevent = NULL;
				XkbStateNotifyEvent* _tmp47_ = NULL;
				guint _tmp48_ = 0U;
				gint _tmp49_ = 0;
				sevent = &(*xkbev).state;
				_tmp47_ = sevent;
				_tmp48_ = (*_tmp47_).changed;
				_tmp49_ = XkbModifierStateMask;
				if ((_tmp48_ & _tmp49_) != ((guint) 0)) {
					XkbStateNotifyEvent* _tmp50_ = NULL;
					guint _tmp51_ = 0U;
					_tmp50_ = sevent;
					_tmp51_ = (*_tmp50_).mods;
					self->priv->modifiers = (guchar) _tmp51_;
				}
			}
		}
	}
	result = GDK_FILTER_CONTINUE;
	return result;
}


static void caribou_xadapter_xkl_state_changed (CaribouXAdapter* self, gint type, gint group, gboolean restore) {
	gchar* group_name = NULL;
	gchar* variant_name = NULL;
	gint _tmp0_ = 0;
	gchar* _tmp1_ = NULL;
	gchar* _tmp2_ = NULL;
	guchar _tmp3_ = '\0';
	g_return_if_fail (self != NULL);
	_tmp0_ = group;
	self->priv->group = (guchar) _tmp0_;
	caribou_display_adapter_get_current_group ((CaribouDisplayAdapter*) self, &_tmp1_, &_tmp2_);
	_g_free0 (group_name);
	group_name = _tmp1_;
	_g_free0 (variant_name);
	variant_name = _tmp2_;
	_tmp3_ = self->priv->group;
	g_signal_emit_by_name ((CaribouDisplayAdapter*) self, "group-changed", (guint) _tmp3_, group_name, variant_name);
	_g_free0 (variant_name);
	_g_free0 (group_name);
}


static void caribou_xadapter_xkl_config_changed (CaribouXAdapter* self) {
	g_return_if_fail (self != NULL);
	g_signal_emit_by_name ((CaribouDisplayAdapter*) self, "config-changed");
}


static guchar caribou_xadapter_keysym_to_modifier (CaribouXAdapter* self, guint keyval) {
	guchar result = '\0';
	g_return_val_if_fail (self != NULL, '\0');
	{
		gint i = 0;
		XkbDescRec* _tmp0_ = NULL;
		guchar _tmp1_ = '\0';
		_tmp0_ = self->priv->xkbdesc;
		_tmp1_ = _tmp0_->min_key_code;
		i = (gint) _tmp1_;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				gint _tmp4_ = 0;
				XkbDescRec* _tmp5_ = NULL;
				guchar _tmp6_ = '\0';
				XkbSymMapRec symmap = {0};
				XkbDescRec* _tmp7_ = NULL;
				XkbClientMapRec* _tmp8_ = NULL;
				XkbSymMapRec* _tmp9_ = NULL;
				gint _tmp9__length1 = 0;
				gint _tmp10_ = 0;
				XkbSymMapRec _tmp11_ = {0};
				if (!_tmp2_) {
					gint _tmp3_ = 0;
					_tmp3_ = i;
					i = _tmp3_ + 1;
				}
				_tmp2_ = FALSE;
				_tmp4_ = i;
				_tmp5_ = self->priv->xkbdesc;
				_tmp6_ = _tmp5_->max_key_code;
				if (!(_tmp4_ <= ((gint) _tmp6_))) {
					break;
				}
				_tmp7_ = self->priv->xkbdesc;
				_tmp8_ = _tmp7_->map;
				_tmp9_ = _tmp8_->key_sym_map;
				_tmp9__length1 = _vala_array_length (_tmp8_->key_sym_map);
				_tmp10_ = i;
				_tmp11_ = _tmp9_[_tmp10_];
				symmap = _tmp11_;
				{
					gint j = 0;
					j = 0;
					{
						gboolean _tmp12_ = FALSE;
						_tmp12_ = TRUE;
						while (TRUE) {
							gint _tmp14_ = 0;
							XkbSymMapRec _tmp15_ = {0};
							guchar _tmp16_ = '\0';
							XkbSymMapRec _tmp17_ = {0};
							guchar _tmp18_ = '\0';
							XkbDescRec* _tmp19_ = NULL;
							XkbClientMapRec* _tmp20_ = NULL;
							gulong* _tmp21_ = NULL;
							gint _tmp21__length1 = 0;
							XkbSymMapRec _tmp22_ = {0};
							gushort _tmp23_ = 0U;
							gint _tmp24_ = 0;
							gulong _tmp25_ = 0UL;
							guint _tmp26_ = 0U;
							if (!_tmp12_) {
								gint _tmp13_ = 0;
								_tmp13_ = j;
								j = _tmp13_ + 1;
							}
							_tmp12_ = FALSE;
							_tmp14_ = j;
							_tmp15_ = symmap;
							_tmp16_ = _tmp15_.width;
							_tmp17_ = symmap;
							_tmp18_ = _tmp17_.group_info;
							if (!(_tmp14_ < ((gint) (_tmp16_ * (_tmp18_ & 0x0f))))) {
								break;
							}
							_tmp19_ = self->priv->xkbdesc;
							_tmp20_ = _tmp19_->map;
							_tmp21_ = _tmp20_->syms;
							_tmp21__length1 = _vala_array_length (_tmp20_->syms);
							_tmp22_ = symmap;
							_tmp23_ = _tmp22_.offset;
							_tmp24_ = j;
							_tmp25_ = _tmp21_[_tmp23_ + _tmp24_];
							_tmp26_ = keyval;
							if (_tmp25_ == ((gulong) _tmp26_)) {
								XkbDescRec* _tmp27_ = NULL;
								XkbClientMapRec* _tmp28_ = NULL;
								guchar* _tmp29_ = NULL;
								gint _tmp29__length1 = 0;
								gint _tmp30_ = 0;
								guchar _tmp31_ = '\0';
								_tmp27_ = self->priv->xkbdesc;
								_tmp28_ = _tmp27_->map;
								_tmp29_ = _tmp28_->modmap;
								_tmp29__length1 = _vala_array_length (_tmp28_->modmap);
								_tmp30_ = i;
								_tmp31_ = _tmp29_[_tmp30_];
								result = _tmp31_;
								return result;
							}
						}
					}
				}
			}
		}
	}
	result = (guchar) 0;
	return result;
}


static guchar caribou_xadapter_get_reserved_keycode (CaribouXAdapter* self) {
	guchar result = '\0';
	gint i = 0;
	XkbDescRec* xkbdesc = NULL;
	XkbDescRec* _tmp0_ = NULL;
	Display* _tmp27_ = NULL;
	guchar _tmp28_ = '\0';
	g_return_val_if_fail (self != NULL, '\0');
	_tmp0_ = self->priv->xkbdesc;
	xkbdesc = _tmp0_;
	{
		XkbDescRec* _tmp1_ = NULL;
		guchar _tmp2_ = '\0';
		gboolean _tmp3_ = FALSE;
		_tmp1_ = xkbdesc;
		_tmp2_ = _tmp1_->max_key_code;
		i = (gint) _tmp2_;
		_tmp3_ = TRUE;
		while (TRUE) {
			gint _tmp5_ = 0;
			XkbDescRec* _tmp6_ = NULL;
			guchar _tmp7_ = '\0';
			XkbDescRec* _tmp8_ = NULL;
			XkbClientMapRec* _tmp9_ = NULL;
			XkbSymMapRec* _tmp10_ = NULL;
			gint _tmp10__length1 = 0;
			gint _tmp11_ = 0;
			XkbSymMapRec _tmp12_ = {0};
			guchar _tmp13_ = '\0';
			gint _tmp14_ = 0;
			if (!_tmp3_) {
				gint _tmp4_ = 0;
				_tmp4_ = i;
				i = _tmp4_ - 1;
			}
			_tmp3_ = FALSE;
			_tmp5_ = i;
			_tmp6_ = xkbdesc;
			_tmp7_ = _tmp6_->min_key_code;
			if (!(_tmp5_ >= ((gint) _tmp7_))) {
				break;
			}
			_tmp8_ = xkbdesc;
			_tmp9_ = _tmp8_->map;
			_tmp10_ = _tmp9_->key_sym_map;
			_tmp10__length1 = _vala_array_length (_tmp9_->key_sym_map);
			_tmp11_ = i;
			_tmp12_ = _tmp10_[_tmp11_];
			_tmp13_ = _tmp12_.kt_index[0];
			_tmp14_ = XkbOneLevelIndex;
			if (((gint) _tmp13_) == _tmp14_) {
				Display* _tmp15_ = NULL;
				gint _tmp16_ = 0;
				gulong _tmp17_ = 0UL;
				_tmp15_ = self->priv->xdisplay;
				_tmp16_ = i;
				_tmp17_ = XKeycodeToKeysym (_tmp15_, (guchar) _tmp16_, 0);
				if (_tmp17_ != ((gulong) 0)) {
					Display* _tmp18_ = NULL;
					gint _tmp19_ = 0;
					Window _tmp20_ = 0;
					Display* _tmp21_ = NULL;
					Display* _tmp22_ = NULL;
					gint _tmp23_ = 0;
					Window _tmp24_ = 0;
					gint _tmp25_ = 0;
					gdk_error_trap_push ();
					_tmp18_ = self->priv->xdisplay;
					_tmp19_ = i;
					_tmp20_ = gdk_x11_get_default_root_xwindow ();
					XGrabKey (_tmp18_, _tmp19_, (guint) 0, _tmp20_, TRUE, (gint) GrabModeSync, (gint) GrabModeSync);
					_tmp21_ = self->priv->xdisplay;
					XFlush (_tmp21_);
					_tmp22_ = self->priv->xdisplay;
					_tmp23_ = i;
					_tmp24_ = gdk_x11_get_default_root_xwindow ();
					XUngrabKey (_tmp22_, _tmp23_, (guint) 0, _tmp24_);
					_tmp25_ = gdk_error_trap_pop ();
					if (_tmp25_ == 0) {
						gint _tmp26_ = 0;
						_tmp26_ = i;
						result = (guchar) _tmp26_;
						return result;
					}
				}
			}
		}
	}
	_tmp27_ = self->priv->xdisplay;
	_tmp28_ = XKeysymToKeycode (_tmp27_, (gulong) 0x0023);
	result = (guchar) _tmp28_;
	return result;
}


static gboolean _caribou_xadapter_reset_reserved_gsource_func (gpointer self) {
	gboolean result;
	result = caribou_xadapter_reset_reserved ((CaribouXAdapter*) self);
	return result;
}


static void caribou_xadapter_replace_keycode (CaribouXAdapter* self, guint keysym) {
	guchar _tmp0_ = '\0';
	Display* _tmp5_ = NULL;
	guint offset = 0U;
	XkbDescRec* _tmp6_ = NULL;
	XkbClientMapRec* _tmp7_ = NULL;
	XkbSymMapRec* _tmp8_ = NULL;
	gint _tmp8__length1 = 0;
	guchar _tmp9_ = '\0';
	XkbSymMapRec _tmp10_ = {0};
	gushort _tmp11_ = 0U;
	XkbDescRec* _tmp12_ = NULL;
	XkbClientMapRec* _tmp13_ = NULL;
	gulong* _tmp14_ = NULL;
	gint _tmp14__length1 = 0;
	guint _tmp15_ = 0U;
	guint _tmp16_ = 0U;
	gulong _tmp17_ = 0UL;
	XkbDescRec* _tmp18_ = NULL;
	gint _tmp19_ = 0;
	XkbMapChangesRec changes = {0};
	gint _tmp20_ = 0;
	gint _tmp21_ = 0;
	guchar _tmp22_ = '\0';
	XkbDescRec* _tmp23_ = NULL;
	XkbClientMapRec* _tmp24_ = NULL;
	XkbSymMapRec* _tmp25_ = NULL;
	gint _tmp25__length1 = 0;
	guchar _tmp26_ = '\0';
	XkbSymMapRec _tmp27_ = {0};
	guchar _tmp28_ = '\0';
	XkbDescRec* _tmp29_ = NULL;
	XkbClientMapRec* _tmp30_ = NULL;
	guchar _tmp31_ = '\0';
	Display* _tmp32_ = NULL;
	XkbDescRec* _tmp33_ = NULL;
	XkbMapChangesRec _tmp34_ = {0};
	Display* _tmp35_ = NULL;
	guint _tmp36_ = 0U;
	guint _tmp37_ = 0U;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->reserved_keycode;
	if (((gint) _tmp0_) == 0) {
		guchar _tmp1_ = '\0';
		Display* _tmp2_ = NULL;
		guchar _tmp3_ = '\0';
		gulong _tmp4_ = 0UL;
		_tmp1_ = caribou_xadapter_get_reserved_keycode (self);
		self->priv->reserved_keycode = _tmp1_;
		_tmp2_ = self->priv->xdisplay;
		_tmp3_ = self->priv->reserved_keycode;
		_tmp4_ = XKeycodeToKeysym (_tmp2_, _tmp3_, 0);
		self->priv->reserved_keysym = (guint) _tmp4_;
	}
	_tmp5_ = self->priv->xdisplay;
	XFlush (_tmp5_);
	_tmp6_ = self->priv->xkbdesc;
	_tmp7_ = _tmp6_->map;
	_tmp8_ = _tmp7_->key_sym_map;
	_tmp8__length1 = _vala_array_length (_tmp7_->key_sym_map);
	_tmp9_ = self->priv->reserved_keycode;
	_tmp10_ = _tmp8_[_tmp9_];
	_tmp11_ = _tmp10_.offset;
	offset = (guint) _tmp11_;
	_tmp12_ = self->priv->xkbdesc;
	_tmp13_ = _tmp12_->map;
	_tmp14_ = _tmp13_->syms;
	_tmp14__length1 = _vala_array_length (_tmp13_->syms);
	_tmp15_ = offset;
	_tmp16_ = keysym;
	_tmp14_[_tmp15_] = (gulong) _tmp16_;
	_tmp17_ = _tmp14_[_tmp15_];
	_tmp18_ = self->priv->xkbdesc;
	_tmp19_ = XkbUseCoreKbd;
	_tmp18_->device_spec = (gushort) _tmp19_;
	memset (&changes, 0, sizeof (XkbMapChangesRec));
	_tmp20_ = XkbKeySymsMask;
	_tmp21_ = XkbKeyTypesMask;
	changes.changed = (gushort) (_tmp20_ | _tmp21_);
	_tmp22_ = self->priv->reserved_keycode;
	changes.first_key_sym = (gchar) _tmp22_;
	_tmp23_ = self->priv->xkbdesc;
	_tmp24_ = _tmp23_->map;
	_tmp25_ = _tmp24_->key_sym_map;
	_tmp25__length1 = _vala_array_length (_tmp24_->key_sym_map);
	_tmp26_ = self->priv->reserved_keycode;
	_tmp27_ = _tmp25_[_tmp26_];
	_tmp28_ = _tmp27_.width;
	changes.num_key_syms = _tmp28_;
	changes.first_type = (guchar) 0;
	_tmp29_ = self->priv->xkbdesc;
	_tmp30_ = _tmp29_->map;
	_tmp31_ = _tmp30_->num_types;
	changes.num_types = _tmp31_;
	_tmp32_ = self->priv->xdisplay;
	_tmp33_ = self->priv->xkbdesc;
	_tmp34_ = changes;
	XkbChangeMap (_tmp32_, _tmp33_, &_tmp34_);
	_tmp35_ = self->priv->xdisplay;
	XFlush (_tmp35_);
	_tmp36_ = keysym;
	_tmp37_ = self->priv->reserved_keysym;
	if (_tmp36_ != _tmp37_) {
		g_timeout_add_full (G_PRIORITY_DEFAULT, (guint) 500, _caribou_xadapter_reset_reserved_gsource_func, g_object_ref (self), g_object_unref);
	}
}


static gboolean caribou_xadapter_reset_reserved (CaribouXAdapter* self) {
	gboolean result = FALSE;
	guint _tmp0_ = 0U;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->reserved_keysym;
	caribou_xadapter_replace_keycode (self, _tmp0_);
	result = FALSE;
	return result;
}


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


static GdkKeymapKey* _gdk_keymap_key_dup (GdkKeymapKey* self) {
	GdkKeymapKey* dup;
	dup = g_new0 (GdkKeymapKey, 1);
	memcpy (dup, self, sizeof (GdkKeymapKey));
	return dup;
}


static gpointer __gdk_keymap_key_dup0 (gpointer self) {
	return self ? _gdk_keymap_key_dup (self) : NULL;
}


static gboolean caribou_xadapter_best_keycode_keyval_match (CaribouXAdapter* self, guint keyval, guchar* keycode, guint* modmask) {
	guchar _vala_keycode = '\0';
	guint _vala_modmask = 0U;
	gboolean result = FALSE;
	GdkKeymap* kmap = NULL;
	GdkKeymap* _tmp0_ = NULL;
	GdkKeymap* _tmp1_ = NULL;
	GdkKeymapKey* kmk = NULL;
	gint kmk_length1 = 0;
	gint _kmk_size_ = 0;
	GdkKeymap* _tmp2_ = NULL;
	guint _tmp3_ = 0U;
	GdkKeymapKey* _tmp4_ = NULL;
	gint _tmp5_ = 0;
	gboolean _tmp6_ = FALSE;
	GdkKeymapKey* best_match = NULL;
	GdkKeymapKey* _tmp7_ = NULL;
	gint _tmp7__length1 = 0;
	GdkKeymapKey* _tmp17_ = NULL;
	GdkKeymapKey* _tmp18_ = NULL;
	guint _tmp19_ = 0U;
	guint* _tmp20_ = NULL;
	gint _tmp20__length1 = 0;
	GdkKeymapKey* _tmp21_ = NULL;
	gint _tmp22_ = 0;
	guint _tmp23_ = 0U;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = gdk_keymap_get_default ();
	_tmp1_ = _g_object_ref0 (_tmp0_);
	kmap = _tmp1_;
	_vala_keycode = (guchar) 0;
	_vala_modmask = (guint) 0;
	_tmp2_ = kmap;
	_tmp3_ = keyval;
	_tmp6_ = gdk_keymap_get_entries_for_keyval (_tmp2_, _tmp3_, &_tmp4_, &_tmp5_);
	kmk = (g_free (kmk), NULL);
	kmk = _tmp4_;
	kmk_length1 = _tmp5_;
	_kmk_size_ = kmk_length1;
	if (!_tmp6_) {
		result = FALSE;
		kmk = (g_free (kmk), NULL);
		_g_object_unref0 (kmap);
		if (keycode) {
			*keycode = _vala_keycode;
		}
		if (modmask) {
			*modmask = _vala_modmask;
		}
		return result;
	}
	best_match = NULL;
	_tmp7_ = kmk;
	_tmp7__length1 = kmk_length1;
	{
		GdkKeymapKey* km_collection = NULL;
		gint km_collection_length1 = 0;
		gint _km_collection_size_ = 0;
		gint km_it = 0;
		km_collection = _tmp7_;
		km_collection_length1 = _tmp7__length1;
		for (km_it = 0; km_it < _tmp7__length1; km_it = km_it + 1) {
			GdkKeymapKey km = {0};
			km = km_collection[km_it];
			{
				gboolean _tmp8_ = FALSE;
				GdkKeymapKey _tmp9_ = {0};
				gint _tmp10_ = 0;
				guchar _tmp11_ = '\0';
				_tmp9_ = km;
				_tmp10_ = _tmp9_.group;
				_tmp11_ = self->priv->group;
				if (_tmp10_ == ((gint) _tmp11_)) {
					GdkKeymapKey _tmp12_ = {0};
					gint _tmp13_ = 0;
					guint* _tmp14_ = NULL;
					gint _tmp14__length1 = 0;
					_tmp12_ = km;
					_tmp13_ = _tmp12_.level;
					_tmp14_ = self->priv->level_switch_modifiers;
					_tmp14__length1 = self->priv->level_switch_modifiers_length1;
					_tmp8_ = _tmp13_ < _tmp14__length1;
				} else {
					_tmp8_ = FALSE;
				}
				if (_tmp8_) {
					GdkKeymapKey _tmp15_ = {0};
					GdkKeymapKey* _tmp16_ = NULL;
					_tmp15_ = km;
					_tmp16_ = __gdk_keymap_key_dup0 (&_tmp15_);
					_g_free0 (best_match);
					best_match = _tmp16_;
				}
			}
		}
	}
	_tmp17_ = best_match;
	if (_tmp17_ == NULL) {
		result = FALSE;
		_g_free0 (best_match);
		kmk = (g_free (kmk), NULL);
		_g_object_unref0 (kmap);
		if (keycode) {
			*keycode = _vala_keycode;
		}
		if (modmask) {
			*modmask = _vala_modmask;
		}
		return result;
	}
	_tmp18_ = best_match;
	_tmp19_ = (*_tmp18_).keycode;
	_vala_keycode = (guchar) _tmp19_;
	_tmp20_ = self->priv->level_switch_modifiers;
	_tmp20__length1 = self->priv->level_switch_modifiers_length1;
	_tmp21_ = best_match;
	_tmp22_ = (*_tmp21_).level;
	_tmp23_ = _tmp20_[_tmp22_];
	_vala_modmask = _tmp23_;
	result = TRUE;
	_g_free0 (best_match);
	kmk = (g_free (kmk), NULL);
	_g_object_unref0 (kmap);
	if (keycode) {
		*keycode = _vala_keycode;
	}
	if (modmask) {
		*modmask = _vala_modmask;
	}
	return result;
}


static guchar caribou_xadapter_keycode_for_keyval (CaribouXAdapter* self, guint keyval, guint* modmask) {
	guint _vala_modmask = 0U;
	guchar result = '\0';
	guchar keycode = '\0';
	guint _tmp0_ = 0U;
	guchar _tmp1_ = '\0';
	guint _tmp2_ = 0U;
	gboolean _tmp3_ = FALSE;
	g_return_val_if_fail (self != NULL, '\0');
	keycode = (guchar) 0;
	_tmp0_ = keyval;
	_tmp3_ = caribou_xadapter_best_keycode_keyval_match (self, _tmp0_, &_tmp1_, &_tmp2_);
	keycode = _tmp1_;
	_vala_modmask = _tmp2_;
	if (!_tmp3_) {
		guint _tmp4_ = 0U;
		guchar _tmp5_ = '\0';
		_tmp4_ = keyval;
		caribou_xadapter_replace_keycode (self, _tmp4_);
		_tmp5_ = self->priv->reserved_keycode;
		keycode = _tmp5_;
		_vala_modmask = (guint) 0;
	}
	result = keycode;
	if (modmask) {
		*modmask = _vala_modmask;
	}
	return result;
}


static void caribou_xadapter_real_keyval_press (CaribouDisplayAdapter* base, guint keyval) {
	CaribouXAdapter * self;
	guint mask = 0U;
	guchar keycode = '\0';
	guint _tmp0_ = 0U;
	guint _tmp1_ = 0U;
	guchar _tmp2_ = '\0';
	guint _tmp3_ = 0U;
	gboolean enabled = FALSE;
	gboolean _tmp5_ = FALSE;
	Display* _tmp6_ = NULL;
	guchar _tmp7_ = '\0';
	Display* _tmp8_ = NULL;
	self = (CaribouXAdapter*) base;
	_tmp0_ = keyval;
	_tmp2_ = caribou_xadapter_keycode_for_keyval (self, _tmp0_, &_tmp1_);
	mask = _tmp1_;
	keycode = _tmp2_;
	_tmp3_ = mask;
	if (_tmp3_ != ((guint) 0)) {
		guint _tmp4_ = 0U;
		_tmp4_ = mask;
		caribou_display_adapter_mod_latch ((CaribouDisplayAdapter*) self, _tmp4_);
	}
	_tmp5_ = caribou_xadapter_set_slowkeys_enabled (self, FALSE);
	enabled = _tmp5_;
	_tmp6_ = self->priv->xdisplay;
	_tmp7_ = keycode;
	XTestFakeKeyEvent (_tmp6_, (guint) _tmp7_, TRUE, CurrentTime);
	_tmp8_ = self->priv->xdisplay;
	XFlush (_tmp8_);
	caribou_xadapter_set_slowkeys_enabled (self, enabled);
}


static void caribou_xadapter_real_keyval_release (CaribouDisplayAdapter* base, guint keyval) {
	CaribouXAdapter * self;
	guchar keycode = '\0';
	guint _tmp0_ = 0U;
	guchar _tmp1_ = '\0';
	Display* _tmp2_ = NULL;
	Display* _tmp3_ = NULL;
	self = (CaribouXAdapter*) base;
	_tmp0_ = keyval;
	_tmp1_ = caribou_xadapter_keycode_for_keyval (self, _tmp0_, NULL);
	keycode = _tmp1_;
	_tmp2_ = self->priv->xdisplay;
	XTestFakeKeyEvent (_tmp2_, (guint) keycode, FALSE, CurrentTime);
	_tmp3_ = self->priv->xdisplay;
	XFlush (_tmp3_);
}


static void caribou_xadapter_real_mod_lock (CaribouDisplayAdapter* base, guint mask) {
	CaribouXAdapter * self;
	Display* _tmp0_ = NULL;
	gint _tmp1_ = 0;
	guint _tmp2_ = 0U;
	guint _tmp3_ = 0U;
	Display* _tmp4_ = NULL;
	self = (CaribouXAdapter*) base;
	_tmp0_ = self->priv->xdisplay;
	_tmp1_ = XkbUseCoreKbd;
	_tmp2_ = mask;
	_tmp3_ = mask;
	XkbLockModifiers (_tmp0_, (guint) _tmp1_, _tmp2_, _tmp3_);
	_tmp4_ = self->priv->xdisplay;
	XFlush (_tmp4_);
}


static void caribou_xadapter_real_mod_unlock (CaribouDisplayAdapter* base, guint mask) {
	CaribouXAdapter * self;
	Display* _tmp0_ = NULL;
	gint _tmp1_ = 0;
	guint _tmp2_ = 0U;
	Display* _tmp3_ = NULL;
	self = (CaribouXAdapter*) base;
	_tmp0_ = self->priv->xdisplay;
	_tmp1_ = XkbUseCoreKbd;
	_tmp2_ = mask;
	XkbLockModifiers (_tmp0_, (guint) _tmp1_, _tmp2_, (guint) 0);
	_tmp3_ = self->priv->xdisplay;
	XFlush (_tmp3_);
}


static void caribou_xadapter_real_mod_latch (CaribouDisplayAdapter* base, guint mask) {
	CaribouXAdapter * self;
	Display* _tmp0_ = NULL;
	gint _tmp1_ = 0;
	guint _tmp2_ = 0U;
	guint _tmp3_ = 0U;
	Display* _tmp4_ = NULL;
	self = (CaribouXAdapter*) base;
	_tmp0_ = self->priv->xdisplay;
	_tmp1_ = XkbUseCoreKbd;
	_tmp2_ = mask;
	_tmp3_ = mask;
	XkbLatchModifiers (_tmp0_, (guint) _tmp1_, _tmp2_, _tmp3_);
	_tmp4_ = self->priv->xdisplay;
	XFlush (_tmp4_);
}


static void caribou_xadapter_real_mod_unlatch (CaribouDisplayAdapter* base, guint mask) {
	CaribouXAdapter * self;
	Display* _tmp0_ = NULL;
	gint _tmp1_ = 0;
	guint _tmp2_ = 0U;
	Display* _tmp3_ = NULL;
	self = (CaribouXAdapter*) base;
	_tmp0_ = self->priv->xdisplay;
	_tmp1_ = XkbUseCoreKbd;
	_tmp2_ = mask;
	XkbLatchModifiers (_tmp0_, (guint) _tmp1_, _tmp2_, (guint) 0);
	_tmp3_ = self->priv->xdisplay;
	XFlush (_tmp3_);
}


static guint caribou_xadapter_real_get_current_group (CaribouDisplayAdapter* base, gchar** group_name, gchar** variant_name) {
	CaribouXAdapter * self;
	gchar* _vala_group_name = NULL;
	gchar* _vala_variant_name = NULL;
	guint result = 0U;
	XklConfigRec* config_rec = NULL;
	XklConfigRec* _tmp0_ = NULL;
	XklConfigRec* _tmp1_ = NULL;
	XklEngine* _tmp2_ = NULL;
	guchar _tmp3_ = '\0';
	XklConfigRec* _tmp4_ = NULL;
	gchar** _tmp5_ = NULL;
	gint _tmp5__length1 = 0;
	guchar _tmp12_ = '\0';
	XklConfigRec* _tmp13_ = NULL;
	gchar** _tmp14_ = NULL;
	gint _tmp14__length1 = 0;
	const gchar* _tmp21_ = NULL;
	guchar _tmp23_ = '\0';
	self = (CaribouXAdapter*) base;
	_tmp0_ = xkl_config_rec_new ();
	config_rec = _tmp0_;
	_tmp1_ = config_rec;
	_tmp2_ = self->priv->xkl_engine;
	xkl_config_rec_get_from_server (_tmp1_, _tmp2_);
	_tmp3_ = self->priv->group;
	_tmp4_ = config_rec;
	_tmp5_ = _tmp4_->layouts;
	_tmp5__length1 = _vala_array_length (_tmp4_->layouts);
	if (((gint) _tmp3_) < _tmp5__length1) {
		XklConfigRec* _tmp6_ = NULL;
		gchar** _tmp7_ = NULL;
		gint _tmp7__length1 = 0;
		guchar _tmp8_ = '\0';
		const gchar* _tmp9_ = NULL;
		gchar* _tmp10_ = NULL;
		_tmp6_ = config_rec;
		_tmp7_ = _tmp6_->layouts;
		_tmp7__length1 = _vala_array_length (_tmp6_->layouts);
		_tmp8_ = self->priv->group;
		_tmp9_ = _tmp7_[_tmp8_];
		_tmp10_ = g_strdup (_tmp9_);
		_g_free0 (_vala_group_name);
		_vala_group_name = _tmp10_;
	} else {
		gchar* _tmp11_ = NULL;
		_tmp11_ = g_strdup ("");
		_g_free0 (_vala_group_name);
		_vala_group_name = _tmp11_;
	}
	_tmp12_ = self->priv->group;
	_tmp13_ = config_rec;
	_tmp14_ = _tmp13_->variants;
	_tmp14__length1 = _vala_array_length (_tmp13_->variants);
	if (((gint) _tmp12_) < _tmp14__length1) {
		XklConfigRec* _tmp15_ = NULL;
		gchar** _tmp16_ = NULL;
		gint _tmp16__length1 = 0;
		guchar _tmp17_ = '\0';
		const gchar* _tmp18_ = NULL;
		gchar* _tmp19_ = NULL;
		_tmp15_ = config_rec;
		_tmp16_ = _tmp15_->variants;
		_tmp16__length1 = _vala_array_length (_tmp15_->variants);
		_tmp17_ = self->priv->group;
		_tmp18_ = _tmp16_[_tmp17_];
		_tmp19_ = g_strdup (_tmp18_);
		_g_free0 (_vala_variant_name);
		_vala_variant_name = _tmp19_;
	} else {
		gchar* _tmp20_ = NULL;
		_tmp20_ = g_strdup ("");
		_g_free0 (_vala_variant_name);
		_vala_variant_name = _tmp20_;
	}
	_tmp21_ = _vala_variant_name;
	if (_tmp21_ == NULL) {
		gchar* _tmp22_ = NULL;
		_tmp22_ = g_strdup ("");
		_g_free0 (_vala_variant_name);
		_vala_variant_name = _tmp22_;
	}
	_tmp23_ = self->priv->group;
	result = (guint) _tmp23_;
	_g_object_unref0 (config_rec);
	if (group_name) {
		*group_name = _vala_group_name;
	} else {
		_g_free0 (_vala_group_name);
	}
	if (variant_name) {
		*variant_name = _vala_variant_name;
	} else {
		_g_free0 (_vala_variant_name);
	}
	return result;
}


static void caribou_xadapter_real_get_groups (CaribouDisplayAdapter* base, gchar*** group_names, int* group_names_length1, gchar*** variant_names, int* variant_names_length1) {
	CaribouXAdapter * self;
	gchar** _vala_group_names = NULL;
	int _vala_group_names_length1 = 0;
	gchar** _vala_variant_names = NULL;
	int _vala_variant_names_length1 = 0;
	gint i = 0;
	XklConfigRec* config_rec = NULL;
	XklConfigRec* _tmp0_ = NULL;
	XklConfigRec* _tmp1_ = NULL;
	XklEngine* _tmp2_ = NULL;
	gint _tmp11_ = 0;
	gchar** _tmp12_ = NULL;
	gint _tmp13_ = 0;
	gchar** _tmp14_ = NULL;
	self = (CaribouXAdapter*) base;
	_tmp0_ = xkl_config_rec_new ();
	config_rec = _tmp0_;
	_tmp1_ = config_rec;
	_tmp2_ = self->priv->xkl_engine;
	xkl_config_rec_get_from_server (_tmp1_, _tmp2_);
	{
		gboolean _tmp3_ = FALSE;
		i = 0;
		_tmp3_ = TRUE;
		while (TRUE) {
			gint _tmp5_ = 0;
			XklConfigRec* _tmp6_ = NULL;
			gchar** _tmp7_ = NULL;
			gint _tmp7__length1 = 0;
			gint _tmp8_ = 0;
			const gchar* _tmp9_ = NULL;
			if (!_tmp3_) {
				gint _tmp4_ = 0;
				_tmp4_ = i;
				i = _tmp4_ + 1;
			}
			_tmp3_ = FALSE;
			_tmp5_ = i;
			if (!(_tmp5_ < 4)) {
				break;
			}
			_tmp6_ = config_rec;
			_tmp7_ = _tmp6_->layouts;
			_tmp7__length1 = _vala_array_length (_tmp6_->layouts);
			_tmp8_ = i;
			_tmp9_ = _tmp7_[_tmp8_];
			if (_tmp9_ == NULL) {
				gint _tmp10_ = 0;
				_tmp10_ = i;
				i = _tmp10_ - 1;
				break;
			}
		}
	}
	_tmp11_ = i;
	_tmp12_ = g_new0 (gchar*, (_tmp11_ + 1) + 1);
	_vala_group_names = (_vala_array_free (_vala_group_names, _vala_group_names_length1, (GDestroyNotify) g_free), NULL);
	_vala_group_names = _tmp12_;
	_vala_group_names_length1 = _tmp11_ + 1;
	_tmp13_ = i;
	_tmp14_ = g_new0 (gchar*, (_tmp13_ + 1) + 1);
	_vala_variant_names = (_vala_array_free (_vala_variant_names, _vala_variant_names_length1, (GDestroyNotify) g_free), NULL);
	_vala_variant_names = _tmp14_;
	_vala_variant_names_length1 = _tmp13_ + 1;
	{
		gboolean _tmp15_ = FALSE;
		_tmp15_ = TRUE;
		while (TRUE) {
			gint _tmp17_ = 0;
			gchar** _tmp18_ = NULL;
			gint _tmp18__length1 = 0;
			gint _tmp19_ = 0;
			XklConfigRec* _tmp20_ = NULL;
			gchar** _tmp21_ = NULL;
			gint _tmp21__length1 = 0;
			gint _tmp22_ = 0;
			const gchar* _tmp23_ = NULL;
			gchar* _tmp24_ = NULL;
			gchar* _tmp25_ = NULL;
			XklConfigRec* _tmp26_ = NULL;
			gchar** _tmp27_ = NULL;
			gint _tmp27__length1 = 0;
			gint _tmp28_ = 0;
			const gchar* _tmp29_ = NULL;
			if (!_tmp15_) {
				gint _tmp16_ = 0;
				_tmp16_ = i;
				i = _tmp16_ - 1;
			}
			_tmp15_ = FALSE;
			_tmp17_ = i;
			if (!(_tmp17_ >= 0)) {
				break;
			}
			_tmp18_ = _vala_group_names;
			_tmp18__length1 = _vala_group_names_length1;
			_tmp19_ = i;
			_tmp20_ = config_rec;
			_tmp21_ = _tmp20_->layouts;
			_tmp21__length1 = _vala_array_length (_tmp20_->layouts);
			_tmp22_ = i;
			_tmp23_ = _tmp21_[_tmp22_];
			_tmp24_ = g_strdup (_tmp23_);
			_g_free0 (_tmp18_[_tmp19_]);
			_tmp18_[_tmp19_] = _tmp24_;
			_tmp25_ = _tmp18_[_tmp19_];
			_tmp26_ = config_rec;
			_tmp27_ = _tmp26_->variants;
			_tmp27__length1 = _vala_array_length (_tmp26_->variants);
			_tmp28_ = i;
			_tmp29_ = _tmp27_[_tmp28_];
			if (_tmp29_ != NULL) {
				gchar** _tmp30_ = NULL;
				gint _tmp30__length1 = 0;
				gint _tmp31_ = 0;
				XklConfigRec* _tmp32_ = NULL;
				gchar** _tmp33_ = NULL;
				gint _tmp33__length1 = 0;
				gint _tmp34_ = 0;
				const gchar* _tmp35_ = NULL;
				gchar* _tmp36_ = NULL;
				gchar* _tmp37_ = NULL;
				_tmp30_ = _vala_variant_names;
				_tmp30__length1 = _vala_variant_names_length1;
				_tmp31_ = i;
				_tmp32_ = config_rec;
				_tmp33_ = _tmp32_->variants;
				_tmp33__length1 = _vala_array_length (_tmp32_->variants);
				_tmp34_ = i;
				_tmp35_ = _tmp33_[_tmp34_];
				_tmp36_ = g_strdup (_tmp35_);
				_g_free0 (_tmp30_[_tmp31_]);
				_tmp30_[_tmp31_] = _tmp36_;
				_tmp37_ = _tmp30_[_tmp31_];
			} else {
				gchar** _tmp38_ = NULL;
				gint _tmp38__length1 = 0;
				gint _tmp39_ = 0;
				gchar* _tmp40_ = NULL;
				gchar* _tmp41_ = NULL;
				_tmp38_ = _vala_variant_names;
				_tmp38__length1 = _vala_variant_names_length1;
				_tmp39_ = i;
				_tmp40_ = g_strdup ("");
				_g_free0 (_tmp38_[_tmp39_]);
				_tmp38_[_tmp39_] = _tmp40_;
				_tmp41_ = _tmp38_[_tmp39_];
			}
		}
	}
	_g_object_unref0 (config_rec);
	if (group_names) {
		*group_names = _vala_group_names;
	} else {
		_vala_group_names = (_vala_array_free (_vala_group_names, _vala_group_names_length1, (GDestroyNotify) g_free), NULL);
	}
	if (group_names_length1) {
		*group_names_length1 = _vala_group_names_length1;
	}
	if (variant_names) {
		*variant_names = _vala_variant_names;
	} else {
		_vala_variant_names = (_vala_array_free (_vala_variant_names, _vala_variant_names_length1, (GDestroyNotify) g_free), NULL);
	}
	if (variant_names_length1) {
		*variant_names_length1 = _vala_variant_names_length1;
	}
}


static void caribou_xadapter_real_register_key_func (CaribouDisplayAdapter* base, guint keyval, CaribouKeyButtonCallback func, void* func_target) {
	CaribouXAdapter * self;
	guchar keycode = '\0';
	guint modmask = 0U;
	guint _tmp0_ = 0U;
	guchar _tmp1_ = '\0';
	guint _tmp2_ = 0U;
	gboolean _tmp3_ = FALSE;
	CaribouKeyButtonCallback _tmp5_ = NULL;
	void* _tmp5__target = NULL;
	self = (CaribouXAdapter*) base;
	_tmp0_ = keyval;
	_tmp3_ = caribou_xadapter_best_keycode_keyval_match (self, _tmp0_, &_tmp1_, &_tmp2_);
	keycode = _tmp1_;
	modmask = _tmp2_;
	if (!_tmp3_) {
		guint _tmp4_ = 0U;
		_tmp4_ = keyval;
		g_warning ("xadapter.vala:352: No good keycode for %d", (gint) _tmp4_);
		return;
	}
	_tmp5_ = func;
	_tmp5__target = func_target;
	if (_tmp5_ != NULL) {
		CaribouXAdapterKeyButtonHandler* handler = NULL;
		CaribouKeyButtonCallback _tmp6_ = NULL;
		void* _tmp6__target = NULL;
		CaribouXAdapterKeyButtonHandler* _tmp7_ = NULL;
		GeeHashMap* _tmp8_ = NULL;
		guchar _tmp9_ = '\0';
		CaribouXAdapterKeyButtonHandler* _tmp10_ = NULL;
		Display* _tmp11_ = NULL;
		guchar _tmp12_ = '\0';
		XID _tmp13_ = 0;
		_tmp6_ = func;
		_tmp6__target = func_target;
		_tmp7_ = caribou_xadapter_key_button_handler_new (_tmp6_, _tmp6__target);
		handler = _tmp7_;
		_tmp8_ = self->priv->key_funcs;
		_tmp9_ = keycode;
		_tmp10_ = handler;
		gee_abstract_map_set ((GeeAbstractMap*) _tmp8_, (gpointer) ((guintptr) ((guint) _tmp9_)), _tmp10_);
		_tmp11_ = self->priv->xdisplay;
		_tmp12_ = keycode;
		_tmp13_ = self->priv->xid;
		XGrabKey (_tmp11_, (gint) _tmp12_, (guint) 0, (Window) _tmp13_, TRUE, (gint) GrabModeAsync, (gint) GrabModeAsync);
		_caribou_xadapter_key_button_handler_unref0 (handler);
	} else {
		GeeHashMap* _tmp14_ = NULL;
		guchar _tmp15_ = '\0';
		Display* _tmp16_ = NULL;
		guchar _tmp17_ = '\0';
		XID _tmp18_ = 0;
		_tmp14_ = self->priv->key_funcs;
		_tmp15_ = keycode;
		gee_abstract_map_unset ((GeeAbstractMap*) _tmp14_, (gpointer) ((guintptr) ((guint) _tmp15_)), NULL);
		_tmp16_ = self->priv->xdisplay;
		_tmp17_ = keycode;
		_tmp18_ = self->priv->xid;
		XUngrabKey (_tmp16_, (gint) _tmp17_, (guint) 0, (Window) _tmp18_);
	}
}


static void caribou_xadapter_real_register_button_func (CaribouDisplayAdapter* base, guint button, CaribouKeyButtonCallback func, void* func_target) {
	CaribouXAdapter * self;
	CaribouKeyButtonCallback _tmp0_ = NULL;
	void* _tmp0__target = NULL;
	self = (CaribouXAdapter*) base;
	_tmp0_ = func;
	_tmp0__target = func_target;
	if (_tmp0_ != NULL) {
		CaribouXAdapterKeyButtonHandler* handler = NULL;
		CaribouKeyButtonCallback _tmp1_ = NULL;
		void* _tmp1__target = NULL;
		CaribouXAdapterKeyButtonHandler* _tmp2_ = NULL;
		GeeHashMap* _tmp3_ = NULL;
		guint _tmp4_ = 0U;
		CaribouXAdapterKeyButtonHandler* _tmp5_ = NULL;
		Display* _tmp6_ = NULL;
		guint _tmp7_ = 0U;
		XID _tmp8_ = 0;
		_tmp1_ = func;
		_tmp1__target = func_target;
		_tmp2_ = caribou_xadapter_key_button_handler_new (_tmp1_, _tmp1__target);
		handler = _tmp2_;
		_tmp3_ = self->priv->button_funcs;
		_tmp4_ = button;
		_tmp5_ = handler;
		gee_abstract_map_set ((GeeAbstractMap*) _tmp3_, (gpointer) ((guintptr) _tmp4_), _tmp5_);
		_tmp6_ = self->priv->xdisplay;
		_tmp7_ = button;
		_tmp8_ = self->priv->xid;
		XGrabButton (_tmp6_, _tmp7_, (guint) 0, (Window) _tmp8_, TRUE, (guint) (ButtonPressMask | ButtonReleaseMask), (gint) GrabModeAsync, (gint) GrabModeAsync, (Window) 0, (guint) 0);
		_caribou_xadapter_key_button_handler_unref0 (handler);
	} else {
		GeeHashMap* _tmp9_ = NULL;
		guint _tmp10_ = 0U;
		Display* _tmp11_ = NULL;
		guint _tmp12_ = 0U;
		XID _tmp13_ = 0;
		_tmp9_ = self->priv->button_funcs;
		_tmp10_ = button;
		gee_abstract_map_unset ((GeeAbstractMap*) _tmp9_, (gpointer) ((guintptr) _tmp10_), NULL);
		_tmp11_ = self->priv->xdisplay;
		_tmp12_ = button;
		_tmp13_ = self->priv->xid;
		XUngrabButton (_tmp11_, _tmp12_, (guint) 0, (Window) _tmp13_);
	}
}


CaribouXAdapter* caribou_xadapter_construct (GType object_type) {
	CaribouXAdapter * self = NULL;
	self = (CaribouXAdapter*) caribou_display_adapter_construct (object_type);
	return self;
}


CaribouXAdapter* caribou_xadapter_new (void) {
	return caribou_xadapter_construct (CARIBOU_TYPE_XADAPTER);
}


static void _caribou_xadapter_xkl_state_changed_xkl_engine_X_state_changed (XklEngine* _sender, gint p0, gint p1, gboolean p2, gpointer self) {
	caribou_xadapter_xkl_state_changed ((CaribouXAdapter*) self, p0, p1, p2);
}


static void _caribou_xadapter_xkl_config_changed_xkl_engine_X_config_changed (XklEngine* _sender, gpointer self) {
	caribou_xadapter_xkl_config_changed ((CaribouXAdapter*) self);
}


static void _vala_array_add1 (guint** array, int* length, int* size, guint value) {
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (guint, *array, *size);
	}
	(*array)[(*length)++] = value;
}


static void _vala_array_add2 (guint** array, int* length, int* size, guint value) {
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (guint, *array, *size);
	}
	(*array)[(*length)++] = value;
}


static GdkFilterReturn _caribou_xadapter_x_event_filter_gdk_filter_func (GdkXEvent* xevent, GdkEvent* event, gpointer self) {
	GdkFilterReturn result;
	result = caribou_xadapter_x_event_filter ((CaribouXAdapter*) self, xevent, event);
	return result;
}


static GObject * caribou_xadapter_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
	GObject * obj;
	GObjectClass * parent_class;
	CaribouXAdapter * self;
	XkbStateRec xkb_state = {0};
	XklState* xkl_state = NULL;
	GdkWindow* rootwin = NULL;
	GdkWindow* _tmp0_ = NULL;
	GdkWindow* _tmp1_ = NULL;
	GdkWindow* _tmp2_ = NULL;
	GdkDisplay* _tmp3_ = NULL;
	Display* _tmp4_ = NULL;
	GdkWindow* _tmp5_ = NULL;
	Window _tmp6_ = 0;
	Display* _tmp7_ = NULL;
	gint _tmp8_ = 0;
	gint _tmp9_ = 0;
	XkbDescRec* _tmp10_ = NULL;
	Display* _tmp11_ = NULL;
	XklEngine* _tmp12_ = NULL;
	XklEngine* _tmp13_ = NULL;
	XklEngine* _tmp14_ = NULL;
	XklEngine* _tmp15_ = NULL;
	XklState* _tmp16_ = NULL;
	XklState* _tmp17_ = NULL;
	gint32 _tmp18_ = 0;
	XklEngine* _tmp19_ = NULL;
	XklEngine* _tmp20_ = NULL;
	Display* _tmp21_ = NULL;
	gint _tmp22_ = 0;
	XkbStateRec _tmp23_ = {0};
	XkbStateRec _tmp24_ = {0};
	guchar _tmp25_ = '\0';
	guint* _tmp26_ = NULL;
	guchar lv3_mod = '\0';
	guchar _tmp27_ = '\0';
	guchar _tmp28_ = '\0';
	GeeHashMap* _tmp33_ = NULL;
	GeeHashMap* _tmp34_ = NULL;
	Display* _tmp35_ = NULL;
	gint _tmp36_ = 0;
	gint _tmp37_ = 0;
	gint _tmp38_ = 0;
	gint _tmp39_ = 0;
	gint _tmp40_ = 0;
	parent_class = G_OBJECT_CLASS (caribou_xadapter_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, CARIBOU_TYPE_XADAPTER, CaribouXAdapter);
	_tmp0_ = gdk_get_default_root_window ();
	_tmp1_ = _g_object_ref0 (_tmp0_);
	rootwin = _tmp1_;
	_tmp2_ = rootwin;
	_tmp3_ = gdk_window_get_display (_tmp2_);
	_tmp4_ = gdk_x11_display_get_xdisplay (_tmp3_);
	self->priv->xdisplay = _tmp4_;
	_tmp5_ = rootwin;
	_tmp6_ = gdk_x11_window_get_xid (_tmp5_);
	self->priv->xid = (XID) _tmp6_;
	_tmp7_ = self->priv->xdisplay;
	_tmp8_ = XkbGBN_AllComponentsMask;
	_tmp9_ = XkbUseCoreKbd;
	_tmp10_ = XkbGetKeyboard (_tmp7_, (guint) _tmp8_, (guint) _tmp9_);
	_0 (self->priv->xkbdesc);
	self->priv->xkbdesc = _tmp10_;
	_tmp11_ = self->priv->xdisplay;
	_tmp12_ = xkl_engine_get_instance (_tmp11_);
	_tmp13_ = _g_object_ref0 (_tmp12_);
	_g_object_unref0 (self->priv->xkl_engine);
	self->priv->xkl_engine = _tmp13_;
	_tmp14_ = self->priv->xkl_engine;
	xkl_engine_start_listen (_tmp14_, (guint) XKLL_TRACK_KEYBOARD_STATE);
	_tmp15_ = self->priv->xkl_engine;
	_tmp16_ = xkl_engine_get_current_state (_tmp15_);
	xkl_state = _tmp16_;
	_tmp17_ = xkl_state;
	_tmp18_ = _tmp17_->group;
	self->priv->group = (guchar) _tmp18_;
	_tmp19_ = self->priv->xkl_engine;
	g_signal_connect_object (_tmp19_, "X-state-changed", (GCallback) _caribou_xadapter_xkl_state_changed_xkl_engine_X_state_changed, self, G_CONNECT_AFTER);
	_tmp20_ = self->priv->xkl_engine;
	g_signal_connect_object (_tmp20_, "X-config-changed", (GCallback) _caribou_xadapter_xkl_config_changed_xkl_engine_X_config_changed, self, G_CONNECT_AFTER);
	_tmp21_ = self->priv->xdisplay;
	_tmp22_ = XkbUseCoreKbd;
	XkbGetState (_tmp21_, (guint) _tmp22_, &_tmp23_);
	xkb_state = _tmp23_;
	_tmp24_ = xkb_state;
	_tmp25_ = _tmp24_.mods;
	self->priv->modifiers = _tmp25_;
	self->priv->reserved_keycode = (guchar) 0;
	_tmp26_ = g_new0 (guint, 2);
	_tmp26_[0] = (guint) 0;
	_tmp26_[1] = (guint) GDK_SHIFT_MASK;
	self->priv->level_switch_modifiers = (g_free (self->priv->level_switch_modifiers), NULL);
	self->priv->level_switch_modifiers = _tmp26_;
	self->priv->level_switch_modifiers_length1 = 2;
	self->priv->_level_switch_modifiers_size_ = self->priv->level_switch_modifiers_length1;
	_tmp27_ = caribou_xadapter_keysym_to_modifier (self, (guint) GDK_KEY_ISO_Level3_Shift);
	lv3_mod = _tmp27_;
	_tmp28_ = lv3_mod;
	if (((gint) _tmp28_) != 0) {
		guint* _tmp29_ = NULL;
		gint _tmp29__length1 = 0;
		guchar _tmp30_ = '\0';
		guint* _tmp31_ = NULL;
		gint _tmp31__length1 = 0;
		guchar _tmp32_ = '\0';
		_tmp29_ = self->priv->level_switch_modifiers;
		_tmp29__length1 = self->priv->level_switch_modifiers_length1;
		_tmp30_ = lv3_mod;
		_vala_array_add1 (&self->priv->level_switch_modifiers, &self->priv->level_switch_modifiers_length1, &self->priv->_level_switch_modifiers_size_, (guint) _tmp30_);
		_tmp31_ = self->priv->level_switch_modifiers;
		_tmp31__length1 = self->priv->level_switch_modifiers_length1;
		_tmp32_ = lv3_mod;
		_vala_array_add2 (&self->priv->level_switch_modifiers, &self->priv->level_switch_modifiers_length1, &self->priv->_level_switch_modifiers_size_, (guint) (GDK_SHIFT_MASK | _tmp32_));
	}
	_tmp33_ = gee_hash_map_new (G_TYPE_UINT, NULL, NULL, CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER, (GBoxedCopyFunc) caribou_xadapter_key_button_handler_ref, caribou_xadapter_key_button_handler_unref, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	_g_object_unref0 (self->priv->button_funcs);
	self->priv->button_funcs = _tmp33_;
	_tmp34_ = gee_hash_map_new (G_TYPE_UINT, NULL, NULL, CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER, (GBoxedCopyFunc) caribou_xadapter_key_button_handler_ref, caribou_xadapter_key_button_handler_unref, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	_g_object_unref0 (self->priv->key_funcs);
	self->priv->key_funcs = _tmp34_;
	_tmp35_ = self->priv->xdisplay;
	_tmp36_ = XkbUseCoreKbd;
	_tmp37_ = XkbStateNotifyMask;
	_tmp38_ = XkbAccessXNotifyMask;
	_tmp39_ = XkbStateNotifyMask;
	_tmp40_ = XkbAccessXNotifyMask;
	XkbSelectEvents (_tmp35_, (guint) _tmp36_, (gulong) (_tmp37_ | _tmp38_), (gulong) (_tmp39_ | _tmp40_));
	gdk_window_add_filter (G_TYPE_CHECK_INSTANCE_CAST (NULL, GDK_TYPE_WINDOW, GdkWindow), _caribou_xadapter_x_event_filter_gdk_filter_func, self);
	_g_object_unref0 (rootwin);
	return obj;
}


static CaribouXAdapterKeyButtonHandler* caribou_xadapter_key_button_handler_construct (GType object_type, CaribouKeyButtonCallback cb, void* cb_target) {
	CaribouXAdapterKeyButtonHandler* self = NULL;
	CaribouKeyButtonCallback _tmp0_ = NULL;
	void* _tmp0__target = NULL;
	self = (CaribouXAdapterKeyButtonHandler*) g_type_create_instance (object_type);
	_tmp0_ = cb;
	_tmp0__target = cb_target;
	caribou_xadapter_key_button_handler_set_cb (self, _tmp0_, _tmp0__target);
	return self;
}


static CaribouXAdapterKeyButtonHandler* caribou_xadapter_key_button_handler_new (CaribouKeyButtonCallback cb, void* cb_target) {
	return caribou_xadapter_key_button_handler_construct (CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER, cb, cb_target);
}


static CaribouKeyButtonCallback caribou_xadapter_key_button_handler_get_cb (CaribouXAdapterKeyButtonHandler* self, gpointer* result_target) {
	CaribouKeyButtonCallback result;
	CaribouKeyButtonCallback _tmp0_ = NULL;
	void* _tmp0__target = NULL;
	CaribouKeyButtonCallback _tmp1_ = NULL;
	void* _tmp1__target = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_cb;
	_tmp0__target = self->priv->_cb_target;
	_tmp1_ = _tmp0_;
	_tmp1__target = _tmp0__target;
	*result_target = _tmp1__target;
	result = _tmp1_;
	return result;
}


static void caribou_xadapter_key_button_handler_set_cb (CaribouXAdapterKeyButtonHandler* self, CaribouKeyButtonCallback value, gpointer value_target) {
	CaribouKeyButtonCallback _tmp0_ = NULL;
	void* _tmp0__target = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = value;
	_tmp0__target = value_target;
	self->priv->_cb = _tmp0_;
	self->priv->_cb_target = _tmp0__target;
}


static void caribou_xadapter_value_key_button_handler_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void caribou_xadapter_value_key_button_handler_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		caribou_xadapter_key_button_handler_unref (value->data[0].v_pointer);
	}
}


static void caribou_xadapter_value_key_button_handler_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = caribou_xadapter_key_button_handler_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer caribou_xadapter_value_key_button_handler_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* caribou_xadapter_value_key_button_handler_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		CaribouXAdapterKeyButtonHandler* object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = caribou_xadapter_key_button_handler_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* caribou_xadapter_value_key_button_handler_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	CaribouXAdapterKeyButtonHandler** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = caribou_xadapter_key_button_handler_ref (value->data[0].v_pointer);
	}
	return NULL;
}


static GParamSpec* caribou_xadapter_param_spec_key_button_handler (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	CaribouXAdapterParamSpecKeyButtonHandler* spec;
	g_return_val_if_fail (g_type_is_a (object_type, CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


static gpointer caribou_xadapter_value_get_key_button_handler (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER), NULL);
	return value->data[0].v_pointer;
}


static void caribou_xadapter_value_set_key_button_handler (GValue* value, gpointer v_object) {
	CaribouXAdapterKeyButtonHandler* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		caribou_xadapter_key_button_handler_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		caribou_xadapter_key_button_handler_unref (old);
	}
}


static void caribou_xadapter_value_take_key_button_handler (GValue* value, gpointer v_object) {
	CaribouXAdapterKeyButtonHandler* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		caribou_xadapter_key_button_handler_unref (old);
	}
}


static void caribou_xadapter_key_button_handler_class_init (CaribouXAdapterKeyButtonHandlerClass * klass) {
	caribou_xadapter_key_button_handler_parent_class = g_type_class_peek_parent (klass);
	((CaribouXAdapterKeyButtonHandlerClass *) klass)->finalize = caribou_xadapter_key_button_handler_finalize;
	g_type_class_add_private (klass, sizeof (CaribouXAdapterKeyButtonHandlerPrivate));
}


static void caribou_xadapter_key_button_handler_instance_init (CaribouXAdapterKeyButtonHandler * self) {
	self->priv = CARIBOU_XADAPTER_KEY_BUTTON_HANDLER_GET_PRIVATE (self);
	self->ref_count = 1;
}


static void caribou_xadapter_key_button_handler_finalize (CaribouXAdapterKeyButtonHandler* obj) {
	CaribouXAdapterKeyButtonHandler * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, CARIBOU_XADAPTER_TYPE_KEY_BUTTON_HANDLER, CaribouXAdapterKeyButtonHandler);
	g_signal_handlers_destroy (self);
}


static GType caribou_xadapter_key_button_handler_get_type (void) {
	static volatile gsize caribou_xadapter_key_button_handler_type_id__volatile = 0;
	if (g_once_init_enter (&caribou_xadapter_key_button_handler_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { caribou_xadapter_value_key_button_handler_init, caribou_xadapter_value_key_button_handler_free_value, caribou_xadapter_value_key_button_handler_copy_value, caribou_xadapter_value_key_button_handler_peek_pointer, "p", caribou_xadapter_value_key_button_handler_collect_value, "p", caribou_xadapter_value_key_button_handler_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (CaribouXAdapterKeyButtonHandlerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) caribou_xadapter_key_button_handler_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (CaribouXAdapterKeyButtonHandler), 0, (GInstanceInitFunc) caribou_xadapter_key_button_handler_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType caribou_xadapter_key_button_handler_type_id;
		caribou_xadapter_key_button_handler_type_id = g_type_register_fundamental (g_type_fundamental_next (), "CaribouXAdapterKeyButtonHandler", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&caribou_xadapter_key_button_handler_type_id__volatile, caribou_xadapter_key_button_handler_type_id);
	}
	return caribou_xadapter_key_button_handler_type_id__volatile;
}


static gpointer caribou_xadapter_key_button_handler_ref (gpointer instance) {
	CaribouXAdapterKeyButtonHandler* self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


static void caribou_xadapter_key_button_handler_unref (gpointer instance) {
	CaribouXAdapterKeyButtonHandler* self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		CARIBOU_XADAPTER_KEY_BUTTON_HANDLER_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}


static void caribou_xadapter_class_init (CaribouXAdapterClass * klass) {
	caribou_xadapter_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (CaribouXAdapterPrivate));
	((CaribouDisplayAdapterClass *) klass)->keyval_press = caribou_xadapter_real_keyval_press;
	((CaribouDisplayAdapterClass *) klass)->keyval_release = caribou_xadapter_real_keyval_release;
	((CaribouDisplayAdapterClass *) klass)->mod_lock = caribou_xadapter_real_mod_lock;
	((CaribouDisplayAdapterClass *) klass)->mod_unlock = caribou_xadapter_real_mod_unlock;
	((CaribouDisplayAdapterClass *) klass)->mod_latch = caribou_xadapter_real_mod_latch;
	((CaribouDisplayAdapterClass *) klass)->mod_unlatch = caribou_xadapter_real_mod_unlatch;
	((CaribouDisplayAdapterClass *) klass)->get_current_group = caribou_xadapter_real_get_current_group;
	((CaribouDisplayAdapterClass *) klass)->get_groups = caribou_xadapter_real_get_groups;
	((CaribouDisplayAdapterClass *) klass)->register_key_func = caribou_xadapter_real_register_key_func;
	((CaribouDisplayAdapterClass *) klass)->register_button_func = caribou_xadapter_real_register_button_func;
	G_OBJECT_CLASS (klass)->constructor = caribou_xadapter_constructor;
	G_OBJECT_CLASS (klass)->finalize = caribou_xadapter_finalize;
}


static void caribou_xadapter_instance_init (CaribouXAdapter * self) {
	self->priv = CARIBOU_XADAPTER_GET_PRIVATE (self);
}


static void caribou_xadapter_finalize (GObject* obj) {
	CaribouXAdapter * self;
	XkbDescRec* _tmp0_ = NULL;
	gint _tmp1_ = 0;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, CARIBOU_TYPE_XADAPTER, CaribouXAdapter);
	_tmp0_ = self->priv->xkbdesc;
	_tmp1_ = XkbGBN_AllComponentsMask;
	XkbFreeKeyboard (_tmp0_, (guint) _tmp1_, TRUE);
	_0 (self->priv->xkbdesc);
	_g_object_unref0 (self->priv->xkl_engine);
	self->priv->level_switch_modifiers = (g_free (self->priv->level_switch_modifiers), NULL);
	_g_object_unref0 (self->priv->button_funcs);
	_g_object_unref0 (self->priv->key_funcs);
	G_OBJECT_CLASS (caribou_xadapter_parent_class)->finalize (obj);
}


/**
     * Singleton object providing access to the X Window facility.
     */
GType caribou_xadapter_get_type (void) {
	static volatile gsize caribou_xadapter_type_id__volatile = 0;
	if (g_once_init_enter (&caribou_xadapter_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (CaribouXAdapterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) caribou_xadapter_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (CaribouXAdapter), 0, (GInstanceInitFunc) caribou_xadapter_instance_init, NULL };
		GType caribou_xadapter_type_id;
		caribou_xadapter_type_id = g_type_register_static (CARIBOU_TYPE_DISPLAY_ADAPTER, "CaribouXAdapter", &g_define_type_info, 0);
		g_once_init_leave (&caribou_xadapter_type_id__volatile, caribou_xadapter_type_id);
	}
	return caribou_xadapter_type_id__volatile;
}


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;
}



