|
Packit Service |
93d855 |
/*
|
|
Packit Service |
93d855 |
* Copyright (C) 2002-2006 Sergey V. Udaltsov <svu@gnome.org>
|
|
Packit Service |
93d855 |
*
|
|
Packit Service |
93d855 |
* This library is free software; you can redistribute it and/or
|
|
Packit Service |
93d855 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit Service |
93d855 |
* License as published by the Free Software Foundation; either
|
|
Packit Service |
93d855 |
* version 2 of the License, or (at your option) any later version.
|
|
Packit Service |
93d855 |
*
|
|
Packit Service |
93d855 |
* This library is distributed in the hope that it will be useful,
|
|
Packit Service |
93d855 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
93d855 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
93d855 |
* Lesser General Public License for more details.
|
|
Packit Service |
93d855 |
*
|
|
Packit Service |
93d855 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
93d855 |
* License along with this library; if not, write to the
|
|
Packit Service |
93d855 |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Packit Service |
93d855 |
* Boston, MA 02111-1307, USA.
|
|
Packit Service |
93d855 |
*/
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
#include <errno.h>
|
|
Packit Service |
93d855 |
#include <locale.h>
|
|
Packit Service |
93d855 |
#include <string.h>
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
#include <X11/Xlib.h>
|
|
Packit Service |
93d855 |
#include <X11/Xatom.h>
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
#include <libxml/xpath.h>
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
#include "config.h"
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
#include "xklavier_private.h"
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static GObjectClass *parent_class = NULL;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static void xkl_config_rec_destroy(XklConfigRec * data);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
G_DEFINE_TYPE(XklConfigItem, xkl_config_item, G_TYPE_OBJECT)
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static void
|
|
Packit Service |
93d855 |
xkl_config_item_init(XklConfigItem * this)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static void
|
|
Packit Service |
93d855 |
xkl_config_item_class_init(XklConfigItemClass * klass)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
XklConfigItem *
|
|
Packit Service |
93d855 |
xkl_config_item_new(void)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
return
|
|
Packit Service |
93d855 |
XKL_CONFIG_ITEM(g_object_new
|
|
Packit Service |
93d855 |
(xkl_config_item_get_type(), NULL));
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
const gchar *
|
|
Packit Service |
93d855 |
xkl_config_item_get_name(XklConfigItem * item)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
return item->name;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
void
|
|
Packit Service |
93d855 |
xkl_config_item_set_name(XklConfigItem * item,
|
|
Packit Service |
93d855 |
const gchar * name)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
if (name != NULL)
|
|
Packit Service |
93d855 |
strncpy (item->name, name, XKL_MAX_CI_SHORT_DESC_LENGTH-1);
|
|
Packit Service |
93d855 |
else
|
|
Packit Service |
93d855 |
item->name[0] = '\0';
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
const gchar *
|
|
Packit Service |
93d855 |
xkl_config_item_get_short_description(XklConfigItem * item)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
return item->short_description;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
void
|
|
Packit Service |
93d855 |
xkl_config_item_set_short_description(XklConfigItem * item,
|
|
Packit Service |
93d855 |
const gchar * short_description)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
if (short_description != NULL)
|
|
Packit Service |
93d855 |
strncpy (item->short_description, short_description, XKL_MAX_CI_DESC_LENGTH-1);
|
|
Packit Service |
93d855 |
else
|
|
Packit Service |
93d855 |
item->short_description[0] = '\0';
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
const gchar *
|
|
Packit Service |
93d855 |
xkl_config_item_get_description(XklConfigItem * item)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
return item->description;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
void
|
|
Packit Service |
93d855 |
xkl_config_item_set_description(XklConfigItem * item,
|
|
Packit Service |
93d855 |
const gchar * description)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
if (description != NULL)
|
|
Packit Service |
93d855 |
strncpy (item->description, description, XKL_MAX_CI_NAME_LENGTH-1);
|
|
Packit Service |
93d855 |
else
|
|
Packit Service |
93d855 |
item->description[0] = '\0';
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
G_DEFINE_TYPE(XklConfigRec, xkl_config_rec, G_TYPE_OBJECT)
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static void
|
|
Packit Service |
93d855 |
xkl_config_rec_finalize(GObject * obj)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
XklConfigRec *this = (XklConfigRec *) obj;
|
|
Packit Service |
93d855 |
xkl_config_rec_destroy(this);
|
|
Packit Service |
93d855 |
G_OBJECT_CLASS(parent_class)->finalize(obj);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static void
|
|
Packit Service |
93d855 |
xkl_config_rec_class_init(XklConfigRecClass * klass)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
GObjectClass *object_class;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
object_class = (GObjectClass *) klass;
|
|
Packit Service |
93d855 |
parent_class = g_type_class_peek_parent(object_class);
|
|
Packit Service |
93d855 |
object_class->finalize = xkl_config_rec_finalize;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
XklConfigRec *
|
|
Packit Service |
93d855 |
xkl_config_rec_new(void)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
return
|
|
Packit Service |
93d855 |
XKL_CONFIG_REC(g_object_new(xkl_config_rec_get_type(), NULL));
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static gboolean
|
|
Packit Service |
93d855 |
xkl_strings_equal(gchar * p1, gchar * p2)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
if (p1 == p2)
|
|
Packit Service |
93d855 |
return TRUE;
|
|
Packit Service |
93d855 |
if ((p1 == NULL && p2 != NULL) || (p1 != NULL && p2 == NULL))
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
return !g_ascii_strcasecmp(p1, p2);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static gboolean
|
|
Packit Service |
93d855 |
xkl_lists_equal(gchar ** items1, gchar ** items2)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
if (items1 == items2)
|
|
Packit Service |
93d855 |
return TRUE;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if ((items1 == NULL && items2 != NULL) ||
|
|
Packit Service |
93d855 |
(items1 != NULL && items2 == NULL))
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
while (*items1 != NULL && *items2 != NULL)
|
|
Packit Service |
93d855 |
if (!xkl_strings_equal(*items1++, *items2++))
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
return (*items1 == NULL && *items2 == NULL);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static gboolean
|
|
Packit Service |
93d855 |
xkl_engine_get_default_names_prop(XklEngine * engine,
|
|
Packit Service |
93d855 |
char **rules_file_out,
|
|
Packit Service |
93d855 |
XklConfigRec * data)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
if (rules_file_out != NULL)
|
|
Packit Service |
93d855 |
*rules_file_out = g_strdup(XKB_DEFAULT_RULESET);
|
|
Packit Service |
93d855 |
data->model = g_strdup(xkl_engine_priv(engine, default_model));
|
|
Packit Service |
93d855 |
/* keeping Nvariants = Nlayouts */
|
|
Packit Service |
93d855 |
data->layouts = g_new0(char *, 2);
|
|
Packit Service |
93d855 |
data->layouts[0] =
|
|
Packit Service |
93d855 |
g_strdup(xkl_engine_priv(engine, default_layout));
|
|
Packit Service |
93d855 |
data->variants = g_new0(char *, 2);
|
|
Packit Service |
93d855 |
data->variants[0] = g_strdup("");
|
|
Packit Service |
93d855 |
data->options = g_new0(char *, 1);
|
|
Packit Service |
93d855 |
return TRUE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
gboolean
|
|
Packit Service |
93d855 |
xkl_config_rec_get_full_from_server(char **rules_file_out,
|
|
Packit Service |
93d855 |
XklConfigRec * data,
|
|
Packit Service |
93d855 |
XklEngine * engine)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
gboolean rv = xkl_config_rec_get_from_root_window_property(data,
|
|
Packit Service |
93d855 |
xkl_engine_priv
|
|
Packit Service |
93d855 |
(engine,
|
|
Packit Service |
93d855 |
base_config_atom),
|
|
Packit Service |
93d855 |
rules_file_out,
|
|
Packit Service |
93d855 |
engine);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (!rv)
|
|
Packit Service |
93d855 |
rv = xkl_engine_get_default_names_prop(engine,
|
|
Packit Service |
93d855 |
rules_file_out,
|
|
Packit Service |
93d855 |
data);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
return rv;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
gboolean
|
|
Packit Service |
93d855 |
xkl_config_rec_equals(XklConfigRec * data1, XklConfigRec * data2)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
if (data1 == data2)
|
|
Packit Service |
93d855 |
return TRUE;
|
|
Packit Service |
93d855 |
if (!xkl_strings_equal(data1->model, data2->model))
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
if (!xkl_lists_equal(data1->layouts, data2->layouts))
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
if (!xkl_lists_equal(data1->variants, data2->variants))
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
return xkl_lists_equal(data1->options, data2->options);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
void
|
|
Packit Service |
93d855 |
xkl_config_rec_set_layouts(XklConfigRec * data,
|
|
Packit Service |
93d855 |
const gchar ** new_layouts)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
g_strfreev (data->layouts);
|
|
Packit Service |
93d855 |
data->layouts = g_strdupv ((gchar**) new_layouts);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
void
|
|
Packit Service |
93d855 |
xkl_config_rec_set_variants(XklConfigRec * data,
|
|
Packit Service |
93d855 |
const gchar ** new_variants)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
g_strfreev (data->variants);
|
|
Packit Service |
93d855 |
data->variants = g_strdupv ((gchar**) new_variants);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
void
|
|
Packit Service |
93d855 |
xkl_config_rec_set_options(XklConfigRec * data,
|
|
Packit Service |
93d855 |
const gchar ** new_options)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
g_strfreev (data->options);
|
|
Packit Service |
93d855 |
data->options = g_strdupv ((gchar**) new_options);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
void
|
|
Packit Service |
93d855 |
xkl_config_rec_set_model(XklConfigRec * data,
|
|
Packit Service |
93d855 |
const gchar * new_model)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
g_free (data->model);
|
|
Packit Service |
93d855 |
data->model = g_strdup (new_model);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
void
|
|
Packit Service |
93d855 |
xkl_config_rec_init(XklConfigRec * data)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
/* clear the structure VarDefsPtr... */
|
|
Packit Service |
93d855 |
data->model = NULL;
|
|
Packit Service |
93d855 |
data->layouts = data->variants = data->options = NULL;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
void
|
|
Packit Service |
93d855 |
xkl_config_rec_destroy(XklConfigRec * data)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
if (data->model != NULL)
|
|
Packit Service |
93d855 |
g_free(data->model);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
g_strfreev(data->layouts);
|
|
Packit Service |
93d855 |
g_strfreev(data->variants);
|
|
Packit Service |
93d855 |
g_strfreev(data->options);
|
|
Packit Service |
93d855 |
data->layouts = data->variants = data->options = NULL;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
void
|
|
Packit Service |
93d855 |
xkl_config_rec_reset(XklConfigRec * data)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
xkl_config_rec_destroy(data);
|
|
Packit Service |
93d855 |
xkl_config_rec_init(data);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
gboolean
|
|
Packit Service |
93d855 |
xkl_config_rec_get_from_server(XklConfigRec * data, XklEngine * engine)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
return xkl_config_rec_get_full_from_server(NULL, data, engine);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
gboolean
|
|
Packit Service |
93d855 |
xkl_config_rec_get_from_backup(XklConfigRec * data, XklEngine * engine)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
return xkl_config_rec_get_from_root_window_property(data,
|
|
Packit Service |
93d855 |
xkl_engine_priv
|
|
Packit Service |
93d855 |
(engine,
|
|
Packit Service |
93d855 |
backup_config_atom),
|
|
Packit Service |
93d855 |
NULL, engine);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
gboolean
|
|
Packit Service |
93d855 |
xkl_engine_backup_names_prop(XklEngine * engine)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
gboolean rv = TRUE;
|
|
Packit Service |
93d855 |
gchar *rf = NULL;
|
|
Packit Service |
93d855 |
XklConfigRec *data = xkl_config_rec_new();
|
|
Packit Service |
93d855 |
gboolean cgp = FALSE;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (xkl_config_rec_get_from_root_window_property
|
|
Packit Service |
93d855 |
(data, xkl_engine_priv(engine, backup_config_atom), NULL,
|
|
Packit Service |
93d855 |
engine)) {
|
|
Packit Service |
93d855 |
g_object_unref(G_OBJECT(data));
|
|
Packit Service |
93d855 |
return TRUE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
/* "backup" property is not defined */
|
|
Packit Service |
93d855 |
xkl_config_rec_reset(data);
|
|
Packit Service |
93d855 |
cgp = xkl_config_rec_get_full_from_server(&rf, data, engine);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (cgp) {
|
|
Packit Service |
93d855 |
if (!xkl_config_rec_set_to_root_window_property
|
|
Packit Service |
93d855 |
(data, xkl_engine_priv(engine, backup_config_atom),
|
|
Packit Service |
93d855 |
rf, engine)) {
|
|
Packit Service |
93d855 |
xkl_debug(150,
|
|
Packit Service |
93d855 |
"Could not backup the configuration");
|
|
Packit Service |
93d855 |
rv = FALSE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
if (rf != NULL)
|
|
Packit Service |
93d855 |
g_free(rf);
|
|
Packit Service |
93d855 |
} else {
|
|
Packit Service |
93d855 |
xkl_debug(150,
|
|
Packit Service |
93d855 |
"Could not get the configuration for backup");
|
|
Packit Service |
93d855 |
rv = FALSE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
g_object_unref(G_OBJECT(data));
|
|
Packit Service |
93d855 |
return rv;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
gboolean
|
|
Packit Service |
93d855 |
xkl_restore_names_prop(XklEngine * engine)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
gboolean rv = TRUE;
|
|
Packit Service |
93d855 |
gchar *rf = NULL;
|
|
Packit Service |
93d855 |
XklConfigRec *data = xkl_config_rec_new();
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (!xkl_config_rec_get_from_root_window_property
|
|
Packit Service |
93d855 |
(data, xkl_engine_priv(engine, backup_config_atom), NULL,
|
|
Packit Service |
93d855 |
engine)) {
|
|
Packit Service |
93d855 |
g_object_unref(G_OBJECT(data));
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (!xkl_config_rec_set_to_root_window_property
|
|
Packit Service |
93d855 |
(data, xkl_engine_priv(engine, base_config_atom), rf,
|
|
Packit Service |
93d855 |
engine)) {
|
|
Packit Service |
93d855 |
xkl_debug(150, "Could not backup the configuration");
|
|
Packit Service |
93d855 |
rv = FALSE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
g_object_unref(G_OBJECT(data));
|
|
Packit Service |
93d855 |
return rv;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
gboolean
|
|
Packit Service |
93d855 |
xkl_config_rec_get_from_root_window_property(XklConfigRec * data,
|
|
Packit Service |
93d855 |
Atom rules_atom,
|
|
Packit Service |
93d855 |
gchar ** rules_file_out,
|
|
Packit Service |
93d855 |
XklEngine * engine)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
Atom real_prop_type;
|
|
Packit Service |
93d855 |
int fmt;
|
|
Packit Service |
93d855 |
unsigned long nitems, extra_bytes;
|
|
Packit Service |
93d855 |
char *prop_data = NULL, *out;
|
|
Packit Service |
93d855 |
Status rtrn;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
/* no such atom! */
|
|
Packit Service |
93d855 |
if (rules_atom == None) { /* property cannot exist */
|
|
Packit Service |
93d855 |
xkl_last_error_message = "Could not find the atom";
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
rtrn =
|
|
Packit Service |
93d855 |
XGetWindowProperty(xkl_engine_get_display(engine),
|
|
Packit Service |
93d855 |
xkl_engine_priv(engine, root_window),
|
|
Packit Service |
93d855 |
rules_atom, 0L, XKB_RF_NAMES_PROP_MAXLEN,
|
|
Packit Service |
93d855 |
False, XA_STRING, &real_prop_type, &fmt,
|
|
Packit Service |
93d855 |
&nitems, &extra_bytes,
|
|
Packit Service |
93d855 |
(unsigned char **) (void *) &prop_data);
|
|
Packit Service |
93d855 |
/* property not found! */
|
|
Packit Service |
93d855 |
if (rtrn != Success) {
|
|
Packit Service |
93d855 |
xkl_last_error_message = "Could not get the property";
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
/* set rules file to "" */
|
|
Packit Service |
93d855 |
if (rules_file_out)
|
|
Packit Service |
93d855 |
*rules_file_out = NULL;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
/* has to be array of strings */
|
|
Packit Service |
93d855 |
if ((extra_bytes > 0) || (real_prop_type != XA_STRING)
|
|
Packit Service |
93d855 |
|| (fmt != 8)) {
|
|
Packit Service |
93d855 |
if (prop_data)
|
|
Packit Service |
93d855 |
XFree(prop_data);
|
|
Packit Service |
93d855 |
xkl_last_error_message = "Wrong property format";
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (!prop_data) {
|
|
Packit Service |
93d855 |
xkl_last_error_message = "No properties returned";
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
/* rules file */
|
|
Packit Service |
93d855 |
out = prop_data;
|
|
Packit Service |
93d855 |
if (out && (*out) && rules_file_out)
|
|
Packit Service |
93d855 |
*rules_file_out = g_strdup(out);
|
|
Packit Service |
93d855 |
out += strlen(out) + 1;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
/* if user is interested in rules only - don't waste the time */
|
|
Packit Service |
93d855 |
if (!data) {
|
|
Packit Service |
93d855 |
XFree(prop_data);
|
|
Packit Service |
93d855 |
return TRUE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if ((out - prop_data) < nitems) {
|
|
Packit Service |
93d855 |
if (*out)
|
|
Packit Service |
93d855 |
data->model = g_strdup(out);
|
|
Packit Service |
93d855 |
out += strlen(out) + 1;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if ((out - prop_data) < nitems) {
|
|
Packit Service |
93d855 |
xkl_config_rec_split_layouts(data, out);
|
|
Packit Service |
93d855 |
out += strlen(out) + 1;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if ((out - prop_data) < nitems) {
|
|
Packit Service |
93d855 |
gint nv, nl;
|
|
Packit Service |
93d855 |
gchar **layout, **variant;
|
|
Packit Service |
93d855 |
xkl_config_rec_split_variants(data, out);
|
|
Packit Service |
93d855 |
/*
|
|
Packit Service |
93d855 |
Now have to ensure that number of variants matches the number of layouts
|
|
Packit Service |
93d855 |
The 'remainder' is filled with NULLs (not ""s!)
|
|
Packit Service |
93d855 |
*/
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
nv = g_strv_length(data->variants);
|
|
Packit Service |
93d855 |
nl = g_strv_length(data->layouts);
|
|
Packit Service |
93d855 |
if (nv < nl) {
|
|
Packit Service |
93d855 |
data->variants = g_realloc(data->variants,
|
|
Packit Service |
93d855 |
(nl +
|
|
Packit Service |
93d855 |
1) * sizeof(char *));
|
|
Packit Service |
93d855 |
memset(data->variants + nv + 1, 0,
|
|
Packit Service |
93d855 |
(nl - nv) * sizeof(char *));
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
/* take variants from layouts like ru(winkeys) */
|
|
Packit Service |
93d855 |
layout = data->layouts;
|
|
Packit Service |
93d855 |
variant = data->variants;
|
|
Packit Service |
93d855 |
while (*layout != NULL && *variant == NULL) {
|
|
Packit Service |
93d855 |
gchar *varstart = g_strstr_len(*layout, -1, "(");
|
|
Packit Service |
93d855 |
if (varstart != NULL) {
|
|
Packit Service |
93d855 |
gchar *varend =
|
|
Packit Service |
93d855 |
g_strstr_len(varstart, -1, ")");
|
|
Packit Service |
93d855 |
if (varend != NULL) {
|
|
Packit Service |
93d855 |
gint varlen = varend - varstart;
|
|
Packit Service |
93d855 |
gint laylen = varstart - *layout;
|
|
Packit Service |
93d855 |
/* I am not sure - but I assume variants in layout have priority */
|
|
Packit Service |
93d855 |
gchar *var = *variant =
|
|
Packit Service |
93d855 |
(*variant !=
|
|
Packit Service |
93d855 |
NULL) ? g_realloc(*variant,
|
|
Packit Service |
93d855 |
varlen) :
|
|
Packit Service |
93d855 |
g_new(gchar, varlen);
|
|
Packit Service |
93d855 |
memcpy(var, varstart + 1,
|
|
Packit Service |
93d855 |
--varlen);
|
|
Packit Service |
93d855 |
var[varlen] = '\0';
|
|
Packit Service |
93d855 |
/* Resize the original layout */
|
|
Packit Service |
93d855 |
*layout =
|
|
Packit Service |
93d855 |
g_realloc(*layout, laylen + 1);
|
|
Packit Service |
93d855 |
(*layout)[laylen] = '\0';
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
layout++;
|
|
Packit Service |
93d855 |
variant++;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
out += strlen(out) + 1;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if ((out - prop_data) < nitems) {
|
|
Packit Service |
93d855 |
xkl_config_rec_split_options(data, out);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
XFree(prop_data);
|
|
Packit Service |
93d855 |
return TRUE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
/* taken from XFree86 maprules.c */
|
|
Packit Service |
93d855 |
gboolean
|
|
Packit Service |
93d855 |
xkl_config_rec_set_to_root_window_property(const XklConfigRec * data,
|
|
Packit Service |
93d855 |
Atom rules_atom,
|
|
Packit Service |
93d855 |
gchar * rules_file,
|
|
Packit Service |
93d855 |
XklEngine * engine)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
gint len;
|
|
Packit Service |
93d855 |
gchar *pval;
|
|
Packit Service |
93d855 |
gchar *next;
|
|
Packit Service |
93d855 |
gchar *all_layouts = xkl_config_rec_merge_layouts(data);
|
|
Packit Service |
93d855 |
gchar *all_variants = xkl_config_rec_merge_variants(data);
|
|
Packit Service |
93d855 |
gchar *all_options = xkl_config_rec_merge_options(data);
|
|
Packit Service |
93d855 |
Display *display;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
len = (rules_file ? strlen(rules_file) : 0);
|
|
Packit Service |
93d855 |
len += (data->model ? strlen(data->model) : 0);
|
|
Packit Service |
93d855 |
len += (all_layouts ? strlen(all_layouts) : 0);
|
|
Packit Service |
93d855 |
len += (all_variants ? strlen(all_variants) : 0);
|
|
Packit Service |
93d855 |
len += (all_options ? strlen(all_options) : 0);
|
|
Packit Service |
93d855 |
if (len < 1) {
|
|
Packit Service |
93d855 |
if (all_layouts)
|
|
Packit Service |
93d855 |
g_free(all_layouts);
|
|
Packit Service |
93d855 |
if (all_variants)
|
|
Packit Service |
93d855 |
g_free(all_variants);
|
|
Packit Service |
93d855 |
if (all_options)
|
|
Packit Service |
93d855 |
g_free(all_options);
|
|
Packit Service |
93d855 |
return TRUE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
len += 5; /* trailing NULs */
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
pval = next = g_new(char, len + 1);
|
|
Packit Service |
93d855 |
if (!pval) {
|
|
Packit Service |
93d855 |
xkl_last_error_message = "Could not allocate buffer";
|
|
Packit Service |
93d855 |
if (all_layouts != NULL)
|
|
Packit Service |
93d855 |
g_free(all_layouts);
|
|
Packit Service |
93d855 |
if (all_variants != NULL)
|
|
Packit Service |
93d855 |
g_free(all_variants);
|
|
Packit Service |
93d855 |
if (all_options != NULL)
|
|
Packit Service |
93d855 |
g_free(all_options);
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
if (rules_file) {
|
|
Packit Service |
93d855 |
strcpy(next, rules_file);
|
|
Packit Service |
93d855 |
next += strlen(rules_file);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
*next++ = '\0';
|
|
Packit Service |
93d855 |
if (data->model) {
|
|
Packit Service |
93d855 |
strcpy(next, data->model);
|
|
Packit Service |
93d855 |
next += strlen(data->model);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
*next++ = '\0';
|
|
Packit Service |
93d855 |
if (data->layouts) {
|
|
Packit Service |
93d855 |
strcpy(next, all_layouts);
|
|
Packit Service |
93d855 |
next += strlen(all_layouts);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
*next++ = '\0';
|
|
Packit Service |
93d855 |
if (data->variants) {
|
|
Packit Service |
93d855 |
strcpy(next, all_variants);
|
|
Packit Service |
93d855 |
next += strlen(all_variants);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
*next++ = '\0';
|
|
Packit Service |
93d855 |
if (data->options) {
|
|
Packit Service |
93d855 |
strcpy(next, all_options);
|
|
Packit Service |
93d855 |
next += strlen(all_options);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
*next++ = '\0';
|
|
Packit Service |
93d855 |
if ((next - pval) != len) {
|
|
Packit Service |
93d855 |
xkl_debug(150, "Illegal final position: %d/%d\n",
|
|
Packit Service |
93d855 |
(next - pval), len);
|
|
Packit Service |
93d855 |
if (all_layouts != NULL)
|
|
Packit Service |
93d855 |
g_free(all_layouts);
|
|
Packit Service |
93d855 |
if (all_variants != NULL)
|
|
Packit Service |
93d855 |
g_free(all_variants);
|
|
Packit Service |
93d855 |
if (all_options != NULL)
|
|
Packit Service |
93d855 |
g_free(all_options);
|
|
Packit Service |
93d855 |
g_free(pval);
|
|
Packit Service |
93d855 |
xkl_last_error_message = "Internal property parsing error";
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
display = xkl_engine_get_display(engine);
|
|
Packit Service |
93d855 |
XChangeProperty(display, xkl_engine_priv(engine, root_window),
|
|
Packit Service |
93d855 |
rules_atom, XA_STRING, 8, PropModeReplace,
|
|
Packit Service |
93d855 |
(unsigned char *) pval, len);
|
|
Packit Service |
93d855 |
XSync(display, False);
|
|
Packit Service |
93d855 |
#if 0
|
|
Packit Service |
93d855 |
for (i = len - 1; --i >= 0;)
|
|
Packit Service |
93d855 |
if (pval[i] == '\0')
|
|
Packit Service |
93d855 |
pval[i] = '?';
|
|
Packit Service |
93d855 |
XklDebug(150, "Stored [%s] of length %d to [%s] of %X\n", pval,
|
|
Packit Service |
93d855 |
len, propName, _xklRootWindow);
|
|
Packit Service |
93d855 |
#endif
|
|
Packit Service |
93d855 |
if (all_layouts != NULL)
|
|
Packit Service |
93d855 |
g_free(all_layouts);
|
|
Packit Service |
93d855 |
if (all_variants != NULL)
|
|
Packit Service |
93d855 |
g_free(all_variants);
|
|
Packit Service |
93d855 |
if (all_options != NULL)
|
|
Packit Service |
93d855 |
g_free(all_options);
|
|
Packit Service |
93d855 |
g_free(pval);
|
|
Packit Service |
93d855 |
return TRUE;
|
|
Packit Service |
93d855 |
}
|