summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Udaltsov <svu@gnome.org>2011-01-29 00:42:34 +0000
committerSergey Udaltsov <svu@gnome.org>2011-01-29 00:42:34 +0000
commitd203797186e1b7debf743536b1d992e44fc98b6b (patch)
treedf83356708cbf9dfd4889fee44e53bf3912199c0
parent47f2b9ba60f9fda2468f23923b1ba03e326cd111 (diff)
downloadlibxklavier-d203797186e1b7debf743536b1d992e44fc98b6b.tar.gz
New function: search layout/variants by pattern. Basic implementation
-rw-r--r--ChangeLog8
-rw-r--r--libxklavier/xkl_config_registry.h20
-rw-r--r--libxklavier/xklavier_config.c96
-rw-r--r--libxklavier/xklavier_config_iso.c8
-rw-r--r--libxklavier/xklavier_private.h4
-rw-r--r--tests/test_config.c31
6 files changed, 158 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 2e3d7a3..8f97bdd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2011-01-28 svu
+
+ * libxklavier/xkl_config_registry.h, libxklavier/xklavier_config.c,
+ libxklavier/xklavier_config_iso.c, libxklavier/xklavier_private.h,
+ tests/test_config.c: Adding the function to perform the search by
+ pattern. Current implementation searches only layouts - variants are
+ to be added
+
2011-01-03 svu
* libxklavier/xklavier_evt.c, libxklavier/xklavier_private.h: fixed
diff --git a/libxklavier/xkl_config_registry.h b/libxklavier/xkl_config_registry.h
index 75356b9..f798377 100644
--- a/libxklavier/xkl_config_registry.h
+++ b/libxklavier/xkl_config_registry.h
@@ -354,6 +354,26 @@ extern "C" {
TwoConfigItemsProcessFunc
func, gpointer data);
+
+/**
+ * xkl_config_registry_search_by_pattern:
+ * @config: the config registry
+ * @pattern: pattern to search for
+ * @func: callback to call for every matching layout/variant
+ * @data: anything which can be stored into the pointer
+ *
+ * Enumerates keyboard layout/variants that match the pattern.
+ * The layout/variant is considered as matching if one of the following
+ * is true:
+ * 1. Country description (from the country list) contains pattern as substring
+ * 2. Language description (from the language list) contains pattern as substring
+ */
+ extern void
+ xkl_config_registry_search_by_pattern(XklConfigRegistry * config,
+ const gchar * pattern,
+ TwoConfigItemsProcessFunc
+ func, gpointer data);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/libxklavier/xklavier_config.c b/libxklavier/xklavier_config.c
index f829cef..25d006e 100644
--- a/libxklavier/xklavier_config.c
+++ b/libxklavier/xklavier_config.c
@@ -48,6 +48,14 @@ enum {
PROP_ENGINE
};
+typedef struct {
+ const gchar *pattern;
+ TwoConfigItemsProcessFunc func;
+ gpointer data;
+ gboolean country_matched;
+ gboolean language_matched;
+} SearchParamType;
+
static gboolean
xkl_xml_find_config_item_child(xmlNodePtr iptr, xmlNodePtr * ptr)
{
@@ -774,6 +782,94 @@ xkl_config_registry_foreach_option(XklConfigRegistry * config,
func, data);
}
+static void
+xkl_config_registry_search_by_pattern_in_layout(XklConfigRegistry * config,
+ const XklConfigItem * item,
+ SearchParamType *
+ search_param)
+{
+ gchar *upper_name = g_ascii_strup(item->name, -1);
+ const gchar *country_desc, *language_desc;
+
+ xkl_debug(200, "Layout to check: [%s]\n", item->name);
+
+ country_desc = xkl_get_country_iso_code(upper_name);
+ xkl_debug(200, "Checking layout country: [%s]\n", country_desc);
+ search_param->country_matched = FALSE;
+ if ((country_desc != NULL)
+ && strcasestr(country_desc, search_param->pattern)) {
+ search_param->country_matched = TRUE;
+ (search_param->func) (config, item, NULL,
+ search_param->data);
+ } else {
+ gchar **countries = g_object_get_data(G_OBJECT(item),
+ XCI_PROP_COUNTRY_LIST);
+ for (; countries && *countries; countries++) {
+ country_desc =
+ xkl_get_country_iso_code(*countries);
+ xkl_debug(200, "Checking country: [%s][%s]\n",
+ *countries, country_desc);
+ if ((country_desc != NULL) && strcasestr
+ (country_desc, search_param->pattern)) {
+ search_param->country_matched = TRUE;
+ (search_param->func) (config, item, NULL,
+ search_param->data);
+ break;
+ }
+ }
+ }
+
+ if (!search_param->country_matched) {
+ language_desc = xkl_get_language_iso_code(item->name);
+ xkl_debug(200, "Checking layout language: [%s]\n",
+ language_desc);
+ search_param->language_matched = FALSE;
+ if ((language_desc != NULL)
+ && strcasestr(language_desc, search_param->pattern)) {
+ search_param->language_matched = TRUE;
+ (search_param->func) (config, item, NULL,
+ search_param->data);
+ } else {
+ gchar **languages =
+ g_object_get_data(G_OBJECT(item),
+ XCI_PROP_LANGUAGE_LIST);
+ for (; languages && *languages; languages++) {
+ language_desc =
+ xkl_get_language_iso_code(*languages);
+ xkl_debug(200,
+ "Checking language: [%s][%s]\n",
+ *languages, language_desc);
+ if ((language_desc != NULL)
+ && strcasestr(language_desc,
+ search_param->pattern)) {
+ search_param->language_matched =
+ TRUE;
+ (search_param->func) (config, item,
+ NULL,
+ search_param->
+ data);
+ break;
+ }
+ }
+ }
+ }
+
+ g_free(upper_name);
+}
+
+void
+xkl_config_registry_search_by_pattern(XklConfigRegistry * config,
+ const gchar * pattern,
+ TwoConfigItemsProcessFunc func,
+ gpointer data)
+{
+ xkl_debug(200, "Searching by pattern: [%s]\n", pattern);
+ SearchParamType search_param = { pattern, func, data };
+ xkl_config_registry_foreach_layout(config, (ConfigItemProcessFunc)
+ xkl_config_registry_search_by_pattern_in_layout,
+ &search_param);
+}
+
gboolean
xkl_config_registry_find_model(XklConfigRegistry * config,
XklConfigItem * pitem /* in/out */ )
diff --git a/libxklavier/xklavier_config_iso.c b/libxklavier/xklavier_config_iso.c
index e9911a9..fdc4f25 100644
--- a/libxklavier/xklavier_config_iso.c
+++ b/libxklavier/xklavier_config_iso.c
@@ -165,7 +165,7 @@ iso_code_names_init(LookupParams * params)
typedef const gchar *(*DescriptionGetterFunc) (const gchar * code);
const gchar *
-get_language_iso_code(const gchar * code)
+xkl_get_language_iso_code(const gchar * code)
{
const gchar *name;
@@ -182,7 +182,7 @@ get_language_iso_code(const gchar * code)
}
const gchar *
-get_country_iso_code(const gchar * code)
+xkl_get_country_iso_code(const gchar * code)
{
const gchar *name;
@@ -292,7 +292,7 @@ xkl_config_registry_foreach_country(XklConfigRegistry *
};
xkl_config_registry_foreach_iso_code(config, func, xpath_exprs,
- get_country_iso_code, TRUE,
+ xkl_get_country_iso_code, TRUE,
data);
}
@@ -309,7 +309,7 @@ xkl_config_registry_foreach_language(XklConfigRegistry *
};
xkl_config_registry_foreach_iso_code(config, func, xpath_exprs,
- get_language_iso_code, FALSE,
+ xkl_get_language_iso_code, FALSE,
data);
}
diff --git a/libxklavier/xklavier_private.h b/libxklavier/xklavier_private.h
index 35fc8a5..c4bf9d8 100644
--- a/libxklavier/xklavier_private.h
+++ b/libxklavier/xklavier_private.h
@@ -480,6 +480,10 @@ extern gboolean xkl_read_config_item(XklConfigRegistry * config,
gint doc_index, xmlNodePtr iptr,
XklConfigItem * item);
+extern const gchar * xkl_get_language_iso_code(const gchar * code);
+
+extern const gchar * xkl_get_country_iso_code(const gchar * code);
+
extern gint xkl_debug_level;
extern const gchar *xkl_last_error_message;
diff --git a/tests/test_config.c b/tests/test_config.c
index 7c8cd71..e4f62a8 100644
--- a/tests/test_config.c
+++ b/tests/test_config.c
@@ -33,14 +33,14 @@
extern void xkl_config_rec_dump(FILE * file, XklConfigRec * data);
enum { ACTION_NONE, ACTION_LIST, ACTION_GET, ACTION_SET,
- ACTION_WRITE
+ ACTION_WRITE, ACTION_SEARCH
};
static void
print_usage(void)
{
printf
- ("Usage: test_config (-g)|(-s -m <model> -l <layouts> -o <options>)|(-h)|(-ws)|(-wb)(-d <debugLevel>)\n");
+ ("Usage: test_config (-g)|(-s -m <model> -l <layouts> -o <options>)|(-h)|(-ws)|(-wb)(-d <debugLevel>)|(-p pattern)\n");
printf("Options:\n");
printf(" -al - list all available layouts and variants\n");
printf(" -am - list all available models\n");
@@ -57,6 +57,7 @@ print_usage(void)
printf(" -wb - Write the source XKB config file (" PACKAGE
".xkb)\n");
printf(" -d - Set the debug level (by default, 0)\n");
+ printf(" -p - Search by pattern\n");
printf(" -h - Show this help\n");
}
@@ -97,8 +98,7 @@ static void
print_xci(XklConfigRegistry * config, const XklConfigItem * item,
gint indent)
{
- gboolean is_extra =
- (gboolean)
+ gboolean is_extra = (gboolean)
GPOINTER_TO_INT(g_object_get_data
(G_OBJECT(item), XCI_PROP_EXTRA_ITEM));
gchar **countries = (gchar **) g_object_get_data(G_OBJECT(item),
@@ -170,6 +170,16 @@ print_language(XklConfigRegistry * config, const XklConfigItem * item,
data);
}
+static void
+print_found_variants(XklConfigRegistry * config,
+ const XklConfigItem * parent_item,
+ const XklConfigItem * child_item)
+{
+ printf("found layout: [%s]\n", parent_item->name);
+ if (child_item != NULL)
+ printf("found variant: [%s]\n", child_item->name);
+}
+
int
main(int argc, char *const argv[])
{
@@ -179,6 +189,7 @@ main(int argc, char *const argv[])
const gchar *model = NULL;
const gchar *layouts = NULL;
const gchar *options = NULL;
+ const gchar *pattern = NULL;
int debug_level = -1;
int binary = 0;
Display *dpy;
@@ -188,7 +199,7 @@ main(int argc, char *const argv[])
G_TYPE_DEBUG_SIGNALS);
while (1) {
- c = getopt(argc, argv, "ha:sgm:l:o:d:w:c:");
+ c = getopt(argc, argv, "ha:sgm:l:o:d:w:c:p:");
if (c == -1)
break;
switch (c) {
@@ -214,6 +225,10 @@ main(int argc, char *const argv[])
case 'o':
printf("Options: [%s]\n", options = optarg);
break;
+ case 'p':
+ action = ACTION_SEARCH;
+ printf("Pattern: [%s]\n", pattern = optarg);
+ break;
case 'h':
print_usage();
exit(0);
@@ -384,6 +399,12 @@ main(int argc, char *const argv[])
xkl_debug(0, "The file " PACKAGE "%s is written\n",
binary ? ".xkm" : ".xkb");
break;
+ case ACTION_SEARCH:
+ xkl_config_registry_search_by_pattern(config,
+ pattern,
+ (TwoConfigItemsProcessFunc)
+ print_found_variants,
+ NULL);
}
g_object_unref(G_OBJECT(current_config));