169 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* 
 | 
						|
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
						|
 * Copyright (C) 2011 Red Hat, Inc.
 | 
						|
 * 
 | 
						|
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
 * 02110-1301 USA
 | 
						|
 */
 | 
						|
#include <string.h>
 | 
						|
#include "eekboard/eekboard-xklutil.h"
 | 
						|
 | 
						|
XklConfigRec *
 | 
						|
eekboard_xkl_config_rec_from_string (const gchar *layouts)
 | 
						|
{
 | 
						|
    XklConfigRec *rec;
 | 
						|
    gchar **strv, **l, **v;
 | 
						|
    gint i;
 | 
						|
 | 
						|
    strv = g_strsplit (layouts, "/", -1);
 | 
						|
    g_return_val_if_fail (g_strv_length (strv) == 3, NULL);
 | 
						|
    
 | 
						|
    l = g_strsplit (strv[1], ";", -1);
 | 
						|
    v = g_strdupv (l);
 | 
						|
    for (i = 0; l[i]; i++) {
 | 
						|
        gchar *layout = l[i], *variant = v[i],
 | 
						|
            *variant_start, *variant_end;
 | 
						|
 | 
						|
        variant_start = strchr (layout, '(');
 | 
						|
        variant_end = strrchr (layout, ')');
 | 
						|
        if (variant_start && variant_end) {
 | 
						|
            *variant_start++ = '\0';
 | 
						|
            g_strlcpy (variant, variant_start,
 | 
						|
                       variant_end - variant_start + 1);
 | 
						|
        } else
 | 
						|
            *variant = '\0';
 | 
						|
    }
 | 
						|
 | 
						|
    rec = xkl_config_rec_new ();
 | 
						|
    rec->model = g_strdup (strv[0]);
 | 
						|
    rec->layouts = l;
 | 
						|
    rec->variants = v;
 | 
						|
    rec->options = g_strsplit (strv[2], ";", -1);
 | 
						|
    g_strfreev (strv);
 | 
						|
 | 
						|
    return rec;
 | 
						|
}
 | 
						|
 | 
						|
gchar *
 | 
						|
eekboard_xkl_config_rec_to_string (XklConfigRec *rec)
 | 
						|
{
 | 
						|
    gchar **strv, **sp, **lp, **vp, *p;
 | 
						|
    gint n_layouts;
 | 
						|
    GString *str;
 | 
						|
 | 
						|
    n_layouts = g_strv_length (rec->layouts);
 | 
						|
    strv = g_malloc0_n (n_layouts + 2, sizeof (gchar *));
 | 
						|
    for (sp = strv, lp = rec->layouts, vp = rec->variants; *lp; sp++, lp++) {
 | 
						|
        if (*vp != NULL && **vp != '\0')
 | 
						|
            *sp = g_strdup_printf ("%s(%s)", *lp, *vp++);
 | 
						|
        else
 | 
						|
            *sp = g_strdup_printf ("%s", *lp);
 | 
						|
    }
 | 
						|
 | 
						|
    /* MODEL/L0(V0);L1(V1);...;Ln(Vn)/O0;O1;...;On */
 | 
						|
    str = g_string_new (rec->model);
 | 
						|
 | 
						|
    g_string_append_c (str, '/');
 | 
						|
    p = g_strjoinv (";", strv);
 | 
						|
    g_strfreev (strv);
 | 
						|
    g_string_append (str, p);
 | 
						|
    g_free (p);
 | 
						|
 | 
						|
    g_string_append_c (str, '/');
 | 
						|
    p = g_strjoinv (";", rec->options);
 | 
						|
    g_string_append (str, p);
 | 
						|
    g_free (p);
 | 
						|
 | 
						|
    return g_string_free (str,FALSE);
 | 
						|
}
 | 
						|
 | 
						|
static XklConfigItem *
 | 
						|
xkl_config_item_copy (const XklConfigItem *item)
 | 
						|
{
 | 
						|
    XklConfigItem *_item = xkl_config_item_new ();
 | 
						|
    memcpy (_item->name,
 | 
						|
            item->name,
 | 
						|
            sizeof (item->name));
 | 
						|
    memcpy (_item->short_description,
 | 
						|
            item->short_description,
 | 
						|
            sizeof (item->short_description));
 | 
						|
    memcpy (_item->description,
 | 
						|
            item->description,
 | 
						|
            sizeof (item->description));
 | 
						|
    return _item;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
prepend_item (XklConfigRegistry   *registry,
 | 
						|
              const XklConfigItem *item,
 | 
						|
              gpointer             data)
 | 
						|
{
 | 
						|
    GSList **list = data;
 | 
						|
    XklConfigItem *_item = xkl_config_item_copy (item);
 | 
						|
    *list = g_slist_prepend (*list, _item);
 | 
						|
}
 | 
						|
 | 
						|
static gint
 | 
						|
compare_item_by_name (gconstpointer a, gconstpointer b)
 | 
						|
{
 | 
						|
    const XklConfigItem *ia = a, *ib = b;
 | 
						|
    return g_strcmp0 (ia->name, ib->name);
 | 
						|
}
 | 
						|
 | 
						|
GSList *
 | 
						|
eekboard_xkl_list_models (XklConfigRegistry *registry)
 | 
						|
{
 | 
						|
    GSList *list = NULL;
 | 
						|
    xkl_config_registry_foreach_model (registry, prepend_item, &list);
 | 
						|
    return g_slist_sort (list, compare_item_by_name);
 | 
						|
}
 | 
						|
 | 
						|
GSList *
 | 
						|
eekboard_xkl_list_layouts (XklConfigRegistry *registry)
 | 
						|
{
 | 
						|
    GSList *list = NULL;
 | 
						|
    xkl_config_registry_foreach_layout (registry, prepend_item, &list);
 | 
						|
    return g_slist_sort (list, compare_item_by_name);
 | 
						|
}
 | 
						|
 | 
						|
GSList *
 | 
						|
eekboard_xkl_list_option_groups (XklConfigRegistry *registry)
 | 
						|
{
 | 
						|
    GSList *list = NULL;
 | 
						|
    xkl_config_registry_foreach_option_group (registry, prepend_item, &list);
 | 
						|
    return g_slist_sort (list, compare_item_by_name);
 | 
						|
}
 | 
						|
 | 
						|
GSList *
 | 
						|
eekboard_xkl_list_layout_variants (XklConfigRegistry *registry,
 | 
						|
                                   const gchar       *layout)
 | 
						|
{
 | 
						|
    GSList *list = NULL;
 | 
						|
    xkl_config_registry_foreach_layout_variant (registry,
 | 
						|
                                                layout,
 | 
						|
                                                prepend_item,
 | 
						|
                                                &list);
 | 
						|
    return g_slist_sort (list, compare_item_by_name);
 | 
						|
}
 | 
						|
 | 
						|
GSList *
 | 
						|
eekboard_xkl_list_options (XklConfigRegistry *registry,
 | 
						|
                           const gchar       *group)
 | 
						|
{
 | 
						|
    GSList *list = NULL;
 | 
						|
    xkl_config_registry_foreach_option (registry, group, prepend_item, &list);
 | 
						|
    return g_slist_sort (list, compare_item_by_name);
 | 
						|
}
 |