summaryrefslogtreecommitdiff
path: root/libxklavier/xklavier_config.c
diff options
context:
space:
mode:
authorSergey Udaltsov <svu@gnome.org>2006-03-12 04:20:01 +0000
committerSergey Udaltsov <svu@gnome.org>2006-03-12 04:20:01 +0000
commit2c88cc80147b72eba939d6358939ef59d403c34e (patch)
treeb6b145f6d50e1f4bba8145bef5963aee8a5f3180 /libxklavier/xklavier_config.c
parentd7bc98fb5f9d55c37a08ceeedbc87cb70ee6f133 (diff)
downloadlibxklavier-2c88cc80147b72eba939d6358939ef59d403c34e.tar.gz
branching 2.x, merging GLIBing to HEAD
Diffstat (limited to 'libxklavier/xklavier_config.c')
-rw-r--r--libxklavier/xklavier_config.c1132
1 files changed, 630 insertions, 502 deletions
diff --git a/libxklavier/xklavier_config.c b/libxklavier/xklavier_config.c
index 6e8c0a4..84645ae 100644
--- a/libxklavier/xklavier_config.c
+++ b/libxklavier/xklavier_config.c
@@ -1,593 +1,721 @@
#include <errno.h>
-#include <string.h>
-#include <stdio.h>
#include <locale.h>
+#include <stdio.h>
+#include <string.h>
#include <sys/stat.h>
-#include <libxml/xpath.h>
-
#include "config.h"
#include "xklavier_private.h"
-typedef struct _XklConfigRegistry
-{
- xmlDocPtr doc;
- xmlXPathContextPtr xpathContext;
-}
-XklConfigRegistry;
-
-static XklConfigRegistry theRegistry;
-
-static xmlXPathCompExprPtr modelsXPath;
-static xmlXPathCompExprPtr layoutsXPath;
-static xmlXPathCompExprPtr optionGroupsXPath;
-
-#define _XklConfigRegistryIsInitialized() \
- ( theRegistry.xpathContext != NULL )
-
-static xmlChar *_XklNodeGetXmlLangAttr( xmlNodePtr nptr )
-{
- if( nptr->properties != NULL &&
- !strcmp( "lang", (char *)nptr->properties[0].name ) &&
- nptr->properties[0].ns != NULL &&
- !strcmp( "xml", (char *)nptr->properties[0].ns->prefix ) &&
- nptr->properties[0].children != NULL )
- return nptr->properties[0].children->content;
- else
- return NULL;
-}
-
-static Bool _XklReadConfigItem( xmlNodePtr iptr, XklConfigItemPtr pci )
-{
- xmlNodePtr nameElement, descElement = NULL, ntDescElement =
- NULL, nptr, ptr, shortDescElement = NULL, ntShortDescElement = NULL;
- int maxDescPriority = -1;
- int maxShortDescPriority = -1;
-
- *pci->name = 0;
- *pci->shortDescription = 0;
- *pci->description = 0;
- if( iptr->type != XML_ELEMENT_NODE )
- return False;
- ptr = iptr->children;
- while( ptr != NULL )
- {
- switch ( ptr->type )
- {
- case XML_ELEMENT_NODE:
- if( !strcmp( (char *)ptr->name, "configItem" ) )
- break;
- return False;
- case XML_TEXT_NODE:
- case XML_COMMENT_NODE:
- ptr = ptr->next;
- continue;
- default:
- return False;
- }
- break;
- }
- if( ptr == NULL )
- return False;
-
- nptr = ptr->children;
-
- if( nptr->type == XML_TEXT_NODE )
- nptr = nptr->next;
- nameElement = nptr;
- nptr = nptr->next;
-
- while( nptr != NULL )
- {
- if( nptr->type != XML_TEXT_NODE )
- {
- xmlChar *lang = _XklNodeGetXmlLangAttr( nptr );
-
- if( lang != NULL )
- {
- int priority = _XklGetLanguagePriority( (char *)lang );
- if( !strcmp( (char *)nptr->name, "description" ) && ( priority > maxDescPriority ) ) /* higher priority */
- {
- descElement = nptr;
- maxDescPriority = priority;
- } else if( !strcmp( (char *)nptr->name, "shortDescription" ) && ( priority > maxShortDescPriority ) ) /* higher priority */
- {
- shortDescElement = nptr;
- maxShortDescPriority = priority;
- }
- } else
- {
- if( !strcmp( (char *)nptr->name, "description" ) )
- ntDescElement = nptr;
- else if( !strcmp( (char *)nptr->name, "shortDescription" ) )
- ntShortDescElement = nptr;
- }
- }
- nptr = nptr->next;
- }
-
- /* if no language-specific description found - use the ones without lang */
- if( descElement == NULL )
- descElement = ntDescElement;
-
- if( shortDescElement == NULL )
- shortDescElement = ntShortDescElement;
-
- /**
- * Actually, here we should have some code to find the correct localized description...
- */
-
- if( nameElement != NULL && nameElement->children != NULL )
- strncat( pci->name, (char *)nameElement->children->content,
- XKL_MAX_CI_NAME_LENGTH - 1 );
-
- if( shortDescElement != NULL && shortDescElement->children != NULL )
- {
- char * lsd = _XklLocaleFromUtf8( (const char *)shortDescElement->children->content );
- strncat( pci->shortDescription,
- lsd,
- XKL_MAX_CI_SHORT_DESC_LENGTH - 1 );
- free( lsd );
- }
-
- if( descElement != NULL && descElement->children != NULL )
- {
- char * ld = _XklLocaleFromUtf8( (const char *)descElement->children->content );
- strncat( pci->description,
- ld,
- XKL_MAX_CI_DESC_LENGTH - 1 );
- free( ld );
- }
- return True;
-}
-
-static void _XklConfigEnumFromNodeSet( xmlNodeSetPtr nodes,
- ConfigItemProcessFunc func,
- void *userData )
+static GObjectClass *parent_class = NULL;
+
+static XklConfigRegistry *the_config = NULL;
+
+static xmlXPathCompExprPtr models_xpath;
+static xmlXPathCompExprPtr layouts_xpath;
+static xmlXPathCompExprPtr option_groups_xpath;
+
+enum {
+ PROP_0,
+ PROP_ENGINE,
+};
+
+#define xkl_config_registry_is_initialized(config) \
+ ( xkl_config_registry_priv(config,xpath_context) != NULL )
+
+static xmlChar *
+xkl_node_get_xml_lang_attr(xmlNodePtr nptr)
+{
+ if (nptr->properties != NULL &&
+ !g_ascii_strcasecmp("lang", (char *) nptr->properties[0].name)
+ && nptr->properties[0].ns != NULL
+ && !g_ascii_strcasecmp("xml",
+ (char *) nptr->properties[0].ns->prefix)
+ && nptr->properties[0].children != NULL)
+ return nptr->properties[0].children->content;
+ else
+ return NULL;
+}
+
+static gboolean
+xkl_read_config_item(xmlNodePtr iptr, XklConfigItem * item)
+{
+ xmlNodePtr name_element, nptr, ptr;
+ xmlNodePtr desc_element = NULL, short_desc_element = NULL;
+ xmlNodePtr nt_desc_element = NULL, nt_short_desc_element = NULL;
+
+ gint max_desc_priority = -1;
+ gint max_short_desc_priority = -1;
+
+ *item->name = 0;
+ *item->short_description = 0;
+ *item->description = 0;
+ if (iptr->type != XML_ELEMENT_NODE)
+ return FALSE;
+ ptr = iptr->children;
+ while (ptr != NULL) {
+ switch (ptr->type) {
+ case XML_ELEMENT_NODE:
+ if (!g_ascii_strcasecmp((char *) ptr->name,
+ "configItem"))
+ break;
+ return FALSE;
+ case XML_TEXT_NODE:
+ case XML_COMMENT_NODE:
+ ptr = ptr->next;
+ continue;
+ default:
+ return FALSE;
+ }
+ break;
+ }
+ if (ptr == NULL)
+ return FALSE;
+
+ nptr = ptr->children;
+
+ if (nptr->type == XML_TEXT_NODE)
+ nptr = nptr->next;
+ name_element = nptr;
+ nptr = nptr->next;
+
+ while (nptr != NULL) {
+ char *node_name = (char *) nptr->name;
+ if (nptr->type != XML_TEXT_NODE) {
+ xmlChar *lang = xkl_node_get_xml_lang_attr(nptr);
+
+ if (lang != NULL) {
+ gint priority =
+ xkl_get_language_priority((gchar *)
+ lang);
+
+ /*
+ * Find desc/shortdesc with highest priority
+ */
+ if (!g_ascii_strcasecmp(node_name,
+ "description") &&
+ (priority > max_desc_priority)) {
+ desc_element = nptr;
+ max_desc_priority = priority;
+ } else if (!g_ascii_strcasecmp(node_name,
+ "shortDescription")
+ && (priority >
+ max_short_desc_priority)) {
+ short_desc_element = nptr;
+ max_short_desc_priority = priority;
+ }
+ } else // no language specified!
+ {
+ if (!g_ascii_strcasecmp(node_name,
+ "description"))
+ nt_desc_element = nptr;
+ else if (!g_ascii_strcasecmp(node_name,
+ "shortDescription"))
+ nt_short_desc_element = nptr;
+ }
+ }
+ nptr = nptr->next;
+ }
+
+ /* if no language-specific description found - use the ones without lang */
+ if (desc_element == NULL)
+ desc_element = nt_desc_element;
+
+ if (short_desc_element == NULL)
+ short_desc_element = nt_short_desc_element;
+
+ /*
+ * Actually, here we should have some code to find
+ * the correct localized description...
+ */
+
+ if (name_element != NULL && name_element->children != NULL)
+ strncat(item->name,
+ (char *) name_element->children->content,
+ XKL_MAX_CI_NAME_LENGTH - 1);
+
+ if (short_desc_element != NULL &&
+ short_desc_element->children != NULL) {
+ gchar *lmsg = xkl_locale_from_utf8((const gchar *)
+ short_desc_element->
+ children->content);
+ strncat(item->short_description, lmsg,
+ XKL_MAX_CI_SHORT_DESC_LENGTH - 1);
+ g_free(lmsg);
+ }
+
+ if (desc_element != NULL && desc_element->children != NULL) {
+ gchar *lmsg =
+ xkl_locale_from_utf8((const gchar *) desc_element->
+ children->content);
+ strncat(item->description, lmsg,
+ XKL_MAX_CI_DESC_LENGTH - 1);
+ g_free(lmsg);
+ }
+ return TRUE;
+}
+
+static void
+xkl_config_registry_foreach_in_nodeset(XklConfigRegistry * config,
+ xmlNodeSetPtr nodes,
+ ConfigItemProcessFunc func,
+ gpointer data)
+{
+ gint i;
+ if (nodes != NULL) {
+ xmlNodePtr *pnode = nodes->nodeTab;
+ for (i = nodes->nodeNr; --i >= 0;) {
+ XklConfigItem ci;
+ if (xkl_read_config_item(*pnode, &ci))
+ func(&ci, data);
+
+ pnode++;
+ }
+ }
+}
+
+static void
+xkl_config_registry_foreach_in_xpath(XklConfigRegistry * config,
+ xmlXPathCompExprPtr xpath_comp_expr,
+ ConfigItemProcessFunc func,
+ gpointer data)
+{
+ xmlXPathObjectPtr xpath_obj;
+
+ 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) {
+ xkl_config_registry_foreach_in_nodeset(config,
+ xpath_obj->
+ nodesetval, func,
+ data);
+ xmlXPathFreeObject(xpath_obj);
+ }
+}
+
+static void
+xkl_config_registry_foreach_in_xpath_with_param(XklConfigRegistry * config,
+ const gchar * format,
+ const gchar * value,
+ ConfigItemProcessFunc func,
+ gpointer data)
{
- int i;
- if( nodes != NULL )
- {
- xmlNodePtr *theNodePtr = nodes->nodeTab;
- for( i = nodes->nodeNr; --i >= 0; )
- {
- XklConfigItem ci;
- if( _XklReadConfigItem( *theNodePtr, &ci ) )
- func( &ci, userData );
+ char xpath_expr[1024];
+ xmlXPathObjectPtr xpath_obj;
- theNodePtr++;
- }
- }
+ if (!xkl_config_registry_is_initialized(config))
+ return;
+ 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) {
+ xkl_config_registry_foreach_in_nodeset(config,
+ xpath_obj->
+ nodesetval, func,
+ data);
+ xmlXPathFreeObject(xpath_obj);
+ }
}
-static void _XklConfigEnumSimple( xmlXPathCompExprPtr xpathCompExpr,
- ConfigItemProcessFunc func, void *userData )
+static gboolean
+xkl_config_registry_find_object(XklConfigRegistry * config,
+ const gchar * format, const gchar * arg1,
+ XklConfigItem * pitem /* in/out */ ,
+ xmlNodePtr * pnode /* out */ )
{
- xmlXPathObjectPtr xpathObj;
+ xmlXPathObjectPtr xpath_obj;
+ xmlNodeSetPtr nodes;
+ gboolean rv = FALSE;
+ gchar xpath_expr[1024];
- if( !_XklConfigRegistryIsInitialized( ) )
- return;
- xpathObj = xmlXPathCompiledEval( xpathCompExpr, theRegistry.xpathContext );
- if( xpathObj != NULL )
- {
- _XklConfigEnumFromNodeSet( xpathObj->nodesetval, func, userData );
- xmlXPathFreeObject( xpathObj );
- }
-}
+ if (!xkl_config_registry_is_initialized(config))
+ return FALSE;
-static void _XklConfigEnumDirect( const char *format,
- const char *value,
- ConfigItemProcessFunc func, void *userData )
-{
- char xpathExpr[1024];
- xmlXPathObjectPtr xpathObj;
+ 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;
- if( !_XklConfigRegistryIsInitialized( ) )
- return;
- snprintf( xpathExpr, sizeof xpathExpr, format, value );
- xpathObj = xmlXPathEval( (unsigned char *)xpathExpr, theRegistry.xpathContext );
- if( xpathObj != NULL )
- {
- _XklConfigEnumFromNodeSet( xpathObj->nodesetval, func, userData );
- xmlXPathFreeObject( xpathObj );
- }
-}
-
-static Bool _XklConfigFindObject( const char *format,
- const char *arg1,
- XklConfigItemPtr ptr /* in/out */ ,
- xmlNodePtr * nodePtr /* out */ )
-{
- xmlXPathObjectPtr xpathObj;
- xmlNodeSetPtr nodes;
- Bool rv = False;
- char xpathExpr[1024];
-
- if( !_XklConfigRegistryIsInitialized( ) )
- return False;
-
- snprintf( xpathExpr, sizeof xpathExpr, format, arg1, ptr->name );
- xpathObj = xmlXPathEval( (unsigned char *)xpathExpr, theRegistry.xpathContext );
- if( xpathObj == NULL )
- return False;
-
- nodes = xpathObj->nodesetval;
- if( nodes != NULL && nodes->nodeTab != NULL )
- {
- rv = _XklReadConfigItem( *nodes->nodeTab, ptr );
- if( nodePtr != NULL )
- {
- *nodePtr = *nodes->nodeTab;
- }
- }
+ nodes = xpath_obj->nodesetval;
+ if (nodes != NULL && nodes->nodeTab != NULL) {
+ rv = xkl_read_config_item(*nodes->nodeTab, pitem);
+ if (pnode != NULL) {
+ *pnode = *nodes->nodeTab;
+ }
+ }
- xmlXPathFreeObject( xpathObj );
- return rv;
+ xmlXPathFreeObject(xpath_obj);
+ return rv;
}
-char *_XklConfigRecMergeLayouts( const XklConfigRecPtr data )
+gchar *
+xkl_config_rec_merge_layouts(const XklConfigRec * data)
{
- return _XklConfigRecMergeByComma( ( const char ** ) data->layouts,
- data->numLayouts );
+ return xkl_strings_concat_comma_separated(data->layouts);
}
-char *_XklConfigRecMergeVariants( const XklConfigRecPtr data )
+gchar *
+xkl_config_rec_merge_variants(const XklConfigRec * data)
{
- return _XklConfigRecMergeByComma( ( const char ** ) data->variants,
- data->numVariants );
+ return xkl_strings_concat_comma_separated(data->variants);
}
-char *_XklConfigRecMergeOptions( const XklConfigRecPtr data )
+gchar *
+xkl_config_rec_merge_options(const XklConfigRec * data)
{
- return _XklConfigRecMergeByComma( ( const char ** ) data->options,
- data->numOptions );
+ return xkl_strings_concat_comma_separated(data->options);
}
-char *_XklConfigRecMergeByComma( const char **array, const int arrayLength )
+gchar *
+xkl_strings_concat_comma_separated(gchar ** array)
{
- int len = 0;
- int i;
- char *merged;
- const char **theString;
-
- if( ( theString = array ) == NULL )
- return NULL;
-
- for( i = arrayLength; --i >= 0; theString++ )
- {
- if( *theString != NULL )
- len += strlen( *theString );
- len++;
- }
-
- if( len < 1 )
- return NULL;
-
- merged = ( char * ) malloc( len );
- merged[0] = '\0';
-
- theString = array;
- for( i = arrayLength; --i >= 0; theString++ )
- {
- if( *theString != NULL )
- strcat( merged, *theString );
- if( i != 0 )
- strcat( merged, "," );
- }
- return merged;
+ return g_strjoinv(",", array);
}
-void _XklConfigRecSplitLayouts( XklConfigRecPtr data, const char *merged )
+void
+xkl_config_rec_split_layouts(XklConfigRec * data, const gchar * merged)
{
- _XklConfigRecSplitByComma( &data->layouts, &data->numLayouts, merged );
+ xkl_strings_split_comma_separated(&data->layouts, merged);
}
-void _XklConfigRecSplitVariants( XklConfigRecPtr data, const char *merged )
+void
+xkl_config_rec_split_variants(XklConfigRec * data, const gchar * merged)
{
- _XklConfigRecSplitByComma( &data->variants, &data->numVariants, merged );
+ xkl_strings_split_comma_separated(&data->variants, merged);
}
-void _XklConfigRecSplitOptions( XklConfigRecPtr data, const char *merged )
+void
+xkl_config_rec_split_options(XklConfigRec * data, const gchar * merged)
{
- _XklConfigRecSplitByComma( &data->options, &data->numOptions, merged );
+ xkl_strings_split_comma_separated(&data->options, merged);
}
-void _XklConfigRecSplitByComma( char ***array,
- int *arraySize, const char *merged )
+void
+xkl_strings_split_comma_separated(gchar *** array, const gchar * merged)
{
- const char *pc = merged;
- char **ppc, *npc;
- *arraySize = 0;
- *array = NULL;
-
- if( merged == NULL || merged[0] == '\0' )
- return;
-
- /* first count the elements */
- while( ( npc = strchr( pc, ',' ) ) != NULL )
- {
- ( *arraySize )++;
- pc = npc + 1;
- }
- ( *arraySize )++;
-
- if( ( *arraySize ) != 0 )
- {
- int len;
- *array = ( char ** ) malloc( ( sizeof( char * ) ) * ( *arraySize ) );
-
- ppc = *array;
- pc = merged;
- while( ( npc = strchr( pc, ',' ) ) != NULL )
- {
- int len = npc - pc;
- /* *ppc = ( char * ) strndup( pc, len ); */
- *ppc = ( char * ) malloc( len + 1 );
- if ( *ppc != NULL )
- {
- strncpy( *ppc, pc, len );
- (*ppc)[len] = '\0';
- }
-
- ppc++;
- pc = npc + 1;
- }
-
- /* len = npc - pc; */
- len = strlen( pc );
- /* *ppc = ( char * ) strndup( pc, len ); */
- *ppc = ( char * ) malloc( len + 1 );
- if ( *ppc != NULL )
- strcpy( *ppc, pc );
- }
+ *array = g_strsplit(merged, ",", 0);
}
-char* _XklGetRulesSetName( const char defaultRuleset[] )
-{
- static char rulesSetName[1024] = "";
- if ( !rulesSetName[0] )
- {
- char* rf = NULL;
- if( !XklGetNamesProp( xklVTable->baseConfigAtom, &rf, NULL ) || ( rf == NULL ) )
- {
- strncpy( rulesSetName, defaultRuleset, sizeof rulesSetName );
- XklDebug( 100, "Using default rules set: [%s]\n", rulesSetName );
- return rulesSetName;
- }
- strncpy( rulesSetName, rf, sizeof rulesSetName );
- free( rf );
- }
- XklDebug( 100, "Rules set: [%s]\n", rulesSetName );
- return rulesSetName;
+gchar *
+xkl_engine_get_ruleset_name(XklEngine * engine,
+ const gchar default_ruleset[])
+{
+ static gchar rules_set_name[1024] = "";
+ if (!rules_set_name[0]) {
+ /* first call */
+ gchar *rf = NULL;
+ if (!xkl_config_rec_get_from_root_window_property
+ (NULL, xkl_engine_priv(engine, base_config_atom), &rf,
+ engine)
+ || (rf == NULL)) {
+ g_strlcpy(rules_set_name, default_ruleset,
+ sizeof rules_set_name);
+ xkl_debug(100, "Using default rules set: [%s]\n",
+ rules_set_name);
+ return rules_set_name;
+ }
+ g_strlcpy(rules_set_name, rf, sizeof rules_set_name);
+ g_free(rf);
+ }
+ xkl_debug(100, "Rules set: [%s]\n", rules_set_name);
+ return rules_set_name;
}
-void XklConfigInit( void )
+XklConfigRegistry *
+xkl_config_registry_get_instance(XklEngine * engine)
{
- xmlXPathInit( );
- modelsXPath = xmlXPathCompile( (unsigned char *)"/xkbConfigRegistry/modelList/model" );
- layoutsXPath = xmlXPathCompile( (unsigned char *)"/xkbConfigRegistry/layoutList/layout" );
- optionGroupsXPath =
- xmlXPathCompile( (unsigned char *)"/xkbConfigRegistry/optionList/group" );
- _XklI18NInit( );
+ if (the_config != NULL) {
+ g_object_ref(G_OBJECT(the_config));
+ return the_config;
+ }
+
+ if (!engine) {
+ xkl_debug(10,
+ "xkl_config_registry_get_instance : engine is NULL ?\n");
+ return NULL;
+ }
- _XklEnsureVTableInited();
- (*xklVTable->xklConfigInitHandler)();
+ the_config =
+ XKL_CONFIG_REGISTRY(g_object_new
+ (xkl_config_registry_get_type(), "engine",
+ engine, NULL));
+
+ return the_config;
}
-void XklConfigTerm( void )
+gboolean
+xkl_config_registry_load_from_file(XklConfigRegistry * config,
+ const gchar * file_name)
{
- if( modelsXPath != NULL )
- {
- xmlXPathFreeCompExpr( modelsXPath );
- modelsXPath = NULL;
- }
- if( layoutsXPath != NULL )
- {
- xmlXPathFreeCompExpr( layoutsXPath );
- layoutsXPath = NULL;
- }
- if( optionGroupsXPath != NULL )
- {
- xmlXPathFreeCompExpr( optionGroupsXPath );
- optionGroupsXPath = NULL;
- }
+ xkl_config_registry_priv(config, doc) = xmlParseFile(file_name);
+ if (xkl_config_registry_priv(config, doc) == NULL) {
+ xkl_config_registry_priv(config, xpath_context) = NULL;
+ xkl_last_error_message =
+ "Could not parse XKB configuration registry";
+ } else
+ xkl_config_registry_priv(config, xpath_context) =
+ xmlXPathNewContext(xkl_config_registry_priv
+ (config, doc));
+ return xkl_config_registry_is_initialized(config);
}
-Bool XklConfigLoadRegistryFromFile( const char * fileName )
+void
+xkl_config_registry_free(XklConfigRegistry * config)
{
- theRegistry.doc = xmlParseFile( fileName );
- if( theRegistry.doc == NULL )
- {
- theRegistry.xpathContext = NULL;
- _xklLastErrorMsg = "Could not parse XKB configuration registry";
- } else
- theRegistry.xpathContext = xmlXPathNewContext( theRegistry.doc );
- return _XklConfigRegistryIsInitialized( );
+ 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;
+ }
}
-void XklConfigFreeRegistry( void )
-{
- if( _XklConfigRegistryIsInitialized( ) )
- {
- xmlXPathFreeContext( theRegistry.xpathContext );
- xmlFreeDoc( theRegistry.doc );
- theRegistry.xpathContext = NULL;
- theRegistry.doc = NULL;
+void
+xkl_config_registry_foreach_model(XklConfigRegistry * config,
+ ConfigItemProcessFunc func,
+ gpointer data)
+{
+ xkl_config_registry_foreach_in_xpath(config, models_xpath, func,
+ data);
+}
+
+void
+xkl_config_registry_foreach_layout(XklConfigRegistry * config,
+ ConfigItemProcessFunc func,
+ gpointer data)
+{
+ xkl_config_registry_foreach_in_xpath(config, layouts_xpath, func,
+ data);
+}
+
+void
+xkl_config_registry_foreach_layout_variant(XklConfigRegistry * config,
+ const gchar * layout_name,
+ ConfigItemProcessFunc func,
+ gpointer data)
+{
+ xkl_config_registry_foreach_in_xpath_with_param
+ (config,
+ "/xkbConfigRegistry/layoutList/layout/variantList/variant[../../configItem/name = '%s']",
+ layout_name, func, data);
+}
+
+void
+xkl_config_registry_foreach_option_group(XklConfigRegistry * config,
+ GroupProcessFunc func,
+ gpointer data)
+{
+ xmlXPathObjectPtr xpath_obj;
+ gint i;
+
+ 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;
+ for (i = nodes->nodeNr; --i >= 0;) {
+ XklConfigItem ci;
+
+ if (xkl_read_config_item(*pnode, &ci)) {
+ gboolean allow_multisel = TRUE;
+ xmlChar *sallow_multisel =
+ xmlGetProp(*pnode,
+ (unsigned char *)
+ "allowMultipleSelection");
+ if (sallow_multisel != NULL) {
+ allow_multisel =
+ !g_ascii_strcasecmp("true",
+ (char *)
+ sallow_multisel);
+ xmlFree(sallow_multisel);
+ }
+
+ func(&ci, allow_multisel, data);
+ }
+
+ pnode++;
+ }
+ xmlXPathFreeObject(xpath_obj);
+ }
+}
+
+void
+xkl_config_registry_foreach_option(XklConfigRegistry * config,
+ const gchar * option_group_name,
+ ConfigItemProcessFunc func,
+ gpointer data)
+{
+ xkl_config_registry_foreach_in_xpath_with_param
+ (config,
+ "/xkbConfigRegistry/optionList/group/option[../configItem/name = '%s']",
+ option_group_name, func, data);
+}
+
+gboolean
+xkl_config_registry_find_model(XklConfigRegistry * config,
+ XklConfigItem * pitem /* in/out */ )
+{
+ return
+ xkl_config_registry_find_object
+ (config,
+ "/xkbConfigRegistry/modelList/model[configItem/name = '%s%s']",
+ "", pitem, NULL);
+}
+
+gboolean
+xkl_config_registry_find_layout(XklConfigRegistry * config,
+ XklConfigItem * pitem /* in/out */ )
+{
+ return
+ xkl_config_registry_find_object
+ (config,
+ "/xkbConfigRegistry/layoutList/layout[configItem/name = '%s%s']",
+ "", pitem, NULL);
+}
+
+gboolean
+xkl_config_registry_find_variant(XklConfigRegistry * config,
+ const char *layout_name,
+ XklConfigItem * pitem /* in/out */ )
+{
+ return
+ xkl_config_registry_find_object
+ (config,
+ "/xkbConfigRegistry/layoutList/layout/variantList/variant"
+ "[../../configItem/name = '%s' and configItem/name = '%s']",
+ layout_name, pitem, NULL);
+}
+
+gboolean
+xkl_config_registry_find_option_group(XklConfigRegistry * config,
+ XklConfigItem * pitem /* in/out */ ,
+ gboolean *
+ allow_multiple_selection /* out */ )
+{
+ xmlNodePtr node;
+ gboolean rv = xkl_config_registry_find_object(config,
+ "/xkbConfigRegistry/optionList/group[configItem/name = '%s%s']",
+ "",
+ pitem, &node);
+
+ if (rv && allow_multiple_selection != NULL) {
+ xmlChar *val = xmlGetProp(node,
+ (unsigned char *)
+ "allowMultipleSelection");
+ *allow_multiple_selection = FALSE;
+ if (val != NULL) {
+ *allow_multiple_selection =
+ !g_ascii_strcasecmp("true", (char *) val);
+ xmlFree(val);
+ }
+ }
+ return rv;
+}
+
+gboolean
+xkl_config_registry_find_option(XklConfigRegistry * config,
+ const char *option_group_name,
+ XklConfigItem * pitem /* in/out */ )
+{
+ return
+ xkl_config_registry_find_object
+ (config, "/xkbConfigRegistry/optionList/group/option"
+ "[../configItem/name = '%s' and configItem/name = '%s']",
+ option_group_name, pitem, NULL);
+}
+
+/*
+ * Calling through vtable
+ */
+gboolean
+xkl_config_rec_activate(const XklConfigRec * data, XklEngine * engine)
+{
+ xkl_engine_ensure_vtable_inited(engine);
+ return xkl_engine_vcall(engine, activate_config_rec) (engine,
+ data);
+}
+
+gboolean
+xkl_config_registry_load(XklConfigRegistry * config)
+{
+ XklEngine *engine = xkl_config_registry_get_engine(config);
+ xkl_engine_ensure_vtable_inited(engine);
+ return xkl_engine_vcall(engine, load_config_registry) (config);
+}
+
+gboolean
+xkl_config_rec_write_to_file(XklEngine * engine, const gchar * file_name,
+ const XklConfigRec * data,
+ const gboolean binary)
+{
+ if ((!binary &&
+ !(xkl_engine_priv(engine, features) &
+ XKLF_CAN_OUTPUT_CONFIG_AS_ASCII))
+ || (binary
+ && !(xkl_engine_priv(engine, features) &
+ XKLF_CAN_OUTPUT_CONFIG_AS_BINARY))) {
+ xkl_last_error_message =
+ "Function not supported at backend";
+ return FALSE;
+ }
+ xkl_engine_ensure_vtable_inited(engine);
+ return xkl_engine_vcall(engine, write_config_rec_to_file) (engine,
+ file_name,
+ data,
+ binary);
+}
+
+void
+xkl_config_rec_dump(FILE * file, XklConfigRec * data)
+{
+ int j;
+ fprintf(file, " model: [%s]\n", data->model);
+
+ fprintf(file, " layouts:\n");
+#define OUTPUT_ARRZ(arrz) \
+ { \
+ fprintf( file, " " #arrz ":\n" ); \
+ gchar **p = data->arrz; \
+ if ( p != NULL ) \
+ for( j = 0; *p != NULL; ) \
+ fprintf( file, " %d: [%s]\n", j++, *p++ ); \
}
-}
+ OUTPUT_ARRZ(layouts);
+ OUTPUT_ARRZ(variants);
+ OUTPUT_ARRZ(options);
-void XklConfigEnumModels( ConfigItemProcessFunc func, void *userData )
-{
- _XklConfigEnumSimple( modelsXPath, func, userData );
}
-void XklConfigEnumLayouts( ConfigItemProcessFunc func, void *userData )
-{
- _XklConfigEnumSimple( layoutsXPath, func, userData );
-}
+G_DEFINE_TYPE(XklConfigRegistry, xkl_config_registry, G_TYPE_OBJECT)
-void XklConfigEnumLayoutVariants( const char *layoutName,
- ConfigItemProcessFunc func, void *userData )
+static GObject *
+xkl_config_registry_constructor(GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *
+ construct_properties)
{
- _XklConfigEnumDirect
- ( "/xkbConfigRegistry/layoutList/layout/variantList/variant[../../configItem/name = '%s']",
- layoutName, func, userData );
-}
+ GObject *obj;
-void XklConfigEnumOptionGroups( GroupProcessFunc func, void *userData )
-{
- xmlXPathObjectPtr xpathObj;
- int i;
+ {
+ /* Invoke parent constructor. */
+ XklConfigRegistryClass *klass;
+ klass =
+ XKL_CONFIG_REGISTRY_CLASS(g_type_class_peek
+ (XKL_TYPE_CONFIG_REGISTRY));
+ obj =
+ parent_class->constructor(type, n_construct_properties,
+ construct_properties);
+ }
- if( !_XklConfigRegistryIsInitialized( ) )
- return;
- xpathObj =
- xmlXPathCompiledEval( optionGroupsXPath, theRegistry.xpathContext );
- if( xpathObj != NULL )
- {
- xmlNodeSetPtr nodes = xpathObj->nodesetval;
- xmlNodePtr *theNodePtr = nodes->nodeTab;
- for( i = nodes->nodeNr; --i >= 0; )
- {
- XklConfigItem ci;
+ XklConfigRegistry *config = XKL_CONFIG_REGISTRY(obj);
- if( _XklReadConfigItem( *theNodePtr, &ci ) )
- {
- Bool allowMC = True;
- xmlChar *allowMCS =
- xmlGetProp( *theNodePtr, (unsigned char *)"allowMultipleSelection" );
- if( allowMCS != NULL )
- {
- allowMC = strcmp( "false", (char *)allowMCS );
- xmlFree( allowMCS );
- }
+ XklEngine *engine =
+ XKL_ENGINE(g_value_peek_pointer(construct_properties[0].
+ value));
+ xkl_config_registry_get_engine(config) = engine;
- func( &ci, allowMC, userData );
- }
+ xkl_engine_ensure_vtable_inited(engine);
+ xkl_engine_vcall(engine, init_config_registry) (config);
- theNodePtr++;
- }
- xmlXPathFreeObject( xpathObj );
- }
+ return obj;
}
-void XklConfigEnumOptions( const char *optionGroupName,
- ConfigItemProcessFunc func, void *userData )
+static void
+xkl_config_registry_init(XklConfigRegistry * config)
{
- _XklConfigEnumDirect
- ( "/xkbConfigRegistry/optionList/group/option[../configItem/name = '%s']",
- optionGroupName, func, userData );
+ config->priv = g_new0(XklConfigRegistryPrivate, 1);
}
-Bool XklConfigFindModel( XklConfigItemPtr ptr /* in/out */ )
+static void
+xkl_config_registry_set_property(GObject * object,
+ guint property_id,
+ const GValue * value, GParamSpec * pspec)
{
- return
- _XklConfigFindObject
- ( "/xkbConfigRegistry/modelList/model[configItem/name = '%s%s']", "",
- ptr, NULL );
}
-Bool XklConfigFindLayout( XklConfigItemPtr ptr /* in/out */ )
+static void
+xkl_config_registry_get_property(GObject * object,
+ guint property_id,
+ GValue * value, GParamSpec * pspec)
{
- return
- _XklConfigFindObject
- ( "/xkbConfigRegistry/layoutList/layout[configItem/name = '%s%s']", "",
- ptr, NULL );
-}
+ XklConfigRegistry *config = XKL_CONFIG_REGISTRY(object);
+
+ switch (property_id) {
+ case PROP_ENGINE:
+ g_value_set_pointer(value,
+ xkl_config_registry_get_engine
+ (config));
+ break;
+ }
-Bool XklConfigFindVariant( const char *layoutName,
- XklConfigItemPtr ptr /* in/out */ )
-{
- return
- _XklConfigFindObject
- ( "/xkbConfigRegistry/layoutList/layout/variantList/variant"
- "[../../configItem/name = '%s' and configItem/name = '%s']",
- layoutName, ptr, NULL );
}
-Bool XklConfigFindOptionGroup( XklConfigItemPtr ptr /* in/out */ ,
- Bool * allowMultipleSelection /* out */ )
+static void
+xkl_config_registry_finalize(GObject * obj)
{
- xmlNodePtr node;
- Bool rv =
- _XklConfigFindObject
- ( "/xkbConfigRegistry/optionList/group[configItem/name = '%s%s']", "",
- ptr, &node );
+ XklConfigRegistry *config = (XklConfigRegistry *) obj;
- if( rv && allowMultipleSelection != NULL )
- {
- xmlChar *val = xmlGetProp( node, (unsigned char *)"allowMultipleSelection" );
- *allowMultipleSelection = False;
- if( val != NULL )
- {
- *allowMultipleSelection = !strcmp( (char *)val, "true" );
- xmlFree( val );
- }
- }
- return rv;
-}
+ if (models_xpath != NULL) {
+ xmlXPathFreeCompExpr(models_xpath);
+ models_xpath = NULL;
+ }
+ if (layouts_xpath != NULL) {
+ xmlXPathFreeCompExpr(layouts_xpath);
+ layouts_xpath = NULL;
+ }
+ if (option_groups_xpath != NULL) {
+ xmlXPathFreeCompExpr(option_groups_xpath);
+ option_groups_xpath = NULL;
+ }
-Bool XklConfigFindOption( const char *optionGroupName,
- XklConfigItemPtr ptr /* in/out */ )
-{
- return
- _XklConfigFindObject
- ( "/xkbConfigRegistry/optionList/group/option"
- "[../configItem/name = '%s' and configItem/name = '%s']",
- optionGroupName, ptr, NULL );
-}
+ g_free(config->priv);
-/**
- * Calling through vtable
- */
-Bool XklConfigActivate( const XklConfigRecPtr data )
-{
- _XklEnsureVTableInited();
- return (*xklVTable->xklConfigActivateHandler)( data );
+ G_OBJECT_CLASS(parent_class)->finalize(obj);
}
-Bool XklConfigLoadRegistry( void )
+static void
+xkl_config_registry_class_init(XklConfigRegistryClass * klass)
{
- _XklEnsureVTableInited();
- return (*xklVTable->xklConfigLoadRegistryHandler)();
-}
+ GObjectClass *object_class;
-Bool XklConfigWriteFile( const char *fileName,
- const XklConfigRecPtr data,
- const Bool binary )
-{
- if( ( !binary &&
- !( xklVTable->features & XKLF_CAN_OUTPUT_CONFIG_AS_ASCII ) ) ||
- ( binary &&
- !( xklVTable->features & XKLF_CAN_OUTPUT_CONFIG_AS_BINARY ) ) )
- {
- _xklLastErrorMsg = "Function not supported at backend";
- return False;
- }
- _XklEnsureVTableInited();
- return (*xklVTable->xklConfigWriteFileHandler)( fileName, data, binary );
-}
+ object_class = (GObjectClass *) klass;
+ parent_class = g_type_class_peek_parent(object_class);
+ object_class->constructor = xkl_config_registry_constructor;
+ object_class->finalize = xkl_config_registry_finalize;
+ object_class->set_property = xkl_config_registry_set_property;
+ object_class->get_property = xkl_config_registry_get_property;
-void XklConfigDump( FILE* file,
- XklConfigRecPtr data )
-{
- int i,j;
- char**p;
- fprintf( file, " model: [%s]\n", data->model );
+ GParamSpec *engine_param_spec = g_param_spec_object("engine",
+ "Engine",
+ "XklEngine",
+ XKL_TYPE_ENGINE,
+ G_PARAM_CONSTRUCT_ONLY
+ |
+ G_PARAM_READWRITE);
- fprintf( file, " layouts(%d):\n", data->numLayouts );
- p = data->layouts;
- for( i = data->numLayouts, j = 0; --i >= 0; )
- fprintf( file, " %d: [%s]\n", j++, *p++ );
+ g_object_class_install_property(object_class,
+ PROP_ENGINE, engine_param_spec);
- fprintf( file, " variants(%d):\n", data->numVariants );
- p = data->variants;
- for( i = data->numVariants, j = 0; --i >= 0; )
- fprintf( file, " %d: [%s]\n", j++, *p++ );
+ /* static stuff initialized */
- fprintf( file, " options(%d):\n", data->numOptions );
- p = data->options;
- for( i = data->numOptions, j = 0; --i >= 0; )
- fprintf( file, " %d: [%s]\n", j++, *p++ );
+ xmlXPathInit();
+ models_xpath = xmlXPathCompile((unsigned char *)
+ "/xkbConfigRegistry/modelList/model");
+ layouts_xpath = xmlXPathCompile((unsigned char *)
+ "/xkbConfigRegistry/layoutList/layout");
+ option_groups_xpath = xmlXPathCompile((unsigned char *)
+ "/xkbConfigRegistry/optionList/group");
+ xkl_i18n_init();
}