|
rpm-build |
18b009 |
/*
|
|
rpm-build |
18b009 |
* Copyright (C) 2012 Red Hat, Inc.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Written by: Rui Matos <rmatos@redhat.com>
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* This program is free software; you can redistribute it and/or modify
|
|
rpm-build |
18b009 |
* it under the terms of the GNU General Public License as published by
|
|
rpm-build |
18b009 |
* the Free Software Foundation; either version 2, or (at your option)
|
|
rpm-build |
18b009 |
* any later version.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* This program is distributed in the hope that it will be useful,
|
|
rpm-build |
18b009 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
rpm-build |
18b009 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
rpm-build |
18b009 |
* GNU General Public License for more details.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* You should have received a copy of the GNU General Public License
|
|
rpm-build |
18b009 |
* along with this program; if not, write to the Free Software
|
|
rpm-build |
18b009 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
rpm-build |
18b009 |
* 02110-1301, USA.
|
|
rpm-build |
18b009 |
*/
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
#include <config.h>
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
#include <stdio.h>
|
|
rpm-build |
18b009 |
#include <stdlib.h>
|
|
rpm-build |
18b009 |
#include <string.h>
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
#include <gio/gio.h>
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
#include <glib/gi18n-lib.h>
|
|
rpm-build |
18b009 |
#define XKEYBOARD_CONFIG_(String) ((char *) g_dgettext ("xkeyboard-config", String))
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
#define GNOME_DESKTOP_USE_UNSTABLE_API
|
|
rpm-build |
18b009 |
#include "gnome-languages.h"
|
|
rpm-build |
18b009 |
#include "gnome-xkb-info.h"
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
#ifndef XKB_RULES_FILE
|
|
rpm-build |
18b009 |
#define XKB_RULES_FILE "evdev"
|
|
rpm-build |
18b009 |
#endif
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
typedef struct _Layout Layout;
|
|
rpm-build |
18b009 |
struct _Layout
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
gchar *id;
|
|
rpm-build |
18b009 |
gchar *xkb_name;
|
|
rpm-build |
18b009 |
gchar *short_desc;
|
|
rpm-build |
18b009 |
gchar *description;
|
|
rpm-build |
18b009 |
gboolean is_variant;
|
|
rpm-build |
18b009 |
const Layout *main_layout;
|
|
rpm-build |
18b009 |
GSList *iso639Ids;
|
|
rpm-build |
18b009 |
GSList *iso3166Ids;
|
|
rpm-build |
18b009 |
};
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
typedef struct _XkbOption XkbOption;
|
|
rpm-build |
18b009 |
struct _XkbOption
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
gchar *id;
|
|
rpm-build |
18b009 |
gchar *description;
|
|
rpm-build |
18b009 |
};
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
typedef struct _XkbOptionGroup XkbOptionGroup;
|
|
rpm-build |
18b009 |
struct _XkbOptionGroup
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
gchar *id;
|
|
rpm-build |
18b009 |
gchar *description;
|
|
rpm-build |
18b009 |
gboolean allow_multiple_selection;
|
|
rpm-build |
18b009 |
GHashTable *options_table;
|
|
rpm-build |
18b009 |
};
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
struct _GnomeXkbInfoPrivate
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GHashTable *option_groups_table;
|
|
rpm-build |
18b009 |
GHashTable *layouts_by_country;
|
|
rpm-build |
18b009 |
GHashTable *layouts_by_language;
|
|
rpm-build |
18b009 |
GHashTable *layouts_table;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
/* Only used while parsing */
|
|
rpm-build |
18b009 |
XkbOptionGroup *current_parser_group;
|
|
rpm-build |
18b009 |
XkbOption *current_parser_option;
|
|
rpm-build |
18b009 |
Layout *current_parser_layout;
|
|
rpm-build |
18b009 |
Layout *current_parser_variant;
|
|
rpm-build |
18b009 |
gchar *current_parser_iso639Id;
|
|
rpm-build |
18b009 |
gchar *current_parser_iso3166Id;
|
|
rpm-build |
18b009 |
gchar **current_parser_text;
|
|
rpm-build |
18b009 |
};
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
G_DEFINE_TYPE (GnomeXkbInfo, gnome_xkb_info, G_TYPE_OBJECT);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
free_layout (gpointer data)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
Layout *layout = data;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_return_if_fail (layout != NULL);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_free (layout->id);
|
|
rpm-build |
18b009 |
g_free (layout->xkb_name);
|
|
rpm-build |
18b009 |
g_free (layout->short_desc);
|
|
rpm-build |
18b009 |
g_free (layout->description);
|
|
rpm-build |
18b009 |
g_slist_free_full (layout->iso639Ids, g_free);
|
|
rpm-build |
18b009 |
g_slist_free_full (layout->iso3166Ids, g_free);
|
|
rpm-build |
18b009 |
g_slice_free (Layout, layout);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
free_option (gpointer data)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
XkbOption *option = data;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_return_if_fail (option != NULL);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_free (option->id);
|
|
rpm-build |
18b009 |
g_free (option->description);
|
|
rpm-build |
18b009 |
g_slice_free (XkbOption, option);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
free_option_group (gpointer data)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
XkbOptionGroup *group = data;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_return_if_fail (group != NULL);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_free (group->id);
|
|
rpm-build |
18b009 |
g_free (group->description);
|
|
rpm-build |
18b009 |
g_hash_table_destroy (group->options_table);
|
|
rpm-build |
18b009 |
g_slice_free (XkbOptionGroup, group);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static gchar *
|
|
rpm-build |
18b009 |
get_xml_rules_file_path (const gchar *suffix)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
gchar *rules_file;
|
|
rpm-build |
18b009 |
gchar *xml_rules_file;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
rules_file = g_build_filename (XKB_BASE, "rules", XKB_RULES_FILE, NULL);
|
|
rpm-build |
18b009 |
xml_rules_file = g_strdup_printf ("%s%s", rules_file, suffix);
|
|
rpm-build |
18b009 |
g_free (rules_file);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
return xml_rules_file;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
parse_start_element (GMarkupParseContext *context,
|
|
rpm-build |
18b009 |
const gchar *element_name,
|
|
rpm-build |
18b009 |
const gchar **attribute_names,
|
|
rpm-build |
18b009 |
const gchar **attribute_values,
|
|
rpm-build |
18b009 |
gpointer data,
|
|
rpm-build |
18b009 |
GError **error)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv = GNOME_XKB_INFO (data)->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (priv->current_parser_text)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
|
rpm-build |
18b009 |
"Expected character data but got element '%s'", element_name);
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (strcmp (element_name, "name") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (priv->current_parser_variant)
|
|
rpm-build |
18b009 |
priv->current_parser_text = &priv->current_parser_variant->xkb_name;
|
|
rpm-build |
18b009 |
else if (priv->current_parser_layout)
|
|
rpm-build |
18b009 |
priv->current_parser_text = &priv->current_parser_layout->xkb_name;
|
|
rpm-build |
18b009 |
else if (priv->current_parser_option)
|
|
rpm-build |
18b009 |
priv->current_parser_text = &priv->current_parser_option->id;
|
|
rpm-build |
18b009 |
else if (priv->current_parser_group)
|
|
rpm-build |
18b009 |
priv->current_parser_text = &priv->current_parser_group->id;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else if (strcmp (element_name, "description") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (priv->current_parser_variant)
|
|
rpm-build |
18b009 |
priv->current_parser_text = &priv->current_parser_variant->description;
|
|
rpm-build |
18b009 |
else if (priv->current_parser_layout)
|
|
rpm-build |
18b009 |
priv->current_parser_text = &priv->current_parser_layout->description;
|
|
rpm-build |
18b009 |
else if (priv->current_parser_option)
|
|
rpm-build |
18b009 |
priv->current_parser_text = &priv->current_parser_option->description;
|
|
rpm-build |
18b009 |
else if (priv->current_parser_group)
|
|
rpm-build |
18b009 |
priv->current_parser_text = &priv->current_parser_group->description;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else if (strcmp (element_name, "shortDescription") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (priv->current_parser_variant)
|
|
rpm-build |
18b009 |
priv->current_parser_text = &priv->current_parser_variant->short_desc;
|
|
rpm-build |
18b009 |
else if (priv->current_parser_layout)
|
|
rpm-build |
18b009 |
priv->current_parser_text = &priv->current_parser_layout->short_desc;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else if (strcmp (element_name, "iso639Id") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
priv->current_parser_text = &priv->current_parser_iso639Id;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else if (strcmp (element_name, "iso3166Id") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
priv->current_parser_text = &priv->current_parser_iso3166Id;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else if (strcmp (element_name, "layout") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (priv->current_parser_layout)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
|
rpm-build |
18b009 |
"'layout' elements can't be nested");
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv->current_parser_layout = g_slice_new0 (Layout);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else if (strcmp (element_name, "variant") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
Layout *layout;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (priv->current_parser_variant)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
|
rpm-build |
18b009 |
"'variant' elements can't be nested");
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!priv->current_parser_layout)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
|
rpm-build |
18b009 |
"'variant' elements must be inside 'layout' elements");
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!priv->current_parser_layout->xkb_name)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
|
rpm-build |
18b009 |
"'variant' elements must be inside named 'layout' elements");
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
layout = g_hash_table_lookup (priv->layouts_table, priv->current_parser_layout->xkb_name);
|
|
rpm-build |
18b009 |
if (!layout)
|
|
rpm-build |
18b009 |
layout = priv->current_parser_layout;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv->current_parser_variant = g_slice_new0 (Layout);
|
|
rpm-build |
18b009 |
priv->current_parser_variant->is_variant = TRUE;
|
|
rpm-build |
18b009 |
priv->current_parser_variant->main_layout = layout;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else if (strcmp (element_name, "group") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (priv->current_parser_group)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
|
rpm-build |
18b009 |
"'group' elements can't be nested");
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv->current_parser_group = g_slice_new0 (XkbOptionGroup);
|
|
rpm-build |
18b009 |
/* Maps option ids to XkbOption structs. Owns the XkbOption structs. */
|
|
rpm-build |
18b009 |
priv->current_parser_group->options_table = g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
rpm-build |
18b009 |
NULL, free_option);
|
|
rpm-build |
18b009 |
g_markup_collect_attributes (element_name,
|
|
rpm-build |
18b009 |
attribute_names,
|
|
rpm-build |
18b009 |
attribute_values,
|
|
rpm-build |
18b009 |
error,
|
|
rpm-build |
18b009 |
G_MARKUP_COLLECT_BOOLEAN | G_MARKUP_COLLECT_OPTIONAL,
|
|
rpm-build |
18b009 |
"allowMultipleSelection",
|
|
rpm-build |
18b009 |
&priv->current_parser_group->allow_multiple_selection,
|
|
rpm-build |
18b009 |
G_MARKUP_COLLECT_INVALID);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else if (strcmp (element_name, "option") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (priv->current_parser_option)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
|
rpm-build |
18b009 |
"'option' elements can't be nested");
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!priv->current_parser_group)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
|
rpm-build |
18b009 |
"'option' elements must be inside 'group' elements");
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv->current_parser_option = g_slice_new0 (XkbOption);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
add_layout_to_table (GHashTable *table,
|
|
rpm-build |
18b009 |
const gchar *key,
|
|
rpm-build |
18b009 |
Layout *layout)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GHashTable *set;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!layout->id)
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
set = g_hash_table_lookup (table, key);
|
|
rpm-build |
18b009 |
if (!set)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
set = g_hash_table_new (g_str_hash, g_str_equal);
|
|
rpm-build |
18b009 |
g_hash_table_replace (table, g_strdup (key), set);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (g_hash_table_contains (set, layout->id))
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
g_hash_table_replace (set, layout->id, layout);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
add_layout_to_locale_tables (Layout *layout,
|
|
rpm-build |
18b009 |
GHashTable *layouts_by_language,
|
|
rpm-build |
18b009 |
GHashTable *layouts_by_country)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GSList *l, *lang_codes, *country_codes;
|
|
rpm-build |
18b009 |
gchar *language, *country;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
lang_codes = layout->iso639Ids;
|
|
rpm-build |
18b009 |
country_codes = layout->iso3166Ids;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (layout->is_variant)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (!lang_codes)
|
|
rpm-build |
18b009 |
lang_codes = layout->main_layout->iso639Ids;
|
|
rpm-build |
18b009 |
if (!country_codes)
|
|
rpm-build |
18b009 |
country_codes = layout->main_layout->iso3166Ids;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
for (l = lang_codes; l; l = l->next)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
language = gnome_get_language_from_code ((gchar *) l->data, NULL);
|
|
rpm-build |
18b009 |
if (language)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
add_layout_to_table (layouts_by_language, language, layout);
|
|
rpm-build |
18b009 |
g_free (language);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
for (l = country_codes; l; l = l->next)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
country = gnome_get_country_from_code ((gchar *) l->data, NULL);
|
|
rpm-build |
18b009 |
if (country)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
add_layout_to_table (layouts_by_country, country, layout);
|
|
rpm-build |
18b009 |
g_free (country);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
add_iso639 (Layout *layout,
|
|
rpm-build |
18b009 |
gchar *id)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
layout->iso639Ids = g_slist_prepend (layout->iso639Ids, id);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
add_iso3166 (Layout *layout,
|
|
rpm-build |
18b009 |
gchar *id)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
layout->iso3166Ids = g_slist_prepend (layout->iso3166Ids, id);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
parse_end_element (GMarkupParseContext *context,
|
|
rpm-build |
18b009 |
const gchar *element_name,
|
|
rpm-build |
18b009 |
gpointer data,
|
|
rpm-build |
18b009 |
GError **error)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv = GNOME_XKB_INFO (data)->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (strcmp (element_name, "layout") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (!priv->current_parser_layout->description || !priv->current_parser_layout->xkb_name)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
|
rpm-build |
18b009 |
"'layout' elements must enclose 'description' and 'name' elements");
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv->current_parser_layout->id = g_strdup (priv->current_parser_layout->xkb_name);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (g_hash_table_contains (priv->layouts_table, priv->current_parser_layout->id))
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_clear_pointer (&priv->current_parser_layout, free_layout);
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_hash_table_replace (priv->layouts_table,
|
|
rpm-build |
18b009 |
priv->current_parser_layout->id,
|
|
rpm-build |
18b009 |
priv->current_parser_layout);
|
|
rpm-build |
18b009 |
add_layout_to_locale_tables (priv->current_parser_layout,
|
|
rpm-build |
18b009 |
priv->layouts_by_language,
|
|
rpm-build |
18b009 |
priv->layouts_by_country);
|
|
rpm-build |
18b009 |
priv->current_parser_layout = NULL;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else if (strcmp (element_name, "variant") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (!priv->current_parser_variant->description || !priv->current_parser_variant->xkb_name)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
|
rpm-build |
18b009 |
"'variant' elements must enclose 'description' and 'name' elements");
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv->current_parser_variant->id = g_strjoin ("+",
|
|
rpm-build |
18b009 |
priv->current_parser_layout->xkb_name,
|
|
rpm-build |
18b009 |
priv->current_parser_variant->xkb_name,
|
|
rpm-build |
18b009 |
NULL);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (g_hash_table_contains (priv->layouts_table, priv->current_parser_variant->id))
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_clear_pointer (&priv->current_parser_variant, free_layout);
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_hash_table_replace (priv->layouts_table,
|
|
rpm-build |
18b009 |
priv->current_parser_variant->id,
|
|
rpm-build |
18b009 |
priv->current_parser_variant);
|
|
rpm-build |
18b009 |
add_layout_to_locale_tables (priv->current_parser_variant,
|
|
rpm-build |
18b009 |
priv->layouts_by_language,
|
|
rpm-build |
18b009 |
priv->layouts_by_country);
|
|
rpm-build |
18b009 |
priv->current_parser_variant = NULL;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else if (strcmp (element_name, "iso639Id") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (!priv->current_parser_iso639Id)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
|
rpm-build |
18b009 |
"'iso639Id' elements must enclose text");
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (priv->current_parser_variant)
|
|
rpm-build |
18b009 |
add_iso639 (priv->current_parser_variant, priv->current_parser_iso639Id);
|
|
rpm-build |
18b009 |
else if (priv->current_parser_layout)
|
|
rpm-build |
18b009 |
add_iso639 (priv->current_parser_layout, priv->current_parser_iso639Id);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv->current_parser_iso639Id = NULL;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else if (strcmp (element_name, "iso3166Id") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (!priv->current_parser_iso3166Id)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
|
rpm-build |
18b009 |
"'iso3166Id' elements must enclose text");
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (priv->current_parser_variant)
|
|
rpm-build |
18b009 |
add_iso3166 (priv->current_parser_variant, priv->current_parser_iso3166Id);
|
|
rpm-build |
18b009 |
else if (priv->current_parser_layout)
|
|
rpm-build |
18b009 |
add_iso3166 (priv->current_parser_layout, priv->current_parser_iso3166Id);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv->current_parser_iso3166Id = NULL;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else if (strcmp (element_name, "group") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (!priv->current_parser_group->description || !priv->current_parser_group->id)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
|
rpm-build |
18b009 |
"'group' elements must enclose 'description' and 'name' elements");
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_hash_table_replace (priv->option_groups_table,
|
|
rpm-build |
18b009 |
priv->current_parser_group->id,
|
|
rpm-build |
18b009 |
priv->current_parser_group);
|
|
rpm-build |
18b009 |
priv->current_parser_group = NULL;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else if (strcmp (element_name, "option") == 0)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (!priv->current_parser_option->description || !priv->current_parser_option->id)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
|
rpm-build |
18b009 |
"'option' elements must enclose 'description' and 'name' elements");
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_hash_table_replace (priv->current_parser_group->options_table,
|
|
rpm-build |
18b009 |
priv->current_parser_option->id,
|
|
rpm-build |
18b009 |
priv->current_parser_option);
|
|
rpm-build |
18b009 |
priv->current_parser_option = NULL;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
parse_text (GMarkupParseContext *context,
|
|
rpm-build |
18b009 |
const gchar *text,
|
|
rpm-build |
18b009 |
gsize text_len,
|
|
rpm-build |
18b009 |
gpointer data,
|
|
rpm-build |
18b009 |
GError **error)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv = GNOME_XKB_INFO (data)->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (priv->current_parser_text)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
*priv->current_parser_text = g_strndup (text, text_len);
|
|
rpm-build |
18b009 |
priv->current_parser_text = NULL;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
parse_error (GMarkupParseContext *context,
|
|
rpm-build |
18b009 |
GError *error,
|
|
rpm-build |
18b009 |
gpointer data)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv = GNOME_XKB_INFO (data)->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
free_option_group (priv->current_parser_group);
|
|
rpm-build |
18b009 |
free_option (priv->current_parser_option);
|
|
rpm-build |
18b009 |
free_layout (priv->current_parser_layout);
|
|
rpm-build |
18b009 |
free_layout (priv->current_parser_variant);
|
|
rpm-build |
18b009 |
g_free (priv->current_parser_iso639Id);
|
|
rpm-build |
18b009 |
g_free (priv->current_parser_iso3166Id);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static const GMarkupParser markup_parser = {
|
|
rpm-build |
18b009 |
parse_start_element,
|
|
rpm-build |
18b009 |
parse_end_element,
|
|
rpm-build |
18b009 |
parse_text,
|
|
rpm-build |
18b009 |
NULL,
|
|
rpm-build |
18b009 |
parse_error
|
|
rpm-build |
18b009 |
};
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
parse_rules_file (GnomeXkbInfo *self,
|
|
rpm-build |
18b009 |
const gchar *path,
|
|
rpm-build |
18b009 |
GError **error)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
gchar *buffer;
|
|
rpm-build |
18b009 |
gsize length;
|
|
rpm-build |
18b009 |
GMarkupParseContext *context;
|
|
rpm-build |
18b009 |
GError *sub_error = NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_file_get_contents (path, &buffer, &length, &sub_error);
|
|
rpm-build |
18b009 |
if (sub_error)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
g_propagate_error (error, sub_error);
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
context = g_markup_parse_context_new (&markup_parser, 0, self, NULL);
|
|
rpm-build |
18b009 |
g_markup_parse_context_parse (context, buffer, length, &sub_error);
|
|
rpm-build |
18b009 |
g_markup_parse_context_free (context);
|
|
rpm-build |
18b009 |
g_free (buffer);
|
|
rpm-build |
18b009 |
if (sub_error)
|
|
rpm-build |
18b009 |
g_propagate_error (error, sub_error);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
parse_rules (GnomeXkbInfo *self)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv = self->priv;
|
|
rpm-build |
18b009 |
GSettings *settings;
|
|
rpm-build |
18b009 |
gboolean show_all_sources;
|
|
rpm-build |
18b009 |
gchar *file_path;
|
|
rpm-build |
18b009 |
GError *error = NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
/* Make sure the translated strings we get from XKEYBOARD_CONFIG() are
|
|
rpm-build |
18b009 |
* in UTF-8 and not in the current locale */
|
|
rpm-build |
18b009 |
bind_textdomain_codeset ("xkeyboard-config", "UTF-8");
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
/* Maps option group ids to XkbOptionGroup structs. Owns the
|
|
rpm-build |
18b009 |
XkbOptionGroup structs. */
|
|
rpm-build |
18b009 |
priv->option_groups_table = g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
rpm-build |
18b009 |
NULL, free_option_group);
|
|
rpm-build |
18b009 |
/* Maps country strings to a GHashTable which is a set of Layout
|
|
rpm-build |
18b009 |
struct pointers into the Layout structs stored in
|
|
rpm-build |
18b009 |
layouts_table. */
|
|
rpm-build |
18b009 |
priv->layouts_by_country = g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
rpm-build |
18b009 |
g_free, (GDestroyNotify) g_hash_table_destroy);
|
|
rpm-build |
18b009 |
/* Maps language strings to a GHashTable which is a set of Layout
|
|
rpm-build |
18b009 |
struct pointers into the Layout structs stored in
|
|
rpm-build |
18b009 |
layouts_table. */
|
|
rpm-build |
18b009 |
priv->layouts_by_language = g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
rpm-build |
18b009 |
g_free, (GDestroyNotify) g_hash_table_destroy);
|
|
rpm-build |
18b009 |
/* Maps layout ids to Layout structs. Owns the Layout structs. */
|
|
rpm-build |
18b009 |
priv->layouts_table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, free_layout);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
file_path = get_xml_rules_file_path (".xml");
|
|
rpm-build |
18b009 |
parse_rules_file (self, file_path, &error);
|
|
rpm-build |
18b009 |
if (error)
|
|
rpm-build |
18b009 |
goto cleanup;
|
|
rpm-build |
18b009 |
g_free (file_path);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
settings = g_settings_new ("org.gnome.desktop.input-sources");
|
|
rpm-build |
18b009 |
show_all_sources = g_settings_get_boolean (settings, "show-all-sources");
|
|
rpm-build |
18b009 |
g_object_unref (settings);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!show_all_sources)
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
file_path = get_xml_rules_file_path (".extras.xml");
|
|
rpm-build |
18b009 |
parse_rules_file (self, file_path, &error);
|
|
rpm-build |
18b009 |
if (error)
|
|
rpm-build |
18b009 |
goto cleanup;
|
|
rpm-build |
18b009 |
g_free (file_path);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
return;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
cleanup:
|
|
rpm-build |
18b009 |
g_warning ("Failed to load XKB rules file %s: %s", file_path, error->message);
|
|
rpm-build |
18b009 |
g_clear_pointer (&error, g_error_free);
|
|
rpm-build |
18b009 |
g_clear_pointer (&file_path, g_free);
|
|
rpm-build |
18b009 |
g_clear_pointer (&priv->option_groups_table, g_hash_table_destroy);
|
|
rpm-build |
18b009 |
g_clear_pointer (&priv->layouts_by_country, g_hash_table_destroy);
|
|
rpm-build |
18b009 |
g_clear_pointer (&priv->layouts_by_language, g_hash_table_destroy);
|
|
rpm-build |
18b009 |
g_clear_pointer (&priv->layouts_table, g_hash_table_destroy);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static gboolean
|
|
rpm-build |
18b009 |
ensure_rules_are_parsed (GnomeXkbInfo *self)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv = self->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!priv->layouts_table)
|
|
rpm-build |
18b009 |
parse_rules (self);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
return !!priv->layouts_table;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
gnome_xkb_info_init (GnomeXkbInfo *self)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GNOME_TYPE_XKB_INFO, GnomeXkbInfoPrivate);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
gnome_xkb_info_finalize (GObject *self)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv = GNOME_XKB_INFO (self)->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (priv->option_groups_table)
|
|
rpm-build |
18b009 |
g_hash_table_destroy (priv->option_groups_table);
|
|
rpm-build |
18b009 |
if (priv->layouts_by_country)
|
|
rpm-build |
18b009 |
g_hash_table_destroy (priv->layouts_by_country);
|
|
rpm-build |
18b009 |
if (priv->layouts_by_language)
|
|
rpm-build |
18b009 |
g_hash_table_destroy (priv->layouts_by_language);
|
|
rpm-build |
18b009 |
if (priv->layouts_table)
|
|
rpm-build |
18b009 |
g_hash_table_destroy (priv->layouts_table);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
G_OBJECT_CLASS (gnome_xkb_info_parent_class)->finalize (self);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
gnome_xkb_info_class_init (GnomeXkbInfoClass *klass)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
gobject_class->finalize = gnome_xkb_info_finalize;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_type_class_add_private (gobject_class, sizeof (GnomeXkbInfoPrivate));
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
/**
|
|
rpm-build |
18b009 |
* gnome_xkb_info_new:
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Returns: (transfer full): a new #GnomeXkbInfo instance.
|
|
rpm-build |
18b009 |
*/
|
|
rpm-build |
18b009 |
GnomeXkbInfo *
|
|
rpm-build |
18b009 |
gnome_xkb_info_new (void)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
return g_object_new (GNOME_TYPE_XKB_INFO, NULL);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
/**
|
|
rpm-build |
18b009 |
* gnome_xkb_info_get_all_layouts:
|
|
rpm-build |
18b009 |
* @self: a #GnomeXkbInfo
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Returns a list of all layout identifiers we know about.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Return value: (transfer container) (element-type utf8): the list
|
|
rpm-build |
18b009 |
* of layout names. The caller takes ownership of the #GList but not
|
|
rpm-build |
18b009 |
* of the strings themselves, those are internally allocated and must
|
|
rpm-build |
18b009 |
* not be modified.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Since: 3.6
|
|
rpm-build |
18b009 |
*/
|
|
rpm-build |
18b009 |
GList *
|
|
rpm-build |
18b009 |
gnome_xkb_info_get_all_layouts (GnomeXkbInfo *self)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_return_val_if_fail (GNOME_IS_XKB_INFO (self), NULL);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv = self->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!ensure_rules_are_parsed (self))
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
return g_hash_table_get_keys (priv->layouts_table);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
/**
|
|
rpm-build |
18b009 |
* gnome_xkb_info_get_all_option_groups:
|
|
rpm-build |
18b009 |
* @self: a #GnomeXkbInfo
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Returns a list of all option group identifiers we know about.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Return value: (transfer container) (element-type utf8): the list
|
|
rpm-build |
18b009 |
* of option group ids. The caller takes ownership of the #GList but
|
|
rpm-build |
18b009 |
* not of the strings themselves, those are internally allocated and
|
|
rpm-build |
18b009 |
* must not be modified.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Since: 3.6
|
|
rpm-build |
18b009 |
*/
|
|
rpm-build |
18b009 |
GList *
|
|
rpm-build |
18b009 |
gnome_xkb_info_get_all_option_groups (GnomeXkbInfo *self)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_return_val_if_fail (GNOME_IS_XKB_INFO (self), NULL);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv = self->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!ensure_rules_are_parsed (self))
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
return g_hash_table_get_keys (priv->option_groups_table);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
/**
|
|
rpm-build |
18b009 |
* gnome_xkb_info_description_for_group:
|
|
rpm-build |
18b009 |
* @self: a #GnomeXkbInfo
|
|
rpm-build |
18b009 |
* @group_id: identifier for group
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Return value: the translated description for the group @group_id.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Since: 3.8
|
|
rpm-build |
18b009 |
*/
|
|
rpm-build |
18b009 |
const gchar *
|
|
rpm-build |
18b009 |
gnome_xkb_info_description_for_group (GnomeXkbInfo *self,
|
|
rpm-build |
18b009 |
const gchar *group_id)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv;
|
|
rpm-build |
18b009 |
const XkbOptionGroup *group;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_return_val_if_fail (GNOME_IS_XKB_INFO (self), NULL);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv = self->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!ensure_rules_are_parsed (self))
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
group = g_hash_table_lookup (priv->option_groups_table, group_id);
|
|
rpm-build |
18b009 |
if (!group)
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
return XKEYBOARD_CONFIG_(group->description);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
/**
|
|
rpm-build |
18b009 |
* gnome_xkb_info_get_options_for_group:
|
|
rpm-build |
18b009 |
* @self: a #GnomeXkbInfo
|
|
rpm-build |
18b009 |
* @group_id: group's identifier about which to retrieve the options
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Returns a list of all option identifiers we know about for group
|
|
rpm-build |
18b009 |
* @group_id.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Return value: (transfer container) (element-type utf8): the list
|
|
rpm-build |
18b009 |
* of option ids. The caller takes ownership of the #GList but not of
|
|
rpm-build |
18b009 |
* the strings themselves, those are internally allocated and must not
|
|
rpm-build |
18b009 |
* be modified.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Since: 3.6
|
|
rpm-build |
18b009 |
*/
|
|
rpm-build |
18b009 |
GList *
|
|
rpm-build |
18b009 |
gnome_xkb_info_get_options_for_group (GnomeXkbInfo *self,
|
|
rpm-build |
18b009 |
const gchar *group_id)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv;
|
|
rpm-build |
18b009 |
const XkbOptionGroup *group;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_return_val_if_fail (GNOME_IS_XKB_INFO (self), NULL);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv = self->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!ensure_rules_are_parsed (self))
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
group = g_hash_table_lookup (priv->option_groups_table, group_id);
|
|
rpm-build |
18b009 |
if (!group)
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
return g_hash_table_get_keys (group->options_table);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
/**
|
|
rpm-build |
18b009 |
* gnome_xkb_info_description_for_option:
|
|
rpm-build |
18b009 |
* @self: a #GnomeXkbInfo
|
|
rpm-build |
18b009 |
* @group_id: identifier for group containing the option
|
|
rpm-build |
18b009 |
* @id: option identifier
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Return value: the translated description for the option @id.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Since: 3.6
|
|
rpm-build |
18b009 |
*/
|
|
rpm-build |
18b009 |
const gchar *
|
|
rpm-build |
18b009 |
gnome_xkb_info_description_for_option (GnomeXkbInfo *self,
|
|
rpm-build |
18b009 |
const gchar *group_id,
|
|
rpm-build |
18b009 |
const gchar *id)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv;
|
|
rpm-build |
18b009 |
const XkbOptionGroup *group;
|
|
rpm-build |
18b009 |
const XkbOption *option;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_return_val_if_fail (GNOME_IS_XKB_INFO (self), NULL);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv = self->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!ensure_rules_are_parsed (self))
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
group = g_hash_table_lookup (priv->option_groups_table, group_id);
|
|
rpm-build |
18b009 |
if (!group)
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
option = g_hash_table_lookup (group->options_table, id);
|
|
rpm-build |
18b009 |
if (!option)
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
return XKEYBOARD_CONFIG_(option->description);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
/**
|
|
rpm-build |
18b009 |
* gnome_xkb_info_get_layout_info:
|
|
rpm-build |
18b009 |
* @self: a #GnomeXkbInfo
|
|
rpm-build |
18b009 |
* @id: layout's identifier about which to retrieve the info
|
|
rpm-build |
18b009 |
* @display_name: (out) (allow-none) (transfer none): location to store
|
|
rpm-build |
18b009 |
* the layout's display name, or %NULL
|
|
rpm-build |
18b009 |
* @short_name: (out) (allow-none) (transfer none): location to store
|
|
rpm-build |
18b009 |
* the layout's short name, or %NULL
|
|
rpm-build |
18b009 |
* @xkb_layout: (out) (allow-none) (transfer none): location to store
|
|
rpm-build |
18b009 |
* the layout's XKB name, or %NULL
|
|
rpm-build |
18b009 |
* @xkb_variant: (out) (allow-none) (transfer none): location to store
|
|
rpm-build |
18b009 |
* the layout's XKB variant, or %NULL
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Retrieves information about a layout. Both @display_name and
|
|
rpm-build |
18b009 |
* @short_name are suitable to show in UIs and might be localized if
|
|
rpm-build |
18b009 |
* translations are available.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Some layouts don't provide a short name (2 or 3 letters) or don't
|
|
rpm-build |
18b009 |
* specify a XKB variant, in those cases @short_name or @xkb_variant
|
|
rpm-build |
18b009 |
* are empty strings, i.e. "".
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* If the given layout doesn't exist the return value is %FALSE and
|
|
rpm-build |
18b009 |
* all the (out) parameters are set to %NULL.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Return value: %TRUE if the layout exists or %FALSE otherwise.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Since: 3.6
|
|
rpm-build |
18b009 |
*/
|
|
rpm-build |
18b009 |
gboolean
|
|
rpm-build |
18b009 |
gnome_xkb_info_get_layout_info (GnomeXkbInfo *self,
|
|
rpm-build |
18b009 |
const gchar *id,
|
|
rpm-build |
18b009 |
const gchar **display_name,
|
|
rpm-build |
18b009 |
const gchar **short_name,
|
|
rpm-build |
18b009 |
const gchar **xkb_layout,
|
|
rpm-build |
18b009 |
const gchar **xkb_variant)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv;
|
|
rpm-build |
18b009 |
const Layout *layout;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (display_name)
|
|
rpm-build |
18b009 |
*display_name = NULL;
|
|
rpm-build |
18b009 |
if (short_name)
|
|
rpm-build |
18b009 |
*short_name = NULL;
|
|
rpm-build |
18b009 |
if (xkb_layout)
|
|
rpm-build |
18b009 |
*xkb_layout = NULL;
|
|
rpm-build |
18b009 |
if (xkb_variant)
|
|
rpm-build |
18b009 |
*xkb_variant = NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_return_val_if_fail (GNOME_IS_XKB_INFO (self), FALSE);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv = self->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!ensure_rules_are_parsed (self))
|
|
rpm-build |
18b009 |
return FALSE;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!g_hash_table_lookup_extended (priv->layouts_table, id, NULL, (gpointer *)&layout))
|
|
rpm-build |
18b009 |
return FALSE;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (display_name)
|
|
rpm-build |
18b009 |
*display_name = XKEYBOARD_CONFIG_(layout->description);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!layout->is_variant)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (short_name)
|
|
rpm-build |
18b009 |
*short_name = XKEYBOARD_CONFIG_(layout->short_desc ? layout->short_desc : "");
|
|
rpm-build |
18b009 |
if (xkb_layout)
|
|
rpm-build |
18b009 |
*xkb_layout = layout->xkb_name;
|
|
rpm-build |
18b009 |
if (xkb_variant)
|
|
rpm-build |
18b009 |
*xkb_variant = "";
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
else
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
if (short_name)
|
|
rpm-build |
18b009 |
*short_name = XKEYBOARD_CONFIG_(layout->short_desc ? layout->short_desc :
|
|
rpm-build |
18b009 |
layout->main_layout->short_desc ? layout->main_layout->short_desc : "");
|
|
rpm-build |
18b009 |
if (xkb_layout)
|
|
rpm-build |
18b009 |
*xkb_layout = layout->main_layout->xkb_name;
|
|
rpm-build |
18b009 |
if (xkb_variant)
|
|
rpm-build |
18b009 |
*xkb_variant = layout->xkb_name;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
return TRUE;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
collect_layout_ids (gpointer key,
|
|
rpm-build |
18b009 |
gpointer value,
|
|
rpm-build |
18b009 |
gpointer data)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
Layout *layout = value;
|
|
rpm-build |
18b009 |
GList **list = data;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
*list = g_list_prepend (*list, layout->id);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
/**
|
|
rpm-build |
18b009 |
* gnome_xkb_info_get_layouts_for_language:
|
|
rpm-build |
18b009 |
* @self: a #GnomeXkbInfo
|
|
rpm-build |
18b009 |
* @language_code: an ISO 639 code string
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Returns a list of all layout identifiers we know about for
|
|
rpm-build |
18b009 |
* @language_code.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Return value: (transfer container) (element-type utf8): the list
|
|
rpm-build |
18b009 |
* of layout ids. The caller takes ownership of the #GList but not of
|
|
rpm-build |
18b009 |
* the strings themselves, those are internally allocated and must not
|
|
rpm-build |
18b009 |
* be modified.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Since: 3.8
|
|
rpm-build |
18b009 |
*/
|
|
rpm-build |
18b009 |
GList *
|
|
rpm-build |
18b009 |
gnome_xkb_info_get_layouts_for_language (GnomeXkbInfo *self,
|
|
rpm-build |
18b009 |
const gchar *language_code)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv;
|
|
rpm-build |
18b009 |
GHashTable *layouts_for_language;
|
|
rpm-build |
18b009 |
gchar *language;
|
|
rpm-build |
18b009 |
GList *list;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_return_val_if_fail (GNOME_IS_XKB_INFO (self), NULL);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv = self->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!ensure_rules_are_parsed (self))
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
language = gnome_get_language_from_code (language_code, NULL);
|
|
rpm-build |
18b009 |
if (!language)
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
layouts_for_language = g_hash_table_lookup (priv->layouts_by_language, language);
|
|
rpm-build |
18b009 |
g_free (language);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!layouts_for_language)
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
list = NULL;
|
|
rpm-build |
18b009 |
g_hash_table_foreach (layouts_for_language, collect_layout_ids, &list);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
return list;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
/**
|
|
rpm-build |
18b009 |
* gnome_xkb_info_get_layouts_for_country:
|
|
rpm-build |
18b009 |
* @self: a #GnomeXkbInfo
|
|
rpm-build |
18b009 |
* @country_code: an ISO 3166 code string
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Returns a list of all layout identifiers we know about for
|
|
rpm-build |
18b009 |
* @country_code.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Return value: (transfer container) (element-type utf8): the list
|
|
rpm-build |
18b009 |
* of layout ids. The caller takes ownership of the #GList but not of
|
|
rpm-build |
18b009 |
* the strings themselves, those are internally allocated and must not
|
|
rpm-build |
18b009 |
* be modified.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Since: 3.8
|
|
rpm-build |
18b009 |
*/
|
|
rpm-build |
18b009 |
GList *
|
|
rpm-build |
18b009 |
gnome_xkb_info_get_layouts_for_country (GnomeXkbInfo *self,
|
|
rpm-build |
18b009 |
const gchar *country_code)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv;
|
|
rpm-build |
18b009 |
GHashTable *layouts_for_country;
|
|
rpm-build |
18b009 |
gchar *country;
|
|
rpm-build |
18b009 |
GList *list;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_return_val_if_fail (GNOME_IS_XKB_INFO (self), NULL);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv = self->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!ensure_rules_are_parsed (self))
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
country = gnome_get_country_from_code (country_code, NULL);
|
|
rpm-build |
18b009 |
if (!country)
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
layouts_for_country = g_hash_table_lookup (priv->layouts_by_country, country);
|
|
rpm-build |
18b009 |
g_free (country);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!layouts_for_country)
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
list = NULL;
|
|
rpm-build |
18b009 |
g_hash_table_foreach (layouts_for_country, collect_layout_ids, &list);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
return list;
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
static void
|
|
rpm-build |
18b009 |
collect_languages (gpointer value,
|
|
rpm-build |
18b009 |
gpointer data)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
gchar *language = value;
|
|
rpm-build |
18b009 |
GList **list = data;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
*list = g_list_append (*list, language);
|
|
rpm-build |
18b009 |
}
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
/**
|
|
rpm-build |
18b009 |
* gnome_xkb_info_get_languages_for_layout:
|
|
rpm-build |
18b009 |
* @self: a #GnomeXkbInfo
|
|
rpm-build |
18b009 |
* @layout_id: a layout identifier
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Returns a list of all languages supported by a layout, given by
|
|
rpm-build |
18b009 |
* @layout_id.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Return value: (transfer container) (element-type utf8): the list of
|
|
rpm-build |
18b009 |
* ISO 639 code strings. The caller takes ownership of the #GList but
|
|
rpm-build |
18b009 |
* not of the strings themselves, those are internally allocated and
|
|
rpm-build |
18b009 |
* must not be modified.
|
|
rpm-build |
18b009 |
*
|
|
rpm-build |
18b009 |
* Since: 3.18
|
|
rpm-build |
18b009 |
*/
|
|
rpm-build |
18b009 |
GList *
|
|
rpm-build |
18b009 |
gnome_xkb_info_get_languages_for_layout (GnomeXkbInfo *self,
|
|
rpm-build |
18b009 |
const gchar *layout_id)
|
|
rpm-build |
18b009 |
{
|
|
rpm-build |
18b009 |
GnomeXkbInfoPrivate *priv;
|
|
rpm-build |
18b009 |
Layout *layout;
|
|
rpm-build |
18b009 |
GList *list;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
g_return_val_if_fail (GNOME_IS_XKB_INFO (self), NULL);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
priv = self->priv;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!ensure_rules_are_parsed (self))
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
layout = g_hash_table_lookup (priv->layouts_table, layout_id);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
if (!layout)
|
|
rpm-build |
18b009 |
return NULL;
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
list = NULL;
|
|
rpm-build |
18b009 |
g_slist_foreach (layout->iso639Ids, collect_languages, &list);
|
|
rpm-build |
18b009 |
|
|
rpm-build |
18b009 |
return list;
|
|
rpm-build |
18b009 |
}
|