diff options
author | Perberos <[email protected]> | 2011-12-01 20:53:10 -0300 |
---|---|---|
committer | Perberos <[email protected]> | 2011-12-01 20:53:10 -0300 |
commit | 916e2eafe251b44f9d0339282f5d00723899caec (patch) | |
tree | d650ca8c97d834499ca107a2a59a41c86c1fc4a9 /libmatekbd/matekbd-keyboard-config.c | |
download | libmatekbd-916e2eafe251b44f9d0339282f5d00723899caec.tar.bz2 libmatekbd-916e2eafe251b44f9d0339282f5d00723899caec.tar.xz |
moving from https://github.com/perberos/mate-desktop-environment
Diffstat (limited to 'libmatekbd/matekbd-keyboard-config.c')
-rw-r--r-- | libmatekbd/matekbd-keyboard-config.c | 827 |
1 files changed, 827 insertions, 0 deletions
diff --git a/libmatekbd/matekbd-keyboard-config.c b/libmatekbd/matekbd-keyboard-config.c new file mode 100644 index 0000000..8be2a37 --- /dev/null +++ b/libmatekbd/matekbd-keyboard-config.c @@ -0,0 +1,827 @@ +/* + * Copyright (C) 2006 Sergey V. Udaltsov <[email protected]> + * + * 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 <config.h> + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <X11/keysym.h> + +#include <glib/gi18n.h> + +#include <matekbd-keyboard-config.h> +#include <matekbd-config-private.h> + +/** + * MatekbdKeyboardConfig + */ +#define MATEKBD_KEYBOARD_CONFIG_KEY_PREFIX MATEKBD_CONFIG_KEY_PREFIX "/kbd" + +#define GROUP_SWITCHERS_GROUP "grp" +#define DEFAULT_GROUP_SWITCH "grp:shift_caps_toggle" + +const gchar MATEKBD_KEYBOARD_CONFIG_DIR[] = MATEKBD_KEYBOARD_CONFIG_KEY_PREFIX; +const gchar MATEKBD_KEYBOARD_CONFIG_KEY_MODEL[] = + MATEKBD_KEYBOARD_CONFIG_KEY_PREFIX "/model"; +const gchar MATEKBD_KEYBOARD_CONFIG_KEY_LAYOUTS[] = + MATEKBD_KEYBOARD_CONFIG_KEY_PREFIX "/layouts"; +const gchar MATEKBD_KEYBOARD_CONFIG_KEY_OPTIONS[] = + MATEKBD_KEYBOARD_CONFIG_KEY_PREFIX "/options"; + +const gchar *MATEKBD_KEYBOARD_CONFIG_ACTIVE[] = { + MATEKBD_KEYBOARD_CONFIG_KEY_MODEL, + MATEKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, + MATEKBD_KEYBOARD_CONFIG_KEY_OPTIONS +}; + +/** + * static common functions + */ +static void +matekbd_keyboard_config_string_list_reset (GSList ** plist) +{ + while (*plist != NULL) { + GSList *p = *plist; + *plist = (*plist)->next; + g_free (p->data); + g_slist_free_1 (p); + } +} + +static gboolean +gslist_str_equal (GSList * l1, GSList * l2) +{ + if (l1 == l2) + return TRUE; + while (l1 != NULL && l2 != NULL) { + if ((l1->data != l2->data) && + (l1->data != NULL) && + (l2->data != NULL) && + g_ascii_strcasecmp (l1->data, l2->data)) + return False; + + l1 = l1->next; + l2 = l2->next; + } + return (l1 == NULL && l2 == NULL); +} + +gboolean +matekbd_keyboard_config_get_lv_descriptions (XklConfigRegistry * + config_registry, + const gchar * layout_name, + const gchar * variant_name, + gchar ** layout_short_descr, + gchar ** layout_descr, + gchar ** variant_short_descr, + gchar ** variant_descr) +{ + /* TODO make it not static */ + static XklConfigItem *litem = NULL; + static XklConfigItem *vitem = NULL; + + if (litem == NULL) + litem = xkl_config_item_new (); + if (vitem == NULL) + vitem = xkl_config_item_new (); + + layout_name = g_strdup (layout_name); + + g_snprintf (litem->name, sizeof litem->name, "%s", layout_name); + if (xkl_config_registry_find_layout (config_registry, litem)) { + *layout_short_descr = litem->short_description; + *layout_descr = litem->description; + } else + *layout_short_descr = *layout_descr = NULL; + + if (variant_name != NULL) { + variant_name = g_strdup (variant_name); + g_snprintf (vitem->name, sizeof vitem->name, "%s", + variant_name); + if (xkl_config_registry_find_variant + (config_registry, layout_name, vitem)) { + *variant_short_descr = vitem->short_description; + *variant_descr = vitem->description; + } else + *variant_short_descr = *variant_descr = NULL; + + g_free ((char *) variant_name); + } else + *variant_descr = NULL; + + g_free ((char *) layout_name); + return *layout_descr != NULL; +} + +/** + * extern common functions + */ +const gchar * +matekbd_keyboard_config_merge_items (const gchar * parent, + const gchar * child) +{ + static gchar buffer[XKL_MAX_CI_NAME_LENGTH * 2 - 1]; + *buffer = '\0'; + if (parent != NULL) { + if (strlen (parent) >= XKL_MAX_CI_NAME_LENGTH) + return NULL; + strcat (buffer, parent); + } + if (child != NULL && *child != 0) { + if (strlen (child) >= XKL_MAX_CI_NAME_LENGTH) + return NULL; + strcat (buffer, "\t"); + strcat (buffer, child); + } + return buffer; +} + +gboolean +matekbd_keyboard_config_split_items (const gchar * merged, gchar ** parent, + gchar ** child) +{ + static gchar pbuffer[XKL_MAX_CI_NAME_LENGTH]; + static gchar cbuffer[XKL_MAX_CI_NAME_LENGTH]; + int plen, clen; + const gchar *pos; + *parent = *child = NULL; + + if (merged == NULL) + return FALSE; + + pos = strchr (merged, '\t'); + if (pos == NULL) { + plen = strlen (merged); + clen = 0; + } else { + plen = pos - merged; + clen = strlen (pos + 1); + if (clen >= XKL_MAX_CI_NAME_LENGTH) + return FALSE; + strcpy (*child = cbuffer, pos + 1); + } + if (plen >= XKL_MAX_CI_NAME_LENGTH) + return FALSE; + memcpy (*parent = pbuffer, merged, plen); + pbuffer[plen] = '\0'; + return TRUE; +} + +/** + * static MatekbdKeyboardConfig functions + */ +static void +matekbd_keyboard_config_options_add_full (MatekbdKeyboardConfig * kbd_config, + const gchar * full_option_name) +{ + kbd_config->options = + g_slist_append (kbd_config->options, + g_strdup (full_option_name)); +} + +static void +matekbd_keyboard_config_layouts_add_full (MatekbdKeyboardConfig * kbd_config, + const gchar * full_layout_name) +{ + kbd_config->layouts_variants = + g_slist_append (kbd_config->layouts_variants, + g_strdup (full_layout_name)); +} + +static void +matekbd_keyboard_config_copy_from_xkl_config (MatekbdKeyboardConfig * kbd_config, + XklConfigRec * pdata) +{ + char **p, **p1; + matekbd_keyboard_config_model_set (kbd_config, pdata->model); + xkl_debug (150, "Loaded Kbd model: [%s]\n", pdata->model); + + matekbd_keyboard_config_layouts_reset (kbd_config); + p = pdata->layouts; + p1 = pdata->variants; + while (p != NULL && *p != NULL) { + const gchar *full_layout = + matekbd_keyboard_config_merge_items (*p, *p1); + xkl_debug (150, + "Loaded Kbd layout (with variant): [%s]\n", + full_layout); + matekbd_keyboard_config_layouts_add_full (kbd_config, + full_layout); + p++; + p1++; + } + + matekbd_keyboard_config_options_reset (kbd_config); + p = pdata->options; + while (p != NULL && *p != NULL) { + char group[XKL_MAX_CI_NAME_LENGTH]; + char *option = *p; + char *delim = + (option != NULL) ? strchr (option, ':') : NULL; + int len; + if ((delim != NULL) && + ((len = (delim - option)) < XKL_MAX_CI_NAME_LENGTH)) { + strncpy (group, option, len); + group[len] = 0; + xkl_debug (150, "Loaded Kbd option: [%s][%s]\n", + group, option); + matekbd_keyboard_config_options_add (kbd_config, + group, option); + } + p++; + } +} + +static void +matekbd_keyboard_config_copy_to_xkl_config (MatekbdKeyboardConfig * kbd_config, + XklConfigRec * pdata) +{ + int i; + int num_layouts, num_options; + pdata->model = + (kbd_config->model == + NULL) ? NULL : g_strdup (kbd_config->model); + + num_layouts = + (kbd_config->layouts_variants == + NULL) ? 0 : g_slist_length (kbd_config->layouts_variants); + num_options = + (kbd_config->options == + NULL) ? 0 : g_slist_length (kbd_config->options); + + xkl_debug (150, "Taking %d layouts\n", num_layouts); + if (num_layouts != 0) { + GSList *the_layout_variant = kbd_config->layouts_variants; + char **p1 = pdata->layouts = + g_new0 (char *, num_layouts + 1); + char **p2 = pdata->variants = + g_new0 (char *, num_layouts + 1); + for (i = num_layouts; --i >= 0;) { + char *layout, *variant; + if (matekbd_keyboard_config_split_items + (the_layout_variant->data, &layout, &variant) + && variant != NULL) { + *p1 = + (layout == + NULL) ? g_strdup ("") : + g_strdup (layout); + *p2 = + (variant == + NULL) ? g_strdup ("") : + g_strdup (variant); + } else { + *p1 = + (the_layout_variant->data == + NULL) ? g_strdup ("") : + g_strdup (the_layout_variant->data); + *p2 = g_strdup (""); + } + xkl_debug (150, "Adding [%s]/%p and [%s]/%p\n", + *p1 ? *p1 : "(nil)", *p1, + *p2 ? *p2 : "(nil)", *p2); + p1++; + p2++; + the_layout_variant = the_layout_variant->next; + } + } + + if (num_options != 0) { + GSList *the_option = kbd_config->options; + char **p = pdata->options = + g_new0 (char *, num_options + 1); + for (i = num_options; --i >= 0;) { + char *group, *option; + if (matekbd_keyboard_config_split_items + (the_option->data, &group, &option) + && option != NULL) + *(p++) = g_strdup (option); + else { + *(p++) = g_strdup (""); + xkl_debug (150, "Could not split [%s]\n", + the_option->data); + } + the_option = the_option->next; + } + } +} + +static void +matekbd_keyboard_config_load_params (MatekbdKeyboardConfig * kbd_config, + const gchar * param_names[]) +{ + GError *gerror = NULL; + gchar *pc; + GSList *pl, *l; + + pc = mateconf_client_get_string (kbd_config->conf_client, + param_names[0], &gerror); + if (pc == NULL || gerror != NULL) { + if (gerror != NULL) { + g_warning ("Error reading configuration:%s\n", + gerror->message); + g_error_free (gerror); + g_free (pc); + gerror = NULL; + } + matekbd_keyboard_config_model_set (kbd_config, NULL); + } else { + matekbd_keyboard_config_model_set (kbd_config, pc); + g_free (pc); + } + xkl_debug (150, "Loaded Kbd model: [%s]\n", + kbd_config->model ? kbd_config->model : "(null)"); + + matekbd_keyboard_config_layouts_reset (kbd_config); + + l = pl = mateconf_client_get_list (kbd_config->conf_client, + param_names[1], + MATECONF_VALUE_STRING, &gerror); + if (pl == NULL || gerror != NULL) { + if (gerror != NULL) { + g_warning ("Error reading configuration:%s\n", + gerror->message); + g_error_free (gerror); + gerror = NULL; + } + } + + while (l != NULL) { + xkl_debug (150, "Loaded Kbd layout: [%s]\n", l->data); + matekbd_keyboard_config_layouts_add_full (kbd_config, + l->data); + l = l->next; + } + matekbd_keyboard_config_string_list_reset (&pl); + + matekbd_keyboard_config_options_reset (kbd_config); + + l = pl = mateconf_client_get_list (kbd_config->conf_client, + param_names[2], + MATECONF_VALUE_STRING, &gerror); + if (pl == NULL || gerror != NULL) { + if (gerror != NULL) { + g_warning ("Error reading configuration:%s\n", + gerror->message); + g_error_free (gerror); + gerror = NULL; + } + } + + while (l != NULL) { + xkl_debug (150, "Loaded Kbd option: [%s]\n", l->data); + matekbd_keyboard_config_options_add_full (kbd_config, + (const gchar *) + l->data); + l = l->next; + } + matekbd_keyboard_config_string_list_reset (&pl); +} + +static void +matekbd_keyboard_config_save_params (MatekbdKeyboardConfig * kbd_config, + MateConfChangeSet * cs, + const gchar * param_names[]) +{ + GSList *pl; + + if (kbd_config->model) + mateconf_change_set_set_string (cs, param_names[0], + kbd_config->model); + else + mateconf_change_set_unset (cs, param_names[0]); + xkl_debug (150, "Saved Kbd model: [%s]\n", + kbd_config->model ? kbd_config->model : "(null)"); + + if (kbd_config->layouts_variants) { + pl = kbd_config->layouts_variants; + while (pl != NULL) { + xkl_debug (150, "Saved Kbd layout: [%s]\n", + pl->data); + pl = pl->next; + } + mateconf_change_set_set_list (cs, + param_names[1], + MATECONF_VALUE_STRING, + kbd_config->layouts_variants); + } else { + xkl_debug (150, "Saved Kbd layouts: []\n"); + mateconf_change_set_unset (cs, param_names[1]); + } + + if (kbd_config->options) { + pl = kbd_config->options; + while (pl != NULL) { + xkl_debug (150, "Saved Kbd option: [%s]\n", + pl->data); + pl = pl->next; + } + mateconf_change_set_set_list (cs, + param_names[2], + MATECONF_VALUE_STRING, + kbd_config->options); + } else { + xkl_debug (150, "Saved Kbd options: []\n"); + mateconf_change_set_unset (cs, param_names[2]); + } +} + +/** + * extern MatekbdKeyboardConfig config functions + */ +void +matekbd_keyboard_config_init (MatekbdKeyboardConfig * kbd_config, + MateConfClient * conf_client, XklEngine * engine) +{ + GError *gerror = NULL; + + memset (kbd_config, 0, sizeof (*kbd_config)); + kbd_config->conf_client = conf_client; + kbd_config->engine = engine; + g_object_ref (kbd_config->conf_client); + + mateconf_client_add_dir (kbd_config->conf_client, + MATEKBD_KEYBOARD_CONFIG_DIR, + MATECONF_CLIENT_PRELOAD_NONE, &gerror); + if (gerror != NULL) { + g_warning ("err: %s\n", gerror->message); + g_error_free (gerror); + gerror = NULL; + } +} + +void +matekbd_keyboard_config_term (MatekbdKeyboardConfig * kbd_config) +{ + matekbd_keyboard_config_model_set (kbd_config, NULL); + + matekbd_keyboard_config_layouts_reset (kbd_config); + matekbd_keyboard_config_options_reset (kbd_config); + + g_object_unref (kbd_config->conf_client); + kbd_config->conf_client = NULL; +} + +void +matekbd_keyboard_config_load_from_mateconf (MatekbdKeyboardConfig * kbd_config, + MatekbdKeyboardConfig * + kbd_config_default) +{ + matekbd_keyboard_config_load_params (kbd_config, + MATEKBD_KEYBOARD_CONFIG_ACTIVE); + + if (kbd_config_default != NULL) { + GSList *pl; + + if (kbd_config->model == NULL) + kbd_config->model = + g_strdup (kbd_config_default->model); + + if (kbd_config->layouts_variants == NULL) { + pl = kbd_config_default->layouts_variants; + while (pl != NULL) { + kbd_config->layouts_variants = + g_slist_append + (kbd_config->layouts_variants, + g_strdup (pl->data)); + pl = pl->next; + } + } + + if (kbd_config->options == NULL) { + pl = kbd_config_default->options; + while (pl != NULL) { + kbd_config->options = + g_slist_append (kbd_config->options, + g_strdup (pl->data)); + pl = pl->next; + } + } + } +} + +void +matekbd_keyboard_config_load_from_x_current (MatekbdKeyboardConfig * kbd_config, + XklConfigRec * data) +{ + gboolean own_data = data == NULL; + xkl_debug (150, "Copying config from X(current)\n"); + if (own_data) + data = xkl_config_rec_new (); + if (xkl_config_rec_get_from_server (data, kbd_config->engine)) + matekbd_keyboard_config_copy_from_xkl_config (kbd_config, + data); + else + xkl_debug (150, + "Could not load keyboard config from server: [%s]\n", + xkl_get_last_error ()); + if (own_data) + g_object_unref (G_OBJECT (data)); +} + +void +matekbd_keyboard_config_load_from_x_initial (MatekbdKeyboardConfig * kbd_config, + XklConfigRec * data) +{ + gboolean own_data = data == NULL; + xkl_debug (150, "Copying config from X(initial)\n"); + if (own_data) + data = xkl_config_rec_new (); + if (xkl_config_rec_get_from_backup (data, kbd_config->engine)) + matekbd_keyboard_config_copy_from_xkl_config (kbd_config, + data); + else + xkl_debug (150, + "Could not load keyboard config from backup: [%s]\n", + xkl_get_last_error ()); + if (own_data) + g_object_unref (G_OBJECT (data)); +} + +gboolean +matekbd_keyboard_config_equals (MatekbdKeyboardConfig * kbd_config1, + MatekbdKeyboardConfig * kbd_config2) +{ + if (kbd_config1 == kbd_config2) + return True; + if ((kbd_config1->model != kbd_config2->model) && + (kbd_config1->model != NULL) && + (kbd_config2->model != NULL) && + g_ascii_strcasecmp (kbd_config1->model, kbd_config2->model)) + return False; + return gslist_str_equal (kbd_config1->layouts_variants, + kbd_config2->layouts_variants) + && gslist_str_equal (kbd_config1->options, + kbd_config2->options); +} + +void +matekbd_keyboard_config_save_to_mateconf (MatekbdKeyboardConfig * kbd_config) +{ + MateConfChangeSet *cs; + GError *gerror = NULL; + + cs = mateconf_change_set_new (); + + matekbd_keyboard_config_save_params (kbd_config, cs, + MATEKBD_KEYBOARD_CONFIG_ACTIVE); + + mateconf_client_commit_change_set (kbd_config->conf_client, cs, TRUE, + &gerror); + if (gerror != NULL) { + g_warning ("Error saving active configuration: %s\n", + gerror->message); + g_error_free (gerror); + gerror = NULL; + } + mateconf_change_set_unref (cs); +} + +void +matekbd_keyboard_config_model_set (MatekbdKeyboardConfig * kbd_config, + const gchar * model_name) +{ + if (kbd_config->model != NULL) + g_free (kbd_config->model); + kbd_config->model = + (model_name == NULL + || model_name[0] == '\0') ? NULL : g_strdup (model_name); +} + +void +matekbd_keyboard_config_layouts_add (MatekbdKeyboardConfig * kbd_config, + const gchar * layout_name, + const gchar * variant_name) +{ + const gchar *merged; + if (layout_name == NULL) + return; + merged = + matekbd_keyboard_config_merge_items (layout_name, variant_name); + if (merged == NULL) + return; + matekbd_keyboard_config_layouts_add_full (kbd_config, merged); +} + +void +matekbd_keyboard_config_layouts_reset (MatekbdKeyboardConfig * kbd_config) +{ + matekbd_keyboard_config_string_list_reset + (&kbd_config->layouts_variants); +} + +void +matekbd_keyboard_config_options_reset (MatekbdKeyboardConfig * kbd_config) +{ + matekbd_keyboard_config_string_list_reset (&kbd_config->options); +} + +void +matekbd_keyboard_config_options_add (MatekbdKeyboardConfig * kbd_config, + const gchar * group_name, + const gchar * option_name) +{ + const gchar *merged; + if (group_name == NULL || option_name == NULL) + return; + merged = + matekbd_keyboard_config_merge_items (group_name, option_name); + if (merged == NULL) + return; + matekbd_keyboard_config_options_add_full (kbd_config, merged); +} + +gboolean +matekbd_keyboard_config_options_is_set (MatekbdKeyboardConfig * kbd_config, + const gchar * group_name, + const gchar * option_name) +{ + const gchar *merged = + matekbd_keyboard_config_merge_items (group_name, option_name); + if (merged == NULL) + return FALSE; + + return NULL != g_slist_find_custom (kbd_config->options, (gpointer) + merged, (GCompareFunc) + g_ascii_strcasecmp); +} + +gboolean +matekbd_keyboard_config_activate (MatekbdKeyboardConfig * kbd_config) +{ + gboolean rv; + XklConfigRec *data = xkl_config_rec_new (); + + matekbd_keyboard_config_copy_to_xkl_config (kbd_config, data); + rv = xkl_config_rec_activate (data, kbd_config->engine); + g_object_unref (G_OBJECT (data)); + + return rv; +} + +void +matekbd_keyboard_config_start_listen (MatekbdKeyboardConfig * kbd_config, + MateConfClientNotifyFunc func, + gpointer user_data) +{ + matekbd_desktop_config_add_listener (kbd_config->conf_client, + MATEKBD_KEYBOARD_CONFIG_DIR, func, + user_data, + &kbd_config->config_listener_id); +} + +void +matekbd_keyboard_config_stop_listen (MatekbdKeyboardConfig * kbd_config) +{ + matekbd_desktop_config_remove_listener (kbd_config->conf_client, + &kbd_config-> + config_listener_id); +} + +gboolean +matekbd_keyboard_config_get_descriptions (XklConfigRegistry * config_registry, + const gchar * name, + gchar ** layout_short_descr, + gchar ** layout_descr, + gchar ** variant_short_descr, + gchar ** variant_descr) +{ + char *layout_name = NULL, *variant_name = NULL; + if (!matekbd_keyboard_config_split_items + (name, &layout_name, &variant_name)) + return FALSE; + return matekbd_keyboard_config_get_lv_descriptions (config_registry, + layout_name, + variant_name, + layout_short_descr, + layout_descr, + variant_short_descr, + variant_descr); +} + +const gchar * +matekbd_keyboard_config_format_full_layout (const gchar * layout_descr, + const gchar * variant_descr) +{ + static gchar full_descr[XKL_MAX_CI_DESC_LENGTH * 2]; + if (variant_descr == NULL || variant_descr[0] == 0) + g_snprintf (full_descr, sizeof (full_descr), "%s", + layout_descr); + else + g_snprintf (full_descr, sizeof (full_descr), "%s %s", + layout_descr, variant_descr); + return full_descr; +} + +gchar * +matekbd_keyboard_config_to_string (const MatekbdKeyboardConfig * config) +{ + gchar *layouts = NULL, *options = NULL; + GString *buffer = g_string_new (NULL); + + GSList *iter; + gint count; + gchar *result; + + if (config->layouts_variants) { + /* g_slist_length is "expensive", so we determinate the length on the fly */ + for (iter = config->layouts_variants, count = 0; iter; + iter = iter->next, ++count) { + if (buffer->len) + g_string_append (buffer, " "); + + g_string_append (buffer, + (const gchar *) iter->data); + } + + /* Translators: The count is related to the number of options. The %s + * format specifier should not be modified, left "as is". */ + layouts = + g_strdup_printf (ngettext + ("layout \"%s\"", "layouts \"%s\"", + count), buffer->str); + g_string_truncate (buffer, 0); + } + if (config->options) { + /* g_slist_length is "expensive", so we determinate the length on the fly */ + for (iter = config->options, count = 0; iter; + iter = iter->next, ++count) { + if (buffer->len) + g_string_append (buffer, " "); + + g_string_append (buffer, + (const gchar *) iter->data); + } + + /* Translators: The count is related to the number of options. The %s + * format specifier should not be modified, left "as is". */ + options = + g_strdup_printf (ngettext + ("option \"%s\"", "options \"%s\"", + count), buffer->str); + g_string_truncate (buffer, 0); + } + + g_string_free (buffer, TRUE); + + result = + g_strdup_printf (_("model \"%s\", %s and %s"), config->model, + layouts ? layouts : _("no layout"), + options ? options : _("no options")); + + g_free (options); + g_free (layouts); + + return result; +} + +GSList * +matekbd_keyboard_config_add_default_switch_option_if_necessary (GSList * + layouts_list, + GSList * + options_list, gboolean *was_appended) +{ + *was_appended = FALSE; + if (g_slist_length (layouts_list) >= 2) { + gboolean any_switcher = False; + GSList *option = options_list; + while (option != NULL) { + char *g, *o; + if (matekbd_keyboard_config_split_items + (option->data, &g, &o)) { + if (!g_ascii_strcasecmp + (g, GROUP_SWITCHERS_GROUP)) { + any_switcher = True; + break; + } + } + option = option->next; + } + if (!any_switcher) { + const gchar *id = + matekbd_keyboard_config_merge_items + (GROUP_SWITCHERS_GROUP, + DEFAULT_GROUP_SWITCH); + options_list = + g_slist_append (options_list, g_strdup (id)); + *was_appended = TRUE; + } + } + return options_list; +} |