summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--libxklavier/xklavier_config.c158
-rw-r--r--libxklavier/xklavier_config_iso.c111
-rw-r--r--libxklavier/xklavier_private.h17
4 files changed, 194 insertions, 97 deletions
diff --git a/ChangeLog b/ChangeLog
index 501c865..b4a5d90 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-06-19 svu
+
+ * libxklavier/xklavier_config.c, libxklavier/xklavier_config_iso.c,
+ libxklavier/xklavier_private.h: use xml files with exotic layouts
+
2009-06-02 svu
* libxklavier/xklavier_config_iso.c: changed g_snprintf to more
diff --git a/libxklavier/xklavier_config.c b/libxklavier/xklavier_config.c
index 0607939..5d95b79 100644
--- a/libxklavier/xklavier_config.c
+++ b/libxklavier/xklavier_config.c
@@ -37,16 +37,15 @@ static xmlXPathCompExprPtr option_groups_xpath;
static GRegex **xml_encode_regexen = NULL;
static GRegex **xml_decode_regexen = NULL;
-static const char const *xml_decode_regexen_str[] =
- { "<", ">", "&" };
-static const char const *xml_encode_regexen_str[] = { "<", ">", "&" };
+static const char *xml_decode_regexen_str[] = { "&lt;", "&gt;", "&amp;" };
+static const char *xml_encode_regexen_str[] = { "<", ">", "&" };
/* gettext domain for translations */
#define XKB_DOMAIN "xkeyboard-config"
enum {
PROP_0,
- PROP_ENGINE,
+ PROP_ENGINE
};
static gboolean
@@ -285,13 +284,21 @@ xkl_config_registry_foreach_in_xpath(XklConfigRegistry * config,
gpointer data)
{
xmlXPathObjectPtr xpath_obj;
+ gint i;
if (!xkl_config_registry_is_initialized(config))
return;
- xpath_obj = xmlXPathCompiledEval(xpath_comp_expr,
- xkl_config_registry_priv
- (config, xpath_context));
- if (xpath_obj != NULL) {
+
+ for (i = XKL_NUMBER_OF_REGISTRY_DOCS; --i >= 0;) {
+ xmlXPathContextPtr xmlctxt =
+ xkl_config_registry_priv(config, xpath_contexts[i]);
+ if (xmlctxt == NULL)
+ continue;
+
+ xpath_obj = xmlXPathCompiledEval(xpath_comp_expr, xmlctxt);
+ if (xpath_obj == NULL)
+ continue;
+
xkl_config_registry_foreach_in_nodeset(config,
xpath_obj->nodesetval,
func, data);
@@ -311,14 +318,23 @@ xkl_config_registry_foreach_in_xpath_with_param(XklConfigRegistry
{
char xpath_expr[1024];
xmlXPathObjectPtr xpath_obj;
+ gint i;
if (!xkl_config_registry_is_initialized(config))
return;
g_snprintf(xpath_expr, sizeof xpath_expr, format, value);
- xpath_obj = xmlXPathEval((unsigned char *) xpath_expr,
- xkl_config_registry_priv(config,
- xpath_context));
- if (xpath_obj != NULL) {
+
+ for (i = XKL_NUMBER_OF_REGISTRY_DOCS; --i >= 0;) {
+ xmlXPathContextPtr xmlctxt =
+ xkl_config_registry_priv(config, xpath_contexts[i]);
+ if (xmlctxt == NULL)
+ continue;
+
+ xpath_obj =
+ xmlXPathEval((unsigned char *) xpath_expr, xmlctxt);
+ if (xpath_obj == NULL)
+ continue;
+
xkl_config_registry_foreach_in_nodeset(config,
xpath_obj->nodesetval,
func, data);
@@ -337,28 +353,38 @@ xkl_config_registry_find_object(XklConfigRegistry * config,
xmlNodeSetPtr nodes;
gboolean rv = FALSE;
gchar xpath_expr[1024];
+ gint i;
if (!xkl_config_registry_is_initialized(config))
return FALSE;
g_snprintf(xpath_expr, sizeof xpath_expr, format, arg1,
pitem->name);
- xpath_obj =
- xmlXPathEval((unsigned char *) xpath_expr,
- xkl_config_registry_priv(config, xpath_context));
- if (xpath_obj == NULL)
- return FALSE;
- nodes = xpath_obj->nodesetval;
- if (nodes != NULL && nodes->nodeTab != NULL && nodes->nodeNr > 0) {
- rv = xkl_read_config_item(config, nodes->nodeTab[0],
- pitem);
- if (pnode != NULL) {
- *pnode = *nodes->nodeTab;
+ for (i = XKL_NUMBER_OF_REGISTRY_DOCS; --i >= 0;) {
+ xmlXPathContextPtr xmlctxt =
+ xkl_config_registry_priv(config, xpath_contexts[i]);
+ if (xmlctxt == NULL)
+ continue;
+
+ xpath_obj =
+ xmlXPathEval((unsigned char *) xpath_expr, xmlctxt);
+ if (xpath_obj == NULL)
+ continue;
+
+ nodes = xpath_obj->nodesetval;
+ if (nodes != NULL && nodes->nodeTab != NULL
+ && nodes->nodeNr > 0) {
+ rv = xkl_read_config_item(config,
+ nodes->nodeTab[0],
+ pitem);
+ if (pnode != NULL) {
+ *pnode = *nodes->nodeTab;
+ }
}
- }
- xmlXPathFreeObject(xpath_obj);
+ xmlXPathFreeObject(xpath_obj);
+ }
return rv;
}
@@ -518,9 +544,11 @@ xkl_xml_sax_end_element_ns(void *ctx,
gboolean
xkl_config_registry_load_from_file(XklConfigRegistry * config,
- const gchar * file_name)
+ const gchar * file_name, gint docidx)
{
xmlParserCtxtPtr ctxt = xmlNewParserCtxt();
+ xmlDocPtr doc;
+
xkl_debug(100, "Loading XML registry from file %s\n", file_name);
/* Filter out all unneeded languages! */
@@ -529,18 +557,20 @@ xkl_config_registry_load_from_file(XklConfigRegistry * config,
ctxt->sax->endElementNs = xkl_xml_sax_end_element_ns;
ctxt->sax->characters = xkl_xml_sax_characters;
- xkl_config_registry_priv(config, doc) =
+ doc = xkl_config_registry_priv(config, docs[docidx]) =
xmlCtxtReadFile(ctxt, file_name, NULL, XML_PARSE_NOBLANKS);
xmlFreeParserCtxt(ctxt);
- if (xkl_config_registry_priv(config, doc) == NULL) {
- xkl_config_registry_priv(config, xpath_context) = NULL;
+ if (doc == NULL) {
+ xkl_config_registry_priv(config, xpath_contexts[docidx]) =
+ NULL;
xkl_last_error_message =
- "Could not parse XKB configuration registry";
+ "Could not parse primary XKB configuration registry";
return FALSE;
}
- xkl_config_registry_priv(config, xpath_context) =
- xmlXPathNewContext(xkl_config_registry_priv(config, doc));
+
+ xkl_config_registry_priv(config, xpath_contexts[docidx]) =
+ xmlXPathNewContext(doc);
return TRUE;
}
@@ -566,18 +596,39 @@ xkl_config_registry_load_helper(XklConfigRegistry * config,
return FALSE;
}
- return xkl_config_registry_load_from_file(config, file_name);
+ if (!xkl_config_registry_load_from_file(config, file_name, 0))
+ return FALSE;
+
+ g_snprintf(file_name, sizeof file_name, "%s/%s.extras.xml",
+ base_dir, rf);
+
+ /* no extras - ok, no problem */
+ if (stat(file_name, &stat_buf) != 0)
+ return TRUE;
+
+ return xkl_config_registry_load_from_file(config, file_name, 1);
}
void
xkl_config_registry_free(XklConfigRegistry * config)
{
+ gint i;
if (xkl_config_registry_is_initialized(config)) {
- xmlXPathFreeContext(xkl_config_registry_priv
- (config, xpath_context));
- xmlFreeDoc(xkl_config_registry_priv(config, doc));
- xkl_config_registry_priv(config, xpath_context) = NULL;
- xkl_config_registry_priv(config, doc) = NULL;
+ for (i = XKL_NUMBER_OF_REGISTRY_DOCS; --i >= 0;) {
+ xmlXPathContextPtr xmlctxt =
+ xkl_config_registry_priv(config,
+ xpath_contexts[i]);
+ if (xmlctxt == NULL)
+ continue;
+
+ xmlXPathFreeContext(xmlctxt);
+ xmlFreeDoc(xkl_config_registry_priv
+ (config, docs[i]));
+ xkl_config_registry_priv(config,
+ xpath_contexts[i]) = NULL;
+ xkl_config_registry_priv(config, docs[i]) = NULL;
+ }
+
}
}
@@ -621,19 +672,30 @@ xkl_config_registry_foreach_option_group(XklConfigRegistry *
func, gpointer data)
{
xmlXPathObjectPtr xpath_obj;
- gint i;
+ gint i, j;
if (!xkl_config_registry_is_initialized(config))
return;
- xpath_obj =
- xmlXPathCompiledEval(option_groups_xpath,
- xkl_config_registry_priv(config,
- xpath_context));
- if (xpath_obj != NULL) {
- xmlNodeSetPtr nodes = xpath_obj->nodesetval;
- xmlNodePtr *pnode = nodes->nodeTab;
- XklConfigItem *ci = xkl_config_item_new();
- for (i = nodes->nodeNr; --i >= 0;) {
+
+ for (i = XKL_NUMBER_OF_REGISTRY_DOCS; --i >= 0;) {
+ xmlNodeSetPtr nodes;
+ xmlNodePtr *pnode;
+ XklConfigItem *ci;
+
+ xmlXPathContextPtr xmlctxt =
+ xkl_config_registry_priv(config, xpath_contexts[i]);
+ if (xmlctxt == NULL)
+ continue;
+
+ xpath_obj =
+ xmlXPathCompiledEval(option_groups_xpath, xmlctxt);
+ if (xpath_obj == NULL)
+ continue;
+
+ nodes = xpath_obj->nodesetval;
+ pnode = nodes->nodeTab;
+ ci = xkl_config_item_new();
+ for (j = nodes->nodeNr; --j >= 0;) {
if (xkl_read_config_item(config, *pnode, ci)) {
gboolean allow_multisel = TRUE;
diff --git a/libxklavier/xklavier_config_iso.c b/libxklavier/xklavier_config_iso.c
index 07d32b1..aac978a 100644
--- a/libxklavier/xklavier_config_iso.c
+++ b/libxklavier/xklavier_config_iso.c
@@ -211,6 +211,7 @@ xkl_config_registry_foreach_iso_code(XklConfigRegistry * config,
const gchar **xpath_expr;
gpointer key, value;
XklConfigItem *ci;
+ gint i;
if (!xkl_config_registry_is_initialized(config))
return;
@@ -218,38 +219,50 @@ xkl_config_registry_foreach_iso_code(XklConfigRegistry * config,
code_pairs = g_hash_table_new(g_str_hash, g_str_equal);
for (xpath_expr = xpath_exprs; *xpath_expr; xpath_expr++) {
- xpath_obj =
- xmlXPathEval((unsigned char *) *xpath_expr,
- xkl_config_registry_priv(config,
- xpath_context));
- if (xpath_obj != NULL) {
+ for (i = XKL_NUMBER_OF_REGISTRY_DOCS; --i >= 0;) {
gint ni;
- xmlNodeSetPtr nodes = xpath_obj->nodesetval;
- if (nodes != NULL) {
- xmlNodePtr *node = nodes->nodeTab;
- for (ni = nodes->nodeNr; --ni >= 0;) {
- gchar *iso_code =
- (gchar *) (*node)->children->
- content;
- const gchar *description;
- iso_code =
- to_upper ?
- g_ascii_strup(iso_code,
- -1) :
- g_strdup(iso_code);
- description = dgf(iso_code);
+ xmlNodePtr *node;
+ xmlNodeSetPtr nodes;
+
+ xmlXPathContextPtr xmlctxt =
+ xkl_config_registry_priv(config,
+ xpath_contexts[i]);
+ if (xmlctxt == NULL)
+ continue;
+
+ xpath_obj =
+ xmlXPathEval((unsigned char *) *xpath_expr,
+ xmlctxt);
+ if (xpath_obj == NULL)
+ continue;
+
+ nodes = xpath_obj->nodesetval;
+ if (nodes == NULL) {
+ xmlXPathFreeObject(xpath_obj);
+ continue;
+ }
+
+ node = nodes->nodeTab;
+ for (ni = nodes->nodeNr; --ni >= 0;) {
+ gchar *iso_code =
+ (gchar *) (*node)->children->content;
+ const gchar *description;
+ iso_code =
+ to_upper ?
+ g_ascii_strup(iso_code,
+ -1) : g_strdup(iso_code);
+ description = dgf(iso_code);
/* If there is a mapping to some ISO description - consider it as ISO code (well, it is just an assumption) */
- if (description)
- g_hash_table_insert
- (code_pairs,
- g_strdup
- (iso_code),
- g_strdup
- (description));
- g_free(iso_code);
- node++;
- }
+ if (description)
+ g_hash_table_insert
+ (code_pairs,
+ g_strdup
+ (iso_code),
+ g_strdup(description));
+ g_free(iso_code);
+ node++;
}
+
xmlXPathFreeObject(xpath_obj);
}
}
@@ -316,9 +329,11 @@ xkl_config_registry_foreach_iso_variant(XklConfigRegistry *
should_code_be_lowered2[])
{
xmlXPathObjectPtr xpath_obj;
+ xmlNodeSetPtr nodes;
const gchar **xpath_expr;
const gboolean *is_low_id = should_code_be_lowered1;
gchar *low_iso_code;
+ gint i;
if (!xkl_config_registry_is_initialized(config))
return;
@@ -329,12 +344,19 @@ xkl_config_registry_foreach_iso_variant(XklConfigRegistry *
xpath_expr++, is_low_id++) {
const gchar *aic = *is_low_id ? low_iso_code : iso_code;
gchar *xpe = g_strdup_printf(*xpath_expr, aic);
- xpath_obj =
- xmlXPathEval((unsigned char *) xpe,
- xkl_config_registry_priv(config,
- xpath_context));
- if (xpath_obj != NULL) {
- xmlNodeSetPtr nodes = xpath_obj->nodesetval;
+ for (i = XKL_NUMBER_OF_REGISTRY_DOCS; --i >= 0;) {
+ xmlXPathContextPtr xmlctxt =
+ xkl_config_registry_priv(config,
+ xpath_contexts[i]);
+ if (xmlctxt == NULL)
+ continue;
+
+ xpath_obj =
+ xmlXPathEval((unsigned char *) xpe, xmlctxt);
+ if (xpath_obj == NULL)
+ continue;
+
+ nodes = xpath_obj->nodesetval;
if (nodes != NULL) {
gint ni;
xmlNodePtr *node = nodes->nodeTab;
@@ -358,12 +380,19 @@ xkl_config_registry_foreach_iso_variant(XklConfigRegistry *
xpath_expr++, is_low_id++) {
const gchar *aic = *is_low_id ? low_iso_code : iso_code;
gchar *xpe = g_strdup_printf(*xpath_expr, aic);
- xpath_obj =
- xmlXPathEval((unsigned char *) xpe,
- xkl_config_registry_priv(config,
- xpath_context));
- if (xpath_obj != NULL) {
- xmlNodeSetPtr nodes = xpath_obj->nodesetval;
+ for (i = XKL_NUMBER_OF_REGISTRY_DOCS; --i >= 0;) {
+ xmlXPathContextPtr xmlctxt =
+ xkl_config_registry_priv(config,
+ xpath_contexts[i]);
+ if (xmlctxt == NULL)
+ continue;
+
+ xpath_obj =
+ xmlXPathEval((unsigned char *) xpe, xmlctxt);
+ if (xpath_obj == NULL)
+ continue;
+
+ nodes = xpath_obj->nodesetval;
if (nodes != NULL) {
gint ni;
xmlNodePtr *node = nodes->nodeTab;
diff --git a/libxklavier/xklavier_private.h b/libxklavier/xklavier_private.h
index 7e1b4a8..5bcd24b 100644
--- a/libxklavier/xklavier_private.h
+++ b/libxklavier/xklavier_private.h
@@ -34,6 +34,8 @@ enum { WM_NAME,
TOTAL_ATOMS
};
+#define XKL_NUMBER_OF_REGISTRY_DOCS 2
+
struct _XklEnginePrivate {
gboolean group_per_toplevel_window;
@@ -245,9 +247,8 @@ extern XklEngine *xkl_get_the_engine(void);
struct _XklConfigRegistryPrivate {
XklEngine *engine;
- xmlDocPtr doc;
-
- xmlXPathContextPtr xpath_context;
+ xmlDocPtr docs[XKL_NUMBER_OF_REGISTRY_DOCS];
+ xmlXPathContextPtr xpath_contexts[XKL_NUMBER_OF_REGISTRY_DOCS];
};
extern void xkl_engine_ensure_vtable_inited(XklEngine * engine);
@@ -388,16 +389,15 @@ extern void xkl_engine_one_switch_to_secondary_group_performed(XklEngine *
extern gboolean xkl_config_registry_load_from_file(XklConfigRegistry *
config,
- const gchar *
- file_name);
+ const gchar * file_name,
+ gint docidx);
extern void xkl_config_registry_free(XklConfigRegistry * config);
extern gchar *xkl_locale_from_utf8(XklConfigRegistry * config,
const gchar * utf8string);
-extern gboolean xkl_config_registry_load_helper(XklConfigRegistry * config,
- const char
+extern gboolean xkl_config_registry_load_helper(XklConfigRegistry * config, const char
default_ruleset[],
const char base_dir[]);
@@ -414,7 +414,7 @@ extern gboolean xkl_config_registry_load_helper(XklConfigRegistry * config,
#define xkl_engine_vcall(engine,func) (*(engine)->priv->func)
#define xkl_config_registry_is_initialized(config) \
- ( xkl_config_registry_priv(config,xpath_context) != NULL )
+ ( xkl_config_registry_priv(config,xpath_contexts[0]) != NULL )
#define xkl_config_registry_priv(config,member) (config)->priv->member
#define xkl_config_registry_get_engine(config) ((config)->priv->engine)
@@ -434,6 +434,7 @@ extern gboolean xkl_config_registry_load_helper(XklConfigRegistry * config,
#define XML_TAG_ISO639ID "iso639Id"
extern void
+
xkl_config_registry_foreach_in_xpath_with_param(XklConfigRegistry * config,
const gchar * format,
const gchar * value,