/* XkbLayoutHandler.c generated by valac 0.56.19, the Vala compiler
 * generated from XkbLayoutHandler.vala, do not modify */

/*
* Copyright (c) 2017 elementary, LLC. (https://elementary.io)
*
* 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 2 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, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/

#include "keyboard.h"
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include <glib-object.h>
#include <glib/gi18n-lib.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>

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

enum  {
	KEYBOARD_XKB_LAYOUT_HANDLER_0_PROPERTY,
	KEYBOARD_XKB_LAYOUT_HANDLER_LANGUAGES_PROPERTY,
	KEYBOARD_XKB_LAYOUT_HANDLER_NUM_PROPERTIES
};
static GParamSpec* keyboard_xkb_layout_handler_properties[KEYBOARD_XKB_LAYOUT_HANDLER_NUM_PROPERTIES];
#define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _xmlFreeDoc0(var) ((var == NULL) ? NULL : (var = (xmlFreeDoc (var), NULL)))
#define _xmlXPathFreeContext0(var) ((var == NULL) ? NULL : (var = (xmlXPathFreeContext (var), NULL)))
#define _xmlXPathFreeObject0(var) ((var == NULL) ? NULL : (var = (xmlXPathFreeObject (var), NULL)))

struct _KeyboardXkbLayoutHandlerPrivate {
	GHashTable* _languages;
};

static gint KeyboardXkbLayoutHandler_private_offset;
static gpointer keyboard_xkb_layout_handler_parent_class = NULL;
static KeyboardXkbLayoutHandler* keyboard_xkb_layout_handler_instance;
static KeyboardXkbLayoutHandler* keyboard_xkb_layout_handler_instance = NULL;

static KeyboardXkbLayoutHandler* keyboard_xkb_layout_handler_new (void);
static KeyboardXkbLayoutHandler* keyboard_xkb_layout_handler_construct (GType object_type);
static gchar* keyboard_xkb_layout_handler_get_xml_rules_file_path (KeyboardXkbLayoutHandler* self);
static void _g_free0_ (gpointer var);
static void keyboard_xkb_layout_handler_set_languages (KeyboardXkbLayoutHandler* self,
                                                GHashTable* value);
static GObject * keyboard_xkb_layout_handler_constructor (GType type,
                                                   guint n_construct_properties,
                                                   GObjectConstructParam * construct_properties);
static void keyboard_xkb_layout_handler_finalize (GObject * obj);
static GType keyboard_xkb_layout_handler_get_type_once (void);
static void _vala_keyboard_xkb_layout_handler_get_property (GObject * object,
                                                     guint property_id,
                                                     GValue * value,
                                                     GParamSpec * pspec);
static void _vala_keyboard_xkb_layout_handler_set_property (GObject * object,
                                                     guint property_id,
                                                     const GValue * value,
                                                     GParamSpec * pspec);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);
static gssize _vala_array_length (gpointer array);

static inline gpointer
keyboard_xkb_layout_handler_get_instance_private (KeyboardXkbLayoutHandler* self)
{
	return G_STRUCT_MEMBER_P (self, KeyboardXkbLayoutHandler_private_offset);
}

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

KeyboardXkbLayoutHandler*
keyboard_xkb_layout_handler_get_instance (void)
{
	KeyboardXkbLayoutHandler* _tmp0_;
	KeyboardXkbLayoutHandler* _tmp2_;
	KeyboardXkbLayoutHandler* _tmp3_;
	KeyboardXkbLayoutHandler* result;
	_tmp0_ = keyboard_xkb_layout_handler_instance;
	if (_tmp0_ == NULL) {
		KeyboardXkbLayoutHandler* _tmp1_;
		_tmp1_ = keyboard_xkb_layout_handler_new ();
		_g_object_unref0 (keyboard_xkb_layout_handler_instance);
		keyboard_xkb_layout_handler_instance = _tmp1_;
	}
	_tmp2_ = keyboard_xkb_layout_handler_instance;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	result = _tmp3_;
	return result;
}

static KeyboardXkbLayoutHandler*
keyboard_xkb_layout_handler_construct (GType object_type)
{
	KeyboardXkbLayoutHandler * self = NULL;
	self = (KeyboardXkbLayoutHandler*) g_object_new (object_type, NULL);
	return self;
}

static KeyboardXkbLayoutHandler*
keyboard_xkb_layout_handler_new (void)
{
	return keyboard_xkb_layout_handler_construct (KEYBOARD_TYPE_XKB_LAYOUT_HANDLER);
}

static gchar*
keyboard_xkb_layout_handler_get_xml_rules_file_path (KeyboardXkbLayoutHandler* self)
{
	const gchar* base_path = NULL;
	const gchar* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_getenv ("XKB_CONFIG_ROOT");
	base_path = _tmp0_;
	_tmp1_ = base_path;
	if (_tmp1_ == NULL) {
		base_path = CONSTANTS_XKB_BASE;
	}
	_tmp2_ = base_path;
	_tmp3_ = g_build_filename (_tmp2_, "rules", KEYBOARD_XKB_LAYOUT_HANDLER_XKB_RULES_FILE, NULL);
	result = _tmp3_;
	return result;
}

static void
_g_free0_ (gpointer var)
{
	var = (g_free (var), NULL);
}

static const gchar*
string_to_string (const gchar* self)
{
	const gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	result = self;
	return result;
}

GHashTable*
keyboard_xkb_layout_handler_get_variants_for_language (KeyboardXkbLayoutHandler* self,
                                                       const gchar* language)
{
	GHashTable* returned_table = NULL;
	GHashFunc _tmp0_;
	GEqualFunc _tmp1_;
	GHashTable* _tmp2_;
	GHashTable* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* file_path = NULL;
	gchar* _tmp6_;
	xmlDoc* doc = NULL;
	const gchar* _tmp7_;
	xmlDoc* _tmp8_;
	xmlDoc* _tmp9_;
	xmlXPathContext* cntx = NULL;
	xmlDoc* _tmp10_;
	xmlXPathContext* _tmp11_;
	gchar* xpath = NULL;
	const gchar* _tmp12_;
	gchar* _tmp13_;
	xmlXPathObject* res = NULL;
	xmlXPathContext* _tmp14_;
	const gchar* _tmp15_;
	xmlXPathObject* _tmp16_;
	xmlXPathObject* _tmp17_;
	gboolean _tmp19_ = FALSE;
	xmlXPathObject* _tmp20_;
	xmlXPathObject* _tmp60_;
	xmlDoc* _tmp61_;
	GHashTable* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (language != NULL, NULL);
	_tmp0_ = g_str_hash;
	_tmp1_ = g_str_equal;
	_tmp2_ = g_hash_table_new_full (_tmp0_, _tmp1_, _g_free0_, _g_free0_);
	returned_table = _tmp2_;
	_tmp3_ = returned_table;
	_tmp4_ = g_strdup ("");
	_tmp5_ = g_strdup (_ ("Default"));
	g_hash_table_insert (_tmp3_, _tmp4_, _tmp5_);
	_tmp6_ = keyboard_xkb_layout_handler_get_xml_rules_file_path (self);
	file_path = _tmp6_;
	_tmp7_ = file_path;
	_tmp8_ = xmlParseFile (_tmp7_);
	doc = _tmp8_;
	_tmp9_ = doc;
	if (_tmp9_ == NULL) {
		g_critical ("XkbLayoutHandler.vala:100: '%s' not found or permissions incorrect\n", KEYBOARD_XKB_LAYOUT_HANDLER_XKB_RULES_FILE);
		result = returned_table;
		_g_free0 (file_path);
		return result;
	}
	_tmp10_ = doc;
	_tmp11_ = xmlXPathNewContext (_tmp10_);
	cntx = _tmp11_;
	_tmp12_ = string_to_string (language);
	_tmp13_ = g_strconcat ("/xkbConfigRegistry/layoutList/layout/configItem/name[text()='", _tmp12_, "']/../../variantList/variant/configItem", NULL);
	xpath = _tmp13_;
	_tmp14_ = cntx;
	_tmp15_ = xpath;
	_tmp16_ = xmlXPathEvalExpression ((xmlChar*) _tmp15_, _tmp14_);
	res = _tmp16_;
	_tmp17_ = res;
	if (_tmp17_ == NULL) {
		xmlDoc* _tmp18_;
		_tmp18_ = doc;
		_xmlFreeDoc0 (_tmp18_);
		g_critical ("XkbLayoutHandler.vala:110: Unable to parse '%s'", KEYBOARD_XKB_LAYOUT_HANDLER_XKB_RULES_FILE);
		result = returned_table;
		_g_free0 (xpath);
		_xmlXPathFreeContext0 (cntx);
		_g_free0 (file_path);
		return result;
	}
	_tmp20_ = res;
	if (_tmp20_->type != XPATH_NODESET) {
		_tmp19_ = TRUE;
	} else {
		xmlXPathObject* _tmp21_;
		xmlNodeSet* _tmp22_;
		_tmp21_ = res;
		_tmp22_ = _tmp21_->nodesetval;
		_tmp19_ = _tmp22_ == NULL;
	}
	if (_tmp19_) {
		xmlXPathObject* _tmp23_;
		xmlDoc* _tmp24_;
		const gchar* _tmp25_;
		gchar* _tmp26_;
		gchar* _tmp27_;
		_tmp23_ = res;
		_xmlXPathFreeObject0 (_tmp23_);
		_tmp24_ = doc;
		_xmlFreeDoc0 (_tmp24_);
		_tmp25_ = string_to_string (language);
		_tmp26_ = g_strconcat ("No variants for ", _tmp25_, " found in '%s'", NULL);
		_tmp27_ = _tmp26_;
		g_warning (_tmp27_, KEYBOARD_XKB_LAYOUT_HANDLER_XKB_RULES_FILE);
		_g_free0 (_tmp27_);
		result = returned_table;
		_g_free0 (xpath);
		_xmlXPathFreeContext0 (cntx);
		_g_free0 (file_path);
		return result;
	}
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp28_ = FALSE;
			_tmp28_ = TRUE;
			while (TRUE) {
				xmlXPathObject* _tmp30_;
				xmlNodeSet* _tmp31_;
				xmlNode* node = NULL;
				xmlXPathObject* _tmp32_;
				xmlNodeSet* _tmp33_;
				xmlNode* _tmp34_;
				gchar* name = NULL;
				gchar* description = NULL;
				gboolean _tmp52_ = FALSE;
				const gchar* _tmp53_;
				if (!_tmp28_) {
					gint _tmp29_;
					_tmp29_ = i;
					i = _tmp29_ + 1;
				}
				_tmp28_ = FALSE;
				_tmp30_ = res;
				_tmp31_ = _tmp30_->nodesetval;
				if (!(i < xmlXPathNodeSetGetLength (_tmp31_))) {
					break;
				}
				_tmp32_ = res;
				_tmp33_ = _tmp32_->nodesetval;
				_tmp34_ = xmlXPathNodeSetItem (_tmp33_, i);
				node = _tmp34_;
				name = NULL;
				description = NULL;
				{
					xmlNode* iter = NULL;
					xmlNode* _tmp35_;
					xmlNode* _tmp36_;
					_tmp35_ = node;
					_tmp36_ = _tmp35_->children;
					iter = _tmp36_;
					{
						gboolean _tmp37_ = FALSE;
						_tmp37_ = TRUE;
						while (TRUE) {
							xmlNode* _tmp40_;
							xmlNode* _tmp41_;
							if (!_tmp37_) {
								xmlNode* _tmp38_;
								xmlNode* _tmp39_;
								_tmp38_ = iter;
								_tmp39_ = _tmp38_->next;
								iter = _tmp39_;
							}
							_tmp37_ = FALSE;
							_tmp40_ = iter;
							if (!(_tmp40_ != NULL)) {
								break;
							}
							_tmp41_ = iter;
							if (_tmp41_->type == XML_ELEMENT_NODE) {
								xmlNode* _tmp42_;
								const gchar* _tmp43_;
								_tmp42_ = iter;
								_tmp43_ = _tmp42_->name;
								if (g_strcmp0 (_tmp43_, "name") == 0) {
									xmlNode* _tmp44_;
									gchar* _tmp45_;
									_tmp44_ = iter;
									_tmp45_ = (gchar*) xmlNodeGetContent (_tmp44_);
									_g_free0 (name);
									name = _tmp45_;
								} else {
									xmlNode* _tmp46_;
									const gchar* _tmp47_;
									_tmp46_ = iter;
									_tmp47_ = _tmp46_->name;
									if (g_strcmp0 (_tmp47_, "description") == 0) {
										xmlNode* _tmp48_;
										gchar* _tmp49_;
										gchar* _tmp50_;
										gchar* _tmp51_;
										_tmp48_ = iter;
										_tmp49_ = (gchar*) xmlNodeGetContent (_tmp48_);
										_tmp50_ = _tmp49_;
										_tmp51_ = g_strdup (g_dgettext ("xkeyboard-config", _tmp50_));
										_g_free0 (description);
										description = _tmp51_;
										_g_free0 (_tmp50_);
									}
								}
							}
						}
					}
				}
				_tmp53_ = name;
				if (_tmp53_ != NULL) {
					const gchar* _tmp54_;
					_tmp54_ = description;
					_tmp52_ = _tmp54_ != NULL;
				} else {
					_tmp52_ = FALSE;
				}
				if (_tmp52_) {
					GHashTable* _tmp55_;
					const gchar* _tmp56_;
					gchar* _tmp57_;
					const gchar* _tmp58_;
					gchar* _tmp59_;
					_tmp55_ = returned_table;
					_tmp56_ = name;
					_tmp57_ = g_strdup (_tmp56_);
					_tmp58_ = description;
					_tmp59_ = g_strdup (_tmp58_);
					g_hash_table_insert (_tmp55_, _tmp57_, _tmp59_);
				}
				_g_free0 (description);
				_g_free0 (name);
			}
		}
	}
	_tmp60_ = res;
	_xmlXPathFreeObject0 (_tmp60_);
	_tmp61_ = doc;
	_xmlFreeDoc0 (_tmp61_);
	result = returned_table;
	_g_free0 (xpath);
	_xmlXPathFreeContext0 (cntx);
	_g_free0 (file_path);
	return result;
}

static gboolean
string_contains (const gchar* self,
                 const gchar* needle)
{
	gchar* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (needle != NULL, FALSE);
	_tmp0_ = strstr ((gchar*) self, (gchar*) needle);
	result = _tmp0_ != NULL;
	return result;
}

gchar*
keyboard_xkb_layout_handler_get_display_name (KeyboardXkbLayoutHandler* self,
                                              const gchar* variant)
{
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (variant != NULL, NULL);
	if (string_contains (variant, "+")) {
		gchar** parts = NULL;
		gchar** _tmp0_;
		gchar** _tmp1_;
		gint parts_length1;
		gint _parts_size_;
		gchar** _tmp2_;
		gint _tmp2__length1;
		const gchar* _tmp3_;
		GHashTable* _tmp4_;
		GHashTable* _tmp5_;
		gchar** _tmp6_;
		gint _tmp6__length1;
		const gchar* _tmp7_;
		gconstpointer _tmp8_;
		gchar* _tmp9_;
		gchar* _tmp10_;
		_tmp1_ = _tmp0_ = g_strsplit (variant, "+", 2);
		parts = _tmp1_;
		parts_length1 = _vala_array_length (_tmp0_);
		_parts_size_ = parts_length1;
		_tmp2_ = parts;
		_tmp2__length1 = parts_length1;
		_tmp3_ = _tmp2_[0];
		_tmp4_ = keyboard_xkb_layout_handler_get_variants_for_language (self, _tmp3_);
		_tmp5_ = _tmp4_;
		_tmp6_ = parts;
		_tmp6__length1 = parts_length1;
		_tmp7_ = _tmp6_[1];
		_tmp8_ = g_hash_table_lookup (_tmp5_, _tmp7_);
		_tmp9_ = g_strdup ((const gchar*) _tmp8_);
		_tmp10_ = _tmp9_;
		_g_hash_table_unref0 (_tmp5_);
		result = _tmp10_;
		parts = (_vala_array_free (parts, parts_length1, (GDestroyNotify) g_free), NULL);
		return result;
	} else {
		GHashTable* _tmp11_;
		gconstpointer _tmp12_;
		gchar* _tmp13_;
		_tmp11_ = self->priv->_languages;
		_tmp12_ = g_hash_table_lookup (_tmp11_, variant);
		_tmp13_ = g_strdup ((const gchar*) _tmp12_);
		result = _tmp13_;
		return result;
	}
}

GHashTable*
keyboard_xkb_layout_handler_get_languages (KeyboardXkbLayoutHandler* self)
{
	GHashTable* result;
	GHashTable* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_languages;
	result = _tmp0_;
	return result;
}

static gpointer
_g_hash_table_ref0 (gpointer self)
{
	return self ? g_hash_table_ref (self) : NULL;
}

static void
keyboard_xkb_layout_handler_set_languages (KeyboardXkbLayoutHandler* self,
                                           GHashTable* value)
{
	GHashTable* old_value;
	g_return_if_fail (self != NULL);
	old_value = keyboard_xkb_layout_handler_get_languages (self);
	if (old_value != value) {
		GHashTable* _tmp0_;
		_tmp0_ = _g_hash_table_ref0 (value);
		_g_hash_table_unref0 (self->priv->_languages);
		self->priv->_languages = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, keyboard_xkb_layout_handler_properties[KEYBOARD_XKB_LAYOUT_HANDLER_LANGUAGES_PROPERTY]);
	}
}

static GObject *
keyboard_xkb_layout_handler_constructor (GType type,
                                         guint n_construct_properties,
                                         GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	KeyboardXkbLayoutHandler * self;
	GHashFunc _tmp0_;
	GEqualFunc _tmp1_;
	GHashTable* _tmp2_;
	GHashTable* _tmp3_;
	xmlDoc* doc = NULL;
	gchar* _tmp4_;
	gchar* _tmp5_;
	xmlDoc* _tmp6_;
	xmlDoc* _tmp7_;
	xmlDoc* _tmp8_;
	xmlXPathContext* cntx = NULL;
	xmlDoc* _tmp9_;
	xmlXPathContext* _tmp10_;
	xmlXPathObject* res = NULL;
	xmlXPathContext* _tmp11_;
	xmlXPathObject* _tmp12_;
	xmlXPathObject* _tmp13_;
	gboolean _tmp15_ = FALSE;
	xmlXPathObject* _tmp16_;
	xmlXPathObject* _tmp53_;
	xmlDoc* _tmp54_;
	parent_class = G_OBJECT_CLASS (keyboard_xkb_layout_handler_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, KEYBOARD_TYPE_XKB_LAYOUT_HANDLER, KeyboardXkbLayoutHandler);
	_tmp0_ = g_str_hash;
	_tmp1_ = g_str_equal;
	_tmp2_ = g_hash_table_new_full (_tmp0_, _tmp1_, _g_free0_, _g_free0_);
	_tmp3_ = _tmp2_;
	keyboard_xkb_layout_handler_set_languages (self, _tmp3_);
	_g_hash_table_unref0 (_tmp3_);
	_tmp4_ = keyboard_xkb_layout_handler_get_xml_rules_file_path (self);
	_tmp5_ = _tmp4_;
	_tmp6_ = xmlParseFile (_tmp5_);
	_tmp7_ = _tmp6_;
	_g_free0 (_tmp5_);
	doc = _tmp7_;
	_tmp8_ = doc;
	if (_tmp8_ == NULL) {
		g_critical ("XkbLayoutHandler.vala:42: '%s' not found or permissions missing\n", KEYBOARD_XKB_LAYOUT_HANDLER_XKB_RULES_FILE);
		return obj;
	}
	_tmp9_ = doc;
	_tmp10_ = xmlXPathNewContext (_tmp9_);
	cntx = _tmp10_;
	_tmp11_ = cntx;
	_tmp12_ = xmlXPathEvalExpression ((xmlChar*) "/xkbConfigRegistry/layoutList/layout/configItem", _tmp11_);
	res = _tmp12_;
	_tmp13_ = res;
	if (_tmp13_ == NULL) {
		xmlDoc* _tmp14_;
		_tmp14_ = doc;
		_xmlFreeDoc0 (_tmp14_);
		g_critical ("XkbLayoutHandler.vala:51: Unable to parse '%s'", KEYBOARD_XKB_LAYOUT_HANDLER_XKB_RULES_FILE);
		_xmlXPathFreeContext0 (cntx);
		return obj;
	}
	_tmp16_ = res;
	if (_tmp16_->type != XPATH_NODESET) {
		_tmp15_ = TRUE;
	} else {
		xmlXPathObject* _tmp17_;
		xmlNodeSet* _tmp18_;
		_tmp17_ = res;
		_tmp18_ = _tmp17_->nodesetval;
		_tmp15_ = _tmp18_ == NULL;
	}
	if (_tmp15_) {
		xmlXPathObject* _tmp19_;
		xmlDoc* _tmp20_;
		_tmp19_ = res;
		_xmlXPathFreeObject0 (_tmp19_);
		_tmp20_ = doc;
		_xmlFreeDoc0 (_tmp20_);
		g_critical ("XkbLayoutHandler.vala:58: No layouts found in '%s'", KEYBOARD_XKB_LAYOUT_HANDLER_XKB_RULES_FILE);
		_xmlXPathFreeContext0 (cntx);
		return obj;
	}
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp21_ = FALSE;
			_tmp21_ = TRUE;
			while (TRUE) {
				xmlXPathObject* _tmp23_;
				xmlNodeSet* _tmp24_;
				xmlNode* node = NULL;
				xmlXPathObject* _tmp25_;
				xmlNodeSet* _tmp26_;
				xmlNode* _tmp27_;
				gchar* name = NULL;
				gchar* description = NULL;
				gboolean _tmp45_ = FALSE;
				const gchar* _tmp46_;
				if (!_tmp21_) {
					gint _tmp22_;
					_tmp22_ = i;
					i = _tmp22_ + 1;
				}
				_tmp21_ = FALSE;
				_tmp23_ = res;
				_tmp24_ = _tmp23_->nodesetval;
				if (!(i < xmlXPathNodeSetGetLength (_tmp24_))) {
					break;
				}
				_tmp25_ = res;
				_tmp26_ = _tmp25_->nodesetval;
				_tmp27_ = xmlXPathNodeSetItem (_tmp26_, i);
				node = _tmp27_;
				name = NULL;
				description = NULL;
				{
					xmlNode* iter = NULL;
					xmlNode* _tmp28_;
					xmlNode* _tmp29_;
					_tmp28_ = node;
					_tmp29_ = _tmp28_->children;
					iter = _tmp29_;
					{
						gboolean _tmp30_ = FALSE;
						_tmp30_ = TRUE;
						while (TRUE) {
							xmlNode* _tmp33_;
							xmlNode* _tmp34_;
							if (!_tmp30_) {
								xmlNode* _tmp31_;
								xmlNode* _tmp32_;
								_tmp31_ = iter;
								_tmp32_ = _tmp31_->next;
								iter = _tmp32_;
							}
							_tmp30_ = FALSE;
							_tmp33_ = iter;
							if (!(_tmp33_ != NULL)) {
								break;
							}
							_tmp34_ = iter;
							if (_tmp34_->type == XML_ELEMENT_NODE) {
								xmlNode* _tmp35_;
								const gchar* _tmp36_;
								_tmp35_ = iter;
								_tmp36_ = _tmp35_->name;
								if (g_strcmp0 (_tmp36_, "name") == 0) {
									xmlNode* _tmp37_;
									gchar* _tmp38_;
									_tmp37_ = iter;
									_tmp38_ = (gchar*) xmlNodeGetContent (_tmp37_);
									_g_free0 (name);
									name = _tmp38_;
								} else {
									xmlNode* _tmp39_;
									const gchar* _tmp40_;
									_tmp39_ = iter;
									_tmp40_ = _tmp39_->name;
									if (g_strcmp0 (_tmp40_, "description") == 0) {
										xmlNode* _tmp41_;
										gchar* _tmp42_;
										gchar* _tmp43_;
										gchar* _tmp44_;
										_tmp41_ = iter;
										_tmp42_ = (gchar*) xmlNodeGetContent (_tmp41_);
										_tmp43_ = _tmp42_;
										_tmp44_ = g_strdup (g_dgettext ("xkeyboard-config", _tmp43_));
										_g_free0 (description);
										description = _tmp44_;
										_g_free0 (_tmp43_);
									}
								}
							}
						}
					}
				}
				_tmp46_ = name;
				if (_tmp46_ != NULL) {
					const gchar* _tmp47_;
					_tmp47_ = description;
					_tmp45_ = _tmp47_ != NULL;
				} else {
					_tmp45_ = FALSE;
				}
				if (_tmp45_) {
					GHashTable* _tmp48_;
					const gchar* _tmp49_;
					gchar* _tmp50_;
					const gchar* _tmp51_;
					gchar* _tmp52_;
					_tmp48_ = self->priv->_languages;
					_tmp49_ = name;
					_tmp50_ = g_strdup (_tmp49_);
					_tmp51_ = description;
					_tmp52_ = g_strdup (_tmp51_);
					g_hash_table_insert (_tmp48_, _tmp50_, _tmp52_);
				}
				_g_free0 (description);
				_g_free0 (name);
			}
		}
	}
	_tmp53_ = res;
	_xmlXPathFreeObject0 (_tmp53_);
	_tmp54_ = doc;
	_xmlFreeDoc0 (_tmp54_);
	_xmlXPathFreeContext0 (cntx);
	return obj;
}

static void
keyboard_xkb_layout_handler_class_init (KeyboardXkbLayoutHandlerClass * klass,
                                        gpointer klass_data)
{
	keyboard_xkb_layout_handler_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &KeyboardXkbLayoutHandler_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_keyboard_xkb_layout_handler_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_keyboard_xkb_layout_handler_set_property;
	G_OBJECT_CLASS (klass)->constructor = keyboard_xkb_layout_handler_constructor;
	G_OBJECT_CLASS (klass)->finalize = keyboard_xkb_layout_handler_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), KEYBOARD_XKB_LAYOUT_HANDLER_LANGUAGES_PROPERTY, keyboard_xkb_layout_handler_properties[KEYBOARD_XKB_LAYOUT_HANDLER_LANGUAGES_PROPERTY] = g_param_spec_boxed ("languages", "languages", "languages", G_TYPE_HASH_TABLE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

static void
keyboard_xkb_layout_handler_instance_init (KeyboardXkbLayoutHandler * self,
                                           gpointer klass)
{
	self->priv = keyboard_xkb_layout_handler_get_instance_private (self);
}

static void
keyboard_xkb_layout_handler_finalize (GObject * obj)
{
	KeyboardXkbLayoutHandler * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, KEYBOARD_TYPE_XKB_LAYOUT_HANDLER, KeyboardXkbLayoutHandler);
	_g_hash_table_unref0 (self->priv->_languages);
	G_OBJECT_CLASS (keyboard_xkb_layout_handler_parent_class)->finalize (obj);
}

static GType
keyboard_xkb_layout_handler_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (KeyboardXkbLayoutHandlerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) keyboard_xkb_layout_handler_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KeyboardXkbLayoutHandler), 0, (GInstanceInitFunc) keyboard_xkb_layout_handler_instance_init, NULL };
	GType keyboard_xkb_layout_handler_type_id;
	keyboard_xkb_layout_handler_type_id = g_type_register_static (G_TYPE_OBJECT, "KeyboardXkbLayoutHandler", &g_define_type_info, 0);
	KeyboardXkbLayoutHandler_private_offset = g_type_add_instance_private (keyboard_xkb_layout_handler_type_id, sizeof (KeyboardXkbLayoutHandlerPrivate));
	return keyboard_xkb_layout_handler_type_id;
}

GType
keyboard_xkb_layout_handler_get_type (void)
{
	static volatile gsize keyboard_xkb_layout_handler_type_id__once = 0;
	if (g_once_init_enter (&keyboard_xkb_layout_handler_type_id__once)) {
		GType keyboard_xkb_layout_handler_type_id;
		keyboard_xkb_layout_handler_type_id = keyboard_xkb_layout_handler_get_type_once ();
		g_once_init_leave (&keyboard_xkb_layout_handler_type_id__once, keyboard_xkb_layout_handler_type_id);
	}
	return keyboard_xkb_layout_handler_type_id__once;
}

static void
_vala_keyboard_xkb_layout_handler_get_property (GObject * object,
                                                guint property_id,
                                                GValue * value,
                                                GParamSpec * pspec)
{
	KeyboardXkbLayoutHandler * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, KEYBOARD_TYPE_XKB_LAYOUT_HANDLER, KeyboardXkbLayoutHandler);
	switch (property_id) {
		case KEYBOARD_XKB_LAYOUT_HANDLER_LANGUAGES_PROPERTY:
		g_value_set_boxed (value, keyboard_xkb_layout_handler_get_languages (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_keyboard_xkb_layout_handler_set_property (GObject * object,
                                                guint property_id,
                                                const GValue * value,
                                                GParamSpec * pspec)
{
	KeyboardXkbLayoutHandler * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, KEYBOARD_TYPE_XKB_LAYOUT_HANDLER, KeyboardXkbLayoutHandler);
	switch (property_id) {
		case KEYBOARD_XKB_LAYOUT_HANDLER_LANGUAGES_PROPERTY:
		keyboard_xkb_layout_handler_set_languages (self, g_value_get_boxed (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_array_destroy (gpointer array,
                     gssize array_length,
                     GDestroyNotify destroy_func)
{
	if ((array != NULL) && (destroy_func != NULL)) {
		gssize 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,
                  gssize array_length,
                  GDestroyNotify destroy_func)
{
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}

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

