|
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 |
#include <unistd.h>
|
|
Packit Service |
93d855 |
#include <sys/param.h>
|
|
Packit Service |
93d855 |
#include <sys/stat.h>
|
|
Packit Service |
93d855 |
#include <sys/wait.h>
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
#include <sys/types.h>
|
|
Packit Service |
93d855 |
#include <fcntl.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 |
#include "xklavier_private_xkb.h"
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
#ifdef LIBXKBFILE_PRESENT
|
|
Packit Service |
93d855 |
#include <X11/extensions/XKBfile.h>
|
|
Packit Service |
93d855 |
#include <X11/extensions/XKM.h>
|
|
Packit Service |
93d855 |
#endif
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
#define XKBCOMP ( XKB_BIN_BASE "/xkbcomp" )
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
#define XK_XKB_KEYS
|
|
Packit Service |
93d855 |
#include <X11/keysymdef.h>
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
#ifdef LIBXKBFILE_PRESENT
|
|
Packit Service |
93d855 |
static XkbRF_RulesPtr xkl_rules;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static XkbRF_RulesPtr
|
|
Packit Service |
93d855 |
xkl_rules_set_load(XklEngine * engine)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
XkbRF_RulesPtr rules_set = NULL;
|
|
Packit Service |
93d855 |
char file_name[MAXPATHLEN] = "";
|
|
Packit Service |
93d855 |
char *rf =
|
|
Packit Service |
93d855 |
xkl_engine_get_ruleset_name(engine, XKB_DEFAULT_RULESET);
|
|
Packit Service |
93d855 |
char *locale = NULL;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (rf == NULL) {
|
|
Packit Service |
93d855 |
xkl_last_error_message =
|
|
Packit Service |
93d855 |
"Could not find the XKB rules set";
|
|
Packit Service |
93d855 |
return NULL;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
locale = setlocale(LC_ALL, NULL);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
g_snprintf(file_name, sizeof file_name, XKB_BASE "/rules/%s", rf);
|
|
Packit Service |
93d855 |
xkl_debug(160, "Loading rules from [%s]\n", file_name);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
rules_set = XkbRF_Load(file_name, locale, True, True);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (rules_set == NULL) {
|
|
Packit Service |
93d855 |
xkl_last_error_message = "Could not load rules";
|
|
Packit Service |
93d855 |
return NULL;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
return rules_set;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static void
|
|
Packit Service |
93d855 |
xkl_rules_set_free(void)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
if (xkl_rules)
|
|
Packit Service |
93d855 |
XkbRF_Free(xkl_rules, True);
|
|
Packit Service |
93d855 |
xkl_rules = NULL;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
#endif
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
void
|
|
Packit Service |
93d855 |
xkl_xkb_init_config_registry(XklConfigRegistry * config)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
#ifdef LIBXKBFILE_PRESENT
|
|
Packit Service |
93d855 |
XkbInitAtoms(NULL);
|
|
Packit Service |
93d855 |
#endif
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
gboolean
|
|
Packit Service |
93d855 |
xkl_xkb_load_config_registry(XklConfigRegistry * config,
|
|
Packit Service |
93d855 |
gboolean if_extras_needed)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
return xkl_config_registry_load_helper(config,
|
|
Packit Service |
93d855 |
XKB_DEFAULT_RULESET,
|
|
Packit Service |
93d855 |
XKB_BASE "/rules",
|
|
Packit Service |
93d855 |
if_extras_needed);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
#ifdef LIBXKBFILE_PRESENT
|
|
Packit Service |
93d855 |
gboolean
|
|
Packit Service |
93d855 |
xkl_xkb_config_native_prepare(XklEngine * engine,
|
|
Packit Service |
93d855 |
const XklConfigRec * data,
|
|
Packit Service |
93d855 |
XkbComponentNamesPtr component_names_ptr)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
XkbRF_VarDefsRec xkl_var_defs;
|
|
Packit Service |
93d855 |
gboolean got_components;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
memset(&xkl_var_defs, 0, sizeof(xkl_var_defs));
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
xkl_rules = xkl_rules_set_load(engine);
|
|
Packit Service |
93d855 |
if (!xkl_rules) {
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
xkl_var_defs.model = (char *) data->model;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (data->layouts != NULL)
|
|
Packit Service |
93d855 |
xkl_var_defs.layout = xkl_config_rec_merge_layouts(data);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (data->variants != NULL)
|
|
Packit Service |
93d855 |
xkl_var_defs.variant = xkl_config_rec_merge_variants(data);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (data->options != NULL)
|
|
Packit Service |
93d855 |
xkl_var_defs.options = xkl_config_rec_merge_options(data);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
got_components =
|
|
Packit Service |
93d855 |
XkbRF_GetComponents(xkl_rules, &xkl_var_defs,
|
|
Packit Service |
93d855 |
component_names_ptr);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
g_free(xkl_var_defs.layout);
|
|
Packit Service |
93d855 |
g_free(xkl_var_defs.variant);
|
|
Packit Service |
93d855 |
g_free(xkl_var_defs.options);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (!got_components) {
|
|
Packit Service |
93d855 |
xkl_last_error_message =
|
|
Packit Service |
93d855 |
"Could not translate rules into components";
|
|
Packit Service |
93d855 |
/* Just cleanup the stuff in case of failure */
|
|
Packit Service |
93d855 |
xkl_xkb_config_native_cleanup(engine, component_names_ptr);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (xkl_debug_level >= 200) {
|
|
Packit Service |
93d855 |
xkl_debug(200, "keymap: %s\n",
|
|
Packit Service |
93d855 |
component_names_ptr->keymap);
|
|
Packit Service |
93d855 |
xkl_debug(200, "keycodes: %s\n",
|
|
Packit Service |
93d855 |
component_names_ptr->keycodes);
|
|
Packit Service |
93d855 |
xkl_debug(200, "compat: %s\n",
|
|
Packit Service |
93d855 |
component_names_ptr->compat);
|
|
Packit Service |
93d855 |
xkl_debug(200, "types: %s\n", component_names_ptr->types);
|
|
Packit Service |
93d855 |
xkl_debug(200, "symbols: %s\n",
|
|
Packit Service |
93d855 |
component_names_ptr->symbols);
|
|
Packit Service |
93d855 |
xkl_debug(200, "geometry: %s\n",
|
|
Packit Service |
93d855 |
component_names_ptr->geometry);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
return TRUE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
void
|
|
Packit Service |
93d855 |
xkl_xkb_config_native_cleanup(XklEngine * engine,
|
|
Packit Service |
93d855 |
XkbComponentNamesPtr component_names_ptr)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
xkl_rules_set_free();
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
g_free(component_names_ptr->keymap);
|
|
Packit Service |
93d855 |
g_free(component_names_ptr->keycodes);
|
|
Packit Service |
93d855 |
g_free(component_names_ptr->compat);
|
|
Packit Service |
93d855 |
g_free(component_names_ptr->types);
|
|
Packit Service |
93d855 |
g_free(component_names_ptr->symbols);
|
|
Packit Service |
93d855 |
g_free(component_names_ptr->geometry);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static gchar *
|
|
Packit Service |
93d855 |
xkl_config_get_current_group_description(XklEngine * engine)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
XklState state;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
xkl_xkb_get_server_state(engine, &state);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
int group = state.group;
|
|
Packit Service |
93d855 |
if ((group < 0) ||
|
|
Packit Service |
93d855 |
(group >=
|
|
Packit Service |
93d855 |
xkl_engine_backend(engine, XklXkb,
|
|
Packit Service |
93d855 |
cached_desc)->ctrls->num_groups))
|
|
Packit Service |
93d855 |
return NULL;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
return g_strdup(xkl_engine_backend(engine, XklXkb, group_names)
|
|
Packit Service |
93d855 |
[group]);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static void
|
|
Packit Service |
93d855 |
xkl_config_set_group_by_description(XklEngine * engine, gchar * descr)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
int group, n_groups;
|
|
Packit Service |
93d855 |
gchar **group_names;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (descr == NULL)
|
|
Packit Service |
93d855 |
return;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
// perhaps could be made mode lightweight?
|
|
Packit Service |
93d855 |
xkl_engine_reset_all_info(engine, FALSE,
|
|
Packit Service |
93d855 |
"Direct reload on activation");
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
n_groups =
|
|
Packit Service |
93d855 |
xkl_engine_backend(engine, XklXkb,
|
|
Packit Service |
93d855 |
cached_desc)->ctrls->num_groups;
|
|
Packit Service |
93d855 |
group_names = xkl_engine_backend(engine, XklXkb, group_names);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
for (group = 0; group < n_groups; group++, group_names++) {
|
|
Packit Service |
93d855 |
if (!g_ascii_strcasecmp(descr, *group_names)) {
|
|
Packit Service |
93d855 |
xkl_debug(150,
|
|
Packit Service |
93d855 |
"Found the group with the same description, %d: [%s]\n",
|
|
Packit Service |
93d855 |
group, *group_names);
|
|
Packit Service |
93d855 |
xkl_engine_lock_group(engine, group);
|
|
Packit Service |
93d855 |
break;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
g_free(descr);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static XkbDescPtr
|
|
Packit Service |
93d855 |
xkl_config_get_keyboard(XklEngine * engine,
|
|
Packit Service |
93d855 |
XkbComponentNamesPtr component_names_ptr,
|
|
Packit Service |
93d855 |
gboolean activate)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
XkbDescPtr xkb = NULL;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
char xkm_fn[L_tmpnam];
|
|
Packit Service |
93d855 |
char xkb_fn[L_tmpnam];
|
|
Packit Service |
93d855 |
FILE *tmpxkm;
|
|
Packit Service |
93d855 |
XkbFileInfo result;
|
|
Packit Service |
93d855 |
int xkmloadres;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
Display *display = xkl_engine_get_display(engine);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
gchar *preactivation_group_description = activate ?
|
|
Packit Service |
93d855 |
xkl_config_get_current_group_description(engine) : NULL;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (tmpnam(xkm_fn) != NULL && tmpnam(xkb_fn) != NULL) {
|
|
Packit Service |
93d855 |
pid_t cpid, pid;
|
|
Packit Service |
93d855 |
int status = 0;
|
|
Packit Service |
93d855 |
FILE *tmpxkb;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
xkl_debug(150, "tmp XKB/XKM file names: [%s]/[%s]\n",
|
|
Packit Service |
93d855 |
xkb_fn, xkm_fn);
|
|
Packit Service |
93d855 |
if ((tmpxkb = fopen(xkb_fn, "w")) != NULL) {
|
|
Packit Service |
93d855 |
fprintf(tmpxkb, "xkb_keymap {\n");
|
|
Packit Service |
93d855 |
fprintf(tmpxkb,
|
|
Packit Service |
93d855 |
" xkb_keycodes { include \"%s\" };\n",
|
|
Packit Service |
93d855 |
component_names_ptr->keycodes);
|
|
Packit Service |
93d855 |
fprintf(tmpxkb,
|
|
Packit Service |
93d855 |
" xkb_types { include \"%s\" };\n",
|
|
Packit Service |
93d855 |
component_names_ptr->types);
|
|
Packit Service |
93d855 |
fprintf(tmpxkb,
|
|
Packit Service |
93d855 |
" xkb_compat { include \"%s\" };\n",
|
|
Packit Service |
93d855 |
component_names_ptr->compat);
|
|
Packit Service |
93d855 |
fprintf(tmpxkb,
|
|
Packit Service |
93d855 |
" xkb_symbols { include \"%s\" };\n",
|
|
Packit Service |
93d855 |
component_names_ptr->symbols);
|
|
Packit Service |
93d855 |
fprintf(tmpxkb,
|
|
Packit Service |
93d855 |
" xkb_geometry { include \"%s\" };\n",
|
|
Packit Service |
93d855 |
component_names_ptr->geometry);
|
|
Packit Service |
93d855 |
fprintf(tmpxkb, "};\n");
|
|
Packit Service |
93d855 |
fclose(tmpxkb);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
xkl_debug(150, "xkb_keymap {\n"
|
|
Packit Service |
93d855 |
" xkb_keycodes { include \"%s\" };\n"
|
|
Packit Service |
93d855 |
" xkb_types { include \"%s\" };\n"
|
|
Packit Service |
93d855 |
" xkb_compat { include \"%s\" };\n"
|
|
Packit Service |
93d855 |
" xkb_symbols { include \"%s\" };\n"
|
|
Packit Service |
93d855 |
" xkb_geometry { include \"%s\" };\n};\n",
|
|
Packit Service |
93d855 |
component_names_ptr->keycodes,
|
|
Packit Service |
93d855 |
component_names_ptr->types,
|
|
Packit Service |
93d855 |
component_names_ptr->compat,
|
|
Packit Service |
93d855 |
component_names_ptr->symbols,
|
|
Packit Service |
93d855 |
component_names_ptr->geometry);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
XSync(display, False);
|
|
Packit Service |
93d855 |
/* From this point, ALL errors should be intercepted only by libxklavier */
|
|
Packit Service |
93d855 |
xkl_engine_priv(engine, critical_section) = TRUE;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
cpid = fork();
|
|
Packit Service |
93d855 |
switch (cpid) {
|
|
Packit Service |
93d855 |
case -1:
|
|
Packit Service |
93d855 |
xkl_debug(0, "Could not fork: %d\n",
|
|
Packit Service |
93d855 |
errno);
|
|
Packit Service |
93d855 |
break;
|
|
Packit Service |
93d855 |
case 0:
|
|
Packit Service |
93d855 |
/* child */
|
|
Packit Service |
93d855 |
xkl_debug(160, "Executing %s\n", XKBCOMP);
|
|
Packit Service |
93d855 |
xkl_debug(160, "%s %s %s %s %s %s %s %s\n",
|
|
Packit Service |
93d855 |
XKBCOMP, XKBCOMP, "-w0", "-I",
|
|
Packit Service |
93d855 |
"-I" XKB_BASE, "-xkm", xkb_fn,
|
|
Packit Service |
93d855 |
xkm_fn);
|
|
Packit Service |
93d855 |
execl(XKBCOMP, XKBCOMP, "-w0", "-I",
|
|
Packit Service |
93d855 |
"-I" XKB_BASE, "-xkm", xkb_fn,
|
|
Packit Service |
93d855 |
xkm_fn, NULL);
|
|
Packit Service |
93d855 |
xkl_debug(0, "Could not exec %s: %d\n",
|
|
Packit Service |
93d855 |
XKBCOMP, errno);
|
|
Packit Service |
93d855 |
exit(1);
|
|
Packit Service |
93d855 |
default:
|
|
Packit Service |
93d855 |
/* parent */
|
|
Packit Service |
93d855 |
pid = waitpid(cpid, &status, 0);
|
|
Packit Service |
93d855 |
xkl_debug(150,
|
|
Packit Service |
93d855 |
"Return status of %d (well, started %d): %d\n",
|
|
Packit Service |
93d855 |
pid, cpid, status);
|
|
Packit Service |
93d855 |
memset((char *) &result, 0,
|
|
Packit Service |
93d855 |
sizeof(result));
|
|
Packit Service |
93d855 |
result.xkb = XkbAllocKeyboard();
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (Success ==
|
|
Packit Service |
93d855 |
XkbChangeKbdDisplay(display,
|
|
Packit Service |
93d855 |
&result)) {
|
|
Packit Service |
93d855 |
xkl_debug(150,
|
|
Packit Service |
93d855 |
"Hacked the kbddesc - set the display...\n");
|
|
Packit Service |
93d855 |
if ((tmpxkm =
|
|
Packit Service |
93d855 |
fopen(xkm_fn, "r")) != NULL) {
|
|
Packit Service |
93d855 |
xkmloadres =
|
|
Packit Service |
93d855 |
XkmReadFile(tmpxkm,
|
|
Packit Service |
93d855 |
XkmKeymapLegal,
|
|
Packit Service |
93d855 |
XkmKeymapLegal,
|
|
Packit Service |
93d855 |
&result);
|
|
Packit Service |
93d855 |
xkl_debug(150,
|
|
Packit Service |
93d855 |
"Loaded %s output as XKM file, got %d (comparing to %d)\n",
|
|
Packit Service |
93d855 |
XKBCOMP,
|
|
Packit Service |
93d855 |
(int) xkmloadres,
|
|
Packit Service |
93d855 |
(int)
|
|
Packit Service |
93d855 |
XkmKeymapLegal);
|
|
Packit Service |
93d855 |
if ((int) xkmloadres !=
|
|
Packit Service |
93d855 |
(int) XkmKeymapLegal) {
|
|
Packit Service |
93d855 |
xkl_debug(150,
|
|
Packit Service |
93d855 |
"Loaded legal keymap\n");
|
|
Packit Service |
93d855 |
if (activate) {
|
|
Packit Service |
93d855 |
xkl_debug
|
|
Packit Service |
93d855 |
(150,
|
|
Packit Service |
93d855 |
"Activating it...\n");
|
|
Packit Service |
93d855 |
if (XkbWriteToServer(&result)) {
|
|
Packit Service |
93d855 |
xkl_debug
|
|
Packit Service |
93d855 |
(150,
|
|
Packit Service |
93d855 |
"Updating the keyboard...\n");
|
|
Packit Service |
93d855 |
xkb = result.xkb;
|
|
Packit Service |
93d855 |
} else {
|
|
Packit Service |
93d855 |
xkl_debug
|
|
Packit Service |
93d855 |
(0,
|
|
Packit Service |
93d855 |
"Could not write keyboard description to the server\n");
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
} else /* no activate, just load */
|
|
Packit Service |
93d855 |
xkb =
|
|
Packit Service |
93d855 |
result.xkb;
|
|
Packit Service |
93d855 |
} else { /* could not load properly */
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
xkl_debug(0,
|
|
Packit Service |
93d855 |
"Could not load %s output as XKM file, got %d (asked %d)\n",
|
|
Packit Service |
93d855 |
XKBCOMP,
|
|
Packit Service |
93d855 |
(int)
|
|
Packit Service |
93d855 |
xkmloadres,
|
|
Packit Service |
93d855 |
(int)
|
|
Packit Service |
93d855 |
XkmKeymapLegal);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
fclose(tmpxkm);
|
|
Packit Service |
93d855 |
xkl_debug(160,
|
|
Packit Service |
93d855 |
"Unlinking the temporary xkm file %s\n",
|
|
Packit Service |
93d855 |
xkm_fn);
|
|
Packit Service |
93d855 |
if (xkl_debug_level < 500) { /* don't remove on high debug levels! */
|
|
Packit Service |
93d855 |
if (remove(xkm_fn)
|
|
Packit Service |
93d855 |
== -1)
|
|
Packit Service |
93d855 |
xkl_debug
|
|
Packit Service |
93d855 |
(0,
|
|
Packit Service |
93d855 |
"Could not unlink the temporary xkm file %s: %d\n",
|
|
Packit Service |
93d855 |
xkm_fn,
|
|
Packit Service |
93d855 |
errno);
|
|
Packit Service |
93d855 |
} else
|
|
Packit Service |
93d855 |
xkl_debug(500,
|
|
Packit Service |
93d855 |
"Well, not really - the debug level is too high: %d\n",
|
|
Packit Service |
93d855 |
xkl_debug_level);
|
|
Packit Service |
93d855 |
} else { /* could not open the file */
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
xkl_debug(0,
|
|
Packit Service |
93d855 |
"Could not open the temporary xkm file %s\n",
|
|
Packit Service |
93d855 |
xkm_fn);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
} else { /* could not assign to display */
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
xkl_debug(0,
|
|
Packit Service |
93d855 |
"Could not change the keyboard description to display\n");
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
if (xkb == NULL)
|
|
Packit Service |
93d855 |
XkbFreeKeyboard(result.xkb,
|
|
Packit Service |
93d855 |
XkbAllComponentsMask,
|
|
Packit Service |
93d855 |
True);
|
|
Packit Service |
93d855 |
break;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
XSync(display, False);
|
|
Packit Service |
93d855 |
/* Return to normal X error processing */
|
|
Packit Service |
93d855 |
xkl_engine_priv(engine, critical_section) = FALSE;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (activate)
|
|
Packit Service |
93d855 |
xkl_config_set_group_by_description(engine,
|
|
Packit Service |
93d855 |
preactivation_group_description);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
xkl_debug(160,
|
|
Packit Service |
93d855 |
"Unlinking the temporary xkb file %s\n",
|
|
Packit Service |
93d855 |
xkb_fn);
|
|
Packit Service |
93d855 |
if (xkl_debug_level < 500) { /* don't remove on high debug levels! */
|
|
Packit Service |
93d855 |
if (remove(xkb_fn) == -1)
|
|
Packit Service |
93d855 |
xkl_debug(0,
|
|
Packit Service |
93d855 |
"Could not unlink the temporary xkb file %s: %d\n",
|
|
Packit Service |
93d855 |
xkb_fn, errno);
|
|
Packit Service |
93d855 |
} else
|
|
Packit Service |
93d855 |
xkl_debug(500,
|
|
Packit Service |
93d855 |
"Well, not really - the debug level is too high: %d\n",
|
|
Packit Service |
93d855 |
xkl_debug_level);
|
|
Packit Service |
93d855 |
} else { /* could not open input tmp file */
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
xkl_debug(0,
|
|
Packit Service |
93d855 |
"Could not open tmp XKB file [%s]: %d\n",
|
|
Packit Service |
93d855 |
xkb_fn, errno);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
} else {
|
|
Packit Service |
93d855 |
xkl_debug(0, "Could not get tmp names\n");
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
return xkb;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
#else /* no XKB headers */
|
|
Packit Service |
93d855 |
gboolean
|
|
Packit Service |
93d855 |
xkl_xkb_config_native_prepare(XklEngine * engine,
|
|
Packit Service |
93d855 |
const XklConfigRec * data,
|
|
Packit Service |
93d855 |
gpointer componentNamesPtr)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
void
|
|
Packit Service |
93d855 |
xkl_xkb_config_native_cleanup(XklEngine * engine,
|
|
Packit Service |
93d855 |
gpointer component_names_ptr)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
#endif
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
/* check only client side support */
|
|
Packit Service |
93d855 |
gboolean
|
|
Packit Service |
93d855 |
xkl_xkb_multiple_layouts_supported(XklEngine * engine)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
enum { NON_SUPPORTED, SUPPORTED, UNCHECKED };
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
static int support_state = UNCHECKED;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (support_state == UNCHECKED) {
|
|
Packit Service |
93d855 |
XklConfigRec *data = xkl_config_rec_new();
|
|
Packit Service |
93d855 |
#ifdef LIBXKBFILE_PRESENT
|
|
Packit Service |
93d855 |
XkbComponentNamesRec component_names;
|
|
Packit Service |
93d855 |
memset(&component_names, 0, sizeof(component_names));
|
|
Packit Service |
93d855 |
#endif
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
data->model = g_strdup("pc105");
|
|
Packit Service |
93d855 |
data->layouts = g_strsplit_set("us:de", ":", -1);
|
|
Packit Service |
93d855 |
data->variants = g_strsplit_set(":", ":", -1);
|
|
Packit Service |
93d855 |
data->options = NULL;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
xkl_debug(100, "!!! Checking multiple layouts support\n");
|
|
Packit Service |
93d855 |
support_state = NON_SUPPORTED;
|
|
Packit Service |
93d855 |
#ifdef LIBXKBFILE_PRESENT
|
|
Packit Service |
93d855 |
if (xkl_xkb_config_native_prepare
|
|
Packit Service |
93d855 |
(engine, data, &component_names)) {
|
|
Packit Service |
93d855 |
xkl_debug(100,
|
|
Packit Service |
93d855 |
"!!! Multiple layouts ARE supported\n");
|
|
Packit Service |
93d855 |
support_state = SUPPORTED;
|
|
Packit Service |
93d855 |
xkl_xkb_config_native_cleanup(engine,
|
|
Packit Service |
93d855 |
&component_names);
|
|
Packit Service |
93d855 |
} else {
|
|
Packit Service |
93d855 |
xkl_debug(100,
|
|
Packit Service |
93d855 |
"!!! Multiple layouts ARE NOT supported\n");
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
#endif
|
|
Packit Service |
93d855 |
g_object_unref(G_OBJECT(data));
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
return support_state == SUPPORTED;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
gboolean
|
|
Packit Service |
93d855 |
xkl_xkb_activate_config_rec(XklEngine * engine, const XklConfigRec * data)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
gboolean rv = FALSE;
|
|
Packit Service |
93d855 |
#if 0
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
int i;
|
|
Packit Service |
93d855 |
xkl_debug(150, "New model: [%s]\n", data->model);
|
|
Packit Service |
93d855 |
xkl_debug(150, "New layouts: %p\n", data->layouts);
|
|
Packit Service |
93d855 |
for (i = 0; i < g_strv_length(data->layouts); i++)
|
|
Packit Service |
93d855 |
xkl_debug(150, "New layout[%d]: [%s]\n", i,
|
|
Packit Service |
93d855 |
data->layouts[i]);
|
|
Packit Service |
93d855 |
xkl_debug(150, "New variants: %p\n", data->variants);
|
|
Packit Service |
93d855 |
for (i = 0; i < g_strv_length(data->variants); i++)
|
|
Packit Service |
93d855 |
xkl_debug(150, "New variant[%d]: [%s]\n", i,
|
|
Packit Service |
93d855 |
data->variants[i]);
|
|
Packit Service |
93d855 |
xkl_debug(150, "New options: %p\n", data->options);
|
|
Packit Service |
93d855 |
for (i = 0; i < g_strv_length(data->options); i++)
|
|
Packit Service |
93d855 |
xkl_debug(150, "New option[%d]: [%s]\n", i,
|
|
Packit Service |
93d855 |
data->options[i]);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
#endif
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
#ifdef LIBXKBFILE_PRESENT
|
|
Packit Service |
93d855 |
XkbComponentNamesRec component_names;
|
|
Packit Service |
93d855 |
memset(&component_names, 0, sizeof(component_names));
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (xkl_xkb_config_native_prepare(engine, data, &component_names)) {
|
|
Packit Service |
93d855 |
XkbDescPtr xkb;
|
|
Packit Service |
93d855 |
xkb =
|
|
Packit Service |
93d855 |
xkl_config_get_keyboard(engine, &component_names,
|
|
Packit Service |
93d855 |
TRUE);
|
|
Packit Service |
93d855 |
if (xkb != NULL) {
|
|
Packit Service |
93d855 |
if (xkl_config_rec_set_to_root_window_property
|
|
Packit Service |
93d855 |
(data,
|
|
Packit Service |
93d855 |
xkl_engine_priv(engine, base_config_atom),
|
|
Packit Service |
93d855 |
xkl_engine_get_ruleset_name(engine,
|
|
Packit Service |
93d855 |
XKB_DEFAULT_RULESET),
|
|
Packit Service |
93d855 |
engine))
|
|
Packit Service |
93d855 |
/* We do not need to check the result of _XklGetRulesSetName -
|
|
Packit Service |
93d855 |
because PrepareBeforeKbd did it for us */
|
|
Packit Service |
93d855 |
rv = TRUE;
|
|
Packit Service |
93d855 |
else
|
|
Packit Service |
93d855 |
xkl_last_error_message =
|
|
Packit Service |
93d855 |
"Could not set names property";
|
|
Packit Service |
93d855 |
XkbFreeKeyboard(xkb, XkbAllComponentsMask, True);
|
|
Packit Service |
93d855 |
} else {
|
|
Packit Service |
93d855 |
xkl_last_error_message =
|
|
Packit Service |
93d855 |
"Could not load keyboard description";
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
xkl_xkb_config_native_cleanup(engine, &component_names);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
#endif
|
|
Packit Service |
93d855 |
return rv;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
gboolean
|
|
Packit Service |
93d855 |
xkl_xkb_write_config_rec_to_file(XklEngine * engine, const char *file_name,
|
|
Packit Service |
93d855 |
const XklConfigRec * data,
|
|
Packit Service |
93d855 |
const gboolean binary)
|
|
Packit Service |
93d855 |
{
|
|
Packit Service |
93d855 |
gboolean rv = FALSE;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
#ifdef LIBXKBFILE_PRESENT
|
|
Packit Service |
93d855 |
XkbComponentNamesRec component_names;
|
|
Packit Service |
93d855 |
FILE *output = fopen(file_name, "w");
|
|
Packit Service |
93d855 |
XkbFileInfo dump_info;
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (output == NULL) {
|
|
Packit Service |
93d855 |
xkl_last_error_message = "Could not open the XKB file";
|
|
Packit Service |
93d855 |
return FALSE;
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
memset(&component_names, 0, sizeof(component_names));
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
if (xkl_xkb_config_native_prepare(engine, data, &component_names)) {
|
|
Packit Service |
93d855 |
XkbDescPtr xkb;
|
|
Packit Service |
93d855 |
xkb =
|
|
Packit Service |
93d855 |
xkl_config_get_keyboard(engine, &component_names,
|
|
Packit Service |
93d855 |
FALSE);
|
|
Packit Service |
93d855 |
if (xkb != NULL) {
|
|
Packit Service |
93d855 |
dump_info.defined = 0;
|
|
Packit Service |
93d855 |
dump_info.xkb = xkb;
|
|
Packit Service |
93d855 |
dump_info.type = XkmKeymapFile;
|
|
Packit Service |
93d855 |
if (binary)
|
|
Packit Service |
93d855 |
rv = XkbWriteXKMFile(output, &dump_info);
|
|
Packit Service |
93d855 |
else
|
|
Packit Service |
93d855 |
rv = XkbWriteXKBFile(output, &dump_info,
|
|
Packit Service |
93d855 |
True, NULL, NULL);
|
|
Packit Service |
93d855 |
|
|
Packit Service |
93d855 |
XkbFreeKeyboard(xkb, XkbGBN_AllComponentsMask,
|
|
Packit Service |
93d855 |
True);
|
|
Packit Service |
93d855 |
} else
|
|
Packit Service |
93d855 |
xkl_last_error_message =
|
|
Packit Service |
93d855 |
"Could not load keyboard description";
|
|
Packit Service |
93d855 |
xkl_xkb_config_native_cleanup(engine, &component_names);
|
|
Packit Service |
93d855 |
}
|
|
Packit Service |
93d855 |
fclose(output);
|
|
Packit Service |
93d855 |
#endif
|
|
Packit Service |
93d855 |
return rv;
|
|
Packit Service |
93d855 |
}
|