/* * Copyright (C) 2002-2006 Sergey V. Udaltsov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #ifdef HAVE_SETLOCALE # include #endif extern void xkl_config_rec_dump(FILE * file, XklConfigRec * data); enum { ACTION_NONE, ACTION_LIST, ACTION_GET, ACTION_SET, ACTION_WRITE, ACTION_SEARCH }; static void print_usage(void) { printf ("Usage: test_config (-g)|(-s -m -l -o )|(-h)|(-ws)|(-wb)(-d )|(-p pattern)\n"); printf("Options:\n"); printf(" -al - list all available layouts and variants\n"); printf(" -am - list all available models\n"); printf (" -ao - list all available options groups and options\n"); printf(" -ac - list all available ISO country codes\n"); printf(" -ag - list all available ISO language codes\n"); printf (" -g - Dump the current config, load original system settings and revert back\n"); printf (" -s - Set the configuration given my -m -l -o options. Similar to setxkbmap\n"); printf(" -ws - Write the binary XKB config file (" PACKAGE ".xkm)\n"); 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"); } static void print_option(XklConfigRegistry * config, const XklConfigItem * item, gpointer data) { printf(" [%s][%s][%s]\n", item->name, item->description, item->short_description); } static void print_option_group(XklConfigRegistry * config, const XklConfigItem * item, gpointer data) { printf("[%s][%s][%s] %s multiple selection\n", item->name, item->description, item->short_description, GPOINTER_TO_INT(g_object_get_data (G_OBJECT(item), XCI_PROP_ALLOW_MULTIPLE_SELECTION)) ? "Allows" : "Does not allow"); xkl_config_registry_foreach_option(config, item->name, print_option, data); } static void print_model(XklConfigRegistry * config, const XklConfigItem * item, gpointer data) { gchar *vendor = (gchar *) g_object_get_data(G_OBJECT(item), XCI_PROP_VENDOR); printf("[%s][%s][%s] by %s\n", item->name, item->description, item->short_description, vendor == NULL ? "unknown" : vendor); } static void print_xci(XklConfigRegistry * config, const XklConfigItem * item, gint indent) { 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), XCI_PROP_COUNTRY_LIST); gchar **languages = (gchar **) g_object_get_data(G_OBJECT(item), XCI_PROP_LANGUAGE_LIST); gint i; printf("%*s[%s][%s][%s]%s\n", indent, "", item->name, item->description, item->short_description, is_extra ? ":extra" : ""); if (countries != NULL) for (i = 0; i < g_strv_length(countries); i++) printf("%*s country: [%s]\n", indent, "", countries[i]); if (languages != NULL) for (i = 0; i < g_strv_length(languages); i++) printf("%*s language: [%s]\n", indent, "", languages[i]); } static void print_variant(XklConfigRegistry * config, const XklConfigItem * item, gpointer data) { print_xci(config, item, 2); } static void print_layout(XklConfigRegistry * config, const XklConfigItem * item, gpointer data) { print_xci(config, item, 0); xkl_config_registry_foreach_layout_variant(config, item->name, print_variant, data); } static void print_iso_variant(XklConfigRegistry * config, const XklConfigItem * item, const XklConfigItem * subitem, gpointer data) { print_xci(config, item, 2); if (subitem) print_xci(config, subitem, 4); } static void print_country(XklConfigRegistry * config, const XklConfigItem * item, gpointer data) { printf("country: "); print_xci(config, item, 0); xkl_config_registry_foreach_country_variant(config, item->name, print_iso_variant, data); } static void print_language(XklConfigRegistry * config, const XklConfigItem * item, gpointer data) { printf("language: "); print_xci(config, item, 0); xkl_config_registry_foreach_language_variant(config, item->name, print_iso_variant, data); } static void print_found_variants(XklConfigRegistry * config, const XklConfigItem * parent_item, const XklConfigItem * child_item) { if (child_item == NULL) printf("found layout: [%s]\n", parent_item->name); else printf("found variant: [%s][%s]\n", parent_item->name, child_item->name); } int main(int argc, char *const argv[]) { int c; gchar which_list = 0; int action = ACTION_NONE; 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; XklEngine *engine; g_type_init_with_debug_flags(G_TYPE_DEBUG_OBJECTS | G_TYPE_DEBUG_SIGNALS); while (1) { c = getopt(argc, argv, "ha:sgm:l:o:d:w:c:p:"); if (c == -1) break; switch (c) { case 'a': which_list = optarg[0]; printf("List the registry\n"); action = ACTION_LIST; break; case 's': printf("Set the config\n"); action = ACTION_SET; break; case 'g': printf("Get the config\n"); action = ACTION_GET; break; case 'm': printf("Model: [%s]\n", model = optarg); break; case 'l': printf("Layouts: [%s]\n", layouts = optarg); break; 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); case 'd': debug_level = atoi(optarg); break; case 'w': action = ACTION_WRITE; binary = ('b' == optarg[0]); default: fprintf(stderr, "?? getopt returned character code 0%o ??\n", c); print_usage(); } } if (action == ACTION_NONE) { print_usage(); exit(0); } #ifdef HAVE_SETLOCALE setlocale(LC_ALL, ""); #endif dpy = XOpenDisplay(NULL); if (dpy == NULL) { fprintf(stderr, "Could not open display\n"); exit(1); } if (debug_level != -1) xkl_set_debug_level(debug_level); engine = xkl_engine_get_instance(dpy); if (engine != NULL) { XklConfigRec *current_config, *r2; XklConfigRegistry *config; xkl_debug(0, "Xklavier initialized\n"); config = xkl_config_registry_get_instance(engine); xkl_config_registry_load(config, TRUE); xkl_debug(0, "Xklavier registry loaded\n"); xkl_debug(0, "Backend: [%s]\n", xkl_engine_get_backend_name(engine)); xkl_debug(0, "Supported features: 0x0%X\n", xkl_engine_get_features(engine)); xkl_debug(0, "Max number of groups: %d\n", xkl_engine_get_max_num_groups(engine)); current_config = xkl_config_rec_new(); xkl_config_rec_get_from_server(current_config, engine); switch (action) { case ACTION_LIST: switch (which_list) { case 'l': xkl_config_registry_foreach_layout(config, print_layout, NULL); break; case 'm': xkl_config_registry_foreach_model(config, print_model, NULL); break; case 'o': xkl_config_registry_foreach_option_group (config, print_option_group, NULL); break; case 'c': xkl_config_registry_foreach_country (config, print_country, NULL); break; case 'g': xkl_config_registry_foreach_language (config, print_language, NULL); break; default: printf("Unknown list: %c\n", which_list); print_usage(); break; } break; case ACTION_GET: xkl_debug(0, "Got config from the server\n"); xkl_config_rec_dump(stdout, current_config); r2 = xkl_config_rec_new(); if (xkl_config_rec_get_from_backup(r2, engine)) { xkl_debug(0, "Got config from the backup\n"); xkl_config_rec_dump(stdout, r2); } if (xkl_config_rec_activate(r2, engine)) { xkl_debug(0, "The backup configuration restored\n"); if (xkl_config_rec_activate (current_config, engine)) { xkl_debug(0, "Reverting the configuration change\n"); } else { xkl_debug(0, "The configuration could not be reverted: %s\n", xkl_get_last_error()); } } else { xkl_debug(0, "The backup configuration could not be restored: %s\n", xkl_get_last_error()); } g_object_unref(G_OBJECT(r2)); break; case ACTION_SET: if (model != NULL) { if (current_config->model != NULL) g_free(current_config->model); current_config->model = g_strdup(model); } if (layouts != NULL) { if (current_config->layouts != NULL) g_strfreev (current_config->layouts); if (current_config->variants != NULL) g_strfreev (current_config->variants); current_config->layouts = g_new0(char *, 2); current_config->layouts[0] = g_strdup(layouts); current_config->variants = g_new0(char *, 2); current_config->variants[0] = g_strdup(""); } if (options != NULL) { if (current_config->options != NULL) g_strfreev (current_config->options); current_config->options = g_new0(char *, 2); current_config->options[0] = g_strdup(options); } xkl_debug(0, "New config:\n"); xkl_config_rec_dump(stdout, current_config); if (xkl_config_rec_activate (current_config, engine)) xkl_debug(0, "Set the config\n"); else xkl_debug(0, "Could not set the config: %s\n", xkl_get_last_error()); break; case ACTION_WRITE: xkl_config_rec_write_to_file(engine, binary ? (PACKAGE ".xkm") : (PACKAGE ".xkb"), current_config, binary); 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)); g_object_unref(G_OBJECT(config)); xkl_debug(0, "Xklavier registry freed\n"); xkl_debug(0, "Xklavier terminating\n"); g_object_unref(G_OBJECT(engine)); } else { fprintf(stderr, "Could not init _xklavier\n"); exit(2); } printf("closing display: %p\n", dpy); XCloseDisplay(dpy); return 0; }