summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/xkbcommon/src
diff options
context:
space:
mode:
authorGatis Paeglis <gatis.paeglis@digia.com>2013-04-11 10:51:49 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-05-07 22:43:14 +0200
commit2122e731abdb619249df89642c0800640b2fa428 (patch)
tree0692aed54d1dbf90ed140da23f0de6c2f656b64f /src/3rdparty/xkbcommon/src
parent4635536bfbdde4dce3fc6af025448dfc610b553b (diff)
Add libxkbcommon to 3rd party libs
This library is required by the XCB platform plugin. As we depend on very recent version of this library and it might not be available in base repositories of distributions, users can use -qt-xkbcommom switch to build Qt with the bundled version. Change-Id: I0ed2a5cc2f1df98b0e7cc926cabfa69818674e08 Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
Diffstat (limited to 'src/3rdparty/xkbcommon/src')
-rw-r--r--src/3rdparty/xkbcommon/src/atom.c248
-rw-r--r--src/3rdparty/xkbcommon/src/atom.h52
-rw-r--r--src/3rdparty/xkbcommon/src/context.c492
-rw-r--r--src/3rdparty/xkbcommon/src/context.h124
-rw-r--r--src/3rdparty/xkbcommon/src/darray.h388
-rw-r--r--src/3rdparty/xkbcommon/src/keymap.h451
-rw-r--r--src/3rdparty/xkbcommon/src/keysym-utf.c971
-rw-r--r--src/3rdparty/xkbcommon/src/keysym.c720
-rw-r--r--src/3rdparty/xkbcommon/src/keysym.h62
-rw-r--r--src/3rdparty/xkbcommon/src/ks_tables.h4681
-rw-r--r--src/3rdparty/xkbcommon/src/state.c1144
-rw-r--r--src/3rdparty/xkbcommon/src/text.c357
-rw-r--r--src/3rdparty/xkbcommon/src/text.h78
-rw-r--r--src/3rdparty/xkbcommon/src/utils.h136
-rw-r--r--src/3rdparty/xkbcommon/src/xkb-compat.c189
-rw-r--r--src/3rdparty/xkbcommon/src/xkb-keymap.c555
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/action.c951
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/action.h53
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c793
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h104
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/ast.h295
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/compat.c1078
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/expr.c685
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/expr.h83
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/include.c289
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/include.h42
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c692
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c662
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/keymap.c333
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h47
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/parser.c3674
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/parser.h230
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/rules.c1231
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/rules.h32
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/scanner.c2861
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/symbols.c1638
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/types.c842
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/vmod.c69
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/vmod.h33
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h130
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c171
41 files changed, 27666 insertions, 0 deletions
diff --git a/src/3rdparty/xkbcommon/src/atom.c b/src/3rdparty/xkbcommon/src/atom.c
new file mode 100644
index 0000000000..a77502336e
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/atom.c
@@ -0,0 +1,248 @@
+/***********************************************************
+ * Copyright 1987, 1998 The Open Group
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of The Open Group shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from The Open Group.
+ *
+ *
+ * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Digital not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ ******************************************************************/
+
+/************************************************************
+ * Copyright 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#include "utils.h"
+#include "atom.h"
+
+struct atom_node {
+ struct atom_node *left, *right;
+ xkb_atom_t atom;
+ unsigned int fingerprint;
+ char *string;
+};
+
+struct atom_table {
+ struct atom_node *root;
+ darray(struct atom_node *) table;
+};
+
+struct atom_table *
+atom_table_new(void)
+{
+ struct atom_table *table;
+
+ table = calloc(1, sizeof(*table));
+ if (!table)
+ return NULL;
+
+ darray_init(table->table);
+ darray_growalloc(table->table, 100);
+ darray_append(table->table, NULL);
+
+ return table;
+}
+
+static void
+free_atom(struct atom_node *patom)
+{
+ if (!patom)
+ return;
+
+ free_atom(patom->left);
+ free_atom(patom->right);
+ free(patom->string);
+ free(patom);
+}
+
+void
+atom_table_free(struct atom_table *table)
+{
+ if (!table)
+ return;
+
+ free_atom(table->root);
+ darray_free(table->table);
+ free(table);
+}
+
+const char *
+atom_text(struct atom_table *table, xkb_atom_t atom)
+{
+ if (atom >= darray_size(table->table) ||
+ darray_item(table->table, atom) == NULL)
+ return NULL;
+
+ return darray_item(table->table, atom)->string;
+}
+
+char *
+atom_strdup(struct atom_table *table, xkb_atom_t atom)
+{
+ return strdup_safe(atom_text(table, atom));
+}
+
+static bool
+find_node_pointer(struct atom_table *table, const char *string,
+ struct atom_node ***np_out, unsigned int *fingerprint_out)
+{
+ struct atom_node **np;
+ unsigned i;
+ int comp;
+ unsigned int fp = 0;
+ size_t len;
+ bool found = false;
+
+ len = strlen(string);
+ np = &table->root;
+ for (i = 0; i < (len + 1) / 2; i++) {
+ fp = fp * 27 + string[i];
+ fp = fp * 27 + string[len - 1 - i];
+ }
+
+ while (*np) {
+ if (fp < (*np)->fingerprint) {
+ np = &((*np)->left);
+ }
+ else if (fp > (*np)->fingerprint) {
+ np = &((*np)->right);
+ }
+ else {
+ /* now start testing the strings */
+ comp = strncmp(string, (*np)->string, len);
+ if (comp < 0 || (comp == 0 && len < strlen((*np)->string))) {
+ np = &((*np)->left);
+ }
+ else if (comp > 0) {
+ np = &((*np)->right);
+ }
+ else {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ *fingerprint_out = fp;
+ *np_out = np;
+ return found;
+}
+
+xkb_atom_t
+atom_lookup(struct atom_table *table, const char *string)
+{
+ struct atom_node **np;
+ unsigned int fp;
+
+ if (!string)
+ return XKB_ATOM_NONE;
+
+ if (!find_node_pointer(table, string, &np, &fp))
+ return XKB_ATOM_NONE;
+
+ return (*np)->atom;
+}
+
+/*
+ * If steal is true, we do not strdup @string; therefore it must be
+ * dynamically allocated, not be free'd by the caller and not be used
+ * afterwards. Use to avoid some redundant allocations.
+ */
+xkb_atom_t
+atom_intern(struct atom_table *table, const char *string,
+ bool steal)
+{
+ struct atom_node **np;
+ struct atom_node *nd;
+ unsigned int fp;
+
+ if (!string)
+ return XKB_ATOM_NONE;
+
+ if (find_node_pointer(table, string, &np, &fp)) {
+ if (steal)
+ free(UNCONSTIFY(string));
+ return (*np)->atom;
+ }
+
+ nd = malloc(sizeof(*nd));
+ if (!nd)
+ return XKB_ATOM_NONE;
+
+ if (steal) {
+ nd->string = UNCONSTIFY(string);
+ }
+ else {
+ nd->string = strdup(string);
+ if (!nd->string) {
+ free(nd);
+ return XKB_ATOM_NONE;
+ }
+ }
+
+ *np = nd;
+ nd->left = nd->right = NULL;
+ nd->fingerprint = fp;
+ nd->atom = darray_size(table->table);
+ darray_append(table->table, nd);
+
+ return nd->atom;
+}
diff --git a/src/3rdparty/xkbcommon/src/atom.h b/src/3rdparty/xkbcommon/src/atom.h
new file mode 100644
index 0000000000..f1abf1b72f
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/atom.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2009 Dan Nicholson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef ATOM_H
+#define ATOM_H
+
+typedef uint32_t xkb_atom_t;
+
+#define XKB_ATOM_NONE 0
+
+struct atom_table;
+
+struct atom_table *
+atom_table_new(void);
+
+void
+atom_table_free(struct atom_table *table);
+
+xkb_atom_t
+atom_lookup(struct atom_table *table, const char *string);
+
+xkb_atom_t
+atom_intern(struct atom_table *table, const char *string,
+ bool steal);
+
+char *
+atom_strdup(struct atom_table *table, xkb_atom_t atom);
+
+const char *
+atom_text(struct atom_table *table, xkb_atom_t atom);
+
+#endif /* ATOM_H */
diff --git a/src/3rdparty/xkbcommon/src/context.c b/src/3rdparty/xkbcommon/src/context.c
new file mode 100644
index 0000000000..8d56487004
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/context.c
@@ -0,0 +1,492 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2012 Ran Benita
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "xkbcommon/xkbcommon.h"
+#include "utils.h"
+#include "context.h"
+
+struct xkb_context {
+ int refcnt;
+
+ ATTR_PRINTF(3, 0) void (*log_fn)(struct xkb_context *ctx,
+ enum xkb_log_level level,
+ const char *fmt, va_list args);
+ enum xkb_log_level log_level;
+ int log_verbosity;
+ void *user_data;
+
+ struct xkb_rule_names names_dflt;
+
+ darray(char *) includes;
+ darray(char *) failed_includes;
+
+ struct atom_table *atom_table;
+
+ /* Buffer for the *Text() functions. */
+ char text_buffer[2048];
+ size_t text_next;
+
+ unsigned int use_environment_names : 1;
+};
+
+/**
+ * Append one directory to the context's include path.
+ */
+XKB_EXPORT int
+xkb_context_include_path_append(struct xkb_context *ctx, const char *path)
+{
+ struct stat stat_buf;
+ int err;
+ char *tmp;
+
+ tmp = strdup(path);
+ if (!tmp)
+ goto err;
+
+ err = stat(path, &stat_buf);
+ if (err != 0)
+ goto err;
+ if (!S_ISDIR(stat_buf.st_mode))
+ goto err;
+
+#if defined(HAVE_EACCESS)
+ if (eaccess(path, R_OK | X_OK) != 0)
+ goto err;
+#elif defined(HAVE_EUIDACCESS)
+ if (euidaccess(path, R_OK | X_OK) != 0)
+ goto err;
+#endif
+
+ darray_append(ctx->includes, tmp);
+ return 1;
+
+err:
+ darray_append(ctx->failed_includes, tmp);
+ return 0;
+}
+
+/**
+ * Append the default include directories to the context.
+ */
+XKB_EXPORT int
+xkb_context_include_path_append_default(struct xkb_context *ctx)
+{
+ const char *home;
+ char *user_path;
+ int err;
+ int ret = 0;
+
+ ret |= xkb_context_include_path_append(ctx, DFLT_XKB_CONFIG_ROOT);
+
+ home = getenv("HOME");
+ if (!home)
+ return ret;
+ err = asprintf(&user_path, "%s/.xkb", home);
+ if (err <= 0)
+ return ret;
+ ret |= xkb_context_include_path_append(ctx, user_path);
+ free(user_path);
+
+ return ret;
+}
+
+/**
+ * Remove all entries in the context's include path.
+ */
+XKB_EXPORT void
+xkb_context_include_path_clear(struct xkb_context *ctx)
+{
+ char **path;
+
+ darray_foreach(path, ctx->includes)
+ free(*path);
+ darray_free(ctx->includes);
+
+ darray_foreach(path, ctx->failed_includes)
+ free(*path);
+ darray_free(ctx->failed_includes);
+}
+
+/**
+ * xkb_context_include_path_clear() + xkb_context_include_path_append_default()
+ */
+XKB_EXPORT int
+xkb_context_include_path_reset_defaults(struct xkb_context *ctx)
+{
+ xkb_context_include_path_clear(ctx);
+ return xkb_context_include_path_append_default(ctx);
+}
+
+/**
+ * Returns the number of entries in the context's include path.
+ */
+XKB_EXPORT unsigned int
+xkb_context_num_include_paths(struct xkb_context *ctx)
+{
+ return darray_size(ctx->includes);
+}
+
+unsigned int
+xkb_context_num_failed_include_paths(struct xkb_context *ctx)
+{
+ return darray_size(ctx->failed_includes);
+}
+
+/**
+ * Returns the given entry in the context's include path, or NULL if an
+ * invalid index is passed.
+ */
+XKB_EXPORT const char *
+xkb_context_include_path_get(struct xkb_context *ctx, unsigned int idx)
+{
+ if (idx >= xkb_context_num_include_paths(ctx))
+ return NULL;
+
+ return darray_item(ctx->includes, idx);
+}
+
+const char *
+xkb_context_failed_include_path_get(struct xkb_context *ctx,
+ unsigned int idx)
+{
+ if (idx >= xkb_context_num_failed_include_paths(ctx))
+ return NULL;
+
+ return darray_item(ctx->failed_includes, idx);
+}
+
+/**
+ * Take a new reference on the context.
+ */
+XKB_EXPORT struct xkb_context *
+xkb_context_ref(struct xkb_context *ctx)
+{
+ ctx->refcnt++;
+ return ctx;
+}
+
+/**
+ * Drop an existing reference on the context, and free it if the refcnt is
+ * now 0.
+ */
+XKB_EXPORT void
+xkb_context_unref(struct xkb_context *ctx)
+{
+ if (!ctx || --ctx->refcnt > 0)
+ return;
+
+ xkb_context_include_path_clear(ctx);
+ atom_table_free(ctx->atom_table);
+ free(ctx);
+}
+
+static const char *
+log_level_to_prefix(enum xkb_log_level level)
+{
+ switch (level) {
+ case XKB_LOG_LEVEL_DEBUG:
+ return "Debug:";
+ case XKB_LOG_LEVEL_INFO:
+ return "Info:";
+ case XKB_LOG_LEVEL_WARNING:
+ return "Warning:";
+ case XKB_LOG_LEVEL_ERROR:
+ return "Error:";
+ case XKB_LOG_LEVEL_CRITICAL:
+ return "Critical:";
+ default:
+ return NULL;
+ }
+}
+
+ATTR_PRINTF(3, 0) static void
+default_log_fn(struct xkb_context *ctx, enum xkb_log_level level,
+ const char *fmt, va_list args)
+{
+ const char *prefix = log_level_to_prefix(level);
+
+ if (prefix)
+ fprintf(stderr, "%-10s", prefix);
+ vfprintf(stderr, fmt, args);
+}
+
+static enum xkb_log_level
+log_level(const char *level) {
+ char *endptr;
+ enum xkb_log_level lvl;
+
+ errno = 0;
+ lvl = strtol(level, &endptr, 10);
+ if (errno == 0 && (endptr[0] == '\0' || isspace(endptr[0])))
+ return lvl;
+ if (istreq_prefix("crit", level))
+ return XKB_LOG_LEVEL_CRITICAL;
+ if (istreq_prefix("err", level))
+ return XKB_LOG_LEVEL_ERROR;
+ if (istreq_prefix("warn", level))
+ return XKB_LOG_LEVEL_WARNING;
+ if (istreq_prefix("info", level))
+ return XKB_LOG_LEVEL_INFO;
+ if (istreq_prefix("debug", level) || istreq_prefix("dbg", level))
+ return XKB_LOG_LEVEL_DEBUG;
+
+ return XKB_LOG_LEVEL_ERROR;
+}
+
+static int
+log_verbosity(const char *verbosity) {
+ char *endptr;
+ int v;
+
+ errno = 0;
+ v = strtol(verbosity, &endptr, 10);
+ if (errno == 0)
+ return v;
+
+ return 0;
+}
+
+#ifndef DEFAULT_XKB_VARIANT
+#define DEFAULT_XKB_VARIANT NULL
+#endif
+
+#ifndef DEFAULT_XKB_OPTIONS
+#define DEFAULT_XKB_OPTIONS NULL
+#endif
+
+/**
+ * Create a new context.
+ */
+XKB_EXPORT struct xkb_context *
+xkb_context_new(enum xkb_context_flags flags)
+{
+ const char *env;
+ struct xkb_context *ctx = calloc(1, sizeof(*ctx));
+
+ if (!ctx)
+ return NULL;
+
+ ctx->refcnt = 1;
+ ctx->log_fn = default_log_fn;
+ ctx->log_level = XKB_LOG_LEVEL_ERROR;
+ ctx->log_verbosity = 0;
+
+ /* Environment overwrites defaults. */
+ env = getenv("XKB_LOG_LEVEL");
+ if (env)
+ xkb_context_set_log_level(ctx, log_level(env));
+
+ env = getenv("XKB_LOG_VERBOSITY");
+ if (env)
+ xkb_context_set_log_verbosity(ctx, log_verbosity(env));
+
+ if (!(flags & XKB_CONTEXT_NO_DEFAULT_INCLUDES) &&
+ !xkb_context_include_path_append_default(ctx)) {
+ log_err(ctx, "failed to add default include path %s\n",
+ DFLT_XKB_CONFIG_ROOT);
+ xkb_context_unref(ctx);
+ return NULL;
+ }
+
+ ctx->use_environment_names = !(flags & XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
+
+ ctx->atom_table = atom_table_new();
+ if (!ctx->atom_table) {
+ xkb_context_unref(ctx);
+ return NULL;
+ }
+
+ return ctx;
+}
+
+xkb_atom_t
+xkb_atom_lookup(struct xkb_context *ctx, const char *string)
+{
+ return atom_lookup(ctx->atom_table, string);
+}
+
+xkb_atom_t
+xkb_atom_intern(struct xkb_context *ctx, const char *string)
+{
+ return atom_intern(ctx->atom_table, string, false);
+}
+
+xkb_atom_t
+xkb_atom_steal(struct xkb_context *ctx, char *string)
+{
+ return atom_intern(ctx->atom_table, string, true);
+}
+
+char *
+xkb_atom_strdup(struct xkb_context *ctx, xkb_atom_t atom)
+{
+ return atom_strdup(ctx->atom_table, atom);
+}
+
+const char *
+xkb_atom_text(struct xkb_context *ctx, xkb_atom_t atom)
+{
+ return atom_text(ctx->atom_table, atom);
+}
+
+void
+xkb_log(struct xkb_context *ctx, enum xkb_log_level level,
+ const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ ctx->log_fn(ctx, level, fmt, args);
+ va_end(args);
+}
+
+XKB_EXPORT void
+xkb_context_set_log_fn(struct xkb_context *ctx,
+ void (*log_fn)(struct xkb_context *ctx,
+ enum xkb_log_level level,
+ const char *fmt, va_list args))
+{
+ ctx->log_fn = (log_fn ? log_fn : default_log_fn);
+}
+
+XKB_EXPORT enum xkb_log_level
+xkb_context_get_log_level(struct xkb_context *ctx)
+{
+ return ctx->log_level;
+}
+
+XKB_EXPORT void
+xkb_context_set_log_level(struct xkb_context *ctx, enum xkb_log_level level)
+{
+ ctx->log_level = level;
+}
+
+XKB_EXPORT int
+xkb_context_get_log_verbosity(struct xkb_context *ctx)
+{
+ return ctx->log_verbosity;
+}
+
+XKB_EXPORT void
+xkb_context_set_log_verbosity(struct xkb_context *ctx, int verbosity)
+{
+ ctx->log_verbosity = verbosity;
+}
+
+XKB_EXPORT void *
+xkb_context_get_user_data(struct xkb_context *ctx)
+{
+ if (ctx)
+ return ctx->user_data;
+ return NULL;
+}
+
+XKB_EXPORT void
+xkb_context_set_user_data(struct xkb_context *ctx, void *user_data)
+{
+ ctx->user_data = user_data;
+}
+
+char *
+xkb_context_get_buffer(struct xkb_context *ctx, size_t size)
+{
+ char *rtrn;
+
+ if (size >= sizeof(ctx->text_buffer))
+ return NULL;
+
+ if (sizeof(ctx->text_buffer) - ctx->text_next <= size)
+ ctx->text_next = 0;
+
+ rtrn = &ctx->text_buffer[ctx->text_next];
+ ctx->text_next += size;
+
+ return rtrn;
+}
+
+const char *
+xkb_context_get_default_rules(struct xkb_context *ctx)
+{
+ const char *env = NULL;
+
+ if (ctx->use_environment_names)
+ env = getenv("XKB_DEFAULT_RULES");
+
+ return env ? env : DEFAULT_XKB_RULES;
+}
+
+const char *
+xkb_context_get_default_model(struct xkb_context *ctx)
+{
+ const char *env = NULL;
+
+ if (ctx->use_environment_names)
+ env = getenv("XKB_DEFAULT_MODEL");
+
+ return env ? env : DEFAULT_XKB_MODEL;
+}
+
+const char *
+xkb_context_get_default_layout(struct xkb_context *ctx)
+{
+ const char *env = NULL;
+
+ if (ctx->use_environment_names)
+ env = getenv("XKB_DEFAULT_LAYOUT");
+
+ return env ? env : DEFAULT_XKB_LAYOUT;
+}
+
+const char *
+xkb_context_get_default_variant(struct xkb_context *ctx)
+{
+ const char *env = NULL;
+ const char *layout = getenv("XKB_DEFAULT_VARIANT");
+
+ /* We don't want to inherit the variant if they haven't also set a
+ * layout, since they're so closely paired. */
+ if (layout && ctx->use_environment_names)
+ env = getenv("XKB_DEFAULT_VARIANT");
+
+ return env ? env : DEFAULT_XKB_VARIANT;
+}
+
+const char *
+xkb_context_get_default_options(struct xkb_context *ctx)
+{
+ const char *env = NULL;
+
+ if (ctx->use_environment_names)
+ env = getenv("XKB_DEFAULT_OPTIONS");
+
+ return env ? env : DEFAULT_XKB_OPTIONS;
+}
diff --git a/src/3rdparty/xkbcommon/src/context.h b/src/3rdparty/xkbcommon/src/context.h
new file mode 100644
index 0000000000..7c061a086f
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/context.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ */
+
+#ifndef CONTEXT_H
+#define CONTEXT_H
+
+#include "atom.h"
+
+unsigned int
+xkb_context_num_failed_include_paths(struct xkb_context *ctx);
+
+const char *
+xkb_context_failed_include_path_get(struct xkb_context *ctx,
+ unsigned int idx);
+
+/*
+ * Returns XKB_ATOM_NONE if @string was not previously interned,
+ * otherwise returns the atom.
+ */
+xkb_atom_t
+xkb_atom_lookup(struct xkb_context *ctx, const char *string);
+
+xkb_atom_t
+xkb_atom_intern(struct xkb_context *ctx, const char *string);
+
+/**
+ * If @string is dynamically allocated, free'd immediately after
+ * being interned, and not used afterwards, use this function
+ * instead of xkb_atom_intern to avoid some unnecessary allocations.
+ * The caller should not use or free the passed in string afterwards.
+ */
+xkb_atom_t
+xkb_atom_steal(struct xkb_context *ctx, char *string);
+
+char *
+xkb_atom_strdup(struct xkb_context *ctx, xkb_atom_t atom);
+
+const char *
+xkb_atom_text(struct xkb_context *ctx, xkb_atom_t atom);
+
+char *
+xkb_context_get_buffer(struct xkb_context *ctx, size_t size);
+
+ATTR_PRINTF(3, 4) void
+xkb_log(struct xkb_context *ctx, enum xkb_log_level level,
+ const char *fmt, ...);
+
+#define xkb_log_cond_level(ctx, level, ...) do { \
+ if (xkb_context_get_log_level(ctx) >= (level)) \
+ xkb_log((ctx), (level), __VA_ARGS__); \
+} while (0)
+
+#define xkb_log_cond_verbosity(ctx, level, vrb, ...) do { \
+ if (xkb_context_get_log_verbosity(ctx) >= (vrb)) \
+ xkb_log_cond_level((ctx), (level), __VA_ARGS__); \
+} while (0)
+
+const char *
+xkb_context_get_default_rules(struct xkb_context *ctx);
+
+const char *
+xkb_context_get_default_model(struct xkb_context *ctx);
+
+const char *
+xkb_context_get_default_layout(struct xkb_context *ctx);
+
+const char *
+xkb_context_get_default_variant(struct xkb_context *ctx);
+
+const char *
+xkb_context_get_default_options(struct xkb_context *ctx);
+
+/*
+ * The format is not part of the argument list in order to avoid the
+ * "ISO C99 requires rest arguments to be used" warning when only the
+ * format is supplied without arguments. Not supplying it would still
+ * result in an error, though.
+ */
+#define log_dbg(ctx, ...) \
+ xkb_log_cond_level((ctx), XKB_LOG_LEVEL_DEBUG, __VA_ARGS__)
+#define log_info(ctx, ...) \
+ xkb_log_cond_level((ctx), XKB_LOG_LEVEL_INFO, __VA_ARGS__)
+#define log_warn(ctx, ...) \
+ xkb_log_cond_level((ctx), XKB_LOG_LEVEL_WARNING, __VA_ARGS__)
+#define log_err(ctx, ...) \
+ xkb_log_cond_level((ctx), XKB_LOG_LEVEL_ERROR, __VA_ARGS__)
+#define log_wsgo(ctx, ...) \
+ xkb_log_cond_level((ctx), XKB_LOG_LEVEL_CRITICAL, __VA_ARGS__)
+#define log_vrb(ctx, vrb, ...) \
+ xkb_log_cond_verbosity((ctx), XKB_LOG_LEVEL_WARNING, (vrb), __VA_ARGS__)
+
+/*
+ * Variants which are prefixed by the name of the function they're
+ * called from.
+ * Here we must have the silly 1 variant.
+ */
+#define log_err_func(ctx, fmt, ...) \
+ log_err(ctx, "%s: " fmt, __func__, __VA_ARGS__)
+#define log_err_func1(ctx, fmt) \
+ log_err(ctx, "%s: " fmt, __func__)
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/darray.h b/src/3rdparty/xkbcommon/src/darray.h
new file mode 100644
index 0000000000..0cf3747be7
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/darray.h
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2011 Joseph Adams <joeyadams3.14159@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef CCAN_DARRAY_H
+#define CCAN_DARRAY_H
+
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * SYNOPSIS
+ *
+ * Life cycle of a darray (dynamically-allocated array):
+ *
+ * darray(int) a = darray_new();
+ * darray_free(a);
+ *
+ * struct {darray(int) a;} foo;
+ * darray_init(foo.a);
+ * darray_free(foo.a);
+ *
+ * Typedefs for darrays of common types:
+ *
+ * darray_char, darray_schar, darray_uchar
+ * darray_short, darray_int, darray_long
+ * darray_ushort, darray_uint, darray_ulong
+ *
+ * Access:
+ *
+ * T darray_item(darray(T) arr, size_t index);
+ * size_t darray_size(darray(T) arr);
+ * size_t darray_alloc(darray(T) arr);
+ * bool darray_empty(darray(T) arr);
+ *
+ * // Access raw memory, starting from the item in offset.
+ * // Not safe, be careful, etc.
+ * T* darray_mem(darray(T) arr, size_t offset);
+ *
+ * Insertion (single item):
+ *
+ * void darray_append(darray(T) arr, T item);
+ * void darray_prepend(darray(T) arr, T item);
+ * void darray_push(darray(T) arr, T item); // same as darray_append
+ *
+ * Insertion (multiple items):
+ *
+ * void darray_append_items(darray(T) arr, T *items, size_t count);
+ * void darray_prepend_items(darray(T) arr, T *items, size_t count);
+ *
+ * void darray_appends(darray(T) arr, [T item, [...]]);
+ * void darray_prepends(darray(T) arr, [T item, [...]]);
+ *
+ * Removal:
+ *
+ * T darray_pop(darray(T) arr | darray_size(arr) != 0);
+ * T* darray_pop_check(darray(T*) arr);
+ *
+ * Replacement:
+ *
+ * void darray_from_items(darray(T) arr, T *items, size_t count);
+ * void darray_from_c(darray(T) arr, T c_array[N]);
+ *
+ * String buffer:
+ *
+ * void darray_append_string(darray(char) arr, const char *str);
+ * void darray_append_lit(darray(char) arr, char stringLiteral[N+1]);
+ *
+ * void darray_prepend_string(darray(char) arr, const char *str);
+ * void darray_prepend_lit(darray(char) arr, char stringLiteral[N+1]);
+ *
+ * void darray_from_string(darray(T) arr, const char *str);
+ * void darray_from_lit(darray(char) arr, char stringLiteral[N+1]);
+ *
+ * Size management:
+ *
+ * void darray_resize(darray(T) arr, size_t newSize);
+ * void darray_resize0(darray(T) arr, size_t newSize);
+ *
+ * void darray_realloc(darray(T) arr, size_t newAlloc);
+ * void darray_growalloc(darray(T) arr, size_t newAlloc);
+ *
+ * Traversal:
+ *
+ * darray_foreach(T *&i, darray(T) arr) {...}
+ * darray_foreach_reverse(T *&i, darray(T) arr) {...}
+ *
+ * Except for darray_foreach and darray_foreach_reverse,
+ * all macros evaluate their non-darray arguments only once.
+ */
+
+/*** Life cycle ***/
+
+#define darray(type) struct { type *item; size_t size; size_t alloc; }
+
+#define darray_new() { 0, 0, 0 }
+
+#define darray_init(arr) do { \
+ (arr).item = 0; (arr).size = 0; (arr).alloc = 0; \
+} while (0)
+
+#define darray_free(arr) do { \
+ free((arr).item); darray_init(arr); \
+} while (0)
+
+/*
+ * Typedefs for darrays of common types. These are useful
+ * when you want to pass a pointer to an darray(T) around.
+ *
+ * The following will produce an incompatible pointer warning:
+ *
+ * void foo(darray(int) *arr);
+ * darray(int) arr = darray_new();
+ * foo(&arr);
+ *
+ * The workaround:
+ *
+ * void foo(darray_int *arr);
+ * darray_int arr = darray_new();
+ * foo(&arr);
+ */
+
+typedef darray (char) darray_char;
+typedef darray (signed char) darray_schar;
+typedef darray (unsigned char) darray_uchar;
+
+typedef darray (short) darray_short;
+typedef darray (int) darray_int;
+typedef darray (long) darray_long;
+
+typedef darray (unsigned short) darray_ushort;
+typedef darray (unsigned int) darray_uint;
+typedef darray (unsigned long) darray_ulong;
+
+/*** Access ***/
+
+#define darray_item(arr, i) ((arr).item[i])
+#define darray_size(arr) ((arr).size)
+#define darray_alloc(arr) ((arr).alloc)
+#define darray_empty(arr) ((arr).size == 0)
+
+#define darray_mem(arr, offset) ((arr).item + (offset))
+#define darray_same(arr1, arr2) ((arr1).item == (arr2).item)
+
+/*** Insertion (single item) ***/
+
+#define darray_append(arr, ...) do { \
+ darray_resize(arr, (arr).size + 1); \
+ (arr).item[(arr).size - 1] = (__VA_ARGS__); \
+} while (0)
+
+#define darray_prepend(arr, ...) do { \
+ darray_resize(arr, (arr).size + 1); \
+ memmove((arr).item + 1, (arr).item, \
+ ((arr).size - 1) * sizeof(*(arr).item)); \
+ (arr).item[0] = (__VA_ARGS__); \
+} while (0)
+
+#define darray_push(arr, ...) darray_append(arr, __VA_ARGS__)
+
+/*** Insertion (multiple items) ***/
+
+#define darray_append_items(arr, items, count) do { \
+ size_t __count = (count), __oldSize = (arr).size; \
+ darray_resize(arr, __oldSize + __count); \
+ memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
+} while (0)
+
+#define darray_prepend_items(arr, items, count) do { \
+ size_t __count = (count), __oldSize = (arr).size; \
+ darray_resize(arr, __count + __oldSize); \
+ memmove((arr).item + __count, (arr).item, \
+ __oldSize * sizeof(*(arr).item)); \
+ memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
+} while (0)
+
+#define darray_append_items_nullterminate(arr, items, count) do { \
+ size_t __count = (count), __oldSize = (arr).size; \
+ darray_resize(arr, __oldSize + __count + 1); \
+ memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
+ (arr).item[--(arr).size] = 0; \
+} while (0)
+
+#define darray_prepend_items_nullterminate(arr, items, count) do { \
+ size_t __count = (count), __oldSize = (arr).size; \
+ darray_resize(arr, __count + __oldSize + 1); \
+ memmove((arr).item + __count, (arr).item, \
+ __oldSize * sizeof(*(arr).item)); \
+ memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
+ (arr).item[--(arr).size] = 0; \
+} while (0)
+
+#define darray_appends_t(arr, type, ...) do { \
+ type __src[] = { __VA_ARGS__ }; \
+ darray_append_items(arr, __src, sizeof(__src) / sizeof(*__src)); \
+} while (0)
+
+#define darray_prepends_t(arr, type, ...) do { \
+ type __src[] = { __VA_ARGS__ }; \
+ darray_prepend_items(arr, __src, sizeof(__src) / sizeof(*__src)); \
+} while (0)
+
+/*** Removal ***/
+
+/* Warning: Do not call darray_pop on an empty darray. */
+#define darray_pop(arr) ((arr).item[--(arr).size])
+#define darray_pop_check(arr) ((arr).size ? darray_pop(arr) : NULL)
+
+/*** Replacement ***/
+
+#define darray_from_items(arr, items, count) do { \
+ size_t __count = (count); \
+ darray_resize(arr, __count); \
+ memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
+} while (0)
+
+#define darray_from_c(arr, c_array) \
+ darray_from_items(arr, c_array, sizeof(c_array) / sizeof(*(c_array)))
+
+#define darray_copy(arr_to, arr_from) \
+ darray_from_items((arr_to), (arr_from).item, (arr_from).size)
+
+/*** String buffer ***/
+
+#define darray_append_string(arr, str) do { \
+ const char *__str = (str); \
+ darray_append_items(arr, __str, strlen(__str) + 1); \
+ (arr).size--; \
+} while (0)
+
+#define darray_append_lit(arr, stringLiteral) do { \
+ darray_append_items(arr, stringLiteral, sizeof(stringLiteral)); \
+ (arr).size--; \
+} while (0)
+
+#define darray_prepend_string(arr, str) do { \
+ const char *__str = (str); \
+ darray_prepend_items_nullterminate(arr, __str, strlen(__str)); \
+} while (0)
+
+#define darray_prepend_lit(arr, stringLiteral) \
+ darray_prepend_items_nullterminate(arr, stringLiteral, \
+ sizeof(stringLiteral) - 1)
+
+#define darray_from_string(arr, str) do { \
+ const char *__str = (str); \
+ darray_from_items(arr, __str, strlen(__str) + 1); \
+ (arr).size--; \
+} while (0)
+
+#define darray_from_lit(arr, stringLiteral) do { \
+ darray_from_items(arr, stringLiteral, sizeof(stringLiteral)); \
+ (arr).size--; \
+} while (0)
+
+/*** Size management ***/
+
+#define darray_resize(arr, newSize) \
+ darray_growalloc(arr, (arr).size = (newSize))
+
+#define darray_resize0(arr, newSize) do { \
+ size_t __oldSize = (arr).size, __newSize = (newSize); \
+ (arr).size = __newSize; \
+ if (__newSize > __oldSize) { \
+ darray_growalloc(arr, __newSize); \
+ memset(&(arr).item[__oldSize], 0, \
+ (__newSize - __oldSize) * sizeof(*(arr).item)); \
+ } \
+} while (0)
+
+#define darray_realloc(arr, newAlloc) do { \
+ (arr).item = realloc((arr).item, \
+ ((arr).alloc = (newAlloc)) * sizeof(*(arr).item)); \
+} while (0)
+
+#define darray_growalloc(arr, need) do { \
+ size_t __need = (need); \
+ if (__need > (arr).alloc) \
+ darray_realloc(arr, darray_next_alloc((arr).alloc, __need)); \
+} while (0)
+
+static inline size_t
+darray_next_alloc(size_t alloc, size_t need)
+{
+ if (alloc == 0)
+ alloc = 4;
+ while (alloc < need)
+ alloc *= 2;
+ return alloc;
+}
+
+/*** Traversal ***/
+
+/*
+ * darray_foreach(T *&i, darray(T) arr) {...}
+ *
+ * Traverse a darray. `i` must be declared in advance as a pointer to an item.
+ */
+#define darray_foreach(i, arr) \
+ for ((i) = &(arr).item[0]; (i) < &(arr).item[(arr).size]; (i)++)
+
+#define darray_foreach_from(i, arr, from) \
+ for ((i) = &(arr).item[from]; (i) < &(arr).item[(arr).size]; (i)++)
+
+/* Iterate on index and value at the same time, like Python's enumerate. */
+#define darray_enumerate(idx, val, arr) \
+ for ((idx) = 0, (val) = &(arr).item[0]; \
+ (idx) < (arr).size; \
+ (idx)++, (val)++)
+
+#define darray_enumerate_from(idx, val, arr, from) \
+ for ((idx) = (from), (val) = &(arr).item[0]; \
+ (idx) < (arr).size; \
+ (idx)++, (val)++)
+
+/*
+ * darray_foreach_reverse(T *&i, darray(T) arr) {...}
+ *
+ * Like darray_foreach, but traverse in reverse order.
+ */
+#define darray_foreach_reverse(i, arr) \
+ for ((i) = &(arr).item[(arr).size]; (i)-- > &(arr).item[0]; )
+
+#endif /* CCAN_DARRAY_H */
+
+/*
+ *
+ * darray_growalloc(arr, newAlloc) sees if the darray can currently hold newAlloc items;
+ * if not, it increases the alloc to satisfy this requirement, allocating slack
+ * space to avoid having to reallocate for every size increment.
+ *
+ * darray_from_string(arr, str) copies a string to an darray_char.
+ *
+ * darray_push(arr, item) pushes an item to the end of the darray.
+ * darray_pop(arr) pops it back out. Be sure there is at least one item in the darray before calling.
+ * darray_pop_check(arr) does the same as darray_pop, but returns NULL if there are no more items left in the darray.
+ *
+ * darray_make_room(arr, room) ensures there's 'room' elements of space after the end of the darray, and it returns a pointer to this space.
+ * Currently requires HAVE_STATEMENT_EXPR, but I plan to remove this dependency by creating an inline function.
+ *
+ * The following require HAVE_TYPEOF==1 :
+ *
+ * darray_appends(arr, item0, item1...) appends a collection of comma-delimited items to the darray.
+ * darray_prepends(arr, item0, item1...) prepends a collection of comma-delimited items to the darray.\
+ *
+ *
+ * Examples:
+ *
+ * darray(int) arr;
+ * int *i;
+ *
+ * darray_appends(arr, 0,1,2,3,4);
+ * darray_appends(arr, -5,-4,-3,-2,-1);
+ * darray_foreach(i, arr)
+ * printf("%d ", *i);
+ * printf("\n");
+ *
+ * darray_free(arr);
+ *
+ *
+ * typedef struct {int n,d;} Fraction;
+ * darray(Fraction) fractions;
+ * Fraction *i;
+ *
+ * darray_appends(fractions, {3,4}, {3,5}, {2,1});
+ * darray_foreach(i, fractions)
+ * printf("%d/%d\n", i->n, i->d);
+ *
+ * darray_free(fractions);
+ */
diff --git a/src/3rdparty/xkbcommon/src/keymap.h b/src/3rdparty/xkbcommon/src/keymap.h
new file mode 100644
index 0000000000..c6b884d6bc
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/keymap.h
@@ -0,0 +1,451 @@
+/*
+ * Copyright 1985, 1987, 1990, 1998 The Open Group
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the authors or their
+ * institutions shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization from the authors.
+ */
+
+/************************************************************
+ * Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+/*
+ * Copyright © 2009 Dan Nicholson
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2012 Ran Benita
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ * Dan Nicholson <dbn.lists@gmail.com>
+ */
+
+#ifndef KEYMAP_H
+#define KEYMAP_H
+
+ /* Don't use compat names in internal code. */
+#define _XKBCOMMON_COMPAT_H
+#include "xkbcommon/xkbcommon.h"
+
+#include "utils.h"
+#include "context.h"
+
+/* This limit is artificially enforced, we do not depend on it any where.
+ * The reason it's still here is that the rules file format does not
+ * support multiple groups very well, and the rules shipped with
+ * xkeyboard-config (see rules/evdev) depend on this limit extensively.
+ * So just lifting this limit would cause problems for people who will use
+ * more than 4 layouts.
+ * TODO: Fix the group index syntax in the rules format, preferably in a
+ * backwards compatible way.
+ * See e.g. https://bugs.freedesktop.org/show_bug.cgi?id=14372
+ * Note: A limit on the number of groups we *do* depend on is imposed by
+ * the size of the xkb_layout_mask_t type (32). This is more than enough
+ * though.
+ */
+#define XKB_MAX_GROUPS 4
+
+/* Don't allow more modifiers than we can hold in xkb_mod_mask_t. */
+#define XKB_MAX_MODS ((xkb_mod_index_t) (sizeof(xkb_mod_mask_t) * 8))
+
+/* Don't allow more leds than we can hold in xkb_led_mask_t. */
+#define XKB_MAX_LEDS ((xkb_led_index_t) (sizeof(xkb_led_mask_t) * 8))
+
+/* These should all go away. */
+enum mod_type {
+ MOD_REAL = (1 << 0),
+ MOD_VIRT = (1 << 1),
+ MOD_BOTH = (MOD_REAL | MOD_VIRT),
+};
+#define MOD_REAL_MASK_ALL ((xkb_mod_mask_t) 0x000000ff)
+
+enum xkb_action_type {
+ ACTION_TYPE_NONE = 0,
+ ACTION_TYPE_MOD_SET,
+ ACTION_TYPE_MOD_LATCH,
+ ACTION_TYPE_MOD_LOCK,
+ ACTION_TYPE_GROUP_SET,
+ ACTION_TYPE_GROUP_LATCH,
+ ACTION_TYPE_GROUP_LOCK,
+ ACTION_TYPE_PTR_MOVE,
+ ACTION_TYPE_PTR_BUTTON,
+ ACTION_TYPE_PTR_LOCK,
+ ACTION_TYPE_PTR_DEFAULT,
+ ACTION_TYPE_TERMINATE,
+ ACTION_TYPE_SWITCH_VT,
+ ACTION_TYPE_CTRL_SET,
+ ACTION_TYPE_CTRL_LOCK,
+ ACTION_TYPE_KEY_REDIRECT,
+ ACTION_TYPE_PRIVATE,
+ _ACTION_TYPE_NUM_ENTRIES
+};
+
+enum xkb_action_flags {
+ ACTION_LOCK_CLEAR = (1 << 0),
+ ACTION_LATCH_TO_LOCK = (1 << 1),
+ ACTION_LOCK_NO_LOCK = (1 << 2),
+ ACTION_LOCK_NO_UNLOCK = (1 << 3),
+ ACTION_MODS_LOOKUP_MODMAP = (1 << 4),
+ ACTION_ABSOLUTE_SWITCH = (1 << 5),
+ ACTION_ABSOLUTE_X = (1 << 6),
+ ACTION_ABSOLUTE_Y = (1 << 7),
+ ACTION_NO_ACCEL = (1 << 8),
+ ACTION_SAME_SCREEN = (1 << 9),
+};
+
+enum xkb_action_controls {
+ CONTROL_REPEAT = (1 << 0),
+ CONTROL_SLOW = (1 << 1),
+ CONTROL_DEBOUNCE = (1 << 2),
+ CONTROL_STICKY = (1 << 3),
+ CONTROL_MOUSEKEYS = (1 << 4),
+ CONTROL_MOUSEKEYS_ACCEL = (1 << 5),
+ CONTROL_AX = (1 << 6),
+ CONTROL_AX_TIMEOUT = (1 << 7),
+ CONTROL_AX_FEEDBACK = (1 << 8),
+ CONTROL_BELL = (1 << 9),
+ CONTROL_IGNORE_GROUP_LOCK = (1 << 10),
+ CONTROL_ALL = \
+ (CONTROL_REPEAT | CONTROL_SLOW | CONTROL_DEBOUNCE | CONTROL_STICKY | \
+ CONTROL_MOUSEKEYS | CONTROL_MOUSEKEYS_ACCEL | CONTROL_AX | \
+ CONTROL_AX_TIMEOUT | CONTROL_AX_FEEDBACK | CONTROL_BELL | \
+ CONTROL_IGNORE_GROUP_LOCK)
+};
+
+enum xkb_match_operation {
+ MATCH_NONE,
+ MATCH_ANY_OR_NONE,
+ MATCH_ANY,
+ MATCH_ALL,
+ MATCH_EXACTLY,
+};
+
+struct xkb_mods {
+ xkb_mod_mask_t mods; /* original real+virtual mods in definition */
+ xkb_mod_mask_t mask; /* computed effective mask */
+};
+
+struct xkb_mod_action {
+ enum xkb_action_type type;
+ enum xkb_action_flags flags;
+ struct xkb_mods mods;
+};
+
+struct xkb_group_action {
+ enum xkb_action_type type;
+ enum xkb_action_flags flags;
+ int32_t group;
+};
+
+struct xkb_controls_action {
+ enum xkb_action_type type;
+ enum xkb_action_flags flags;
+ enum xkb_action_controls ctrls;
+};
+
+struct xkb_pointer_default_action {
+ enum xkb_action_type type;
+ enum xkb_action_flags flags;
+ int8_t value;
+};
+
+struct xkb_switch_screen_action {
+ enum xkb_action_type type;
+ enum xkb_action_flags flags;
+ int8_t screen;
+};
+
+struct xkb_redirect_key_action {
+ enum xkb_action_type type;
+ enum xkb_action_flags flags;
+ xkb_keycode_t new_kc;
+ uint8_t mods_mask;
+ uint8_t mods;
+ uint16_t vmods_mask;
+ uint16_t vmods;
+};
+
+struct xkb_pointer_action {
+ enum xkb_action_type type;
+ enum xkb_action_flags flags;
+ int16_t x;
+ int16_t y;
+};
+
+struct xkb_pointer_button_action {
+ enum xkb_action_type type;
+ enum xkb_action_flags flags;
+ uint8_t count;
+ int8_t button;
+};
+
+struct xkb_private_action {
+ enum xkb_action_type type;
+ enum xkb_action_flags flags;
+ uint8_t data[7];
+};
+
+union xkb_action {
+ enum xkb_action_type type;
+ struct xkb_mod_action mods;
+ struct xkb_group_action group;
+ struct xkb_controls_action ctrls;
+ struct xkb_pointer_default_action dflt;
+ struct xkb_switch_screen_action screen;
+ struct xkb_redirect_key_action redirect; /* XXX wholly unnecessary? */
+ struct xkb_pointer_action ptr;
+ struct xkb_pointer_button_action btn;
+ struct xkb_private_action priv;
+};
+
+struct xkb_key_type_entry {
+ xkb_level_index_t level;
+ struct xkb_mods mods;
+ struct xkb_mods preserve;
+};
+
+struct xkb_key_type {
+ xkb_atom_t name;
+ struct xkb_mods mods;
+ xkb_level_index_t num_levels;
+ xkb_atom_t *level_names;
+ unsigned int num_entries;
+ struct xkb_key_type_entry *entries;
+};
+
+struct xkb_sym_interpret {
+ xkb_keysym_t sym;
+ enum xkb_match_operation match;
+ bool level_one_only;
+ xkb_mod_mask_t mods;
+ xkb_mod_index_t virtual_mod;
+ union xkb_action action;
+ bool repeat;
+};
+
+struct xkb_led {
+ xkb_atom_t name;
+ enum xkb_state_component which_groups;
+ xkb_layout_mask_t groups;
+ enum xkb_state_component which_mods;
+ struct xkb_mods mods;
+ enum xkb_action_controls ctrls;
+};
+
+struct xkb_key_alias {
+ xkb_atom_t real;
+ xkb_atom_t alias;
+};
+
+struct xkb_controls {
+ unsigned char groups_wrap;
+ struct xkb_mods internal;
+ struct xkb_mods ignore_lock;
+ unsigned short repeat_delay;
+ unsigned short repeat_interval;
+ unsigned short slow_keys_delay;
+ unsigned short debounce_delay;
+ unsigned short ax_options;
+ unsigned short ax_timeout;
+ unsigned short axt_opts_mask;
+ unsigned short axt_opts_values;
+ unsigned int axt_ctrls_mask;
+ unsigned int axt_ctrls_values;
+};
+
+/* Such an awkward name. Oh well. */
+enum xkb_range_exceed_type {
+ RANGE_SATURATE,
+ RANGE_WRAP,
+ RANGE_REDIRECT,
+};
+
+enum xkb_explicit_components {
+ EXPLICIT_INTERP = (1 << 0),
+ EXPLICIT_VMODMAP = (1 << 1),
+ EXPLICIT_REPEAT = (1 << 2),
+};
+
+struct xkb_level {
+ union xkb_action action;
+ unsigned int num_syms;
+ union {
+ xkb_keysym_t sym; /* num_syms == 1 */
+ xkb_keysym_t *syms; /* num_syms > 1 */
+ } u;
+};
+
+struct xkb_group {
+ bool explicit_type;
+ /* Points to a type in keymap->types. */
+ const struct xkb_key_type *type;
+ /* Use XkbKeyGroupWidth for the number of levels. */
+ struct xkb_level *levels;
+};
+
+struct xkb_key {
+ xkb_keycode_t keycode;
+ xkb_atom_t name;
+
+ enum xkb_explicit_components explicit;
+
+ xkb_mod_mask_t modmap;
+ xkb_mod_mask_t vmodmap;
+
+ bool repeats;
+
+ enum xkb_range_exceed_type out_of_range_group_action;
+ xkb_layout_index_t out_of_range_group_number;
+
+ xkb_layout_index_t num_groups;
+ struct xkb_group *groups;
+};
+
+struct xkb_mod {
+ xkb_atom_t name;
+ enum mod_type type;
+ xkb_mod_mask_t mapping; /* vmod -> real mod mapping */
+};
+
+/* Common keyboard description structure */
+struct xkb_keymap {
+ struct xkb_context *ctx;
+
+ int refcnt;
+ enum xkb_keymap_compile_flags flags;
+ enum xkb_keymap_format format;
+
+ enum xkb_action_controls enabled_ctrls;
+
+ xkb_keycode_t min_key_code;
+ xkb_keycode_t max_key_code;
+ struct xkb_key *keys;
+
+ /* aliases in no particular order */
+ unsigned int num_key_aliases;
+ struct xkb_key_alias *key_aliases;
+
+ struct xkb_key_type *types;
+ unsigned int num_types;
+
+ darray(struct xkb_sym_interpret) sym_interprets;
+
+ darray(struct xkb_mod) mods;
+
+ /* Number of groups in the key with the most groups. */
+ xkb_layout_index_t num_groups;
+ /* Not all groups must have names. */
+ xkb_layout_index_t num_group_names;
+ xkb_atom_t *group_names;
+
+ darray(struct xkb_led) leds;
+
+ char *keycodes_section_name;
+ char *symbols_section_name;
+ char *types_section_name;
+ char *compat_section_name;
+};
+
+#define xkb_foreach_key(iter, keymap) \
+ for (iter = keymap->keys + keymap->min_key_code; \
+ iter <= keymap->keys + keymap->max_key_code; \
+ iter++)
+
+static inline const struct xkb_key *
+XkbKey(struct xkb_keymap *keymap, xkb_keycode_t kc)
+{
+ if (kc < keymap->min_key_code || kc > keymap->max_key_code)
+ return NULL;
+ return &keymap->keys[kc];
+}
+
+static inline xkb_level_index_t
+XkbKeyGroupWidth(const struct xkb_key *key, xkb_layout_index_t layout)
+{
+ return key->groups[layout].type->num_levels;
+}
+
+struct xkb_key *
+XkbKeyByName(struct xkb_keymap *keymap, xkb_atom_t name, bool use_aliases);
+
+xkb_atom_t
+XkbResolveKeyAlias(struct xkb_keymap *keymap, xkb_atom_t name);
+
+xkb_layout_index_t
+wrap_group_into_range(int32_t group,
+ xkb_layout_index_t num_groups,
+ enum xkb_range_exceed_type out_of_range_group_action,
+ xkb_layout_index_t out_of_range_group_number);
+
+struct xkb_keymap_format_ops {
+ bool (*keymap_new_from_names)(struct xkb_keymap *keymap,
+ const struct xkb_rule_names *names);
+ bool (*keymap_new_from_string)(struct xkb_keymap *keymap,
+ const char *string);
+ bool (*keymap_new_from_buffer)(struct xkb_keymap *keymap,
+ const char *buffer, size_t length);
+ bool (*keymap_new_from_file)(struct xkb_keymap *keymap, FILE *file);
+ char *(*keymap_get_as_string)(struct xkb_keymap *keymap);
+};
+
+extern const struct xkb_keymap_format_ops text_v1_keymap_format_ops;
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/keysym-utf.c b/src/3rdparty/xkbcommon/src/keysym-utf.c
new file mode 100644
index 0000000000..5484a8311d
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/keysym-utf.c
@@ -0,0 +1,971 @@
+/* The table and comments below along with the function xkb_keysym_to_ucs4
+ * are under the public domain and are derived as described below.
+ */
+/* This module converts keysym values into the corresponding ISO 10646
+ * (UCS, Unicode) values.
+ *
+ * The array keysymtab[] contains pairs of X11 keysym values for graphical
+ * characters and the corresponding Unicode value. The function
+ * keysym2ucs() maps a keysym onto a Unicode value using a binary search,
+ * therefore keysymtab[] must remain SORTED by keysym value.
+ *
+ * The keysym -> UTF-8 conversion will hopefully one day be provided
+ * by Xlib via XmbLookupString() and should ideally not have to be
+ * done in X applications. But we are not there yet.
+ *
+ * We allow to represent any UCS character in the range U-00000000 to
+ * U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff.
+ * This admittedly does not cover the entire 31-bit space of UCS, but
+ * it does cover all of the characters up to U-10FFFF, which can be
+ * represented by UTF-16, and more, and it is very unlikely that higher
+ * UCS codes will ever be assigned by ISO. So to get Unicode character
+ * U+ABCD you can directly use keysym 0x0100abcd.
+ *
+ * NOTE: The comments in the table below contain the actual character
+ * encoded in UTF-8, so for viewing and editing best use an editor in
+ * UTF-8 mode.
+ *
+ * Author: Markus G. Kuhn <http://www.cl.cam.ac.uk/~mgk25/>,
+ * University of Cambridge, April 2001
+ *
+ * Special thanks to Richard Verhoeven <river@win.tue.nl> for preparing
+ * an initial draft of the mapping table.
+ *
+ * This software is in the public domain. Share and enjoy!
+ *
+ */
+
+#include "xkbcommon/xkbcommon.h"
+#include "utils.h"
+
+/* We don't use the uint32_t types here, to save some space. */
+struct codepair {
+ uint16_t keysym;
+ uint16_t ucs;
+};
+
+static const struct codepair keysymtab[] = {
+ { 0x01a1, 0x0104 }, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */
+ { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */
+ { 0x01a3, 0x0141 }, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */
+ { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */
+ { 0x01a6, 0x015a }, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */
+ { 0x01a9, 0x0160 }, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */
+ { 0x01aa, 0x015e }, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */
+ { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */
+ { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */
+ { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */
+ { 0x01af, 0x017b }, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */
+ { 0x01b1, 0x0105 }, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */
+ { 0x01b2, 0x02db }, /* ogonek ˛ OGONEK */
+ { 0x01b3, 0x0142 }, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */
+ { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */
+ { 0x01b6, 0x015b }, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */
+ { 0x01b7, 0x02c7 }, /* caron ˇ CARON */
+ { 0x01b9, 0x0161 }, /* scaron š LATIN SMALL LETTER S WITH CARON */
+ { 0x01ba, 0x015f }, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */
+ { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */
+ { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */
+ { 0x01bd, 0x02dd }, /* doubleacute ˝ DOUBLE ACUTE ACCENT */
+ { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */
+ { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */
+ { 0x01c0, 0x0154 }, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */
+ { 0x01c3, 0x0102 }, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */
+ { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */
+ { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */
+ { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */
+ { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */
+ { 0x01cc, 0x011a }, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */
+ { 0x01cf, 0x010e }, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */
+ { 0x01d0, 0x0110 }, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */
+ { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */
+ { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */
+ { 0x01d5, 0x0150 }, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
+ { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */
+ { 0x01d9, 0x016e }, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */
+ { 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
+ { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */
+ { 0x01e0, 0x0155 }, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */
+ { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */
+ { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */
+ { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */
+ { 0x01e8, 0x010d }, /* ccaron č LATIN SMALL LETTER C WITH CARON */
+ { 0x01ea, 0x0119 }, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */
+ { 0x01ec, 0x011b }, /* ecaron ě LATIN SMALL LETTER E WITH CARON */
+ { 0x01ef, 0x010f }, /* dcaron ď LATIN SMALL LETTER D WITH CARON */
+ { 0x01f0, 0x0111 }, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */
+ { 0x01f1, 0x0144 }, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */
+ { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */
+ { 0x01f5, 0x0151 }, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */
+ { 0x01f8, 0x0159 }, /* rcaron ř LATIN SMALL LETTER R WITH CARON */
+ { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */
+ { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */
+ { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */
+ { 0x01ff, 0x02d9 }, /* abovedot ˙ DOT ABOVE */
+ { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */
+ { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
+ { 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */
+ { 0x02ab, 0x011e }, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */
+ { 0x02ac, 0x0134 }, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
+ { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */
+ { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */
+ { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */
+ { 0x02bb, 0x011f }, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */
+ { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */
+ { 0x02c5, 0x010a }, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */
+ { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
+ { 0x02d5, 0x0120 }, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */
+ { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
+ { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */
+ { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
+ { 0x02e5, 0x010b }, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */
+ { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */
+ { 0x02f5, 0x0121 }, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */
+ { 0x02f8, 0x011d }, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */
+ { 0x02fd, 0x016d }, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */
+ { 0x02fe, 0x015d }, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */
+ { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */
+ { 0x03a3, 0x0156 }, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */
+ { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */
+ { 0x03a6, 0x013b }, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */
+ { 0x03aa, 0x0112 }, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */
+ { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */
+ { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */
+ { 0x03b3, 0x0157 }, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */
+ { 0x03b5, 0x0129 }, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */
+ { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */
+ { 0x03ba, 0x0113 }, /* emacron ē LATIN SMALL LETTER E WITH MACRON */
+ { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */
+ { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */
+ { 0x03bd, 0x014a }, /* ENG Ŋ LATIN CAPITAL LETTER ENG */
+ { 0x03bf, 0x014b }, /* eng ŋ LATIN SMALL LETTER ENG */
+ { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */
+ { 0x03c7, 0x012e }, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */
+ { 0x03cc, 0x0116 }, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */
+ { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */
+ { 0x03d1, 0x0145 }, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */
+ { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */
+ { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */
+ { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */
+ { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */
+ { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */
+ { 0x03e0, 0x0101 }, /* amacron ā LATIN SMALL LETTER A WITH MACRON */
+ { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */
+ { 0x03ec, 0x0117 }, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */
+ { 0x03ef, 0x012b }, /* imacron ī LATIN SMALL LETTER I WITH MACRON */
+ { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */
+ { 0x03f2, 0x014d }, /* omacron ō LATIN SMALL LETTER O WITH MACRON */
+ { 0x03f3, 0x0137 }, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */
+ { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */
+ { 0x03fd, 0x0169 }, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */
+ { 0x03fe, 0x016b }, /* umacron ū LATIN SMALL LETTER U WITH MACRON */
+ { 0x047e, 0x203e }, /* overline ‾ OVERLINE */
+ { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */
+ { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */
+ { 0x04a3, 0x300d }, /* kana_closingbracket 」 RIGHT CORNER BRACKET */
+ { 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */
+ { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */
+ { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */
+ { 0x04a7, 0x30a1 }, /* kana_a ァ KATAKANA LETTER SMALL A */
+ { 0x04a8, 0x30a3 }, /* kana_i ィ KATAKANA LETTER SMALL I */
+ { 0x04a9, 0x30a5 }, /* kana_u ゥ KATAKANA LETTER SMALL U */
+ { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */
+ { 0x04ab, 0x30a9 }, /* kana_o ォ KATAKANA LETTER SMALL O */
+ { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */
+ { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */
+ { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */
+ { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */
+ { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */
+ { 0x04b1, 0x30a2 }, /* kana_A ア KATAKANA LETTER A */
+ { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */
+ { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */
+ { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */
+ { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */
+ { 0x04b6, 0x30ab }, /* kana_KA カ KATAKANA LETTER KA */
+ { 0x04b7, 0x30ad }, /* kana_KI キ KATAKANA LETTER KI */
+ { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */
+ { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */
+ { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */
+ { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */
+ { 0x04bc, 0x30b7 }, /* kana_SHI シ KATAKANA LETTER SI */
+ { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */
+ { 0x04be, 0x30bb }, /* kana_SE セ KATAKANA LETTER SE */
+ { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */
+ { 0x04c0, 0x30bf }, /* kana_TA タ KATAKANA LETTER TA */
+ { 0x04c1, 0x30c1 }, /* kana_CHI チ KATAKANA LETTER TI */
+ { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */
+ { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */
+ { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */
+ { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */
+ { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */
+ { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */
+ { 0x04c8, 0x30cd }, /* kana_NE ネ KATAKANA LETTER NE */
+ { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */
+ { 0x04ca, 0x30cf }, /* kana_HA ハ KATAKANA LETTER HA */
+ { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */
+ { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */
+ { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */
+ { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */
+ { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */
+ { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */
+ { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */
+ { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */
+ { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */
+ { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */
+ { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */
+ { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */
+ { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */
+ { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */
+ { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */
+ { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */
+ { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */
+ { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */
+ { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */
+ { 0x04de, 0x309b }, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */
+ { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
+ { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */
+ { 0x05bb, 0x061b }, /* Arabic_semicolon ؛ ARABIC SEMICOLON */
+ { 0x05bf, 0x061f }, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */
+ { 0x05c1, 0x0621 }, /* Arabic_hamza ء ARABIC LETTER HAMZA */
+ { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */
+ { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */
+ { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */
+ { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */
+ { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */
+ { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */
+ { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */
+ { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */
+ { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */
+ { 0x05cb, 0x062b }, /* Arabic_theh ث ARABIC LETTER THEH */
+ { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */
+ { 0x05cd, 0x062d }, /* Arabic_hah ح ARABIC LETTER HAH */
+ { 0x05ce, 0x062e }, /* Arabic_khah خ ARABIC LETTER KHAH */
+ { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */
+ { 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */
+ { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */
+ { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */
+ { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */
+ { 0x05d4, 0x0634 }, /* Arabic_sheen ش ARABIC LETTER SHEEN */
+ { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */
+ { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */
+ { 0x05d7, 0x0637 }, /* Arabic_tah ط ARABIC LETTER TAH */
+ { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */
+ { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */
+ { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */
+ { 0x05e0, 0x0640 }, /* Arabic_tatweel ـ ARABIC TATWEEL */
+ { 0x05e1, 0x0641 }, /* Arabic_feh ف ARABIC LETTER FEH */
+ { 0x05e2, 0x0642 }, /* Arabic_qaf ق ARABIC LETTER QAF */
+ { 0x05e3, 0x0643 }, /* Arabic_kaf ك ARABIC LETTER KAF */
+ { 0x05e4, 0x0644 }, /* Arabic_lam ل ARABIC LETTER LAM */
+ { 0x05e5, 0x0645 }, /* Arabic_meem م ARABIC LETTER MEEM */
+ { 0x05e6, 0x0646 }, /* Arabic_noon ن ARABIC LETTER NOON */
+ { 0x05e7, 0x0647 }, /* Arabic_ha ه ARABIC LETTER HEH */
+ { 0x05e8, 0x0648 }, /* Arabic_waw و ARABIC LETTER WAW */
+ { 0x05e9, 0x0649 }, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */
+ { 0x05ea, 0x064a }, /* Arabic_yeh ي ARABIC LETTER YEH */
+ { 0x05eb, 0x064b }, /* Arabic_fathatan ً ARABIC FATHATAN */
+ { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */
+ { 0x05ed, 0x064d }, /* Arabic_kasratan ٍ ARABIC KASRATAN */
+ { 0x05ee, 0x064e }, /* Arabic_fatha َ ARABIC FATHA */
+ { 0x05ef, 0x064f }, /* Arabic_damma ُ ARABIC DAMMA */
+ { 0x05f0, 0x0650 }, /* Arabic_kasra ِ ARABIC KASRA */
+ { 0x05f1, 0x0651 }, /* Arabic_shadda ّ ARABIC SHADDA */
+ { 0x05f2, 0x0652 }, /* Arabic_sukun ْ ARABIC SUKUN */
+ { 0x06a1, 0x0452 }, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */
+ { 0x06a2, 0x0453 }, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */
+ { 0x06a3, 0x0451 }, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */
+ { 0x06a4, 0x0454 }, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */
+ { 0x06a5, 0x0455 }, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */
+ { 0x06a6, 0x0456 }, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
+ { 0x06a7, 0x0457 }, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */
+ { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */
+ { 0x06a9, 0x0459 }, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */
+ { 0x06aa, 0x045a }, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */
+ { 0x06ab, 0x045b }, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */
+ { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */
+ { 0x06ad, 0x0491 }, /* Ukrainian_ghe_with_upturn ґ CYRILLIC SMALL LETTER GHE WITH UPTURN */
+ { 0x06ae, 0x045e }, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */
+ { 0x06af, 0x045f }, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */
+ { 0x06b0, 0x2116 }, /* numerosign № NUMERO SIGN */
+ { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */
+ { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */
+ { 0x06b3, 0x0401 }, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */
+ { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */
+ { 0x06b5, 0x0405 }, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */
+ { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
+ { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */
+ { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */
+ { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */
+ { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */
+ { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */
+ { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */
+ { 0x06bd, 0x0490 }, /* Ukrainian_GHE_WITH_UPTURN Ґ CYRILLIC CAPITAL LETTER GHE WITH UPTURN */
+ { 0x06be, 0x040e }, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */
+ { 0x06bf, 0x040f }, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */
+ { 0x06c0, 0x044e }, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */
+ { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */
+ { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */
+ { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */
+ { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */
+ { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */
+ { 0x06c6, 0x0444 }, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */
+ { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */
+ { 0x06c8, 0x0445 }, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */
+ { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */
+ { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */
+ { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */
+ { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */
+ { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */
+ { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */
+ { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */
+ { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */
+ { 0x06d1, 0x044f }, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */
+ { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */
+ { 0x06d3, 0x0441 }, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */
+ { 0x06d4, 0x0442 }, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */
+ { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */
+ { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */
+ { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */
+ { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */
+ { 0x06d9, 0x044b }, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */
+ { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */
+ { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */
+ { 0x06dc, 0x044d }, /* Cyrillic_e э CYRILLIC SMALL LETTER E */
+ { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */
+ { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */
+ { 0x06df, 0x044a }, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */
+ { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */
+ { 0x06e1, 0x0410 }, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */
+ { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */
+ { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */
+ { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */
+ { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */
+ { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */
+ { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */
+ { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */
+ { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */
+ { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */
+ { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */
+ { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */
+ { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */
+ { 0x06ee, 0x041d }, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */
+ { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */
+ { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */
+ { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */
+ { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */
+ { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */
+ { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */
+ { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */
+ { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */
+ { 0x06f7, 0x0412 }, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */
+ { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */
+ { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */
+ { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */
+ { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */
+ { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */
+ { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */
+ { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */
+ { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */
+ { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */
+ { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */
+ { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */
+ { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */
+ { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
+ { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */
+ { 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */
+ { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
+ { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */
+ { 0x07ae, 0x0385 }, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */
+ { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */
+ { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */
+ { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */
+ { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */
+ { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */
+ { 0x07b5, 0x03ca }, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */
+ { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
+ { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */
+ { 0x07b8, 0x03cd }, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */
+ { 0x07b9, 0x03cb }, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
+ { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
+ { 0x07bb, 0x03ce }, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */
+ { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */
+ { 0x07c2, 0x0392 }, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */
+ { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */
+ { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */
+ { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */
+ { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */
+ { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */
+ { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */
+ { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */
+ { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */
+ { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */
+ { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */
+ { 0x07cd, 0x039d }, /* Greek_NU Ν GREEK CAPITAL LETTER NU */
+ { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */
+ { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */
+ { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */
+ { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */
+ { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */
+ { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */
+ { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */
+ { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */
+ { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */
+ { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */
+ { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */
+ { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */
+ { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */
+ { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */
+ { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */
+ { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */
+ { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */
+ { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */
+ { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */
+ { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */
+ { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */
+ { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */
+ { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */
+ { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */
+ { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */
+ { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */
+ { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */
+ { 0x07f1, 0x03c1 }, /* Greek_rho ρ GREEK SMALL LETTER RHO */
+ { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */
+ { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */
+ { 0x07f4, 0x03c4 }, /* Greek_tau τ GREEK SMALL LETTER TAU */
+ { 0x07f5, 0x03c5 }, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */
+ { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */
+ { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */
+ { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */
+ { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */
+ { 0x08a1, 0x23b7 }, /* leftradical ⎷ ??? */
+ { 0x08a2, 0x250c }, /* topleftradical ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
+ { 0x08a3, 0x2500 }, /* horizconnector ─ BOX DRAWINGS LIGHT HORIZONTAL */
+ { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */
+ { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */
+ { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */
+ { 0x08a7, 0x23a1 }, /* topleftsqbracket ⎡ ??? */
+ { 0x08a8, 0x23a3 }, /* botleftsqbracket ⎣ ??? */
+ { 0x08a9, 0x23a4 }, /* toprightsqbracket ⎤ ??? */
+ { 0x08aa, 0x23a6 }, /* botrightsqbracket ⎦ ??? */
+ { 0x08ab, 0x239b }, /* topleftparens ⎛ ??? */
+ { 0x08ac, 0x239d }, /* botleftparens ⎝ ??? */
+ { 0x08ad, 0x239e }, /* toprightparens ⎞ ??? */
+ { 0x08ae, 0x23a0 }, /* botrightparens ⎠ ??? */
+ { 0x08af, 0x23a8 }, /* leftmiddlecurlybrace ⎨ ??? */
+ { 0x08b0, 0x23ac }, /* rightmiddlecurlybrace ⎬ ??? */
+ /* 0x08b1 topleftsummation ? ??? */
+ /* 0x08b2 botleftsummation ? ??? */
+ /* 0x08b3 topvertsummationconnector ? ??? */
+ /* 0x08b4 botvertsummationconnector ? ??? */
+ /* 0x08b5 toprightsummation ? ??? */
+ /* 0x08b6 botrightsummation ? ??? */
+ /* 0x08b7 rightmiddlesummation ? ??? */
+ { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */
+ { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */
+ { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */
+ { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */
+ { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */
+ { 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */
+ { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */
+ { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */
+ { 0x08c8, 0x223c }, /* approximate ∼ TILDE OPERATOR */
+ { 0x08c9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */
+ { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */
+ { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */
+ { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */
+ { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */
+ { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */
+ { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */
+ { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */
+ { 0x08dd, 0x222a }, /* union ∪ UNION */
+ { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */
+ { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */
+ { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */
+ { 0x08f6, 0x0192 }, /* function ƒ LATIN SMALL LETTER F WITH HOOK */
+ { 0x08fb, 0x2190 }, /* leftarrow ← LEFTWARDS ARROW */
+ { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */
+ { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */
+ { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */
+/* 0x09df blank ? ??? */
+ { 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */
+ { 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */
+ { 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */
+ { 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */
+ { 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */
+ { 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */
+ { 0x09e8, 0x2424 }, /* nl ␤ SYMBOL FOR NEWLINE */
+ { 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */
+ { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */
+ { 0x09eb, 0x2510 }, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */
+ { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
+ { 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */
+ { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
+ { 0x09ef, 0x23ba }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 (Unicode 3.2 draft) */
+ { 0x09f0, 0x23bb }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 (Unicode 3.2 draft) */
+ { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */
+ { 0x09f2, 0x23bc }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 (Unicode 3.2 draft) */
+ { 0x09f3, 0x23bd }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 (Unicode 3.2 draft) */
+ { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
+ { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */
+ { 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */
+ { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
+ { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */
+ { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */
+ { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */
+ { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */
+ { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */
+ { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */
+ { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */
+ { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */
+ { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */
+ { 0x0aa9, 0x2014 }, /* emdash — EM DASH */
+ { 0x0aaa, 0x2013 }, /* endash – EN DASH */
+ /* 0x0aac signifblank ? ??? */
+ { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */
+ { 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */
+ { 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */
+ { 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */
+ { 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */
+ { 0x0ab3, 0x2156 }, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */
+ { 0x0ab4, 0x2157 }, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */
+ { 0x0ab5, 0x2158 }, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */
+ { 0x0ab6, 0x2159 }, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */
+ { 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */
+ { 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */
+ { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */
+ { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */
+ { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */
+ { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */
+ /* 0x0abf marker ? ??? */
+ { 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */
+ { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */
+ { 0x0ac5, 0x215d }, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */
+ { 0x0ac6, 0x215e }, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */
+ { 0x0ac9, 0x2122 }, /* trademark ™ TRADE MARK SIGN */
+ { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */
+ /* 0x0acb trademarkincircle ? ??? */
+ { 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */
+ { 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */
+ { 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */
+ { 0x0acf, 0x25af }, /* emopenrectangle ▯ WHITE VERTICAL RECTANGLE */
+ { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */
+ { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */
+ { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */
+ { 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */
+ { 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */
+ { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */
+ { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */
+ { 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */
+ /* 0x0ada hexagram ? ??? */
+ { 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */
+ { 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */
+ { 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */
+ { 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */
+ { 0x0adf, 0x25ae }, /* emfilledrect ▮ BLACK VERTICAL RECTANGLE */
+ { 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */
+ { 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */
+ { 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */
+ { 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */
+ { 0x0ae4, 0x25bd }, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */
+ { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */
+ { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */
+ { 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */
+ { 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */
+ { 0x0ae9, 0x25bc }, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */
+ { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */
+ { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */
+ { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */
+ { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */
+ { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */
+ { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */
+ { 0x0af1, 0x2020 }, /* dagger † DAGGER */
+ { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */
+ { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */
+ { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */
+ { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */
+ { 0x0af6, 0x266d }, /* musicalflat ♭ MUSIC FLAT SIGN */
+ { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */
+ { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */
+ { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */
+ { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */
+ { 0x0afb, 0x2117 }, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */
+ { 0x0afc, 0x2038 }, /* caret ‸ CARET */
+ { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */
+ { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */
+ /* 0x0aff cursor ? ??? */
+ { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */
+ { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */
+ { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */
+ { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */
+ { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */
+ { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */
+ { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */
+ { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */
+ { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */
+ { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */
+ { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */
+ { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */
+ { 0x0bcf, 0x25cb }, /* circle ○ WHITE CIRCLE */
+ { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */
+ { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */
+ { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */
+ { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */
+ { 0x0bdc, 0x22a2 }, /* lefttack ⊢ RIGHT TACK */
+ { 0x0bfc, 0x22a3 }, /* righttack ⊣ LEFT TACK */
+ { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */
+ { 0x0ce0, 0x05d0 }, /* hebrew_aleph א HEBREW LETTER ALEF */
+ { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */
+ { 0x0ce2, 0x05d2 }, /* hebrew_gimel ג HEBREW LETTER GIMEL */
+ { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */
+ { 0x0ce4, 0x05d4 }, /* hebrew_he ה HEBREW LETTER HE */
+ { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */
+ { 0x0ce6, 0x05d6 }, /* hebrew_zain ז HEBREW LETTER ZAYIN */
+ { 0x0ce7, 0x05d7 }, /* hebrew_chet ח HEBREW LETTER HET */
+ { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */
+ { 0x0ce9, 0x05d9 }, /* hebrew_yod י HEBREW LETTER YOD */
+ { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */
+ { 0x0ceb, 0x05db }, /* hebrew_kaph כ HEBREW LETTER KAF */
+ { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */
+ { 0x0ced, 0x05dd }, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */
+ { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */
+ { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */
+ { 0x0cf0, 0x05e0 }, /* hebrew_nun נ HEBREW LETTER NUN */
+ { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */
+ { 0x0cf2, 0x05e2 }, /* hebrew_ayin ע HEBREW LETTER AYIN */
+ { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */
+ { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */
+ { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */
+ { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */
+ { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */
+ { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */
+ { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */
+ { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */
+ { 0x0da1, 0x0e01 }, /* Thai_kokai ก THAI CHARACTER KO KAI */
+ { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */
+ { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */
+ { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */
+ { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */
+ { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */
+ { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */
+ { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */
+ { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */
+ { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */
+ { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */
+ { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */
+ { 0x0dad, 0x0e0d }, /* Thai_yoying ญ THAI CHARACTER YO YING */
+ { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */
+ { 0x0daf, 0x0e0f }, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */
+ { 0x0db0, 0x0e10 }, /* Thai_thothan ฐ THAI CHARACTER THO THAN */
+ { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */
+ { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */
+ { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */
+ { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */
+ { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */
+ { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */
+ { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */
+ { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */
+ { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */
+ { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */
+ { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */
+ { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */
+ { 0x0dbd, 0x0e1d }, /* Thai_fofa ฝ THAI CHARACTER FO FA */
+ { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */
+ { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */
+ { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */
+ { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */
+ { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */
+ { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */
+ { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */
+ { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */
+ { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */
+ { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */
+ { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */
+ { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */
+ { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */
+ { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */
+ { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */
+ { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */
+ { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */
+ { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */
+ { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */
+ { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */
+ { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */
+ { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */
+ { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */
+ { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */
+ { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */
+ { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */
+ { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */
+ { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */
+ { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */
+ { 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ฾ ??? */
+ { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */
+ { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */
+ { 0x0de1, 0x0e41 }, /* Thai_saraae แ THAI CHARACTER SARA AE */
+ { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */
+ { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */
+ { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */
+ { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */
+ { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */
+ { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */
+ { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */
+ { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */
+ { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */
+ { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */
+ { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */
+ { 0x0ded, 0x0e4d }, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */
+ { 0x0df0, 0x0e50 }, /* Thai_leksun ๐ THAI DIGIT ZERO */
+ { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */
+ { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */
+ { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */
+ { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */
+ { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */
+ { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */
+ { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */
+ { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */
+ { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */
+ { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */
+ { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */
+ { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */
+ { 0x0ea4, 0x3134 }, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */
+ { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */
+ { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */
+ { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */
+ { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */
+ { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */
+ { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */
+ { 0x0eab, 0x313b }, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */
+ { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */
+ { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */
+ { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */
+ { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */
+ { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */
+ { 0x0eb1, 0x3141 }, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */
+ { 0x0eb2, 0x3142 }, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */
+ { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */
+ { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */
+ { 0x0eb5, 0x3145 }, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */
+ { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */
+ { 0x0eb7, 0x3147 }, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */
+ { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */
+ { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */
+ { 0x0eba, 0x314a }, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */
+ { 0x0ebb, 0x314b }, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */
+ { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */
+ { 0x0ebd, 0x314d }, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */
+ { 0x0ebe, 0x314e }, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */
+ { 0x0ebf, 0x314f }, /* Hangul_A ㅏ HANGUL LETTER A */
+ { 0x0ec0, 0x3150 }, /* Hangul_AE ㅐ HANGUL LETTER AE */
+ { 0x0ec1, 0x3151 }, /* Hangul_YA ㅑ HANGUL LETTER YA */
+ { 0x0ec2, 0x3152 }, /* Hangul_YAE ㅒ HANGUL LETTER YAE */
+ { 0x0ec3, 0x3153 }, /* Hangul_EO ㅓ HANGUL LETTER EO */
+ { 0x0ec4, 0x3154 }, /* Hangul_E ㅔ HANGUL LETTER E */
+ { 0x0ec5, 0x3155 }, /* Hangul_YEO ㅕ HANGUL LETTER YEO */
+ { 0x0ec6, 0x3156 }, /* Hangul_YE ㅖ HANGUL LETTER YE */
+ { 0x0ec7, 0x3157 }, /* Hangul_O ㅗ HANGUL LETTER O */
+ { 0x0ec8, 0x3158 }, /* Hangul_WA ㅘ HANGUL LETTER WA */
+ { 0x0ec9, 0x3159 }, /* Hangul_WAE ㅙ HANGUL LETTER WAE */
+ { 0x0eca, 0x315a }, /* Hangul_OE ㅚ HANGUL LETTER OE */
+ { 0x0ecb, 0x315b }, /* Hangul_YO ㅛ HANGUL LETTER YO */
+ { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */
+ { 0x0ecd, 0x315d }, /* Hangul_WEO ㅝ HANGUL LETTER WEO */
+ { 0x0ece, 0x315e }, /* Hangul_WE ㅞ HANGUL LETTER WE */
+ { 0x0ecf, 0x315f }, /* Hangul_WI ㅟ HANGUL LETTER WI */
+ { 0x0ed0, 0x3160 }, /* Hangul_YU ㅠ HANGUL LETTER YU */
+ { 0x0ed1, 0x3161 }, /* Hangul_EU ㅡ HANGUL LETTER EU */
+ { 0x0ed2, 0x3162 }, /* Hangul_YI ㅢ HANGUL LETTER YI */
+ { 0x0ed3, 0x3163 }, /* Hangul_I ㅣ HANGUL LETTER I */
+ { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */
+ { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */
+ { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */
+ { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */
+ { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */
+ { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */
+ { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */
+ { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */
+ { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */
+ { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */
+ { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */
+ { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */
+ { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */
+ { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */
+ { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */
+ { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */
+ { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */
+ { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */
+ { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */
+ { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */
+ { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */
+ { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */
+ { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */
+ { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */
+ { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */
+ { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */
+ { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */
+ { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */
+ { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */
+ { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */
+ { 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */
+/* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */
+ { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
+ { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
+ { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */
+ { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */
+ { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */
+ { 0x0ef9, 0x11f0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */
+ { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */
+ { 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */
+ { 0x13a4, 0x20ac }, /* Euro € EURO SIGN */
+ { 0x13bc, 0x0152 }, /* OE ΠLATIN CAPITAL LIGATURE OE */
+ { 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */
+ { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */
+ { 0x20a0, 0x20a0 }, /* EcuSign ₠ EURO-CURRENCY SIGN */
+ { 0x20a1, 0x20a1 }, /* ColonSign ₡ COLON SIGN */
+ { 0x20a2, 0x20a2 }, /* CruzeiroSign ₢ CRUZEIRO SIGN */
+ { 0x20a3, 0x20a3 }, /* FFrancSign ₣ FRENCH FRANC SIGN */
+ { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */
+ { 0x20a5, 0x20a5 }, /* MillSign ₥ MILL SIGN */
+ { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */
+ { 0x20a7, 0x20a7 }, /* PesetaSign ₧ PESETA SIGN */
+ { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */
+ { 0x20a9, 0x20a9 }, /* WonSign ₩ WON SIGN */
+ { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */
+ { 0x20ab, 0x20ab }, /* DongSign ₫ DONG SIGN */
+ { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */
+};
+
+/* binary search with range check */
+static uint32_t
+bin_search(const struct codepair *table, size_t length, xkb_keysym_t keysym)
+{
+ int min = 0;
+ int max = length;
+ int mid;
+
+ if (keysym < table[0].keysym || keysym > table[length].keysym)
+ return 0;
+
+ /* binary search in table */
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (table[mid].keysym < keysym)
+ min = mid + 1;
+ else if (table[mid].keysym > keysym)
+ max = mid - 1;
+ else /* found it */
+ return table[mid].ucs;
+ }
+
+ /* no matching Unicode value found in table */
+ return 0;
+}
+
+XKB_EXPORT uint32_t
+xkb_keysym_to_utf32(xkb_keysym_t keysym)
+{
+ /* first check for Latin-1 characters (1:1 mapping) */
+ if ((keysym >= 0x0020 && keysym <= 0x007e) ||
+ (keysym >= 0x00a0 && keysym <= 0x00ff))
+ return keysym;
+
+ /* patch encoding botch */
+ if (keysym == XKB_KEY_KP_Space)
+ return XKB_KEY_space & 0x7f;
+
+ /* special keysyms */
+ if ((keysym >= XKB_KEY_BackSpace && keysym <= XKB_KEY_Clear) ||
+ (keysym >= XKB_KEY_KP_Multiply && keysym <= XKB_KEY_KP_9) ||
+ keysym == XKB_KEY_Return || keysym == XKB_KEY_Escape ||
+ keysym == XKB_KEY_Delete || keysym == XKB_KEY_KP_Tab ||
+ keysym == XKB_KEY_KP_Enter || keysym == XKB_KEY_KP_Equal)
+ return keysym & 0x7f;
+
+ /* also check for directly encoded 24-bit UCS characters */
+ if ((keysym & 0xff000000) == 0x01000000)
+ return keysym & 0x00ffffff;
+
+ /* search main table */
+ return bin_search(keysymtab, ARRAY_SIZE(keysymtab) - 1, keysym);
+}
+
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Rob Bradford <rob@linux.intel.com>
+ */
+
+static int
+utf32_to_utf8(uint32_t unichar, char *buffer)
+{
+ int count, shift, length;
+ uint8_t head;
+
+ if (unichar <= 0x007f) {
+ buffer[0] = unichar;
+ buffer[1] = '\0';
+ return 2;
+ }
+ else if (unichar <= 0x07FF) {
+ length = 2;
+ head = 0xc0;
+ }
+ else if (unichar <= 0xffff) {
+ length = 3;
+ head = 0xe0;
+ }
+ else if (unichar <= 0x1fffff) {
+ length = 4;
+ head = 0xf0;
+ }
+ else if (unichar <= 0x3ffffff) {
+ length = 5;
+ head = 0xf8;
+ }
+ else {
+ length = 6;
+ head = 0xfc;
+ }
+
+ for (count = length - 1, shift = 0; count > 0; count--, shift += 6)
+ buffer[count] = 0x80 | ((unichar >> shift) & 0x3f);
+
+ buffer[0] = head | ((unichar >> shift) & 0x3f);
+ buffer[length] = '\0';
+
+ return length + 1;
+}
+
+XKB_EXPORT int
+xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size)
+{
+ uint32_t codepoint;
+
+ if (size < 7)
+ return -1;
+
+ codepoint = xkb_keysym_to_utf32(keysym);
+
+ if (codepoint == 0)
+ return 0;
+
+ return utf32_to_utf8(codepoint, buffer);
+}
diff --git a/src/3rdparty/xkbcommon/src/keysym.c b/src/3rdparty/xkbcommon/src/keysym.c
new file mode 100644
index 0000000000..1e92a4ac9f
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/keysym.c
@@ -0,0 +1,720 @@
+/*
+ * Copyright 1985, 1987, 1990, 1998 The Open Group
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the authors or their
+ * institutions shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization from the authors.
+ */
+
+/*
+ * Copyright © 2009 Dan Nicholson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include "xkbcommon/xkbcommon.h"
+#include "utils.h"
+#include "keysym.h"
+#include "ks_tables.h"
+
+static int
+compare_by_keysym(const void *a, const void *b)
+{
+ const struct name_keysym *key = a, *entry = b;
+ return key->keysym - (int32_t)entry->keysym;
+}
+
+static int
+compare_by_name(const void *a, const void *b)
+{
+ const struct name_keysym *key = a, *entry = b;
+ return strcasecmp(key->name, entry->name);
+}
+
+XKB_EXPORT int
+xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
+{
+ const struct name_keysym search = { .name = NULL, .keysym = ks };
+ const struct name_keysym *entry;
+
+ if ((ks & ((unsigned long) ~0x1fffffff)) != 0) {
+ snprintf(buffer, size, "Invalid");
+ return -1;
+ }
+
+ entry = bsearch(&search, keysym_to_name,
+ ARRAY_SIZE(keysym_to_name),
+ sizeof(*keysym_to_name),
+ compare_by_keysym);
+ if (entry)
+ return snprintf(buffer, size, "%s", entry->name);
+
+ /* Unnamed Unicode codepoint. */
+ if (ks >= 0x01000100 && ks <= 0x0110ffff) {
+ const int width = (ks & 0xff0000UL) ? 8 : 4;
+ return snprintf(buffer, size, "U%0*lX", width, ks & 0xffffffUL);
+ }
+
+ /* Unnamed, non-Unicode, symbol (shouldn't generally happen). */
+ return snprintf(buffer, size, "0x%08x", ks);
+}
+
+/*
+ * Find the correct keysym if one case-insensitive match is given.
+ *
+ * The name_to_keysym table is sorted by strcasecmp(). So bsearch() may return
+ * _any_ of all possible case-insensitive duplicates. This function searches the
+ * returned entry @entry, all previous and all next entries that match by
+ * case-insensitive comparison and returns the exact match to @name. If @icase
+ * is true, then this returns the best case-insensitive match instead of a
+ * correct match.
+ * The "best" case-insensitive match is the lower-case keysym which we find with
+ * the help of xkb_keysym_is_lower().
+ * The only keysyms that only differ by letter-case are keysyms that are
+ * available as lower-case and upper-case variant (like KEY_a and KEY_A). So
+ * returning the first lower-case match is enough in this case.
+ */
+static const struct name_keysym *
+find_sym(const struct name_keysym *entry, const char *name, bool icase)
+{
+ const struct name_keysym *iter, *last;
+ size_t len = ARRAY_SIZE(name_to_keysym);
+
+ if (!entry)
+ return NULL;
+
+ if (!icase && strcmp(entry->name, name) == 0)
+ return entry;
+ if (icase && xkb_keysym_is_lower(entry->keysym))
+ return entry;
+
+ for (iter = entry - 1; iter >= name_to_keysym; --iter) {
+ if (!icase && strcmp(iter->name, name) == 0)
+ return iter;
+ if (strcasecmp(iter->name, entry->name) != 0)
+ break;
+ if (icase && xkb_keysym_is_lower(iter->keysym))
+ return iter;
+ }
+
+ last = name_to_keysym + len;
+ for (iter = entry + 1; iter < last; --iter) {
+ if (!icase && strcmp(iter->name, name) == 0)
+ return iter;
+ if (strcasecmp(iter->name, entry->name) != 0)
+ break;
+ if (icase && xkb_keysym_is_lower(iter->keysym))
+ return iter;
+ }
+
+ if (icase)
+ return entry;
+ return NULL;
+}
+
+XKB_EXPORT xkb_keysym_t
+xkb_keysym_from_name(const char *s, enum xkb_keysym_flags flags)
+{
+ const struct name_keysym search = { .name = s, .keysym = 0 };
+ const struct name_keysym *entry;
+ char *tmp;
+ xkb_keysym_t val;
+ bool icase = !!(flags & XKB_KEYSYM_CASE_INSENSITIVE);
+
+ if (flags & ~XKB_KEYSYM_CASE_INSENSITIVE)
+ return XKB_KEY_NoSymbol;
+
+ entry = bsearch(&search, name_to_keysym,
+ ARRAY_SIZE(name_to_keysym),
+ sizeof(*name_to_keysym),
+ compare_by_name);
+ entry = find_sym(entry, s, icase);
+ if (entry)
+ return entry->keysym;
+
+ if (*s == 'U' || (icase && *s == 'u')) {
+ val = strtoul(&s[1], &tmp, 16);
+ if (tmp && *tmp != '\0')
+ return XKB_KEY_NoSymbol;
+
+ if (val < 0x20 || (val > 0x7e && val < 0xa0))
+ return XKB_KEY_NoSymbol;
+ if (val < 0x100)
+ return val;
+ if (val > 0x10ffff)
+ return XKB_KEY_NoSymbol;
+ return val | 0x01000000;
+ }
+ else if (s[0] == '0' && (s[1] == 'x' || (icase && s[1] == 'X'))) {
+ val = strtoul(&s[2], &tmp, 16);
+ if (tmp && *tmp != '\0')
+ return XKB_KEY_NoSymbol;
+
+ return val;
+ }
+
+ /* Stupid inconsistency between the headers and XKeysymDB: the former has
+ * no separating underscore, while some XF86* syms in the latter did.
+ * As a last ditch effort, try without. */
+ if (strncmp(s, "XF86_", 5) == 0 ||
+ (icase && strncasecmp(s, "XF86_", 5) == 0)) {
+ xkb_keysym_t ret;
+ tmp = strdup(s);
+ if (!tmp)
+ return XKB_KEY_NoSymbol;
+ memmove(&tmp[4], &tmp[5], strlen(s) - 5 + 1);
+ ret = xkb_keysym_from_name(tmp, flags);
+ free(tmp);
+ return ret;
+ }
+
+ return XKB_KEY_NoSymbol;
+}
+
+bool
+xkb_keysym_is_keypad(xkb_keysym_t keysym)
+{
+ return keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_Equal;
+}
+
+static void
+XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper);
+
+bool
+xkb_keysym_is_lower(xkb_keysym_t ks)
+{
+ xkb_keysym_t lower, upper;
+
+ XConvertCase(ks, &lower, &upper);
+
+ if (lower == upper)
+ return false;
+
+ return (ks == lower ? true : false);
+}
+
+bool
+xkb_keysym_is_upper(xkb_keysym_t ks)
+{
+ xkb_keysym_t lower, upper;
+
+ XConvertCase(ks, &lower, &upper);
+
+ if (lower == upper)
+ return false;
+
+ return (ks == upper ? true : false);
+}
+
+/*
+ * The following is copied verbatim from libX11:src/KeyBind.c, commit
+ * d45b3fc19fbe95c41afc4e51d768df6d42332010, with the following changes:
+ * - unsigned -> uint32_t
+ * - unsigend short -> uint16_t
+ * - s/XK_/XKB_KEY_
+ *
+ * XXX: If newlocale() and iswlower_l()/iswupper_l() interface ever
+ * become portable, we should use that in conjunction with
+ * xkb_keysym_to_utf32(), instead of all this stuff. We should
+ * be sure to give the same results as libX11, though, and be
+ * locale independent; this information is used by xkbcomp to
+ * find the automatic type to assign to key groups.
+ */
+
+static void
+UCSConvertCase(uint32_t code, xkb_keysym_t *lower, xkb_keysym_t *upper)
+{
+ /* Case conversion for UCS, as in Unicode Data version 4.0.0 */
+ /* NB: Only converts simple one-to-one mappings. */
+
+ /* Tables are used where they take less space than */
+ /* the code to work out the mappings. Zero values mean */
+ /* undefined code points. */
+
+ static uint16_t const IPAExt_upper_mapping[] = { /* part only */
+ 0x0181, 0x0186, 0x0255, 0x0189, 0x018A,
+ 0x0258, 0x018F, 0x025A, 0x0190, 0x025C, 0x025D, 0x025E, 0x025F,
+ 0x0193, 0x0261, 0x0262, 0x0194, 0x0264, 0x0265, 0x0266, 0x0267,
+ 0x0197, 0x0196, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x019C,
+ 0x0270, 0x0271, 0x019D, 0x0273, 0x0274, 0x019F, 0x0276, 0x0277,
+ 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F,
+ 0x01A6, 0x0281, 0x0282, 0x01A9, 0x0284, 0x0285, 0x0286, 0x0287,
+ 0x01AE, 0x0289, 0x01B1, 0x01B2, 0x028C, 0x028D, 0x028E, 0x028F,
+ 0x0290, 0x0291, 0x01B7
+ };
+
+ static uint16_t const LatinExtB_upper_mapping[] = { /* first part only */
+ 0x0180, 0x0181, 0x0182, 0x0182, 0x0184, 0x0184, 0x0186, 0x0187,
+ 0x0187, 0x0189, 0x018A, 0x018B, 0x018B, 0x018D, 0x018E, 0x018F,
+ 0x0190, 0x0191, 0x0191, 0x0193, 0x0194, 0x01F6, 0x0196, 0x0197,
+ 0x0198, 0x0198, 0x019A, 0x019B, 0x019C, 0x019D, 0x0220, 0x019F,
+ 0x01A0, 0x01A0, 0x01A2, 0x01A2, 0x01A4, 0x01A4, 0x01A6, 0x01A7,
+ 0x01A7, 0x01A9, 0x01AA, 0x01AB, 0x01AC, 0x01AC, 0x01AE, 0x01AF,
+ 0x01AF, 0x01B1, 0x01B2, 0x01B3, 0x01B3, 0x01B5, 0x01B5, 0x01B7,
+ 0x01B8, 0x01B8, 0x01BA, 0x01BB, 0x01BC, 0x01BC, 0x01BE, 0x01F7,
+ 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C4, 0x01C4, 0x01C7,
+ 0x01C7, 0x01C7, 0x01CA, 0x01CA, 0x01CA
+ };
+
+ static uint16_t const LatinExtB_lower_mapping[] = { /* first part only */
+ 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188,
+ 0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259,
+ 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268,
+ 0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275,
+ 0x01A1, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x0280, 0x01A8,
+ 0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01B0,
+ 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292,
+ 0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF,
+ 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9,
+ 0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC
+ };
+
+ static uint16_t const Greek_upper_mapping[] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x0386, 0x0387,
+ 0x0388, 0x0389, 0x038A, 0x0000, 0x038C, 0x0000, 0x038E, 0x038F,
+ 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+ 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
+ 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x0386, 0x0388, 0x0389, 0x038A,
+ 0x03B0, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+ 0x03A0, 0x03A1, 0x03A3, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
+ 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x038C, 0x038E, 0x038F, 0x0000,
+ 0x0392, 0x0398, 0x03D2, 0x03D3, 0x03D4, 0x03A6, 0x03A0, 0x03D7,
+ 0x03D8, 0x03D8, 0x03DA, 0x03DA, 0x03DC, 0x03DC, 0x03DE, 0x03DE,
+ 0x03E0, 0x03E0, 0x03E2, 0x03E2, 0x03E4, 0x03E4, 0x03E6, 0x03E6,
+ 0x03E8, 0x03E8, 0x03EA, 0x03EA, 0x03EC, 0x03EC, 0x03EE, 0x03EE,
+ 0x039A, 0x03A1, 0x03F9, 0x03F3, 0x03F4, 0x0395, 0x03F6, 0x03F7,
+ 0x03F7, 0x03F9, 0x03FA, 0x03FA, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+
+ static uint16_t const Greek_lower_mapping[] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x03AC, 0x0387,
+ 0x03AD, 0x03AE, 0x03AF, 0x0000, 0x03CC, 0x0000, 0x03CD, 0x03CE,
+ 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+ 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+ 0x03C0, 0x03C1, 0x0000, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
+ 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
+ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+ 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
+ 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000,
+ 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7,
+ 0x03D9, 0x03D9, 0x03DB, 0x03DB, 0x03DD, 0x03DD, 0x03DF, 0x03DF,
+ 0x03E1, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7,
+ 0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF,
+ 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03B8, 0x03F5, 0x03F6, 0x03F8,
+ 0x03F8, 0x03F2, 0x03FB, 0x03FB, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+
+ static uint16_t const GreekExt_lower_mapping[] = {
+ 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
+ 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
+ 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
+ 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
+ 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
+ 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
+ 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
+ 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
+ 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
+ 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
+ 0x1F50, 0x1F51, 0x1F52, 0x1F53, 0x1F54, 0x1F55, 0x1F56, 0x1F57,
+ 0x0000, 0x1F51, 0x0000, 0x1F53, 0x0000, 0x1F55, 0x0000, 0x1F57,
+ 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
+ 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
+ 0x1F70, 0x1F71, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F76, 0x1F77,
+ 0x1F78, 0x1F79, 0x1F7A, 0x1F7B, 0x1F7C, 0x1F7D, 0x0000, 0x0000,
+ 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
+ 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
+ 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
+ 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
+ 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
+ 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
+ 0x1FB0, 0x1FB1, 0x1FB2, 0x1FB3, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7,
+ 0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x1FBD, 0x1FBE, 0x1FBF,
+ 0x1FC0, 0x1FC1, 0x1FC2, 0x1FC3, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7,
+ 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x1FCD, 0x1FCE, 0x1FCF,
+ 0x1FD0, 0x1FD1, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7,
+ 0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF,
+ 0x1FE0, 0x1FE1, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FE5, 0x1FE6, 0x1FE7,
+ 0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x1FED, 0x1FEE, 0x1FEF,
+ 0x0000, 0x0000, 0x1FF2, 0x1FF3, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7,
+ 0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x1FFD, 0x1FFE, 0x0000
+ };
+
+ static uint16_t const GreekExt_upper_mapping[] = {
+ 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
+ 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
+ 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000,
+ 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000,
+ 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F,
+ 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F,
+ 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
+ 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
+ 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000,
+ 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000,
+ 0x1F50, 0x1F59, 0x1F52, 0x1F5B, 0x1F54, 0x1F5D, 0x1F56, 0x1F5F,
+ 0x0000, 0x1F59, 0x0000, 0x1F5B, 0x0000, 0x1F5D, 0x0000, 0x1F5F,
+ 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
+ 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
+ 0x1FBA, 0x1FBB, 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FDA, 0x1FDB,
+ 0x1FF8, 0x1FF9, 0x1FEA, 0x1FEB, 0x1FFA, 0x1FFB, 0x0000, 0x0000,
+ 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F,
+ 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F,
+ 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
+ 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
+ 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF,
+ 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF,
+ 0x1FB8, 0x1FB9, 0x1FB2, 0x1FBC, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7,
+ 0x1FB8, 0x1FB9, 0x1FBA, 0x1FBB, 0x1FBC, 0x1FBD, 0x0399, 0x1FBF,
+ 0x1FC0, 0x1FC1, 0x1FC2, 0x1FCC, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7,
+ 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FCC, 0x1FCD, 0x1FCE, 0x1FCF,
+ 0x1FD8, 0x1FD9, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7,
+ 0x1FD8, 0x1FD9, 0x1FDA, 0x1FDB, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF,
+ 0x1FE8, 0x1FE9, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FEC, 0x1FE6, 0x1FE7,
+ 0x1FE8, 0x1FE9, 0x1FEA, 0x1FEB, 0x1FEC, 0x1FED, 0x1FEE, 0x1FEF,
+ 0x0000, 0x0000, 0x1FF2, 0x1FFC, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7,
+ 0x1FF8, 0x1FF9, 0x1FFA, 0x1FFB, 0x1FFC, 0x1FFD, 0x1FFE, 0x0000
+ };
+
+ *lower = code;
+ *upper = code;
+
+ /* Basic Latin and Latin-1 Supplement, U+0000 to U+00FF */
+ if (code <= 0x00ff) {
+ if (code >= 0x0041 && code <= 0x005a) /* A-Z */
+ *lower += 0x20;
+ else if (code >= 0x0061 && code <= 0x007a) /* a-z */
+ *upper -= 0x20;
+ else if ( (code >= 0x00c0 && code <= 0x00d6) ||
+ (code >= 0x00d8 && code <= 0x00de) )
+ *lower += 0x20;
+ else if ( (code >= 0x00e0 && code <= 0x00f6) ||
+ (code >= 0x00f8 && code <= 0x00fe) )
+ *upper -= 0x20;
+ else if (code == 0x00ff) /* y with diaeresis */
+ *upper = 0x0178;
+ else if (code == 0x00b5) /* micro sign */
+ *upper = 0x039c;
+ return;
+ }
+
+ /* Latin Extended-A, U+0100 to U+017F */
+ if (code >= 0x0100 && code <= 0x017f) {
+ if ( (code >= 0x0100 && code <= 0x012f) ||
+ (code >= 0x0132 && code <= 0x0137) ||
+ (code >= 0x014a && code <= 0x0177) ) {
+ *upper = code & ~1;
+ *lower = code | 1;
+ }
+ else if ( (code >= 0x0139 && code <= 0x0148) ||
+ (code >= 0x0179 && code <= 0x017e) ) {
+ if (code & 1)
+ *lower += 1;
+ else
+ *upper -= 1;
+ }
+ else if (code == 0x0130)
+ *lower = 0x0069;
+ else if (code == 0x0131)
+ *upper = 0x0049;
+ else if (code == 0x0178)
+ *lower = 0x00ff;
+ else if (code == 0x017f)
+ *upper = 0x0053;
+ return;
+ }
+
+ /* Latin Extended-B, U+0180 to U+024F */
+ if (code >= 0x0180 && code <= 0x024f) {
+ if (code >= 0x01cd && code <= 0x01dc) {
+ if (code & 1)
+ *lower += 1;
+ else
+ *upper -= 1;
+ }
+ else if ( (code >= 0x01de && code <= 0x01ef) ||
+ (code >= 0x01f4 && code <= 0x01f5) ||
+ (code >= 0x01f8 && code <= 0x021f) ||
+ (code >= 0x0222 && code <= 0x0233) ) {
+ *lower |= 1;
+ *upper &= ~1;
+ }
+ else if (code >= 0x0180 && code <= 0x01cc) {
+ *lower = LatinExtB_lower_mapping[code - 0x0180];
+ *upper = LatinExtB_upper_mapping[code - 0x0180];
+ }
+ else if (code == 0x01dd)
+ *upper = 0x018e;
+ else if (code == 0x01f1 || code == 0x01f2) {
+ *lower = 0x01f3;
+ *upper = 0x01f1;
+ }
+ else if (code == 0x01f3)
+ *upper = 0x01f1;
+ else if (code == 0x01f6)
+ *lower = 0x0195;
+ else if (code == 0x01f7)
+ *lower = 0x01bf;
+ else if (code == 0x0220)
+ *lower = 0x019e;
+ return;
+ }
+
+ /* IPA Extensions, U+0250 to U+02AF */
+ if (code >= 0x0253 && code <= 0x0292) {
+ *upper = IPAExt_upper_mapping[code - 0x0253];
+ }
+
+ /* Combining Diacritical Marks, U+0300 to U+036F */
+ if (code == 0x0345) {
+ *upper = 0x0399;
+ }
+
+ /* Greek and Coptic, U+0370 to U+03FF */
+ if (code >= 0x0370 && code <= 0x03ff) {
+ *lower = Greek_lower_mapping[code - 0x0370];
+ *upper = Greek_upper_mapping[code - 0x0370];
+ if (*upper == 0)
+ *upper = code;
+ if (*lower == 0)
+ *lower = code;
+ }
+
+ /* Cyrillic and Cyrillic Supplementary, U+0400 to U+052F */
+ if ( (code >= 0x0400 && code <= 0x04ff) ||
+ (code >= 0x0500 && code <= 0x052f) ) {
+ if (code >= 0x0400 && code <= 0x040f)
+ *lower += 0x50;
+ else if (code >= 0x0410 && code <= 0x042f)
+ *lower += 0x20;
+ else if (code >= 0x0430 && code <= 0x044f)
+ *upper -= 0x20;
+ else if (code >= 0x0450 && code <= 0x045f)
+ *upper -= 0x50;
+ else if ( (code >= 0x0460 && code <= 0x0481) ||
+ (code >= 0x048a && code <= 0x04bf) ||
+ (code >= 0x04d0 && code <= 0x04f5) ||
+ (code >= 0x04f8 && code <= 0x04f9) ||
+ (code >= 0x0500 && code <= 0x050f) ) {
+ *upper &= ~1;
+ *lower |= 1;
+ }
+ else if (code >= 0x04c1 && code <= 0x04ce) {
+ if (code & 1)
+ *lower += 1;
+ else
+ *upper -= 1;
+ }
+ }
+
+ /* Armenian, U+0530 to U+058F */
+ if (code >= 0x0530 && code <= 0x058f) {
+ if (code >= 0x0531 && code <= 0x0556)
+ *lower += 0x30;
+ else if (code >=0x0561 && code <= 0x0586)
+ *upper -= 0x30;
+ }
+
+ /* Latin Extended Additional, U+1E00 to U+1EFF */
+ if (code >= 0x1e00 && code <= 0x1eff) {
+ if ( (code >= 0x1e00 && code <= 0x1e95) ||
+ (code >= 0x1ea0 && code <= 0x1ef9) ) {
+ *upper &= ~1;
+ *lower |= 1;
+ }
+ else if (code == 0x1e9b)
+ *upper = 0x1e60;
+ }
+
+ /* Greek Extended, U+1F00 to U+1FFF */
+ if (code >= 0x1f00 && code <= 0x1fff) {
+ *lower = GreekExt_lower_mapping[code - 0x1f00];
+ *upper = GreekExt_upper_mapping[code - 0x1f00];
+ if (*upper == 0)
+ *upper = code;
+ if (*lower == 0)
+ *lower = code;
+ }
+
+ /* Letterlike Symbols, U+2100 to U+214F */
+ if (code >= 0x2100 && code <= 0x214f) {
+ switch (code) {
+ case 0x2126: *lower = 0x03c9; break;
+ case 0x212a: *lower = 0x006b; break;
+ case 0x212b: *lower = 0x00e5; break;
+ }
+ }
+ /* Number Forms, U+2150 to U+218F */
+ else if (code >= 0x2160 && code <= 0x216f)
+ *lower += 0x10;
+ else if (code >= 0x2170 && code <= 0x217f)
+ *upper -= 0x10;
+ /* Enclosed Alphanumerics, U+2460 to U+24FF */
+ else if (code >= 0x24b6 && code <= 0x24cf)
+ *lower += 0x1a;
+ else if (code >= 0x24d0 && code <= 0x24e9)
+ *upper -= 0x1a;
+ /* Halfwidth and Fullwidth Forms, U+FF00 to U+FFEF */
+ else if (code >= 0xff21 && code <= 0xff3a)
+ *lower += 0x20;
+ else if (code >= 0xff41 && code <= 0xff5a)
+ *upper -= 0x20;
+ /* Deseret, U+10400 to U+104FF */
+ else if (code >= 0x10400 && code <= 0x10427)
+ *lower += 0x28;
+ else if (code >= 0x10428 && code <= 0x1044f)
+ *upper -= 0x28;
+}
+
+static void
+XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper)
+{
+ /* Latin 1 keysym */
+ if (sym < 0x100) {
+ UCSConvertCase(sym, lower, upper);
+ return;
+ }
+
+ /* Unicode keysym */
+ if ((sym & 0xff000000) == 0x01000000) {
+ UCSConvertCase((sym & 0x00ffffff), lower, upper);
+ *upper |= 0x01000000;
+ *lower |= 0x01000000;
+ return;
+ }
+
+ /* Legacy keysym */
+
+ *lower = sym;
+ *upper = sym;
+
+ switch(sym >> 8) {
+ case 1: /* Latin 2 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym == XKB_KEY_Aogonek)
+ *lower = XKB_KEY_aogonek;
+ else if (sym >= XKB_KEY_Lstroke && sym <= XKB_KEY_Sacute)
+ *lower += (XKB_KEY_lstroke - XKB_KEY_Lstroke);
+ else if (sym >= XKB_KEY_Scaron && sym <= XKB_KEY_Zacute)
+ *lower += (XKB_KEY_scaron - XKB_KEY_Scaron);
+ else if (sym >= XKB_KEY_Zcaron && sym <= XKB_KEY_Zabovedot)
+ *lower += (XKB_KEY_zcaron - XKB_KEY_Zcaron);
+ else if (sym == XKB_KEY_aogonek)
+ *upper = XKB_KEY_Aogonek;
+ else if (sym >= XKB_KEY_lstroke && sym <= XKB_KEY_sacute)
+ *upper -= (XKB_KEY_lstroke - XKB_KEY_Lstroke);
+ else if (sym >= XKB_KEY_scaron && sym <= XKB_KEY_zacute)
+ *upper -= (XKB_KEY_scaron - XKB_KEY_Scaron);
+ else if (sym >= XKB_KEY_zcaron && sym <= XKB_KEY_zabovedot)
+ *upper -= (XKB_KEY_zcaron - XKB_KEY_Zcaron);
+ else if (sym >= XKB_KEY_Racute && sym <= XKB_KEY_Tcedilla)
+ *lower += (XKB_KEY_racute - XKB_KEY_Racute);
+ else if (sym >= XKB_KEY_racute && sym <= XKB_KEY_tcedilla)
+ *upper -= (XKB_KEY_racute - XKB_KEY_Racute);
+ break;
+ case 2: /* Latin 3 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XKB_KEY_Hstroke && sym <= XKB_KEY_Hcircumflex)
+ *lower += (XKB_KEY_hstroke - XKB_KEY_Hstroke);
+ else if (sym >= XKB_KEY_Gbreve && sym <= XKB_KEY_Jcircumflex)
+ *lower += (XKB_KEY_gbreve - XKB_KEY_Gbreve);
+ else if (sym >= XKB_KEY_hstroke && sym <= XKB_KEY_hcircumflex)
+ *upper -= (XKB_KEY_hstroke - XKB_KEY_Hstroke);
+ else if (sym >= XKB_KEY_gbreve && sym <= XKB_KEY_jcircumflex)
+ *upper -= (XKB_KEY_gbreve - XKB_KEY_Gbreve);
+ else if (sym >= XKB_KEY_Cabovedot && sym <= XKB_KEY_Scircumflex)
+ *lower += (XKB_KEY_cabovedot - XKB_KEY_Cabovedot);
+ else if (sym >= XKB_KEY_cabovedot && sym <= XKB_KEY_scircumflex)
+ *upper -= (XKB_KEY_cabovedot - XKB_KEY_Cabovedot);
+ break;
+ case 3: /* Latin 4 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XKB_KEY_Rcedilla && sym <= XKB_KEY_Tslash)
+ *lower += (XKB_KEY_rcedilla - XKB_KEY_Rcedilla);
+ else if (sym >= XKB_KEY_rcedilla && sym <= XKB_KEY_tslash)
+ *upper -= (XKB_KEY_rcedilla - XKB_KEY_Rcedilla);
+ else if (sym == XKB_KEY_ENG)
+ *lower = XKB_KEY_eng;
+ else if (sym == XKB_KEY_eng)
+ *upper = XKB_KEY_ENG;
+ else if (sym >= XKB_KEY_Amacron && sym <= XKB_KEY_Umacron)
+ *lower += (XKB_KEY_amacron - XKB_KEY_Amacron);
+ else if (sym >= XKB_KEY_amacron && sym <= XKB_KEY_umacron)
+ *upper -= (XKB_KEY_amacron - XKB_KEY_Amacron);
+ break;
+ case 6: /* Cyrillic */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XKB_KEY_Serbian_DJE && sym <= XKB_KEY_Serbian_DZE)
+ *lower -= (XKB_KEY_Serbian_DJE - XKB_KEY_Serbian_dje);
+ else if (sym >= XKB_KEY_Serbian_dje && sym <= XKB_KEY_Serbian_dze)
+ *upper += (XKB_KEY_Serbian_DJE - XKB_KEY_Serbian_dje);
+ else if (sym >= XKB_KEY_Cyrillic_YU && sym <= XKB_KEY_Cyrillic_HARDSIGN)
+ *lower -= (XKB_KEY_Cyrillic_YU - XKB_KEY_Cyrillic_yu);
+ else if (sym >= XKB_KEY_Cyrillic_yu && sym <= XKB_KEY_Cyrillic_hardsign)
+ *upper += (XKB_KEY_Cyrillic_YU - XKB_KEY_Cyrillic_yu);
+ break;
+ case 7: /* Greek */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XKB_KEY_Greek_ALPHAaccent && sym <= XKB_KEY_Greek_OMEGAaccent)
+ *lower += (XKB_KEY_Greek_alphaaccent - XKB_KEY_Greek_ALPHAaccent);
+ else if (sym >= XKB_KEY_Greek_alphaaccent && sym <= XKB_KEY_Greek_omegaaccent &&
+ sym != XKB_KEY_Greek_iotaaccentdieresis &&
+ sym != XKB_KEY_Greek_upsilonaccentdieresis)
+ *upper -= (XKB_KEY_Greek_alphaaccent - XKB_KEY_Greek_ALPHAaccent);
+ else if (sym >= XKB_KEY_Greek_ALPHA && sym <= XKB_KEY_Greek_OMEGA)
+ *lower += (XKB_KEY_Greek_alpha - XKB_KEY_Greek_ALPHA);
+ else if (sym >= XKB_KEY_Greek_alpha && sym <= XKB_KEY_Greek_omega &&
+ sym != XKB_KEY_Greek_finalsmallsigma)
+ *upper -= (XKB_KEY_Greek_alpha - XKB_KEY_Greek_ALPHA);
+ break;
+ case 0x13: /* Latin 9 */
+ if (sym == XKB_KEY_OE)
+ *lower = XKB_KEY_oe;
+ else if (sym == XKB_KEY_oe)
+ *upper = XKB_KEY_OE;
+ else if (sym == XKB_KEY_Ydiaeresis)
+ *lower = XKB_KEY_ydiaeresis;
+ break;
+ }
+}
diff --git a/src/3rdparty/xkbcommon/src/keysym.h b/src/3rdparty/xkbcommon/src/keysym.h
new file mode 100644
index 0000000000..6f2280bfd4
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/keysym.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1985, 1987, 1990, 1998 The Open Group
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the authors or their
+ * institutions shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization from the authors.
+ */
+
+/*
+ * Copyright © 2009 Dan Nicholson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef KEYSYM_H
+#define KEYSYM_H
+
+bool
+xkb_keysym_is_lower(xkb_keysym_t keysym);
+
+bool
+xkb_keysym_is_upper(xkb_keysym_t keysym);
+
+bool
+xkb_keysym_is_keypad(xkb_keysym_t keysym);
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/ks_tables.h b/src/3rdparty/xkbcommon/src/ks_tables.h
new file mode 100644
index 0000000000..a7e2b4705f
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/ks_tables.h
@@ -0,0 +1,4681 @@
+/* This file is autogenerated from Makefile.am; please do not commit directly. */
+
+struct name_keysym {
+ const char *name;
+ xkb_keysym_t keysym;
+};
+
+static const struct name_keysym name_to_keysym[] = {
+ { "0", XKB_KEY_0 },
+ { "1", XKB_KEY_1 },
+ { "2", XKB_KEY_2 },
+ { "3", XKB_KEY_3 },
+ { "3270_AltCursor", XKB_KEY_3270_AltCursor },
+ { "3270_Attn", XKB_KEY_3270_Attn },
+ { "3270_BackTab", XKB_KEY_3270_BackTab },
+ { "3270_ChangeScreen", XKB_KEY_3270_ChangeScreen },
+ { "3270_Copy", XKB_KEY_3270_Copy },
+ { "3270_CursorBlink", XKB_KEY_3270_CursorBlink },
+ { "3270_CursorSelect", XKB_KEY_3270_CursorSelect },
+ { "3270_DeleteWord", XKB_KEY_3270_DeleteWord },
+ { "3270_Duplicate", XKB_KEY_3270_Duplicate },
+ { "3270_Enter", XKB_KEY_3270_Enter },
+ { "3270_EraseEOF", XKB_KEY_3270_EraseEOF },
+ { "3270_EraseInput", XKB_KEY_3270_EraseInput },
+ { "3270_ExSelect", XKB_KEY_3270_ExSelect },
+ { "3270_FieldMark", XKB_KEY_3270_FieldMark },
+ { "3270_Ident", XKB_KEY_3270_Ident },
+ { "3270_Jump", XKB_KEY_3270_Jump },
+ { "3270_KeyClick", XKB_KEY_3270_KeyClick },
+ { "3270_Left2", XKB_KEY_3270_Left2 },
+ { "3270_PA1", XKB_KEY_3270_PA1 },
+ { "3270_PA2", XKB_KEY_3270_PA2 },
+ { "3270_PA3", XKB_KEY_3270_PA3 },
+ { "3270_Play", XKB_KEY_3270_Play },
+ { "3270_PrintScreen", XKB_KEY_3270_PrintScreen },
+ { "3270_Quit", XKB_KEY_3270_Quit },
+ { "3270_Record", XKB_KEY_3270_Record },
+ { "3270_Reset", XKB_KEY_3270_Reset },
+ { "3270_Right2", XKB_KEY_3270_Right2 },
+ { "3270_Rule", XKB_KEY_3270_Rule },
+ { "3270_Setup", XKB_KEY_3270_Setup },
+ { "3270_Test", XKB_KEY_3270_Test },
+ { "4", XKB_KEY_4 },
+ { "5", XKB_KEY_5 },
+ { "6", XKB_KEY_6 },
+ { "7", XKB_KEY_7 },
+ { "8", XKB_KEY_8 },
+ { "9", XKB_KEY_9 },
+ { "A", XKB_KEY_A },
+ { "a", XKB_KEY_a },
+ { "Aacute", XKB_KEY_Aacute },
+ { "aacute", XKB_KEY_aacute },
+ { "Abelowdot", XKB_KEY_Abelowdot },
+ { "abelowdot", XKB_KEY_abelowdot },
+ { "abovedot", XKB_KEY_abovedot },
+ { "Abreve", XKB_KEY_Abreve },
+ { "abreve", XKB_KEY_abreve },
+ { "Abreveacute", XKB_KEY_Abreveacute },
+ { "abreveacute", XKB_KEY_abreveacute },
+ { "Abrevebelowdot", XKB_KEY_Abrevebelowdot },
+ { "abrevebelowdot", XKB_KEY_abrevebelowdot },
+ { "Abrevegrave", XKB_KEY_Abrevegrave },
+ { "abrevegrave", XKB_KEY_abrevegrave },
+ { "Abrevehook", XKB_KEY_Abrevehook },
+ { "abrevehook", XKB_KEY_abrevehook },
+ { "Abrevetilde", XKB_KEY_Abrevetilde },
+ { "abrevetilde", XKB_KEY_abrevetilde },
+ { "AccessX_Enable", XKB_KEY_AccessX_Enable },
+ { "AccessX_Feedback_Enable", XKB_KEY_AccessX_Feedback_Enable },
+ { "Acircumflex", XKB_KEY_Acircumflex },
+ { "acircumflex", XKB_KEY_acircumflex },
+ { "Acircumflexacute", XKB_KEY_Acircumflexacute },
+ { "acircumflexacute", XKB_KEY_acircumflexacute },
+ { "Acircumflexbelowdot", XKB_KEY_Acircumflexbelowdot },
+ { "acircumflexbelowdot", XKB_KEY_acircumflexbelowdot },
+ { "Acircumflexgrave", XKB_KEY_Acircumflexgrave },
+ { "acircumflexgrave", XKB_KEY_acircumflexgrave },
+ { "Acircumflexhook", XKB_KEY_Acircumflexhook },
+ { "acircumflexhook", XKB_KEY_acircumflexhook },
+ { "Acircumflextilde", XKB_KEY_Acircumflextilde },
+ { "acircumflextilde", XKB_KEY_acircumflextilde },
+ { "acute", XKB_KEY_acute },
+ { "Adiaeresis", XKB_KEY_Adiaeresis },
+ { "adiaeresis", XKB_KEY_adiaeresis },
+ { "AE", XKB_KEY_AE },
+ { "ae", XKB_KEY_ae },
+ { "Agrave", XKB_KEY_Agrave },
+ { "agrave", XKB_KEY_agrave },
+ { "Ahook", XKB_KEY_Ahook },
+ { "ahook", XKB_KEY_ahook },
+ { "Alt_L", XKB_KEY_Alt_L },
+ { "Alt_R", XKB_KEY_Alt_R },
+ { "Amacron", XKB_KEY_Amacron },
+ { "amacron", XKB_KEY_amacron },
+ { "ampersand", XKB_KEY_ampersand },
+ { "Aogonek", XKB_KEY_Aogonek },
+ { "aogonek", XKB_KEY_aogonek },
+ { "apostrophe", XKB_KEY_apostrophe },
+ { "approxeq", XKB_KEY_approxeq },
+ { "approximate", XKB_KEY_approximate },
+ { "Arabic_0", XKB_KEY_Arabic_0 },
+ { "Arabic_1", XKB_KEY_Arabic_1 },
+ { "Arabic_2", XKB_KEY_Arabic_2 },
+ { "Arabic_3", XKB_KEY_Arabic_3 },
+ { "Arabic_4", XKB_KEY_Arabic_4 },
+ { "Arabic_5", XKB_KEY_Arabic_5 },
+ { "Arabic_6", XKB_KEY_Arabic_6 },
+ { "Arabic_7", XKB_KEY_Arabic_7 },
+ { "Arabic_8", XKB_KEY_Arabic_8 },
+ { "Arabic_9", XKB_KEY_Arabic_9 },
+ { "Arabic_ain", XKB_KEY_Arabic_ain },
+ { "Arabic_alef", XKB_KEY_Arabic_alef },
+ { "Arabic_alefmaksura", XKB_KEY_Arabic_alefmaksura },
+ { "Arabic_beh", XKB_KEY_Arabic_beh },
+ { "Arabic_comma", XKB_KEY_Arabic_comma },
+ { "Arabic_dad", XKB_KEY_Arabic_dad },
+ { "Arabic_dal", XKB_KEY_Arabic_dal },
+ { "Arabic_damma", XKB_KEY_Arabic_damma },
+ { "Arabic_dammatan", XKB_KEY_Arabic_dammatan },
+ { "Arabic_ddal", XKB_KEY_Arabic_ddal },
+ { "Arabic_farsi_yeh", XKB_KEY_Arabic_farsi_yeh },
+ { "Arabic_fatha", XKB_KEY_Arabic_fatha },
+ { "Arabic_fathatan", XKB_KEY_Arabic_fathatan },
+ { "Arabic_feh", XKB_KEY_Arabic_feh },
+ { "Arabic_fullstop", XKB_KEY_Arabic_fullstop },
+ { "Arabic_gaf", XKB_KEY_Arabic_gaf },
+ { "Arabic_ghain", XKB_KEY_Arabic_ghain },
+ { "Arabic_ha", XKB_KEY_Arabic_ha },
+ { "Arabic_hah", XKB_KEY_Arabic_hah },
+ { "Arabic_hamza", XKB_KEY_Arabic_hamza },
+ { "Arabic_hamza_above", XKB_KEY_Arabic_hamza_above },
+ { "Arabic_hamza_below", XKB_KEY_Arabic_hamza_below },
+ { "Arabic_hamzaonalef", XKB_KEY_Arabic_hamzaonalef },
+ { "Arabic_hamzaonwaw", XKB_KEY_Arabic_hamzaonwaw },
+ { "Arabic_hamzaonyeh", XKB_KEY_Arabic_hamzaonyeh },
+ { "Arabic_hamzaunderalef", XKB_KEY_Arabic_hamzaunderalef },
+ { "Arabic_heh", XKB_KEY_Arabic_heh },
+ { "Arabic_heh_doachashmee", XKB_KEY_Arabic_heh_doachashmee },
+ { "Arabic_heh_goal", XKB_KEY_Arabic_heh_goal },
+ { "Arabic_jeem", XKB_KEY_Arabic_jeem },
+ { "Arabic_jeh", XKB_KEY_Arabic_jeh },
+ { "Arabic_kaf", XKB_KEY_Arabic_kaf },
+ { "Arabic_kasra", XKB_KEY_Arabic_kasra },
+ { "Arabic_kasratan", XKB_KEY_Arabic_kasratan },
+ { "Arabic_keheh", XKB_KEY_Arabic_keheh },
+ { "Arabic_khah", XKB_KEY_Arabic_khah },
+ { "Arabic_lam", XKB_KEY_Arabic_lam },
+ { "Arabic_madda_above", XKB_KEY_Arabic_madda_above },
+ { "Arabic_maddaonalef", XKB_KEY_Arabic_maddaonalef },
+ { "Arabic_meem", XKB_KEY_Arabic_meem },
+ { "Arabic_noon", XKB_KEY_Arabic_noon },
+ { "Arabic_noon_ghunna", XKB_KEY_Arabic_noon_ghunna },
+ { "Arabic_peh", XKB_KEY_Arabic_peh },
+ { "Arabic_percent", XKB_KEY_Arabic_percent },
+ { "Arabic_qaf", XKB_KEY_Arabic_qaf },
+ { "Arabic_question_mark", XKB_KEY_Arabic_question_mark },
+ { "Arabic_ra", XKB_KEY_Arabic_ra },
+ { "Arabic_rreh", XKB_KEY_Arabic_rreh },
+ { "Arabic_sad", XKB_KEY_Arabic_sad },
+ { "Arabic_seen", XKB_KEY_Arabic_seen },
+ { "Arabic_semicolon", XKB_KEY_Arabic_semicolon },
+ { "Arabic_shadda", XKB_KEY_Arabic_shadda },
+ { "Arabic_sheen", XKB_KEY_Arabic_sheen },
+ { "Arabic_sukun", XKB_KEY_Arabic_sukun },
+ { "Arabic_superscript_alef", XKB_KEY_Arabic_superscript_alef },
+ { "Arabic_switch", XKB_KEY_Arabic_switch },
+ { "Arabic_tah", XKB_KEY_Arabic_tah },
+ { "Arabic_tatweel", XKB_KEY_Arabic_tatweel },
+ { "Arabic_tcheh", XKB_KEY_Arabic_tcheh },
+ { "Arabic_teh", XKB_KEY_Arabic_teh },
+ { "Arabic_tehmarbuta", XKB_KEY_Arabic_tehmarbuta },
+ { "Arabic_thal", XKB_KEY_Arabic_thal },
+ { "Arabic_theh", XKB_KEY_Arabic_theh },
+ { "Arabic_tteh", XKB_KEY_Arabic_tteh },
+ { "Arabic_veh", XKB_KEY_Arabic_veh },
+ { "Arabic_waw", XKB_KEY_Arabic_waw },
+ { "Arabic_yeh", XKB_KEY_Arabic_yeh },
+ { "Arabic_yeh_baree", XKB_KEY_Arabic_yeh_baree },
+ { "Arabic_zah", XKB_KEY_Arabic_zah },
+ { "Arabic_zain", XKB_KEY_Arabic_zain },
+ { "Aring", XKB_KEY_Aring },
+ { "aring", XKB_KEY_aring },
+ { "Armenian_accent", XKB_KEY_Armenian_accent },
+ { "Armenian_amanak", XKB_KEY_Armenian_amanak },
+ { "Armenian_apostrophe", XKB_KEY_Armenian_apostrophe },
+ { "Armenian_AT", XKB_KEY_Armenian_AT },
+ { "Armenian_at", XKB_KEY_Armenian_at },
+ { "Armenian_AYB", XKB_KEY_Armenian_AYB },
+ { "Armenian_ayb", XKB_KEY_Armenian_ayb },
+ { "Armenian_BEN", XKB_KEY_Armenian_BEN },
+ { "Armenian_ben", XKB_KEY_Armenian_ben },
+ { "Armenian_but", XKB_KEY_Armenian_but },
+ { "Armenian_CHA", XKB_KEY_Armenian_CHA },
+ { "Armenian_cha", XKB_KEY_Armenian_cha },
+ { "Armenian_DA", XKB_KEY_Armenian_DA },
+ { "Armenian_da", XKB_KEY_Armenian_da },
+ { "Armenian_DZA", XKB_KEY_Armenian_DZA },
+ { "Armenian_dza", XKB_KEY_Armenian_dza },
+ { "Armenian_E", XKB_KEY_Armenian_E },
+ { "Armenian_e", XKB_KEY_Armenian_e },
+ { "Armenian_exclam", XKB_KEY_Armenian_exclam },
+ { "Armenian_FE", XKB_KEY_Armenian_FE },
+ { "Armenian_fe", XKB_KEY_Armenian_fe },
+ { "Armenian_full_stop", XKB_KEY_Armenian_full_stop },
+ { "Armenian_GHAT", XKB_KEY_Armenian_GHAT },
+ { "Armenian_ghat", XKB_KEY_Armenian_ghat },
+ { "Armenian_GIM", XKB_KEY_Armenian_GIM },
+ { "Armenian_gim", XKB_KEY_Armenian_gim },
+ { "Armenian_HI", XKB_KEY_Armenian_HI },
+ { "Armenian_hi", XKB_KEY_Armenian_hi },
+ { "Armenian_HO", XKB_KEY_Armenian_HO },
+ { "Armenian_ho", XKB_KEY_Armenian_ho },
+ { "Armenian_hyphen", XKB_KEY_Armenian_hyphen },
+ { "Armenian_INI", XKB_KEY_Armenian_INI },
+ { "Armenian_ini", XKB_KEY_Armenian_ini },
+ { "Armenian_JE", XKB_KEY_Armenian_JE },
+ { "Armenian_je", XKB_KEY_Armenian_je },
+ { "Armenian_KE", XKB_KEY_Armenian_KE },
+ { "Armenian_ke", XKB_KEY_Armenian_ke },
+ { "Armenian_KEN", XKB_KEY_Armenian_KEN },
+ { "Armenian_ken", XKB_KEY_Armenian_ken },
+ { "Armenian_KHE", XKB_KEY_Armenian_KHE },
+ { "Armenian_khe", XKB_KEY_Armenian_khe },
+ { "Armenian_ligature_ew", XKB_KEY_Armenian_ligature_ew },
+ { "Armenian_LYUN", XKB_KEY_Armenian_LYUN },
+ { "Armenian_lyun", XKB_KEY_Armenian_lyun },
+ { "Armenian_MEN", XKB_KEY_Armenian_MEN },
+ { "Armenian_men", XKB_KEY_Armenian_men },
+ { "Armenian_NU", XKB_KEY_Armenian_NU },
+ { "Armenian_nu", XKB_KEY_Armenian_nu },
+ { "Armenian_O", XKB_KEY_Armenian_O },
+ { "Armenian_o", XKB_KEY_Armenian_o },
+ { "Armenian_paruyk", XKB_KEY_Armenian_paruyk },
+ { "Armenian_PE", XKB_KEY_Armenian_PE },
+ { "Armenian_pe", XKB_KEY_Armenian_pe },
+ { "Armenian_PYUR", XKB_KEY_Armenian_PYUR },
+ { "Armenian_pyur", XKB_KEY_Armenian_pyur },
+ { "Armenian_question", XKB_KEY_Armenian_question },
+ { "Armenian_RA", XKB_KEY_Armenian_RA },
+ { "Armenian_ra", XKB_KEY_Armenian_ra },
+ { "Armenian_RE", XKB_KEY_Armenian_RE },
+ { "Armenian_re", XKB_KEY_Armenian_re },
+ { "Armenian_SE", XKB_KEY_Armenian_SE },
+ { "Armenian_se", XKB_KEY_Armenian_se },
+ { "Armenian_separation_mark", XKB_KEY_Armenian_separation_mark },
+ { "Armenian_SHA", XKB_KEY_Armenian_SHA },
+ { "Armenian_sha", XKB_KEY_Armenian_sha },
+ { "Armenian_shesht", XKB_KEY_Armenian_shesht },
+ { "Armenian_TCHE", XKB_KEY_Armenian_TCHE },
+ { "Armenian_tche", XKB_KEY_Armenian_tche },
+ { "Armenian_TO", XKB_KEY_Armenian_TO },
+ { "Armenian_to", XKB_KEY_Armenian_to },
+ { "Armenian_TSA", XKB_KEY_Armenian_TSA },
+ { "Armenian_tsa", XKB_KEY_Armenian_tsa },
+ { "Armenian_TSO", XKB_KEY_Armenian_TSO },
+ { "Armenian_tso", XKB_KEY_Armenian_tso },
+ { "Armenian_TYUN", XKB_KEY_Armenian_TYUN },
+ { "Armenian_tyun", XKB_KEY_Armenian_tyun },
+ { "Armenian_verjaket", XKB_KEY_Armenian_verjaket },
+ { "Armenian_VEV", XKB_KEY_Armenian_VEV },
+ { "Armenian_vev", XKB_KEY_Armenian_vev },
+ { "Armenian_VO", XKB_KEY_Armenian_VO },
+ { "Armenian_vo", XKB_KEY_Armenian_vo },
+ { "Armenian_VYUN", XKB_KEY_Armenian_VYUN },
+ { "Armenian_vyun", XKB_KEY_Armenian_vyun },
+ { "Armenian_YECH", XKB_KEY_Armenian_YECH },
+ { "Armenian_yech", XKB_KEY_Armenian_yech },
+ { "Armenian_yentamna", XKB_KEY_Armenian_yentamna },
+ { "Armenian_ZA", XKB_KEY_Armenian_ZA },
+ { "Armenian_za", XKB_KEY_Armenian_za },
+ { "Armenian_ZHE", XKB_KEY_Armenian_ZHE },
+ { "Armenian_zhe", XKB_KEY_Armenian_zhe },
+ { "asciicircum", XKB_KEY_asciicircum },
+ { "asciitilde", XKB_KEY_asciitilde },
+ { "asterisk", XKB_KEY_asterisk },
+ { "at", XKB_KEY_at },
+ { "Atilde", XKB_KEY_Atilde },
+ { "atilde", XKB_KEY_atilde },
+ { "AudibleBell_Enable", XKB_KEY_AudibleBell_Enable },
+ { "B", XKB_KEY_B },
+ { "b", XKB_KEY_b },
+ { "Babovedot", XKB_KEY_Babovedot },
+ { "babovedot", XKB_KEY_babovedot },
+ { "backslash", XKB_KEY_backslash },
+ { "BackSpace", XKB_KEY_BackSpace },
+ { "BackTab", XKB_KEY_BackTab },
+ { "ballotcross", XKB_KEY_ballotcross },
+ { "bar", XKB_KEY_bar },
+ { "because", XKB_KEY_because },
+ { "Begin", XKB_KEY_Begin },
+ { "blank", XKB_KEY_blank },
+ { "block", XKB_KEY_block },
+ { "botintegral", XKB_KEY_botintegral },
+ { "botleftparens", XKB_KEY_botleftparens },
+ { "botleftsqbracket", XKB_KEY_botleftsqbracket },
+ { "botleftsummation", XKB_KEY_botleftsummation },
+ { "botrightparens", XKB_KEY_botrightparens },
+ { "botrightsqbracket", XKB_KEY_botrightsqbracket },
+ { "botrightsummation", XKB_KEY_botrightsummation },
+ { "bott", XKB_KEY_bott },
+ { "botvertsummationconnector", XKB_KEY_botvertsummationconnector },
+ { "BounceKeys_Enable", XKB_KEY_BounceKeys_Enable },
+ { "braceleft", XKB_KEY_braceleft },
+ { "braceright", XKB_KEY_braceright },
+ { "bracketleft", XKB_KEY_bracketleft },
+ { "bracketright", XKB_KEY_bracketright },
+ { "braille_blank", XKB_KEY_braille_blank },
+ { "braille_dot_1", XKB_KEY_braille_dot_1 },
+ { "braille_dot_10", XKB_KEY_braille_dot_10 },
+ { "braille_dot_2", XKB_KEY_braille_dot_2 },
+ { "braille_dot_3", XKB_KEY_braille_dot_3 },
+ { "braille_dot_4", XKB_KEY_braille_dot_4 },
+ { "braille_dot_5", XKB_KEY_braille_dot_5 },
+ { "braille_dot_6", XKB_KEY_braille_dot_6 },
+ { "braille_dot_7", XKB_KEY_braille_dot_7 },
+ { "braille_dot_8", XKB_KEY_braille_dot_8 },
+ { "braille_dot_9", XKB_KEY_braille_dot_9 },
+ { "braille_dots_1", XKB_KEY_braille_dots_1 },
+ { "braille_dots_12", XKB_KEY_braille_dots_12 },
+ { "braille_dots_123", XKB_KEY_braille_dots_123 },
+ { "braille_dots_1234", XKB_KEY_braille_dots_1234 },
+ { "braille_dots_12345", XKB_KEY_braille_dots_12345 },
+ { "braille_dots_123456", XKB_KEY_braille_dots_123456 },
+ { "braille_dots_1234567", XKB_KEY_braille_dots_1234567 },
+ { "braille_dots_12345678", XKB_KEY_braille_dots_12345678 },
+ { "braille_dots_1234568", XKB_KEY_braille_dots_1234568 },
+ { "braille_dots_123457", XKB_KEY_braille_dots_123457 },
+ { "braille_dots_1234578", XKB_KEY_braille_dots_1234578 },
+ { "braille_dots_123458", XKB_KEY_braille_dots_123458 },
+ { "braille_dots_12346", XKB_KEY_braille_dots_12346 },
+ { "braille_dots_123467", XKB_KEY_braille_dots_123467 },
+ { "braille_dots_1234678", XKB_KEY_braille_dots_1234678 },
+ { "braille_dots_123468", XKB_KEY_braille_dots_123468 },
+ { "braille_dots_12347", XKB_KEY_braille_dots_12347 },
+ { "braille_dots_123478", XKB_KEY_braille_dots_123478 },
+ { "braille_dots_12348", XKB_KEY_braille_dots_12348 },
+ { "braille_dots_1235", XKB_KEY_braille_dots_1235 },
+ { "braille_dots_12356", XKB_KEY_braille_dots_12356 },
+ { "braille_dots_123567", XKB_KEY_braille_dots_123567 },
+ { "braille_dots_1235678", XKB_KEY_braille_dots_1235678 },
+ { "braille_dots_123568", XKB_KEY_braille_dots_123568 },
+ { "braille_dots_12357", XKB_KEY_braille_dots_12357 },
+ { "braille_dots_123578", XKB_KEY_braille_dots_123578 },
+ { "braille_dots_12358", XKB_KEY_braille_dots_12358 },
+ { "braille_dots_1236", XKB_KEY_braille_dots_1236 },
+ { "braille_dots_12367", XKB_KEY_braille_dots_12367 },
+ { "braille_dots_123678", XKB_KEY_braille_dots_123678 },
+ { "braille_dots_12368", XKB_KEY_braille_dots_12368 },
+ { "braille_dots_1237", XKB_KEY_braille_dots_1237 },
+ { "braille_dots_12378", XKB_KEY_braille_dots_12378 },
+ { "braille_dots_1238", XKB_KEY_braille_dots_1238 },
+ { "braille_dots_124", XKB_KEY_braille_dots_124 },
+ { "braille_dots_1245", XKB_KEY_braille_dots_1245 },
+ { "braille_dots_12456", XKB_KEY_braille_dots_12456 },
+ { "braille_dots_124567", XKB_KEY_braille_dots_124567 },
+ { "braille_dots_1245678", XKB_KEY_braille_dots_1245678 },
+ { "braille_dots_124568", XKB_KEY_braille_dots_124568 },
+ { "braille_dots_12457", XKB_KEY_braille_dots_12457 },
+ { "braille_dots_124578", XKB_KEY_braille_dots_124578 },
+ { "braille_dots_12458", XKB_KEY_braille_dots_12458 },
+ { "braille_dots_1246", XKB_KEY_braille_dots_1246 },
+ { "braille_dots_12467", XKB_KEY_braille_dots_12467 },
+ { "braille_dots_124678", XKB_KEY_braille_dots_124678 },
+ { "braille_dots_12468", XKB_KEY_braille_dots_12468 },
+ { "braille_dots_1247", XKB_KEY_braille_dots_1247 },
+ { "braille_dots_12478", XKB_KEY_braille_dots_12478 },
+ { "braille_dots_1248", XKB_KEY_braille_dots_1248 },
+ { "braille_dots_125", XKB_KEY_braille_dots_125 },
+ { "braille_dots_1256", XKB_KEY_braille_dots_1256 },
+ { "braille_dots_12567", XKB_KEY_braille_dots_12567 },
+ { "braille_dots_125678", XKB_KEY_braille_dots_125678 },
+ { "braille_dots_12568", XKB_KEY_braille_dots_12568 },
+ { "braille_dots_1257", XKB_KEY_braille_dots_1257 },
+ { "braille_dots_12578", XKB_KEY_braille_dots_12578 },
+ { "braille_dots_1258", XKB_KEY_braille_dots_1258 },
+ { "braille_dots_126", XKB_KEY_braille_dots_126 },
+ { "braille_dots_1267", XKB_KEY_braille_dots_1267 },
+ { "braille_dots_12678", XKB_KEY_braille_dots_12678 },
+ { "braille_dots_1268", XKB_KEY_braille_dots_1268 },
+ { "braille_dots_127", XKB_KEY_braille_dots_127 },
+ { "braille_dots_1278", XKB_KEY_braille_dots_1278 },
+ { "braille_dots_128", XKB_KEY_braille_dots_128 },
+ { "braille_dots_13", XKB_KEY_braille_dots_13 },
+ { "braille_dots_134", XKB_KEY_braille_dots_134 },
+ { "braille_dots_1345", XKB_KEY_braille_dots_1345 },
+ { "braille_dots_13456", XKB_KEY_braille_dots_13456 },
+ { "braille_dots_134567", XKB_KEY_braille_dots_134567 },
+ { "braille_dots_1345678", XKB_KEY_braille_dots_1345678 },
+ { "braille_dots_134568", XKB_KEY_braille_dots_134568 },
+ { "braille_dots_13457", XKB_KEY_braille_dots_13457 },
+ { "braille_dots_134578", XKB_KEY_braille_dots_134578 },
+ { "braille_dots_13458", XKB_KEY_braille_dots_13458 },
+ { "braille_dots_1346", XKB_KEY_braille_dots_1346 },
+ { "braille_dots_13467", XKB_KEY_braille_dots_13467 },
+ { "braille_dots_134678", XKB_KEY_braille_dots_134678 },
+ { "braille_dots_13468", XKB_KEY_braille_dots_13468 },
+ { "braille_dots_1347", XKB_KEY_braille_dots_1347 },
+ { "braille_dots_13478", XKB_KEY_braille_dots_13478 },
+ { "braille_dots_1348", XKB_KEY_braille_dots_1348 },
+ { "braille_dots_135", XKB_KEY_braille_dots_135 },
+ { "braille_dots_1356", XKB_KEY_braille_dots_1356 },
+ { "braille_dots_13567", XKB_KEY_braille_dots_13567 },
+ { "braille_dots_135678", XKB_KEY_braille_dots_135678 },
+ { "braille_dots_13568", XKB_KEY_braille_dots_13568 },
+ { "braille_dots_1357", XKB_KEY_braille_dots_1357 },
+ { "braille_dots_13578", XKB_KEY_braille_dots_13578 },
+ { "braille_dots_1358", XKB_KEY_braille_dots_1358 },
+ { "braille_dots_136", XKB_KEY_braille_dots_136 },
+ { "braille_dots_1367", XKB_KEY_braille_dots_1367 },
+ { "braille_dots_13678", XKB_KEY_braille_dots_13678 },
+ { "braille_dots_1368", XKB_KEY_braille_dots_1368 },
+ { "braille_dots_137", XKB_KEY_braille_dots_137 },
+ { "braille_dots_1378", XKB_KEY_braille_dots_1378 },
+ { "braille_dots_138", XKB_KEY_braille_dots_138 },
+ { "braille_dots_14", XKB_KEY_braille_dots_14 },
+ { "braille_dots_145", XKB_KEY_braille_dots_145 },
+ { "braille_dots_1456", XKB_KEY_braille_dots_1456 },
+ { "braille_dots_14567", XKB_KEY_braille_dots_14567 },
+ { "braille_dots_145678", XKB_KEY_braille_dots_145678 },
+ { "braille_dots_14568", XKB_KEY_braille_dots_14568 },
+ { "braille_dots_1457", XKB_KEY_braille_dots_1457 },
+ { "braille_dots_14578", XKB_KEY_braille_dots_14578 },
+ { "braille_dots_1458", XKB_KEY_braille_dots_1458 },
+ { "braille_dots_146", XKB_KEY_braille_dots_146 },
+ { "braille_dots_1467", XKB_KEY_braille_dots_1467 },
+ { "braille_dots_14678", XKB_KEY_braille_dots_14678 },
+ { "braille_dots_1468", XKB_KEY_braille_dots_1468 },
+ { "braille_dots_147", XKB_KEY_braille_dots_147 },
+ { "braille_dots_1478", XKB_KEY_braille_dots_1478 },
+ { "braille_dots_148", XKB_KEY_braille_dots_148 },
+ { "braille_dots_15", XKB_KEY_braille_dots_15 },
+ { "braille_dots_156", XKB_KEY_braille_dots_156 },
+ { "braille_dots_1567", XKB_KEY_braille_dots_1567 },
+ { "braille_dots_15678", XKB_KEY_braille_dots_15678 },
+ { "braille_dots_1568", XKB_KEY_braille_dots_1568 },
+ { "braille_dots_157", XKB_KEY_braille_dots_157 },
+ { "braille_dots_1578", XKB_KEY_braille_dots_1578 },
+ { "braille_dots_158", XKB_KEY_braille_dots_158 },
+ { "braille_dots_16", XKB_KEY_braille_dots_16 },
+ { "braille_dots_167", XKB_KEY_braille_dots_167 },
+ { "braille_dots_1678", XKB_KEY_braille_dots_1678 },
+ { "braille_dots_168", XKB_KEY_braille_dots_168 },
+ { "braille_dots_17", XKB_KEY_braille_dots_17 },
+ { "braille_dots_178", XKB_KEY_braille_dots_178 },
+ { "braille_dots_18", XKB_KEY_braille_dots_18 },
+ { "braille_dots_2", XKB_KEY_braille_dots_2 },
+ { "braille_dots_23", XKB_KEY_braille_dots_23 },
+ { "braille_dots_234", XKB_KEY_braille_dots_234 },
+ { "braille_dots_2345", XKB_KEY_braille_dots_2345 },
+ { "braille_dots_23456", XKB_KEY_braille_dots_23456 },
+ { "braille_dots_234567", XKB_KEY_braille_dots_234567 },
+ { "braille_dots_2345678", XKB_KEY_braille_dots_2345678 },
+ { "braille_dots_234568", XKB_KEY_braille_dots_234568 },
+ { "braille_dots_23457", XKB_KEY_braille_dots_23457 },
+ { "braille_dots_234578", XKB_KEY_braille_dots_234578 },
+ { "braille_dots_23458", XKB_KEY_braille_dots_23458 },
+ { "braille_dots_2346", XKB_KEY_braille_dots_2346 },
+ { "braille_dots_23467", XKB_KEY_braille_dots_23467 },
+ { "braille_dots_234678", XKB_KEY_braille_dots_234678 },
+ { "braille_dots_23468", XKB_KEY_braille_dots_23468 },
+ { "braille_dots_2347", XKB_KEY_braille_dots_2347 },
+ { "braille_dots_23478", XKB_KEY_braille_dots_23478 },
+ { "braille_dots_2348", XKB_KEY_braille_dots_2348 },
+ { "braille_dots_235", XKB_KEY_braille_dots_235 },
+ { "braille_dots_2356", XKB_KEY_braille_dots_2356 },
+ { "braille_dots_23567", XKB_KEY_braille_dots_23567 },
+ { "braille_dots_235678", XKB_KEY_braille_dots_235678 },
+ { "braille_dots_23568", XKB_KEY_braille_dots_23568 },
+ { "braille_dots_2357", XKB_KEY_braille_dots_2357 },
+ { "braille_dots_23578", XKB_KEY_braille_dots_23578 },
+ { "braille_dots_2358", XKB_KEY_braille_dots_2358 },
+ { "braille_dots_236", XKB_KEY_braille_dots_236 },
+ { "braille_dots_2367", XKB_KEY_braille_dots_2367 },
+ { "braille_dots_23678", XKB_KEY_braille_dots_23678 },
+ { "braille_dots_2368", XKB_KEY_braille_dots_2368 },
+ { "braille_dots_237", XKB_KEY_braille_dots_237 },
+ { "braille_dots_2378", XKB_KEY_braille_dots_2378 },
+ { "braille_dots_238", XKB_KEY_braille_dots_238 },
+ { "braille_dots_24", XKB_KEY_braille_dots_24 },
+ { "braille_dots_245", XKB_KEY_braille_dots_245 },
+ { "braille_dots_2456", XKB_KEY_braille_dots_2456 },
+ { "braille_dots_24567", XKB_KEY_braille_dots_24567 },
+ { "braille_dots_245678", XKB_KEY_braille_dots_245678 },
+ { "braille_dots_24568", XKB_KEY_braille_dots_24568 },
+ { "braille_dots_2457", XKB_KEY_braille_dots_2457 },
+ { "braille_dots_24578", XKB_KEY_braille_dots_24578 },
+ { "braille_dots_2458", XKB_KEY_braille_dots_2458 },
+ { "braille_dots_246", XKB_KEY_braille_dots_246 },
+ { "braille_dots_2467", XKB_KEY_braille_dots_2467 },
+ { "braille_dots_24678", XKB_KEY_braille_dots_24678 },
+ { "braille_dots_2468", XKB_KEY_braille_dots_2468 },
+ { "braille_dots_247", XKB_KEY_braille_dots_247 },
+ { "braille_dots_2478", XKB_KEY_braille_dots_2478 },
+ { "braille_dots_248", XKB_KEY_braille_dots_248 },
+ { "braille_dots_25", XKB_KEY_braille_dots_25 },
+ { "braille_dots_256", XKB_KEY_braille_dots_256 },
+ { "braille_dots_2567", XKB_KEY_braille_dots_2567 },
+ { "braille_dots_25678", XKB_KEY_braille_dots_25678 },
+ { "braille_dots_2568", XKB_KEY_braille_dots_2568 },
+ { "braille_dots_257", XKB_KEY_braille_dots_257 },
+ { "braille_dots_2578", XKB_KEY_braille_dots_2578 },
+ { "braille_dots_258", XKB_KEY_braille_dots_258 },
+ { "braille_dots_26", XKB_KEY_braille_dots_26 },
+ { "braille_dots_267", XKB_KEY_braille_dots_267 },
+ { "braille_dots_2678", XKB_KEY_braille_dots_2678 },
+ { "braille_dots_268", XKB_KEY_braille_dots_268 },
+ { "braille_dots_27", XKB_KEY_braille_dots_27 },
+ { "braille_dots_278", XKB_KEY_braille_dots_278 },
+ { "braille_dots_28", XKB_KEY_braille_dots_28 },
+ { "braille_dots_3", XKB_KEY_braille_dots_3 },
+ { "braille_dots_34", XKB_KEY_braille_dots_34 },
+ { "braille_dots_345", XKB_KEY_braille_dots_345 },
+ { "braille_dots_3456", XKB_KEY_braille_dots_3456 },
+ { "braille_dots_34567", XKB_KEY_braille_dots_34567 },
+ { "braille_dots_345678", XKB_KEY_braille_dots_345678 },
+ { "braille_dots_34568", XKB_KEY_braille_dots_34568 },
+ { "braille_dots_3457", XKB_KEY_braille_dots_3457 },
+ { "braille_dots_34578", XKB_KEY_braille_dots_34578 },
+ { "braille_dots_3458", XKB_KEY_braille_dots_3458 },
+ { "braille_dots_346", XKB_KEY_braille_dots_346 },
+ { "braille_dots_3467", XKB_KEY_braille_dots_3467 },
+ { "braille_dots_34678", XKB_KEY_braille_dots_34678 },
+ { "braille_dots_3468", XKB_KEY_braille_dots_3468 },
+ { "braille_dots_347", XKB_KEY_braille_dots_347 },
+ { "braille_dots_3478", XKB_KEY_braille_dots_3478 },
+ { "braille_dots_348", XKB_KEY_braille_dots_348 },
+ { "braille_dots_35", XKB_KEY_braille_dots_35 },
+ { "braille_dots_356", XKB_KEY_braille_dots_356 },
+ { "braille_dots_3567", XKB_KEY_braille_dots_3567 },
+ { "braille_dots_35678", XKB_KEY_braille_dots_35678 },
+ { "braille_dots_3568", XKB_KEY_braille_dots_3568 },
+ { "braille_dots_357", XKB_KEY_braille_dots_357 },
+ { "braille_dots_3578", XKB_KEY_braille_dots_3578 },
+ { "braille_dots_358", XKB_KEY_braille_dots_358 },
+ { "braille_dots_36", XKB_KEY_braille_dots_36 },
+ { "braille_dots_367", XKB_KEY_braille_dots_367 },
+ { "braille_dots_3678", XKB_KEY_braille_dots_3678 },
+ { "braille_dots_368", XKB_KEY_braille_dots_368 },
+ { "braille_dots_37", XKB_KEY_braille_dots_37 },
+ { "braille_dots_378", XKB_KEY_braille_dots_378 },
+ { "braille_dots_38", XKB_KEY_braille_dots_38 },
+ { "braille_dots_4", XKB_KEY_braille_dots_4 },
+ { "braille_dots_45", XKB_KEY_braille_dots_45 },
+ { "braille_dots_456", XKB_KEY_braille_dots_456 },
+ { "braille_dots_4567", XKB_KEY_braille_dots_4567 },
+ { "braille_dots_45678", XKB_KEY_braille_dots_45678 },
+ { "braille_dots_4568", XKB_KEY_braille_dots_4568 },
+ { "braille_dots_457", XKB_KEY_braille_dots_457 },
+ { "braille_dots_4578", XKB_KEY_braille_dots_4578 },
+ { "braille_dots_458", XKB_KEY_braille_dots_458 },
+ { "braille_dots_46", XKB_KEY_braille_dots_46 },
+ { "braille_dots_467", XKB_KEY_braille_dots_467 },
+ { "braille_dots_4678", XKB_KEY_braille_dots_4678 },
+ { "braille_dots_468", XKB_KEY_braille_dots_468 },
+ { "braille_dots_47", XKB_KEY_braille_dots_47 },
+ { "braille_dots_478", XKB_KEY_braille_dots_478 },
+ { "braille_dots_48", XKB_KEY_braille_dots_48 },
+ { "braille_dots_5", XKB_KEY_braille_dots_5 },
+ { "braille_dots_56", XKB_KEY_braille_dots_56 },
+ { "braille_dots_567", XKB_KEY_braille_dots_567 },
+ { "braille_dots_5678", XKB_KEY_braille_dots_5678 },
+ { "braille_dots_568", XKB_KEY_braille_dots_568 },
+ { "braille_dots_57", XKB_KEY_braille_dots_57 },
+ { "braille_dots_578", XKB_KEY_braille_dots_578 },
+ { "braille_dots_58", XKB_KEY_braille_dots_58 },
+ { "braille_dots_6", XKB_KEY_braille_dots_6 },
+ { "braille_dots_67", XKB_KEY_braille_dots_67 },
+ { "braille_dots_678", XKB_KEY_braille_dots_678 },
+ { "braille_dots_68", XKB_KEY_braille_dots_68 },
+ { "braille_dots_7", XKB_KEY_braille_dots_7 },
+ { "braille_dots_78", XKB_KEY_braille_dots_78 },
+ { "braille_dots_8", XKB_KEY_braille_dots_8 },
+ { "Break", XKB_KEY_Break },
+ { "breve", XKB_KEY_breve },
+ { "brokenbar", XKB_KEY_brokenbar },
+ { "Byelorussian_shortu", XKB_KEY_Byelorussian_shortu },
+ { "Byelorussian_SHORTU", XKB_KEY_Byelorussian_SHORTU },
+ { "C", XKB_KEY_C },
+ { "c", XKB_KEY_c },
+ { "c_h", XKB_KEY_c_h },
+ { "C_h", XKB_KEY_C_h },
+ { "C_H", XKB_KEY_C_H },
+ { "Cabovedot", XKB_KEY_Cabovedot },
+ { "cabovedot", XKB_KEY_cabovedot },
+ { "Cacute", XKB_KEY_Cacute },
+ { "cacute", XKB_KEY_cacute },
+ { "Cancel", XKB_KEY_Cancel },
+ { "Caps_Lock", XKB_KEY_Caps_Lock },
+ { "careof", XKB_KEY_careof },
+ { "caret", XKB_KEY_caret },
+ { "caron", XKB_KEY_caron },
+ { "Ccaron", XKB_KEY_Ccaron },
+ { "ccaron", XKB_KEY_ccaron },
+ { "Ccedilla", XKB_KEY_Ccedilla },
+ { "ccedilla", XKB_KEY_ccedilla },
+ { "Ccircumflex", XKB_KEY_Ccircumflex },
+ { "ccircumflex", XKB_KEY_ccircumflex },
+ { "cedilla", XKB_KEY_cedilla },
+ { "cent", XKB_KEY_cent },
+ { "ch", XKB_KEY_ch },
+ { "Ch", XKB_KEY_Ch },
+ { "CH", XKB_KEY_CH },
+ { "checkerboard", XKB_KEY_checkerboard },
+ { "checkmark", XKB_KEY_checkmark },
+ { "circle", XKB_KEY_circle },
+ { "Clear", XKB_KEY_Clear },
+ { "ClearLine", XKB_KEY_ClearLine },
+ { "club", XKB_KEY_club },
+ { "Codeinput", XKB_KEY_Codeinput },
+ { "colon", XKB_KEY_colon },
+ { "ColonSign", XKB_KEY_ColonSign },
+ { "comma", XKB_KEY_comma },
+ { "containsas", XKB_KEY_containsas },
+ { "Control_L", XKB_KEY_Control_L },
+ { "Control_R", XKB_KEY_Control_R },
+ { "copyright", XKB_KEY_copyright },
+ { "cr", XKB_KEY_cr },
+ { "crossinglines", XKB_KEY_crossinglines },
+ { "CruzeiroSign", XKB_KEY_CruzeiroSign },
+ { "cuberoot", XKB_KEY_cuberoot },
+ { "currency", XKB_KEY_currency },
+ { "cursor", XKB_KEY_cursor },
+ { "Cyrillic_a", XKB_KEY_Cyrillic_a },
+ { "Cyrillic_A", XKB_KEY_Cyrillic_A },
+ { "Cyrillic_be", XKB_KEY_Cyrillic_be },
+ { "Cyrillic_BE", XKB_KEY_Cyrillic_BE },
+ { "Cyrillic_che", XKB_KEY_Cyrillic_che },
+ { "Cyrillic_CHE", XKB_KEY_Cyrillic_CHE },
+ { "Cyrillic_CHE_descender", XKB_KEY_Cyrillic_CHE_descender },
+ { "Cyrillic_che_descender", XKB_KEY_Cyrillic_che_descender },
+ { "Cyrillic_CHE_vertstroke", XKB_KEY_Cyrillic_CHE_vertstroke },
+ { "Cyrillic_che_vertstroke", XKB_KEY_Cyrillic_che_vertstroke },
+ { "Cyrillic_de", XKB_KEY_Cyrillic_de },
+ { "Cyrillic_DE", XKB_KEY_Cyrillic_DE },
+ { "Cyrillic_dzhe", XKB_KEY_Cyrillic_dzhe },
+ { "Cyrillic_DZHE", XKB_KEY_Cyrillic_DZHE },
+ { "Cyrillic_e", XKB_KEY_Cyrillic_e },
+ { "Cyrillic_E", XKB_KEY_Cyrillic_E },
+ { "Cyrillic_ef", XKB_KEY_Cyrillic_ef },
+ { "Cyrillic_EF", XKB_KEY_Cyrillic_EF },
+ { "Cyrillic_el", XKB_KEY_Cyrillic_el },
+ { "Cyrillic_EL", XKB_KEY_Cyrillic_EL },
+ { "Cyrillic_em", XKB_KEY_Cyrillic_em },
+ { "Cyrillic_EM", XKB_KEY_Cyrillic_EM },
+ { "Cyrillic_en", XKB_KEY_Cyrillic_en },
+ { "Cyrillic_EN", XKB_KEY_Cyrillic_EN },
+ { "Cyrillic_EN_descender", XKB_KEY_Cyrillic_EN_descender },
+ { "Cyrillic_en_descender", XKB_KEY_Cyrillic_en_descender },
+ { "Cyrillic_er", XKB_KEY_Cyrillic_er },
+ { "Cyrillic_ER", XKB_KEY_Cyrillic_ER },
+ { "Cyrillic_es", XKB_KEY_Cyrillic_es },
+ { "Cyrillic_ES", XKB_KEY_Cyrillic_ES },
+ { "Cyrillic_ghe", XKB_KEY_Cyrillic_ghe },
+ { "Cyrillic_GHE", XKB_KEY_Cyrillic_GHE },
+ { "Cyrillic_GHE_bar", XKB_KEY_Cyrillic_GHE_bar },
+ { "Cyrillic_ghe_bar", XKB_KEY_Cyrillic_ghe_bar },
+ { "Cyrillic_ha", XKB_KEY_Cyrillic_ha },
+ { "Cyrillic_HA", XKB_KEY_Cyrillic_HA },
+ { "Cyrillic_HA_descender", XKB_KEY_Cyrillic_HA_descender },
+ { "Cyrillic_ha_descender", XKB_KEY_Cyrillic_ha_descender },
+ { "Cyrillic_hardsign", XKB_KEY_Cyrillic_hardsign },
+ { "Cyrillic_HARDSIGN", XKB_KEY_Cyrillic_HARDSIGN },
+ { "Cyrillic_i", XKB_KEY_Cyrillic_i },
+ { "Cyrillic_I", XKB_KEY_Cyrillic_I },
+ { "Cyrillic_I_macron", XKB_KEY_Cyrillic_I_macron },
+ { "Cyrillic_i_macron", XKB_KEY_Cyrillic_i_macron },
+ { "Cyrillic_ie", XKB_KEY_Cyrillic_ie },
+ { "Cyrillic_IE", XKB_KEY_Cyrillic_IE },
+ { "Cyrillic_io", XKB_KEY_Cyrillic_io },
+ { "Cyrillic_IO", XKB_KEY_Cyrillic_IO },
+ { "Cyrillic_je", XKB_KEY_Cyrillic_je },
+ { "Cyrillic_JE", XKB_KEY_Cyrillic_JE },
+ { "Cyrillic_ka", XKB_KEY_Cyrillic_ka },
+ { "Cyrillic_KA", XKB_KEY_Cyrillic_KA },
+ { "Cyrillic_KA_descender", XKB_KEY_Cyrillic_KA_descender },
+ { "Cyrillic_ka_descender", XKB_KEY_Cyrillic_ka_descender },
+ { "Cyrillic_KA_vertstroke", XKB_KEY_Cyrillic_KA_vertstroke },
+ { "Cyrillic_ka_vertstroke", XKB_KEY_Cyrillic_ka_vertstroke },
+ { "Cyrillic_lje", XKB_KEY_Cyrillic_lje },
+ { "Cyrillic_LJE", XKB_KEY_Cyrillic_LJE },
+ { "Cyrillic_nje", XKB_KEY_Cyrillic_nje },
+ { "Cyrillic_NJE", XKB_KEY_Cyrillic_NJE },
+ { "Cyrillic_o", XKB_KEY_Cyrillic_o },
+ { "Cyrillic_O", XKB_KEY_Cyrillic_O },
+ { "Cyrillic_O_bar", XKB_KEY_Cyrillic_O_bar },
+ { "Cyrillic_o_bar", XKB_KEY_Cyrillic_o_bar },
+ { "Cyrillic_pe", XKB_KEY_Cyrillic_pe },
+ { "Cyrillic_PE", XKB_KEY_Cyrillic_PE },
+ { "Cyrillic_SCHWA", XKB_KEY_Cyrillic_SCHWA },
+ { "Cyrillic_schwa", XKB_KEY_Cyrillic_schwa },
+ { "Cyrillic_sha", XKB_KEY_Cyrillic_sha },
+ { "Cyrillic_SHA", XKB_KEY_Cyrillic_SHA },
+ { "Cyrillic_shcha", XKB_KEY_Cyrillic_shcha },
+ { "Cyrillic_SHCHA", XKB_KEY_Cyrillic_SHCHA },
+ { "Cyrillic_SHHA", XKB_KEY_Cyrillic_SHHA },
+ { "Cyrillic_shha", XKB_KEY_Cyrillic_shha },
+ { "Cyrillic_shorti", XKB_KEY_Cyrillic_shorti },
+ { "Cyrillic_SHORTI", XKB_KEY_Cyrillic_SHORTI },
+ { "Cyrillic_softsign", XKB_KEY_Cyrillic_softsign },
+ { "Cyrillic_SOFTSIGN", XKB_KEY_Cyrillic_SOFTSIGN },
+ { "Cyrillic_te", XKB_KEY_Cyrillic_te },
+ { "Cyrillic_TE", XKB_KEY_Cyrillic_TE },
+ { "Cyrillic_tse", XKB_KEY_Cyrillic_tse },
+ { "Cyrillic_TSE", XKB_KEY_Cyrillic_TSE },
+ { "Cyrillic_u", XKB_KEY_Cyrillic_u },
+ { "Cyrillic_U", XKB_KEY_Cyrillic_U },
+ { "Cyrillic_U_macron", XKB_KEY_Cyrillic_U_macron },
+ { "Cyrillic_u_macron", XKB_KEY_Cyrillic_u_macron },
+ { "Cyrillic_U_straight", XKB_KEY_Cyrillic_U_straight },
+ { "Cyrillic_u_straight", XKB_KEY_Cyrillic_u_straight },
+ { "Cyrillic_U_straight_bar", XKB_KEY_Cyrillic_U_straight_bar },
+ { "Cyrillic_u_straight_bar", XKB_KEY_Cyrillic_u_straight_bar },
+ { "Cyrillic_ve", XKB_KEY_Cyrillic_ve },
+ { "Cyrillic_VE", XKB_KEY_Cyrillic_VE },
+ { "Cyrillic_ya", XKB_KEY_Cyrillic_ya },
+ { "Cyrillic_YA", XKB_KEY_Cyrillic_YA },
+ { "Cyrillic_yeru", XKB_KEY_Cyrillic_yeru },
+ { "Cyrillic_YERU", XKB_KEY_Cyrillic_YERU },
+ { "Cyrillic_yu", XKB_KEY_Cyrillic_yu },
+ { "Cyrillic_YU", XKB_KEY_Cyrillic_YU },
+ { "Cyrillic_ze", XKB_KEY_Cyrillic_ze },
+ { "Cyrillic_ZE", XKB_KEY_Cyrillic_ZE },
+ { "Cyrillic_zhe", XKB_KEY_Cyrillic_zhe },
+ { "Cyrillic_ZHE", XKB_KEY_Cyrillic_ZHE },
+ { "Cyrillic_ZHE_descender", XKB_KEY_Cyrillic_ZHE_descender },
+ { "Cyrillic_zhe_descender", XKB_KEY_Cyrillic_zhe_descender },
+ { "D", XKB_KEY_D },
+ { "d", XKB_KEY_d },
+ { "Dabovedot", XKB_KEY_Dabovedot },
+ { "dabovedot", XKB_KEY_dabovedot },
+ { "Dacute_accent", XKB_KEY_Dacute_accent },
+ { "dagger", XKB_KEY_dagger },
+ { "Dcaron", XKB_KEY_Dcaron },
+ { "dcaron", XKB_KEY_dcaron },
+ { "Dcedilla_accent", XKB_KEY_Dcedilla_accent },
+ { "Dcircumflex_accent", XKB_KEY_Dcircumflex_accent },
+ { "Ddiaeresis", XKB_KEY_Ddiaeresis },
+ { "dead_a", XKB_KEY_dead_a },
+ { "dead_A", XKB_KEY_dead_A },
+ { "dead_abovecomma", XKB_KEY_dead_abovecomma },
+ { "dead_abovedot", XKB_KEY_dead_abovedot },
+ { "dead_abovereversedcomma", XKB_KEY_dead_abovereversedcomma },
+ { "dead_abovering", XKB_KEY_dead_abovering },
+ { "dead_acute", XKB_KEY_dead_acute },
+ { "dead_belowbreve", XKB_KEY_dead_belowbreve },
+ { "dead_belowcircumflex", XKB_KEY_dead_belowcircumflex },
+ { "dead_belowcomma", XKB_KEY_dead_belowcomma },
+ { "dead_belowdiaeresis", XKB_KEY_dead_belowdiaeresis },
+ { "dead_belowdot", XKB_KEY_dead_belowdot },
+ { "dead_belowmacron", XKB_KEY_dead_belowmacron },
+ { "dead_belowring", XKB_KEY_dead_belowring },
+ { "dead_belowtilde", XKB_KEY_dead_belowtilde },
+ { "dead_breve", XKB_KEY_dead_breve },
+ { "dead_capital_schwa", XKB_KEY_dead_capital_schwa },
+ { "dead_caron", XKB_KEY_dead_caron },
+ { "dead_cedilla", XKB_KEY_dead_cedilla },
+ { "dead_circumflex", XKB_KEY_dead_circumflex },
+ { "dead_currency", XKB_KEY_dead_currency },
+ { "dead_dasia", XKB_KEY_dead_dasia },
+ { "dead_diaeresis", XKB_KEY_dead_diaeresis },
+ { "dead_doubleacute", XKB_KEY_dead_doubleacute },
+ { "dead_doublegrave", XKB_KEY_dead_doublegrave },
+ { "dead_e", XKB_KEY_dead_e },
+ { "dead_E", XKB_KEY_dead_E },
+ { "dead_grave", XKB_KEY_dead_grave },
+ { "dead_greek", XKB_KEY_dead_greek },
+ { "dead_hook", XKB_KEY_dead_hook },
+ { "dead_horn", XKB_KEY_dead_horn },
+ { "dead_i", XKB_KEY_dead_i },
+ { "dead_I", XKB_KEY_dead_I },
+ { "dead_invertedbreve", XKB_KEY_dead_invertedbreve },
+ { "dead_iota", XKB_KEY_dead_iota },
+ { "dead_macron", XKB_KEY_dead_macron },
+ { "dead_o", XKB_KEY_dead_o },
+ { "dead_O", XKB_KEY_dead_O },
+ { "dead_ogonek", XKB_KEY_dead_ogonek },
+ { "dead_perispomeni", XKB_KEY_dead_perispomeni },
+ { "dead_psili", XKB_KEY_dead_psili },
+ { "dead_semivoiced_sound", XKB_KEY_dead_semivoiced_sound },
+ { "dead_small_schwa", XKB_KEY_dead_small_schwa },
+ { "dead_stroke", XKB_KEY_dead_stroke },
+ { "dead_tilde", XKB_KEY_dead_tilde },
+ { "dead_u", XKB_KEY_dead_u },
+ { "dead_U", XKB_KEY_dead_U },
+ { "dead_voiced_sound", XKB_KEY_dead_voiced_sound },
+ { "decimalpoint", XKB_KEY_decimalpoint },
+ { "degree", XKB_KEY_degree },
+ { "Delete", XKB_KEY_Delete },
+ { "DeleteChar", XKB_KEY_DeleteChar },
+ { "DeleteLine", XKB_KEY_DeleteLine },
+ { "Dgrave_accent", XKB_KEY_Dgrave_accent },
+ { "diaeresis", XKB_KEY_diaeresis },
+ { "diamond", XKB_KEY_diamond },
+ { "digitspace", XKB_KEY_digitspace },
+ { "dintegral", XKB_KEY_dintegral },
+ { "division", XKB_KEY_division },
+ { "dollar", XKB_KEY_dollar },
+ { "DongSign", XKB_KEY_DongSign },
+ { "doubbaselinedot", XKB_KEY_doubbaselinedot },
+ { "doubleacute", XKB_KEY_doubleacute },
+ { "doubledagger", XKB_KEY_doubledagger },
+ { "doublelowquotemark", XKB_KEY_doublelowquotemark },
+ { "Down", XKB_KEY_Down },
+ { "downarrow", XKB_KEY_downarrow },
+ { "downcaret", XKB_KEY_downcaret },
+ { "downshoe", XKB_KEY_downshoe },
+ { "downstile", XKB_KEY_downstile },
+ { "downtack", XKB_KEY_downtack },
+ { "DRemove", XKB_KEY_DRemove },
+ { "Dring_accent", XKB_KEY_Dring_accent },
+ { "Dstroke", XKB_KEY_Dstroke },
+ { "dstroke", XKB_KEY_dstroke },
+ { "Dtilde", XKB_KEY_Dtilde },
+ { "E", XKB_KEY_E },
+ { "e", XKB_KEY_e },
+ { "Eabovedot", XKB_KEY_Eabovedot },
+ { "eabovedot", XKB_KEY_eabovedot },
+ { "Eacute", XKB_KEY_Eacute },
+ { "eacute", XKB_KEY_eacute },
+ { "Ebelowdot", XKB_KEY_Ebelowdot },
+ { "ebelowdot", XKB_KEY_ebelowdot },
+ { "Ecaron", XKB_KEY_Ecaron },
+ { "ecaron", XKB_KEY_ecaron },
+ { "Ecircumflex", XKB_KEY_Ecircumflex },
+ { "ecircumflex", XKB_KEY_ecircumflex },
+ { "Ecircumflexacute", XKB_KEY_Ecircumflexacute },
+ { "ecircumflexacute", XKB_KEY_ecircumflexacute },
+ { "Ecircumflexbelowdot", XKB_KEY_Ecircumflexbelowdot },
+ { "ecircumflexbelowdot", XKB_KEY_ecircumflexbelowdot },
+ { "Ecircumflexgrave", XKB_KEY_Ecircumflexgrave },
+ { "ecircumflexgrave", XKB_KEY_ecircumflexgrave },
+ { "Ecircumflexhook", XKB_KEY_Ecircumflexhook },
+ { "ecircumflexhook", XKB_KEY_ecircumflexhook },
+ { "Ecircumflextilde", XKB_KEY_Ecircumflextilde },
+ { "ecircumflextilde", XKB_KEY_ecircumflextilde },
+ { "EcuSign", XKB_KEY_EcuSign },
+ { "Ediaeresis", XKB_KEY_Ediaeresis },
+ { "ediaeresis", XKB_KEY_ediaeresis },
+ { "Egrave", XKB_KEY_Egrave },
+ { "egrave", XKB_KEY_egrave },
+ { "Ehook", XKB_KEY_Ehook },
+ { "ehook", XKB_KEY_ehook },
+ { "eightsubscript", XKB_KEY_eightsubscript },
+ { "eightsuperior", XKB_KEY_eightsuperior },
+ { "Eisu_Shift", XKB_KEY_Eisu_Shift },
+ { "Eisu_toggle", XKB_KEY_Eisu_toggle },
+ { "elementof", XKB_KEY_elementof },
+ { "ellipsis", XKB_KEY_ellipsis },
+ { "em3space", XKB_KEY_em3space },
+ { "em4space", XKB_KEY_em4space },
+ { "Emacron", XKB_KEY_Emacron },
+ { "emacron", XKB_KEY_emacron },
+ { "emdash", XKB_KEY_emdash },
+ { "emfilledcircle", XKB_KEY_emfilledcircle },
+ { "emfilledrect", XKB_KEY_emfilledrect },
+ { "emopencircle", XKB_KEY_emopencircle },
+ { "emopenrectangle", XKB_KEY_emopenrectangle },
+ { "emptyset", XKB_KEY_emptyset },
+ { "emspace", XKB_KEY_emspace },
+ { "End", XKB_KEY_End },
+ { "endash", XKB_KEY_endash },
+ { "enfilledcircbullet", XKB_KEY_enfilledcircbullet },
+ { "enfilledsqbullet", XKB_KEY_enfilledsqbullet },
+ { "ENG", XKB_KEY_ENG },
+ { "eng", XKB_KEY_eng },
+ { "enopencircbullet", XKB_KEY_enopencircbullet },
+ { "enopensquarebullet", XKB_KEY_enopensquarebullet },
+ { "enspace", XKB_KEY_enspace },
+ { "Eogonek", XKB_KEY_Eogonek },
+ { "eogonek", XKB_KEY_eogonek },
+ { "equal", XKB_KEY_equal },
+ { "Escape", XKB_KEY_Escape },
+ { "ETH", XKB_KEY_ETH },
+ { "Eth", XKB_KEY_Eth },
+ { "eth", XKB_KEY_eth },
+ { "Etilde", XKB_KEY_Etilde },
+ { "etilde", XKB_KEY_etilde },
+ { "EuroSign", XKB_KEY_EuroSign },
+ { "exclam", XKB_KEY_exclam },
+ { "exclamdown", XKB_KEY_exclamdown },
+ { "Execute", XKB_KEY_Execute },
+ { "Ext16bit_L", XKB_KEY_Ext16bit_L },
+ { "Ext16bit_R", XKB_KEY_Ext16bit_R },
+ { "EZH", XKB_KEY_EZH },
+ { "ezh", XKB_KEY_ezh },
+ { "F", XKB_KEY_F },
+ { "f", XKB_KEY_f },
+ { "F1", XKB_KEY_F1 },
+ { "F10", XKB_KEY_F10 },
+ { "F11", XKB_KEY_F11 },
+ { "F12", XKB_KEY_F12 },
+ { "F13", XKB_KEY_F13 },
+ { "F14", XKB_KEY_F14 },
+ { "F15", XKB_KEY_F15 },
+ { "F16", XKB_KEY_F16 },
+ { "F17", XKB_KEY_F17 },
+ { "F18", XKB_KEY_F18 },
+ { "F19", XKB_KEY_F19 },
+ { "F2", XKB_KEY_F2 },
+ { "F20", XKB_KEY_F20 },
+ { "F21", XKB_KEY_F21 },
+ { "F22", XKB_KEY_F22 },
+ { "F23", XKB_KEY_F23 },
+ { "F24", XKB_KEY_F24 },
+ { "F25", XKB_KEY_F25 },
+ { "F26", XKB_KEY_F26 },
+ { "F27", XKB_KEY_F27 },
+ { "F28", XKB_KEY_F28 },
+ { "F29", XKB_KEY_F29 },
+ { "F3", XKB_KEY_F3 },
+ { "F30", XKB_KEY_F30 },
+ { "F31", XKB_KEY_F31 },
+ { "F32", XKB_KEY_F32 },
+ { "F33", XKB_KEY_F33 },
+ { "F34", XKB_KEY_F34 },
+ { "F35", XKB_KEY_F35 },
+ { "F4", XKB_KEY_F4 },
+ { "F5", XKB_KEY_F5 },
+ { "F6", XKB_KEY_F6 },
+ { "F7", XKB_KEY_F7 },
+ { "F8", XKB_KEY_F8 },
+ { "F9", XKB_KEY_F9 },
+ { "Fabovedot", XKB_KEY_Fabovedot },
+ { "fabovedot", XKB_KEY_fabovedot },
+ { "Farsi_0", XKB_KEY_Farsi_0 },
+ { "Farsi_1", XKB_KEY_Farsi_1 },
+ { "Farsi_2", XKB_KEY_Farsi_2 },
+ { "Farsi_3", XKB_KEY_Farsi_3 },
+ { "Farsi_4", XKB_KEY_Farsi_4 },
+ { "Farsi_5", XKB_KEY_Farsi_5 },
+ { "Farsi_6", XKB_KEY_Farsi_6 },
+ { "Farsi_7", XKB_KEY_Farsi_7 },
+ { "Farsi_8", XKB_KEY_Farsi_8 },
+ { "Farsi_9", XKB_KEY_Farsi_9 },
+ { "Farsi_yeh", XKB_KEY_Farsi_yeh },
+ { "femalesymbol", XKB_KEY_femalesymbol },
+ { "ff", XKB_KEY_ff },
+ { "FFrancSign", XKB_KEY_FFrancSign },
+ { "figdash", XKB_KEY_figdash },
+ { "filledlefttribullet", XKB_KEY_filledlefttribullet },
+ { "filledrectbullet", XKB_KEY_filledrectbullet },
+ { "filledrighttribullet", XKB_KEY_filledrighttribullet },
+ { "filledtribulletdown", XKB_KEY_filledtribulletdown },
+ { "filledtribulletup", XKB_KEY_filledtribulletup },
+ { "Find", XKB_KEY_Find },
+ { "First_Virtual_Screen", XKB_KEY_First_Virtual_Screen },
+ { "fiveeighths", XKB_KEY_fiveeighths },
+ { "fivesixths", XKB_KEY_fivesixths },
+ { "fivesubscript", XKB_KEY_fivesubscript },
+ { "fivesuperior", XKB_KEY_fivesuperior },
+ { "fourfifths", XKB_KEY_fourfifths },
+ { "foursubscript", XKB_KEY_foursubscript },
+ { "foursuperior", XKB_KEY_foursuperior },
+ { "fourthroot", XKB_KEY_fourthroot },
+ { "function", XKB_KEY_function },
+ { "G", XKB_KEY_G },
+ { "g", XKB_KEY_g },
+ { "Gabovedot", XKB_KEY_Gabovedot },
+ { "gabovedot", XKB_KEY_gabovedot },
+ { "Gbreve", XKB_KEY_Gbreve },
+ { "gbreve", XKB_KEY_gbreve },
+ { "Gcaron", XKB_KEY_Gcaron },
+ { "gcaron", XKB_KEY_gcaron },
+ { "Gcedilla", XKB_KEY_Gcedilla },
+ { "gcedilla", XKB_KEY_gcedilla },
+ { "Gcircumflex", XKB_KEY_Gcircumflex },
+ { "gcircumflex", XKB_KEY_gcircumflex },
+ { "Georgian_an", XKB_KEY_Georgian_an },
+ { "Georgian_ban", XKB_KEY_Georgian_ban },
+ { "Georgian_can", XKB_KEY_Georgian_can },
+ { "Georgian_char", XKB_KEY_Georgian_char },
+ { "Georgian_chin", XKB_KEY_Georgian_chin },
+ { "Georgian_cil", XKB_KEY_Georgian_cil },
+ { "Georgian_don", XKB_KEY_Georgian_don },
+ { "Georgian_en", XKB_KEY_Georgian_en },
+ { "Georgian_fi", XKB_KEY_Georgian_fi },
+ { "Georgian_gan", XKB_KEY_Georgian_gan },
+ { "Georgian_ghan", XKB_KEY_Georgian_ghan },
+ { "Georgian_hae", XKB_KEY_Georgian_hae },
+ { "Georgian_har", XKB_KEY_Georgian_har },
+ { "Georgian_he", XKB_KEY_Georgian_he },
+ { "Georgian_hie", XKB_KEY_Georgian_hie },
+ { "Georgian_hoe", XKB_KEY_Georgian_hoe },
+ { "Georgian_in", XKB_KEY_Georgian_in },
+ { "Georgian_jhan", XKB_KEY_Georgian_jhan },
+ { "Georgian_jil", XKB_KEY_Georgian_jil },
+ { "Georgian_kan", XKB_KEY_Georgian_kan },
+ { "Georgian_khar", XKB_KEY_Georgian_khar },
+ { "Georgian_las", XKB_KEY_Georgian_las },
+ { "Georgian_man", XKB_KEY_Georgian_man },
+ { "Georgian_nar", XKB_KEY_Georgian_nar },
+ { "Georgian_on", XKB_KEY_Georgian_on },
+ { "Georgian_par", XKB_KEY_Georgian_par },
+ { "Georgian_phar", XKB_KEY_Georgian_phar },
+ { "Georgian_qar", XKB_KEY_Georgian_qar },
+ { "Georgian_rae", XKB_KEY_Georgian_rae },
+ { "Georgian_san", XKB_KEY_Georgian_san },
+ { "Georgian_shin", XKB_KEY_Georgian_shin },
+ { "Georgian_tan", XKB_KEY_Georgian_tan },
+ { "Georgian_tar", XKB_KEY_Georgian_tar },
+ { "Georgian_un", XKB_KEY_Georgian_un },
+ { "Georgian_vin", XKB_KEY_Georgian_vin },
+ { "Georgian_we", XKB_KEY_Georgian_we },
+ { "Georgian_xan", XKB_KEY_Georgian_xan },
+ { "Georgian_zen", XKB_KEY_Georgian_zen },
+ { "Georgian_zhar", XKB_KEY_Georgian_zhar },
+ { "grave", XKB_KEY_grave },
+ { "greater", XKB_KEY_greater },
+ { "greaterthanequal", XKB_KEY_greaterthanequal },
+ { "Greek_accentdieresis", XKB_KEY_Greek_accentdieresis },
+ { "Greek_ALPHA", XKB_KEY_Greek_ALPHA },
+ { "Greek_alpha", XKB_KEY_Greek_alpha },
+ { "Greek_ALPHAaccent", XKB_KEY_Greek_ALPHAaccent },
+ { "Greek_alphaaccent", XKB_KEY_Greek_alphaaccent },
+ { "Greek_BETA", XKB_KEY_Greek_BETA },
+ { "Greek_beta", XKB_KEY_Greek_beta },
+ { "Greek_CHI", XKB_KEY_Greek_CHI },
+ { "Greek_chi", XKB_KEY_Greek_chi },
+ { "Greek_DELTA", XKB_KEY_Greek_DELTA },
+ { "Greek_delta", XKB_KEY_Greek_delta },
+ { "Greek_EPSILON", XKB_KEY_Greek_EPSILON },
+ { "Greek_epsilon", XKB_KEY_Greek_epsilon },
+ { "Greek_EPSILONaccent", XKB_KEY_Greek_EPSILONaccent },
+ { "Greek_epsilonaccent", XKB_KEY_Greek_epsilonaccent },
+ { "Greek_ETA", XKB_KEY_Greek_ETA },
+ { "Greek_eta", XKB_KEY_Greek_eta },
+ { "Greek_ETAaccent", XKB_KEY_Greek_ETAaccent },
+ { "Greek_etaaccent", XKB_KEY_Greek_etaaccent },
+ { "Greek_finalsmallsigma", XKB_KEY_Greek_finalsmallsigma },
+ { "Greek_GAMMA", XKB_KEY_Greek_GAMMA },
+ { "Greek_gamma", XKB_KEY_Greek_gamma },
+ { "Greek_horizbar", XKB_KEY_Greek_horizbar },
+ { "Greek_IOTA", XKB_KEY_Greek_IOTA },
+ { "Greek_iota", XKB_KEY_Greek_iota },
+ { "Greek_IOTAaccent", XKB_KEY_Greek_IOTAaccent },
+ { "Greek_iotaaccent", XKB_KEY_Greek_iotaaccent },
+ { "Greek_iotaaccentdieresis", XKB_KEY_Greek_iotaaccentdieresis },
+ { "Greek_IOTAdiaeresis", XKB_KEY_Greek_IOTAdiaeresis },
+ { "Greek_IOTAdieresis", XKB_KEY_Greek_IOTAdieresis },
+ { "Greek_iotadieresis", XKB_KEY_Greek_iotadieresis },
+ { "Greek_KAPPA", XKB_KEY_Greek_KAPPA },
+ { "Greek_kappa", XKB_KEY_Greek_kappa },
+ { "Greek_LAMBDA", XKB_KEY_Greek_LAMBDA },
+ { "Greek_lambda", XKB_KEY_Greek_lambda },
+ { "Greek_LAMDA", XKB_KEY_Greek_LAMDA },
+ { "Greek_lamda", XKB_KEY_Greek_lamda },
+ { "Greek_MU", XKB_KEY_Greek_MU },
+ { "Greek_mu", XKB_KEY_Greek_mu },
+ { "Greek_NU", XKB_KEY_Greek_NU },
+ { "Greek_nu", XKB_KEY_Greek_nu },
+ { "Greek_OMEGA", XKB_KEY_Greek_OMEGA },
+ { "Greek_omega", XKB_KEY_Greek_omega },
+ { "Greek_OMEGAaccent", XKB_KEY_Greek_OMEGAaccent },
+ { "Greek_omegaaccent", XKB_KEY_Greek_omegaaccent },
+ { "Greek_OMICRON", XKB_KEY_Greek_OMICRON },
+ { "Greek_omicron", XKB_KEY_Greek_omicron },
+ { "Greek_OMICRONaccent", XKB_KEY_Greek_OMICRONaccent },
+ { "Greek_omicronaccent", XKB_KEY_Greek_omicronaccent },
+ { "Greek_PHI", XKB_KEY_Greek_PHI },
+ { "Greek_phi", XKB_KEY_Greek_phi },
+ { "Greek_PI", XKB_KEY_Greek_PI },
+ { "Greek_pi", XKB_KEY_Greek_pi },
+ { "Greek_PSI", XKB_KEY_Greek_PSI },
+ { "Greek_psi", XKB_KEY_Greek_psi },
+ { "Greek_RHO", XKB_KEY_Greek_RHO },
+ { "Greek_rho", XKB_KEY_Greek_rho },
+ { "Greek_SIGMA", XKB_KEY_Greek_SIGMA },
+ { "Greek_sigma", XKB_KEY_Greek_sigma },
+ { "Greek_switch", XKB_KEY_Greek_switch },
+ { "Greek_TAU", XKB_KEY_Greek_TAU },
+ { "Greek_tau", XKB_KEY_Greek_tau },
+ { "Greek_THETA", XKB_KEY_Greek_THETA },
+ { "Greek_theta", XKB_KEY_Greek_theta },
+ { "Greek_UPSILON", XKB_KEY_Greek_UPSILON },
+ { "Greek_upsilon", XKB_KEY_Greek_upsilon },
+ { "Greek_UPSILONaccent", XKB_KEY_Greek_UPSILONaccent },
+ { "Greek_upsilonaccent", XKB_KEY_Greek_upsilonaccent },
+ { "Greek_upsilonaccentdieresis", XKB_KEY_Greek_upsilonaccentdieresis },
+ { "Greek_UPSILONdieresis", XKB_KEY_Greek_UPSILONdieresis },
+ { "Greek_upsilondieresis", XKB_KEY_Greek_upsilondieresis },
+ { "Greek_XI", XKB_KEY_Greek_XI },
+ { "Greek_xi", XKB_KEY_Greek_xi },
+ { "Greek_ZETA", XKB_KEY_Greek_ZETA },
+ { "Greek_zeta", XKB_KEY_Greek_zeta },
+ { "guilder", XKB_KEY_guilder },
+ { "guillemotleft", XKB_KEY_guillemotleft },
+ { "guillemotright", XKB_KEY_guillemotright },
+ { "H", XKB_KEY_H },
+ { "h", XKB_KEY_h },
+ { "hairspace", XKB_KEY_hairspace },
+ { "Hangul", XKB_KEY_Hangul },
+ { "Hangul_A", XKB_KEY_Hangul_A },
+ { "Hangul_AE", XKB_KEY_Hangul_AE },
+ { "Hangul_AraeA", XKB_KEY_Hangul_AraeA },
+ { "Hangul_AraeAE", XKB_KEY_Hangul_AraeAE },
+ { "Hangul_Banja", XKB_KEY_Hangul_Banja },
+ { "Hangul_Cieuc", XKB_KEY_Hangul_Cieuc },
+ { "Hangul_Codeinput", XKB_KEY_Hangul_Codeinput },
+ { "Hangul_Dikeud", XKB_KEY_Hangul_Dikeud },
+ { "Hangul_E", XKB_KEY_Hangul_E },
+ { "Hangul_End", XKB_KEY_Hangul_End },
+ { "Hangul_EO", XKB_KEY_Hangul_EO },
+ { "Hangul_EU", XKB_KEY_Hangul_EU },
+ { "Hangul_Hanja", XKB_KEY_Hangul_Hanja },
+ { "Hangul_Hieuh", XKB_KEY_Hangul_Hieuh },
+ { "Hangul_I", XKB_KEY_Hangul_I },
+ { "Hangul_Ieung", XKB_KEY_Hangul_Ieung },
+ { "Hangul_J_Cieuc", XKB_KEY_Hangul_J_Cieuc },
+ { "Hangul_J_Dikeud", XKB_KEY_Hangul_J_Dikeud },
+ { "Hangul_J_Hieuh", XKB_KEY_Hangul_J_Hieuh },
+ { "Hangul_J_Ieung", XKB_KEY_Hangul_J_Ieung },
+ { "Hangul_J_Jieuj", XKB_KEY_Hangul_J_Jieuj },
+ { "Hangul_J_Khieuq", XKB_KEY_Hangul_J_Khieuq },
+ { "Hangul_J_Kiyeog", XKB_KEY_Hangul_J_Kiyeog },
+ { "Hangul_J_KiyeogSios", XKB_KEY_Hangul_J_KiyeogSios },
+ { "Hangul_J_KkogjiDalrinIeung", XKB_KEY_Hangul_J_KkogjiDalrinIeung },
+ { "Hangul_J_Mieum", XKB_KEY_Hangul_J_Mieum },
+ { "Hangul_J_Nieun", XKB_KEY_Hangul_J_Nieun },
+ { "Hangul_J_NieunHieuh", XKB_KEY_Hangul_J_NieunHieuh },
+ { "Hangul_J_NieunJieuj", XKB_KEY_Hangul_J_NieunJieuj },
+ { "Hangul_J_PanSios", XKB_KEY_Hangul_J_PanSios },
+ { "Hangul_J_Phieuf", XKB_KEY_Hangul_J_Phieuf },
+ { "Hangul_J_Pieub", XKB_KEY_Hangul_J_Pieub },
+ { "Hangul_J_PieubSios", XKB_KEY_Hangul_J_PieubSios },
+ { "Hangul_J_Rieul", XKB_KEY_Hangul_J_Rieul },
+ { "Hangul_J_RieulHieuh", XKB_KEY_Hangul_J_RieulHieuh },
+ { "Hangul_J_RieulKiyeog", XKB_KEY_Hangul_J_RieulKiyeog },
+ { "Hangul_J_RieulMieum", XKB_KEY_Hangul_J_RieulMieum },
+ { "Hangul_J_RieulPhieuf", XKB_KEY_Hangul_J_RieulPhieuf },
+ { "Hangul_J_RieulPieub", XKB_KEY_Hangul_J_RieulPieub },
+ { "Hangul_J_RieulSios", XKB_KEY_Hangul_J_RieulSios },
+ { "Hangul_J_RieulTieut", XKB_KEY_Hangul_J_RieulTieut },
+ { "Hangul_J_Sios", XKB_KEY_Hangul_J_Sios },
+ { "Hangul_J_SsangKiyeog", XKB_KEY_Hangul_J_SsangKiyeog },
+ { "Hangul_J_SsangSios", XKB_KEY_Hangul_J_SsangSios },
+ { "Hangul_J_Tieut", XKB_KEY_Hangul_J_Tieut },
+ { "Hangul_J_YeorinHieuh", XKB_KEY_Hangul_J_YeorinHieuh },
+ { "Hangul_Jamo", XKB_KEY_Hangul_Jamo },
+ { "Hangul_Jeonja", XKB_KEY_Hangul_Jeonja },
+ { "Hangul_Jieuj", XKB_KEY_Hangul_Jieuj },
+ { "Hangul_Khieuq", XKB_KEY_Hangul_Khieuq },
+ { "Hangul_Kiyeog", XKB_KEY_Hangul_Kiyeog },
+ { "Hangul_KiyeogSios", XKB_KEY_Hangul_KiyeogSios },
+ { "Hangul_KkogjiDalrinIeung", XKB_KEY_Hangul_KkogjiDalrinIeung },
+ { "Hangul_Mieum", XKB_KEY_Hangul_Mieum },
+ { "Hangul_MultipleCandidate", XKB_KEY_Hangul_MultipleCandidate },
+ { "Hangul_Nieun", XKB_KEY_Hangul_Nieun },
+ { "Hangul_NieunHieuh", XKB_KEY_Hangul_NieunHieuh },
+ { "Hangul_NieunJieuj", XKB_KEY_Hangul_NieunJieuj },
+ { "Hangul_O", XKB_KEY_Hangul_O },
+ { "Hangul_OE", XKB_KEY_Hangul_OE },
+ { "Hangul_PanSios", XKB_KEY_Hangul_PanSios },
+ { "Hangul_Phieuf", XKB_KEY_Hangul_Phieuf },
+ { "Hangul_Pieub", XKB_KEY_Hangul_Pieub },
+ { "Hangul_PieubSios", XKB_KEY_Hangul_PieubSios },
+ { "Hangul_PostHanja", XKB_KEY_Hangul_PostHanja },
+ { "Hangul_PreHanja", XKB_KEY_Hangul_PreHanja },
+ { "Hangul_PreviousCandidate", XKB_KEY_Hangul_PreviousCandidate },
+ { "Hangul_Rieul", XKB_KEY_Hangul_Rieul },
+ { "Hangul_RieulHieuh", XKB_KEY_Hangul_RieulHieuh },
+ { "Hangul_RieulKiyeog", XKB_KEY_Hangul_RieulKiyeog },
+ { "Hangul_RieulMieum", XKB_KEY_Hangul_RieulMieum },
+ { "Hangul_RieulPhieuf", XKB_KEY_Hangul_RieulPhieuf },
+ { "Hangul_RieulPieub", XKB_KEY_Hangul_RieulPieub },
+ { "Hangul_RieulSios", XKB_KEY_Hangul_RieulSios },
+ { "Hangul_RieulTieut", XKB_KEY_Hangul_RieulTieut },
+ { "Hangul_RieulYeorinHieuh", XKB_KEY_Hangul_RieulYeorinHieuh },
+ { "Hangul_Romaja", XKB_KEY_Hangul_Romaja },
+ { "Hangul_SingleCandidate", XKB_KEY_Hangul_SingleCandidate },
+ { "Hangul_Sios", XKB_KEY_Hangul_Sios },
+ { "Hangul_Special", XKB_KEY_Hangul_Special },
+ { "Hangul_SsangDikeud", XKB_KEY_Hangul_SsangDikeud },
+ { "Hangul_SsangJieuj", XKB_KEY_Hangul_SsangJieuj },
+ { "Hangul_SsangKiyeog", XKB_KEY_Hangul_SsangKiyeog },
+ { "Hangul_SsangPieub", XKB_KEY_Hangul_SsangPieub },
+ { "Hangul_SsangSios", XKB_KEY_Hangul_SsangSios },
+ { "Hangul_Start", XKB_KEY_Hangul_Start },
+ { "Hangul_SunkyeongeumMieum", XKB_KEY_Hangul_SunkyeongeumMieum },
+ { "Hangul_SunkyeongeumPhieuf", XKB_KEY_Hangul_SunkyeongeumPhieuf },
+ { "Hangul_SunkyeongeumPieub", XKB_KEY_Hangul_SunkyeongeumPieub },
+ { "Hangul_switch", XKB_KEY_Hangul_switch },
+ { "Hangul_Tieut", XKB_KEY_Hangul_Tieut },
+ { "Hangul_U", XKB_KEY_Hangul_U },
+ { "Hangul_WA", XKB_KEY_Hangul_WA },
+ { "Hangul_WAE", XKB_KEY_Hangul_WAE },
+ { "Hangul_WE", XKB_KEY_Hangul_WE },
+ { "Hangul_WEO", XKB_KEY_Hangul_WEO },
+ { "Hangul_WI", XKB_KEY_Hangul_WI },
+ { "Hangul_YA", XKB_KEY_Hangul_YA },
+ { "Hangul_YAE", XKB_KEY_Hangul_YAE },
+ { "Hangul_YE", XKB_KEY_Hangul_YE },
+ { "Hangul_YEO", XKB_KEY_Hangul_YEO },
+ { "Hangul_YeorinHieuh", XKB_KEY_Hangul_YeorinHieuh },
+ { "Hangul_YI", XKB_KEY_Hangul_YI },
+ { "Hangul_YO", XKB_KEY_Hangul_YO },
+ { "Hangul_YU", XKB_KEY_Hangul_YU },
+ { "Hankaku", XKB_KEY_Hankaku },
+ { "Hcircumflex", XKB_KEY_Hcircumflex },
+ { "hcircumflex", XKB_KEY_hcircumflex },
+ { "heart", XKB_KEY_heart },
+ { "hebrew_aleph", XKB_KEY_hebrew_aleph },
+ { "hebrew_ayin", XKB_KEY_hebrew_ayin },
+ { "hebrew_bet", XKB_KEY_hebrew_bet },
+ { "hebrew_beth", XKB_KEY_hebrew_beth },
+ { "hebrew_chet", XKB_KEY_hebrew_chet },
+ { "hebrew_dalet", XKB_KEY_hebrew_dalet },
+ { "hebrew_daleth", XKB_KEY_hebrew_daleth },
+ { "hebrew_doublelowline", XKB_KEY_hebrew_doublelowline },
+ { "hebrew_finalkaph", XKB_KEY_hebrew_finalkaph },
+ { "hebrew_finalmem", XKB_KEY_hebrew_finalmem },
+ { "hebrew_finalnun", XKB_KEY_hebrew_finalnun },
+ { "hebrew_finalpe", XKB_KEY_hebrew_finalpe },
+ { "hebrew_finalzade", XKB_KEY_hebrew_finalzade },
+ { "hebrew_finalzadi", XKB_KEY_hebrew_finalzadi },
+ { "hebrew_gimel", XKB_KEY_hebrew_gimel },
+ { "hebrew_gimmel", XKB_KEY_hebrew_gimmel },
+ { "hebrew_he", XKB_KEY_hebrew_he },
+ { "hebrew_het", XKB_KEY_hebrew_het },
+ { "hebrew_kaph", XKB_KEY_hebrew_kaph },
+ { "hebrew_kuf", XKB_KEY_hebrew_kuf },
+ { "hebrew_lamed", XKB_KEY_hebrew_lamed },
+ { "hebrew_mem", XKB_KEY_hebrew_mem },
+ { "hebrew_nun", XKB_KEY_hebrew_nun },
+ { "hebrew_pe", XKB_KEY_hebrew_pe },
+ { "hebrew_qoph", XKB_KEY_hebrew_qoph },
+ { "hebrew_resh", XKB_KEY_hebrew_resh },
+ { "hebrew_samech", XKB_KEY_hebrew_samech },
+ { "hebrew_samekh", XKB_KEY_hebrew_samekh },
+ { "hebrew_shin", XKB_KEY_hebrew_shin },
+ { "Hebrew_switch", XKB_KEY_Hebrew_switch },
+ { "hebrew_taf", XKB_KEY_hebrew_taf },
+ { "hebrew_taw", XKB_KEY_hebrew_taw },
+ { "hebrew_tet", XKB_KEY_hebrew_tet },
+ { "hebrew_teth", XKB_KEY_hebrew_teth },
+ { "hebrew_waw", XKB_KEY_hebrew_waw },
+ { "hebrew_yod", XKB_KEY_hebrew_yod },
+ { "hebrew_zade", XKB_KEY_hebrew_zade },
+ { "hebrew_zadi", XKB_KEY_hebrew_zadi },
+ { "hebrew_zain", XKB_KEY_hebrew_zain },
+ { "hebrew_zayin", XKB_KEY_hebrew_zayin },
+ { "Help", XKB_KEY_Help },
+ { "Henkan", XKB_KEY_Henkan },
+ { "Henkan_Mode", XKB_KEY_Henkan_Mode },
+ { "hexagram", XKB_KEY_hexagram },
+ { "Hiragana", XKB_KEY_Hiragana },
+ { "Hiragana_Katakana", XKB_KEY_Hiragana_Katakana },
+ { "Home", XKB_KEY_Home },
+ { "horizconnector", XKB_KEY_horizconnector },
+ { "horizlinescan1", XKB_KEY_horizlinescan1 },
+ { "horizlinescan3", XKB_KEY_horizlinescan3 },
+ { "horizlinescan5", XKB_KEY_horizlinescan5 },
+ { "horizlinescan7", XKB_KEY_horizlinescan7 },
+ { "horizlinescan9", XKB_KEY_horizlinescan9 },
+ { "hpBackTab", XKB_KEY_hpBackTab },
+ { "hpblock", XKB_KEY_hpblock },
+ { "hpClearLine", XKB_KEY_hpClearLine },
+ { "hpDeleteChar", XKB_KEY_hpDeleteChar },
+ { "hpDeleteLine", XKB_KEY_hpDeleteLine },
+ { "hpguilder", XKB_KEY_hpguilder },
+ { "hpInsertChar", XKB_KEY_hpInsertChar },
+ { "hpInsertLine", XKB_KEY_hpInsertLine },
+ { "hpIO", XKB_KEY_hpIO },
+ { "hpKP_BackTab", XKB_KEY_hpKP_BackTab },
+ { "hplira", XKB_KEY_hplira },
+ { "hplongminus", XKB_KEY_hplongminus },
+ { "hpModelock1", XKB_KEY_hpModelock1 },
+ { "hpModelock2", XKB_KEY_hpModelock2 },
+ { "hpmute_acute", XKB_KEY_hpmute_acute },
+ { "hpmute_asciicircum", XKB_KEY_hpmute_asciicircum },
+ { "hpmute_asciitilde", XKB_KEY_hpmute_asciitilde },
+ { "hpmute_diaeresis", XKB_KEY_hpmute_diaeresis },
+ { "hpmute_grave", XKB_KEY_hpmute_grave },
+ { "hpReset", XKB_KEY_hpReset },
+ { "hpSystem", XKB_KEY_hpSystem },
+ { "hpUser", XKB_KEY_hpUser },
+ { "hpYdiaeresis", XKB_KEY_hpYdiaeresis },
+ { "Hstroke", XKB_KEY_Hstroke },
+ { "hstroke", XKB_KEY_hstroke },
+ { "ht", XKB_KEY_ht },
+ { "Hyper_L", XKB_KEY_Hyper_L },
+ { "Hyper_R", XKB_KEY_Hyper_R },
+ { "hyphen", XKB_KEY_hyphen },
+ { "I", XKB_KEY_I },
+ { "i", XKB_KEY_i },
+ { "Iabovedot", XKB_KEY_Iabovedot },
+ { "Iacute", XKB_KEY_Iacute },
+ { "iacute", XKB_KEY_iacute },
+ { "Ibelowdot", XKB_KEY_Ibelowdot },
+ { "ibelowdot", XKB_KEY_ibelowdot },
+ { "Ibreve", XKB_KEY_Ibreve },
+ { "ibreve", XKB_KEY_ibreve },
+ { "Icircumflex", XKB_KEY_Icircumflex },
+ { "icircumflex", XKB_KEY_icircumflex },
+ { "identical", XKB_KEY_identical },
+ { "Idiaeresis", XKB_KEY_Idiaeresis },
+ { "idiaeresis", XKB_KEY_idiaeresis },
+ { "idotless", XKB_KEY_idotless },
+ { "ifonlyif", XKB_KEY_ifonlyif },
+ { "Igrave", XKB_KEY_Igrave },
+ { "igrave", XKB_KEY_igrave },
+ { "Ihook", XKB_KEY_Ihook },
+ { "ihook", XKB_KEY_ihook },
+ { "Imacron", XKB_KEY_Imacron },
+ { "imacron", XKB_KEY_imacron },
+ { "implies", XKB_KEY_implies },
+ { "includedin", XKB_KEY_includedin },
+ { "includes", XKB_KEY_includes },
+ { "infinity", XKB_KEY_infinity },
+ { "Insert", XKB_KEY_Insert },
+ { "InsertChar", XKB_KEY_InsertChar },
+ { "InsertLine", XKB_KEY_InsertLine },
+ { "integral", XKB_KEY_integral },
+ { "intersection", XKB_KEY_intersection },
+ { "IO", XKB_KEY_IO },
+ { "Iogonek", XKB_KEY_Iogonek },
+ { "iogonek", XKB_KEY_iogonek },
+ { "ISO_Center_Object", XKB_KEY_ISO_Center_Object },
+ { "ISO_Continuous_Underline", XKB_KEY_ISO_Continuous_Underline },
+ { "ISO_Discontinuous_Underline", XKB_KEY_ISO_Discontinuous_Underline },
+ { "ISO_Emphasize", XKB_KEY_ISO_Emphasize },
+ { "ISO_Enter", XKB_KEY_ISO_Enter },
+ { "ISO_Fast_Cursor_Down", XKB_KEY_ISO_Fast_Cursor_Down },
+ { "ISO_Fast_Cursor_Left", XKB_KEY_ISO_Fast_Cursor_Left },
+ { "ISO_Fast_Cursor_Right", XKB_KEY_ISO_Fast_Cursor_Right },
+ { "ISO_Fast_Cursor_Up", XKB_KEY_ISO_Fast_Cursor_Up },
+ { "ISO_First_Group", XKB_KEY_ISO_First_Group },
+ { "ISO_First_Group_Lock", XKB_KEY_ISO_First_Group_Lock },
+ { "ISO_Group_Latch", XKB_KEY_ISO_Group_Latch },
+ { "ISO_Group_Lock", XKB_KEY_ISO_Group_Lock },
+ { "ISO_Group_Shift", XKB_KEY_ISO_Group_Shift },
+ { "ISO_Last_Group", XKB_KEY_ISO_Last_Group },
+ { "ISO_Last_Group_Lock", XKB_KEY_ISO_Last_Group_Lock },
+ { "ISO_Left_Tab", XKB_KEY_ISO_Left_Tab },
+ { "ISO_Level2_Latch", XKB_KEY_ISO_Level2_Latch },
+ { "ISO_Level3_Latch", XKB_KEY_ISO_Level3_Latch },
+ { "ISO_Level3_Lock", XKB_KEY_ISO_Level3_Lock },
+ { "ISO_Level3_Shift", XKB_KEY_ISO_Level3_Shift },
+ { "ISO_Level5_Latch", XKB_KEY_ISO_Level5_Latch },
+ { "ISO_Level5_Lock", XKB_KEY_ISO_Level5_Lock },
+ { "ISO_Level5_Shift", XKB_KEY_ISO_Level5_Shift },
+ { "ISO_Lock", XKB_KEY_ISO_Lock },
+ { "ISO_Move_Line_Down", XKB_KEY_ISO_Move_Line_Down },
+ { "ISO_Move_Line_Up", XKB_KEY_ISO_Move_Line_Up },
+ { "ISO_Next_Group", XKB_KEY_ISO_Next_Group },
+ { "ISO_Next_Group_Lock", XKB_KEY_ISO_Next_Group_Lock },
+ { "ISO_Partial_Line_Down", XKB_KEY_ISO_Partial_Line_Down },
+ { "ISO_Partial_Line_Up", XKB_KEY_ISO_Partial_Line_Up },
+ { "ISO_Partial_Space_Left", XKB_KEY_ISO_Partial_Space_Left },
+ { "ISO_Partial_Space_Right", XKB_KEY_ISO_Partial_Space_Right },
+ { "ISO_Prev_Group", XKB_KEY_ISO_Prev_Group },
+ { "ISO_Prev_Group_Lock", XKB_KEY_ISO_Prev_Group_Lock },
+ { "ISO_Release_Both_Margins", XKB_KEY_ISO_Release_Both_Margins },
+ { "ISO_Release_Margin_Left", XKB_KEY_ISO_Release_Margin_Left },
+ { "ISO_Release_Margin_Right", XKB_KEY_ISO_Release_Margin_Right },
+ { "ISO_Set_Margin_Left", XKB_KEY_ISO_Set_Margin_Left },
+ { "ISO_Set_Margin_Right", XKB_KEY_ISO_Set_Margin_Right },
+ { "Itilde", XKB_KEY_Itilde },
+ { "itilde", XKB_KEY_itilde },
+ { "J", XKB_KEY_J },
+ { "j", XKB_KEY_j },
+ { "Jcircumflex", XKB_KEY_Jcircumflex },
+ { "jcircumflex", XKB_KEY_jcircumflex },
+ { "jot", XKB_KEY_jot },
+ { "K", XKB_KEY_K },
+ { "k", XKB_KEY_k },
+ { "kana_a", XKB_KEY_kana_a },
+ { "kana_A", XKB_KEY_kana_A },
+ { "kana_CHI", XKB_KEY_kana_CHI },
+ { "kana_closingbracket", XKB_KEY_kana_closingbracket },
+ { "kana_comma", XKB_KEY_kana_comma },
+ { "kana_conjunctive", XKB_KEY_kana_conjunctive },
+ { "kana_e", XKB_KEY_kana_e },
+ { "kana_E", XKB_KEY_kana_E },
+ { "kana_FU", XKB_KEY_kana_FU },
+ { "kana_fullstop", XKB_KEY_kana_fullstop },
+ { "kana_HA", XKB_KEY_kana_HA },
+ { "kana_HE", XKB_KEY_kana_HE },
+ { "kana_HI", XKB_KEY_kana_HI },
+ { "kana_HO", XKB_KEY_kana_HO },
+ { "kana_HU", XKB_KEY_kana_HU },
+ { "kana_i", XKB_KEY_kana_i },
+ { "kana_I", XKB_KEY_kana_I },
+ { "kana_KA", XKB_KEY_kana_KA },
+ { "kana_KE", XKB_KEY_kana_KE },
+ { "kana_KI", XKB_KEY_kana_KI },
+ { "kana_KO", XKB_KEY_kana_KO },
+ { "kana_KU", XKB_KEY_kana_KU },
+ { "Kana_Lock", XKB_KEY_Kana_Lock },
+ { "kana_MA", XKB_KEY_kana_MA },
+ { "kana_ME", XKB_KEY_kana_ME },
+ { "kana_MI", XKB_KEY_kana_MI },
+ { "kana_middledot", XKB_KEY_kana_middledot },
+ { "kana_MO", XKB_KEY_kana_MO },
+ { "kana_MU", XKB_KEY_kana_MU },
+ { "kana_N", XKB_KEY_kana_N },
+ { "kana_NA", XKB_KEY_kana_NA },
+ { "kana_NE", XKB_KEY_kana_NE },
+ { "kana_NI", XKB_KEY_kana_NI },
+ { "kana_NO", XKB_KEY_kana_NO },
+ { "kana_NU", XKB_KEY_kana_NU },
+ { "kana_o", XKB_KEY_kana_o },
+ { "kana_O", XKB_KEY_kana_O },
+ { "kana_openingbracket", XKB_KEY_kana_openingbracket },
+ { "kana_RA", XKB_KEY_kana_RA },
+ { "kana_RE", XKB_KEY_kana_RE },
+ { "kana_RI", XKB_KEY_kana_RI },
+ { "kana_RO", XKB_KEY_kana_RO },
+ { "kana_RU", XKB_KEY_kana_RU },
+ { "kana_SA", XKB_KEY_kana_SA },
+ { "kana_SE", XKB_KEY_kana_SE },
+ { "kana_SHI", XKB_KEY_kana_SHI },
+ { "Kana_Shift", XKB_KEY_Kana_Shift },
+ { "kana_SO", XKB_KEY_kana_SO },
+ { "kana_SU", XKB_KEY_kana_SU },
+ { "kana_switch", XKB_KEY_kana_switch },
+ { "kana_TA", XKB_KEY_kana_TA },
+ { "kana_TE", XKB_KEY_kana_TE },
+ { "kana_TI", XKB_KEY_kana_TI },
+ { "kana_TO", XKB_KEY_kana_TO },
+ { "kana_tsu", XKB_KEY_kana_tsu },
+ { "kana_TSU", XKB_KEY_kana_TSU },
+ { "kana_tu", XKB_KEY_kana_tu },
+ { "kana_TU", XKB_KEY_kana_TU },
+ { "kana_u", XKB_KEY_kana_u },
+ { "kana_U", XKB_KEY_kana_U },
+ { "kana_WA", XKB_KEY_kana_WA },
+ { "kana_WO", XKB_KEY_kana_WO },
+ { "kana_ya", XKB_KEY_kana_ya },
+ { "kana_YA", XKB_KEY_kana_YA },
+ { "kana_yo", XKB_KEY_kana_yo },
+ { "kana_YO", XKB_KEY_kana_YO },
+ { "kana_yu", XKB_KEY_kana_yu },
+ { "kana_YU", XKB_KEY_kana_YU },
+ { "Kanji", XKB_KEY_Kanji },
+ { "Kanji_Bangou", XKB_KEY_Kanji_Bangou },
+ { "kappa", XKB_KEY_kappa },
+ { "Katakana", XKB_KEY_Katakana },
+ { "Kcedilla", XKB_KEY_Kcedilla },
+ { "kcedilla", XKB_KEY_kcedilla },
+ { "Korean_Won", XKB_KEY_Korean_Won },
+ { "KP_0", XKB_KEY_KP_0 },
+ { "KP_1", XKB_KEY_KP_1 },
+ { "KP_2", XKB_KEY_KP_2 },
+ { "KP_3", XKB_KEY_KP_3 },
+ { "KP_4", XKB_KEY_KP_4 },
+ { "KP_5", XKB_KEY_KP_5 },
+ { "KP_6", XKB_KEY_KP_6 },
+ { "KP_7", XKB_KEY_KP_7 },
+ { "KP_8", XKB_KEY_KP_8 },
+ { "KP_9", XKB_KEY_KP_9 },
+ { "KP_Add", XKB_KEY_KP_Add },
+ { "KP_BackTab", XKB_KEY_KP_BackTab },
+ { "KP_Begin", XKB_KEY_KP_Begin },
+ { "KP_Decimal", XKB_KEY_KP_Decimal },
+ { "KP_Delete", XKB_KEY_KP_Delete },
+ { "KP_Divide", XKB_KEY_KP_Divide },
+ { "KP_Down", XKB_KEY_KP_Down },
+ { "KP_End", XKB_KEY_KP_End },
+ { "KP_Enter", XKB_KEY_KP_Enter },
+ { "KP_Equal", XKB_KEY_KP_Equal },
+ { "KP_F1", XKB_KEY_KP_F1 },
+ { "KP_F2", XKB_KEY_KP_F2 },
+ { "KP_F3", XKB_KEY_KP_F3 },
+ { "KP_F4", XKB_KEY_KP_F4 },
+ { "KP_Home", XKB_KEY_KP_Home },
+ { "KP_Insert", XKB_KEY_KP_Insert },
+ { "KP_Left", XKB_KEY_KP_Left },
+ { "KP_Multiply", XKB_KEY_KP_Multiply },
+ { "KP_Next", XKB_KEY_KP_Next },
+ { "KP_Page_Down", XKB_KEY_KP_Page_Down },
+ { "KP_Page_Up", XKB_KEY_KP_Page_Up },
+ { "KP_Prior", XKB_KEY_KP_Prior },
+ { "KP_Right", XKB_KEY_KP_Right },
+ { "KP_Separator", XKB_KEY_KP_Separator },
+ { "KP_Space", XKB_KEY_KP_Space },
+ { "KP_Subtract", XKB_KEY_KP_Subtract },
+ { "KP_Tab", XKB_KEY_KP_Tab },
+ { "KP_Up", XKB_KEY_KP_Up },
+ { "kra", XKB_KEY_kra },
+ { "L", XKB_KEY_L },
+ { "l", XKB_KEY_l },
+ { "L1", XKB_KEY_L1 },
+ { "L10", XKB_KEY_L10 },
+ { "L2", XKB_KEY_L2 },
+ { "L3", XKB_KEY_L3 },
+ { "L4", XKB_KEY_L4 },
+ { "L5", XKB_KEY_L5 },
+ { "L6", XKB_KEY_L6 },
+ { "L7", XKB_KEY_L7 },
+ { "L8", XKB_KEY_L8 },
+ { "L9", XKB_KEY_L9 },
+ { "Lacute", XKB_KEY_Lacute },
+ { "lacute", XKB_KEY_lacute },
+ { "Last_Virtual_Screen", XKB_KEY_Last_Virtual_Screen },
+ { "latincross", XKB_KEY_latincross },
+ { "Lbelowdot", XKB_KEY_Lbelowdot },
+ { "lbelowdot", XKB_KEY_lbelowdot },
+ { "Lcaron", XKB_KEY_Lcaron },
+ { "lcaron", XKB_KEY_lcaron },
+ { "Lcedilla", XKB_KEY_Lcedilla },
+ { "lcedilla", XKB_KEY_lcedilla },
+ { "Left", XKB_KEY_Left },
+ { "leftanglebracket", XKB_KEY_leftanglebracket },
+ { "leftarrow", XKB_KEY_leftarrow },
+ { "leftcaret", XKB_KEY_leftcaret },
+ { "leftdoublequotemark", XKB_KEY_leftdoublequotemark },
+ { "leftmiddlecurlybrace", XKB_KEY_leftmiddlecurlybrace },
+ { "leftopentriangle", XKB_KEY_leftopentriangle },
+ { "leftpointer", XKB_KEY_leftpointer },
+ { "leftradical", XKB_KEY_leftradical },
+ { "leftshoe", XKB_KEY_leftshoe },
+ { "leftsinglequotemark", XKB_KEY_leftsinglequotemark },
+ { "leftt", XKB_KEY_leftt },
+ { "lefttack", XKB_KEY_lefttack },
+ { "less", XKB_KEY_less },
+ { "lessthanequal", XKB_KEY_lessthanequal },
+ { "lf", XKB_KEY_lf },
+ { "Linefeed", XKB_KEY_Linefeed },
+ { "lira", XKB_KEY_lira },
+ { "LiraSign", XKB_KEY_LiraSign },
+ { "logicaland", XKB_KEY_logicaland },
+ { "logicalor", XKB_KEY_logicalor },
+ { "longminus", XKB_KEY_longminus },
+ { "lowleftcorner", XKB_KEY_lowleftcorner },
+ { "lowrightcorner", XKB_KEY_lowrightcorner },
+ { "Lstroke", XKB_KEY_Lstroke },
+ { "lstroke", XKB_KEY_lstroke },
+ { "M", XKB_KEY_M },
+ { "m", XKB_KEY_m },
+ { "Mabovedot", XKB_KEY_Mabovedot },
+ { "mabovedot", XKB_KEY_mabovedot },
+ { "Macedonia_dse", XKB_KEY_Macedonia_dse },
+ { "Macedonia_DSE", XKB_KEY_Macedonia_DSE },
+ { "Macedonia_gje", XKB_KEY_Macedonia_gje },
+ { "Macedonia_GJE", XKB_KEY_Macedonia_GJE },
+ { "Macedonia_kje", XKB_KEY_Macedonia_kje },
+ { "Macedonia_KJE", XKB_KEY_Macedonia_KJE },
+ { "macron", XKB_KEY_macron },
+ { "Mae_Koho", XKB_KEY_Mae_Koho },
+ { "malesymbol", XKB_KEY_malesymbol },
+ { "maltesecross", XKB_KEY_maltesecross },
+ { "marker", XKB_KEY_marker },
+ { "masculine", XKB_KEY_masculine },
+ { "Massyo", XKB_KEY_Massyo },
+ { "Menu", XKB_KEY_Menu },
+ { "Meta_L", XKB_KEY_Meta_L },
+ { "Meta_R", XKB_KEY_Meta_R },
+ { "MillSign", XKB_KEY_MillSign },
+ { "minus", XKB_KEY_minus },
+ { "minutes", XKB_KEY_minutes },
+ { "Mode_switch", XKB_KEY_Mode_switch },
+ { "MouseKeys_Accel_Enable", XKB_KEY_MouseKeys_Accel_Enable },
+ { "MouseKeys_Enable", XKB_KEY_MouseKeys_Enable },
+ { "mu", XKB_KEY_mu },
+ { "Muhenkan", XKB_KEY_Muhenkan },
+ { "Multi_key", XKB_KEY_Multi_key },
+ { "MultipleCandidate", XKB_KEY_MultipleCandidate },
+ { "multiply", XKB_KEY_multiply },
+ { "musicalflat", XKB_KEY_musicalflat },
+ { "musicalsharp", XKB_KEY_musicalsharp },
+ { "mute_acute", XKB_KEY_mute_acute },
+ { "mute_asciicircum", XKB_KEY_mute_asciicircum },
+ { "mute_asciitilde", XKB_KEY_mute_asciitilde },
+ { "mute_diaeresis", XKB_KEY_mute_diaeresis },
+ { "mute_grave", XKB_KEY_mute_grave },
+ { "N", XKB_KEY_N },
+ { "n", XKB_KEY_n },
+ { "nabla", XKB_KEY_nabla },
+ { "Nacute", XKB_KEY_Nacute },
+ { "nacute", XKB_KEY_nacute },
+ { "NairaSign", XKB_KEY_NairaSign },
+ { "Ncaron", XKB_KEY_Ncaron },
+ { "ncaron", XKB_KEY_ncaron },
+ { "Ncedilla", XKB_KEY_Ncedilla },
+ { "ncedilla", XKB_KEY_ncedilla },
+ { "NewSheqelSign", XKB_KEY_NewSheqelSign },
+ { "Next", XKB_KEY_Next },
+ { "Next_Virtual_Screen", XKB_KEY_Next_Virtual_Screen },
+ { "ninesubscript", XKB_KEY_ninesubscript },
+ { "ninesuperior", XKB_KEY_ninesuperior },
+ { "nl", XKB_KEY_nl },
+ { "nobreakspace", XKB_KEY_nobreakspace },
+ { "NoSymbol", XKB_KEY_NoSymbol },
+ { "notapproxeq", XKB_KEY_notapproxeq },
+ { "notelementof", XKB_KEY_notelementof },
+ { "notequal", XKB_KEY_notequal },
+ { "notidentical", XKB_KEY_notidentical },
+ { "notsign", XKB_KEY_notsign },
+ { "Ntilde", XKB_KEY_Ntilde },
+ { "ntilde", XKB_KEY_ntilde },
+ { "Num_Lock", XKB_KEY_Num_Lock },
+ { "numbersign", XKB_KEY_numbersign },
+ { "numerosign", XKB_KEY_numerosign },
+ { "O", XKB_KEY_O },
+ { "o", XKB_KEY_o },
+ { "Oacute", XKB_KEY_Oacute },
+ { "oacute", XKB_KEY_oacute },
+ { "Obarred", XKB_KEY_Obarred },
+ { "obarred", XKB_KEY_obarred },
+ { "Obelowdot", XKB_KEY_Obelowdot },
+ { "obelowdot", XKB_KEY_obelowdot },
+ { "Ocaron", XKB_KEY_Ocaron },
+ { "ocaron", XKB_KEY_ocaron },
+ { "Ocircumflex", XKB_KEY_Ocircumflex },
+ { "ocircumflex", XKB_KEY_ocircumflex },
+ { "Ocircumflexacute", XKB_KEY_Ocircumflexacute },
+ { "ocircumflexacute", XKB_KEY_ocircumflexacute },
+ { "Ocircumflexbelowdot", XKB_KEY_Ocircumflexbelowdot },
+ { "ocircumflexbelowdot", XKB_KEY_ocircumflexbelowdot },
+ { "Ocircumflexgrave", XKB_KEY_Ocircumflexgrave },
+ { "ocircumflexgrave", XKB_KEY_ocircumflexgrave },
+ { "Ocircumflexhook", XKB_KEY_Ocircumflexhook },
+ { "ocircumflexhook", XKB_KEY_ocircumflexhook },
+ { "Ocircumflextilde", XKB_KEY_Ocircumflextilde },
+ { "ocircumflextilde", XKB_KEY_ocircumflextilde },
+ { "Odiaeresis", XKB_KEY_Odiaeresis },
+ { "odiaeresis", XKB_KEY_odiaeresis },
+ { "Odoubleacute", XKB_KEY_Odoubleacute },
+ { "odoubleacute", XKB_KEY_odoubleacute },
+ { "OE", XKB_KEY_OE },
+ { "oe", XKB_KEY_oe },
+ { "ogonek", XKB_KEY_ogonek },
+ { "Ograve", XKB_KEY_Ograve },
+ { "ograve", XKB_KEY_ograve },
+ { "Ohook", XKB_KEY_Ohook },
+ { "ohook", XKB_KEY_ohook },
+ { "Ohorn", XKB_KEY_Ohorn },
+ { "ohorn", XKB_KEY_ohorn },
+ { "Ohornacute", XKB_KEY_Ohornacute },
+ { "ohornacute", XKB_KEY_ohornacute },
+ { "Ohornbelowdot", XKB_KEY_Ohornbelowdot },
+ { "ohornbelowdot", XKB_KEY_ohornbelowdot },
+ { "Ohorngrave", XKB_KEY_Ohorngrave },
+ { "ohorngrave", XKB_KEY_ohorngrave },
+ { "Ohornhook", XKB_KEY_Ohornhook },
+ { "ohornhook", XKB_KEY_ohornhook },
+ { "Ohorntilde", XKB_KEY_Ohorntilde },
+ { "ohorntilde", XKB_KEY_ohorntilde },
+ { "Omacron", XKB_KEY_Omacron },
+ { "omacron", XKB_KEY_omacron },
+ { "oneeighth", XKB_KEY_oneeighth },
+ { "onefifth", XKB_KEY_onefifth },
+ { "onehalf", XKB_KEY_onehalf },
+ { "onequarter", XKB_KEY_onequarter },
+ { "onesixth", XKB_KEY_onesixth },
+ { "onesubscript", XKB_KEY_onesubscript },
+ { "onesuperior", XKB_KEY_onesuperior },
+ { "onethird", XKB_KEY_onethird },
+ { "Ooblique", XKB_KEY_Ooblique },
+ { "ooblique", XKB_KEY_ooblique },
+ { "openrectbullet", XKB_KEY_openrectbullet },
+ { "openstar", XKB_KEY_openstar },
+ { "opentribulletdown", XKB_KEY_opentribulletdown },
+ { "opentribulletup", XKB_KEY_opentribulletup },
+ { "ordfeminine", XKB_KEY_ordfeminine },
+ { "osfActivate", XKB_KEY_osfActivate },
+ { "osfAddMode", XKB_KEY_osfAddMode },
+ { "osfBackSpace", XKB_KEY_osfBackSpace },
+ { "osfBackTab", XKB_KEY_osfBackTab },
+ { "osfBeginData", XKB_KEY_osfBeginData },
+ { "osfBeginLine", XKB_KEY_osfBeginLine },
+ { "osfCancel", XKB_KEY_osfCancel },
+ { "osfClear", XKB_KEY_osfClear },
+ { "osfCopy", XKB_KEY_osfCopy },
+ { "osfCut", XKB_KEY_osfCut },
+ { "osfDelete", XKB_KEY_osfDelete },
+ { "osfDeselectAll", XKB_KEY_osfDeselectAll },
+ { "osfDown", XKB_KEY_osfDown },
+ { "osfEndData", XKB_KEY_osfEndData },
+ { "osfEndLine", XKB_KEY_osfEndLine },
+ { "osfEscape", XKB_KEY_osfEscape },
+ { "osfExtend", XKB_KEY_osfExtend },
+ { "osfHelp", XKB_KEY_osfHelp },
+ { "osfInsert", XKB_KEY_osfInsert },
+ { "osfLeft", XKB_KEY_osfLeft },
+ { "osfMenu", XKB_KEY_osfMenu },
+ { "osfMenuBar", XKB_KEY_osfMenuBar },
+ { "osfNextField", XKB_KEY_osfNextField },
+ { "osfNextMenu", XKB_KEY_osfNextMenu },
+ { "osfPageDown", XKB_KEY_osfPageDown },
+ { "osfPageLeft", XKB_KEY_osfPageLeft },
+ { "osfPageRight", XKB_KEY_osfPageRight },
+ { "osfPageUp", XKB_KEY_osfPageUp },
+ { "osfPaste", XKB_KEY_osfPaste },
+ { "osfPrevField", XKB_KEY_osfPrevField },
+ { "osfPrevMenu", XKB_KEY_osfPrevMenu },
+ { "osfPrimaryPaste", XKB_KEY_osfPrimaryPaste },
+ { "osfQuickPaste", XKB_KEY_osfQuickPaste },
+ { "osfReselect", XKB_KEY_osfReselect },
+ { "osfRestore", XKB_KEY_osfRestore },
+ { "osfRight", XKB_KEY_osfRight },
+ { "osfSelect", XKB_KEY_osfSelect },
+ { "osfSelectAll", XKB_KEY_osfSelectAll },
+ { "osfUndo", XKB_KEY_osfUndo },
+ { "osfUp", XKB_KEY_osfUp },
+ { "Oslash", XKB_KEY_Oslash },
+ { "oslash", XKB_KEY_oslash },
+ { "Otilde", XKB_KEY_Otilde },
+ { "otilde", XKB_KEY_otilde },
+ { "overbar", XKB_KEY_overbar },
+ { "Overlay1_Enable", XKB_KEY_Overlay1_Enable },
+ { "Overlay2_Enable", XKB_KEY_Overlay2_Enable },
+ { "overline", XKB_KEY_overline },
+ { "P", XKB_KEY_P },
+ { "p", XKB_KEY_p },
+ { "Pabovedot", XKB_KEY_Pabovedot },
+ { "pabovedot", XKB_KEY_pabovedot },
+ { "Page_Down", XKB_KEY_Page_Down },
+ { "Page_Up", XKB_KEY_Page_Up },
+ { "paragraph", XKB_KEY_paragraph },
+ { "parenleft", XKB_KEY_parenleft },
+ { "parenright", XKB_KEY_parenright },
+ { "partdifferential", XKB_KEY_partdifferential },
+ { "partialderivative", XKB_KEY_partialderivative },
+ { "Pause", XKB_KEY_Pause },
+ { "percent", XKB_KEY_percent },
+ { "period", XKB_KEY_period },
+ { "periodcentered", XKB_KEY_periodcentered },
+ { "permille", XKB_KEY_permille },
+ { "PesetaSign", XKB_KEY_PesetaSign },
+ { "phonographcopyright", XKB_KEY_phonographcopyright },
+ { "plus", XKB_KEY_plus },
+ { "plusminus", XKB_KEY_plusminus },
+ { "Pointer_Accelerate", XKB_KEY_Pointer_Accelerate },
+ { "Pointer_Button1", XKB_KEY_Pointer_Button1 },
+ { "Pointer_Button2", XKB_KEY_Pointer_Button2 },
+ { "Pointer_Button3", XKB_KEY_Pointer_Button3 },
+ { "Pointer_Button4", XKB_KEY_Pointer_Button4 },
+ { "Pointer_Button5", XKB_KEY_Pointer_Button5 },
+ { "Pointer_Button_Dflt", XKB_KEY_Pointer_Button_Dflt },
+ { "Pointer_DblClick1", XKB_KEY_Pointer_DblClick1 },
+ { "Pointer_DblClick2", XKB_KEY_Pointer_DblClick2 },
+ { "Pointer_DblClick3", XKB_KEY_Pointer_DblClick3 },
+ { "Pointer_DblClick4", XKB_KEY_Pointer_DblClick4 },
+ { "Pointer_DblClick5", XKB_KEY_Pointer_DblClick5 },
+ { "Pointer_DblClick_Dflt", XKB_KEY_Pointer_DblClick_Dflt },
+ { "Pointer_DfltBtnNext", XKB_KEY_Pointer_DfltBtnNext },
+ { "Pointer_DfltBtnPrev", XKB_KEY_Pointer_DfltBtnPrev },
+ { "Pointer_Down", XKB_KEY_Pointer_Down },
+ { "Pointer_DownLeft", XKB_KEY_Pointer_DownLeft },
+ { "Pointer_DownRight", XKB_KEY_Pointer_DownRight },
+ { "Pointer_Drag1", XKB_KEY_Pointer_Drag1 },
+ { "Pointer_Drag2", XKB_KEY_Pointer_Drag2 },
+ { "Pointer_Drag3", XKB_KEY_Pointer_Drag3 },
+ { "Pointer_Drag4", XKB_KEY_Pointer_Drag4 },
+ { "Pointer_Drag5", XKB_KEY_Pointer_Drag5 },
+ { "Pointer_Drag_Dflt", XKB_KEY_Pointer_Drag_Dflt },
+ { "Pointer_EnableKeys", XKB_KEY_Pointer_EnableKeys },
+ { "Pointer_Left", XKB_KEY_Pointer_Left },
+ { "Pointer_Right", XKB_KEY_Pointer_Right },
+ { "Pointer_Up", XKB_KEY_Pointer_Up },
+ { "Pointer_UpLeft", XKB_KEY_Pointer_UpLeft },
+ { "Pointer_UpRight", XKB_KEY_Pointer_UpRight },
+ { "prescription", XKB_KEY_prescription },
+ { "Prev_Virtual_Screen", XKB_KEY_Prev_Virtual_Screen },
+ { "PreviousCandidate", XKB_KEY_PreviousCandidate },
+ { "Print", XKB_KEY_Print },
+ { "Prior", XKB_KEY_Prior },
+ { "prolongedsound", XKB_KEY_prolongedsound },
+ { "punctspace", XKB_KEY_punctspace },
+ { "Q", XKB_KEY_Q },
+ { "q", XKB_KEY_q },
+ { "quad", XKB_KEY_quad },
+ { "question", XKB_KEY_question },
+ { "questiondown", XKB_KEY_questiondown },
+ { "quotedbl", XKB_KEY_quotedbl },
+ { "quoteleft", XKB_KEY_quoteleft },
+ { "quoteright", XKB_KEY_quoteright },
+ { "R", XKB_KEY_R },
+ { "r", XKB_KEY_r },
+ { "R1", XKB_KEY_R1 },
+ { "R10", XKB_KEY_R10 },
+ { "R11", XKB_KEY_R11 },
+ { "R12", XKB_KEY_R12 },
+ { "R13", XKB_KEY_R13 },
+ { "R14", XKB_KEY_R14 },
+ { "R15", XKB_KEY_R15 },
+ { "R2", XKB_KEY_R2 },
+ { "R3", XKB_KEY_R3 },
+ { "R4", XKB_KEY_R4 },
+ { "R5", XKB_KEY_R5 },
+ { "R6", XKB_KEY_R6 },
+ { "R7", XKB_KEY_R7 },
+ { "R8", XKB_KEY_R8 },
+ { "R9", XKB_KEY_R9 },
+ { "Racute", XKB_KEY_Racute },
+ { "racute", XKB_KEY_racute },
+ { "radical", XKB_KEY_radical },
+ { "Rcaron", XKB_KEY_Rcaron },
+ { "rcaron", XKB_KEY_rcaron },
+ { "Rcedilla", XKB_KEY_Rcedilla },
+ { "rcedilla", XKB_KEY_rcedilla },
+ { "Redo", XKB_KEY_Redo },
+ { "registered", XKB_KEY_registered },
+ { "RepeatKeys_Enable", XKB_KEY_RepeatKeys_Enable },
+ { "Reset", XKB_KEY_Reset },
+ { "Return", XKB_KEY_Return },
+ { "Right", XKB_KEY_Right },
+ { "rightanglebracket", XKB_KEY_rightanglebracket },
+ { "rightarrow", XKB_KEY_rightarrow },
+ { "rightcaret", XKB_KEY_rightcaret },
+ { "rightdoublequotemark", XKB_KEY_rightdoublequotemark },
+ { "rightmiddlecurlybrace", XKB_KEY_rightmiddlecurlybrace },
+ { "rightmiddlesummation", XKB_KEY_rightmiddlesummation },
+ { "rightopentriangle", XKB_KEY_rightopentriangle },
+ { "rightpointer", XKB_KEY_rightpointer },
+ { "rightshoe", XKB_KEY_rightshoe },
+ { "rightsinglequotemark", XKB_KEY_rightsinglequotemark },
+ { "rightt", XKB_KEY_rightt },
+ { "righttack", XKB_KEY_righttack },
+ { "Romaji", XKB_KEY_Romaji },
+ { "RupeeSign", XKB_KEY_RupeeSign },
+ { "S", XKB_KEY_S },
+ { "s", XKB_KEY_s },
+ { "Sabovedot", XKB_KEY_Sabovedot },
+ { "sabovedot", XKB_KEY_sabovedot },
+ { "Sacute", XKB_KEY_Sacute },
+ { "sacute", XKB_KEY_sacute },
+ { "Scaron", XKB_KEY_Scaron },
+ { "scaron", XKB_KEY_scaron },
+ { "Scedilla", XKB_KEY_Scedilla },
+ { "scedilla", XKB_KEY_scedilla },
+ { "SCHWA", XKB_KEY_SCHWA },
+ { "schwa", XKB_KEY_schwa },
+ { "Scircumflex", XKB_KEY_Scircumflex },
+ { "scircumflex", XKB_KEY_scircumflex },
+ { "script_switch", XKB_KEY_script_switch },
+ { "Scroll_Lock", XKB_KEY_Scroll_Lock },
+ { "seconds", XKB_KEY_seconds },
+ { "section", XKB_KEY_section },
+ { "Select", XKB_KEY_Select },
+ { "semicolon", XKB_KEY_semicolon },
+ { "semivoicedsound", XKB_KEY_semivoicedsound },
+ { "Serbian_dje", XKB_KEY_Serbian_dje },
+ { "Serbian_DJE", XKB_KEY_Serbian_DJE },
+ { "Serbian_dze", XKB_KEY_Serbian_dze },
+ { "Serbian_DZE", XKB_KEY_Serbian_DZE },
+ { "Serbian_je", XKB_KEY_Serbian_je },
+ { "Serbian_JE", XKB_KEY_Serbian_JE },
+ { "Serbian_lje", XKB_KEY_Serbian_lje },
+ { "Serbian_LJE", XKB_KEY_Serbian_LJE },
+ { "Serbian_nje", XKB_KEY_Serbian_nje },
+ { "Serbian_NJE", XKB_KEY_Serbian_NJE },
+ { "Serbian_tshe", XKB_KEY_Serbian_tshe },
+ { "Serbian_TSHE", XKB_KEY_Serbian_TSHE },
+ { "seveneighths", XKB_KEY_seveneighths },
+ { "sevensubscript", XKB_KEY_sevensubscript },
+ { "sevensuperior", XKB_KEY_sevensuperior },
+ { "Shift_L", XKB_KEY_Shift_L },
+ { "Shift_Lock", XKB_KEY_Shift_Lock },
+ { "Shift_R", XKB_KEY_Shift_R },
+ { "signaturemark", XKB_KEY_signaturemark },
+ { "signifblank", XKB_KEY_signifblank },
+ { "similarequal", XKB_KEY_similarequal },
+ { "SingleCandidate", XKB_KEY_SingleCandidate },
+ { "singlelowquotemark", XKB_KEY_singlelowquotemark },
+ { "Sinh_a", XKB_KEY_Sinh_a },
+ { "Sinh_aa", XKB_KEY_Sinh_aa },
+ { "Sinh_aa2", XKB_KEY_Sinh_aa2 },
+ { "Sinh_ae", XKB_KEY_Sinh_ae },
+ { "Sinh_ae2", XKB_KEY_Sinh_ae2 },
+ { "Sinh_aee", XKB_KEY_Sinh_aee },
+ { "Sinh_aee2", XKB_KEY_Sinh_aee2 },
+ { "Sinh_ai", XKB_KEY_Sinh_ai },
+ { "Sinh_ai2", XKB_KEY_Sinh_ai2 },
+ { "Sinh_al", XKB_KEY_Sinh_al },
+ { "Sinh_au", XKB_KEY_Sinh_au },
+ { "Sinh_au2", XKB_KEY_Sinh_au2 },
+ { "Sinh_ba", XKB_KEY_Sinh_ba },
+ { "Sinh_bha", XKB_KEY_Sinh_bha },
+ { "Sinh_ca", XKB_KEY_Sinh_ca },
+ { "Sinh_cha", XKB_KEY_Sinh_cha },
+ { "Sinh_dda", XKB_KEY_Sinh_dda },
+ { "Sinh_ddha", XKB_KEY_Sinh_ddha },
+ { "Sinh_dha", XKB_KEY_Sinh_dha },
+ { "Sinh_dhha", XKB_KEY_Sinh_dhha },
+ { "Sinh_e", XKB_KEY_Sinh_e },
+ { "Sinh_e2", XKB_KEY_Sinh_e2 },
+ { "Sinh_ee", XKB_KEY_Sinh_ee },
+ { "Sinh_ee2", XKB_KEY_Sinh_ee2 },
+ { "Sinh_fa", XKB_KEY_Sinh_fa },
+ { "Sinh_ga", XKB_KEY_Sinh_ga },
+ { "Sinh_gha", XKB_KEY_Sinh_gha },
+ { "Sinh_h2", XKB_KEY_Sinh_h2 },
+ { "Sinh_ha", XKB_KEY_Sinh_ha },
+ { "Sinh_i", XKB_KEY_Sinh_i },
+ { "Sinh_i2", XKB_KEY_Sinh_i2 },
+ { "Sinh_ii", XKB_KEY_Sinh_ii },
+ { "Sinh_ii2", XKB_KEY_Sinh_ii2 },
+ { "Sinh_ja", XKB_KEY_Sinh_ja },
+ { "Sinh_jha", XKB_KEY_Sinh_jha },
+ { "Sinh_jnya", XKB_KEY_Sinh_jnya },
+ { "Sinh_ka", XKB_KEY_Sinh_ka },
+ { "Sinh_kha", XKB_KEY_Sinh_kha },
+ { "Sinh_kunddaliya", XKB_KEY_Sinh_kunddaliya },
+ { "Sinh_la", XKB_KEY_Sinh_la },
+ { "Sinh_lla", XKB_KEY_Sinh_lla },
+ { "Sinh_lu", XKB_KEY_Sinh_lu },
+ { "Sinh_lu2", XKB_KEY_Sinh_lu2 },
+ { "Sinh_luu", XKB_KEY_Sinh_luu },
+ { "Sinh_luu2", XKB_KEY_Sinh_luu2 },
+ { "Sinh_ma", XKB_KEY_Sinh_ma },
+ { "Sinh_mba", XKB_KEY_Sinh_mba },
+ { "Sinh_na", XKB_KEY_Sinh_na },
+ { "Sinh_ndda", XKB_KEY_Sinh_ndda },
+ { "Sinh_ndha", XKB_KEY_Sinh_ndha },
+ { "Sinh_ng", XKB_KEY_Sinh_ng },
+ { "Sinh_ng2", XKB_KEY_Sinh_ng2 },
+ { "Sinh_nga", XKB_KEY_Sinh_nga },
+ { "Sinh_nja", XKB_KEY_Sinh_nja },
+ { "Sinh_nna", XKB_KEY_Sinh_nna },
+ { "Sinh_nya", XKB_KEY_Sinh_nya },
+ { "Sinh_o", XKB_KEY_Sinh_o },
+ { "Sinh_o2", XKB_KEY_Sinh_o2 },
+ { "Sinh_oo", XKB_KEY_Sinh_oo },
+ { "Sinh_oo2", XKB_KEY_Sinh_oo2 },
+ { "Sinh_pa", XKB_KEY_Sinh_pa },
+ { "Sinh_pha", XKB_KEY_Sinh_pha },
+ { "Sinh_ra", XKB_KEY_Sinh_ra },
+ { "Sinh_ri", XKB_KEY_Sinh_ri },
+ { "Sinh_rii", XKB_KEY_Sinh_rii },
+ { "Sinh_ru2", XKB_KEY_Sinh_ru2 },
+ { "Sinh_ruu2", XKB_KEY_Sinh_ruu2 },
+ { "Sinh_sa", XKB_KEY_Sinh_sa },
+ { "Sinh_sha", XKB_KEY_Sinh_sha },
+ { "Sinh_ssha", XKB_KEY_Sinh_ssha },
+ { "Sinh_tha", XKB_KEY_Sinh_tha },
+ { "Sinh_thha", XKB_KEY_Sinh_thha },
+ { "Sinh_tta", XKB_KEY_Sinh_tta },
+ { "Sinh_ttha", XKB_KEY_Sinh_ttha },
+ { "Sinh_u", XKB_KEY_Sinh_u },
+ { "Sinh_u2", XKB_KEY_Sinh_u2 },
+ { "Sinh_uu", XKB_KEY_Sinh_uu },
+ { "Sinh_uu2", XKB_KEY_Sinh_uu2 },
+ { "Sinh_va", XKB_KEY_Sinh_va },
+ { "Sinh_ya", XKB_KEY_Sinh_ya },
+ { "sixsubscript", XKB_KEY_sixsubscript },
+ { "sixsuperior", XKB_KEY_sixsuperior },
+ { "slash", XKB_KEY_slash },
+ { "SlowKeys_Enable", XKB_KEY_SlowKeys_Enable },
+ { "soliddiamond", XKB_KEY_soliddiamond },
+ { "space", XKB_KEY_space },
+ { "squareroot", XKB_KEY_squareroot },
+ { "ssharp", XKB_KEY_ssharp },
+ { "sterling", XKB_KEY_sterling },
+ { "StickyKeys_Enable", XKB_KEY_StickyKeys_Enable },
+ { "stricteq", XKB_KEY_stricteq },
+ { "SunAgain", XKB_KEY_SunAgain },
+ { "SunAltGraph", XKB_KEY_SunAltGraph },
+ { "SunAudioLowerVolume", XKB_KEY_SunAudioLowerVolume },
+ { "SunAudioMute", XKB_KEY_SunAudioMute },
+ { "SunAudioRaiseVolume", XKB_KEY_SunAudioRaiseVolume },
+ { "SunCompose", XKB_KEY_SunCompose },
+ { "SunCopy", XKB_KEY_SunCopy },
+ { "SunCut", XKB_KEY_SunCut },
+ { "SunF36", XKB_KEY_SunF36 },
+ { "SunF37", XKB_KEY_SunF37 },
+ { "SunFA_Acute", XKB_KEY_SunFA_Acute },
+ { "SunFA_Cedilla", XKB_KEY_SunFA_Cedilla },
+ { "SunFA_Circum", XKB_KEY_SunFA_Circum },
+ { "SunFA_Diaeresis", XKB_KEY_SunFA_Diaeresis },
+ { "SunFA_Grave", XKB_KEY_SunFA_Grave },
+ { "SunFA_Tilde", XKB_KEY_SunFA_Tilde },
+ { "SunFind", XKB_KEY_SunFind },
+ { "SunFront", XKB_KEY_SunFront },
+ { "SunOpen", XKB_KEY_SunOpen },
+ { "SunPageDown", XKB_KEY_SunPageDown },
+ { "SunPageUp", XKB_KEY_SunPageUp },
+ { "SunPaste", XKB_KEY_SunPaste },
+ { "SunPowerSwitch", XKB_KEY_SunPowerSwitch },
+ { "SunPowerSwitchShift", XKB_KEY_SunPowerSwitchShift },
+ { "SunPrint_Screen", XKB_KEY_SunPrint_Screen },
+ { "SunProps", XKB_KEY_SunProps },
+ { "SunStop", XKB_KEY_SunStop },
+ { "SunSys_Req", XKB_KEY_SunSys_Req },
+ { "SunUndo", XKB_KEY_SunUndo },
+ { "SunVideoDegauss", XKB_KEY_SunVideoDegauss },
+ { "SunVideoLowerBrightness", XKB_KEY_SunVideoLowerBrightness },
+ { "SunVideoRaiseBrightness", XKB_KEY_SunVideoRaiseBrightness },
+ { "Super_L", XKB_KEY_Super_L },
+ { "Super_R", XKB_KEY_Super_R },
+ { "Sys_Req", XKB_KEY_Sys_Req },
+ { "System", XKB_KEY_System },
+ { "T", XKB_KEY_T },
+ { "t", XKB_KEY_t },
+ { "Tab", XKB_KEY_Tab },
+ { "Tabovedot", XKB_KEY_Tabovedot },
+ { "tabovedot", XKB_KEY_tabovedot },
+ { "Tcaron", XKB_KEY_Tcaron },
+ { "tcaron", XKB_KEY_tcaron },
+ { "Tcedilla", XKB_KEY_Tcedilla },
+ { "tcedilla", XKB_KEY_tcedilla },
+ { "telephone", XKB_KEY_telephone },
+ { "telephonerecorder", XKB_KEY_telephonerecorder },
+ { "Terminate_Server", XKB_KEY_Terminate_Server },
+ { "Thai_baht", XKB_KEY_Thai_baht },
+ { "Thai_bobaimai", XKB_KEY_Thai_bobaimai },
+ { "Thai_chochan", XKB_KEY_Thai_chochan },
+ { "Thai_chochang", XKB_KEY_Thai_chochang },
+ { "Thai_choching", XKB_KEY_Thai_choching },
+ { "Thai_chochoe", XKB_KEY_Thai_chochoe },
+ { "Thai_dochada", XKB_KEY_Thai_dochada },
+ { "Thai_dodek", XKB_KEY_Thai_dodek },
+ { "Thai_fofa", XKB_KEY_Thai_fofa },
+ { "Thai_fofan", XKB_KEY_Thai_fofan },
+ { "Thai_hohip", XKB_KEY_Thai_hohip },
+ { "Thai_honokhuk", XKB_KEY_Thai_honokhuk },
+ { "Thai_khokhai", XKB_KEY_Thai_khokhai },
+ { "Thai_khokhon", XKB_KEY_Thai_khokhon },
+ { "Thai_khokhuat", XKB_KEY_Thai_khokhuat },
+ { "Thai_khokhwai", XKB_KEY_Thai_khokhwai },
+ { "Thai_khorakhang", XKB_KEY_Thai_khorakhang },
+ { "Thai_kokai", XKB_KEY_Thai_kokai },
+ { "Thai_lakkhangyao", XKB_KEY_Thai_lakkhangyao },
+ { "Thai_lekchet", XKB_KEY_Thai_lekchet },
+ { "Thai_lekha", XKB_KEY_Thai_lekha },
+ { "Thai_lekhok", XKB_KEY_Thai_lekhok },
+ { "Thai_lekkao", XKB_KEY_Thai_lekkao },
+ { "Thai_leknung", XKB_KEY_Thai_leknung },
+ { "Thai_lekpaet", XKB_KEY_Thai_lekpaet },
+ { "Thai_leksam", XKB_KEY_Thai_leksam },
+ { "Thai_leksi", XKB_KEY_Thai_leksi },
+ { "Thai_leksong", XKB_KEY_Thai_leksong },
+ { "Thai_leksun", XKB_KEY_Thai_leksun },
+ { "Thai_lochula", XKB_KEY_Thai_lochula },
+ { "Thai_loling", XKB_KEY_Thai_loling },
+ { "Thai_lu", XKB_KEY_Thai_lu },
+ { "Thai_maichattawa", XKB_KEY_Thai_maichattawa },
+ { "Thai_maiek", XKB_KEY_Thai_maiek },
+ { "Thai_maihanakat", XKB_KEY_Thai_maihanakat },
+ { "Thai_maihanakat_maitho", XKB_KEY_Thai_maihanakat_maitho },
+ { "Thai_maitaikhu", XKB_KEY_Thai_maitaikhu },
+ { "Thai_maitho", XKB_KEY_Thai_maitho },
+ { "Thai_maitri", XKB_KEY_Thai_maitri },
+ { "Thai_maiyamok", XKB_KEY_Thai_maiyamok },
+ { "Thai_moma", XKB_KEY_Thai_moma },
+ { "Thai_ngongu", XKB_KEY_Thai_ngongu },
+ { "Thai_nikhahit", XKB_KEY_Thai_nikhahit },
+ { "Thai_nonen", XKB_KEY_Thai_nonen },
+ { "Thai_nonu", XKB_KEY_Thai_nonu },
+ { "Thai_oang", XKB_KEY_Thai_oang },
+ { "Thai_paiyannoi", XKB_KEY_Thai_paiyannoi },
+ { "Thai_phinthu", XKB_KEY_Thai_phinthu },
+ { "Thai_phophan", XKB_KEY_Thai_phophan },
+ { "Thai_phophung", XKB_KEY_Thai_phophung },
+ { "Thai_phosamphao", XKB_KEY_Thai_phosamphao },
+ { "Thai_popla", XKB_KEY_Thai_popla },
+ { "Thai_rorua", XKB_KEY_Thai_rorua },
+ { "Thai_ru", XKB_KEY_Thai_ru },
+ { "Thai_saraa", XKB_KEY_Thai_saraa },
+ { "Thai_saraaa", XKB_KEY_Thai_saraaa },
+ { "Thai_saraae", XKB_KEY_Thai_saraae },
+ { "Thai_saraaimaimalai", XKB_KEY_Thai_saraaimaimalai },
+ { "Thai_saraaimaimuan", XKB_KEY_Thai_saraaimaimuan },
+ { "Thai_saraam", XKB_KEY_Thai_saraam },
+ { "Thai_sarae", XKB_KEY_Thai_sarae },
+ { "Thai_sarai", XKB_KEY_Thai_sarai },
+ { "Thai_saraii", XKB_KEY_Thai_saraii },
+ { "Thai_sarao", XKB_KEY_Thai_sarao },
+ { "Thai_sarau", XKB_KEY_Thai_sarau },
+ { "Thai_saraue", XKB_KEY_Thai_saraue },
+ { "Thai_sarauee", XKB_KEY_Thai_sarauee },
+ { "Thai_sarauu", XKB_KEY_Thai_sarauu },
+ { "Thai_sorusi", XKB_KEY_Thai_sorusi },
+ { "Thai_sosala", XKB_KEY_Thai_sosala },
+ { "Thai_soso", XKB_KEY_Thai_soso },
+ { "Thai_sosua", XKB_KEY_Thai_sosua },
+ { "Thai_thanthakhat", XKB_KEY_Thai_thanthakhat },
+ { "Thai_thonangmontho", XKB_KEY_Thai_thonangmontho },
+ { "Thai_thophuthao", XKB_KEY_Thai_thophuthao },
+ { "Thai_thothahan", XKB_KEY_Thai_thothahan },
+ { "Thai_thothan", XKB_KEY_Thai_thothan },
+ { "Thai_thothong", XKB_KEY_Thai_thothong },
+ { "Thai_thothung", XKB_KEY_Thai_thothung },
+ { "Thai_topatak", XKB_KEY_Thai_topatak },
+ { "Thai_totao", XKB_KEY_Thai_totao },
+ { "Thai_wowaen", XKB_KEY_Thai_wowaen },
+ { "Thai_yoyak", XKB_KEY_Thai_yoyak },
+ { "Thai_yoying", XKB_KEY_Thai_yoying },
+ { "therefore", XKB_KEY_therefore },
+ { "thinspace", XKB_KEY_thinspace },
+ { "THORN", XKB_KEY_THORN },
+ { "Thorn", XKB_KEY_Thorn },
+ { "thorn", XKB_KEY_thorn },
+ { "threeeighths", XKB_KEY_threeeighths },
+ { "threefifths", XKB_KEY_threefifths },
+ { "threequarters", XKB_KEY_threequarters },
+ { "threesubscript", XKB_KEY_threesubscript },
+ { "threesuperior", XKB_KEY_threesuperior },
+ { "tintegral", XKB_KEY_tintegral },
+ { "topintegral", XKB_KEY_topintegral },
+ { "topleftparens", XKB_KEY_topleftparens },
+ { "topleftradical", XKB_KEY_topleftradical },
+ { "topleftsqbracket", XKB_KEY_topleftsqbracket },
+ { "topleftsummation", XKB_KEY_topleftsummation },
+ { "toprightparens", XKB_KEY_toprightparens },
+ { "toprightsqbracket", XKB_KEY_toprightsqbracket },
+ { "toprightsummation", XKB_KEY_toprightsummation },
+ { "topt", XKB_KEY_topt },
+ { "topvertsummationconnector", XKB_KEY_topvertsummationconnector },
+ { "Touroku", XKB_KEY_Touroku },
+ { "trademark", XKB_KEY_trademark },
+ { "trademarkincircle", XKB_KEY_trademarkincircle },
+ { "Tslash", XKB_KEY_Tslash },
+ { "tslash", XKB_KEY_tslash },
+ { "twofifths", XKB_KEY_twofifths },
+ { "twosubscript", XKB_KEY_twosubscript },
+ { "twosuperior", XKB_KEY_twosuperior },
+ { "twothirds", XKB_KEY_twothirds },
+ { "U", XKB_KEY_U },
+ { "u", XKB_KEY_u },
+ { "Uacute", XKB_KEY_Uacute },
+ { "uacute", XKB_KEY_uacute },
+ { "Ubelowdot", XKB_KEY_Ubelowdot },
+ { "ubelowdot", XKB_KEY_ubelowdot },
+ { "Ubreve", XKB_KEY_Ubreve },
+ { "ubreve", XKB_KEY_ubreve },
+ { "Ucircumflex", XKB_KEY_Ucircumflex },
+ { "ucircumflex", XKB_KEY_ucircumflex },
+ { "Udiaeresis", XKB_KEY_Udiaeresis },
+ { "udiaeresis", XKB_KEY_udiaeresis },
+ { "Udoubleacute", XKB_KEY_Udoubleacute },
+ { "udoubleacute", XKB_KEY_udoubleacute },
+ { "Ugrave", XKB_KEY_Ugrave },
+ { "ugrave", XKB_KEY_ugrave },
+ { "Uhook", XKB_KEY_Uhook },
+ { "uhook", XKB_KEY_uhook },
+ { "Uhorn", XKB_KEY_Uhorn },
+ { "uhorn", XKB_KEY_uhorn },
+ { "Uhornacute", XKB_KEY_Uhornacute },
+ { "uhornacute", XKB_KEY_uhornacute },
+ { "Uhornbelowdot", XKB_KEY_Uhornbelowdot },
+ { "uhornbelowdot", XKB_KEY_uhornbelowdot },
+ { "Uhorngrave", XKB_KEY_Uhorngrave },
+ { "uhorngrave", XKB_KEY_uhorngrave },
+ { "Uhornhook", XKB_KEY_Uhornhook },
+ { "uhornhook", XKB_KEY_uhornhook },
+ { "Uhorntilde", XKB_KEY_Uhorntilde },
+ { "uhorntilde", XKB_KEY_uhorntilde },
+ { "Ukrainian_ghe_with_upturn", XKB_KEY_Ukrainian_ghe_with_upturn },
+ { "Ukrainian_GHE_WITH_UPTURN", XKB_KEY_Ukrainian_GHE_WITH_UPTURN },
+ { "Ukrainian_i", XKB_KEY_Ukrainian_i },
+ { "Ukrainian_I", XKB_KEY_Ukrainian_I },
+ { "Ukrainian_ie", XKB_KEY_Ukrainian_ie },
+ { "Ukrainian_IE", XKB_KEY_Ukrainian_IE },
+ { "Ukrainian_yi", XKB_KEY_Ukrainian_yi },
+ { "Ukrainian_YI", XKB_KEY_Ukrainian_YI },
+ { "Ukranian_i", XKB_KEY_Ukranian_i },
+ { "Ukranian_I", XKB_KEY_Ukranian_I },
+ { "Ukranian_je", XKB_KEY_Ukranian_je },
+ { "Ukranian_JE", XKB_KEY_Ukranian_JE },
+ { "Ukranian_yi", XKB_KEY_Ukranian_yi },
+ { "Ukranian_YI", XKB_KEY_Ukranian_YI },
+ { "Umacron", XKB_KEY_Umacron },
+ { "umacron", XKB_KEY_umacron },
+ { "underbar", XKB_KEY_underbar },
+ { "underscore", XKB_KEY_underscore },
+ { "Undo", XKB_KEY_Undo },
+ { "union", XKB_KEY_union },
+ { "Uogonek", XKB_KEY_Uogonek },
+ { "uogonek", XKB_KEY_uogonek },
+ { "Up", XKB_KEY_Up },
+ { "uparrow", XKB_KEY_uparrow },
+ { "upcaret", XKB_KEY_upcaret },
+ { "upleftcorner", XKB_KEY_upleftcorner },
+ { "uprightcorner", XKB_KEY_uprightcorner },
+ { "upshoe", XKB_KEY_upshoe },
+ { "upstile", XKB_KEY_upstile },
+ { "uptack", XKB_KEY_uptack },
+ { "Uring", XKB_KEY_Uring },
+ { "uring", XKB_KEY_uring },
+ { "User", XKB_KEY_User },
+ { "Utilde", XKB_KEY_Utilde },
+ { "utilde", XKB_KEY_utilde },
+ { "V", XKB_KEY_V },
+ { "v", XKB_KEY_v },
+ { "variation", XKB_KEY_variation },
+ { "vertbar", XKB_KEY_vertbar },
+ { "vertconnector", XKB_KEY_vertconnector },
+ { "voicedsound", XKB_KEY_voicedsound },
+ { "VoidSymbol", XKB_KEY_VoidSymbol },
+ { "vt", XKB_KEY_vt },
+ { "W", XKB_KEY_W },
+ { "w", XKB_KEY_w },
+ { "Wacute", XKB_KEY_Wacute },
+ { "wacute", XKB_KEY_wacute },
+ { "Wcircumflex", XKB_KEY_Wcircumflex },
+ { "wcircumflex", XKB_KEY_wcircumflex },
+ { "Wdiaeresis", XKB_KEY_Wdiaeresis },
+ { "wdiaeresis", XKB_KEY_wdiaeresis },
+ { "Wgrave", XKB_KEY_Wgrave },
+ { "wgrave", XKB_KEY_wgrave },
+ { "WonSign", XKB_KEY_WonSign },
+ { "X", XKB_KEY_X },
+ { "x", XKB_KEY_x },
+ { "Xabovedot", XKB_KEY_Xabovedot },
+ { "xabovedot", XKB_KEY_xabovedot },
+ { "XF86AddFavorite", XKB_KEY_XF86AddFavorite },
+ { "XF86ApplicationLeft", XKB_KEY_XF86ApplicationLeft },
+ { "XF86ApplicationRight", XKB_KEY_XF86ApplicationRight },
+ { "XF86AudioCycleTrack", XKB_KEY_XF86AudioCycleTrack },
+ { "XF86AudioForward", XKB_KEY_XF86AudioForward },
+ { "XF86AudioLowerVolume", XKB_KEY_XF86AudioLowerVolume },
+ { "XF86AudioMedia", XKB_KEY_XF86AudioMedia },
+ { "XF86AudioMute", XKB_KEY_XF86AudioMute },
+ { "XF86AudioNext", XKB_KEY_XF86AudioNext },
+ { "XF86AudioPause", XKB_KEY_XF86AudioPause },
+ { "XF86AudioPlay", XKB_KEY_XF86AudioPlay },
+ { "XF86AudioPrev", XKB_KEY_XF86AudioPrev },
+ { "XF86AudioRaiseVolume", XKB_KEY_XF86AudioRaiseVolume },
+ { "XF86AudioRandomPlay", XKB_KEY_XF86AudioRandomPlay },
+ { "XF86AudioRecord", XKB_KEY_XF86AudioRecord },
+ { "XF86AudioRepeat", XKB_KEY_XF86AudioRepeat },
+ { "XF86AudioRewind", XKB_KEY_XF86AudioRewind },
+ { "XF86AudioStop", XKB_KEY_XF86AudioStop },
+ { "XF86Away", XKB_KEY_XF86Away },
+ { "XF86Back", XKB_KEY_XF86Back },
+ { "XF86BackForward", XKB_KEY_XF86BackForward },
+ { "XF86Battery", XKB_KEY_XF86Battery },
+ { "XF86Blue", XKB_KEY_XF86Blue },
+ { "XF86Bluetooth", XKB_KEY_XF86Bluetooth },
+ { "XF86Book", XKB_KEY_XF86Book },
+ { "XF86BrightnessAdjust", XKB_KEY_XF86BrightnessAdjust },
+ { "XF86Calculater", XKB_KEY_XF86Calculater },
+ { "XF86Calculator", XKB_KEY_XF86Calculator },
+ { "XF86Calendar", XKB_KEY_XF86Calendar },
+ { "XF86CD", XKB_KEY_XF86CD },
+ { "XF86Clear", XKB_KEY_XF86Clear },
+ { "XF86ClearGrab", XKB_KEY_XF86ClearGrab },
+ { "XF86Close", XKB_KEY_XF86Close },
+ { "XF86Community", XKB_KEY_XF86Community },
+ { "XF86ContrastAdjust", XKB_KEY_XF86ContrastAdjust },
+ { "XF86Copy", XKB_KEY_XF86Copy },
+ { "XF86Cut", XKB_KEY_XF86Cut },
+ { "XF86CycleAngle", XKB_KEY_XF86CycleAngle },
+ { "XF86Display", XKB_KEY_XF86Display },
+ { "XF86Documents", XKB_KEY_XF86Documents },
+ { "XF86DOS", XKB_KEY_XF86DOS },
+ { "XF86Eject", XKB_KEY_XF86Eject },
+ { "XF86Excel", XKB_KEY_XF86Excel },
+ { "XF86Explorer", XKB_KEY_XF86Explorer },
+ { "XF86Favorites", XKB_KEY_XF86Favorites },
+ { "XF86Finance", XKB_KEY_XF86Finance },
+ { "XF86Forward", XKB_KEY_XF86Forward },
+ { "XF86FrameBack", XKB_KEY_XF86FrameBack },
+ { "XF86FrameForward", XKB_KEY_XF86FrameForward },
+ { "XF86Game", XKB_KEY_XF86Game },
+ { "XF86Go", XKB_KEY_XF86Go },
+ { "XF86Green", XKB_KEY_XF86Green },
+ { "XF86Hibernate", XKB_KEY_XF86Hibernate },
+ { "XF86History", XKB_KEY_XF86History },
+ { "XF86HomePage", XKB_KEY_XF86HomePage },
+ { "XF86HotLinks", XKB_KEY_XF86HotLinks },
+ { "XF86iTouch", XKB_KEY_XF86iTouch },
+ { "XF86KbdBrightnessDown", XKB_KEY_XF86KbdBrightnessDown },
+ { "XF86KbdBrightnessUp", XKB_KEY_XF86KbdBrightnessUp },
+ { "XF86KbdLightOnOff", XKB_KEY_XF86KbdLightOnOff },
+ { "XF86Launch0", XKB_KEY_XF86Launch0 },
+ { "XF86Launch1", XKB_KEY_XF86Launch1 },
+ { "XF86Launch2", XKB_KEY_XF86Launch2 },
+ { "XF86Launch3", XKB_KEY_XF86Launch3 },
+ { "XF86Launch4", XKB_KEY_XF86Launch4 },
+ { "XF86Launch5", XKB_KEY_XF86Launch5 },
+ { "XF86Launch6", XKB_KEY_XF86Launch6 },
+ { "XF86Launch7", XKB_KEY_XF86Launch7 },
+ { "XF86Launch8", XKB_KEY_XF86Launch8 },
+ { "XF86Launch9", XKB_KEY_XF86Launch9 },
+ { "XF86LaunchA", XKB_KEY_XF86LaunchA },
+ { "XF86LaunchB", XKB_KEY_XF86LaunchB },
+ { "XF86LaunchC", XKB_KEY_XF86LaunchC },
+ { "XF86LaunchD", XKB_KEY_XF86LaunchD },
+ { "XF86LaunchE", XKB_KEY_XF86LaunchE },
+ { "XF86LaunchF", XKB_KEY_XF86LaunchF },
+ { "XF86LightBulb", XKB_KEY_XF86LightBulb },
+ { "XF86LogGrabInfo", XKB_KEY_XF86LogGrabInfo },
+ { "XF86LogOff", XKB_KEY_XF86LogOff },
+ { "XF86LogWindowTree", XKB_KEY_XF86LogWindowTree },
+ { "XF86Mail", XKB_KEY_XF86Mail },
+ { "XF86MailForward", XKB_KEY_XF86MailForward },
+ { "XF86Market", XKB_KEY_XF86Market },
+ { "XF86Meeting", XKB_KEY_XF86Meeting },
+ { "XF86Memo", XKB_KEY_XF86Memo },
+ { "XF86MenuKB", XKB_KEY_XF86MenuKB },
+ { "XF86MenuPB", XKB_KEY_XF86MenuPB },
+ { "XF86Messenger", XKB_KEY_XF86Messenger },
+ { "XF86ModeLock", XKB_KEY_XF86ModeLock },
+ { "XF86MonBrightnessDown", XKB_KEY_XF86MonBrightnessDown },
+ { "XF86MonBrightnessUp", XKB_KEY_XF86MonBrightnessUp },
+ { "XF86Music", XKB_KEY_XF86Music },
+ { "XF86MyComputer", XKB_KEY_XF86MyComputer },
+ { "XF86MySites", XKB_KEY_XF86MySites },
+ { "XF86New", XKB_KEY_XF86New },
+ { "XF86News", XKB_KEY_XF86News },
+ { "XF86Next_VMode", XKB_KEY_XF86Next_VMode },
+ { "XF86OfficeHome", XKB_KEY_XF86OfficeHome },
+ { "XF86Open", XKB_KEY_XF86Open },
+ { "XF86OpenURL", XKB_KEY_XF86OpenURL },
+ { "XF86Option", XKB_KEY_XF86Option },
+ { "XF86Paste", XKB_KEY_XF86Paste },
+ { "XF86Phone", XKB_KEY_XF86Phone },
+ { "XF86Pictures", XKB_KEY_XF86Pictures },
+ { "XF86PowerDown", XKB_KEY_XF86PowerDown },
+ { "XF86PowerOff", XKB_KEY_XF86PowerOff },
+ { "XF86Prev_VMode", XKB_KEY_XF86Prev_VMode },
+ { "XF86Q", XKB_KEY_XF86Q },
+ { "XF86Red", XKB_KEY_XF86Red },
+ { "XF86Refresh", XKB_KEY_XF86Refresh },
+ { "XF86Reload", XKB_KEY_XF86Reload },
+ { "XF86Reply", XKB_KEY_XF86Reply },
+ { "XF86RockerDown", XKB_KEY_XF86RockerDown },
+ { "XF86RockerEnter", XKB_KEY_XF86RockerEnter },
+ { "XF86RockerUp", XKB_KEY_XF86RockerUp },
+ { "XF86RotateWindows", XKB_KEY_XF86RotateWindows },
+ { "XF86RotationKB", XKB_KEY_XF86RotationKB },
+ { "XF86RotationPB", XKB_KEY_XF86RotationPB },
+ { "XF86Save", XKB_KEY_XF86Save },
+ { "XF86ScreenSaver", XKB_KEY_XF86ScreenSaver },
+ { "XF86ScrollClick", XKB_KEY_XF86ScrollClick },
+ { "XF86ScrollDown", XKB_KEY_XF86ScrollDown },
+ { "XF86ScrollUp", XKB_KEY_XF86ScrollUp },
+ { "XF86Search", XKB_KEY_XF86Search },
+ { "XF86Select", XKB_KEY_XF86Select },
+ { "XF86Send", XKB_KEY_XF86Send },
+ { "XF86Shop", XKB_KEY_XF86Shop },
+ { "XF86Sleep", XKB_KEY_XF86Sleep },
+ { "XF86Spell", XKB_KEY_XF86Spell },
+ { "XF86SplitScreen", XKB_KEY_XF86SplitScreen },
+ { "XF86Standby", XKB_KEY_XF86Standby },
+ { "XF86Start", XKB_KEY_XF86Start },
+ { "XF86Stop", XKB_KEY_XF86Stop },
+ { "XF86Subtitle", XKB_KEY_XF86Subtitle },
+ { "XF86Support", XKB_KEY_XF86Support },
+ { "XF86Suspend", XKB_KEY_XF86Suspend },
+ { "XF86Switch_VT_1", XKB_KEY_XF86Switch_VT_1 },
+ { "XF86Switch_VT_10", XKB_KEY_XF86Switch_VT_10 },
+ { "XF86Switch_VT_11", XKB_KEY_XF86Switch_VT_11 },
+ { "XF86Switch_VT_12", XKB_KEY_XF86Switch_VT_12 },
+ { "XF86Switch_VT_2", XKB_KEY_XF86Switch_VT_2 },
+ { "XF86Switch_VT_3", XKB_KEY_XF86Switch_VT_3 },
+ { "XF86Switch_VT_4", XKB_KEY_XF86Switch_VT_4 },
+ { "XF86Switch_VT_5", XKB_KEY_XF86Switch_VT_5 },
+ { "XF86Switch_VT_6", XKB_KEY_XF86Switch_VT_6 },
+ { "XF86Switch_VT_7", XKB_KEY_XF86Switch_VT_7 },
+ { "XF86Switch_VT_8", XKB_KEY_XF86Switch_VT_8 },
+ { "XF86Switch_VT_9", XKB_KEY_XF86Switch_VT_9 },
+ { "XF86TaskPane", XKB_KEY_XF86TaskPane },
+ { "XF86Terminal", XKB_KEY_XF86Terminal },
+ { "XF86Time", XKB_KEY_XF86Time },
+ { "XF86ToDoList", XKB_KEY_XF86ToDoList },
+ { "XF86Tools", XKB_KEY_XF86Tools },
+ { "XF86TopMenu", XKB_KEY_XF86TopMenu },
+ { "XF86TouchpadOff", XKB_KEY_XF86TouchpadOff },
+ { "XF86TouchpadOn", XKB_KEY_XF86TouchpadOn },
+ { "XF86TouchpadToggle", XKB_KEY_XF86TouchpadToggle },
+ { "XF86Travel", XKB_KEY_XF86Travel },
+ { "XF86Ungrab", XKB_KEY_XF86Ungrab },
+ { "XF86User1KB", XKB_KEY_XF86User1KB },
+ { "XF86User2KB", XKB_KEY_XF86User2KB },
+ { "XF86UserPB", XKB_KEY_XF86UserPB },
+ { "XF86UWB", XKB_KEY_XF86UWB },
+ { "XF86VendorHome", XKB_KEY_XF86VendorHome },
+ { "XF86Video", XKB_KEY_XF86Video },
+ { "XF86View", XKB_KEY_XF86View },
+ { "XF86WakeUp", XKB_KEY_XF86WakeUp },
+ { "XF86WebCam", XKB_KEY_XF86WebCam },
+ { "XF86WheelButton", XKB_KEY_XF86WheelButton },
+ { "XF86WLAN", XKB_KEY_XF86WLAN },
+ { "XF86Word", XKB_KEY_XF86Word },
+ { "XF86WWW", XKB_KEY_XF86WWW },
+ { "XF86Xfer", XKB_KEY_XF86Xfer },
+ { "XF86Yellow", XKB_KEY_XF86Yellow },
+ { "XF86ZoomIn", XKB_KEY_XF86ZoomIn },
+ { "XF86ZoomOut", XKB_KEY_XF86ZoomOut },
+ { "Y", XKB_KEY_Y },
+ { "y", XKB_KEY_y },
+ { "Yacute", XKB_KEY_Yacute },
+ { "yacute", XKB_KEY_yacute },
+ { "Ybelowdot", XKB_KEY_Ybelowdot },
+ { "ybelowdot", XKB_KEY_ybelowdot },
+ { "Ycircumflex", XKB_KEY_Ycircumflex },
+ { "ycircumflex", XKB_KEY_ycircumflex },
+ { "ydiaeresis", XKB_KEY_ydiaeresis },
+ { "Ydiaeresis", XKB_KEY_Ydiaeresis },
+ { "yen", XKB_KEY_yen },
+ { "Ygrave", XKB_KEY_Ygrave },
+ { "ygrave", XKB_KEY_ygrave },
+ { "Yhook", XKB_KEY_Yhook },
+ { "yhook", XKB_KEY_yhook },
+ { "Ytilde", XKB_KEY_Ytilde },
+ { "ytilde", XKB_KEY_ytilde },
+ { "Z", XKB_KEY_Z },
+ { "z", XKB_KEY_z },
+ { "Zabovedot", XKB_KEY_Zabovedot },
+ { "zabovedot", XKB_KEY_zabovedot },
+ { "Zacute", XKB_KEY_Zacute },
+ { "zacute", XKB_KEY_zacute },
+ { "Zcaron", XKB_KEY_Zcaron },
+ { "zcaron", XKB_KEY_zcaron },
+ { "Zen_Koho", XKB_KEY_Zen_Koho },
+ { "Zenkaku", XKB_KEY_Zenkaku },
+ { "Zenkaku_Hankaku", XKB_KEY_Zenkaku_Hankaku },
+ { "zerosubscript", XKB_KEY_zerosubscript },
+ { "zerosuperior", XKB_KEY_zerosuperior },
+ { "Zstroke", XKB_KEY_Zstroke },
+ { "zstroke", XKB_KEY_zstroke },
+};
+
+static const struct name_keysym keysym_to_name[] = {
+ { "NoSymbol", XKB_KEY_NoSymbol },
+ { "space", XKB_KEY_space },
+ { "exclam", XKB_KEY_exclam },
+ { "quotedbl", XKB_KEY_quotedbl },
+ { "numbersign", XKB_KEY_numbersign },
+ { "dollar", XKB_KEY_dollar },
+ { "percent", XKB_KEY_percent },
+ { "ampersand", XKB_KEY_ampersand },
+ { "apostrophe", XKB_KEY_apostrophe },
+ { "parenleft", XKB_KEY_parenleft },
+ { "parenright", XKB_KEY_parenright },
+ { "asterisk", XKB_KEY_asterisk },
+ { "plus", XKB_KEY_plus },
+ { "comma", XKB_KEY_comma },
+ { "minus", XKB_KEY_minus },
+ { "period", XKB_KEY_period },
+ { "slash", XKB_KEY_slash },
+ { "0", XKB_KEY_0 },
+ { "1", XKB_KEY_1 },
+ { "2", XKB_KEY_2 },
+ { "3", XKB_KEY_3 },
+ { "4", XKB_KEY_4 },
+ { "5", XKB_KEY_5 },
+ { "6", XKB_KEY_6 },
+ { "7", XKB_KEY_7 },
+ { "8", XKB_KEY_8 },
+ { "9", XKB_KEY_9 },
+ { "colon", XKB_KEY_colon },
+ { "semicolon", XKB_KEY_semicolon },
+ { "less", XKB_KEY_less },
+ { "equal", XKB_KEY_equal },
+ { "greater", XKB_KEY_greater },
+ { "question", XKB_KEY_question },
+ { "at", XKB_KEY_at },
+ { "A", XKB_KEY_A },
+ { "B", XKB_KEY_B },
+ { "C", XKB_KEY_C },
+ { "D", XKB_KEY_D },
+ { "E", XKB_KEY_E },
+ { "F", XKB_KEY_F },
+ { "G", XKB_KEY_G },
+ { "H", XKB_KEY_H },
+ { "I", XKB_KEY_I },
+ { "J", XKB_KEY_J },
+ { "K", XKB_KEY_K },
+ { "L", XKB_KEY_L },
+ { "M", XKB_KEY_M },
+ { "N", XKB_KEY_N },
+ { "O", XKB_KEY_O },
+ { "P", XKB_KEY_P },
+ { "Q", XKB_KEY_Q },
+ { "R", XKB_KEY_R },
+ { "S", XKB_KEY_S },
+ { "T", XKB_KEY_T },
+ { "U", XKB_KEY_U },
+ { "V", XKB_KEY_V },
+ { "W", XKB_KEY_W },
+ { "X", XKB_KEY_X },
+ { "Y", XKB_KEY_Y },
+ { "Z", XKB_KEY_Z },
+ { "bracketleft", XKB_KEY_bracketleft },
+ { "backslash", XKB_KEY_backslash },
+ { "bracketright", XKB_KEY_bracketright },
+ { "asciicircum", XKB_KEY_asciicircum },
+ { "underscore", XKB_KEY_underscore },
+ { "grave", XKB_KEY_grave },
+ { "a", XKB_KEY_a },
+ { "b", XKB_KEY_b },
+ { "c", XKB_KEY_c },
+ { "d", XKB_KEY_d },
+ { "e", XKB_KEY_e },
+ { "f", XKB_KEY_f },
+ { "g", XKB_KEY_g },
+ { "h", XKB_KEY_h },
+ { "i", XKB_KEY_i },
+ { "j", XKB_KEY_j },
+ { "k", XKB_KEY_k },
+ { "l", XKB_KEY_l },
+ { "m", XKB_KEY_m },
+ { "n", XKB_KEY_n },
+ { "o", XKB_KEY_o },
+ { "p", XKB_KEY_p },
+ { "q", XKB_KEY_q },
+ { "r", XKB_KEY_r },
+ { "s", XKB_KEY_s },
+ { "t", XKB_KEY_t },
+ { "u", XKB_KEY_u },
+ { "v", XKB_KEY_v },
+ { "w", XKB_KEY_w },
+ { "x", XKB_KEY_x },
+ { "y", XKB_KEY_y },
+ { "z", XKB_KEY_z },
+ { "braceleft", XKB_KEY_braceleft },
+ { "bar", XKB_KEY_bar },
+ { "braceright", XKB_KEY_braceright },
+ { "asciitilde", XKB_KEY_asciitilde },
+ { "nobreakspace", XKB_KEY_nobreakspace },
+ { "exclamdown", XKB_KEY_exclamdown },
+ { "cent", XKB_KEY_cent },
+ { "sterling", XKB_KEY_sterling },
+ { "currency", XKB_KEY_currency },
+ { "yen", XKB_KEY_yen },
+ { "brokenbar", XKB_KEY_brokenbar },
+ { "section", XKB_KEY_section },
+ { "diaeresis", XKB_KEY_diaeresis },
+ { "copyright", XKB_KEY_copyright },
+ { "ordfeminine", XKB_KEY_ordfeminine },
+ { "guillemotleft", XKB_KEY_guillemotleft },
+ { "notsign", XKB_KEY_notsign },
+ { "hyphen", XKB_KEY_hyphen },
+ { "registered", XKB_KEY_registered },
+ { "macron", XKB_KEY_macron },
+ { "degree", XKB_KEY_degree },
+ { "plusminus", XKB_KEY_plusminus },
+ { "twosuperior", XKB_KEY_twosuperior },
+ { "threesuperior", XKB_KEY_threesuperior },
+ { "acute", XKB_KEY_acute },
+ { "mu", XKB_KEY_mu },
+ { "paragraph", XKB_KEY_paragraph },
+ { "periodcentered", XKB_KEY_periodcentered },
+ { "cedilla", XKB_KEY_cedilla },
+ { "onesuperior", XKB_KEY_onesuperior },
+ { "masculine", XKB_KEY_masculine },
+ { "guillemotright", XKB_KEY_guillemotright },
+ { "onequarter", XKB_KEY_onequarter },
+ { "onehalf", XKB_KEY_onehalf },
+ { "threequarters", XKB_KEY_threequarters },
+ { "questiondown", XKB_KEY_questiondown },
+ { "Agrave", XKB_KEY_Agrave },
+ { "Aacute", XKB_KEY_Aacute },
+ { "Acircumflex", XKB_KEY_Acircumflex },
+ { "Atilde", XKB_KEY_Atilde },
+ { "Adiaeresis", XKB_KEY_Adiaeresis },
+ { "Aring", XKB_KEY_Aring },
+ { "AE", XKB_KEY_AE },
+ { "Ccedilla", XKB_KEY_Ccedilla },
+ { "Egrave", XKB_KEY_Egrave },
+ { "Eacute", XKB_KEY_Eacute },
+ { "Ecircumflex", XKB_KEY_Ecircumflex },
+ { "Ediaeresis", XKB_KEY_Ediaeresis },
+ { "Igrave", XKB_KEY_Igrave },
+ { "Iacute", XKB_KEY_Iacute },
+ { "Icircumflex", XKB_KEY_Icircumflex },
+ { "Idiaeresis", XKB_KEY_Idiaeresis },
+ { "ETH", XKB_KEY_ETH },
+ { "Ntilde", XKB_KEY_Ntilde },
+ { "Ograve", XKB_KEY_Ograve },
+ { "Oacute", XKB_KEY_Oacute },
+ { "Ocircumflex", XKB_KEY_Ocircumflex },
+ { "Otilde", XKB_KEY_Otilde },
+ { "Odiaeresis", XKB_KEY_Odiaeresis },
+ { "multiply", XKB_KEY_multiply },
+ { "Oslash", XKB_KEY_Oslash },
+ { "Ugrave", XKB_KEY_Ugrave },
+ { "Uacute", XKB_KEY_Uacute },
+ { "Ucircumflex", XKB_KEY_Ucircumflex },
+ { "Udiaeresis", XKB_KEY_Udiaeresis },
+ { "Yacute", XKB_KEY_Yacute },
+ { "THORN", XKB_KEY_THORN },
+ { "ssharp", XKB_KEY_ssharp },
+ { "agrave", XKB_KEY_agrave },
+ { "aacute", XKB_KEY_aacute },
+ { "acircumflex", XKB_KEY_acircumflex },
+ { "atilde", XKB_KEY_atilde },
+ { "adiaeresis", XKB_KEY_adiaeresis },
+ { "aring", XKB_KEY_aring },
+ { "ae", XKB_KEY_ae },
+ { "ccedilla", XKB_KEY_ccedilla },
+ { "egrave", XKB_KEY_egrave },
+ { "eacute", XKB_KEY_eacute },
+ { "ecircumflex", XKB_KEY_ecircumflex },
+ { "ediaeresis", XKB_KEY_ediaeresis },
+ { "igrave", XKB_KEY_igrave },
+ { "iacute", XKB_KEY_iacute },
+ { "icircumflex", XKB_KEY_icircumflex },
+ { "idiaeresis", XKB_KEY_idiaeresis },
+ { "eth", XKB_KEY_eth },
+ { "ntilde", XKB_KEY_ntilde },
+ { "ograve", XKB_KEY_ograve },
+ { "oacute", XKB_KEY_oacute },
+ { "ocircumflex", XKB_KEY_ocircumflex },
+ { "otilde", XKB_KEY_otilde },
+ { "odiaeresis", XKB_KEY_odiaeresis },
+ { "division", XKB_KEY_division },
+ { "oslash", XKB_KEY_oslash },
+ { "ugrave", XKB_KEY_ugrave },
+ { "uacute", XKB_KEY_uacute },
+ { "ucircumflex", XKB_KEY_ucircumflex },
+ { "udiaeresis", XKB_KEY_udiaeresis },
+ { "yacute", XKB_KEY_yacute },
+ { "thorn", XKB_KEY_thorn },
+ { "ydiaeresis", XKB_KEY_ydiaeresis },
+ { "Aogonek", XKB_KEY_Aogonek },
+ { "breve", XKB_KEY_breve },
+ { "Lstroke", XKB_KEY_Lstroke },
+ { "Lcaron", XKB_KEY_Lcaron },
+ { "Sacute", XKB_KEY_Sacute },
+ { "Scaron", XKB_KEY_Scaron },
+ { "Scedilla", XKB_KEY_Scedilla },
+ { "Tcaron", XKB_KEY_Tcaron },
+ { "Zacute", XKB_KEY_Zacute },
+ { "Zcaron", XKB_KEY_Zcaron },
+ { "Zabovedot", XKB_KEY_Zabovedot },
+ { "aogonek", XKB_KEY_aogonek },
+ { "ogonek", XKB_KEY_ogonek },
+ { "lstroke", XKB_KEY_lstroke },
+ { "lcaron", XKB_KEY_lcaron },
+ { "sacute", XKB_KEY_sacute },
+ { "caron", XKB_KEY_caron },
+ { "scaron", XKB_KEY_scaron },
+ { "scedilla", XKB_KEY_scedilla },
+ { "tcaron", XKB_KEY_tcaron },
+ { "zacute", XKB_KEY_zacute },
+ { "doubleacute", XKB_KEY_doubleacute },
+ { "zcaron", XKB_KEY_zcaron },
+ { "zabovedot", XKB_KEY_zabovedot },
+ { "Racute", XKB_KEY_Racute },
+ { "Abreve", XKB_KEY_Abreve },
+ { "Lacute", XKB_KEY_Lacute },
+ { "Cacute", XKB_KEY_Cacute },
+ { "Ccaron", XKB_KEY_Ccaron },
+ { "Eogonek", XKB_KEY_Eogonek },
+ { "Ecaron", XKB_KEY_Ecaron },
+ { "Dcaron", XKB_KEY_Dcaron },
+ { "Dstroke", XKB_KEY_Dstroke },
+ { "Nacute", XKB_KEY_Nacute },
+ { "Ncaron", XKB_KEY_Ncaron },
+ { "Odoubleacute", XKB_KEY_Odoubleacute },
+ { "Rcaron", XKB_KEY_Rcaron },
+ { "Uring", XKB_KEY_Uring },
+ { "Udoubleacute", XKB_KEY_Udoubleacute },
+ { "Tcedilla", XKB_KEY_Tcedilla },
+ { "racute", XKB_KEY_racute },
+ { "abreve", XKB_KEY_abreve },
+ { "lacute", XKB_KEY_lacute },
+ { "cacute", XKB_KEY_cacute },
+ { "ccaron", XKB_KEY_ccaron },
+ { "eogonek", XKB_KEY_eogonek },
+ { "ecaron", XKB_KEY_ecaron },
+ { "dcaron", XKB_KEY_dcaron },
+ { "dstroke", XKB_KEY_dstroke },
+ { "nacute", XKB_KEY_nacute },
+ { "ncaron", XKB_KEY_ncaron },
+ { "odoubleacute", XKB_KEY_odoubleacute },
+ { "rcaron", XKB_KEY_rcaron },
+ { "uring", XKB_KEY_uring },
+ { "udoubleacute", XKB_KEY_udoubleacute },
+ { "tcedilla", XKB_KEY_tcedilla },
+ { "abovedot", XKB_KEY_abovedot },
+ { "Hstroke", XKB_KEY_Hstroke },
+ { "Hcircumflex", XKB_KEY_Hcircumflex },
+ { "Iabovedot", XKB_KEY_Iabovedot },
+ { "Gbreve", XKB_KEY_Gbreve },
+ { "Jcircumflex", XKB_KEY_Jcircumflex },
+ { "hstroke", XKB_KEY_hstroke },
+ { "hcircumflex", XKB_KEY_hcircumflex },
+ { "idotless", XKB_KEY_idotless },
+ { "gbreve", XKB_KEY_gbreve },
+ { "jcircumflex", XKB_KEY_jcircumflex },
+ { "Cabovedot", XKB_KEY_Cabovedot },
+ { "Ccircumflex", XKB_KEY_Ccircumflex },
+ { "Gabovedot", XKB_KEY_Gabovedot },
+ { "Gcircumflex", XKB_KEY_Gcircumflex },
+ { "Ubreve", XKB_KEY_Ubreve },
+ { "Scircumflex", XKB_KEY_Scircumflex },
+ { "cabovedot", XKB_KEY_cabovedot },
+ { "ccircumflex", XKB_KEY_ccircumflex },
+ { "gabovedot", XKB_KEY_gabovedot },
+ { "gcircumflex", XKB_KEY_gcircumflex },
+ { "ubreve", XKB_KEY_ubreve },
+ { "scircumflex", XKB_KEY_scircumflex },
+ { "kra", XKB_KEY_kra },
+ { "Rcedilla", XKB_KEY_Rcedilla },
+ { "Itilde", XKB_KEY_Itilde },
+ { "Lcedilla", XKB_KEY_Lcedilla },
+ { "Emacron", XKB_KEY_Emacron },
+ { "Gcedilla", XKB_KEY_Gcedilla },
+ { "Tslash", XKB_KEY_Tslash },
+ { "rcedilla", XKB_KEY_rcedilla },
+ { "itilde", XKB_KEY_itilde },
+ { "lcedilla", XKB_KEY_lcedilla },
+ { "emacron", XKB_KEY_emacron },
+ { "gcedilla", XKB_KEY_gcedilla },
+ { "tslash", XKB_KEY_tslash },
+ { "ENG", XKB_KEY_ENG },
+ { "eng", XKB_KEY_eng },
+ { "Amacron", XKB_KEY_Amacron },
+ { "Iogonek", XKB_KEY_Iogonek },
+ { "Eabovedot", XKB_KEY_Eabovedot },
+ { "Imacron", XKB_KEY_Imacron },
+ { "Ncedilla", XKB_KEY_Ncedilla },
+ { "Omacron", XKB_KEY_Omacron },
+ { "Kcedilla", XKB_KEY_Kcedilla },
+ { "Uogonek", XKB_KEY_Uogonek },
+ { "Utilde", XKB_KEY_Utilde },
+ { "Umacron", XKB_KEY_Umacron },
+ { "amacron", XKB_KEY_amacron },
+ { "iogonek", XKB_KEY_iogonek },
+ { "eabovedot", XKB_KEY_eabovedot },
+ { "imacron", XKB_KEY_imacron },
+ { "ncedilla", XKB_KEY_ncedilla },
+ { "omacron", XKB_KEY_omacron },
+ { "kcedilla", XKB_KEY_kcedilla },
+ { "uogonek", XKB_KEY_uogonek },
+ { "utilde", XKB_KEY_utilde },
+ { "umacron", XKB_KEY_umacron },
+ { "overline", XKB_KEY_overline },
+ { "kana_fullstop", XKB_KEY_kana_fullstop },
+ { "kana_openingbracket", XKB_KEY_kana_openingbracket },
+ { "kana_closingbracket", XKB_KEY_kana_closingbracket },
+ { "kana_comma", XKB_KEY_kana_comma },
+ { "kana_conjunctive", XKB_KEY_kana_conjunctive },
+ { "kana_WO", XKB_KEY_kana_WO },
+ { "kana_a", XKB_KEY_kana_a },
+ { "kana_i", XKB_KEY_kana_i },
+ { "kana_u", XKB_KEY_kana_u },
+ { "kana_e", XKB_KEY_kana_e },
+ { "kana_o", XKB_KEY_kana_o },
+ { "kana_ya", XKB_KEY_kana_ya },
+ { "kana_yu", XKB_KEY_kana_yu },
+ { "kana_yo", XKB_KEY_kana_yo },
+ { "kana_tsu", XKB_KEY_kana_tsu },
+ { "prolongedsound", XKB_KEY_prolongedsound },
+ { "kana_A", XKB_KEY_kana_A },
+ { "kana_I", XKB_KEY_kana_I },
+ { "kana_U", XKB_KEY_kana_U },
+ { "kana_E", XKB_KEY_kana_E },
+ { "kana_O", XKB_KEY_kana_O },
+ { "kana_KA", XKB_KEY_kana_KA },
+ { "kana_KI", XKB_KEY_kana_KI },
+ { "kana_KU", XKB_KEY_kana_KU },
+ { "kana_KE", XKB_KEY_kana_KE },
+ { "kana_KO", XKB_KEY_kana_KO },
+ { "kana_SA", XKB_KEY_kana_SA },
+ { "kana_SHI", XKB_KEY_kana_SHI },
+ { "kana_SU", XKB_KEY_kana_SU },
+ { "kana_SE", XKB_KEY_kana_SE },
+ { "kana_SO", XKB_KEY_kana_SO },
+ { "kana_TA", XKB_KEY_kana_TA },
+ { "kana_CHI", XKB_KEY_kana_CHI },
+ { "kana_TSU", XKB_KEY_kana_TSU },
+ { "kana_TE", XKB_KEY_kana_TE },
+ { "kana_TO", XKB_KEY_kana_TO },
+ { "kana_NA", XKB_KEY_kana_NA },
+ { "kana_NI", XKB_KEY_kana_NI },
+ { "kana_NU", XKB_KEY_kana_NU },
+ { "kana_NE", XKB_KEY_kana_NE },
+ { "kana_NO", XKB_KEY_kana_NO },
+ { "kana_HA", XKB_KEY_kana_HA },
+ { "kana_HI", XKB_KEY_kana_HI },
+ { "kana_FU", XKB_KEY_kana_FU },
+ { "kana_HE", XKB_KEY_kana_HE },
+ { "kana_HO", XKB_KEY_kana_HO },
+ { "kana_MA", XKB_KEY_kana_MA },
+ { "kana_MI", XKB_KEY_kana_MI },
+ { "kana_MU", XKB_KEY_kana_MU },
+ { "kana_ME", XKB_KEY_kana_ME },
+ { "kana_MO", XKB_KEY_kana_MO },
+ { "kana_YA", XKB_KEY_kana_YA },
+ { "kana_YU", XKB_KEY_kana_YU },
+ { "kana_YO", XKB_KEY_kana_YO },
+ { "kana_RA", XKB_KEY_kana_RA },
+ { "kana_RI", XKB_KEY_kana_RI },
+ { "kana_RU", XKB_KEY_kana_RU },
+ { "kana_RE", XKB_KEY_kana_RE },
+ { "kana_RO", XKB_KEY_kana_RO },
+ { "kana_WA", XKB_KEY_kana_WA },
+ { "kana_N", XKB_KEY_kana_N },
+ { "voicedsound", XKB_KEY_voicedsound },
+ { "semivoicedsound", XKB_KEY_semivoicedsound },
+ { "Arabic_comma", XKB_KEY_Arabic_comma },
+ { "Arabic_semicolon", XKB_KEY_Arabic_semicolon },
+ { "Arabic_question_mark", XKB_KEY_Arabic_question_mark },
+ { "Arabic_hamza", XKB_KEY_Arabic_hamza },
+ { "Arabic_maddaonalef", XKB_KEY_Arabic_maddaonalef },
+ { "Arabic_hamzaonalef", XKB_KEY_Arabic_hamzaonalef },
+ { "Arabic_hamzaonwaw", XKB_KEY_Arabic_hamzaonwaw },
+ { "Arabic_hamzaunderalef", XKB_KEY_Arabic_hamzaunderalef },
+ { "Arabic_hamzaonyeh", XKB_KEY_Arabic_hamzaonyeh },
+ { "Arabic_alef", XKB_KEY_Arabic_alef },
+ { "Arabic_beh", XKB_KEY_Arabic_beh },
+ { "Arabic_tehmarbuta", XKB_KEY_Arabic_tehmarbuta },
+ { "Arabic_teh", XKB_KEY_Arabic_teh },
+ { "Arabic_theh", XKB_KEY_Arabic_theh },
+ { "Arabic_jeem", XKB_KEY_Arabic_jeem },
+ { "Arabic_hah", XKB_KEY_Arabic_hah },
+ { "Arabic_khah", XKB_KEY_Arabic_khah },
+ { "Arabic_dal", XKB_KEY_Arabic_dal },
+ { "Arabic_thal", XKB_KEY_Arabic_thal },
+ { "Arabic_ra", XKB_KEY_Arabic_ra },
+ { "Arabic_zain", XKB_KEY_Arabic_zain },
+ { "Arabic_seen", XKB_KEY_Arabic_seen },
+ { "Arabic_sheen", XKB_KEY_Arabic_sheen },
+ { "Arabic_sad", XKB_KEY_Arabic_sad },
+ { "Arabic_dad", XKB_KEY_Arabic_dad },
+ { "Arabic_tah", XKB_KEY_Arabic_tah },
+ { "Arabic_zah", XKB_KEY_Arabic_zah },
+ { "Arabic_ain", XKB_KEY_Arabic_ain },
+ { "Arabic_ghain", XKB_KEY_Arabic_ghain },
+ { "Arabic_tatweel", XKB_KEY_Arabic_tatweel },
+ { "Arabic_feh", XKB_KEY_Arabic_feh },
+ { "Arabic_qaf", XKB_KEY_Arabic_qaf },
+ { "Arabic_kaf", XKB_KEY_Arabic_kaf },
+ { "Arabic_lam", XKB_KEY_Arabic_lam },
+ { "Arabic_meem", XKB_KEY_Arabic_meem },
+ { "Arabic_noon", XKB_KEY_Arabic_noon },
+ { "Arabic_ha", XKB_KEY_Arabic_ha },
+ { "Arabic_waw", XKB_KEY_Arabic_waw },
+ { "Arabic_alefmaksura", XKB_KEY_Arabic_alefmaksura },
+ { "Arabic_yeh", XKB_KEY_Arabic_yeh },
+ { "Arabic_fathatan", XKB_KEY_Arabic_fathatan },
+ { "Arabic_dammatan", XKB_KEY_Arabic_dammatan },
+ { "Arabic_kasratan", XKB_KEY_Arabic_kasratan },
+ { "Arabic_fatha", XKB_KEY_Arabic_fatha },
+ { "Arabic_damma", XKB_KEY_Arabic_damma },
+ { "Arabic_kasra", XKB_KEY_Arabic_kasra },
+ { "Arabic_shadda", XKB_KEY_Arabic_shadda },
+ { "Arabic_sukun", XKB_KEY_Arabic_sukun },
+ { "Serbian_dje", XKB_KEY_Serbian_dje },
+ { "Macedonia_gje", XKB_KEY_Macedonia_gje },
+ { "Cyrillic_io", XKB_KEY_Cyrillic_io },
+ { "Ukrainian_ie", XKB_KEY_Ukrainian_ie },
+ { "Macedonia_dse", XKB_KEY_Macedonia_dse },
+ { "Ukrainian_i", XKB_KEY_Ukrainian_i },
+ { "Ukrainian_yi", XKB_KEY_Ukrainian_yi },
+ { "Cyrillic_je", XKB_KEY_Cyrillic_je },
+ { "Cyrillic_lje", XKB_KEY_Cyrillic_lje },
+ { "Cyrillic_nje", XKB_KEY_Cyrillic_nje },
+ { "Serbian_tshe", XKB_KEY_Serbian_tshe },
+ { "Macedonia_kje", XKB_KEY_Macedonia_kje },
+ { "Ukrainian_ghe_with_upturn", XKB_KEY_Ukrainian_ghe_with_upturn },
+ { "Byelorussian_shortu", XKB_KEY_Byelorussian_shortu },
+ { "Cyrillic_dzhe", XKB_KEY_Cyrillic_dzhe },
+ { "numerosign", XKB_KEY_numerosign },
+ { "Serbian_DJE", XKB_KEY_Serbian_DJE },
+ { "Macedonia_GJE", XKB_KEY_Macedonia_GJE },
+ { "Cyrillic_IO", XKB_KEY_Cyrillic_IO },
+ { "Ukrainian_IE", XKB_KEY_Ukrainian_IE },
+ { "Macedonia_DSE", XKB_KEY_Macedonia_DSE },
+ { "Ukrainian_I", XKB_KEY_Ukrainian_I },
+ { "Ukrainian_YI", XKB_KEY_Ukrainian_YI },
+ { "Cyrillic_JE", XKB_KEY_Cyrillic_JE },
+ { "Cyrillic_LJE", XKB_KEY_Cyrillic_LJE },
+ { "Cyrillic_NJE", XKB_KEY_Cyrillic_NJE },
+ { "Serbian_TSHE", XKB_KEY_Serbian_TSHE },
+ { "Macedonia_KJE", XKB_KEY_Macedonia_KJE },
+ { "Ukrainian_GHE_WITH_UPTURN", XKB_KEY_Ukrainian_GHE_WITH_UPTURN },
+ { "Byelorussian_SHORTU", XKB_KEY_Byelorussian_SHORTU },
+ { "Cyrillic_DZHE", XKB_KEY_Cyrillic_DZHE },
+ { "Cyrillic_yu", XKB_KEY_Cyrillic_yu },
+ { "Cyrillic_a", XKB_KEY_Cyrillic_a },
+ { "Cyrillic_be", XKB_KEY_Cyrillic_be },
+ { "Cyrillic_tse", XKB_KEY_Cyrillic_tse },
+ { "Cyrillic_de", XKB_KEY_Cyrillic_de },
+ { "Cyrillic_ie", XKB_KEY_Cyrillic_ie },
+ { "Cyrillic_ef", XKB_KEY_Cyrillic_ef },
+ { "Cyrillic_ghe", XKB_KEY_Cyrillic_ghe },
+ { "Cyrillic_ha", XKB_KEY_Cyrillic_ha },
+ { "Cyrillic_i", XKB_KEY_Cyrillic_i },
+ { "Cyrillic_shorti", XKB_KEY_Cyrillic_shorti },
+ { "Cyrillic_ka", XKB_KEY_Cyrillic_ka },
+ { "Cyrillic_el", XKB_KEY_Cyrillic_el },
+ { "Cyrillic_em", XKB_KEY_Cyrillic_em },
+ { "Cyrillic_en", XKB_KEY_Cyrillic_en },
+ { "Cyrillic_o", XKB_KEY_Cyrillic_o },
+ { "Cyrillic_pe", XKB_KEY_Cyrillic_pe },
+ { "Cyrillic_ya", XKB_KEY_Cyrillic_ya },
+ { "Cyrillic_er", XKB_KEY_Cyrillic_er },
+ { "Cyrillic_es", XKB_KEY_Cyrillic_es },
+ { "Cyrillic_te", XKB_KEY_Cyrillic_te },
+ { "Cyrillic_u", XKB_KEY_Cyrillic_u },
+ { "Cyrillic_zhe", XKB_KEY_Cyrillic_zhe },
+ { "Cyrillic_ve", XKB_KEY_Cyrillic_ve },
+ { "Cyrillic_softsign", XKB_KEY_Cyrillic_softsign },
+ { "Cyrillic_yeru", XKB_KEY_Cyrillic_yeru },
+ { "Cyrillic_ze", XKB_KEY_Cyrillic_ze },
+ { "Cyrillic_sha", XKB_KEY_Cyrillic_sha },
+ { "Cyrillic_e", XKB_KEY_Cyrillic_e },
+ { "Cyrillic_shcha", XKB_KEY_Cyrillic_shcha },
+ { "Cyrillic_che", XKB_KEY_Cyrillic_che },
+ { "Cyrillic_hardsign", XKB_KEY_Cyrillic_hardsign },
+ { "Cyrillic_YU", XKB_KEY_Cyrillic_YU },
+ { "Cyrillic_A", XKB_KEY_Cyrillic_A },
+ { "Cyrillic_BE", XKB_KEY_Cyrillic_BE },
+ { "Cyrillic_TSE", XKB_KEY_Cyrillic_TSE },
+ { "Cyrillic_DE", XKB_KEY_Cyrillic_DE },
+ { "Cyrillic_IE", XKB_KEY_Cyrillic_IE },
+ { "Cyrillic_EF", XKB_KEY_Cyrillic_EF },
+ { "Cyrillic_GHE", XKB_KEY_Cyrillic_GHE },
+ { "Cyrillic_HA", XKB_KEY_Cyrillic_HA },
+ { "Cyrillic_I", XKB_KEY_Cyrillic_I },
+ { "Cyrillic_SHORTI", XKB_KEY_Cyrillic_SHORTI },
+ { "Cyrillic_KA", XKB_KEY_Cyrillic_KA },
+ { "Cyrillic_EL", XKB_KEY_Cyrillic_EL },
+ { "Cyrillic_EM", XKB_KEY_Cyrillic_EM },
+ { "Cyrillic_EN", XKB_KEY_Cyrillic_EN },
+ { "Cyrillic_O", XKB_KEY_Cyrillic_O },
+ { "Cyrillic_PE", XKB_KEY_Cyrillic_PE },
+ { "Cyrillic_YA", XKB_KEY_Cyrillic_YA },
+ { "Cyrillic_ER", XKB_KEY_Cyrillic_ER },
+ { "Cyrillic_ES", XKB_KEY_Cyrillic_ES },
+ { "Cyrillic_TE", XKB_KEY_Cyrillic_TE },
+ { "Cyrillic_U", XKB_KEY_Cyrillic_U },
+ { "Cyrillic_ZHE", XKB_KEY_Cyrillic_ZHE },
+ { "Cyrillic_VE", XKB_KEY_Cyrillic_VE },
+ { "Cyrillic_SOFTSIGN", XKB_KEY_Cyrillic_SOFTSIGN },
+ { "Cyrillic_YERU", XKB_KEY_Cyrillic_YERU },
+ { "Cyrillic_ZE", XKB_KEY_Cyrillic_ZE },
+ { "Cyrillic_SHA", XKB_KEY_Cyrillic_SHA },
+ { "Cyrillic_E", XKB_KEY_Cyrillic_E },
+ { "Cyrillic_SHCHA", XKB_KEY_Cyrillic_SHCHA },
+ { "Cyrillic_CHE", XKB_KEY_Cyrillic_CHE },
+ { "Cyrillic_HARDSIGN", XKB_KEY_Cyrillic_HARDSIGN },
+ { "Greek_ALPHAaccent", XKB_KEY_Greek_ALPHAaccent },
+ { "Greek_EPSILONaccent", XKB_KEY_Greek_EPSILONaccent },
+ { "Greek_ETAaccent", XKB_KEY_Greek_ETAaccent },
+ { "Greek_IOTAaccent", XKB_KEY_Greek_IOTAaccent },
+ { "Greek_IOTAdieresis", XKB_KEY_Greek_IOTAdieresis },
+ { "Greek_OMICRONaccent", XKB_KEY_Greek_OMICRONaccent },
+ { "Greek_UPSILONaccent", XKB_KEY_Greek_UPSILONaccent },
+ { "Greek_UPSILONdieresis", XKB_KEY_Greek_UPSILONdieresis },
+ { "Greek_OMEGAaccent", XKB_KEY_Greek_OMEGAaccent },
+ { "Greek_accentdieresis", XKB_KEY_Greek_accentdieresis },
+ { "Greek_horizbar", XKB_KEY_Greek_horizbar },
+ { "Greek_alphaaccent", XKB_KEY_Greek_alphaaccent },
+ { "Greek_epsilonaccent", XKB_KEY_Greek_epsilonaccent },
+ { "Greek_etaaccent", XKB_KEY_Greek_etaaccent },
+ { "Greek_iotaaccent", XKB_KEY_Greek_iotaaccent },
+ { "Greek_iotadieresis", XKB_KEY_Greek_iotadieresis },
+ { "Greek_iotaaccentdieresis", XKB_KEY_Greek_iotaaccentdieresis },
+ { "Greek_omicronaccent", XKB_KEY_Greek_omicronaccent },
+ { "Greek_upsilonaccent", XKB_KEY_Greek_upsilonaccent },
+ { "Greek_upsilondieresis", XKB_KEY_Greek_upsilondieresis },
+ { "Greek_upsilonaccentdieresis", XKB_KEY_Greek_upsilonaccentdieresis },
+ { "Greek_omegaaccent", XKB_KEY_Greek_omegaaccent },
+ { "Greek_ALPHA", XKB_KEY_Greek_ALPHA },
+ { "Greek_BETA", XKB_KEY_Greek_BETA },
+ { "Greek_GAMMA", XKB_KEY_Greek_GAMMA },
+ { "Greek_DELTA", XKB_KEY_Greek_DELTA },
+ { "Greek_EPSILON", XKB_KEY_Greek_EPSILON },
+ { "Greek_ZETA", XKB_KEY_Greek_ZETA },
+ { "Greek_ETA", XKB_KEY_Greek_ETA },
+ { "Greek_THETA", XKB_KEY_Greek_THETA },
+ { "Greek_IOTA", XKB_KEY_Greek_IOTA },
+ { "Greek_KAPPA", XKB_KEY_Greek_KAPPA },
+ { "Greek_LAMDA", XKB_KEY_Greek_LAMDA },
+ { "Greek_MU", XKB_KEY_Greek_MU },
+ { "Greek_NU", XKB_KEY_Greek_NU },
+ { "Greek_XI", XKB_KEY_Greek_XI },
+ { "Greek_OMICRON", XKB_KEY_Greek_OMICRON },
+ { "Greek_PI", XKB_KEY_Greek_PI },
+ { "Greek_RHO", XKB_KEY_Greek_RHO },
+ { "Greek_SIGMA", XKB_KEY_Greek_SIGMA },
+ { "Greek_TAU", XKB_KEY_Greek_TAU },
+ { "Greek_UPSILON", XKB_KEY_Greek_UPSILON },
+ { "Greek_PHI", XKB_KEY_Greek_PHI },
+ { "Greek_CHI", XKB_KEY_Greek_CHI },
+ { "Greek_PSI", XKB_KEY_Greek_PSI },
+ { "Greek_OMEGA", XKB_KEY_Greek_OMEGA },
+ { "Greek_alpha", XKB_KEY_Greek_alpha },
+ { "Greek_beta", XKB_KEY_Greek_beta },
+ { "Greek_gamma", XKB_KEY_Greek_gamma },
+ { "Greek_delta", XKB_KEY_Greek_delta },
+ { "Greek_epsilon", XKB_KEY_Greek_epsilon },
+ { "Greek_zeta", XKB_KEY_Greek_zeta },
+ { "Greek_eta", XKB_KEY_Greek_eta },
+ { "Greek_theta", XKB_KEY_Greek_theta },
+ { "Greek_iota", XKB_KEY_Greek_iota },
+ { "Greek_kappa", XKB_KEY_Greek_kappa },
+ { "Greek_lamda", XKB_KEY_Greek_lamda },
+ { "Greek_mu", XKB_KEY_Greek_mu },
+ { "Greek_nu", XKB_KEY_Greek_nu },
+ { "Greek_xi", XKB_KEY_Greek_xi },
+ { "Greek_omicron", XKB_KEY_Greek_omicron },
+ { "Greek_pi", XKB_KEY_Greek_pi },
+ { "Greek_rho", XKB_KEY_Greek_rho },
+ { "Greek_sigma", XKB_KEY_Greek_sigma },
+ { "Greek_finalsmallsigma", XKB_KEY_Greek_finalsmallsigma },
+ { "Greek_tau", XKB_KEY_Greek_tau },
+ { "Greek_upsilon", XKB_KEY_Greek_upsilon },
+ { "Greek_phi", XKB_KEY_Greek_phi },
+ { "Greek_chi", XKB_KEY_Greek_chi },
+ { "Greek_psi", XKB_KEY_Greek_psi },
+ { "Greek_omega", XKB_KEY_Greek_omega },
+ { "leftradical", XKB_KEY_leftradical },
+ { "topleftradical", XKB_KEY_topleftradical },
+ { "horizconnector", XKB_KEY_horizconnector },
+ { "topintegral", XKB_KEY_topintegral },
+ { "botintegral", XKB_KEY_botintegral },
+ { "vertconnector", XKB_KEY_vertconnector },
+ { "topleftsqbracket", XKB_KEY_topleftsqbracket },
+ { "botleftsqbracket", XKB_KEY_botleftsqbracket },
+ { "toprightsqbracket", XKB_KEY_toprightsqbracket },
+ { "botrightsqbracket", XKB_KEY_botrightsqbracket },
+ { "topleftparens", XKB_KEY_topleftparens },
+ { "botleftparens", XKB_KEY_botleftparens },
+ { "toprightparens", XKB_KEY_toprightparens },
+ { "botrightparens", XKB_KEY_botrightparens },
+ { "leftmiddlecurlybrace", XKB_KEY_leftmiddlecurlybrace },
+ { "rightmiddlecurlybrace", XKB_KEY_rightmiddlecurlybrace },
+ { "topleftsummation", XKB_KEY_topleftsummation },
+ { "botleftsummation", XKB_KEY_botleftsummation },
+ { "topvertsummationconnector", XKB_KEY_topvertsummationconnector },
+ { "botvertsummationconnector", XKB_KEY_botvertsummationconnector },
+ { "toprightsummation", XKB_KEY_toprightsummation },
+ { "botrightsummation", XKB_KEY_botrightsummation },
+ { "rightmiddlesummation", XKB_KEY_rightmiddlesummation },
+ { "lessthanequal", XKB_KEY_lessthanequal },
+ { "notequal", XKB_KEY_notequal },
+ { "greaterthanequal", XKB_KEY_greaterthanequal },
+ { "integral", XKB_KEY_integral },
+ { "therefore", XKB_KEY_therefore },
+ { "variation", XKB_KEY_variation },
+ { "infinity", XKB_KEY_infinity },
+ { "nabla", XKB_KEY_nabla },
+ { "approximate", XKB_KEY_approximate },
+ { "similarequal", XKB_KEY_similarequal },
+ { "ifonlyif", XKB_KEY_ifonlyif },
+ { "implies", XKB_KEY_implies },
+ { "identical", XKB_KEY_identical },
+ { "radical", XKB_KEY_radical },
+ { "includedin", XKB_KEY_includedin },
+ { "includes", XKB_KEY_includes },
+ { "intersection", XKB_KEY_intersection },
+ { "union", XKB_KEY_union },
+ { "logicaland", XKB_KEY_logicaland },
+ { "logicalor", XKB_KEY_logicalor },
+ { "partialderivative", XKB_KEY_partialderivative },
+ { "function", XKB_KEY_function },
+ { "leftarrow", XKB_KEY_leftarrow },
+ { "uparrow", XKB_KEY_uparrow },
+ { "rightarrow", XKB_KEY_rightarrow },
+ { "downarrow", XKB_KEY_downarrow },
+ { "blank", XKB_KEY_blank },
+ { "soliddiamond", XKB_KEY_soliddiamond },
+ { "checkerboard", XKB_KEY_checkerboard },
+ { "ht", XKB_KEY_ht },
+ { "ff", XKB_KEY_ff },
+ { "cr", XKB_KEY_cr },
+ { "lf", XKB_KEY_lf },
+ { "nl", XKB_KEY_nl },
+ { "vt", XKB_KEY_vt },
+ { "lowrightcorner", XKB_KEY_lowrightcorner },
+ { "uprightcorner", XKB_KEY_uprightcorner },
+ { "upleftcorner", XKB_KEY_upleftcorner },
+ { "lowleftcorner", XKB_KEY_lowleftcorner },
+ { "crossinglines", XKB_KEY_crossinglines },
+ { "horizlinescan1", XKB_KEY_horizlinescan1 },
+ { "horizlinescan3", XKB_KEY_horizlinescan3 },
+ { "horizlinescan5", XKB_KEY_horizlinescan5 },
+ { "horizlinescan7", XKB_KEY_horizlinescan7 },
+ { "horizlinescan9", XKB_KEY_horizlinescan9 },
+ { "leftt", XKB_KEY_leftt },
+ { "rightt", XKB_KEY_rightt },
+ { "bott", XKB_KEY_bott },
+ { "topt", XKB_KEY_topt },
+ { "vertbar", XKB_KEY_vertbar },
+ { "emspace", XKB_KEY_emspace },
+ { "enspace", XKB_KEY_enspace },
+ { "em3space", XKB_KEY_em3space },
+ { "em4space", XKB_KEY_em4space },
+ { "digitspace", XKB_KEY_digitspace },
+ { "punctspace", XKB_KEY_punctspace },
+ { "thinspace", XKB_KEY_thinspace },
+ { "hairspace", XKB_KEY_hairspace },
+ { "emdash", XKB_KEY_emdash },
+ { "endash", XKB_KEY_endash },
+ { "signifblank", XKB_KEY_signifblank },
+ { "ellipsis", XKB_KEY_ellipsis },
+ { "doubbaselinedot", XKB_KEY_doubbaselinedot },
+ { "onethird", XKB_KEY_onethird },
+ { "twothirds", XKB_KEY_twothirds },
+ { "onefifth", XKB_KEY_onefifth },
+ { "twofifths", XKB_KEY_twofifths },
+ { "threefifths", XKB_KEY_threefifths },
+ { "fourfifths", XKB_KEY_fourfifths },
+ { "onesixth", XKB_KEY_onesixth },
+ { "fivesixths", XKB_KEY_fivesixths },
+ { "careof", XKB_KEY_careof },
+ { "figdash", XKB_KEY_figdash },
+ { "leftanglebracket", XKB_KEY_leftanglebracket },
+ { "decimalpoint", XKB_KEY_decimalpoint },
+ { "rightanglebracket", XKB_KEY_rightanglebracket },
+ { "marker", XKB_KEY_marker },
+ { "oneeighth", XKB_KEY_oneeighth },
+ { "threeeighths", XKB_KEY_threeeighths },
+ { "fiveeighths", XKB_KEY_fiveeighths },
+ { "seveneighths", XKB_KEY_seveneighths },
+ { "trademark", XKB_KEY_trademark },
+ { "signaturemark", XKB_KEY_signaturemark },
+ { "trademarkincircle", XKB_KEY_trademarkincircle },
+ { "leftopentriangle", XKB_KEY_leftopentriangle },
+ { "rightopentriangle", XKB_KEY_rightopentriangle },
+ { "emopencircle", XKB_KEY_emopencircle },
+ { "emopenrectangle", XKB_KEY_emopenrectangle },
+ { "leftsinglequotemark", XKB_KEY_leftsinglequotemark },
+ { "rightsinglequotemark", XKB_KEY_rightsinglequotemark },
+ { "leftdoublequotemark", XKB_KEY_leftdoublequotemark },
+ { "rightdoublequotemark", XKB_KEY_rightdoublequotemark },
+ { "prescription", XKB_KEY_prescription },
+ { "permille", XKB_KEY_permille },
+ { "minutes", XKB_KEY_minutes },
+ { "seconds", XKB_KEY_seconds },
+ { "latincross", XKB_KEY_latincross },
+ { "hexagram", XKB_KEY_hexagram },
+ { "filledrectbullet", XKB_KEY_filledrectbullet },
+ { "filledlefttribullet", XKB_KEY_filledlefttribullet },
+ { "filledrighttribullet", XKB_KEY_filledrighttribullet },
+ { "emfilledcircle", XKB_KEY_emfilledcircle },
+ { "emfilledrect", XKB_KEY_emfilledrect },
+ { "enopencircbullet", XKB_KEY_enopencircbullet },
+ { "enopensquarebullet", XKB_KEY_enopensquarebullet },
+ { "openrectbullet", XKB_KEY_openrectbullet },
+ { "opentribulletup", XKB_KEY_opentribulletup },
+ { "opentribulletdown", XKB_KEY_opentribulletdown },
+ { "openstar", XKB_KEY_openstar },
+ { "enfilledcircbullet", XKB_KEY_enfilledcircbullet },
+ { "enfilledsqbullet", XKB_KEY_enfilledsqbullet },
+ { "filledtribulletup", XKB_KEY_filledtribulletup },
+ { "filledtribulletdown", XKB_KEY_filledtribulletdown },
+ { "leftpointer", XKB_KEY_leftpointer },
+ { "rightpointer", XKB_KEY_rightpointer },
+ { "club", XKB_KEY_club },
+ { "diamond", XKB_KEY_diamond },
+ { "heart", XKB_KEY_heart },
+ { "maltesecross", XKB_KEY_maltesecross },
+ { "dagger", XKB_KEY_dagger },
+ { "doubledagger", XKB_KEY_doubledagger },
+ { "checkmark", XKB_KEY_checkmark },
+ { "ballotcross", XKB_KEY_ballotcross },
+ { "musicalsharp", XKB_KEY_musicalsharp },
+ { "musicalflat", XKB_KEY_musicalflat },
+ { "malesymbol", XKB_KEY_malesymbol },
+ { "femalesymbol", XKB_KEY_femalesymbol },
+ { "telephone", XKB_KEY_telephone },
+ { "telephonerecorder", XKB_KEY_telephonerecorder },
+ { "phonographcopyright", XKB_KEY_phonographcopyright },
+ { "caret", XKB_KEY_caret },
+ { "singlelowquotemark", XKB_KEY_singlelowquotemark },
+ { "doublelowquotemark", XKB_KEY_doublelowquotemark },
+ { "cursor", XKB_KEY_cursor },
+ { "leftcaret", XKB_KEY_leftcaret },
+ { "rightcaret", XKB_KEY_rightcaret },
+ { "downcaret", XKB_KEY_downcaret },
+ { "upcaret", XKB_KEY_upcaret },
+ { "overbar", XKB_KEY_overbar },
+ { "downtack", XKB_KEY_downtack },
+ { "upshoe", XKB_KEY_upshoe },
+ { "downstile", XKB_KEY_downstile },
+ { "underbar", XKB_KEY_underbar },
+ { "jot", XKB_KEY_jot },
+ { "quad", XKB_KEY_quad },
+ { "uptack", XKB_KEY_uptack },
+ { "circle", XKB_KEY_circle },
+ { "upstile", XKB_KEY_upstile },
+ { "downshoe", XKB_KEY_downshoe },
+ { "rightshoe", XKB_KEY_rightshoe },
+ { "leftshoe", XKB_KEY_leftshoe },
+ { "lefttack", XKB_KEY_lefttack },
+ { "righttack", XKB_KEY_righttack },
+ { "hebrew_doublelowline", XKB_KEY_hebrew_doublelowline },
+ { "hebrew_aleph", XKB_KEY_hebrew_aleph },
+ { "hebrew_bet", XKB_KEY_hebrew_bet },
+ { "hebrew_gimel", XKB_KEY_hebrew_gimel },
+ { "hebrew_dalet", XKB_KEY_hebrew_dalet },
+ { "hebrew_he", XKB_KEY_hebrew_he },
+ { "hebrew_waw", XKB_KEY_hebrew_waw },
+ { "hebrew_zain", XKB_KEY_hebrew_zain },
+ { "hebrew_chet", XKB_KEY_hebrew_chet },
+ { "hebrew_tet", XKB_KEY_hebrew_tet },
+ { "hebrew_yod", XKB_KEY_hebrew_yod },
+ { "hebrew_finalkaph", XKB_KEY_hebrew_finalkaph },
+ { "hebrew_kaph", XKB_KEY_hebrew_kaph },
+ { "hebrew_lamed", XKB_KEY_hebrew_lamed },
+ { "hebrew_finalmem", XKB_KEY_hebrew_finalmem },
+ { "hebrew_mem", XKB_KEY_hebrew_mem },
+ { "hebrew_finalnun", XKB_KEY_hebrew_finalnun },
+ { "hebrew_nun", XKB_KEY_hebrew_nun },
+ { "hebrew_samech", XKB_KEY_hebrew_samech },
+ { "hebrew_ayin", XKB_KEY_hebrew_ayin },
+ { "hebrew_finalpe", XKB_KEY_hebrew_finalpe },
+ { "hebrew_pe", XKB_KEY_hebrew_pe },
+ { "hebrew_finalzade", XKB_KEY_hebrew_finalzade },
+ { "hebrew_zade", XKB_KEY_hebrew_zade },
+ { "hebrew_qoph", XKB_KEY_hebrew_qoph },
+ { "hebrew_resh", XKB_KEY_hebrew_resh },
+ { "hebrew_shin", XKB_KEY_hebrew_shin },
+ { "hebrew_taw", XKB_KEY_hebrew_taw },
+ { "Thai_kokai", XKB_KEY_Thai_kokai },
+ { "Thai_khokhai", XKB_KEY_Thai_khokhai },
+ { "Thai_khokhuat", XKB_KEY_Thai_khokhuat },
+ { "Thai_khokhwai", XKB_KEY_Thai_khokhwai },
+ { "Thai_khokhon", XKB_KEY_Thai_khokhon },
+ { "Thai_khorakhang", XKB_KEY_Thai_khorakhang },
+ { "Thai_ngongu", XKB_KEY_Thai_ngongu },
+ { "Thai_chochan", XKB_KEY_Thai_chochan },
+ { "Thai_choching", XKB_KEY_Thai_choching },
+ { "Thai_chochang", XKB_KEY_Thai_chochang },
+ { "Thai_soso", XKB_KEY_Thai_soso },
+ { "Thai_chochoe", XKB_KEY_Thai_chochoe },
+ { "Thai_yoying", XKB_KEY_Thai_yoying },
+ { "Thai_dochada", XKB_KEY_Thai_dochada },
+ { "Thai_topatak", XKB_KEY_Thai_topatak },
+ { "Thai_thothan", XKB_KEY_Thai_thothan },
+ { "Thai_thonangmontho", XKB_KEY_Thai_thonangmontho },
+ { "Thai_thophuthao", XKB_KEY_Thai_thophuthao },
+ { "Thai_nonen", XKB_KEY_Thai_nonen },
+ { "Thai_dodek", XKB_KEY_Thai_dodek },
+ { "Thai_totao", XKB_KEY_Thai_totao },
+ { "Thai_thothung", XKB_KEY_Thai_thothung },
+ { "Thai_thothahan", XKB_KEY_Thai_thothahan },
+ { "Thai_thothong", XKB_KEY_Thai_thothong },
+ { "Thai_nonu", XKB_KEY_Thai_nonu },
+ { "Thai_bobaimai", XKB_KEY_Thai_bobaimai },
+ { "Thai_popla", XKB_KEY_Thai_popla },
+ { "Thai_phophung", XKB_KEY_Thai_phophung },
+ { "Thai_fofa", XKB_KEY_Thai_fofa },
+ { "Thai_phophan", XKB_KEY_Thai_phophan },
+ { "Thai_fofan", XKB_KEY_Thai_fofan },
+ { "Thai_phosamphao", XKB_KEY_Thai_phosamphao },
+ { "Thai_moma", XKB_KEY_Thai_moma },
+ { "Thai_yoyak", XKB_KEY_Thai_yoyak },
+ { "Thai_rorua", XKB_KEY_Thai_rorua },
+ { "Thai_ru", XKB_KEY_Thai_ru },
+ { "Thai_loling", XKB_KEY_Thai_loling },
+ { "Thai_lu", XKB_KEY_Thai_lu },
+ { "Thai_wowaen", XKB_KEY_Thai_wowaen },
+ { "Thai_sosala", XKB_KEY_Thai_sosala },
+ { "Thai_sorusi", XKB_KEY_Thai_sorusi },
+ { "Thai_sosua", XKB_KEY_Thai_sosua },
+ { "Thai_hohip", XKB_KEY_Thai_hohip },
+ { "Thai_lochula", XKB_KEY_Thai_lochula },
+ { "Thai_oang", XKB_KEY_Thai_oang },
+ { "Thai_honokhuk", XKB_KEY_Thai_honokhuk },
+ { "Thai_paiyannoi", XKB_KEY_Thai_paiyannoi },
+ { "Thai_saraa", XKB_KEY_Thai_saraa },
+ { "Thai_maihanakat", XKB_KEY_Thai_maihanakat },
+ { "Thai_saraaa", XKB_KEY_Thai_saraaa },
+ { "Thai_saraam", XKB_KEY_Thai_saraam },
+ { "Thai_sarai", XKB_KEY_Thai_sarai },
+ { "Thai_saraii", XKB_KEY_Thai_saraii },
+ { "Thai_saraue", XKB_KEY_Thai_saraue },
+ { "Thai_sarauee", XKB_KEY_Thai_sarauee },
+ { "Thai_sarau", XKB_KEY_Thai_sarau },
+ { "Thai_sarauu", XKB_KEY_Thai_sarauu },
+ { "Thai_phinthu", XKB_KEY_Thai_phinthu },
+ { "Thai_maihanakat_maitho", XKB_KEY_Thai_maihanakat_maitho },
+ { "Thai_baht", XKB_KEY_Thai_baht },
+ { "Thai_sarae", XKB_KEY_Thai_sarae },
+ { "Thai_saraae", XKB_KEY_Thai_saraae },
+ { "Thai_sarao", XKB_KEY_Thai_sarao },
+ { "Thai_saraaimaimuan", XKB_KEY_Thai_saraaimaimuan },
+ { "Thai_saraaimaimalai", XKB_KEY_Thai_saraaimaimalai },
+ { "Thai_lakkhangyao", XKB_KEY_Thai_lakkhangyao },
+ { "Thai_maiyamok", XKB_KEY_Thai_maiyamok },
+ { "Thai_maitaikhu", XKB_KEY_Thai_maitaikhu },
+ { "Thai_maiek", XKB_KEY_Thai_maiek },
+ { "Thai_maitho", XKB_KEY_Thai_maitho },
+ { "Thai_maitri", XKB_KEY_Thai_maitri },
+ { "Thai_maichattawa", XKB_KEY_Thai_maichattawa },
+ { "Thai_thanthakhat", XKB_KEY_Thai_thanthakhat },
+ { "Thai_nikhahit", XKB_KEY_Thai_nikhahit },
+ { "Thai_leksun", XKB_KEY_Thai_leksun },
+ { "Thai_leknung", XKB_KEY_Thai_leknung },
+ { "Thai_leksong", XKB_KEY_Thai_leksong },
+ { "Thai_leksam", XKB_KEY_Thai_leksam },
+ { "Thai_leksi", XKB_KEY_Thai_leksi },
+ { "Thai_lekha", XKB_KEY_Thai_lekha },
+ { "Thai_lekhok", XKB_KEY_Thai_lekhok },
+ { "Thai_lekchet", XKB_KEY_Thai_lekchet },
+ { "Thai_lekpaet", XKB_KEY_Thai_lekpaet },
+ { "Thai_lekkao", XKB_KEY_Thai_lekkao },
+ { "Hangul_Kiyeog", XKB_KEY_Hangul_Kiyeog },
+ { "Hangul_SsangKiyeog", XKB_KEY_Hangul_SsangKiyeog },
+ { "Hangul_KiyeogSios", XKB_KEY_Hangul_KiyeogSios },
+ { "Hangul_Nieun", XKB_KEY_Hangul_Nieun },
+ { "Hangul_NieunJieuj", XKB_KEY_Hangul_NieunJieuj },
+ { "Hangul_NieunHieuh", XKB_KEY_Hangul_NieunHieuh },
+ { "Hangul_Dikeud", XKB_KEY_Hangul_Dikeud },
+ { "Hangul_SsangDikeud", XKB_KEY_Hangul_SsangDikeud },
+ { "Hangul_Rieul", XKB_KEY_Hangul_Rieul },
+ { "Hangul_RieulKiyeog", XKB_KEY_Hangul_RieulKiyeog },
+ { "Hangul_RieulMieum", XKB_KEY_Hangul_RieulMieum },
+ { "Hangul_RieulPieub", XKB_KEY_Hangul_RieulPieub },
+ { "Hangul_RieulSios", XKB_KEY_Hangul_RieulSios },
+ { "Hangul_RieulTieut", XKB_KEY_Hangul_RieulTieut },
+ { "Hangul_RieulPhieuf", XKB_KEY_Hangul_RieulPhieuf },
+ { "Hangul_RieulHieuh", XKB_KEY_Hangul_RieulHieuh },
+ { "Hangul_Mieum", XKB_KEY_Hangul_Mieum },
+ { "Hangul_Pieub", XKB_KEY_Hangul_Pieub },
+ { "Hangul_SsangPieub", XKB_KEY_Hangul_SsangPieub },
+ { "Hangul_PieubSios", XKB_KEY_Hangul_PieubSios },
+ { "Hangul_Sios", XKB_KEY_Hangul_Sios },
+ { "Hangul_SsangSios", XKB_KEY_Hangul_SsangSios },
+ { "Hangul_Ieung", XKB_KEY_Hangul_Ieung },
+ { "Hangul_Jieuj", XKB_KEY_Hangul_Jieuj },
+ { "Hangul_SsangJieuj", XKB_KEY_Hangul_SsangJieuj },
+ { "Hangul_Cieuc", XKB_KEY_Hangul_Cieuc },
+ { "Hangul_Khieuq", XKB_KEY_Hangul_Khieuq },
+ { "Hangul_Tieut", XKB_KEY_Hangul_Tieut },
+ { "Hangul_Phieuf", XKB_KEY_Hangul_Phieuf },
+ { "Hangul_Hieuh", XKB_KEY_Hangul_Hieuh },
+ { "Hangul_A", XKB_KEY_Hangul_A },
+ { "Hangul_AE", XKB_KEY_Hangul_AE },
+ { "Hangul_YA", XKB_KEY_Hangul_YA },
+ { "Hangul_YAE", XKB_KEY_Hangul_YAE },
+ { "Hangul_EO", XKB_KEY_Hangul_EO },
+ { "Hangul_E", XKB_KEY_Hangul_E },
+ { "Hangul_YEO", XKB_KEY_Hangul_YEO },
+ { "Hangul_YE", XKB_KEY_Hangul_YE },
+ { "Hangul_O", XKB_KEY_Hangul_O },
+ { "Hangul_WA", XKB_KEY_Hangul_WA },
+ { "Hangul_WAE", XKB_KEY_Hangul_WAE },
+ { "Hangul_OE", XKB_KEY_Hangul_OE },
+ { "Hangul_YO", XKB_KEY_Hangul_YO },
+ { "Hangul_U", XKB_KEY_Hangul_U },
+ { "Hangul_WEO", XKB_KEY_Hangul_WEO },
+ { "Hangul_WE", XKB_KEY_Hangul_WE },
+ { "Hangul_WI", XKB_KEY_Hangul_WI },
+ { "Hangul_YU", XKB_KEY_Hangul_YU },
+ { "Hangul_EU", XKB_KEY_Hangul_EU },
+ { "Hangul_YI", XKB_KEY_Hangul_YI },
+ { "Hangul_I", XKB_KEY_Hangul_I },
+ { "Hangul_J_Kiyeog", XKB_KEY_Hangul_J_Kiyeog },
+ { "Hangul_J_SsangKiyeog", XKB_KEY_Hangul_J_SsangKiyeog },
+ { "Hangul_J_KiyeogSios", XKB_KEY_Hangul_J_KiyeogSios },
+ { "Hangul_J_Nieun", XKB_KEY_Hangul_J_Nieun },
+ { "Hangul_J_NieunJieuj", XKB_KEY_Hangul_J_NieunJieuj },
+ { "Hangul_J_NieunHieuh", XKB_KEY_Hangul_J_NieunHieuh },
+ { "Hangul_J_Dikeud", XKB_KEY_Hangul_J_Dikeud },
+ { "Hangul_J_Rieul", XKB_KEY_Hangul_J_Rieul },
+ { "Hangul_J_RieulKiyeog", XKB_KEY_Hangul_J_RieulKiyeog },
+ { "Hangul_J_RieulMieum", XKB_KEY_Hangul_J_RieulMieum },
+ { "Hangul_J_RieulPieub", XKB_KEY_Hangul_J_RieulPieub },
+ { "Hangul_J_RieulSios", XKB_KEY_Hangul_J_RieulSios },
+ { "Hangul_J_RieulTieut", XKB_KEY_Hangul_J_RieulTieut },
+ { "Hangul_J_RieulPhieuf", XKB_KEY_Hangul_J_RieulPhieuf },
+ { "Hangul_J_RieulHieuh", XKB_KEY_Hangul_J_RieulHieuh },
+ { "Hangul_J_Mieum", XKB_KEY_Hangul_J_Mieum },
+ { "Hangul_J_Pieub", XKB_KEY_Hangul_J_Pieub },
+ { "Hangul_J_PieubSios", XKB_KEY_Hangul_J_PieubSios },
+ { "Hangul_J_Sios", XKB_KEY_Hangul_J_Sios },
+ { "Hangul_J_SsangSios", XKB_KEY_Hangul_J_SsangSios },
+ { "Hangul_J_Ieung", XKB_KEY_Hangul_J_Ieung },
+ { "Hangul_J_Jieuj", XKB_KEY_Hangul_J_Jieuj },
+ { "Hangul_J_Cieuc", XKB_KEY_Hangul_J_Cieuc },
+ { "Hangul_J_Khieuq", XKB_KEY_Hangul_J_Khieuq },
+ { "Hangul_J_Tieut", XKB_KEY_Hangul_J_Tieut },
+ { "Hangul_J_Phieuf", XKB_KEY_Hangul_J_Phieuf },
+ { "Hangul_J_Hieuh", XKB_KEY_Hangul_J_Hieuh },
+ { "Hangul_RieulYeorinHieuh", XKB_KEY_Hangul_RieulYeorinHieuh },
+ { "Hangul_SunkyeongeumMieum", XKB_KEY_Hangul_SunkyeongeumMieum },
+ { "Hangul_SunkyeongeumPieub", XKB_KEY_Hangul_SunkyeongeumPieub },
+ { "Hangul_PanSios", XKB_KEY_Hangul_PanSios },
+ { "Hangul_KkogjiDalrinIeung", XKB_KEY_Hangul_KkogjiDalrinIeung },
+ { "Hangul_SunkyeongeumPhieuf", XKB_KEY_Hangul_SunkyeongeumPhieuf },
+ { "Hangul_YeorinHieuh", XKB_KEY_Hangul_YeorinHieuh },
+ { "Hangul_AraeA", XKB_KEY_Hangul_AraeA },
+ { "Hangul_AraeAE", XKB_KEY_Hangul_AraeAE },
+ { "Hangul_J_PanSios", XKB_KEY_Hangul_J_PanSios },
+ { "Hangul_J_KkogjiDalrinIeung", XKB_KEY_Hangul_J_KkogjiDalrinIeung },
+ { "Hangul_J_YeorinHieuh", XKB_KEY_Hangul_J_YeorinHieuh },
+ { "Korean_Won", XKB_KEY_Korean_Won },
+ { "OE", XKB_KEY_OE },
+ { "oe", XKB_KEY_oe },
+ { "Ydiaeresis", XKB_KEY_Ydiaeresis },
+ { "EuroSign", XKB_KEY_EuroSign },
+ { "3270_Duplicate", XKB_KEY_3270_Duplicate },
+ { "3270_FieldMark", XKB_KEY_3270_FieldMark },
+ { "3270_Right2", XKB_KEY_3270_Right2 },
+ { "3270_Left2", XKB_KEY_3270_Left2 },
+ { "3270_BackTab", XKB_KEY_3270_BackTab },
+ { "3270_EraseEOF", XKB_KEY_3270_EraseEOF },
+ { "3270_EraseInput", XKB_KEY_3270_EraseInput },
+ { "3270_Reset", XKB_KEY_3270_Reset },
+ { "3270_Quit", XKB_KEY_3270_Quit },
+ { "3270_PA1", XKB_KEY_3270_PA1 },
+ { "3270_PA2", XKB_KEY_3270_PA2 },
+ { "3270_PA3", XKB_KEY_3270_PA3 },
+ { "3270_Test", XKB_KEY_3270_Test },
+ { "3270_Attn", XKB_KEY_3270_Attn },
+ { "3270_CursorBlink", XKB_KEY_3270_CursorBlink },
+ { "3270_AltCursor", XKB_KEY_3270_AltCursor },
+ { "3270_KeyClick", XKB_KEY_3270_KeyClick },
+ { "3270_Jump", XKB_KEY_3270_Jump },
+ { "3270_Ident", XKB_KEY_3270_Ident },
+ { "3270_Rule", XKB_KEY_3270_Rule },
+ { "3270_Copy", XKB_KEY_3270_Copy },
+ { "3270_Play", XKB_KEY_3270_Play },
+ { "3270_Setup", XKB_KEY_3270_Setup },
+ { "3270_Record", XKB_KEY_3270_Record },
+ { "3270_ChangeScreen", XKB_KEY_3270_ChangeScreen },
+ { "3270_DeleteWord", XKB_KEY_3270_DeleteWord },
+ { "3270_ExSelect", XKB_KEY_3270_ExSelect },
+ { "3270_CursorSelect", XKB_KEY_3270_CursorSelect },
+ { "3270_PrintScreen", XKB_KEY_3270_PrintScreen },
+ { "3270_Enter", XKB_KEY_3270_Enter },
+ { "ISO_Lock", XKB_KEY_ISO_Lock },
+ { "ISO_Level2_Latch", XKB_KEY_ISO_Level2_Latch },
+ { "ISO_Level3_Shift", XKB_KEY_ISO_Level3_Shift },
+ { "ISO_Level3_Latch", XKB_KEY_ISO_Level3_Latch },
+ { "ISO_Level3_Lock", XKB_KEY_ISO_Level3_Lock },
+ { "ISO_Group_Latch", XKB_KEY_ISO_Group_Latch },
+ { "ISO_Group_Lock", XKB_KEY_ISO_Group_Lock },
+ { "ISO_Next_Group", XKB_KEY_ISO_Next_Group },
+ { "ISO_Next_Group_Lock", XKB_KEY_ISO_Next_Group_Lock },
+ { "ISO_Prev_Group", XKB_KEY_ISO_Prev_Group },
+ { "ISO_Prev_Group_Lock", XKB_KEY_ISO_Prev_Group_Lock },
+ { "ISO_First_Group", XKB_KEY_ISO_First_Group },
+ { "ISO_First_Group_Lock", XKB_KEY_ISO_First_Group_Lock },
+ { "ISO_Last_Group", XKB_KEY_ISO_Last_Group },
+ { "ISO_Last_Group_Lock", XKB_KEY_ISO_Last_Group_Lock },
+ { "ISO_Level5_Shift", XKB_KEY_ISO_Level5_Shift },
+ { "ISO_Level5_Latch", XKB_KEY_ISO_Level5_Latch },
+ { "ISO_Level5_Lock", XKB_KEY_ISO_Level5_Lock },
+ { "ISO_Left_Tab", XKB_KEY_ISO_Left_Tab },
+ { "ISO_Move_Line_Up", XKB_KEY_ISO_Move_Line_Up },
+ { "ISO_Move_Line_Down", XKB_KEY_ISO_Move_Line_Down },
+ { "ISO_Partial_Line_Up", XKB_KEY_ISO_Partial_Line_Up },
+ { "ISO_Partial_Line_Down", XKB_KEY_ISO_Partial_Line_Down },
+ { "ISO_Partial_Space_Left", XKB_KEY_ISO_Partial_Space_Left },
+ { "ISO_Partial_Space_Right", XKB_KEY_ISO_Partial_Space_Right },
+ { "ISO_Set_Margin_Left", XKB_KEY_ISO_Set_Margin_Left },
+ { "ISO_Set_Margin_Right", XKB_KEY_ISO_Set_Margin_Right },
+ { "ISO_Release_Margin_Left", XKB_KEY_ISO_Release_Margin_Left },
+ { "ISO_Release_Margin_Right", XKB_KEY_ISO_Release_Margin_Right },
+ { "ISO_Release_Both_Margins", XKB_KEY_ISO_Release_Both_Margins },
+ { "ISO_Fast_Cursor_Left", XKB_KEY_ISO_Fast_Cursor_Left },
+ { "ISO_Fast_Cursor_Right", XKB_KEY_ISO_Fast_Cursor_Right },
+ { "ISO_Fast_Cursor_Up", XKB_KEY_ISO_Fast_Cursor_Up },
+ { "ISO_Fast_Cursor_Down", XKB_KEY_ISO_Fast_Cursor_Down },
+ { "ISO_Continuous_Underline", XKB_KEY_ISO_Continuous_Underline },
+ { "ISO_Discontinuous_Underline", XKB_KEY_ISO_Discontinuous_Underline },
+ { "ISO_Emphasize", XKB_KEY_ISO_Emphasize },
+ { "ISO_Center_Object", XKB_KEY_ISO_Center_Object },
+ { "ISO_Enter", XKB_KEY_ISO_Enter },
+ { "dead_grave", XKB_KEY_dead_grave },
+ { "dead_acute", XKB_KEY_dead_acute },
+ { "dead_circumflex", XKB_KEY_dead_circumflex },
+ { "dead_tilde", XKB_KEY_dead_tilde },
+ { "dead_macron", XKB_KEY_dead_macron },
+ { "dead_breve", XKB_KEY_dead_breve },
+ { "dead_abovedot", XKB_KEY_dead_abovedot },
+ { "dead_diaeresis", XKB_KEY_dead_diaeresis },
+ { "dead_abovering", XKB_KEY_dead_abovering },
+ { "dead_doubleacute", XKB_KEY_dead_doubleacute },
+ { "dead_caron", XKB_KEY_dead_caron },
+ { "dead_cedilla", XKB_KEY_dead_cedilla },
+ { "dead_ogonek", XKB_KEY_dead_ogonek },
+ { "dead_iota", XKB_KEY_dead_iota },
+ { "dead_voiced_sound", XKB_KEY_dead_voiced_sound },
+ { "dead_semivoiced_sound", XKB_KEY_dead_semivoiced_sound },
+ { "dead_belowdot", XKB_KEY_dead_belowdot },
+ { "dead_hook", XKB_KEY_dead_hook },
+ { "dead_horn", XKB_KEY_dead_horn },
+ { "dead_stroke", XKB_KEY_dead_stroke },
+ { "dead_abovecomma", XKB_KEY_dead_abovecomma },
+ { "dead_abovereversedcomma", XKB_KEY_dead_abovereversedcomma },
+ { "dead_doublegrave", XKB_KEY_dead_doublegrave },
+ { "dead_belowring", XKB_KEY_dead_belowring },
+ { "dead_belowmacron", XKB_KEY_dead_belowmacron },
+ { "dead_belowcircumflex", XKB_KEY_dead_belowcircumflex },
+ { "dead_belowtilde", XKB_KEY_dead_belowtilde },
+ { "dead_belowbreve", XKB_KEY_dead_belowbreve },
+ { "dead_belowdiaeresis", XKB_KEY_dead_belowdiaeresis },
+ { "dead_invertedbreve", XKB_KEY_dead_invertedbreve },
+ { "dead_belowcomma", XKB_KEY_dead_belowcomma },
+ { "dead_currency", XKB_KEY_dead_currency },
+ { "AccessX_Enable", XKB_KEY_AccessX_Enable },
+ { "AccessX_Feedback_Enable", XKB_KEY_AccessX_Feedback_Enable },
+ { "RepeatKeys_Enable", XKB_KEY_RepeatKeys_Enable },
+ { "SlowKeys_Enable", XKB_KEY_SlowKeys_Enable },
+ { "BounceKeys_Enable", XKB_KEY_BounceKeys_Enable },
+ { "StickyKeys_Enable", XKB_KEY_StickyKeys_Enable },
+ { "MouseKeys_Enable", XKB_KEY_MouseKeys_Enable },
+ { "MouseKeys_Accel_Enable", XKB_KEY_MouseKeys_Accel_Enable },
+ { "Overlay1_Enable", XKB_KEY_Overlay1_Enable },
+ { "Overlay2_Enable", XKB_KEY_Overlay2_Enable },
+ { "AudibleBell_Enable", XKB_KEY_AudibleBell_Enable },
+ { "dead_a", XKB_KEY_dead_a },
+ { "dead_A", XKB_KEY_dead_A },
+ { "dead_e", XKB_KEY_dead_e },
+ { "dead_E", XKB_KEY_dead_E },
+ { "dead_i", XKB_KEY_dead_i },
+ { "dead_I", XKB_KEY_dead_I },
+ { "dead_o", XKB_KEY_dead_o },
+ { "dead_O", XKB_KEY_dead_O },
+ { "dead_u", XKB_KEY_dead_u },
+ { "dead_U", XKB_KEY_dead_U },
+ { "dead_small_schwa", XKB_KEY_dead_small_schwa },
+ { "dead_capital_schwa", XKB_KEY_dead_capital_schwa },
+ { "dead_greek", XKB_KEY_dead_greek },
+ { "ch", XKB_KEY_ch },
+ { "Ch", XKB_KEY_Ch },
+ { "CH", XKB_KEY_CH },
+ { "c_h", XKB_KEY_c_h },
+ { "C_h", XKB_KEY_C_h },
+ { "C_H", XKB_KEY_C_H },
+ { "First_Virtual_Screen", XKB_KEY_First_Virtual_Screen },
+ { "Prev_Virtual_Screen", XKB_KEY_Prev_Virtual_Screen },
+ { "Next_Virtual_Screen", XKB_KEY_Next_Virtual_Screen },
+ { "Last_Virtual_Screen", XKB_KEY_Last_Virtual_Screen },
+ { "Terminate_Server", XKB_KEY_Terminate_Server },
+ { "Pointer_Left", XKB_KEY_Pointer_Left },
+ { "Pointer_Right", XKB_KEY_Pointer_Right },
+ { "Pointer_Up", XKB_KEY_Pointer_Up },
+ { "Pointer_Down", XKB_KEY_Pointer_Down },
+ { "Pointer_UpLeft", XKB_KEY_Pointer_UpLeft },
+ { "Pointer_UpRight", XKB_KEY_Pointer_UpRight },
+ { "Pointer_DownLeft", XKB_KEY_Pointer_DownLeft },
+ { "Pointer_DownRight", XKB_KEY_Pointer_DownRight },
+ { "Pointer_Button_Dflt", XKB_KEY_Pointer_Button_Dflt },
+ { "Pointer_Button1", XKB_KEY_Pointer_Button1 },
+ { "Pointer_Button2", XKB_KEY_Pointer_Button2 },
+ { "Pointer_Button3", XKB_KEY_Pointer_Button3 },
+ { "Pointer_Button4", XKB_KEY_Pointer_Button4 },
+ { "Pointer_Button5", XKB_KEY_Pointer_Button5 },
+ { "Pointer_DblClick_Dflt", XKB_KEY_Pointer_DblClick_Dflt },
+ { "Pointer_DblClick1", XKB_KEY_Pointer_DblClick1 },
+ { "Pointer_DblClick2", XKB_KEY_Pointer_DblClick2 },
+ { "Pointer_DblClick3", XKB_KEY_Pointer_DblClick3 },
+ { "Pointer_DblClick4", XKB_KEY_Pointer_DblClick4 },
+ { "Pointer_DblClick5", XKB_KEY_Pointer_DblClick5 },
+ { "Pointer_Drag_Dflt", XKB_KEY_Pointer_Drag_Dflt },
+ { "Pointer_Drag1", XKB_KEY_Pointer_Drag1 },
+ { "Pointer_Drag2", XKB_KEY_Pointer_Drag2 },
+ { "Pointer_Drag3", XKB_KEY_Pointer_Drag3 },
+ { "Pointer_Drag4", XKB_KEY_Pointer_Drag4 },
+ { "Pointer_EnableKeys", XKB_KEY_Pointer_EnableKeys },
+ { "Pointer_Accelerate", XKB_KEY_Pointer_Accelerate },
+ { "Pointer_DfltBtnNext", XKB_KEY_Pointer_DfltBtnNext },
+ { "Pointer_DfltBtnPrev", XKB_KEY_Pointer_DfltBtnPrev },
+ { "Pointer_Drag5", XKB_KEY_Pointer_Drag5 },
+ { "BackSpace", XKB_KEY_BackSpace },
+ { "Tab", XKB_KEY_Tab },
+ { "Linefeed", XKB_KEY_Linefeed },
+ { "Clear", XKB_KEY_Clear },
+ { "Return", XKB_KEY_Return },
+ { "Pause", XKB_KEY_Pause },
+ { "Scroll_Lock", XKB_KEY_Scroll_Lock },
+ { "Sys_Req", XKB_KEY_Sys_Req },
+ { "Escape", XKB_KEY_Escape },
+ { "Multi_key", XKB_KEY_Multi_key },
+ { "Kanji", XKB_KEY_Kanji },
+ { "Muhenkan", XKB_KEY_Muhenkan },
+ { "Henkan_Mode", XKB_KEY_Henkan_Mode },
+ { "Romaji", XKB_KEY_Romaji },
+ { "Hiragana", XKB_KEY_Hiragana },
+ { "Katakana", XKB_KEY_Katakana },
+ { "Hiragana_Katakana", XKB_KEY_Hiragana_Katakana },
+ { "Zenkaku", XKB_KEY_Zenkaku },
+ { "Hankaku", XKB_KEY_Hankaku },
+ { "Zenkaku_Hankaku", XKB_KEY_Zenkaku_Hankaku },
+ { "Touroku", XKB_KEY_Touroku },
+ { "Massyo", XKB_KEY_Massyo },
+ { "Kana_Lock", XKB_KEY_Kana_Lock },
+ { "Kana_Shift", XKB_KEY_Kana_Shift },
+ { "Eisu_Shift", XKB_KEY_Eisu_Shift },
+ { "Eisu_toggle", XKB_KEY_Eisu_toggle },
+ { "Hangul", XKB_KEY_Hangul },
+ { "Hangul_Start", XKB_KEY_Hangul_Start },
+ { "Hangul_End", XKB_KEY_Hangul_End },
+ { "Hangul_Hanja", XKB_KEY_Hangul_Hanja },
+ { "Hangul_Jamo", XKB_KEY_Hangul_Jamo },
+ { "Hangul_Romaja", XKB_KEY_Hangul_Romaja },
+ { "Codeinput", XKB_KEY_Codeinput },
+ { "Hangul_Jeonja", XKB_KEY_Hangul_Jeonja },
+ { "Hangul_Banja", XKB_KEY_Hangul_Banja },
+ { "Hangul_PreHanja", XKB_KEY_Hangul_PreHanja },
+ { "Hangul_PostHanja", XKB_KEY_Hangul_PostHanja },
+ { "SingleCandidate", XKB_KEY_SingleCandidate },
+ { "MultipleCandidate", XKB_KEY_MultipleCandidate },
+ { "PreviousCandidate", XKB_KEY_PreviousCandidate },
+ { "Hangul_Special", XKB_KEY_Hangul_Special },
+ { "Home", XKB_KEY_Home },
+ { "Left", XKB_KEY_Left },
+ { "Up", XKB_KEY_Up },
+ { "Right", XKB_KEY_Right },
+ { "Down", XKB_KEY_Down },
+ { "Prior", XKB_KEY_Prior },
+ { "Next", XKB_KEY_Next },
+ { "End", XKB_KEY_End },
+ { "Begin", XKB_KEY_Begin },
+ { "Select", XKB_KEY_Select },
+ { "Print", XKB_KEY_Print },
+ { "Execute", XKB_KEY_Execute },
+ { "Insert", XKB_KEY_Insert },
+ { "Undo", XKB_KEY_Undo },
+ { "Redo", XKB_KEY_Redo },
+ { "Menu", XKB_KEY_Menu },
+ { "Find", XKB_KEY_Find },
+ { "Cancel", XKB_KEY_Cancel },
+ { "Help", XKB_KEY_Help },
+ { "Break", XKB_KEY_Break },
+ { "Mode_switch", XKB_KEY_Mode_switch },
+ { "Num_Lock", XKB_KEY_Num_Lock },
+ { "KP_Space", XKB_KEY_KP_Space },
+ { "KP_Tab", XKB_KEY_KP_Tab },
+ { "KP_Enter", XKB_KEY_KP_Enter },
+ { "KP_F1", XKB_KEY_KP_F1 },
+ { "KP_F2", XKB_KEY_KP_F2 },
+ { "KP_F3", XKB_KEY_KP_F3 },
+ { "KP_F4", XKB_KEY_KP_F4 },
+ { "KP_Home", XKB_KEY_KP_Home },
+ { "KP_Left", XKB_KEY_KP_Left },
+ { "KP_Up", XKB_KEY_KP_Up },
+ { "KP_Right", XKB_KEY_KP_Right },
+ { "KP_Down", XKB_KEY_KP_Down },
+ { "KP_Prior", XKB_KEY_KP_Prior },
+ { "KP_Next", XKB_KEY_KP_Next },
+ { "KP_End", XKB_KEY_KP_End },
+ { "KP_Begin", XKB_KEY_KP_Begin },
+ { "KP_Insert", XKB_KEY_KP_Insert },
+ { "KP_Delete", XKB_KEY_KP_Delete },
+ { "KP_Multiply", XKB_KEY_KP_Multiply },
+ { "KP_Add", XKB_KEY_KP_Add },
+ { "KP_Separator", XKB_KEY_KP_Separator },
+ { "KP_Subtract", XKB_KEY_KP_Subtract },
+ { "KP_Decimal", XKB_KEY_KP_Decimal },
+ { "KP_Divide", XKB_KEY_KP_Divide },
+ { "KP_0", XKB_KEY_KP_0 },
+ { "KP_1", XKB_KEY_KP_1 },
+ { "KP_2", XKB_KEY_KP_2 },
+ { "KP_3", XKB_KEY_KP_3 },
+ { "KP_4", XKB_KEY_KP_4 },
+ { "KP_5", XKB_KEY_KP_5 },
+ { "KP_6", XKB_KEY_KP_6 },
+ { "KP_7", XKB_KEY_KP_7 },
+ { "KP_8", XKB_KEY_KP_8 },
+ { "KP_9", XKB_KEY_KP_9 },
+ { "KP_Equal", XKB_KEY_KP_Equal },
+ { "F1", XKB_KEY_F1 },
+ { "F2", XKB_KEY_F2 },
+ { "F3", XKB_KEY_F3 },
+ { "F4", XKB_KEY_F4 },
+ { "F5", XKB_KEY_F5 },
+ { "F6", XKB_KEY_F6 },
+ { "F7", XKB_KEY_F7 },
+ { "F8", XKB_KEY_F8 },
+ { "F9", XKB_KEY_F9 },
+ { "F10", XKB_KEY_F10 },
+ { "F11", XKB_KEY_F11 },
+ { "F12", XKB_KEY_F12 },
+ { "F13", XKB_KEY_F13 },
+ { "F14", XKB_KEY_F14 },
+ { "F15", XKB_KEY_F15 },
+ { "F16", XKB_KEY_F16 },
+ { "F17", XKB_KEY_F17 },
+ { "F18", XKB_KEY_F18 },
+ { "F19", XKB_KEY_F19 },
+ { "F20", XKB_KEY_F20 },
+ { "F21", XKB_KEY_F21 },
+ { "F22", XKB_KEY_F22 },
+ { "F23", XKB_KEY_F23 },
+ { "F24", XKB_KEY_F24 },
+ { "F25", XKB_KEY_F25 },
+ { "F26", XKB_KEY_F26 },
+ { "F27", XKB_KEY_F27 },
+ { "F28", XKB_KEY_F28 },
+ { "F29", XKB_KEY_F29 },
+ { "F30", XKB_KEY_F30 },
+ { "F31", XKB_KEY_F31 },
+ { "F32", XKB_KEY_F32 },
+ { "F33", XKB_KEY_F33 },
+ { "F34", XKB_KEY_F34 },
+ { "F35", XKB_KEY_F35 },
+ { "Shift_L", XKB_KEY_Shift_L },
+ { "Shift_R", XKB_KEY_Shift_R },
+ { "Control_L", XKB_KEY_Control_L },
+ { "Control_R", XKB_KEY_Control_R },
+ { "Caps_Lock", XKB_KEY_Caps_Lock },
+ { "Shift_Lock", XKB_KEY_Shift_Lock },
+ { "Meta_L", XKB_KEY_Meta_L },
+ { "Meta_R", XKB_KEY_Meta_R },
+ { "Alt_L", XKB_KEY_Alt_L },
+ { "Alt_R", XKB_KEY_Alt_R },
+ { "Super_L", XKB_KEY_Super_L },
+ { "Super_R", XKB_KEY_Super_R },
+ { "Hyper_L", XKB_KEY_Hyper_L },
+ { "Hyper_R", XKB_KEY_Hyper_R },
+ { "braille_dot_1", XKB_KEY_braille_dot_1 },
+ { "braille_dot_2", XKB_KEY_braille_dot_2 },
+ { "braille_dot_3", XKB_KEY_braille_dot_3 },
+ { "braille_dot_4", XKB_KEY_braille_dot_4 },
+ { "braille_dot_5", XKB_KEY_braille_dot_5 },
+ { "braille_dot_6", XKB_KEY_braille_dot_6 },
+ { "braille_dot_7", XKB_KEY_braille_dot_7 },
+ { "braille_dot_8", XKB_KEY_braille_dot_8 },
+ { "braille_dot_9", XKB_KEY_braille_dot_9 },
+ { "braille_dot_10", XKB_KEY_braille_dot_10 },
+ { "Delete", XKB_KEY_Delete },
+ { "VoidSymbol", XKB_KEY_VoidSymbol },
+ { "Ibreve", XKB_KEY_Ibreve },
+ { "ibreve", XKB_KEY_ibreve },
+ { "Wcircumflex", XKB_KEY_Wcircumflex },
+ { "wcircumflex", XKB_KEY_wcircumflex },
+ { "Ycircumflex", XKB_KEY_Ycircumflex },
+ { "ycircumflex", XKB_KEY_ycircumflex },
+ { "SCHWA", XKB_KEY_SCHWA },
+ { "Obarred", XKB_KEY_Obarred },
+ { "Ohorn", XKB_KEY_Ohorn },
+ { "ohorn", XKB_KEY_ohorn },
+ { "Uhorn", XKB_KEY_Uhorn },
+ { "uhorn", XKB_KEY_uhorn },
+ { "Zstroke", XKB_KEY_Zstroke },
+ { "zstroke", XKB_KEY_zstroke },
+ { "EZH", XKB_KEY_EZH },
+ { "Ocaron", XKB_KEY_Ocaron },
+ { "ocaron", XKB_KEY_ocaron },
+ { "Gcaron", XKB_KEY_Gcaron },
+ { "gcaron", XKB_KEY_gcaron },
+ { "schwa", XKB_KEY_schwa },
+ { "obarred", XKB_KEY_obarred },
+ { "ezh", XKB_KEY_ezh },
+ { "Cyrillic_GHE_bar", XKB_KEY_Cyrillic_GHE_bar },
+ { "Cyrillic_ghe_bar", XKB_KEY_Cyrillic_ghe_bar },
+ { "Cyrillic_ZHE_descender", XKB_KEY_Cyrillic_ZHE_descender },
+ { "Cyrillic_zhe_descender", XKB_KEY_Cyrillic_zhe_descender },
+ { "Cyrillic_KA_descender", XKB_KEY_Cyrillic_KA_descender },
+ { "Cyrillic_ka_descender", XKB_KEY_Cyrillic_ka_descender },
+ { "Cyrillic_KA_vertstroke", XKB_KEY_Cyrillic_KA_vertstroke },
+ { "Cyrillic_ka_vertstroke", XKB_KEY_Cyrillic_ka_vertstroke },
+ { "Cyrillic_EN_descender", XKB_KEY_Cyrillic_EN_descender },
+ { "Cyrillic_en_descender", XKB_KEY_Cyrillic_en_descender },
+ { "Cyrillic_U_straight", XKB_KEY_Cyrillic_U_straight },
+ { "Cyrillic_u_straight", XKB_KEY_Cyrillic_u_straight },
+ { "Cyrillic_U_straight_bar", XKB_KEY_Cyrillic_U_straight_bar },
+ { "Cyrillic_u_straight_bar", XKB_KEY_Cyrillic_u_straight_bar },
+ { "Cyrillic_HA_descender", XKB_KEY_Cyrillic_HA_descender },
+ { "Cyrillic_ha_descender", XKB_KEY_Cyrillic_ha_descender },
+ { "Cyrillic_CHE_descender", XKB_KEY_Cyrillic_CHE_descender },
+ { "Cyrillic_che_descender", XKB_KEY_Cyrillic_che_descender },
+ { "Cyrillic_CHE_vertstroke", XKB_KEY_Cyrillic_CHE_vertstroke },
+ { "Cyrillic_che_vertstroke", XKB_KEY_Cyrillic_che_vertstroke },
+ { "Cyrillic_SHHA", XKB_KEY_Cyrillic_SHHA },
+ { "Cyrillic_shha", XKB_KEY_Cyrillic_shha },
+ { "Cyrillic_SCHWA", XKB_KEY_Cyrillic_SCHWA },
+ { "Cyrillic_schwa", XKB_KEY_Cyrillic_schwa },
+ { "Cyrillic_I_macron", XKB_KEY_Cyrillic_I_macron },
+ { "Cyrillic_i_macron", XKB_KEY_Cyrillic_i_macron },
+ { "Cyrillic_O_bar", XKB_KEY_Cyrillic_O_bar },
+ { "Cyrillic_o_bar", XKB_KEY_Cyrillic_o_bar },
+ { "Cyrillic_U_macron", XKB_KEY_Cyrillic_U_macron },
+ { "Cyrillic_u_macron", XKB_KEY_Cyrillic_u_macron },
+ { "Armenian_AYB", XKB_KEY_Armenian_AYB },
+ { "Armenian_BEN", XKB_KEY_Armenian_BEN },
+ { "Armenian_GIM", XKB_KEY_Armenian_GIM },
+ { "Armenian_DA", XKB_KEY_Armenian_DA },
+ { "Armenian_YECH", XKB_KEY_Armenian_YECH },
+ { "Armenian_ZA", XKB_KEY_Armenian_ZA },
+ { "Armenian_E", XKB_KEY_Armenian_E },
+ { "Armenian_AT", XKB_KEY_Armenian_AT },
+ { "Armenian_TO", XKB_KEY_Armenian_TO },
+ { "Armenian_ZHE", XKB_KEY_Armenian_ZHE },
+ { "Armenian_INI", XKB_KEY_Armenian_INI },
+ { "Armenian_LYUN", XKB_KEY_Armenian_LYUN },
+ { "Armenian_KHE", XKB_KEY_Armenian_KHE },
+ { "Armenian_TSA", XKB_KEY_Armenian_TSA },
+ { "Armenian_KEN", XKB_KEY_Armenian_KEN },
+ { "Armenian_HO", XKB_KEY_Armenian_HO },
+ { "Armenian_DZA", XKB_KEY_Armenian_DZA },
+ { "Armenian_GHAT", XKB_KEY_Armenian_GHAT },
+ { "Armenian_TCHE", XKB_KEY_Armenian_TCHE },
+ { "Armenian_MEN", XKB_KEY_Armenian_MEN },
+ { "Armenian_HI", XKB_KEY_Armenian_HI },
+ { "Armenian_NU", XKB_KEY_Armenian_NU },
+ { "Armenian_SHA", XKB_KEY_Armenian_SHA },
+ { "Armenian_VO", XKB_KEY_Armenian_VO },
+ { "Armenian_CHA", XKB_KEY_Armenian_CHA },
+ { "Armenian_PE", XKB_KEY_Armenian_PE },
+ { "Armenian_JE", XKB_KEY_Armenian_JE },
+ { "Armenian_RA", XKB_KEY_Armenian_RA },
+ { "Armenian_SE", XKB_KEY_Armenian_SE },
+ { "Armenian_VEV", XKB_KEY_Armenian_VEV },
+ { "Armenian_TYUN", XKB_KEY_Armenian_TYUN },
+ { "Armenian_RE", XKB_KEY_Armenian_RE },
+ { "Armenian_TSO", XKB_KEY_Armenian_TSO },
+ { "Armenian_VYUN", XKB_KEY_Armenian_VYUN },
+ { "Armenian_PYUR", XKB_KEY_Armenian_PYUR },
+ { "Armenian_KE", XKB_KEY_Armenian_KE },
+ { "Armenian_O", XKB_KEY_Armenian_O },
+ { "Armenian_FE", XKB_KEY_Armenian_FE },
+ { "Armenian_apostrophe", XKB_KEY_Armenian_apostrophe },
+ { "Armenian_accent", XKB_KEY_Armenian_accent },
+ { "Armenian_exclam", XKB_KEY_Armenian_exclam },
+ { "Armenian_separation_mark", XKB_KEY_Armenian_separation_mark },
+ { "Armenian_question", XKB_KEY_Armenian_question },
+ { "Armenian_ayb", XKB_KEY_Armenian_ayb },
+ { "Armenian_ben", XKB_KEY_Armenian_ben },
+ { "Armenian_gim", XKB_KEY_Armenian_gim },
+ { "Armenian_da", XKB_KEY_Armenian_da },
+ { "Armenian_yech", XKB_KEY_Armenian_yech },
+ { "Armenian_za", XKB_KEY_Armenian_za },
+ { "Armenian_e", XKB_KEY_Armenian_e },
+ { "Armenian_at", XKB_KEY_Armenian_at },
+ { "Armenian_to", XKB_KEY_Armenian_to },
+ { "Armenian_zhe", XKB_KEY_Armenian_zhe },
+ { "Armenian_ini", XKB_KEY_Armenian_ini },
+ { "Armenian_lyun", XKB_KEY_Armenian_lyun },
+ { "Armenian_khe", XKB_KEY_Armenian_khe },
+ { "Armenian_tsa", XKB_KEY_Armenian_tsa },
+ { "Armenian_ken", XKB_KEY_Armenian_ken },
+ { "Armenian_ho", XKB_KEY_Armenian_ho },
+ { "Armenian_dza", XKB_KEY_Armenian_dza },
+ { "Armenian_ghat", XKB_KEY_Armenian_ghat },
+ { "Armenian_tche", XKB_KEY_Armenian_tche },
+ { "Armenian_men", XKB_KEY_Armenian_men },
+ { "Armenian_hi", XKB_KEY_Armenian_hi },
+ { "Armenian_nu", XKB_KEY_Armenian_nu },
+ { "Armenian_sha", XKB_KEY_Armenian_sha },
+ { "Armenian_vo", XKB_KEY_Armenian_vo },
+ { "Armenian_cha", XKB_KEY_Armenian_cha },
+ { "Armenian_pe", XKB_KEY_Armenian_pe },
+ { "Armenian_je", XKB_KEY_Armenian_je },
+ { "Armenian_ra", XKB_KEY_Armenian_ra },
+ { "Armenian_se", XKB_KEY_Armenian_se },
+ { "Armenian_vev", XKB_KEY_Armenian_vev },
+ { "Armenian_tyun", XKB_KEY_Armenian_tyun },
+ { "Armenian_re", XKB_KEY_Armenian_re },
+ { "Armenian_tso", XKB_KEY_Armenian_tso },
+ { "Armenian_vyun", XKB_KEY_Armenian_vyun },
+ { "Armenian_pyur", XKB_KEY_Armenian_pyur },
+ { "Armenian_ke", XKB_KEY_Armenian_ke },
+ { "Armenian_o", XKB_KEY_Armenian_o },
+ { "Armenian_fe", XKB_KEY_Armenian_fe },
+ { "Armenian_ligature_ew", XKB_KEY_Armenian_ligature_ew },
+ { "Armenian_full_stop", XKB_KEY_Armenian_full_stop },
+ { "Armenian_hyphen", XKB_KEY_Armenian_hyphen },
+ { "Arabic_madda_above", XKB_KEY_Arabic_madda_above },
+ { "Arabic_hamza_above", XKB_KEY_Arabic_hamza_above },
+ { "Arabic_hamza_below", XKB_KEY_Arabic_hamza_below },
+ { "Arabic_0", XKB_KEY_Arabic_0 },
+ { "Arabic_1", XKB_KEY_Arabic_1 },
+ { "Arabic_2", XKB_KEY_Arabic_2 },
+ { "Arabic_3", XKB_KEY_Arabic_3 },
+ { "Arabic_4", XKB_KEY_Arabic_4 },
+ { "Arabic_5", XKB_KEY_Arabic_5 },
+ { "Arabic_6", XKB_KEY_Arabic_6 },
+ { "Arabic_7", XKB_KEY_Arabic_7 },
+ { "Arabic_8", XKB_KEY_Arabic_8 },
+ { "Arabic_9", XKB_KEY_Arabic_9 },
+ { "Arabic_percent", XKB_KEY_Arabic_percent },
+ { "Arabic_superscript_alef", XKB_KEY_Arabic_superscript_alef },
+ { "Arabic_tteh", XKB_KEY_Arabic_tteh },
+ { "Arabic_peh", XKB_KEY_Arabic_peh },
+ { "Arabic_tcheh", XKB_KEY_Arabic_tcheh },
+ { "Arabic_ddal", XKB_KEY_Arabic_ddal },
+ { "Arabic_rreh", XKB_KEY_Arabic_rreh },
+ { "Arabic_jeh", XKB_KEY_Arabic_jeh },
+ { "Arabic_veh", XKB_KEY_Arabic_veh },
+ { "Arabic_keheh", XKB_KEY_Arabic_keheh },
+ { "Arabic_gaf", XKB_KEY_Arabic_gaf },
+ { "Arabic_noon_ghunna", XKB_KEY_Arabic_noon_ghunna },
+ { "Arabic_heh_doachashmee", XKB_KEY_Arabic_heh_doachashmee },
+ { "Arabic_heh_goal", XKB_KEY_Arabic_heh_goal },
+ { "Farsi_yeh", XKB_KEY_Farsi_yeh },
+ { "Arabic_yeh_baree", XKB_KEY_Arabic_yeh_baree },
+ { "Arabic_fullstop", XKB_KEY_Arabic_fullstop },
+ { "Farsi_0", XKB_KEY_Farsi_0 },
+ { "Farsi_1", XKB_KEY_Farsi_1 },
+ { "Farsi_2", XKB_KEY_Farsi_2 },
+ { "Farsi_3", XKB_KEY_Farsi_3 },
+ { "Farsi_4", XKB_KEY_Farsi_4 },
+ { "Farsi_5", XKB_KEY_Farsi_5 },
+ { "Farsi_6", XKB_KEY_Farsi_6 },
+ { "Farsi_7", XKB_KEY_Farsi_7 },
+ { "Farsi_8", XKB_KEY_Farsi_8 },
+ { "Farsi_9", XKB_KEY_Farsi_9 },
+ { "Sinh_ng", XKB_KEY_Sinh_ng },
+ { "Sinh_h2", XKB_KEY_Sinh_h2 },
+ { "Sinh_a", XKB_KEY_Sinh_a },
+ { "Sinh_aa", XKB_KEY_Sinh_aa },
+ { "Sinh_ae", XKB_KEY_Sinh_ae },
+ { "Sinh_aee", XKB_KEY_Sinh_aee },
+ { "Sinh_i", XKB_KEY_Sinh_i },
+ { "Sinh_ii", XKB_KEY_Sinh_ii },
+ { "Sinh_u", XKB_KEY_Sinh_u },
+ { "Sinh_uu", XKB_KEY_Sinh_uu },
+ { "Sinh_ri", XKB_KEY_Sinh_ri },
+ { "Sinh_rii", XKB_KEY_Sinh_rii },
+ { "Sinh_lu", XKB_KEY_Sinh_lu },
+ { "Sinh_luu", XKB_KEY_Sinh_luu },
+ { "Sinh_e", XKB_KEY_Sinh_e },
+ { "Sinh_ee", XKB_KEY_Sinh_ee },
+ { "Sinh_ai", XKB_KEY_Sinh_ai },
+ { "Sinh_o", XKB_KEY_Sinh_o },
+ { "Sinh_oo", XKB_KEY_Sinh_oo },
+ { "Sinh_au", XKB_KEY_Sinh_au },
+ { "Sinh_ka", XKB_KEY_Sinh_ka },
+ { "Sinh_kha", XKB_KEY_Sinh_kha },
+ { "Sinh_ga", XKB_KEY_Sinh_ga },
+ { "Sinh_gha", XKB_KEY_Sinh_gha },
+ { "Sinh_ng2", XKB_KEY_Sinh_ng2 },
+ { "Sinh_nga", XKB_KEY_Sinh_nga },
+ { "Sinh_ca", XKB_KEY_Sinh_ca },
+ { "Sinh_cha", XKB_KEY_Sinh_cha },
+ { "Sinh_ja", XKB_KEY_Sinh_ja },
+ { "Sinh_jha", XKB_KEY_Sinh_jha },
+ { "Sinh_nya", XKB_KEY_Sinh_nya },
+ { "Sinh_jnya", XKB_KEY_Sinh_jnya },
+ { "Sinh_nja", XKB_KEY_Sinh_nja },
+ { "Sinh_tta", XKB_KEY_Sinh_tta },
+ { "Sinh_ttha", XKB_KEY_Sinh_ttha },
+ { "Sinh_dda", XKB_KEY_Sinh_dda },
+ { "Sinh_ddha", XKB_KEY_Sinh_ddha },
+ { "Sinh_nna", XKB_KEY_Sinh_nna },
+ { "Sinh_ndda", XKB_KEY_Sinh_ndda },
+ { "Sinh_tha", XKB_KEY_Sinh_tha },
+ { "Sinh_thha", XKB_KEY_Sinh_thha },
+ { "Sinh_dha", XKB_KEY_Sinh_dha },
+ { "Sinh_dhha", XKB_KEY_Sinh_dhha },
+ { "Sinh_na", XKB_KEY_Sinh_na },
+ { "Sinh_ndha", XKB_KEY_Sinh_ndha },
+ { "Sinh_pa", XKB_KEY_Sinh_pa },
+ { "Sinh_pha", XKB_KEY_Sinh_pha },
+ { "Sinh_ba", XKB_KEY_Sinh_ba },
+ { "Sinh_bha", XKB_KEY_Sinh_bha },
+ { "Sinh_ma", XKB_KEY_Sinh_ma },
+ { "Sinh_mba", XKB_KEY_Sinh_mba },
+ { "Sinh_ya", XKB_KEY_Sinh_ya },
+ { "Sinh_ra", XKB_KEY_Sinh_ra },
+ { "Sinh_la", XKB_KEY_Sinh_la },
+ { "Sinh_va", XKB_KEY_Sinh_va },
+ { "Sinh_sha", XKB_KEY_Sinh_sha },
+ { "Sinh_ssha", XKB_KEY_Sinh_ssha },
+ { "Sinh_sa", XKB_KEY_Sinh_sa },
+ { "Sinh_ha", XKB_KEY_Sinh_ha },
+ { "Sinh_lla", XKB_KEY_Sinh_lla },
+ { "Sinh_fa", XKB_KEY_Sinh_fa },
+ { "Sinh_al", XKB_KEY_Sinh_al },
+ { "Sinh_aa2", XKB_KEY_Sinh_aa2 },
+ { "Sinh_ae2", XKB_KEY_Sinh_ae2 },
+ { "Sinh_aee2", XKB_KEY_Sinh_aee2 },
+ { "Sinh_i2", XKB_KEY_Sinh_i2 },
+ { "Sinh_ii2", XKB_KEY_Sinh_ii2 },
+ { "Sinh_u2", XKB_KEY_Sinh_u2 },
+ { "Sinh_uu2", XKB_KEY_Sinh_uu2 },
+ { "Sinh_ru2", XKB_KEY_Sinh_ru2 },
+ { "Sinh_e2", XKB_KEY_Sinh_e2 },
+ { "Sinh_ee2", XKB_KEY_Sinh_ee2 },
+ { "Sinh_ai2", XKB_KEY_Sinh_ai2 },
+ { "Sinh_o2", XKB_KEY_Sinh_o2 },
+ { "Sinh_oo2", XKB_KEY_Sinh_oo2 },
+ { "Sinh_au2", XKB_KEY_Sinh_au2 },
+ { "Sinh_lu2", XKB_KEY_Sinh_lu2 },
+ { "Sinh_ruu2", XKB_KEY_Sinh_ruu2 },
+ { "Sinh_luu2", XKB_KEY_Sinh_luu2 },
+ { "Sinh_kunddaliya", XKB_KEY_Sinh_kunddaliya },
+ { "Georgian_an", XKB_KEY_Georgian_an },
+ { "Georgian_ban", XKB_KEY_Georgian_ban },
+ { "Georgian_gan", XKB_KEY_Georgian_gan },
+ { "Georgian_don", XKB_KEY_Georgian_don },
+ { "Georgian_en", XKB_KEY_Georgian_en },
+ { "Georgian_vin", XKB_KEY_Georgian_vin },
+ { "Georgian_zen", XKB_KEY_Georgian_zen },
+ { "Georgian_tan", XKB_KEY_Georgian_tan },
+ { "Georgian_in", XKB_KEY_Georgian_in },
+ { "Georgian_kan", XKB_KEY_Georgian_kan },
+ { "Georgian_las", XKB_KEY_Georgian_las },
+ { "Georgian_man", XKB_KEY_Georgian_man },
+ { "Georgian_nar", XKB_KEY_Georgian_nar },
+ { "Georgian_on", XKB_KEY_Georgian_on },
+ { "Georgian_par", XKB_KEY_Georgian_par },
+ { "Georgian_zhar", XKB_KEY_Georgian_zhar },
+ { "Georgian_rae", XKB_KEY_Georgian_rae },
+ { "Georgian_san", XKB_KEY_Georgian_san },
+ { "Georgian_tar", XKB_KEY_Georgian_tar },
+ { "Georgian_un", XKB_KEY_Georgian_un },
+ { "Georgian_phar", XKB_KEY_Georgian_phar },
+ { "Georgian_khar", XKB_KEY_Georgian_khar },
+ { "Georgian_ghan", XKB_KEY_Georgian_ghan },
+ { "Georgian_qar", XKB_KEY_Georgian_qar },
+ { "Georgian_shin", XKB_KEY_Georgian_shin },
+ { "Georgian_chin", XKB_KEY_Georgian_chin },
+ { "Georgian_can", XKB_KEY_Georgian_can },
+ { "Georgian_jil", XKB_KEY_Georgian_jil },
+ { "Georgian_cil", XKB_KEY_Georgian_cil },
+ { "Georgian_char", XKB_KEY_Georgian_char },
+ { "Georgian_xan", XKB_KEY_Georgian_xan },
+ { "Georgian_jhan", XKB_KEY_Georgian_jhan },
+ { "Georgian_hae", XKB_KEY_Georgian_hae },
+ { "Georgian_he", XKB_KEY_Georgian_he },
+ { "Georgian_hie", XKB_KEY_Georgian_hie },
+ { "Georgian_we", XKB_KEY_Georgian_we },
+ { "Georgian_har", XKB_KEY_Georgian_har },
+ { "Georgian_hoe", XKB_KEY_Georgian_hoe },
+ { "Georgian_fi", XKB_KEY_Georgian_fi },
+ { "Babovedot", XKB_KEY_Babovedot },
+ { "babovedot", XKB_KEY_babovedot },
+ { "Dabovedot", XKB_KEY_Dabovedot },
+ { "dabovedot", XKB_KEY_dabovedot },
+ { "Fabovedot", XKB_KEY_Fabovedot },
+ { "fabovedot", XKB_KEY_fabovedot },
+ { "Lbelowdot", XKB_KEY_Lbelowdot },
+ { "lbelowdot", XKB_KEY_lbelowdot },
+ { "Mabovedot", XKB_KEY_Mabovedot },
+ { "mabovedot", XKB_KEY_mabovedot },
+ { "Pabovedot", XKB_KEY_Pabovedot },
+ { "pabovedot", XKB_KEY_pabovedot },
+ { "Sabovedot", XKB_KEY_Sabovedot },
+ { "sabovedot", XKB_KEY_sabovedot },
+ { "Tabovedot", XKB_KEY_Tabovedot },
+ { "tabovedot", XKB_KEY_tabovedot },
+ { "Wgrave", XKB_KEY_Wgrave },
+ { "wgrave", XKB_KEY_wgrave },
+ { "Wacute", XKB_KEY_Wacute },
+ { "wacute", XKB_KEY_wacute },
+ { "Wdiaeresis", XKB_KEY_Wdiaeresis },
+ { "wdiaeresis", XKB_KEY_wdiaeresis },
+ { "Xabovedot", XKB_KEY_Xabovedot },
+ { "xabovedot", XKB_KEY_xabovedot },
+ { "Abelowdot", XKB_KEY_Abelowdot },
+ { "abelowdot", XKB_KEY_abelowdot },
+ { "Ahook", XKB_KEY_Ahook },
+ { "ahook", XKB_KEY_ahook },
+ { "Acircumflexacute", XKB_KEY_Acircumflexacute },
+ { "acircumflexacute", XKB_KEY_acircumflexacute },
+ { "Acircumflexgrave", XKB_KEY_Acircumflexgrave },
+ { "acircumflexgrave", XKB_KEY_acircumflexgrave },
+ { "Acircumflexhook", XKB_KEY_Acircumflexhook },
+ { "acircumflexhook", XKB_KEY_acircumflexhook },
+ { "Acircumflextilde", XKB_KEY_Acircumflextilde },
+ { "acircumflextilde", XKB_KEY_acircumflextilde },
+ { "Acircumflexbelowdot", XKB_KEY_Acircumflexbelowdot },
+ { "acircumflexbelowdot", XKB_KEY_acircumflexbelowdot },
+ { "Abreveacute", XKB_KEY_Abreveacute },
+ { "abreveacute", XKB_KEY_abreveacute },
+ { "Abrevegrave", XKB_KEY_Abrevegrave },
+ { "abrevegrave", XKB_KEY_abrevegrave },
+ { "Abrevehook", XKB_KEY_Abrevehook },
+ { "abrevehook", XKB_KEY_abrevehook },
+ { "Abrevetilde", XKB_KEY_Abrevetilde },
+ { "abrevetilde", XKB_KEY_abrevetilde },
+ { "Abrevebelowdot", XKB_KEY_Abrevebelowdot },
+ { "abrevebelowdot", XKB_KEY_abrevebelowdot },
+ { "Ebelowdot", XKB_KEY_Ebelowdot },
+ { "ebelowdot", XKB_KEY_ebelowdot },
+ { "Ehook", XKB_KEY_Ehook },
+ { "ehook", XKB_KEY_ehook },
+ { "Etilde", XKB_KEY_Etilde },
+ { "etilde", XKB_KEY_etilde },
+ { "Ecircumflexacute", XKB_KEY_Ecircumflexacute },
+ { "ecircumflexacute", XKB_KEY_ecircumflexacute },
+ { "Ecircumflexgrave", XKB_KEY_Ecircumflexgrave },
+ { "ecircumflexgrave", XKB_KEY_ecircumflexgrave },
+ { "Ecircumflexhook", XKB_KEY_Ecircumflexhook },
+ { "ecircumflexhook", XKB_KEY_ecircumflexhook },
+ { "Ecircumflextilde", XKB_KEY_Ecircumflextilde },
+ { "ecircumflextilde", XKB_KEY_ecircumflextilde },
+ { "Ecircumflexbelowdot", XKB_KEY_Ecircumflexbelowdot },
+ { "ecircumflexbelowdot", XKB_KEY_ecircumflexbelowdot },
+ { "Ihook", XKB_KEY_Ihook },
+ { "ihook", XKB_KEY_ihook },
+ { "Ibelowdot", XKB_KEY_Ibelowdot },
+ { "ibelowdot", XKB_KEY_ibelowdot },
+ { "Obelowdot", XKB_KEY_Obelowdot },
+ { "obelowdot", XKB_KEY_obelowdot },
+ { "Ohook", XKB_KEY_Ohook },
+ { "ohook", XKB_KEY_ohook },
+ { "Ocircumflexacute", XKB_KEY_Ocircumflexacute },
+ { "ocircumflexacute", XKB_KEY_ocircumflexacute },
+ { "Ocircumflexgrave", XKB_KEY_Ocircumflexgrave },
+ { "ocircumflexgrave", XKB_KEY_ocircumflexgrave },
+ { "Ocircumflexhook", XKB_KEY_Ocircumflexhook },
+ { "ocircumflexhook", XKB_KEY_ocircumflexhook },
+ { "Ocircumflextilde", XKB_KEY_Ocircumflextilde },
+ { "ocircumflextilde", XKB_KEY_ocircumflextilde },
+ { "Ocircumflexbelowdot", XKB_KEY_Ocircumflexbelowdot },
+ { "ocircumflexbelowdot", XKB_KEY_ocircumflexbelowdot },
+ { "Ohornacute", XKB_KEY_Ohornacute },
+ { "ohornacute", XKB_KEY_ohornacute },
+ { "Ohorngrave", XKB_KEY_Ohorngrave },
+ { "ohorngrave", XKB_KEY_ohorngrave },
+ { "Ohornhook", XKB_KEY_Ohornhook },
+ { "ohornhook", XKB_KEY_ohornhook },
+ { "Ohorntilde", XKB_KEY_Ohorntilde },
+ { "ohorntilde", XKB_KEY_ohorntilde },
+ { "Ohornbelowdot", XKB_KEY_Ohornbelowdot },
+ { "ohornbelowdot", XKB_KEY_ohornbelowdot },
+ { "Ubelowdot", XKB_KEY_Ubelowdot },
+ { "ubelowdot", XKB_KEY_ubelowdot },
+ { "Uhook", XKB_KEY_Uhook },
+ { "uhook", XKB_KEY_uhook },
+ { "Uhornacute", XKB_KEY_Uhornacute },
+ { "uhornacute", XKB_KEY_uhornacute },
+ { "Uhorngrave", XKB_KEY_Uhorngrave },
+ { "uhorngrave", XKB_KEY_uhorngrave },
+ { "Uhornhook", XKB_KEY_Uhornhook },
+ { "uhornhook", XKB_KEY_uhornhook },
+ { "Uhorntilde", XKB_KEY_Uhorntilde },
+ { "uhorntilde", XKB_KEY_uhorntilde },
+ { "Uhornbelowdot", XKB_KEY_Uhornbelowdot },
+ { "uhornbelowdot", XKB_KEY_uhornbelowdot },
+ { "Ygrave", XKB_KEY_Ygrave },
+ { "ygrave", XKB_KEY_ygrave },
+ { "Ybelowdot", XKB_KEY_Ybelowdot },
+ { "ybelowdot", XKB_KEY_ybelowdot },
+ { "Yhook", XKB_KEY_Yhook },
+ { "yhook", XKB_KEY_yhook },
+ { "Ytilde", XKB_KEY_Ytilde },
+ { "ytilde", XKB_KEY_ytilde },
+ { "zerosuperior", XKB_KEY_zerosuperior },
+ { "foursuperior", XKB_KEY_foursuperior },
+ { "fivesuperior", XKB_KEY_fivesuperior },
+ { "sixsuperior", XKB_KEY_sixsuperior },
+ { "sevensuperior", XKB_KEY_sevensuperior },
+ { "eightsuperior", XKB_KEY_eightsuperior },
+ { "ninesuperior", XKB_KEY_ninesuperior },
+ { "zerosubscript", XKB_KEY_zerosubscript },
+ { "onesubscript", XKB_KEY_onesubscript },
+ { "twosubscript", XKB_KEY_twosubscript },
+ { "threesubscript", XKB_KEY_threesubscript },
+ { "foursubscript", XKB_KEY_foursubscript },
+ { "fivesubscript", XKB_KEY_fivesubscript },
+ { "sixsubscript", XKB_KEY_sixsubscript },
+ { "sevensubscript", XKB_KEY_sevensubscript },
+ { "eightsubscript", XKB_KEY_eightsubscript },
+ { "ninesubscript", XKB_KEY_ninesubscript },
+ { "EcuSign", XKB_KEY_EcuSign },
+ { "ColonSign", XKB_KEY_ColonSign },
+ { "CruzeiroSign", XKB_KEY_CruzeiroSign },
+ { "FFrancSign", XKB_KEY_FFrancSign },
+ { "LiraSign", XKB_KEY_LiraSign },
+ { "MillSign", XKB_KEY_MillSign },
+ { "NairaSign", XKB_KEY_NairaSign },
+ { "PesetaSign", XKB_KEY_PesetaSign },
+ { "RupeeSign", XKB_KEY_RupeeSign },
+ { "WonSign", XKB_KEY_WonSign },
+ { "NewSheqelSign", XKB_KEY_NewSheqelSign },
+ { "DongSign", XKB_KEY_DongSign },
+ { "partdifferential", XKB_KEY_partdifferential },
+ { "emptyset", XKB_KEY_emptyset },
+ { "elementof", XKB_KEY_elementof },
+ { "notelementof", XKB_KEY_notelementof },
+ { "containsas", XKB_KEY_containsas },
+ { "squareroot", XKB_KEY_squareroot },
+ { "cuberoot", XKB_KEY_cuberoot },
+ { "fourthroot", XKB_KEY_fourthroot },
+ { "dintegral", XKB_KEY_dintegral },
+ { "tintegral", XKB_KEY_tintegral },
+ { "because", XKB_KEY_because },
+ { "notapproxeq", XKB_KEY_notapproxeq },
+ { "approxeq", XKB_KEY_approxeq },
+ { "notidentical", XKB_KEY_notidentical },
+ { "stricteq", XKB_KEY_stricteq },
+ { "braille_blank", XKB_KEY_braille_blank },
+ { "braille_dots_1", XKB_KEY_braille_dots_1 },
+ { "braille_dots_2", XKB_KEY_braille_dots_2 },
+ { "braille_dots_12", XKB_KEY_braille_dots_12 },
+ { "braille_dots_3", XKB_KEY_braille_dots_3 },
+ { "braille_dots_13", XKB_KEY_braille_dots_13 },
+ { "braille_dots_23", XKB_KEY_braille_dots_23 },
+ { "braille_dots_123", XKB_KEY_braille_dots_123 },
+ { "braille_dots_4", XKB_KEY_braille_dots_4 },
+ { "braille_dots_14", XKB_KEY_braille_dots_14 },
+ { "braille_dots_24", XKB_KEY_braille_dots_24 },
+ { "braille_dots_124", XKB_KEY_braille_dots_124 },
+ { "braille_dots_34", XKB_KEY_braille_dots_34 },
+ { "braille_dots_134", XKB_KEY_braille_dots_134 },
+ { "braille_dots_234", XKB_KEY_braille_dots_234 },
+ { "braille_dots_1234", XKB_KEY_braille_dots_1234 },
+ { "braille_dots_5", XKB_KEY_braille_dots_5 },
+ { "braille_dots_15", XKB_KEY_braille_dots_15 },
+ { "braille_dots_25", XKB_KEY_braille_dots_25 },
+ { "braille_dots_125", XKB_KEY_braille_dots_125 },
+ { "braille_dots_35", XKB_KEY_braille_dots_35 },
+ { "braille_dots_135", XKB_KEY_braille_dots_135 },
+ { "braille_dots_235", XKB_KEY_braille_dots_235 },
+ { "braille_dots_1235", XKB_KEY_braille_dots_1235 },
+ { "braille_dots_45", XKB_KEY_braille_dots_45 },
+ { "braille_dots_145", XKB_KEY_braille_dots_145 },
+ { "braille_dots_245", XKB_KEY_braille_dots_245 },
+ { "braille_dots_1245", XKB_KEY_braille_dots_1245 },
+ { "braille_dots_345", XKB_KEY_braille_dots_345 },
+ { "braille_dots_1345", XKB_KEY_braille_dots_1345 },
+ { "braille_dots_2345", XKB_KEY_braille_dots_2345 },
+ { "braille_dots_12345", XKB_KEY_braille_dots_12345 },
+ { "braille_dots_6", XKB_KEY_braille_dots_6 },
+ { "braille_dots_16", XKB_KEY_braille_dots_16 },
+ { "braille_dots_26", XKB_KEY_braille_dots_26 },
+ { "braille_dots_126", XKB_KEY_braille_dots_126 },
+ { "braille_dots_36", XKB_KEY_braille_dots_36 },
+ { "braille_dots_136", XKB_KEY_braille_dots_136 },
+ { "braille_dots_236", XKB_KEY_braille_dots_236 },
+ { "braille_dots_1236", XKB_KEY_braille_dots_1236 },
+ { "braille_dots_46", XKB_KEY_braille_dots_46 },
+ { "braille_dots_146", XKB_KEY_braille_dots_146 },
+ { "braille_dots_246", XKB_KEY_braille_dots_246 },
+ { "braille_dots_1246", XKB_KEY_braille_dots_1246 },
+ { "braille_dots_346", XKB_KEY_braille_dots_346 },
+ { "braille_dots_1346", XKB_KEY_braille_dots_1346 },
+ { "braille_dots_2346", XKB_KEY_braille_dots_2346 },
+ { "braille_dots_12346", XKB_KEY_braille_dots_12346 },
+ { "braille_dots_56", XKB_KEY_braille_dots_56 },
+ { "braille_dots_156", XKB_KEY_braille_dots_156 },
+ { "braille_dots_256", XKB_KEY_braille_dots_256 },
+ { "braille_dots_1256", XKB_KEY_braille_dots_1256 },
+ { "braille_dots_356", XKB_KEY_braille_dots_356 },
+ { "braille_dots_1356", XKB_KEY_braille_dots_1356 },
+ { "braille_dots_2356", XKB_KEY_braille_dots_2356 },
+ { "braille_dots_12356", XKB_KEY_braille_dots_12356 },
+ { "braille_dots_456", XKB_KEY_braille_dots_456 },
+ { "braille_dots_1456", XKB_KEY_braille_dots_1456 },
+ { "braille_dots_2456", XKB_KEY_braille_dots_2456 },
+ { "braille_dots_12456", XKB_KEY_braille_dots_12456 },
+ { "braille_dots_3456", XKB_KEY_braille_dots_3456 },
+ { "braille_dots_13456", XKB_KEY_braille_dots_13456 },
+ { "braille_dots_23456", XKB_KEY_braille_dots_23456 },
+ { "braille_dots_123456", XKB_KEY_braille_dots_123456 },
+ { "braille_dots_7", XKB_KEY_braille_dots_7 },
+ { "braille_dots_17", XKB_KEY_braille_dots_17 },
+ { "braille_dots_27", XKB_KEY_braille_dots_27 },
+ { "braille_dots_127", XKB_KEY_braille_dots_127 },
+ { "braille_dots_37", XKB_KEY_braille_dots_37 },
+ { "braille_dots_137", XKB_KEY_braille_dots_137 },
+ { "braille_dots_237", XKB_KEY_braille_dots_237 },
+ { "braille_dots_1237", XKB_KEY_braille_dots_1237 },
+ { "braille_dots_47", XKB_KEY_braille_dots_47 },
+ { "braille_dots_147", XKB_KEY_braille_dots_147 },
+ { "braille_dots_247", XKB_KEY_braille_dots_247 },
+ { "braille_dots_1247", XKB_KEY_braille_dots_1247 },
+ { "braille_dots_347", XKB_KEY_braille_dots_347 },
+ { "braille_dots_1347", XKB_KEY_braille_dots_1347 },
+ { "braille_dots_2347", XKB_KEY_braille_dots_2347 },
+ { "braille_dots_12347", XKB_KEY_braille_dots_12347 },
+ { "braille_dots_57", XKB_KEY_braille_dots_57 },
+ { "braille_dots_157", XKB_KEY_braille_dots_157 },
+ { "braille_dots_257", XKB_KEY_braille_dots_257 },
+ { "braille_dots_1257", XKB_KEY_braille_dots_1257 },
+ { "braille_dots_357", XKB_KEY_braille_dots_357 },
+ { "braille_dots_1357", XKB_KEY_braille_dots_1357 },
+ { "braille_dots_2357", XKB_KEY_braille_dots_2357 },
+ { "braille_dots_12357", XKB_KEY_braille_dots_12357 },
+ { "braille_dots_457", XKB_KEY_braille_dots_457 },
+ { "braille_dots_1457", XKB_KEY_braille_dots_1457 },
+ { "braille_dots_2457", XKB_KEY_braille_dots_2457 },
+ { "braille_dots_12457", XKB_KEY_braille_dots_12457 },
+ { "braille_dots_3457", XKB_KEY_braille_dots_3457 },
+ { "braille_dots_13457", XKB_KEY_braille_dots_13457 },
+ { "braille_dots_23457", XKB_KEY_braille_dots_23457 },
+ { "braille_dots_123457", XKB_KEY_braille_dots_123457 },
+ { "braille_dots_67", XKB_KEY_braille_dots_67 },
+ { "braille_dots_167", XKB_KEY_braille_dots_167 },
+ { "braille_dots_267", XKB_KEY_braille_dots_267 },
+ { "braille_dots_1267", XKB_KEY_braille_dots_1267 },
+ { "braille_dots_367", XKB_KEY_braille_dots_367 },
+ { "braille_dots_1367", XKB_KEY_braille_dots_1367 },
+ { "braille_dots_2367", XKB_KEY_braille_dots_2367 },
+ { "braille_dots_12367", XKB_KEY_braille_dots_12367 },
+ { "braille_dots_467", XKB_KEY_braille_dots_467 },
+ { "braille_dots_1467", XKB_KEY_braille_dots_1467 },
+ { "braille_dots_2467", XKB_KEY_braille_dots_2467 },
+ { "braille_dots_12467", XKB_KEY_braille_dots_12467 },
+ { "braille_dots_3467", XKB_KEY_braille_dots_3467 },
+ { "braille_dots_13467", XKB_KEY_braille_dots_13467 },
+ { "braille_dots_23467", XKB_KEY_braille_dots_23467 },
+ { "braille_dots_123467", XKB_KEY_braille_dots_123467 },
+ { "braille_dots_567", XKB_KEY_braille_dots_567 },
+ { "braille_dots_1567", XKB_KEY_braille_dots_1567 },
+ { "braille_dots_2567", XKB_KEY_braille_dots_2567 },
+ { "braille_dots_12567", XKB_KEY_braille_dots_12567 },
+ { "braille_dots_3567", XKB_KEY_braille_dots_3567 },
+ { "braille_dots_13567", XKB_KEY_braille_dots_13567 },
+ { "braille_dots_23567", XKB_KEY_braille_dots_23567 },
+ { "braille_dots_123567", XKB_KEY_braille_dots_123567 },
+ { "braille_dots_4567", XKB_KEY_braille_dots_4567 },
+ { "braille_dots_14567", XKB_KEY_braille_dots_14567 },
+ { "braille_dots_24567", XKB_KEY_braille_dots_24567 },
+ { "braille_dots_124567", XKB_KEY_braille_dots_124567 },
+ { "braille_dots_34567", XKB_KEY_braille_dots_34567 },
+ { "braille_dots_134567", XKB_KEY_braille_dots_134567 },
+ { "braille_dots_234567", XKB_KEY_braille_dots_234567 },
+ { "braille_dots_1234567", XKB_KEY_braille_dots_1234567 },
+ { "braille_dots_8", XKB_KEY_braille_dots_8 },
+ { "braille_dots_18", XKB_KEY_braille_dots_18 },
+ { "braille_dots_28", XKB_KEY_braille_dots_28 },
+ { "braille_dots_128", XKB_KEY_braille_dots_128 },
+ { "braille_dots_38", XKB_KEY_braille_dots_38 },
+ { "braille_dots_138", XKB_KEY_braille_dots_138 },
+ { "braille_dots_238", XKB_KEY_braille_dots_238 },
+ { "braille_dots_1238", XKB_KEY_braille_dots_1238 },
+ { "braille_dots_48", XKB_KEY_braille_dots_48 },
+ { "braille_dots_148", XKB_KEY_braille_dots_148 },
+ { "braille_dots_248", XKB_KEY_braille_dots_248 },
+ { "braille_dots_1248", XKB_KEY_braille_dots_1248 },
+ { "braille_dots_348", XKB_KEY_braille_dots_348 },
+ { "braille_dots_1348", XKB_KEY_braille_dots_1348 },
+ { "braille_dots_2348", XKB_KEY_braille_dots_2348 },
+ { "braille_dots_12348", XKB_KEY_braille_dots_12348 },
+ { "braille_dots_58", XKB_KEY_braille_dots_58 },
+ { "braille_dots_158", XKB_KEY_braille_dots_158 },
+ { "braille_dots_258", XKB_KEY_braille_dots_258 },
+ { "braille_dots_1258", XKB_KEY_braille_dots_1258 },
+ { "braille_dots_358", XKB_KEY_braille_dots_358 },
+ { "braille_dots_1358", XKB_KEY_braille_dots_1358 },
+ { "braille_dots_2358", XKB_KEY_braille_dots_2358 },
+ { "braille_dots_12358", XKB_KEY_braille_dots_12358 },
+ { "braille_dots_458", XKB_KEY_braille_dots_458 },
+ { "braille_dots_1458", XKB_KEY_braille_dots_1458 },
+ { "braille_dots_2458", XKB_KEY_braille_dots_2458 },
+ { "braille_dots_12458", XKB_KEY_braille_dots_12458 },
+ { "braille_dots_3458", XKB_KEY_braille_dots_3458 },
+ { "braille_dots_13458", XKB_KEY_braille_dots_13458 },
+ { "braille_dots_23458", XKB_KEY_braille_dots_23458 },
+ { "braille_dots_123458", XKB_KEY_braille_dots_123458 },
+ { "braille_dots_68", XKB_KEY_braille_dots_68 },
+ { "braille_dots_168", XKB_KEY_braille_dots_168 },
+ { "braille_dots_268", XKB_KEY_braille_dots_268 },
+ { "braille_dots_1268", XKB_KEY_braille_dots_1268 },
+ { "braille_dots_368", XKB_KEY_braille_dots_368 },
+ { "braille_dots_1368", XKB_KEY_braille_dots_1368 },
+ { "braille_dots_2368", XKB_KEY_braille_dots_2368 },
+ { "braille_dots_12368", XKB_KEY_braille_dots_12368 },
+ { "braille_dots_468", XKB_KEY_braille_dots_468 },
+ { "braille_dots_1468", XKB_KEY_braille_dots_1468 },
+ { "braille_dots_2468", XKB_KEY_braille_dots_2468 },
+ { "braille_dots_12468", XKB_KEY_braille_dots_12468 },
+ { "braille_dots_3468", XKB_KEY_braille_dots_3468 },
+ { "braille_dots_13468", XKB_KEY_braille_dots_13468 },
+ { "braille_dots_23468", XKB_KEY_braille_dots_23468 },
+ { "braille_dots_123468", XKB_KEY_braille_dots_123468 },
+ { "braille_dots_568", XKB_KEY_braille_dots_568 },
+ { "braille_dots_1568", XKB_KEY_braille_dots_1568 },
+ { "braille_dots_2568", XKB_KEY_braille_dots_2568 },
+ { "braille_dots_12568", XKB_KEY_braille_dots_12568 },
+ { "braille_dots_3568", XKB_KEY_braille_dots_3568 },
+ { "braille_dots_13568", XKB_KEY_braille_dots_13568 },
+ { "braille_dots_23568", XKB_KEY_braille_dots_23568 },
+ { "braille_dots_123568", XKB_KEY_braille_dots_123568 },
+ { "braille_dots_4568", XKB_KEY_braille_dots_4568 },
+ { "braille_dots_14568", XKB_KEY_braille_dots_14568 },
+ { "braille_dots_24568", XKB_KEY_braille_dots_24568 },
+ { "braille_dots_124568", XKB_KEY_braille_dots_124568 },
+ { "braille_dots_34568", XKB_KEY_braille_dots_34568 },
+ { "braille_dots_134568", XKB_KEY_braille_dots_134568 },
+ { "braille_dots_234568", XKB_KEY_braille_dots_234568 },
+ { "braille_dots_1234568", XKB_KEY_braille_dots_1234568 },
+ { "braille_dots_78", XKB_KEY_braille_dots_78 },
+ { "braille_dots_178", XKB_KEY_braille_dots_178 },
+ { "braille_dots_278", XKB_KEY_braille_dots_278 },
+ { "braille_dots_1278", XKB_KEY_braille_dots_1278 },
+ { "braille_dots_378", XKB_KEY_braille_dots_378 },
+ { "braille_dots_1378", XKB_KEY_braille_dots_1378 },
+ { "braille_dots_2378", XKB_KEY_braille_dots_2378 },
+ { "braille_dots_12378", XKB_KEY_braille_dots_12378 },
+ { "braille_dots_478", XKB_KEY_braille_dots_478 },
+ { "braille_dots_1478", XKB_KEY_braille_dots_1478 },
+ { "braille_dots_2478", XKB_KEY_braille_dots_2478 },
+ { "braille_dots_12478", XKB_KEY_braille_dots_12478 },
+ { "braille_dots_3478", XKB_KEY_braille_dots_3478 },
+ { "braille_dots_13478", XKB_KEY_braille_dots_13478 },
+ { "braille_dots_23478", XKB_KEY_braille_dots_23478 },
+ { "braille_dots_123478", XKB_KEY_braille_dots_123478 },
+ { "braille_dots_578", XKB_KEY_braille_dots_578 },
+ { "braille_dots_1578", XKB_KEY_braille_dots_1578 },
+ { "braille_dots_2578", XKB_KEY_braille_dots_2578 },
+ { "braille_dots_12578", XKB_KEY_braille_dots_12578 },
+ { "braille_dots_3578", XKB_KEY_braille_dots_3578 },
+ { "braille_dots_13578", XKB_KEY_braille_dots_13578 },
+ { "braille_dots_23578", XKB_KEY_braille_dots_23578 },
+ { "braille_dots_123578", XKB_KEY_braille_dots_123578 },
+ { "braille_dots_4578", XKB_KEY_braille_dots_4578 },
+ { "braille_dots_14578", XKB_KEY_braille_dots_14578 },
+ { "braille_dots_24578", XKB_KEY_braille_dots_24578 },
+ { "braille_dots_124578", XKB_KEY_braille_dots_124578 },
+ { "braille_dots_34578", XKB_KEY_braille_dots_34578 },
+ { "braille_dots_134578", XKB_KEY_braille_dots_134578 },
+ { "braille_dots_234578", XKB_KEY_braille_dots_234578 },
+ { "braille_dots_1234578", XKB_KEY_braille_dots_1234578 },
+ { "braille_dots_678", XKB_KEY_braille_dots_678 },
+ { "braille_dots_1678", XKB_KEY_braille_dots_1678 },
+ { "braille_dots_2678", XKB_KEY_braille_dots_2678 },
+ { "braille_dots_12678", XKB_KEY_braille_dots_12678 },
+ { "braille_dots_3678", XKB_KEY_braille_dots_3678 },
+ { "braille_dots_13678", XKB_KEY_braille_dots_13678 },
+ { "braille_dots_23678", XKB_KEY_braille_dots_23678 },
+ { "braille_dots_123678", XKB_KEY_braille_dots_123678 },
+ { "braille_dots_4678", XKB_KEY_braille_dots_4678 },
+ { "braille_dots_14678", XKB_KEY_braille_dots_14678 },
+ { "braille_dots_24678", XKB_KEY_braille_dots_24678 },
+ { "braille_dots_124678", XKB_KEY_braille_dots_124678 },
+ { "braille_dots_34678", XKB_KEY_braille_dots_34678 },
+ { "braille_dots_134678", XKB_KEY_braille_dots_134678 },
+ { "braille_dots_234678", XKB_KEY_braille_dots_234678 },
+ { "braille_dots_1234678", XKB_KEY_braille_dots_1234678 },
+ { "braille_dots_5678", XKB_KEY_braille_dots_5678 },
+ { "braille_dots_15678", XKB_KEY_braille_dots_15678 },
+ { "braille_dots_25678", XKB_KEY_braille_dots_25678 },
+ { "braille_dots_125678", XKB_KEY_braille_dots_125678 },
+ { "braille_dots_35678", XKB_KEY_braille_dots_35678 },
+ { "braille_dots_135678", XKB_KEY_braille_dots_135678 },
+ { "braille_dots_235678", XKB_KEY_braille_dots_235678 },
+ { "braille_dots_1235678", XKB_KEY_braille_dots_1235678 },
+ { "braille_dots_45678", XKB_KEY_braille_dots_45678 },
+ { "braille_dots_145678", XKB_KEY_braille_dots_145678 },
+ { "braille_dots_245678", XKB_KEY_braille_dots_245678 },
+ { "braille_dots_1245678", XKB_KEY_braille_dots_1245678 },
+ { "braille_dots_345678", XKB_KEY_braille_dots_345678 },
+ { "braille_dots_1345678", XKB_KEY_braille_dots_1345678 },
+ { "braille_dots_2345678", XKB_KEY_braille_dots_2345678 },
+ { "braille_dots_12345678", XKB_KEY_braille_dots_12345678 },
+ { "hpmute_acute", XKB_KEY_hpmute_acute },
+ { "hpmute_grave", XKB_KEY_hpmute_grave },
+ { "hpmute_asciicircum", XKB_KEY_hpmute_asciicircum },
+ { "hpmute_diaeresis", XKB_KEY_hpmute_diaeresis },
+ { "hpmute_asciitilde", XKB_KEY_hpmute_asciitilde },
+ { "hplira", XKB_KEY_hplira },
+ { "hpguilder", XKB_KEY_hpguilder },
+ { "hpYdiaeresis", XKB_KEY_hpYdiaeresis },
+ { "hplongminus", XKB_KEY_hplongminus },
+ { "hpblock", XKB_KEY_hpblock },
+ { "Ddiaeresis", XKB_KEY_Ddiaeresis },
+ { "Dacute_accent", XKB_KEY_Dacute_accent },
+ { "Dcedilla_accent", XKB_KEY_Dcedilla_accent },
+ { "Dcircumflex_accent", XKB_KEY_Dcircumflex_accent },
+ { "Dgrave_accent", XKB_KEY_Dgrave_accent },
+ { "Dtilde", XKB_KEY_Dtilde },
+ { "Dring_accent", XKB_KEY_Dring_accent },
+ { "DRemove", XKB_KEY_DRemove },
+ { "hpModelock1", XKB_KEY_hpModelock1 },
+ { "hpModelock2", XKB_KEY_hpModelock2 },
+ { "hpReset", XKB_KEY_hpReset },
+ { "hpSystem", XKB_KEY_hpSystem },
+ { "hpUser", XKB_KEY_hpUser },
+ { "hpClearLine", XKB_KEY_hpClearLine },
+ { "hpInsertLine", XKB_KEY_hpInsertLine },
+ { "hpDeleteLine", XKB_KEY_hpDeleteLine },
+ { "hpInsertChar", XKB_KEY_hpInsertChar },
+ { "hpDeleteChar", XKB_KEY_hpDeleteChar },
+ { "hpBackTab", XKB_KEY_hpBackTab },
+ { "hpKP_BackTab", XKB_KEY_hpKP_BackTab },
+ { "Ext16bit_L", XKB_KEY_Ext16bit_L },
+ { "Ext16bit_R", XKB_KEY_Ext16bit_R },
+ { "osfCopy", XKB_KEY_osfCopy },
+ { "osfCut", XKB_KEY_osfCut },
+ { "osfPaste", XKB_KEY_osfPaste },
+ { "osfBackTab", XKB_KEY_osfBackTab },
+ { "osfBackSpace", XKB_KEY_osfBackSpace },
+ { "osfClear", XKB_KEY_osfClear },
+ { "osfEscape", XKB_KEY_osfEscape },
+ { "osfAddMode", XKB_KEY_osfAddMode },
+ { "osfPrimaryPaste", XKB_KEY_osfPrimaryPaste },
+ { "osfQuickPaste", XKB_KEY_osfQuickPaste },
+ { "osfPageLeft", XKB_KEY_osfPageLeft },
+ { "osfPageUp", XKB_KEY_osfPageUp },
+ { "osfPageDown", XKB_KEY_osfPageDown },
+ { "osfPageRight", XKB_KEY_osfPageRight },
+ { "osfActivate", XKB_KEY_osfActivate },
+ { "osfMenuBar", XKB_KEY_osfMenuBar },
+ { "osfLeft", XKB_KEY_osfLeft },
+ { "osfUp", XKB_KEY_osfUp },
+ { "osfRight", XKB_KEY_osfRight },
+ { "osfDown", XKB_KEY_osfDown },
+ { "osfEndLine", XKB_KEY_osfEndLine },
+ { "osfBeginLine", XKB_KEY_osfBeginLine },
+ { "osfEndData", XKB_KEY_osfEndData },
+ { "osfBeginData", XKB_KEY_osfBeginData },
+ { "osfPrevMenu", XKB_KEY_osfPrevMenu },
+ { "osfNextMenu", XKB_KEY_osfNextMenu },
+ { "osfPrevField", XKB_KEY_osfPrevField },
+ { "osfNextField", XKB_KEY_osfNextField },
+ { "osfSelect", XKB_KEY_osfSelect },
+ { "osfInsert", XKB_KEY_osfInsert },
+ { "osfUndo", XKB_KEY_osfUndo },
+ { "osfMenu", XKB_KEY_osfMenu },
+ { "osfCancel", XKB_KEY_osfCancel },
+ { "osfHelp", XKB_KEY_osfHelp },
+ { "osfSelectAll", XKB_KEY_osfSelectAll },
+ { "osfDeselectAll", XKB_KEY_osfDeselectAll },
+ { "osfReselect", XKB_KEY_osfReselect },
+ { "osfExtend", XKB_KEY_osfExtend },
+ { "osfRestore", XKB_KEY_osfRestore },
+ { "osfDelete", XKB_KEY_osfDelete },
+ { "SunFA_Grave", XKB_KEY_SunFA_Grave },
+ { "SunFA_Circum", XKB_KEY_SunFA_Circum },
+ { "SunFA_Tilde", XKB_KEY_SunFA_Tilde },
+ { "SunFA_Acute", XKB_KEY_SunFA_Acute },
+ { "SunFA_Diaeresis", XKB_KEY_SunFA_Diaeresis },
+ { "SunFA_Cedilla", XKB_KEY_SunFA_Cedilla },
+ { "SunF36", XKB_KEY_SunF36 },
+ { "SunF37", XKB_KEY_SunF37 },
+ { "SunSys_Req", XKB_KEY_SunSys_Req },
+ { "SunProps", XKB_KEY_SunProps },
+ { "SunFront", XKB_KEY_SunFront },
+ { "SunCopy", XKB_KEY_SunCopy },
+ { "SunOpen", XKB_KEY_SunOpen },
+ { "SunPaste", XKB_KEY_SunPaste },
+ { "SunCut", XKB_KEY_SunCut },
+ { "SunPowerSwitch", XKB_KEY_SunPowerSwitch },
+ { "SunAudioLowerVolume", XKB_KEY_SunAudioLowerVolume },
+ { "SunAudioMute", XKB_KEY_SunAudioMute },
+ { "SunAudioRaiseVolume", XKB_KEY_SunAudioRaiseVolume },
+ { "SunVideoDegauss", XKB_KEY_SunVideoDegauss },
+ { "SunVideoLowerBrightness", XKB_KEY_SunVideoLowerBrightness },
+ { "SunVideoRaiseBrightness", XKB_KEY_SunVideoRaiseBrightness },
+ { "SunPowerSwitchShift", XKB_KEY_SunPowerSwitchShift },
+ { "XF86Switch_VT_1", XKB_KEY_XF86Switch_VT_1 },
+ { "XF86Switch_VT_2", XKB_KEY_XF86Switch_VT_2 },
+ { "XF86Switch_VT_3", XKB_KEY_XF86Switch_VT_3 },
+ { "XF86Switch_VT_4", XKB_KEY_XF86Switch_VT_4 },
+ { "XF86Switch_VT_5", XKB_KEY_XF86Switch_VT_5 },
+ { "XF86Switch_VT_6", XKB_KEY_XF86Switch_VT_6 },
+ { "XF86Switch_VT_7", XKB_KEY_XF86Switch_VT_7 },
+ { "XF86Switch_VT_8", XKB_KEY_XF86Switch_VT_8 },
+ { "XF86Switch_VT_9", XKB_KEY_XF86Switch_VT_9 },
+ { "XF86Switch_VT_10", XKB_KEY_XF86Switch_VT_10 },
+ { "XF86Switch_VT_11", XKB_KEY_XF86Switch_VT_11 },
+ { "XF86Switch_VT_12", XKB_KEY_XF86Switch_VT_12 },
+ { "XF86Ungrab", XKB_KEY_XF86Ungrab },
+ { "XF86ClearGrab", XKB_KEY_XF86ClearGrab },
+ { "XF86Next_VMode", XKB_KEY_XF86Next_VMode },
+ { "XF86Prev_VMode", XKB_KEY_XF86Prev_VMode },
+ { "XF86LogWindowTree", XKB_KEY_XF86LogWindowTree },
+ { "XF86LogGrabInfo", XKB_KEY_XF86LogGrabInfo },
+ { "XF86ModeLock", XKB_KEY_XF86ModeLock },
+ { "XF86MonBrightnessUp", XKB_KEY_XF86MonBrightnessUp },
+ { "XF86MonBrightnessDown", XKB_KEY_XF86MonBrightnessDown },
+ { "XF86KbdLightOnOff", XKB_KEY_XF86KbdLightOnOff },
+ { "XF86KbdBrightnessUp", XKB_KEY_XF86KbdBrightnessUp },
+ { "XF86KbdBrightnessDown", XKB_KEY_XF86KbdBrightnessDown },
+ { "XF86Standby", XKB_KEY_XF86Standby },
+ { "XF86AudioLowerVolume", XKB_KEY_XF86AudioLowerVolume },
+ { "XF86AudioMute", XKB_KEY_XF86AudioMute },
+ { "XF86AudioRaiseVolume", XKB_KEY_XF86AudioRaiseVolume },
+ { "XF86AudioPlay", XKB_KEY_XF86AudioPlay },
+ { "XF86AudioStop", XKB_KEY_XF86AudioStop },
+ { "XF86AudioPrev", XKB_KEY_XF86AudioPrev },
+ { "XF86AudioNext", XKB_KEY_XF86AudioNext },
+ { "XF86HomePage", XKB_KEY_XF86HomePage },
+ { "XF86Mail", XKB_KEY_XF86Mail },
+ { "XF86Start", XKB_KEY_XF86Start },
+ { "XF86Search", XKB_KEY_XF86Search },
+ { "XF86AudioRecord", XKB_KEY_XF86AudioRecord },
+ { "XF86Calculator", XKB_KEY_XF86Calculator },
+ { "XF86Memo", XKB_KEY_XF86Memo },
+ { "XF86ToDoList", XKB_KEY_XF86ToDoList },
+ { "XF86Calendar", XKB_KEY_XF86Calendar },
+ { "XF86PowerDown", XKB_KEY_XF86PowerDown },
+ { "XF86ContrastAdjust", XKB_KEY_XF86ContrastAdjust },
+ { "XF86RockerUp", XKB_KEY_XF86RockerUp },
+ { "XF86RockerDown", XKB_KEY_XF86RockerDown },
+ { "XF86RockerEnter", XKB_KEY_XF86RockerEnter },
+ { "XF86Back", XKB_KEY_XF86Back },
+ { "XF86Forward", XKB_KEY_XF86Forward },
+ { "XF86Stop", XKB_KEY_XF86Stop },
+ { "XF86Refresh", XKB_KEY_XF86Refresh },
+ { "XF86PowerOff", XKB_KEY_XF86PowerOff },
+ { "XF86WakeUp", XKB_KEY_XF86WakeUp },
+ { "XF86Eject", XKB_KEY_XF86Eject },
+ { "XF86ScreenSaver", XKB_KEY_XF86ScreenSaver },
+ { "XF86WWW", XKB_KEY_XF86WWW },
+ { "XF86Sleep", XKB_KEY_XF86Sleep },
+ { "XF86Favorites", XKB_KEY_XF86Favorites },
+ { "XF86AudioPause", XKB_KEY_XF86AudioPause },
+ { "XF86AudioMedia", XKB_KEY_XF86AudioMedia },
+ { "XF86MyComputer", XKB_KEY_XF86MyComputer },
+ { "XF86VendorHome", XKB_KEY_XF86VendorHome },
+ { "XF86LightBulb", XKB_KEY_XF86LightBulb },
+ { "XF86Shop", XKB_KEY_XF86Shop },
+ { "XF86History", XKB_KEY_XF86History },
+ { "XF86OpenURL", XKB_KEY_XF86OpenURL },
+ { "XF86AddFavorite", XKB_KEY_XF86AddFavorite },
+ { "XF86HotLinks", XKB_KEY_XF86HotLinks },
+ { "XF86BrightnessAdjust", XKB_KEY_XF86BrightnessAdjust },
+ { "XF86Finance", XKB_KEY_XF86Finance },
+ { "XF86Community", XKB_KEY_XF86Community },
+ { "XF86AudioRewind", XKB_KEY_XF86AudioRewind },
+ { "XF86BackForward", XKB_KEY_XF86BackForward },
+ { "XF86Launch0", XKB_KEY_XF86Launch0 },
+ { "XF86Launch1", XKB_KEY_XF86Launch1 },
+ { "XF86Launch2", XKB_KEY_XF86Launch2 },
+ { "XF86Launch3", XKB_KEY_XF86Launch3 },
+ { "XF86Launch4", XKB_KEY_XF86Launch4 },
+ { "XF86Launch5", XKB_KEY_XF86Launch5 },
+ { "XF86Launch6", XKB_KEY_XF86Launch6 },
+ { "XF86Launch7", XKB_KEY_XF86Launch7 },
+ { "XF86Launch8", XKB_KEY_XF86Launch8 },
+ { "XF86Launch9", XKB_KEY_XF86Launch9 },
+ { "XF86LaunchA", XKB_KEY_XF86LaunchA },
+ { "XF86LaunchB", XKB_KEY_XF86LaunchB },
+ { "XF86LaunchC", XKB_KEY_XF86LaunchC },
+ { "XF86LaunchD", XKB_KEY_XF86LaunchD },
+ { "XF86LaunchE", XKB_KEY_XF86LaunchE },
+ { "XF86LaunchF", XKB_KEY_XF86LaunchF },
+ { "XF86ApplicationLeft", XKB_KEY_XF86ApplicationLeft },
+ { "XF86ApplicationRight", XKB_KEY_XF86ApplicationRight },
+ { "XF86Book", XKB_KEY_XF86Book },
+ { "XF86CD", XKB_KEY_XF86CD },
+ { "XF86Calculater", XKB_KEY_XF86Calculater },
+ { "XF86Clear", XKB_KEY_XF86Clear },
+ { "XF86Close", XKB_KEY_XF86Close },
+ { "XF86Copy", XKB_KEY_XF86Copy },
+ { "XF86Cut", XKB_KEY_XF86Cut },
+ { "XF86Display", XKB_KEY_XF86Display },
+ { "XF86DOS", XKB_KEY_XF86DOS },
+ { "XF86Documents", XKB_KEY_XF86Documents },
+ { "XF86Excel", XKB_KEY_XF86Excel },
+ { "XF86Explorer", XKB_KEY_XF86Explorer },
+ { "XF86Game", XKB_KEY_XF86Game },
+ { "XF86Go", XKB_KEY_XF86Go },
+ { "XF86iTouch", XKB_KEY_XF86iTouch },
+ { "XF86LogOff", XKB_KEY_XF86LogOff },
+ { "XF86Market", XKB_KEY_XF86Market },
+ { "XF86Meeting", XKB_KEY_XF86Meeting },
+ { "XF86MenuKB", XKB_KEY_XF86MenuKB },
+ { "XF86MenuPB", XKB_KEY_XF86MenuPB },
+ { "XF86MySites", XKB_KEY_XF86MySites },
+ { "XF86New", XKB_KEY_XF86New },
+ { "XF86News", XKB_KEY_XF86News },
+ { "XF86OfficeHome", XKB_KEY_XF86OfficeHome },
+ { "XF86Open", XKB_KEY_XF86Open },
+ { "XF86Option", XKB_KEY_XF86Option },
+ { "XF86Paste", XKB_KEY_XF86Paste },
+ { "XF86Phone", XKB_KEY_XF86Phone },
+ { "XF86Q", XKB_KEY_XF86Q },
+ { "XF86Reply", XKB_KEY_XF86Reply },
+ { "XF86Reload", XKB_KEY_XF86Reload },
+ { "XF86RotateWindows", XKB_KEY_XF86RotateWindows },
+ { "XF86RotationPB", XKB_KEY_XF86RotationPB },
+ { "XF86RotationKB", XKB_KEY_XF86RotationKB },
+ { "XF86Save", XKB_KEY_XF86Save },
+ { "XF86ScrollUp", XKB_KEY_XF86ScrollUp },
+ { "XF86ScrollDown", XKB_KEY_XF86ScrollDown },
+ { "XF86ScrollClick", XKB_KEY_XF86ScrollClick },
+ { "XF86Send", XKB_KEY_XF86Send },
+ { "XF86Spell", XKB_KEY_XF86Spell },
+ { "XF86SplitScreen", XKB_KEY_XF86SplitScreen },
+ { "XF86Support", XKB_KEY_XF86Support },
+ { "XF86TaskPane", XKB_KEY_XF86TaskPane },
+ { "XF86Terminal", XKB_KEY_XF86Terminal },
+ { "XF86Tools", XKB_KEY_XF86Tools },
+ { "XF86Travel", XKB_KEY_XF86Travel },
+ { "XF86UserPB", XKB_KEY_XF86UserPB },
+ { "XF86User1KB", XKB_KEY_XF86User1KB },
+ { "XF86User2KB", XKB_KEY_XF86User2KB },
+ { "XF86Video", XKB_KEY_XF86Video },
+ { "XF86WheelButton", XKB_KEY_XF86WheelButton },
+ { "XF86Word", XKB_KEY_XF86Word },
+ { "XF86Xfer", XKB_KEY_XF86Xfer },
+ { "XF86ZoomIn", XKB_KEY_XF86ZoomIn },
+ { "XF86ZoomOut", XKB_KEY_XF86ZoomOut },
+ { "XF86Away", XKB_KEY_XF86Away },
+ { "XF86Messenger", XKB_KEY_XF86Messenger },
+ { "XF86WebCam", XKB_KEY_XF86WebCam },
+ { "XF86MailForward", XKB_KEY_XF86MailForward },
+ { "XF86Pictures", XKB_KEY_XF86Pictures },
+ { "XF86Music", XKB_KEY_XF86Music },
+ { "XF86Battery", XKB_KEY_XF86Battery },
+ { "XF86Bluetooth", XKB_KEY_XF86Bluetooth },
+ { "XF86WLAN", XKB_KEY_XF86WLAN },
+ { "XF86UWB", XKB_KEY_XF86UWB },
+ { "XF86AudioForward", XKB_KEY_XF86AudioForward },
+ { "XF86AudioRepeat", XKB_KEY_XF86AudioRepeat },
+ { "XF86AudioRandomPlay", XKB_KEY_XF86AudioRandomPlay },
+ { "XF86Subtitle", XKB_KEY_XF86Subtitle },
+ { "XF86AudioCycleTrack", XKB_KEY_XF86AudioCycleTrack },
+ { "XF86CycleAngle", XKB_KEY_XF86CycleAngle },
+ { "XF86FrameBack", XKB_KEY_XF86FrameBack },
+ { "XF86FrameForward", XKB_KEY_XF86FrameForward },
+ { "XF86Time", XKB_KEY_XF86Time },
+ { "XF86Select", XKB_KEY_XF86Select },
+ { "XF86View", XKB_KEY_XF86View },
+ { "XF86TopMenu", XKB_KEY_XF86TopMenu },
+ { "XF86Red", XKB_KEY_XF86Red },
+ { "XF86Green", XKB_KEY_XF86Green },
+ { "XF86Yellow", XKB_KEY_XF86Yellow },
+ { "XF86Blue", XKB_KEY_XF86Blue },
+ { "XF86Suspend", XKB_KEY_XF86Suspend },
+ { "XF86Hibernate", XKB_KEY_XF86Hibernate },
+ { "XF86TouchpadToggle", XKB_KEY_XF86TouchpadToggle },
+ { "XF86TouchpadOn", XKB_KEY_XF86TouchpadOn },
+ { "XF86TouchpadOff", XKB_KEY_XF86TouchpadOff },
+};
diff --git a/src/3rdparty/xkbcommon/src/state.c b/src/3rdparty/xkbcommon/src/state.c
new file mode 100644
index 0000000000..ac4576f5b8
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/state.c
@@ -0,0 +1,1144 @@
+/************************************************************
+ * Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+/*
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ */
+
+/*
+ * This is a bastardised version of xkbActions.c from the X server which
+ * does not support, for the moment:
+ * - AccessX sticky/debounce/etc (will come later)
+ * - pointer keys (may come later)
+ * - key redirects (unlikely)
+ * - messages (very unlikely)
+ */
+
+#include "keymap.h"
+
+struct xkb_filter {
+ union xkb_action action;
+ const struct xkb_key *key;
+ uint32_t priv;
+ bool (*func)(struct xkb_state *state,
+ struct xkb_filter *filter,
+ const struct xkb_key *key,
+ enum xkb_key_direction direction);
+ int refcnt;
+};
+
+struct state_components {
+ /* These may be negative, because of -1 group actions. */
+ int32_t base_group; /**< depressed */
+ int32_t latched_group;
+ int32_t locked_group;
+ xkb_layout_index_t group; /**< effective */
+
+ xkb_mod_mask_t base_mods; /**< depressed */
+ xkb_mod_mask_t latched_mods;
+ xkb_mod_mask_t locked_mods;
+ xkb_mod_mask_t mods; /**< effective */
+
+ xkb_led_mask_t leds;
+};
+
+struct xkb_state {
+ /*
+ * Before updating the state, we keep a copy of just this struct. This
+ * allows us to report which components of the state have changed.
+ */
+ struct state_components components;
+
+ /*
+ * At each event, we accumulate all the needed modifications to the base
+ * modifiers, and apply them at the end. These keep track of this state.
+ */
+ xkb_mod_mask_t set_mods;
+ xkb_mod_mask_t clear_mods;
+
+ /*
+ * We mustn't clear a base modifier if there's another depressed key
+ * which affects it, e.g. given this sequence
+ * < Left Shift down, Right Shift down, Left Shift Up >
+ * the modifier should still be set. This keeps the count.
+ */
+ int16_t mod_key_count[sizeof(xkb_mod_mask_t) * 8];
+
+ int refcnt;
+ darray(struct xkb_filter) filters;
+ struct xkb_keymap *keymap;
+};
+
+static const struct xkb_key_type_entry *
+get_entry_for_key_state(struct xkb_state *state, const struct xkb_key *key,
+ xkb_layout_index_t group)
+{
+ const struct xkb_key_type *type = key->groups[group].type;
+ xkb_mod_mask_t active_mods = state->components.mods & type->mods.mask;
+ unsigned int i;
+
+ for (i = 0; i < type->num_entries; i++) {
+ /*
+ * If the virtual modifiers are not bound to anything, we're
+ * supposed to skip the entry (xserver does this with cached
+ * entry->active field).
+ */
+ if (!type->entries[i].mods.mask)
+ continue;
+
+ if (type->entries[i].mods.mask == active_mods)
+ return &type->entries[i];
+ }
+
+ return NULL;
+}
+
+/**
+ * Returns the level to use for the given key and state, or
+ * XKB_LEVEL_INVALID.
+ */
+XKB_EXPORT xkb_level_index_t
+xkb_state_key_get_level(struct xkb_state *state, xkb_keycode_t kc,
+ xkb_layout_index_t layout)
+{
+ const struct xkb_key *key = XkbKey(state->keymap, kc);
+ const struct xkb_key_type_entry *entry;
+
+ if (!key || layout >= key->num_groups)
+ return XKB_LEVEL_INVALID;
+
+ /* If we don't find an explicit match the default is 0. */
+ entry = get_entry_for_key_state(state, key, layout);
+ if (!entry)
+ return 0;
+
+ return entry->level;
+}
+
+xkb_layout_index_t
+wrap_group_into_range(int32_t group,
+ xkb_layout_index_t num_groups,
+ enum xkb_range_exceed_type out_of_range_group_action,
+ xkb_layout_index_t out_of_range_group_number)
+{
+ if (num_groups == 0)
+ return XKB_LAYOUT_INVALID;
+
+ if (group < num_groups)
+ return group;
+
+ switch (out_of_range_group_action) {
+ case RANGE_REDIRECT:
+ if (out_of_range_group_number >= num_groups)
+ return 0;
+ return out_of_range_group_number;
+
+ case RANGE_SATURATE:
+ if (group < 0)
+ return 0;
+ else
+ return num_groups - 1;
+
+ case RANGE_WRAP:
+ default:
+ /*
+ * C99 says a negative dividend in a modulo operation always
+ * gives a negative result.
+ */
+ if (group < 0)
+ return ((int) num_groups + (group % (int) num_groups));
+ else
+ return group % num_groups;
+ }
+}
+
+/**
+ * Returns the layout to use for the given key and state, taking
+ * wrapping/clamping/etc into account, or XKB_LAYOUT_INVALID.
+ */
+XKB_EXPORT xkb_layout_index_t
+xkb_state_key_get_layout(struct xkb_state *state, xkb_keycode_t kc)
+{
+ const struct xkb_key *key = XkbKey(state->keymap, kc);
+
+ if (!key)
+ return XKB_LAYOUT_INVALID;
+
+ return wrap_group_into_range(state->components.group, key->num_groups,
+ key->out_of_range_group_action,
+ key->out_of_range_group_number);
+}
+
+static const union xkb_action fake = { .type = ACTION_TYPE_NONE };
+
+static const union xkb_action *
+xkb_key_get_action(struct xkb_state *state, const struct xkb_key *key)
+{
+ xkb_layout_index_t layout;
+ xkb_level_index_t level;
+
+ layout = xkb_state_key_get_layout(state, key->keycode);
+ if (layout == XKB_LAYOUT_INVALID)
+ return &fake;
+
+ level = xkb_state_key_get_level(state, key->keycode, layout);
+ if (level == XKB_LEVEL_INVALID)
+ return &fake;
+
+ return &key->groups[layout].levels[level].action;
+}
+
+static struct xkb_filter *
+xkb_filter_new(struct xkb_state *state)
+{
+ struct xkb_filter *filter = NULL, *iter;
+
+ darray_foreach(iter, state->filters) {
+ if (iter->func)
+ continue;
+ filter = iter;
+ break;
+ }
+
+ if (!filter) {
+ darray_resize0(state->filters, darray_size(state->filters) + 1);
+ filter = &darray_item(state->filters, darray_size(state->filters) -1);
+ }
+
+ filter->refcnt = 1;
+ return filter;
+}
+
+/***====================================================================***/
+
+static bool
+xkb_filter_group_set_func(struct xkb_state *state,
+ struct xkb_filter *filter,
+ const struct xkb_key *key,
+ enum xkb_key_direction direction)
+{
+ if (key != filter->key) {
+ filter->action.group.flags &= ~ACTION_LOCK_CLEAR;
+ return true;
+ }
+
+ if (direction == XKB_KEY_DOWN) {
+ filter->refcnt++;
+ return false;
+ }
+ else if (--filter->refcnt > 0) {
+ return false;
+ }
+
+ state->components.base_group = filter->priv;
+
+ if (filter->action.group.flags & ACTION_LOCK_CLEAR)
+ state->components.locked_group = 0;
+
+ filter->func = NULL;
+ return true;
+}
+
+static void
+xkb_filter_group_set_new(struct xkb_state *state, struct xkb_filter *filter)
+{
+ filter->priv = state->components.base_group;
+ if (filter->action.group.flags & ACTION_ABSOLUTE_SWITCH)
+ state->components.base_group = filter->action.group.group;
+ else
+ state->components.base_group += filter->action.group.group;
+}
+
+static bool
+xkb_filter_group_lock_func(struct xkb_state *state,
+ struct xkb_filter *filter,
+ const struct xkb_key *key,
+ enum xkb_key_direction direction)
+{
+ if (key != filter->key)
+ return true;
+
+ if (direction == XKB_KEY_DOWN) {
+ filter->refcnt++;
+ return false;
+ }
+ if (--filter->refcnt > 0)
+ return false;
+
+ filter->func = NULL;
+ return true;
+}
+
+static void
+xkb_filter_group_lock_new(struct xkb_state *state, struct xkb_filter *filter)
+{
+ if (filter->action.group.flags & ACTION_ABSOLUTE_SWITCH)
+ state->components.locked_group = filter->action.group.group;
+ else
+ state->components.locked_group += filter->action.group.group;
+}
+
+static bool
+xkb_filter_mod_set_func(struct xkb_state *state,
+ struct xkb_filter *filter,
+ const struct xkb_key *key,
+ enum xkb_key_direction direction)
+{
+ if (key != filter->key) {
+ filter->action.mods.flags &= ~ACTION_LOCK_CLEAR;
+ return true;
+ }
+
+ if (direction == XKB_KEY_DOWN) {
+ filter->refcnt++;
+ return false;
+ }
+ else if (--filter->refcnt > 0) {
+ return false;
+ }
+
+ state->clear_mods = filter->action.mods.mods.mask;
+ if (filter->action.mods.flags & ACTION_LOCK_CLEAR)
+ state->components.locked_mods &= ~filter->action.mods.mods.mask;
+
+ filter->func = NULL;
+ return true;
+}
+
+static void
+xkb_filter_mod_set_new(struct xkb_state *state, struct xkb_filter *filter)
+{
+ state->set_mods = filter->action.mods.mods.mask;
+}
+
+static bool
+xkb_filter_mod_lock_func(struct xkb_state *state,
+ struct xkb_filter *filter,
+ const struct xkb_key *key,
+ enum xkb_key_direction direction)
+{
+ if (key != filter->key)
+ return true;
+
+ if (direction == XKB_KEY_DOWN) {
+ filter->refcnt++;
+ return false;
+ }
+ if (--filter->refcnt > 0)
+ return false;
+
+ state->clear_mods |= filter->action.mods.mods.mask;
+ if (!(filter->action.mods.flags & ACTION_LOCK_NO_UNLOCK))
+ state->components.locked_mods &= ~filter->priv;
+
+ filter->func = NULL;
+ return true;
+}
+
+static void
+xkb_filter_mod_lock_new(struct xkb_state *state, struct xkb_filter *filter)
+{
+ filter->priv = (state->components.locked_mods &
+ filter->action.mods.mods.mask);
+ state->set_mods |= filter->action.mods.mods.mask;
+ if (!(filter->action.mods.flags & ACTION_LOCK_NO_LOCK))
+ state->components.locked_mods |= filter->action.mods.mods.mask;
+}
+
+enum xkb_key_latch_state {
+ NO_LATCH,
+ LATCH_KEY_DOWN,
+ LATCH_PENDING,
+};
+
+static bool
+xkb_action_breaks_latch(const union xkb_action *action)
+{
+ switch (action->type) {
+ case ACTION_TYPE_NONE:
+ case ACTION_TYPE_PTR_BUTTON:
+ case ACTION_TYPE_PTR_LOCK:
+ case ACTION_TYPE_CTRL_SET:
+ case ACTION_TYPE_CTRL_LOCK:
+ case ACTION_TYPE_KEY_REDIRECT:
+ case ACTION_TYPE_SWITCH_VT:
+ case ACTION_TYPE_TERMINATE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool
+xkb_filter_mod_latch_func(struct xkb_state *state,
+ struct xkb_filter *filter,
+ const struct xkb_key *key,
+ enum xkb_key_direction direction)
+{
+ enum xkb_key_latch_state latch = filter->priv;
+
+ if (direction == XKB_KEY_DOWN && latch == LATCH_PENDING) {
+ /* If this is a new keypress and we're awaiting our single latched
+ * keypress, then either break the latch if any random key is pressed,
+ * or promote it to a lock or plain base set if it's the same
+ * modifier. */
+ const union xkb_action *action = xkb_key_get_action(state, key);
+ if (action->type == ACTION_TYPE_MOD_LATCH &&
+ action->mods.flags == filter->action.mods.flags &&
+ action->mods.mods.mask == filter->action.mods.mods.mask) {
+ filter->action = *action;
+ if (filter->action.mods.flags & ACTION_LATCH_TO_LOCK) {
+ filter->action.type = ACTION_TYPE_MOD_LOCK;
+ filter->func = xkb_filter_mod_lock_func;
+ state->components.locked_mods |= filter->action.mods.mods.mask;
+ }
+ else {
+ filter->action.type = ACTION_TYPE_MOD_SET;
+ filter->func = xkb_filter_mod_set_func;
+ state->set_mods = filter->action.mods.mods.mask;
+ }
+ filter->key = key;
+ state->components.latched_mods &= ~filter->action.mods.mods.mask;
+ /* XXX beep beep! */
+ return false;
+ }
+ else if (xkb_action_breaks_latch(action)) {
+ /* XXX: This may be totally broken, we might need to break the
+ * latch in the next run after this press? */
+ state->components.latched_mods &= ~filter->action.mods.mods.mask;
+ filter->func = NULL;
+ return true;
+ }
+ }
+ else if (direction == XKB_KEY_UP && key == filter->key) {
+ /* Our key got released. If we've set it to clear locks, and we
+ * currently have the same modifiers locked, then release them and
+ * don't actually latch. Else we've actually hit the latching
+ * stage, so set PENDING and move our modifier from base to
+ * latched. */
+ if (latch == NO_LATCH ||
+ ((filter->action.mods.flags & ACTION_LOCK_CLEAR) &&
+ (state->components.locked_mods & filter->action.mods.mods.mask) ==
+ filter->action.mods.mods.mask)) {
+ /* XXX: We might be a bit overenthusiastic about clearing
+ * mods other filters have set here? */
+ if (latch == LATCH_PENDING)
+ state->components.latched_mods &=
+ ~filter->action.mods.mods.mask;
+ else
+ state->clear_mods = filter->action.mods.mods.mask;
+ state->components.locked_mods &= ~filter->action.mods.mods.mask;
+ filter->func = NULL;
+ }
+ else {
+ latch = LATCH_PENDING;
+ state->clear_mods = filter->action.mods.mods.mask;
+ state->components.latched_mods |= filter->action.mods.mods.mask;
+ /* XXX beep beep! */
+ }
+ }
+ else if (direction == XKB_KEY_DOWN && latch == LATCH_KEY_DOWN) {
+ /* Someone's pressed another key while we've still got the latching
+ * key held down, so keep the base modifier state active (from
+ * xkb_filter_mod_latch_new), but don't trip the latch, just clear
+ * it as soon as the modifier gets released. */
+ latch = NO_LATCH;
+ }
+
+ filter->priv = latch;
+
+ return true;
+}
+
+static void
+xkb_filter_mod_latch_new(struct xkb_state *state, struct xkb_filter *filter)
+{
+ filter->priv = LATCH_KEY_DOWN;
+ state->set_mods = filter->action.mods.mods.mask;
+}
+
+static const struct {
+ void (*new)(struct xkb_state *state, struct xkb_filter *filter);
+ bool (*func)(struct xkb_state *state, struct xkb_filter *filter,
+ const struct xkb_key *key, enum xkb_key_direction direction);
+} filter_action_funcs[_ACTION_TYPE_NUM_ENTRIES] = {
+ [ACTION_TYPE_MOD_SET] = { xkb_filter_mod_set_new,
+ xkb_filter_mod_set_func },
+ [ACTION_TYPE_MOD_LATCH] = { xkb_filter_mod_latch_new,
+ xkb_filter_mod_latch_func },
+ [ACTION_TYPE_MOD_LOCK] = { xkb_filter_mod_lock_new,
+ xkb_filter_mod_lock_func },
+ [ACTION_TYPE_GROUP_SET] = { xkb_filter_group_set_new,
+ xkb_filter_group_set_func },
+ [ACTION_TYPE_GROUP_LOCK] = { xkb_filter_group_lock_new,
+ xkb_filter_group_lock_func },
+};
+
+/**
+ * Applies any relevant filters to the key, first from the list of filters
+ * that are currently active, then if no filter has claimed the key, possibly
+ * apply a new filter from the key action.
+ */
+static void
+xkb_filter_apply_all(struct xkb_state *state,
+ const struct xkb_key *key,
+ enum xkb_key_direction direction)
+{
+ struct xkb_filter *filter;
+ const union xkb_action *action;
+ bool send = true;
+
+ /* First run through all the currently active filters and see if any of
+ * them have claimed this event. */
+ darray_foreach(filter, state->filters) {
+ if (!filter->func)
+ continue;
+ send = filter->func(state, filter, key, direction) && send;
+ }
+
+ if (!send || direction == XKB_KEY_UP)
+ return;
+
+ action = xkb_key_get_action(state, key);
+
+ /*
+ * It's possible for the keymap to set action->type explicitly, like so:
+ * interpret XF86_Next_VMode {
+ * action = Private(type=0x86, data="+VMode");
+ * };
+ * We don't handle those.
+ */
+ if (action->type >= _ACTION_TYPE_NUM_ENTRIES)
+ return;
+
+ if (!filter_action_funcs[action->type].new)
+ return;
+
+ filter = xkb_filter_new(state);
+ if (!filter)
+ return; /* WSGO */
+
+ filter->key = key;
+ filter->func = filter_action_funcs[action->type].func;
+ filter->action = *action;
+ filter_action_funcs[action->type].new(state, filter);
+}
+
+XKB_EXPORT struct xkb_state *
+xkb_state_new(struct xkb_keymap *keymap)
+{
+ struct xkb_state *ret;
+
+ ret = calloc(sizeof(*ret), 1);
+ if (!ret)
+ return NULL;
+
+ ret->refcnt = 1;
+ ret->keymap = xkb_keymap_ref(keymap);
+
+ return ret;
+}
+
+XKB_EXPORT struct xkb_state *
+xkb_state_ref(struct xkb_state *state)
+{
+ state->refcnt++;
+ return state;
+}
+
+XKB_EXPORT void
+xkb_state_unref(struct xkb_state *state)
+{
+ if (!state || --state->refcnt > 0)
+ return;
+
+ xkb_keymap_unref(state->keymap);
+ darray_free(state->filters);
+ free(state);
+}
+
+XKB_EXPORT struct xkb_keymap *
+xkb_state_get_keymap(struct xkb_state *state)
+{
+ return state->keymap;
+}
+
+/**
+ * Update the LED state to match the rest of the xkb_state.
+ */
+static void
+xkb_state_led_update_all(struct xkb_state *state)
+{
+ xkb_led_index_t idx;
+ const struct xkb_led *led;
+
+ state->components.leds = 0;
+
+ darray_enumerate(idx, led, state->keymap->leds) {
+ xkb_mod_mask_t mod_mask = 0;
+ xkb_layout_mask_t group_mask = 0;
+
+ if (led->which_mods & XKB_STATE_MODS_EFFECTIVE)
+ mod_mask |= state->components.mods;
+ if (led->which_mods & XKB_STATE_MODS_DEPRESSED)
+ mod_mask |= state->components.base_mods;
+ if (led->which_mods & XKB_STATE_MODS_LATCHED)
+ mod_mask |= state->components.latched_mods;
+ if (led->which_mods & XKB_STATE_MODS_LOCKED)
+ mod_mask |= state->components.locked_mods;
+ if (led->mods.mask & mod_mask)
+ state->components.leds |= (1 << idx);
+
+ if (led->which_groups & XKB_STATE_LAYOUT_EFFECTIVE)
+ group_mask |= (1 << state->components.group);
+ if (led->which_groups & XKB_STATE_LAYOUT_DEPRESSED)
+ group_mask |= (1 << state->components.base_group);
+ if (led->which_groups & XKB_STATE_LAYOUT_LATCHED)
+ group_mask |= (1 << state->components.latched_group);
+ if (led->which_groups & XKB_STATE_LAYOUT_LOCKED)
+ group_mask |= (1 << state->components.locked_group);
+ if (led->groups & group_mask)
+ state->components.leds |= (1 << idx);
+
+ if (led->ctrls & state->keymap->enabled_ctrls)
+ state->components.leds |= (1 << idx);
+ }
+}
+
+/**
+ * Calculates the derived state (effective mods/group and LEDs) from an
+ * up-to-date xkb_state.
+ */
+static void
+xkb_state_update_derived(struct xkb_state *state)
+{
+ state->components.mods = (state->components.base_mods |
+ state->components.latched_mods |
+ state->components.locked_mods);
+
+ /* TODO: Use groups_wrap control instead of always RANGE_WRAP. */
+
+ state->components.locked_group =
+ wrap_group_into_range(state->components.locked_group,
+ state->keymap->num_groups,
+ RANGE_WRAP, 0);
+
+ state->components.group =
+ wrap_group_into_range(state->components.base_group +
+ state->components.latched_group +
+ state->components.locked_group,
+ state->keymap->num_groups,
+ RANGE_WRAP, 0);
+
+ xkb_state_led_update_all(state);
+}
+
+static enum xkb_state_component
+get_state_component_changes(const struct state_components *a,
+ const struct state_components *b)
+{
+ xkb_mod_mask_t mask = 0;
+
+ if (a->group != b->group)
+ mask |= XKB_STATE_LAYOUT_EFFECTIVE;
+ if (a->base_group != b->base_group)
+ mask |= XKB_STATE_LAYOUT_DEPRESSED;
+ if (a->latched_group != b->latched_group)
+ mask |= XKB_STATE_LAYOUT_LATCHED;
+ if (a->locked_group != b->locked_group)
+ mask |= XKB_STATE_LAYOUT_LOCKED;
+ if (a->mods != b->mods)
+ mask |= XKB_STATE_MODS_EFFECTIVE;
+ if (a->base_mods != b->base_mods)
+ mask |= XKB_STATE_MODS_DEPRESSED;
+ if (a->latched_mods != b->latched_mods)
+ mask |= XKB_STATE_MODS_LATCHED;
+ if (a->locked_mods != b->locked_mods)
+ mask |= XKB_STATE_MODS_LOCKED;
+ if (a->leds != b->leds)
+ mask |= XKB_STATE_LEDS;
+
+ return mask;
+}
+
+/**
+ * Given a particular key event, updates the state structure to reflect the
+ * new modifiers.
+ */
+XKB_EXPORT enum xkb_state_component
+xkb_state_update_key(struct xkb_state *state, xkb_keycode_t kc,
+ enum xkb_key_direction direction)
+{
+ xkb_mod_index_t i;
+ xkb_mod_mask_t bit;
+ struct state_components prev_components;
+ const struct xkb_key *key = XkbKey(state->keymap, kc);
+
+ if (!key)
+ return 0;
+
+ prev_components = state->components;
+
+ state->set_mods = 0;
+ state->clear_mods = 0;
+
+ xkb_filter_apply_all(state, key, direction);
+
+ for (i = 0, bit = 1; state->set_mods; i++, bit <<= 1) {
+ if (state->set_mods & bit) {
+ state->mod_key_count[i]++;
+ state->components.base_mods |= bit;
+ state->set_mods &= ~bit;
+ }
+ }
+
+ for (i = 0, bit = 1; state->clear_mods; i++, bit <<= 1) {
+ if (state->clear_mods & bit) {
+ state->mod_key_count[i]--;
+ if (state->mod_key_count[i] <= 0) {
+ state->components.base_mods &= ~bit;
+ state->mod_key_count[i] = 0;
+ }
+ state->clear_mods &= ~bit;
+ }
+ }
+
+ xkb_state_update_derived(state);
+
+ return get_state_component_changes(&prev_components, &state->components);
+}
+
+/**
+ * Updates the state from a set of explicit masks as gained from
+ * xkb_state_serialize_mods and xkb_state_serialize_groups. As noted in the
+ * documentation for these functions in xkbcommon.h, this round-trip is
+ * lossy, and should only be used to update a slave state mirroring the
+ * master, e.g. in a client/server window system.
+ */
+XKB_EXPORT enum xkb_state_component
+xkb_state_update_mask(struct xkb_state *state,
+ xkb_mod_mask_t base_mods,
+ xkb_mod_mask_t latched_mods,
+ xkb_mod_mask_t locked_mods,
+ xkb_layout_index_t base_group,
+ xkb_layout_index_t latched_group,
+ xkb_layout_index_t locked_group)
+{
+ struct state_components prev_components;
+ xkb_mod_index_t num_mods;
+ xkb_mod_index_t idx;
+
+ prev_components = state->components;
+
+ state->components.base_mods = 0;
+ state->components.latched_mods = 0;
+ state->components.locked_mods = 0;
+ num_mods = xkb_keymap_num_mods(state->keymap);
+
+ for (idx = 0; idx < num_mods; idx++) {
+ xkb_mod_mask_t mod = (1 << idx);
+ if (base_mods & mod)
+ state->components.base_mods |= mod;
+ if (latched_mods & mod)
+ state->components.latched_mods |= mod;
+ if (locked_mods & mod)
+ state->components.locked_mods |= mod;
+ }
+
+ state->components.base_group = base_group;
+ state->components.latched_group = latched_group;
+ state->components.locked_group = locked_group;
+
+ xkb_state_update_derived(state);
+
+ return get_state_component_changes(&prev_components, &state->components);
+}
+
+/**
+ * Provides the symbols to use for the given key and state. Returns the
+ * number of symbols pointed to in syms_out.
+ */
+XKB_EXPORT int
+xkb_state_key_get_syms(struct xkb_state *state, xkb_keycode_t kc,
+ const xkb_keysym_t **syms_out)
+{
+ xkb_layout_index_t layout;
+ xkb_level_index_t level;
+
+ layout = xkb_state_key_get_layout(state, kc);
+ if (layout == XKB_LAYOUT_INVALID)
+ goto err;
+
+ level = xkb_state_key_get_level(state, kc, layout);
+ if (level == XKB_LEVEL_INVALID)
+ goto err;
+
+ return xkb_keymap_key_get_syms_by_level(state->keymap, kc, layout, level,
+ syms_out);
+
+err:
+ *syms_out = NULL;
+ return 0;
+}
+
+/**
+ * Provides either exactly one symbol, or XKB_KEY_NoSymbol.
+ */
+XKB_EXPORT xkb_keysym_t
+xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t kc)
+{
+ const xkb_keysym_t *syms;
+ int num_syms;
+
+ num_syms = xkb_state_key_get_syms(state, kc, &syms);
+ if (num_syms != 1)
+ return XKB_KEY_NoSymbol;
+
+ return syms[0];
+}
+
+/**
+ * Serialises the requested modifier state into an xkb_mod_mask_t, with all
+ * the same disclaimers as in xkb_state_update_mask.
+ */
+XKB_EXPORT xkb_mod_mask_t
+xkb_state_serialize_mods(struct xkb_state *state,
+ enum xkb_state_component type)
+{
+ xkb_mod_mask_t ret = 0;
+
+ if (type & XKB_STATE_MODS_EFFECTIVE)
+ return state->components.mods;
+
+ if (type & XKB_STATE_MODS_DEPRESSED)
+ ret |= state->components.base_mods;
+ if (type & XKB_STATE_MODS_LATCHED)
+ ret |= state->components.latched_mods;
+ if (type & XKB_STATE_MODS_LOCKED)
+ ret |= state->components.locked_mods;
+
+ return ret;
+}
+
+/**
+ * Serialises the requested group state, with all the same disclaimers as
+ * in xkb_state_update_mask.
+ */
+XKB_EXPORT xkb_layout_index_t
+xkb_state_serialize_layout(struct xkb_state *state,
+ enum xkb_state_component type)
+{
+ xkb_layout_index_t ret = 0;
+
+ if (type & XKB_STATE_LAYOUT_EFFECTIVE)
+ return state->components.group;
+
+ if (type & XKB_STATE_LAYOUT_DEPRESSED)
+ ret += state->components.base_group;
+ if (type & XKB_STATE_LAYOUT_LATCHED)
+ ret += state->components.latched_group;
+ if (type & XKB_STATE_LAYOUT_LOCKED)
+ ret += state->components.locked_group;
+
+ return ret;
+}
+
+/**
+ * Returns 1 if the given modifier is active with the specified type(s), 0 if
+ * not, or -1 if the modifier is invalid.
+ */
+XKB_EXPORT int
+xkb_state_mod_index_is_active(struct xkb_state *state,
+ xkb_mod_index_t idx,
+ enum xkb_state_component type)
+{
+ if (idx >= xkb_keymap_num_mods(state->keymap))
+ return -1;
+
+ return !!(xkb_state_serialize_mods(state, type) & (1 << idx));
+}
+
+/**
+ * Helper function for xkb_state_mod_indices_are_active and
+ * xkb_state_mod_names_are_active.
+ */
+static int
+match_mod_masks(struct xkb_state *state,
+ enum xkb_state_component type,
+ enum xkb_state_match match,
+ xkb_mod_mask_t wanted)
+{
+ xkb_mod_mask_t active = xkb_state_serialize_mods(state, type);
+
+ if (!(match & XKB_STATE_MATCH_NON_EXCLUSIVE) && (active & ~wanted))
+ return 0;
+
+ if (match & XKB_STATE_MATCH_ANY)
+ return !!(active & wanted);
+ else
+ return (active & wanted) == wanted;
+
+ return 0;
+}
+
+/**
+ * Returns 1 if the modifiers are active with the specified type(s), 0 if
+ * not, or -1 if any of the modifiers are invalid.
+ */
+XKB_EXPORT int
+xkb_state_mod_indices_are_active(struct xkb_state *state,
+ enum xkb_state_component type,
+ enum xkb_state_match match,
+ ...)
+{
+ va_list ap;
+ xkb_mod_index_t idx = 0;
+ xkb_mod_mask_t wanted = 0;
+ int ret = 0;
+ xkb_mod_index_t num_mods = xkb_keymap_num_mods(state->keymap);
+
+ va_start(ap, match);
+ while (1) {
+ idx = va_arg(ap, xkb_mod_index_t);
+ if (idx == XKB_MOD_INVALID)
+ break;
+ if (idx >= num_mods) {
+ ret = -1;
+ break;
+ }
+ wanted |= (1 << idx);
+ }
+ va_end(ap);
+
+ if (ret == -1)
+ return ret;
+
+ return match_mod_masks(state, type, match, wanted);
+}
+
+/**
+ * Returns 1 if the given modifier is active with the specified type(s), 0 if
+ * not, or -1 if the modifier is invalid.
+ */
+XKB_EXPORT int
+xkb_state_mod_name_is_active(struct xkb_state *state, const char *name,
+ enum xkb_state_component type)
+{
+ xkb_mod_index_t idx = xkb_keymap_mod_get_index(state->keymap, name);
+
+ if (idx == XKB_MOD_INVALID)
+ return -1;
+
+ return xkb_state_mod_index_is_active(state, idx, type);
+}
+
+/**
+ * Returns 1 if the modifiers are active with the specified type(s), 0 if
+ * not, or -1 if any of the modifiers are invalid.
+ */
+XKB_EXPORT ATTR_NULL_SENTINEL int
+xkb_state_mod_names_are_active(struct xkb_state *state,
+ enum xkb_state_component type,
+ enum xkb_state_match match,
+ ...)
+{
+ va_list ap;
+ xkb_mod_index_t idx = 0;
+ const char *str;
+ xkb_mod_mask_t wanted = 0;
+ int ret = 0;
+
+ va_start(ap, match);
+ while (1) {
+ str = va_arg(ap, const char *);
+ if (str == NULL)
+ break;
+ idx = xkb_keymap_mod_get_index(state->keymap, str);
+ if (idx == XKB_MOD_INVALID) {
+ ret = -1;
+ break;
+ }
+ wanted |= (1 << idx);
+ }
+ va_end(ap);
+
+ if (ret == -1)
+ return ret;
+
+ return match_mod_masks(state, type, match, wanted);
+}
+
+/**
+ * Returns 1 if the given group is active with the specified type(s), 0 if
+ * not, or -1 if the group is invalid.
+ */
+XKB_EXPORT int
+xkb_state_layout_index_is_active(struct xkb_state *state,
+ xkb_layout_index_t idx,
+ enum xkb_state_component type)
+{
+ int ret = 0;
+
+ if (idx >= state->keymap->num_groups)
+ return -1;
+
+ if (type & XKB_STATE_LAYOUT_EFFECTIVE)
+ ret |= (state->components.group == idx);
+ if (type & XKB_STATE_LAYOUT_DEPRESSED)
+ ret |= (state->components.base_group == idx);
+ if (type & XKB_STATE_LAYOUT_LATCHED)
+ ret |= (state->components.latched_group == idx);
+ if (type & XKB_STATE_LAYOUT_LOCKED)
+ ret |= (state->components.locked_group == idx);
+
+ return ret;
+}
+
+/**
+ * Returns 1 if the given modifier is active with the specified type(s), 0 if
+ * not, or -1 if the modifier is invalid.
+ */
+XKB_EXPORT int
+xkb_state_layout_name_is_active(struct xkb_state *state, const char *name,
+ enum xkb_state_component type)
+{
+ xkb_layout_index_t idx = xkb_keymap_layout_get_index(state->keymap, name);
+
+ if (idx == XKB_LAYOUT_INVALID)
+ return -1;
+
+ return xkb_state_layout_index_is_active(state, idx, type);
+}
+
+/**
+ * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
+ */
+XKB_EXPORT int
+xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx)
+{
+ if (idx >= darray_size(state->keymap->leds) ||
+ darray_item(state->keymap->leds, idx).name == XKB_ATOM_NONE)
+ return -1;
+
+ return !!(state->components.leds & (1 << idx));
+}
+
+/**
+ * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
+ */
+XKB_EXPORT int
+xkb_state_led_name_is_active(struct xkb_state *state, const char *name)
+{
+ xkb_led_index_t idx = xkb_keymap_led_get_index(state->keymap, name);
+
+ if (idx == XKB_LED_INVALID)
+ return -1;
+
+ return xkb_state_led_index_is_active(state, idx);
+}
+
+static xkb_mod_mask_t
+key_get_consumed(struct xkb_state *state, const struct xkb_key *key)
+{
+ const struct xkb_key_type_entry *entry;
+ xkb_layout_index_t group;
+
+ group = xkb_state_key_get_layout(state, key->keycode);
+ if (group == XKB_LAYOUT_INVALID)
+ return 0;
+
+ entry = get_entry_for_key_state(state, key, group);
+ if (!entry)
+ return 0;
+
+ return entry->mods.mask & ~entry->preserve.mask;
+}
+
+/**
+ * Tests to see if a modifier is used up by our translation of a
+ * keycode to keysyms, taking note of the current modifier state and
+ * the appropriate key type's preserve information, if any. This allows
+ * the user to mask out the modifier in later processing of the
+ * modifiers, e.g. when implementing hot keys or accelerators.
+ *
+ * See also, for example:
+ * - XkbTranslateKeyCode(3), mod_rtrn return value, from libX11.
+ * - gdk_keymap_translate_keyboard_state, consumed_modifiers return value,
+ * from gtk+.
+ */
+XKB_EXPORT int
+xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t kc,
+ xkb_mod_index_t idx)
+{
+ const struct xkb_key *key = XkbKey(state->keymap, kc);
+
+ if (!key || idx >= xkb_keymap_num_mods(state->keymap))
+ return -1;
+
+ return !!((1 << idx) & key_get_consumed(state, key));
+}
+
+/**
+ * Calculates which modifiers should be consumed during key processing,
+ * and returns the mask with all these modifiers removed. e.g. if
+ * given a state of Alt and Shift active for a two-level alphabetic
+ * key containing plus and equal on the first and second level
+ * respectively, will return a mask of only Alt, as Shift has been
+ * consumed by the type handling.
+ */
+XKB_EXPORT xkb_mod_mask_t
+xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t kc,
+ xkb_mod_mask_t mask)
+{
+ const struct xkb_key *key = XkbKey(state->keymap, kc);
+
+ if (!key)
+ return 0;
+
+ return mask & ~key_get_consumed(state, key);
+}
diff --git a/src/3rdparty/xkbcommon/src/text.c b/src/3rdparty/xkbcommon/src/text.c
new file mode 100644
index 0000000000..4b8ad0984f
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/text.c
@@ -0,0 +1,357 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#include "keymap.h"
+#include "text.h"
+
+bool
+LookupString(const LookupEntry tab[], const char *string,
+ unsigned int *value_rtrn)
+{
+ if (!string)
+ return false;
+
+ for (const LookupEntry *entry = tab; entry->name; entry++) {
+ if (istreq(entry->name, string)) {
+ *value_rtrn = entry->value;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+const char *
+LookupValue(const LookupEntry tab[], unsigned int value)
+{
+ for (const LookupEntry *entry = tab; entry->name; entry++)
+ if (entry->value == value)
+ return entry->name;
+
+ return NULL;
+}
+
+const LookupEntry ctrlMaskNames[] = {
+ { "RepeatKeys", CONTROL_REPEAT },
+ { "Repeat", CONTROL_REPEAT },
+ { "AutoRepeat", CONTROL_REPEAT },
+ { "SlowKeys", CONTROL_SLOW },
+ { "BounceKeys", CONTROL_DEBOUNCE },
+ { "StickyKeys", CONTROL_STICKY },
+ { "MouseKeys", CONTROL_MOUSEKEYS },
+ { "MouseKeysAccel", CONTROL_MOUSEKEYS_ACCEL },
+ { "AccessXKeys", CONTROL_AX },
+ { "AccessXTimeout", CONTROL_AX_TIMEOUT },
+ { "AccessXFeedback", CONTROL_AX_FEEDBACK },
+ { "AudibleBell", CONTROL_BELL },
+ { "IgnoreGroupLock", CONTROL_IGNORE_GROUP_LOCK },
+ { "all", CONTROL_ALL },
+ { "none", 0 },
+ { "Overlay1", 0 },
+ { "Overlay2", 0 },
+ { NULL, 0 }
+};
+
+const LookupEntry modComponentMaskNames[] = {
+ { "base", XKB_STATE_MODS_DEPRESSED },
+ { "latched", XKB_STATE_MODS_LATCHED },
+ { "locked", XKB_STATE_MODS_LOCKED },
+ { "effective", XKB_STATE_MODS_EFFECTIVE },
+ { "compat", XKB_STATE_MODS_EFFECTIVE },
+ { "any", XKB_STATE_MODS_EFFECTIVE },
+ { "none", 0 },
+ { NULL, 0 }
+};
+
+const LookupEntry groupComponentMaskNames[] = {
+ { "base", XKB_STATE_LAYOUT_DEPRESSED },
+ { "latched", XKB_STATE_LAYOUT_LATCHED },
+ { "locked", XKB_STATE_LAYOUT_LOCKED },
+ { "effective", XKB_STATE_LAYOUT_EFFECTIVE },
+ { "any", XKB_STATE_LAYOUT_EFFECTIVE },
+ { "none", 0 },
+ { NULL, 0 }
+};
+
+const LookupEntry groupMaskNames[] = {
+ { "Group1", 0x01 },
+ { "Group2", 0x02 },
+ { "Group3", 0x04 },
+ { "Group4", 0x08 },
+ { "Group5", 0x10 },
+ { "Group6", 0x20 },
+ { "Group7", 0x40 },
+ { "Group8", 0x80 },
+ { "none", 0x00 },
+ { "all", 0xff },
+ { NULL, 0 }
+};
+
+const LookupEntry groupNames[] = {
+ { "Group1", 1 },
+ { "Group2", 2 },
+ { "Group3", 3 },
+ { "Group4", 4 },
+ { "Group5", 5 },
+ { "Group6", 6 },
+ { "Group7", 7 },
+ { "Group8", 8 },
+ { NULL, 0 }
+};
+
+const LookupEntry levelNames[] = {
+ { "Level1", 1 },
+ { "Level2", 2 },
+ { "Level3", 3 },
+ { "Level4", 4 },
+ { "Level5", 5 },
+ { "Level6", 6 },
+ { "Level7", 7 },
+ { "Level8", 8 },
+ { NULL, 0 }
+};
+
+const LookupEntry buttonNames[] = {
+ { "Button1", 1 },
+ { "Button2", 2 },
+ { "Button3", 3 },
+ { "Button4", 4 },
+ { "Button5", 5 },
+ { "default", 0 },
+ { NULL, 0 }
+};
+
+const LookupEntry useModMapValueNames[] = {
+ { "LevelOne", 1 },
+ { "Level1", 1 },
+ { "AnyLevel", 0 },
+ { "any", 0 },
+ { NULL, 0 }
+};
+
+const LookupEntry actionTypeNames[] = {
+ { "NoAction", ACTION_TYPE_NONE },
+ { "SetMods", ACTION_TYPE_MOD_SET },
+ { "LatchMods", ACTION_TYPE_MOD_LATCH },
+ { "LockMods", ACTION_TYPE_MOD_LOCK },
+ { "SetGroup", ACTION_TYPE_GROUP_SET },
+ { "LatchGroup", ACTION_TYPE_GROUP_LATCH },
+ { "LockGroup", ACTION_TYPE_GROUP_LOCK },
+ { "MovePtr", ACTION_TYPE_PTR_MOVE },
+ { "MovePointer", ACTION_TYPE_PTR_MOVE },
+ { "PtrBtn", ACTION_TYPE_PTR_BUTTON },
+ { "PointerButton", ACTION_TYPE_PTR_BUTTON },
+ { "LockPtrBtn", ACTION_TYPE_PTR_LOCK },
+ { "LockPtrButton", ACTION_TYPE_PTR_LOCK },
+ { "LockPointerButton", ACTION_TYPE_PTR_LOCK },
+ { "LockPointerBtn", ACTION_TYPE_PTR_LOCK },
+ { "SetPtrDflt", ACTION_TYPE_PTR_DEFAULT },
+ { "SetPointerDefault", ACTION_TYPE_PTR_DEFAULT },
+ { "Terminate", ACTION_TYPE_TERMINATE },
+ { "TerminateServer", ACTION_TYPE_TERMINATE },
+ { "SwitchScreen", ACTION_TYPE_SWITCH_VT },
+ { "SetControls", ACTION_TYPE_CTRL_SET },
+ { "LockControls", ACTION_TYPE_CTRL_LOCK },
+ { "RedirectKey", ACTION_TYPE_KEY_REDIRECT },
+ { "Redirect", ACTION_TYPE_KEY_REDIRECT },
+ { "Private", ACTION_TYPE_PRIVATE },
+ /* deprecated actions below here - unused */
+ { "ISOLock", ACTION_TYPE_NONE },
+ { "ActionMessage", ACTION_TYPE_NONE },
+ { "MessageAction", ACTION_TYPE_NONE },
+ { "Message", ACTION_TYPE_NONE },
+ { "DeviceBtn", ACTION_TYPE_NONE },
+ { "DevBtn", ACTION_TYPE_NONE },
+ { "DevButton", ACTION_TYPE_NONE },
+ { "DeviceButton", ACTION_TYPE_NONE },
+ { "LockDeviceBtn", ACTION_TYPE_NONE },
+ { "LockDevBtn", ACTION_TYPE_NONE },
+ { "LockDevButton", ACTION_TYPE_NONE },
+ { "LockDeviceButton", ACTION_TYPE_NONE },
+ { "DeviceValuator", ACTION_TYPE_NONE },
+ { "DevVal", ACTION_TYPE_NONE },
+ { "DeviceVal", ACTION_TYPE_NONE },
+ { "DevValuator", ACTION_TYPE_NONE },
+ { NULL, 0 },
+};
+
+const LookupEntry symInterpretMatchMaskNames[] = {
+ { "NoneOf", MATCH_NONE },
+ { "AnyOfOrNone", MATCH_ANY_OR_NONE },
+ { "AnyOf", MATCH_ANY },
+ { "AllOf", MATCH_ALL },
+ { "Exactly", MATCH_EXACTLY },
+};
+
+const char *
+ModIndexText(const struct xkb_keymap *keymap, xkb_mod_index_t ndx)
+{
+ if (ndx == XKB_MOD_INVALID)
+ return "none";
+
+ if (ndx >= darray_size(keymap->mods))
+ return NULL;
+
+ return xkb_atom_text(keymap->ctx, darray_item(keymap->mods, ndx).name);
+}
+
+xkb_mod_index_t
+ModNameToIndex(const struct xkb_keymap *keymap, xkb_atom_t name,
+ enum mod_type type)
+{
+ xkb_mod_index_t i;
+ const struct xkb_mod *mod;
+
+ darray_enumerate(i, mod, keymap->mods)
+ if ((mod->type & type) && name == mod->name)
+ return i;
+
+ return XKB_MOD_INVALID;
+}
+
+const char *
+ActionTypeText(enum xkb_action_type type)
+{
+ const char *name = LookupValue(actionTypeNames, type);
+ return name ? name : "Private";
+}
+
+const char *
+KeysymText(struct xkb_context *ctx, xkb_keysym_t sym)
+{
+ char *buffer = xkb_context_get_buffer(ctx, 64);
+ xkb_keysym_get_name(sym, buffer, 64);
+ return buffer;
+}
+
+const char *
+KeyNameText(struct xkb_context *ctx, xkb_atom_t name)
+{
+ const char *sname = xkb_atom_text(ctx, name);
+ size_t len = strlen(sname) + 3;
+ char *buf = xkb_context_get_buffer(ctx, len);
+ snprintf(buf, len, "<%s>", sname);
+ return buf;
+}
+
+const char *
+SIMatchText(enum xkb_match_operation type)
+{
+ return LookupValue(symInterpretMatchMaskNames, type);
+}
+
+const char *
+ModMaskText(const struct xkb_keymap *keymap, xkb_mod_mask_t mask)
+{
+ char buf[1024];
+ size_t pos = 0;
+ xkb_mod_index_t i;
+ const struct xkb_mod *mod;
+
+ if (mask == 0)
+ return "none";
+
+ if (mask == MOD_REAL_MASK_ALL)
+ return "all";
+
+ darray_enumerate(i, mod, keymap->mods) {
+ int ret;
+
+ if (!(mask & (1 << i)))
+ continue;
+
+ ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
+ pos == 0 ? "" : "+",
+ xkb_atom_text(keymap->ctx, mod->name));
+ if (ret <= 0 || pos + ret >= sizeof(buf))
+ break;
+ else
+ pos += ret;
+ }
+
+ return strcpy(xkb_context_get_buffer(keymap->ctx, pos + 1), buf);
+}
+
+const char *
+LedStateMaskText(struct xkb_context *ctx, enum xkb_state_component mask)
+{
+ char buf[1024];
+ size_t pos = 0;
+
+ if (mask == 0)
+ return "0";
+
+ for (unsigned i = 0; mask; i++) {
+ int ret;
+
+ if (!(mask & (1 << i)))
+ continue;
+
+ mask &= ~(1 << i);
+
+ ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
+ pos == 0 ? "" : "+",
+ LookupValue(modComponentMaskNames, 1 << i));
+ if (ret <= 0 || pos + ret >= sizeof(buf))
+ break;
+ else
+ pos += ret;
+ }
+
+ return strcpy(xkb_context_get_buffer(ctx, pos + 1), buf);
+}
+
+const char *
+ControlMaskText(struct xkb_context *ctx, enum xkb_action_controls mask)
+{
+ char buf[1024];
+ size_t pos = 0;
+
+ if (mask == 0)
+ return "none";
+
+ if (mask == CONTROL_ALL)
+ return "all";
+
+ for (unsigned i = 0; mask; i++) {
+ int ret;
+
+ if (!(mask & (1 << i)))
+ continue;
+
+ mask &= ~(1 << i);
+
+ ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
+ pos == 0 ? "" : "+",
+ LookupValue(ctrlMaskNames, 1 << i));
+ if (ret <= 0 || pos + ret >= sizeof(buf))
+ break;
+ else
+ pos += ret;
+ }
+
+ return strcpy(xkb_context_get_buffer(ctx, pos + 1), buf);
+}
diff --git a/src/3rdparty/xkbcommon/src/text.h b/src/3rdparty/xkbcommon/src/text.h
new file mode 100644
index 0000000000..29f73abc95
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/text.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2009 Dan Nicholson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef TEXT_H
+#define TEXT_H
+
+typedef struct {
+ const char *name;
+ unsigned int value;
+} LookupEntry;
+
+bool
+LookupString(const LookupEntry tab[], const char *string,
+ unsigned int *value_rtrn);
+
+const char *
+LookupValue(const LookupEntry tab[], unsigned int value);
+
+extern const LookupEntry ctrlMaskNames[];
+extern const LookupEntry modComponentMaskNames[];
+extern const LookupEntry groupComponentMaskNames[];
+extern const LookupEntry groupMaskNames[];
+extern const LookupEntry groupNames[];
+extern const LookupEntry levelNames[];
+extern const LookupEntry buttonNames[];
+extern const LookupEntry useModMapValueNames[];
+extern const LookupEntry actionTypeNames[];
+extern const LookupEntry symInterpretMatchMaskNames[];
+
+const char *
+ModMaskText(const struct xkb_keymap *keymap, xkb_mod_mask_t mask);
+
+const char *
+ModIndexText(const struct xkb_keymap *keymap, xkb_mod_index_t ndx);
+
+xkb_mod_index_t
+ModNameToIndex(const struct xkb_keymap *keymap, xkb_atom_t name,
+ enum mod_type type);
+
+const char *
+ActionTypeText(enum xkb_action_type type);
+
+const char *
+KeysymText(struct xkb_context *ctx, xkb_keysym_t sym);
+
+const char *
+KeyNameText(struct xkb_context *ctx, xkb_atom_t name);
+
+const char *
+SIMatchText(enum xkb_match_operation type);
+
+const char *
+LedStateMaskText(struct xkb_context *ctx, enum xkb_state_component mask);
+
+const char *
+ControlMaskText(struct xkb_context *ctx, enum xkb_action_controls mask);
+
+#endif /* TEXT_H */
diff --git a/src/3rdparty/xkbcommon/src/utils.h b/src/3rdparty/xkbcommon/src/utils.h
new file mode 100644
index 0000000000..b4daaddaaa
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/utils.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef UTILS_H
+#define UTILS_H 1
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <string.h>
+#include <strings.h>
+
+#include "darray.h"
+
+/*
+ * We sometimes malloc strings and then expose them as const char*'s. This
+ * macro is used when we free these strings in order to avoid -Wcast-qual
+ * errors.
+ */
+#define UNCONSTIFY(const_ptr) ((void *) (uintptr_t) (const_ptr))
+
+static inline bool
+streq(const char *s1, const char *s2)
+{
+ return strcmp(s1, s2) == 0;
+}
+
+static inline bool
+streq_not_null(const char *s1, const char *s2)
+{
+ if (!s1 || !s2)
+ return false;
+ return streq(s1, s2);
+}
+
+static inline bool
+istreq(const char *s1, const char *s2)
+{
+ return strcasecmp(s1, s2) == 0;
+}
+
+static inline bool
+istreq_prefix(const char *s1, const char *s2)
+{
+ return strncasecmp(s1, s2, strlen(s1)) == 0;
+}
+
+static inline char *
+strdup_safe(const char *s)
+{
+ return s ? strdup(s) : NULL;
+}
+
+static inline bool
+isempty(const char *s)
+{
+ return s == NULL || s[0] == '\0';
+}
+
+static inline const char *
+strnull(const char *s)
+{
+ return s ? s : "(null)";
+}
+
+static inline void *
+memdup(const void *mem, size_t nmemb, size_t size)
+{
+ void *p = malloc(nmemb * size);
+ if (p)
+ memcpy(p, mem, nmemb * size);
+ return p;
+}
+
+#define ARRAY_SIZE(arr) ((sizeof(arr) / sizeof(*(arr))))
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MIN3(a, b, c) MIN(MIN((a), (b)), (c))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MAX3(a, b, c) MAX(MAX((a), (b)), (c))
+
+/* Compiler Attributes */
+
+#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__CYGWIN__)
+# define XKB_EXPORT __attribute__((visibility("default")))
+#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
+# define XKB_EXPORT __global
+#else /* not gcc >= 4 and not Sun Studio >= 8 */
+# define XKB_EXPORT
+#endif
+
+#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)
+# define ATTR_PRINTF(x,y) __attribute__((__format__(__printf__, x, y)))
+#else /* not gcc >= 2.3 */
+# define ATTR_PRINTF(x,y)
+#endif
+
+#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
+ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+# define ATTR_NORETURN __attribute__((__noreturn__))
+#else
+# define ATTR_NORETURN
+#endif /* GNUC */
+
+#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 296)
+#define ATTR_MALLOC __attribute__((__malloc__))
+#else
+#define ATTR_MALLOC
+#endif
+
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+# define ATTR_NULL_SENTINEL __attribute__((__sentinel__))
+#else
+# define ATTR_NULL_SENTINEL
+#endif /* GNUC >= 4 */
+
+#endif /* UTILS_H */
diff --git a/src/3rdparty/xkbcommon/src/xkb-compat.c b/src/3rdparty/xkbcommon/src/xkb-compat.c
new file mode 100644
index 0000000000..3cc3ab3d6e
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkb-compat.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright © 2012 Daniel Stone
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ */
+
+#define _XKBCOMMON_COMPAT_H /* don't mangle our legacy names! */
+
+#include "xkbcommon/xkbcommon.h"
+#include "utils.h"
+
+/* We don't carry any prototypes for these functions, as we #define them
+ * to their newer versions so people link against those. */
+#pragma GCC diagnostic ignored "-Wmissing-prototypes"
+
+XKB_EXPORT struct xkb_keymap *
+xkb_map_new_from_names(struct xkb_context *context,
+ const struct xkb_rule_names *names,
+ enum xkb_keymap_compile_flags flags)
+{
+ return xkb_keymap_new_from_names(context, names, flags);
+}
+
+XKB_EXPORT struct xkb_keymap *
+xkb_map_new_from_file(struct xkb_context *context, FILE *file,
+ enum xkb_keymap_format format,
+ enum xkb_keymap_compile_flags flags)
+{
+ return xkb_keymap_new_from_file(context, file, format, flags);
+}
+
+XKB_EXPORT struct xkb_keymap *
+xkb_map_new_from_string(struct xkb_context *context, const char *string,
+ enum xkb_keymap_format format,
+ enum xkb_keymap_compile_flags flags)
+{
+ return xkb_keymap_new_from_string(context, string, format, flags);
+}
+
+XKB_EXPORT char *
+xkb_map_get_as_string(struct xkb_keymap *keymap)
+{
+ return xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
+}
+
+XKB_EXPORT struct xkb_keymap *
+xkb_map_ref(struct xkb_keymap *keymap)
+{
+ return xkb_keymap_ref(keymap);
+}
+
+XKB_EXPORT void
+xkb_map_unref(struct xkb_keymap *keymap)
+{
+ xkb_keymap_unref(keymap);
+}
+
+XKB_EXPORT xkb_mod_index_t
+xkb_map_num_mods(struct xkb_keymap *keymap)
+{
+ return xkb_keymap_num_mods(keymap);
+}
+
+XKB_EXPORT const char *
+xkb_map_mod_get_name(struct xkb_keymap *keymap, xkb_mod_index_t idx)
+{
+ return xkb_keymap_mod_get_name(keymap, idx);
+}
+
+XKB_EXPORT xkb_mod_index_t
+xkb_map_mod_get_index(struct xkb_keymap *keymap, const char *name)
+{
+ return xkb_keymap_mod_get_index(keymap, name);
+}
+
+XKB_EXPORT bool
+xkb_key_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t kc,
+ xkb_mod_index_t idx)
+{
+ return xkb_state_mod_index_is_consumed(state, kc, idx);
+}
+
+XKB_EXPORT xkb_mod_mask_t
+xkb_key_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t kc,
+ xkb_mod_mask_t mask)
+{
+ return xkb_state_mod_mask_remove_consumed(state, kc, mask);
+}
+
+XKB_EXPORT xkb_layout_index_t
+xkb_map_num_groups(struct xkb_keymap *keymap)
+{
+ return xkb_keymap_num_layouts(keymap);
+}
+
+XKB_EXPORT xkb_layout_index_t
+xkb_key_num_groups(struct xkb_keymap *keymap, xkb_keycode_t kc)
+{
+ return xkb_keymap_num_layouts_for_key(keymap, kc);
+}
+
+XKB_EXPORT const char *
+xkb_map_group_get_name(struct xkb_keymap *keymap, xkb_layout_index_t idx)
+{
+ return xkb_keymap_layout_get_name(keymap, idx);
+}
+
+XKB_EXPORT xkb_layout_index_t
+xkb_map_group_get_index(struct xkb_keymap *keymap, const char *name)
+{
+ return xkb_keymap_layout_get_index(keymap, name);
+}
+
+XKB_EXPORT xkb_led_index_t
+xkb_map_num_leds(struct xkb_keymap *keymap)
+{
+ return xkb_keymap_num_leds(keymap);
+}
+
+XKB_EXPORT const char *
+xkb_map_led_get_name(struct xkb_keymap *keymap, xkb_led_index_t idx)
+{
+ return xkb_keymap_led_get_name(keymap, idx);
+}
+
+XKB_EXPORT xkb_led_index_t
+xkb_map_led_get_index(struct xkb_keymap *keymap, const char *name)
+{
+ return xkb_keymap_led_get_index(keymap, name);
+}
+
+XKB_EXPORT bool
+xkb_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t kc)
+{
+ return xkb_keymap_key_repeats(keymap, kc);
+}
+
+XKB_EXPORT int
+xkb_key_get_syms(struct xkb_state *state, xkb_keycode_t kc,
+ const xkb_keysym_t **syms_out)
+{
+ return xkb_state_key_get_syms(state, kc, syms_out);
+}
+
+XKB_EXPORT bool
+xkb_state_group_name_is_active(struct xkb_state *state, const char *name,
+ enum xkb_state_component type)
+{
+ return xkb_state_layout_name_is_active(state, name, type);
+}
+
+XKB_EXPORT bool
+xkb_state_group_index_is_active(struct xkb_state *state, xkb_layout_index_t idx,
+ enum xkb_state_component type)
+{
+ return xkb_state_layout_index_is_active(state, idx, type);
+}
+
+XKB_EXPORT xkb_layout_index_t
+xkb_state_serialize_group(struct xkb_state *state,
+ enum xkb_state_component type)
+{
+ return xkb_state_serialize_layout(state, type);
+}
+
+XKB_EXPORT struct xkb_keymap *
+xkb_state_get_map(struct xkb_state *state)
+{
+ return xkb_state_get_keymap(state);
+}
diff --git a/src/3rdparty/xkbcommon/src/xkb-keymap.c b/src/3rdparty/xkbcommon/src/xkb-keymap.c
new file mode 100644
index 0000000000..3df183a64f
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkb-keymap.c
@@ -0,0 +1,555 @@
+/**
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ */
+
+/************************************************************
+ * Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * ********************************************************/
+
+#include "keymap.h"
+#include "text.h"
+
+static struct xkb_keymap *
+xkb_keymap_new(struct xkb_context *ctx,
+ enum xkb_keymap_format format,
+ enum xkb_keymap_compile_flags flags)
+{
+ struct xkb_keymap *keymap;
+
+ keymap = calloc(1, sizeof(*keymap));
+ if (!keymap)
+ return NULL;
+
+ keymap->refcnt = 1;
+ keymap->ctx = xkb_context_ref(ctx);
+
+ keymap->format = format;
+ keymap->flags = flags;
+
+ return keymap;
+}
+
+XKB_EXPORT struct xkb_keymap *
+xkb_keymap_ref(struct xkb_keymap *keymap)
+{
+ keymap->refcnt++;
+ return keymap;
+}
+
+XKB_EXPORT void
+xkb_keymap_unref(struct xkb_keymap *keymap)
+{
+ unsigned int i, j;
+ struct xkb_key *key;
+
+ if (!keymap || --keymap->refcnt > 0)
+ return;
+
+ if (keymap->keys) {
+ xkb_foreach_key(key, keymap) {
+ for (i = 0; i < key->num_groups; i++) {
+ for (j = 0; j < XkbKeyGroupWidth(key, i); j++)
+ if (key->groups[i].levels[j].num_syms > 1)
+ free(key->groups[i].levels[j].u.syms);
+ free(key->groups[i].levels);
+ }
+ free(key->groups);
+ }
+ free(keymap->keys);
+ }
+ for (i = 0; i < keymap->num_types; i++) {
+ free(keymap->types[i].entries);
+ free(keymap->types[i].level_names);
+ }
+ free(keymap->types);
+ darray_free(keymap->sym_interprets);
+ free(keymap->key_aliases);
+ free(keymap->group_names);
+ darray_free(keymap->mods);
+ darray_free(keymap->leds);
+ free(keymap->keycodes_section_name);
+ free(keymap->symbols_section_name);
+ free(keymap->types_section_name);
+ free(keymap->compat_section_name);
+ xkb_context_unref(keymap->ctx);
+ free(keymap);
+}
+
+static const struct xkb_keymap_format_ops *
+get_keymap_format_ops(enum xkb_keymap_format format)
+{
+ static const struct xkb_keymap_format_ops *keymap_format_ops[] = {
+ [XKB_KEYMAP_FORMAT_TEXT_V1] = &text_v1_keymap_format_ops,
+ };
+
+ if ((int) format < 0 || (int) format >= ARRAY_SIZE(keymap_format_ops))
+ return NULL;
+
+ return keymap_format_ops[format];
+}
+
+XKB_EXPORT struct xkb_keymap *
+xkb_keymap_new_from_names(struct xkb_context *ctx,
+ const struct xkb_rule_names *rmlvo_in,
+ enum xkb_keymap_compile_flags flags)
+{
+ struct xkb_keymap *keymap;
+ struct xkb_rule_names rmlvo;
+ const enum xkb_keymap_format format = XKB_KEYMAP_FORMAT_TEXT_V1;
+ const struct xkb_keymap_format_ops *ops;
+
+ ops = get_keymap_format_ops(format);
+ if (!ops || !ops->keymap_new_from_names) {
+ log_err_func(ctx, "unsupported keymap format: %d\n", format);
+ return NULL;
+ }
+
+ if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
+ log_err_func(ctx, "unrecognized flags: %#x\n", flags);
+ return NULL;
+ }
+
+ if (rmlvo_in)
+ rmlvo = *rmlvo_in;
+ else
+ memset(&rmlvo, 0, sizeof(rmlvo));
+
+ if (isempty(rmlvo.rules))
+ rmlvo.rules = xkb_context_get_default_rules(ctx);
+ if (isempty(rmlvo.model))
+ rmlvo.model = xkb_context_get_default_model(ctx);
+ /* Layout and variant are tied together, so don't try to use one from
+ * the caller and one from the environment. */
+ if (isempty(rmlvo.layout)) {
+ rmlvo.layout = xkb_context_get_default_layout(ctx);
+ rmlvo.variant = xkb_context_get_default_variant(ctx);
+ }
+ /* Options can be empty, so respect that if passed in. */
+ if (rmlvo.options == NULL)
+ rmlvo.options = xkb_context_get_default_options(ctx);
+
+ keymap = xkb_keymap_new(ctx, format, flags);
+ if (!keymap)
+ return NULL;
+
+ if (!ops->keymap_new_from_names(keymap, &rmlvo)) {
+ xkb_keymap_unref(keymap);
+ return NULL;
+ }
+
+ return keymap;
+}
+
+XKB_EXPORT struct xkb_keymap *
+xkb_keymap_new_from_string(struct xkb_context *ctx,
+ const char *string,
+ enum xkb_keymap_format format,
+ enum xkb_keymap_compile_flags flags)
+{
+ struct xkb_keymap *keymap;
+ const struct xkb_keymap_format_ops *ops;
+
+ ops = get_keymap_format_ops(format);
+ if (!ops || !ops->keymap_new_from_string) {
+ log_err_func(ctx, "unsupported keymap format: %d\n", format);
+ return NULL;
+ }
+
+ if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
+ log_err_func(ctx, "unrecognized flags: %#x\n", flags);
+ return NULL;
+ }
+
+ if (!string) {
+ log_err_func1(ctx, "no string specified\n");
+ return NULL;
+ }
+
+ keymap = xkb_keymap_new(ctx, format, flags);
+ if (!keymap)
+ return NULL;
+
+ if (!ops->keymap_new_from_string(keymap, string)) {
+ xkb_keymap_unref(keymap);
+ return NULL;
+ }
+
+ return keymap;
+}
+
+XKB_EXPORT struct xkb_keymap *
+xkb_keymap_new_from_buffer(struct xkb_context *ctx,
+ const char *buffer, size_t length,
+ enum xkb_keymap_format format,
+ enum xkb_keymap_compile_flags flags)
+{
+ struct xkb_keymap *keymap;
+ const struct xkb_keymap_format_ops *ops;
+
+ ops = get_keymap_format_ops(format);
+ if (!ops || !ops->keymap_new_from_string) {
+ log_err_func(ctx, "unsupported keymap format: %d\n", format);
+ return NULL;
+ }
+
+ if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
+ log_err_func(ctx, "unrecognized flags: %#x\n", flags);
+ return NULL;
+ }
+
+ if (!buffer) {
+ log_err_func1(ctx, "no buffer specified\n");
+ return NULL;
+ }
+
+ keymap = xkb_keymap_new(ctx, format, flags);
+ if (!keymap)
+ return NULL;
+
+ if (!ops->keymap_new_from_buffer(keymap, buffer, length)) {
+ xkb_keymap_unref(keymap);
+ return NULL;
+ }
+
+ return keymap;
+}
+
+XKB_EXPORT struct xkb_keymap *
+xkb_keymap_new_from_file(struct xkb_context *ctx,
+ FILE *file,
+ enum xkb_keymap_format format,
+ enum xkb_keymap_compile_flags flags)
+{
+ struct xkb_keymap *keymap;
+ const struct xkb_keymap_format_ops *ops;
+
+ ops = get_keymap_format_ops(format);
+ if (!ops || !ops->keymap_new_from_file) {
+ log_err_func(ctx, "unsupported keymap format: %d\n", format);
+ return NULL;
+ }
+
+ if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
+ log_err_func(ctx, "unrecognized flags: %#x\n", flags);
+ return NULL;
+ }
+
+ if (!file) {
+ log_err_func1(ctx, "no file specified\n");
+ return NULL;
+ }
+
+ keymap = xkb_keymap_new(ctx, format, flags);
+ if (!keymap)
+ return NULL;
+
+ if (!ops->keymap_new_from_file(keymap, file)) {
+ xkb_keymap_unref(keymap);
+ return NULL;
+ }
+
+ return keymap;
+}
+
+XKB_EXPORT char *
+xkb_keymap_get_as_string(struct xkb_keymap *keymap,
+ enum xkb_keymap_format format)
+{
+ const struct xkb_keymap_format_ops *ops;
+
+ if (format == XKB_KEYMAP_USE_ORIGINAL_FORMAT)
+ format = keymap->format;
+
+ ops = get_keymap_format_ops(format);
+ if (!ops || !ops->keymap_get_as_string) {
+ log_err_func(keymap->ctx, "unsupported keymap format: %d\n", format);
+ return NULL;
+ }
+
+ return ops->keymap_get_as_string(keymap);
+}
+
+/**
+ * Returns the total number of modifiers active in the keymap.
+ */
+XKB_EXPORT xkb_mod_index_t
+xkb_keymap_num_mods(struct xkb_keymap *keymap)
+{
+ return darray_size(keymap->mods);
+}
+
+/**
+ * Return the name for a given modifier.
+ */
+XKB_EXPORT const char *
+xkb_keymap_mod_get_name(struct xkb_keymap *keymap, xkb_mod_index_t idx)
+{
+ if (idx >= darray_size(keymap->mods))
+ return NULL;
+
+ return xkb_atom_text(keymap->ctx, darray_item(keymap->mods, idx).name);
+}
+
+/**
+ * Returns the index for a named modifier.
+ */
+XKB_EXPORT xkb_mod_index_t
+xkb_keymap_mod_get_index(struct xkb_keymap *keymap, const char *name)
+{
+ xkb_mod_index_t i;
+ xkb_atom_t atom;
+ const struct xkb_mod *mod;
+
+ atom = xkb_atom_lookup(keymap->ctx, name);
+ if (atom == XKB_ATOM_NONE)
+ return XKB_MOD_INVALID;
+
+ darray_enumerate(i, mod, keymap->mods)
+ if (mod->name == atom)
+ return i;
+
+ return XKB_MOD_INVALID;
+}
+
+/**
+ * Return the total number of active groups in the keymap.
+ */
+XKB_EXPORT xkb_layout_index_t
+xkb_keymap_num_layouts(struct xkb_keymap *keymap)
+{
+ return keymap->num_groups;
+}
+
+/**
+ * Returns the name for a given group.
+ */
+XKB_EXPORT const char *
+xkb_keymap_layout_get_name(struct xkb_keymap *keymap, xkb_layout_index_t idx)
+{
+ if (idx >= keymap->num_group_names)
+ return NULL;
+
+ return xkb_atom_text(keymap->ctx, keymap->group_names[idx]);
+}
+
+/**
+ * Returns the index for a named layout.
+ */
+XKB_EXPORT xkb_layout_index_t
+xkb_keymap_layout_get_index(struct xkb_keymap *keymap, const char *name)
+{
+ xkb_atom_t atom = xkb_atom_lookup(keymap->ctx, name);
+ xkb_layout_index_t i;
+
+ if (atom == XKB_ATOM_NONE)
+ return XKB_LAYOUT_INVALID;
+
+ for (i = 0; i < keymap->num_group_names; i++)
+ if (keymap->group_names[i] == atom)
+ return i;
+
+ return XKB_LAYOUT_INVALID;
+}
+
+/**
+ * Returns the number of layouts active for a particular key.
+ */
+XKB_EXPORT xkb_layout_index_t
+xkb_keymap_num_layouts_for_key(struct xkb_keymap *keymap, xkb_keycode_t kc)
+{
+ const struct xkb_key *key = XkbKey(keymap, kc);
+
+ if (!key)
+ return 0;
+
+ return key->num_groups;
+}
+
+/**
+ * Returns the number of levels active for a particular key and layout.
+ */
+XKB_EXPORT xkb_level_index_t
+xkb_keymap_num_levels_for_key(struct xkb_keymap *keymap, xkb_keycode_t kc,
+ xkb_layout_index_t layout)
+{
+ const struct xkb_key *key = XkbKey(keymap, kc);
+
+ if (!key)
+ return 0;
+
+ layout = wrap_group_into_range(layout, key->num_groups,
+ key->out_of_range_group_action,
+ key->out_of_range_group_number);
+ if (layout == XKB_LAYOUT_INVALID)
+ return 0;
+
+ return XkbKeyGroupWidth(key, layout);
+}
+
+/**
+ * Return the total number of LEDs in the keymap.
+ */
+XKB_EXPORT xkb_led_index_t
+xkb_keymap_num_leds(struct xkb_keymap *keymap)
+{
+ return darray_size(keymap->leds);
+}
+
+/**
+ * Returns the name for a given LED.
+ */
+XKB_EXPORT const char *
+xkb_keymap_led_get_name(struct xkb_keymap *keymap, xkb_led_index_t idx)
+{
+ if (idx >= darray_size(keymap->leds))
+ return NULL;
+
+ return xkb_atom_text(keymap->ctx, darray_item(keymap->leds, idx).name);
+}
+
+/**
+ * Returns the index for a named LED.
+ */
+XKB_EXPORT xkb_led_index_t
+xkb_keymap_led_get_index(struct xkb_keymap *keymap, const char *name)
+{
+ xkb_atom_t atom = xkb_atom_lookup(keymap->ctx, name);
+ xkb_led_index_t i;
+ const struct xkb_led *led;
+
+ if (atom == XKB_ATOM_NONE)
+ return XKB_LED_INVALID;
+
+ darray_enumerate(i, led, keymap->leds)
+ if (led->name == atom)
+ return i;
+
+ return XKB_LED_INVALID;
+}
+
+/**
+ * As below, but takes an explicit layout/level rather than state.
+ */
+XKB_EXPORT int
+xkb_keymap_key_get_syms_by_level(struct xkb_keymap *keymap,
+ xkb_keycode_t kc,
+ xkb_layout_index_t layout,
+ xkb_level_index_t level,
+ const xkb_keysym_t **syms_out)
+{
+ const struct xkb_key *key = XkbKey(keymap, kc);
+ int num_syms;
+
+ if (!key)
+ goto err;
+
+ layout = wrap_group_into_range(layout, key->num_groups,
+ key->out_of_range_group_action,
+ key->out_of_range_group_number);
+ if (layout == XKB_LAYOUT_INVALID)
+ goto err;
+
+ if (level >= XkbKeyGroupWidth(key, layout))
+ goto err;
+
+ num_syms = key->groups[layout].levels[level].num_syms;
+ if (num_syms == 0)
+ goto err;
+
+ if (num_syms == 1)
+ *syms_out = &key->groups[layout].levels[level].u.sym;
+ else
+ *syms_out = key->groups[layout].levels[level].u.syms;
+
+ return num_syms;
+
+err:
+ *syms_out = NULL;
+ return 0;
+}
+
+/**
+ * Simple boolean specifying whether or not the key should repeat.
+ */
+XKB_EXPORT int
+xkb_keymap_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t kc)
+{
+ const struct xkb_key *key = XkbKey(keymap, kc);
+
+ if (!key)
+ return 0;
+
+ return key->repeats;
+}
+
+struct xkb_key *
+XkbKeyByName(struct xkb_keymap *keymap, xkb_atom_t name, bool use_aliases)
+{
+ struct xkb_key *key;
+
+ xkb_foreach_key(key, keymap)
+ if (key->name == name)
+ return key;
+
+ if (use_aliases) {
+ xkb_atom_t new_name = XkbResolveKeyAlias(keymap, name);
+ if (new_name != XKB_ATOM_NONE)
+ return XkbKeyByName(keymap, new_name, false);
+ }
+
+ return NULL;
+}
+
+xkb_atom_t
+XkbResolveKeyAlias(struct xkb_keymap *keymap, xkb_atom_t name)
+{
+ for (unsigned i = 0; i < keymap->num_key_aliases; i++)
+ if (keymap->key_aliases[i].alias == name)
+ return keymap->key_aliases[i].real;
+
+ return XKB_ATOM_NONE;
+}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/action.c b/src/3rdparty/xkbcommon/src/xkbcomp/action.c
new file mode 100644
index 0000000000..88323f9952
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/action.c
@@ -0,0 +1,951 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+/*
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ * Ran Benita <ran234@gmail.com>
+ */
+
+#include "xkbcomp-priv.h"
+#include "text.h"
+#include "expr.h"
+#include "action.h"
+
+static const ExprDef constTrue = {
+ .common = { .type = STMT_EXPR, .next = NULL },
+ .op = EXPR_VALUE,
+ .value_type = EXPR_TYPE_BOOLEAN,
+ .value = { .ival = 1 },
+};
+
+static const ExprDef constFalse = {
+ .common = { .type = STMT_EXPR, .next = NULL },
+ .op = EXPR_VALUE,
+ .value_type = EXPR_TYPE_BOOLEAN,
+ .value = { .ival = 0 },
+};
+
+enum action_field {
+ ACTION_FIELD_CLEAR_LOCKS,
+ ACTION_FIELD_LATCH_TO_LOCK,
+ ACTION_FIELD_GEN_KEY_EVENT,
+ ACTION_FIELD_REPORT,
+ ACTION_FIELD_DEFAULT,
+ ACTION_FIELD_AFFECT,
+ ACTION_FIELD_INCREMENT,
+ ACTION_FIELD_MODIFIERS,
+ ACTION_FIELD_GROUP,
+ ACTION_FIELD_X,
+ ACTION_FIELD_Y,
+ ACTION_FIELD_ACCEL,
+ ACTION_FIELD_BUTTON,
+ ACTION_FIELD_VALUE,
+ ACTION_FIELD_CONTROLS,
+ ACTION_FIELD_TYPE,
+ ACTION_FIELD_COUNT,
+ ACTION_FIELD_SCREEN,
+ ACTION_FIELD_SAME,
+ ACTION_FIELD_DATA,
+ ACTION_FIELD_DEVICE,
+ ACTION_FIELD_KEYCODE,
+ ACTION_FIELD_MODS_TO_CLEAR,
+};
+
+ActionsInfo *
+NewActionsInfo(void)
+{
+ unsigned type;
+ ActionsInfo *info;
+
+ info = calloc(1, sizeof(*info));
+ if (!info)
+ return NULL;
+
+ for (type = 0; type < _ACTION_TYPE_NUM_ENTRIES; type++)
+ info->actions[type].type = type;
+
+ /* Apply some "factory defaults". */
+
+ /* Increment default button. */
+ info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.flags = 0;
+ info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.value = 1;
+
+ return info;
+}
+
+void
+FreeActionsInfo(ActionsInfo *info)
+{
+ free(info);
+}
+
+static const LookupEntry fieldStrings[] = {
+ { "clearLocks", ACTION_FIELD_CLEAR_LOCKS },
+ { "latchToLock", ACTION_FIELD_LATCH_TO_LOCK },
+ { "genKeyEvent", ACTION_FIELD_GEN_KEY_EVENT },
+ { "generateKeyEvent", ACTION_FIELD_GEN_KEY_EVENT },
+ { "report", ACTION_FIELD_REPORT },
+ { "default", ACTION_FIELD_DEFAULT },
+ { "affect", ACTION_FIELD_AFFECT },
+ { "increment", ACTION_FIELD_INCREMENT },
+ { "modifiers", ACTION_FIELD_MODIFIERS },
+ { "mods", ACTION_FIELD_MODIFIERS },
+ { "group", ACTION_FIELD_GROUP },
+ { "x", ACTION_FIELD_X },
+ { "y", ACTION_FIELD_Y },
+ { "accel", ACTION_FIELD_ACCEL },
+ { "accelerate", ACTION_FIELD_ACCEL },
+ { "repeat", ACTION_FIELD_ACCEL },
+ { "button", ACTION_FIELD_BUTTON },
+ { "value", ACTION_FIELD_VALUE },
+ { "controls", ACTION_FIELD_CONTROLS },
+ { "ctrls", ACTION_FIELD_CONTROLS },
+ { "type", ACTION_FIELD_TYPE },
+ { "count", ACTION_FIELD_COUNT },
+ { "screen", ACTION_FIELD_SCREEN },
+ { "same", ACTION_FIELD_SAME },
+ { "sameServer", ACTION_FIELD_SAME },
+ { "data", ACTION_FIELD_DATA },
+ { "device", ACTION_FIELD_DEVICE },
+ { "dev", ACTION_FIELD_DEVICE },
+ { "key", ACTION_FIELD_KEYCODE },
+ { "keycode", ACTION_FIELD_KEYCODE },
+ { "kc", ACTION_FIELD_KEYCODE },
+ { "clearmods", ACTION_FIELD_MODS_TO_CLEAR },
+ { "clearmodifiers", ACTION_FIELD_MODS_TO_CLEAR },
+ { NULL, 0 }
+};
+
+static bool
+stringToAction(const char *str, unsigned *type_rtrn)
+{
+ return LookupString(actionTypeNames, str, type_rtrn);
+}
+
+static bool
+stringToField(const char *str, enum action_field *field_rtrn)
+{
+ return LookupString(fieldStrings, str, field_rtrn);
+}
+
+static const char *
+fieldText(enum action_field field)
+{
+ return LookupValue(fieldStrings, field);
+}
+
+/***====================================================================***/
+
+static inline bool
+ReportMismatch(struct xkb_keymap *keymap, enum xkb_action_type action,
+ enum action_field field, const char *type)
+{
+ log_err(keymap->ctx,
+ "Value of %s field must be of type %s; "
+ "Action %s definition ignored\n",
+ fieldText(field), type, ActionTypeText(action));
+ return false;
+}
+
+static inline bool
+ReportIllegal(struct xkb_keymap *keymap, enum xkb_action_type action,
+ enum action_field field)
+{
+ log_err(keymap->ctx,
+ "Field %s is not defined for an action of type %s; "
+ "Action definition ignored\n",
+ fieldText(field), ActionTypeText(action));
+ return false;
+}
+
+static inline bool
+ReportActionNotArray(struct xkb_keymap *keymap, enum xkb_action_type action,
+ enum action_field field)
+{
+ log_err(keymap->ctx,
+ "The %s field in the %s action is not an array; "
+ "Action definition ignored\n",
+ fieldText(field), ActionTypeText(action));
+ return false;
+}
+
+static inline bool
+ReportNotFound(struct xkb_keymap *keymap, enum xkb_action_type action,
+ enum action_field field, const char *what, const char *bad)
+{
+ log_err(keymap->ctx,
+ "%s named %s not found; "
+ "Ignoring the %s field of an %s action\n",
+ what, bad, fieldText(field), ActionTypeText(action));
+ return false;
+}
+
+static bool
+HandleNoAction(struct xkb_keymap *keymap, union xkb_action *action,
+ enum action_field field, const ExprDef *array_ndx,
+ const ExprDef *value)
+
+{
+ return true;
+}
+
+static bool
+CheckLatchLockFlags(struct xkb_keymap *keymap, enum xkb_action_type action,
+ enum action_field field, const ExprDef *value,
+ enum xkb_action_flags *flags_inout)
+{
+ enum xkb_action_flags tmp;
+ bool result;
+
+ if (field == ACTION_FIELD_CLEAR_LOCKS)
+ tmp = ACTION_LOCK_CLEAR;
+ else if (field == ACTION_FIELD_LATCH_TO_LOCK)
+ tmp = ACTION_LATCH_TO_LOCK;
+ else
+ return false; /* WSGO! */
+
+ if (!ExprResolveBoolean(keymap->ctx, value, &result))
+ return ReportMismatch(keymap, action, field, "boolean");
+
+ if (result)
+ *flags_inout |= tmp;
+ else
+ *flags_inout &= ~tmp;
+
+ return true;
+}
+
+static bool
+CheckModifierField(struct xkb_keymap *keymap, enum xkb_action_type action,
+ const ExprDef *value, enum xkb_action_flags *flags_inout,
+ xkb_mod_mask_t *mods_rtrn)
+{
+ if (value->op == EXPR_IDENT) {
+ const char *valStr;
+ valStr = xkb_atom_text(keymap->ctx, value->value.str);
+ if (valStr && (istreq(valStr, "usemodmapmods") ||
+ istreq(valStr, "modmapmods"))) {
+
+ *mods_rtrn = 0;
+ *flags_inout |= ACTION_MODS_LOOKUP_MODMAP;
+ return true;
+ }
+ }
+
+ if (!ExprResolveModMask(keymap, value, MOD_BOTH, mods_rtrn))
+ return ReportMismatch(keymap, action,
+ ACTION_FIELD_MODIFIERS, "modifier mask");
+
+ *flags_inout &= ~ACTION_MODS_LOOKUP_MODMAP;
+ return true;
+}
+
+static bool
+HandleSetLatchMods(struct xkb_keymap *keymap, union xkb_action *action,
+ enum action_field field, const ExprDef *array_ndx,
+ const ExprDef *value)
+{
+ struct xkb_mod_action *act = &action->mods;
+ enum xkb_action_flags rtrn, t1;
+ xkb_mod_mask_t t2;
+
+ if (array_ndx != NULL) {
+ switch (field) {
+ case ACTION_FIELD_CLEAR_LOCKS:
+ case ACTION_FIELD_LATCH_TO_LOCK:
+ case ACTION_FIELD_MODIFIERS:
+ return ReportActionNotArray(keymap, action->type, field);
+ default:
+ break;
+ }
+ }
+
+ switch (field) {
+ case ACTION_FIELD_CLEAR_LOCKS:
+ case ACTION_FIELD_LATCH_TO_LOCK:
+ rtrn = act->flags;
+ if (CheckLatchLockFlags(keymap, action->type, field, value, &rtrn)) {
+ act->flags = rtrn;
+ return true;
+ }
+ return false;
+
+ case ACTION_FIELD_MODIFIERS:
+ t1 = act->flags;
+ if (CheckModifierField(keymap, action->type, value, &t1, &t2)) {
+ act->flags = t1;
+ act->mods.mods = t2;
+ return true;
+ }
+ return false;
+
+ default:
+ break;
+ }
+
+ return ReportIllegal(keymap, action->type, field);
+}
+
+static bool
+HandleLockMods(struct xkb_keymap *keymap, union xkb_action *action,
+ enum action_field field, const ExprDef *array_ndx,
+ const ExprDef *value)
+{
+ struct xkb_mod_action *act = &action->mods;
+ enum xkb_action_flags t1;
+ xkb_mod_mask_t t2;
+
+ if (array_ndx && field == ACTION_FIELD_MODIFIERS)
+ return ReportActionNotArray(keymap, action->type, field);
+
+ switch (field) {
+ case ACTION_FIELD_MODIFIERS:
+ t1 = act->flags;
+ if (CheckModifierField(keymap, action->type, value, &t1, &t2)) {
+ act->flags = t1;
+ act->mods.mods = t2;
+ return true;
+ }
+ return false;
+
+ default:
+ break;
+ }
+
+ return ReportIllegal(keymap, action->type, field);
+}
+
+static bool
+CheckGroupField(struct xkb_keymap *keymap, unsigned action,
+ const ExprDef *value, enum xkb_action_flags *flags_inout,
+ xkb_layout_index_t *grp_rtrn)
+{
+ const ExprDef *spec;
+
+ if (value->op == EXPR_NEGATE || value->op == EXPR_UNARY_PLUS) {
+ *flags_inout &= ~ACTION_ABSOLUTE_SWITCH;
+ spec = value->value.child;
+ }
+ else {
+ *flags_inout |= ACTION_ABSOLUTE_SWITCH;
+ spec = value;
+ }
+
+ if (!ExprResolveGroup(keymap->ctx, spec, grp_rtrn))
+ return ReportMismatch(keymap, action, ACTION_FIELD_GROUP,
+ "integer (range 1..8)");
+
+ if (value->op == EXPR_NEGATE)
+ *grp_rtrn = -*grp_rtrn;
+ else if (value->op != EXPR_UNARY_PLUS)
+ (*grp_rtrn)--;
+
+ return true;
+}
+
+static bool
+HandleSetLatchGroup(struct xkb_keymap *keymap, union xkb_action *action,
+ enum action_field field, const ExprDef *array_ndx,
+ const ExprDef *value)
+{
+ struct xkb_group_action *act = &action->group;
+ enum xkb_action_flags rtrn, t1;
+ xkb_layout_index_t t2;
+
+ if (array_ndx != NULL) {
+ switch (field) {
+ case ACTION_FIELD_CLEAR_LOCKS:
+ case ACTION_FIELD_LATCH_TO_LOCK:
+ case ACTION_FIELD_GROUP:
+ return ReportActionNotArray(keymap, action->type, field);
+
+ default:
+ break;
+ }
+ }
+
+ switch (field) {
+ case ACTION_FIELD_CLEAR_LOCKS:
+ case ACTION_FIELD_LATCH_TO_LOCK:
+ rtrn = act->flags;
+ if (CheckLatchLockFlags(keymap, action->type, field, value, &rtrn)) {
+ act->flags = rtrn;
+ return true;
+ }
+ return false;
+
+ case ACTION_FIELD_GROUP:
+ t1 = act->flags;
+ if (CheckGroupField(keymap, action->type, value, &t1, &t2)) {
+ act->flags = t1;
+ act->group = t2;
+ return true;
+ }
+ return false;
+
+ default:
+ break;
+ }
+
+ return ReportIllegal(keymap, action->type, field);
+}
+
+static bool
+HandleLockGroup(struct xkb_keymap *keymap, union xkb_action *action,
+ enum action_field field, const ExprDef *array_ndx,
+ const ExprDef *value)
+{
+ struct xkb_group_action *act = &action->group;
+ enum xkb_action_flags t1;
+ xkb_layout_index_t t2;
+
+ if ((array_ndx != NULL) && (field == ACTION_FIELD_GROUP))
+ return ReportActionNotArray(keymap, action->type, field);
+ if (field == ACTION_FIELD_GROUP) {
+ t1 = act->flags;
+ if (CheckGroupField(keymap, action->type, value, &t1, &t2)) {
+ act->flags = t1;
+ act->group = t2;
+ return true;
+ }
+ return false;
+ }
+ return ReportIllegal(keymap, action->type, field);
+}
+
+static bool
+HandleMovePtr(struct xkb_keymap *keymap, union xkb_action *action,
+ enum action_field field, const ExprDef *array_ndx,
+ const ExprDef *value)
+{
+ struct xkb_pointer_action *act = &action->ptr;
+ bool absolute;
+
+ if (array_ndx && (field == ACTION_FIELD_X || field == ACTION_FIELD_Y))
+ return ReportActionNotArray(keymap, action->type, field);
+
+ if (field == ACTION_FIELD_X || field == ACTION_FIELD_Y) {
+ int val;
+
+ if (value->op == EXPR_NEGATE || value->op == EXPR_UNARY_PLUS)
+ absolute = false;
+ else
+ absolute = true;
+
+ if (!ExprResolveInteger(keymap->ctx, value, &val))
+ return ReportMismatch(keymap, action->type, field, "integer");
+
+ if (field == ACTION_FIELD_X) {
+ if (absolute)
+ act->flags |= ACTION_ABSOLUTE_X;
+ act->x = val;
+ }
+ else {
+ if (absolute)
+ act->flags |= ACTION_ABSOLUTE_Y;
+ act->y = val;
+ }
+
+ return true;
+ }
+ else if (field == ACTION_FIELD_ACCEL) {
+ bool set;
+
+ if (!ExprResolveBoolean(keymap->ctx, value, &set))
+ return ReportMismatch(keymap, action->type, field, "boolean");
+
+ if (set)
+ act->flags &= ~ACTION_NO_ACCEL;
+ else
+ act->flags |= ACTION_NO_ACCEL;
+ }
+
+ return ReportIllegal(keymap, action->type, field);
+}
+
+static const LookupEntry lockWhich[] = {
+ { "both", 0 },
+ { "lock", ACTION_LOCK_NO_UNLOCK },
+ { "neither", (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK) },
+ { "unlock", ACTION_LOCK_NO_LOCK },
+ { NULL, 0 }
+};
+
+static bool
+HandlePtrBtn(struct xkb_keymap *keymap, union xkb_action *action,
+ enum action_field field, const ExprDef *array_ndx,
+ const ExprDef *value)
+{
+ struct xkb_pointer_button_action *act = &action->btn;
+
+ if (field == ACTION_FIELD_BUTTON) {
+ int btn;
+
+ if (array_ndx)
+ return ReportActionNotArray(keymap, action->type, field);
+
+ if (!ExprResolveButton(keymap->ctx, value, &btn))
+ return ReportMismatch(keymap, action->type, field,
+ "integer (range 1..5)");
+
+ if (btn < 0 || btn > 5) {
+ log_err(keymap->ctx,
+ "Button must specify default or be in the range 1..5; "
+ "Illegal button value %d ignored\n", btn);
+ return false;
+ }
+
+ act->button = btn;
+ return true;
+ }
+ else if (action->type == ACTION_TYPE_PTR_LOCK &&
+ field == ACTION_FIELD_AFFECT) {
+ enum xkb_action_flags val;
+
+ if (array_ndx)
+ return ReportActionNotArray(keymap, action->type, field);
+
+ if (!ExprResolveEnum(keymap->ctx, value, &val, lockWhich))
+ return ReportMismatch(keymap, action->type, field,
+ "lock or unlock");
+
+ act->flags &= ~(ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK);
+ act->flags |= val;
+ return true;
+ }
+ else if (field == ACTION_FIELD_COUNT) {
+ int btn;
+
+ if (array_ndx)
+ return ReportActionNotArray(keymap, action->type, field);
+
+ /* XXX: Should this actually be ResolveButton? */
+ if (!ExprResolveButton(keymap->ctx, value, &btn))
+ return ReportMismatch(keymap, action->type, field, "integer");
+
+ if (btn < 0 || btn > 255) {
+ log_err(keymap->ctx,
+ "The count field must have a value in the range 0..255; "
+ "Illegal count %d ignored\n", btn);
+ return false;
+ }
+
+ act->count = btn;
+ return true;
+ }
+ return ReportIllegal(keymap, action->type, field);
+}
+
+static const LookupEntry ptrDflts[] = {
+ { "dfltbtn", 1 },
+ { "defaultbutton", 1 },
+ { "button", 1 },
+ { NULL, 0 }
+};
+
+static bool
+HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
+ enum action_field field, const ExprDef *array_ndx,
+ const ExprDef *value)
+{
+ struct xkb_pointer_default_action *act = &action->dflt;
+
+ if (field == ACTION_FIELD_AFFECT) {
+ unsigned int val;
+
+ if (array_ndx)
+ return ReportActionNotArray(keymap, action->type, field);
+
+ if (!ExprResolveEnum(keymap->ctx, value, &val, ptrDflts))
+ return ReportMismatch(keymap, action->type, field,
+ "pointer component");
+ return true;
+ }
+ else if (field == ACTION_FIELD_BUTTON || field == ACTION_FIELD_VALUE) {
+ const ExprDef *button;
+ int btn;
+
+ if (array_ndx)
+ return ReportActionNotArray(keymap, action->type, field);
+
+ if (value->op == EXPR_NEGATE || value->op == EXPR_UNARY_PLUS) {
+ act->flags &= ~ACTION_ABSOLUTE_SWITCH;
+ button = value->value.child;
+ }
+ else {
+ act->flags |= ACTION_ABSOLUTE_SWITCH;
+ button = value;
+ }
+
+ if (!ExprResolveButton(keymap->ctx, button, &btn))
+ return ReportMismatch(keymap, action->type, field,
+ "integer (range 1..5)");
+
+ if (btn < 0 || btn > 5) {
+ log_err(keymap->ctx,
+ "New default button value must be in the range 1..5; "
+ "Illegal default button value %d ignored\n", btn);
+ return false;
+ }
+ if (btn == 0) {
+ log_err(keymap->ctx,
+ "Cannot set default pointer button to \"default\"; "
+ "Illegal default button setting ignored\n");
+ return false;
+ }
+
+ act->value = (value->op == EXPR_NEGATE ? -btn: btn);
+ return true;
+ }
+
+ return ReportIllegal(keymap, action->type, field);
+}
+
+static bool
+HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action,
+ enum action_field field, const ExprDef *array_ndx,
+ const ExprDef *value)
+{
+ struct xkb_switch_screen_action *act = &action->screen;
+
+ if (field == ACTION_FIELD_SCREEN) {
+ const ExprDef *scrn;
+ int val;
+
+ if (array_ndx)
+ return ReportActionNotArray(keymap, action->type, field);
+
+ if (value->op == EXPR_NEGATE || value->op == EXPR_UNARY_PLUS) {
+ act->flags &= ~ACTION_ABSOLUTE_SWITCH;
+ scrn = value->value.child;
+ }
+ else {
+ act->flags |= ACTION_ABSOLUTE_SWITCH;
+ scrn = value;
+ }
+
+ if (!ExprResolveInteger(keymap->ctx, scrn, &val))
+ return ReportMismatch(keymap, action->type, field,
+ "integer (0..255)");
+
+ if (val < 0 || val > 255) {
+ log_err(keymap->ctx,
+ "Screen index must be in the range 1..255; "
+ "Illegal screen value %d ignored\n", val);
+ return false;
+ }
+
+ act->screen = (value->op == EXPR_NEGATE ? -val : val);
+ return true;
+ }
+ else if (field == ACTION_FIELD_SAME) {
+ bool set;
+
+ if (array_ndx)
+ return ReportActionNotArray(keymap, action->type, field);
+
+ if (!ExprResolveBoolean(keymap->ctx, value, &set))
+ return ReportMismatch(keymap, action->type, field, "boolean");
+
+ if (set)
+ act->flags &= ~ACTION_SAME_SCREEN;
+ else
+ act->flags |= ACTION_SAME_SCREEN;
+
+ return true;
+ }
+
+ return ReportIllegal(keymap, action->type, field);
+}
+
+static bool
+HandleSetLockControls(struct xkb_keymap *keymap, union xkb_action *action,
+ enum action_field field, const ExprDef *array_ndx,
+ const ExprDef *value)
+{
+ struct xkb_controls_action *act = &action->ctrls;
+
+ if (field == ACTION_FIELD_CONTROLS) {
+ unsigned int mask;
+
+ if (array_ndx)
+ return ReportActionNotArray(keymap, action->type, field);
+
+ if (!ExprResolveMask(keymap->ctx, value, &mask, ctrlMaskNames))
+ return ReportMismatch(keymap, action->type, field,
+ "controls mask");
+
+ act->ctrls = mask;
+ return true;
+ }
+
+ return ReportIllegal(keymap, action->type, field);
+}
+
+static bool
+HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action,
+ enum action_field field, const ExprDef *array_ndx,
+ const ExprDef *value)
+{
+ struct xkb_private_action *act = &action->priv;
+
+ if (field == ACTION_FIELD_TYPE) {
+ int type;
+
+ if (!ExprResolveInteger(keymap->ctx, value, &type))
+ return ReportMismatch(keymap, ACTION_TYPE_PRIVATE, field, "integer");
+
+ if (type < 0 || type > 255) {
+ log_err(keymap->ctx,
+ "Private action type must be in the range 0..255; "
+ "Illegal type %d ignored\n", type);
+ return false;
+ }
+
+ /*
+ * It's possible for someone to write something like this:
+ * actions = [ Private(type=3,data[0]=1,data[1]=3,data[2]=3) ]
+ * where the type refers to some existing action type, e.g. LockMods.
+ * This assumes that this action's struct is laid out in memory
+ * exactly as described in the XKB specification and libraries.
+ * We, however, have changed these structs in various ways, so this
+ * assumption is no longer true. Since this is a lousy "feature", we
+ * make actions like these no-ops for now.
+ */
+ if (type < ACTION_TYPE_PRIVATE) {
+ log_info(keymap->ctx,
+ "Private actions of type %s are not supported; Ignored\n",
+ ActionTypeText(type));
+ act->type = ACTION_TYPE_NONE;
+ }
+ else {
+ act->type = (enum xkb_action_type) type;
+ }
+
+ return true;
+ }
+ else if (field == ACTION_FIELD_DATA) {
+ if (array_ndx == NULL) {
+ xkb_atom_t val;
+ const char *str;
+ int len;
+
+ if (!ExprResolveString(keymap->ctx, value, &val))
+ return ReportMismatch(keymap, action->type, field, "string");
+
+ str = xkb_atom_text(keymap->ctx, val);
+ len = strlen(str);
+ if (len < 1 || len > 7) {
+ log_warn(keymap->ctx,
+ "A private action has 7 data bytes; "
+ "Extra %d bytes ignored\n", len - 6);
+ return false;
+ }
+
+ strncpy((char *) act->data, str, sizeof(act->data));
+ return true;
+ }
+ else {
+ int ndx, datum;
+
+ if (!ExprResolveInteger(keymap->ctx, array_ndx, &ndx)) {
+ log_err(keymap->ctx,
+ "Array subscript must be integer; "
+ "Illegal subscript ignored\n");
+ return false;
+ }
+
+ if (ndx < 0 || ndx >= sizeof(act->data)) {
+ log_err(keymap->ctx,
+ "The data for a private action is %lu bytes long; "
+ "Attempt to use data[%d] ignored\n",
+ (unsigned long) sizeof(act->data), ndx);
+ return false;
+ }
+
+ if (!ExprResolveInteger(keymap->ctx, value, &datum))
+ return ReportMismatch(keymap, act->type, field, "integer");
+
+ if (datum < 0 || datum > 255) {
+ log_err(keymap->ctx,
+ "All data for a private action must be 0..255; "
+ "Illegal datum %d ignored\n", datum);
+ return false;
+ }
+
+ act->data[ndx] = (uint8_t) datum;
+ return true;
+ }
+ }
+
+ return ReportIllegal(keymap, ACTION_TYPE_NONE, field);
+}
+
+typedef bool (*actionHandler)(struct xkb_keymap *keymap,
+ union xkb_action *action,
+ enum action_field field,
+ const ExprDef *array_ndx,
+ const ExprDef *value);
+
+static const actionHandler handleAction[_ACTION_TYPE_NUM_ENTRIES] = {
+ [ACTION_TYPE_NONE] = HandleNoAction,
+ [ACTION_TYPE_MOD_SET] = HandleSetLatchMods,
+ [ACTION_TYPE_MOD_LATCH] = HandleSetLatchMods,
+ [ACTION_TYPE_MOD_LOCK] = HandleLockMods,
+ [ACTION_TYPE_GROUP_SET] = HandleSetLatchGroup,
+ [ACTION_TYPE_GROUP_LATCH] = HandleSetLatchGroup,
+ [ACTION_TYPE_GROUP_LOCK] = HandleLockGroup,
+ [ACTION_TYPE_PTR_MOVE] = HandleMovePtr,
+ [ACTION_TYPE_PTR_BUTTON] = HandlePtrBtn,
+ [ACTION_TYPE_PTR_LOCK] = HandlePtrBtn,
+ [ACTION_TYPE_PTR_DEFAULT] = HandleSetPtrDflt,
+ [ACTION_TYPE_TERMINATE] = HandleNoAction,
+ [ACTION_TYPE_SWITCH_VT] = HandleSwitchScreen,
+ [ACTION_TYPE_CTRL_SET] = HandleSetLockControls,
+ [ACTION_TYPE_CTRL_LOCK] = HandleSetLockControls,
+ [ACTION_TYPE_PRIVATE] = HandlePrivate,
+};
+
+/***====================================================================***/
+
+bool
+HandleActionDef(ExprDef *def, struct xkb_keymap *keymap,
+ union xkb_action *action, ActionsInfo *info)
+{
+ ExprDef *arg;
+ const char *str;
+ unsigned handler_type;
+
+ if (def->op != EXPR_ACTION_DECL) {
+ log_err(keymap->ctx, "Expected an action definition, found %s\n",
+ expr_op_type_to_string(def->op));
+ return false;
+ }
+
+ str = xkb_atom_text(keymap->ctx, def->value.action.name);
+ if (!stringToAction(str, &handler_type)) {
+ log_err(keymap->ctx, "Unknown action %s\n", str);
+ return false;
+ }
+
+ /*
+ * Get the default values for this action type, as modified by
+ * statements such as:
+ * latchMods.clearLocks = True;
+ */
+ *action = info->actions[handler_type];
+
+ /*
+ * Now change the action properties as specified for this
+ * particular instance, e.g. "modifiers" and "clearLocks" in:
+ * SetMods(modifiers=Alt,clearLocks);
+ */
+ for (arg = def->value.action.args; arg != NULL;
+ arg = (ExprDef *) arg->common.next) {
+ const ExprDef *value;
+ ExprDef *field, *arrayRtrn;
+ const char *elemRtrn, *fieldRtrn;
+ enum action_field fieldNdx;
+
+ if (arg->op == EXPR_ASSIGN) {
+ field = arg->value.binary.left;
+ value = arg->value.binary.right;
+ }
+ else if (arg->op == EXPR_NOT || arg->op == EXPR_INVERT) {
+ field = arg->value.child;
+ value = &constFalse;
+ }
+ else {
+ field = arg;
+ value = &constTrue;
+ }
+
+ if (!ExprResolveLhs(keymap->ctx, field, &elemRtrn, &fieldRtrn,
+ &arrayRtrn))
+ return false;
+
+ if (elemRtrn) {
+ log_err(keymap->ctx,
+ "Cannot change defaults in an action definition; "
+ "Ignoring attempt to change %s.%s\n",
+ elemRtrn, fieldRtrn);
+ return false;
+ }
+
+ if (!stringToField(fieldRtrn, &fieldNdx)) {
+ log_err(keymap->ctx, "Unknown field name %s\n", fieldRtrn);
+ return false;
+ }
+
+ if (!handleAction[handler_type](keymap, action, fieldNdx, arrayRtrn,
+ value))
+ return false;
+ }
+
+ return true;
+}
+
+
+bool
+SetActionField(struct xkb_keymap *keymap, const char *elem, const char *field,
+ ExprDef *array_ndx, ExprDef *value, ActionsInfo *info)
+{
+ unsigned action;
+ enum action_field action_field;
+
+ if (!stringToAction(elem, &action))
+ return false;
+
+ if (!stringToField(field, &action_field)) {
+ log_err(keymap->ctx, "\"%s\" is not a legal field name\n", field);
+ return false;
+ }
+
+ return handleAction[action](keymap, &info->actions[action],
+ action_field, array_ndx, value);
+}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/action.h b/src/3rdparty/xkbcommon/src/xkbcomp/action.h
new file mode 100644
index 0000000000..82915ef57d
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/action.h
@@ -0,0 +1,53 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#ifndef XKBCOMP_ACTION_H
+#define XKBCOMP_ACTION_H
+
+/*
+ * This struct contains the default values which every new action
+ * (e.g. in an interpret statement) starts off with. It can be
+ * modified within the files (see calls to SetActionField).
+ */
+typedef struct {
+ union xkb_action actions[_ACTION_TYPE_NUM_ENTRIES];
+} ActionsInfo;
+
+ActionsInfo *
+NewActionsInfo(void);
+
+void
+FreeActionsInfo(ActionsInfo *info);
+
+bool
+HandleActionDef(ExprDef *def, struct xkb_keymap *keymap,
+ union xkb_action *action, ActionsInfo *info);
+
+bool
+SetActionField(struct xkb_keymap *keymap, const char *elem, const char *field,
+ ExprDef *array_ndx, ExprDef *value, ActionsInfo *info);
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c
new file mode 100644
index 0000000000..c9b7cb0a3e
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c
@@ -0,0 +1,793 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+/*
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ * Ran Benita <ran234@gmail.com>
+ */
+
+#include "xkbcomp-priv.h"
+#include "ast-build.h"
+#include "parser-priv.h"
+#include "include.h"
+
+ParseCommon *
+AppendStmt(ParseCommon *to, ParseCommon *append)
+{
+ ParseCommon *iter;
+
+ if (!to)
+ return append;
+
+ for (iter = to; iter->next; iter = iter->next);
+
+ iter->next = append;
+ return to;
+}
+
+ExprDef *
+ExprCreate(enum expr_op_type op, enum expr_value_type type)
+{
+ ExprDef *expr = malloc(sizeof(*expr));
+ if (!expr)
+ return NULL;
+
+ expr->common.type = STMT_EXPR;
+ expr->common.next = NULL;
+ expr->op = op;
+ expr->value_type = type;
+
+ return expr;
+}
+
+ExprDef *
+ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
+ ExprDef *child)
+{
+ ExprDef *expr = malloc(sizeof(*expr));
+ if (!expr)
+ return NULL;
+
+ expr->common.type = STMT_EXPR;
+ expr->common.next = NULL;
+ expr->op = op;
+ expr->value_type = type;
+ expr->value.child = child;
+
+ return expr;
+}
+
+ExprDef *
+ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
+{
+ ExprDef *expr = malloc(sizeof(*expr));
+ if (!expr)
+ return NULL;
+
+ expr->common.type = STMT_EXPR;
+ expr->common.next = NULL;
+ expr->op = op;
+ if (op == EXPR_ASSIGN || left->value_type == EXPR_TYPE_UNKNOWN)
+ expr->value_type = right->value_type;
+ else if (left->value_type == right->value_type ||
+ right->value_type == EXPR_TYPE_UNKNOWN)
+ expr->value_type = left->value_type;
+ else
+ expr->value_type = EXPR_TYPE_UNKNOWN;
+ expr->value.binary.left = left;
+ expr->value.binary.right = right;
+
+ return expr;
+}
+
+KeycodeDef *
+KeycodeCreate(xkb_atom_t name, int64_t value)
+{
+ KeycodeDef *def = malloc(sizeof(*def));
+ if (!def)
+ return NULL;
+
+ def->common.type = STMT_KEYCODE;
+ def->common.next = NULL;
+ def->name = name;
+ def->value = value;
+
+ return def;
+}
+
+KeyAliasDef *
+KeyAliasCreate(xkb_atom_t alias, xkb_atom_t real)
+{
+ KeyAliasDef *def = malloc(sizeof(*def));
+ if (!def)
+ return NULL;
+
+ def->common.type = STMT_ALIAS;
+ def->common.next = NULL;
+ def->alias = alias;
+ def->real = real;
+
+ return def;
+}
+
+VModDef *
+VModCreate(xkb_atom_t name, ExprDef *value)
+{
+ VModDef *def = malloc(sizeof(*def));
+ if (!def)
+ return NULL;
+
+ def->common.type = STMT_VMOD;
+ def->common.next = NULL;
+ def->name = name;
+ def->value = value;
+
+ return def;
+}
+
+VarDef *
+VarCreate(ExprDef *name, ExprDef *value)
+{
+ VarDef *def = malloc(sizeof(*def));
+ if (!def)
+ return NULL;
+
+ def->common.type = STMT_VAR;
+ def->common.next = NULL;
+ def->name = name;
+ def->value = value;
+
+ return def;
+}
+
+VarDef *
+BoolVarCreate(xkb_atom_t nameToken, unsigned set)
+{
+ ExprDef *name, *value;
+ VarDef *def;
+
+ name = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
+ name->value.str = nameToken;
+ value = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN);
+ value->value.uval = set;
+ def = VarCreate(name, value);
+
+ return def;
+}
+
+InterpDef *
+InterpCreate(char *sym, ExprDef *match)
+{
+ InterpDef *def = malloc(sizeof(*def));
+ if (!def)
+ return NULL;
+
+ def->common.type = STMT_INTERP;
+ def->common.next = NULL;
+ def->sym = sym;
+ def->match = match;
+
+ return def;
+}
+
+KeyTypeDef *
+KeyTypeCreate(xkb_atom_t name, VarDef *body)
+{
+ KeyTypeDef *def = malloc(sizeof(*def));
+ if (!def)
+ return NULL;
+
+ def->common.type = STMT_TYPE;
+ def->common.next = NULL;
+ def->merge = MERGE_DEFAULT;
+ def->name = name;
+ def->body = body;
+
+ return def;
+}
+
+SymbolsDef *
+SymbolsCreate(xkb_atom_t keyName, ExprDef *symbols)
+{
+ SymbolsDef *def = malloc(sizeof(*def));
+ if (!def)
+ return NULL;
+
+ def->common.type = STMT_SYMBOLS;
+ def->common.next = NULL;
+ def->merge = MERGE_DEFAULT;
+ def->keyName = keyName;
+ def->symbols = symbols;
+
+ return def;
+}
+
+GroupCompatDef *
+GroupCompatCreate(int group, ExprDef *val)
+{
+ GroupCompatDef *def = malloc(sizeof(*def));
+ if (!def)
+ return NULL;
+
+ def->common.type = STMT_GROUP_COMPAT;
+ def->common.next = NULL;
+ def->merge = MERGE_DEFAULT;
+ def->group = group;
+ def->def = val;
+
+ return def;
+}
+
+ModMapDef *
+ModMapCreate(uint32_t modifier, ExprDef *keys)
+{
+ ModMapDef *def = malloc(sizeof(*def));
+ if (!def)
+ return NULL;
+
+ def->common.type = STMT_MODMAP;
+ def->common.next = NULL;
+ def->merge = MERGE_DEFAULT;
+ def->modifier = modifier;
+ def->keys = keys;
+
+ return def;
+}
+
+LedMapDef *
+LedMapCreate(xkb_atom_t name, VarDef *body)
+{
+ LedMapDef *def = malloc(sizeof(*def));
+ if (!def)
+ return NULL;
+
+ def->common.type = STMT_LED_MAP;
+ def->common.next = NULL;
+ def->merge = MERGE_DEFAULT;
+ def->name = name;
+ def->body = body;
+
+ return def;
+}
+
+LedNameDef *
+LedNameCreate(int ndx, ExprDef *name, bool virtual)
+{
+ LedNameDef *def = malloc(sizeof(*def));
+ if (!def)
+ return NULL;
+
+ def->common.type = STMT_LED_NAME;
+ def->common.next = NULL;
+ def->merge = MERGE_DEFAULT;
+ def->ndx = ndx;
+ def->name = name;
+ def->virtual = virtual;
+
+ return def;
+}
+
+ExprDef *
+ActionCreate(xkb_atom_t name, ExprDef *args)
+{
+ ExprDef *act = malloc(sizeof(*act));
+ if (!act)
+ return NULL;
+
+ act->common.type = STMT_EXPR;
+ act->common.next = NULL;
+ act->op = EXPR_ACTION_DECL;
+ act->value.action.name = name;
+ act->value.action.args = args;
+
+ return act;
+}
+
+ExprDef *
+CreateKeysymList(char *sym)
+{
+ ExprDef *def;
+
+ def = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS);
+
+ darray_init(def->value.list.syms);
+ darray_init(def->value.list.symsMapIndex);
+ darray_init(def->value.list.symsNumEntries);
+
+ darray_append(def->value.list.syms, sym);
+ darray_append(def->value.list.symsMapIndex, 0);
+ darray_append(def->value.list.symsNumEntries, 1);
+
+ return def;
+}
+
+ExprDef *
+CreateMultiKeysymList(ExprDef *list)
+{
+ size_t nLevels = darray_size(list->value.list.symsMapIndex);
+
+ darray_resize(list->value.list.symsMapIndex, 1);
+ darray_resize(list->value.list.symsNumEntries, 1);
+ darray_item(list->value.list.symsMapIndex, 0) = 0;
+ darray_item(list->value.list.symsNumEntries, 0) = nLevels;
+
+ return list;
+}
+
+ExprDef *
+AppendKeysymList(ExprDef *list, char *sym)
+{
+ size_t nSyms = darray_size(list->value.list.syms);
+
+ darray_append(list->value.list.symsMapIndex, nSyms);
+ darray_append(list->value.list.symsNumEntries, 1);
+ darray_append(list->value.list.syms, sym);
+
+ return list;
+}
+
+ExprDef *
+AppendMultiKeysymList(ExprDef *list, ExprDef *append)
+{
+ size_t nSyms = darray_size(list->value.list.syms);
+ size_t numEntries = darray_size(append->value.list.syms);
+
+ darray_append(list->value.list.symsMapIndex, nSyms);
+ darray_append(list->value.list.symsNumEntries, numEntries);
+ darray_append_items(list->value.list.syms,
+ darray_mem(append->value.list.syms, 0),
+ numEntries);
+
+ darray_resize(append->value.list.syms, 0);
+ FreeStmt(&append->common);
+
+ return list;
+}
+
+static void
+FreeInclude(IncludeStmt *incl);
+
+IncludeStmt *
+IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge)
+{
+ IncludeStmt *incl, *first;
+ char *file, *map, *stmt, *tmp, *extra_data;
+ char nextop;
+
+ incl = first = NULL;
+ file = map = NULL;
+ tmp = str;
+ stmt = strdup_safe(str);
+ while (tmp && *tmp)
+ {
+ if (!ParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
+ goto err;
+
+ /*
+ * Given an RMLVO (here layout) like 'us,,fr', the rules parser
+ * will give out something like 'pc+us+:2+fr:3+inet(evdev)'.
+ * We should just skip the ':2' in this case and leave it to the
+ * appropriate section to deal with the empty group.
+ */
+ if (isempty(file)) {
+ free(file);
+ free(map);
+ free(extra_data);
+ continue;
+ }
+
+ if (first == NULL) {
+ first = incl = malloc(sizeof(*first));
+ } else {
+ incl->next_incl = malloc(sizeof(*first));
+ incl = incl->next_incl;
+ }
+
+ if (!incl) {
+ log_wsgo(ctx,
+ "Allocation failure in IncludeCreate; "
+ "Using only part of the include\n");
+ break;
+ }
+
+ incl->common.type = STMT_INCLUDE;
+ incl->common.next = NULL;
+ incl->merge = merge;
+ incl->stmt = NULL;
+ incl->file = file;
+ incl->map = map;
+ incl->modifier = extra_data;
+ incl->next_incl = NULL;
+
+ if (nextop == '|')
+ merge = MERGE_AUGMENT;
+ else
+ merge = MERGE_OVERRIDE;
+ }
+
+ if (first)
+ first->stmt = stmt;
+ else
+ free(stmt);
+
+ return first;
+
+err:
+ log_err(ctx, "Illegal include statement \"%s\"; Ignored\n", stmt);
+ FreeInclude(first);
+ free(stmt);
+ return NULL;
+}
+
+static void
+EscapeMapName(char *name)
+{
+ /*
+ * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
+ * wildcards.
+ */
+ static const unsigned char legal[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
+ 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
+ };
+
+ if (!name)
+ return;
+
+ while (*name) {
+ if (!(legal[*name / 8] & (1 << (*name % 8))))
+ *name = '_';
+ name++;
+ }
+}
+
+XkbFile *
+XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name,
+ ParseCommon *defs, enum xkb_map_flags flags)
+{
+ XkbFile *file;
+
+ file = calloc(1, sizeof(*file));
+ if (!file)
+ return NULL;
+
+ EscapeMapName(name);
+ file->file_type = type;
+ file->topName = strdup_safe(name);
+ file->name = name;
+ file->defs = defs;
+ file->flags = flags;
+
+ return file;
+}
+
+XkbFile *
+XkbFileFromComponents(struct xkb_context *ctx,
+ const struct xkb_component_names *kkctgs)
+{
+ char *const components[] = {
+ kkctgs->keycodes, kkctgs->types,
+ kkctgs->compat, kkctgs->symbols,
+ };
+ enum xkb_file_type type;
+ IncludeStmt *include = NULL;
+ XkbFile *file = NULL;
+ ParseCommon *defs = NULL;
+
+ for (type = FIRST_KEYMAP_FILE_TYPE; type <= LAST_KEYMAP_FILE_TYPE; type++) {
+ include = IncludeCreate(ctx, components[type], MERGE_DEFAULT);
+ if (!include)
+ goto err;
+
+ file = XkbFileCreate(ctx, type, NULL, &include->common, 0);
+ if (!file) {
+ FreeInclude(include);
+ goto err;
+ }
+
+ defs = AppendStmt(defs, &file->common);
+ }
+
+ file = XkbFileCreate(ctx, FILE_TYPE_KEYMAP, NULL, defs, 0);
+ if (!file)
+ goto err;
+
+ return file;
+
+err:
+ FreeXkbFile((XkbFile *) defs);
+ return NULL;
+}
+
+static void
+FreeExpr(ExprDef *expr)
+{
+ char **sym;
+
+ if (!expr)
+ return;
+
+ switch (expr->op) {
+ case EXPR_ACTION_LIST:
+ case EXPR_NEGATE:
+ case EXPR_UNARY_PLUS:
+ case EXPR_NOT:
+ case EXPR_INVERT:
+ FreeStmt(&expr->value.child->common);
+ break;
+
+ case EXPR_DIVIDE:
+ case EXPR_ADD:
+ case EXPR_SUBTRACT:
+ case EXPR_MULTIPLY:
+ case EXPR_ASSIGN:
+ FreeStmt(&expr->value.binary.left->common);
+ FreeStmt(&expr->value.binary.right->common);
+ break;
+
+ case EXPR_ACTION_DECL:
+ FreeStmt(&expr->value.action.args->common);
+ break;
+
+ case EXPR_ARRAY_REF:
+ FreeStmt(&expr->value.array.entry->common);
+ break;
+
+ case EXPR_KEYSYM_LIST:
+ darray_foreach(sym, expr->value.list.syms)
+ free(*sym);
+ darray_free(expr->value.list.syms);
+ darray_free(expr->value.list.symsMapIndex);
+ darray_free(expr->value.list.symsNumEntries);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+FreeInclude(IncludeStmt *incl)
+{
+ IncludeStmt *next;
+
+ while (incl)
+ {
+ next = incl->next_incl;
+
+ free(incl->file);
+ free(incl->map);
+ free(incl->modifier);
+ free(incl->stmt);
+
+ free(incl);
+ incl = next;
+ }
+}
+
+void
+FreeStmt(ParseCommon *stmt)
+{
+ ParseCommon *next;
+ YYSTYPE u;
+
+ while (stmt)
+ {
+ next = stmt->next;
+ u.any = stmt;
+
+ switch (stmt->type) {
+ case STMT_INCLUDE:
+ FreeInclude((IncludeStmt *) stmt);
+ /* stmt is already free'd here. */
+ stmt = NULL;
+ break;
+ case STMT_EXPR:
+ FreeExpr(u.expr);
+ break;
+ case STMT_VAR:
+ FreeStmt(&u.var->name->common);
+ FreeStmt(&u.var->value->common);
+ break;
+ case STMT_TYPE:
+ FreeStmt(&u.keyType->body->common);
+ break;
+ case STMT_INTERP:
+ free(u.interp->sym);
+ FreeStmt(&u.interp->match->common);
+ FreeStmt(&u.interp->def->common);
+ break;
+ case STMT_VMOD:
+ FreeStmt(&u.vmod->value->common);
+ break;
+ case STMT_SYMBOLS:
+ FreeStmt(&u.syms->symbols->common);
+ break;
+ case STMT_MODMAP:
+ FreeStmt(&u.modMask->keys->common);
+ break;
+ case STMT_GROUP_COMPAT:
+ FreeStmt(&u.groupCompat->def->common);
+ break;
+ case STMT_LED_MAP:
+ FreeStmt(&u.ledMap->body->common);
+ break;
+ case STMT_LED_NAME:
+ FreeStmt(&u.ledName->name->common);
+ break;
+ default:
+ break;
+ }
+
+ free(stmt);
+ stmt = next;
+ }
+}
+
+void
+FreeXkbFile(XkbFile *file)
+{
+ XkbFile *next;
+
+ while (file)
+ {
+ next = (XkbFile *) file->common.next;
+
+ switch (file->file_type) {
+ case FILE_TYPE_KEYMAP:
+ FreeXkbFile((XkbFile *) file->defs);
+ break;
+
+ case FILE_TYPE_TYPES:
+ case FILE_TYPE_COMPAT:
+ case FILE_TYPE_SYMBOLS:
+ case FILE_TYPE_KEYCODES:
+ case FILE_TYPE_GEOMETRY:
+ FreeStmt(file->defs);
+ break;
+
+ default:
+ break;
+ }
+
+ free(file->name);
+ free(file->topName);
+ free(file);
+ file = next;
+ }
+}
+
+static const char *xkb_file_type_strings[_FILE_TYPE_NUM_ENTRIES] = {
+ [FILE_TYPE_KEYCODES] = "xkb_keycodes",
+ [FILE_TYPE_TYPES] = "xkb_types",
+ [FILE_TYPE_COMPAT] = "xkb_compatibility",
+ [FILE_TYPE_SYMBOLS] = "xkb_symbols",
+ [FILE_TYPE_GEOMETRY] = "xkb_geometry",
+ [FILE_TYPE_KEYMAP] = "xkb_keymap",
+ [FILE_TYPE_RULES] = "rules",
+};
+
+const char *
+xkb_file_type_to_string(enum xkb_file_type type)
+{
+ if (type > _FILE_TYPE_NUM_ENTRIES)
+ return "unknown";
+ return xkb_file_type_strings[type];
+}
+
+static const char *stmt_type_strings[_STMT_NUM_VALUES] = {
+ [STMT_UNKNOWN] = "unknown statement",
+ [STMT_INCLUDE] = "include statement",
+ [STMT_KEYCODE] = "key name definition",
+ [STMT_ALIAS] = "key alias definition",
+ [STMT_EXPR] = "expression",
+ [STMT_VAR] = "variable definition",
+ [STMT_TYPE] = "key type definition",
+ [STMT_INTERP] = "symbol interpretation definition",
+ [STMT_VMOD] = "virtual modifiers definition",
+ [STMT_SYMBOLS] = "key symbols definition",
+ [STMT_MODMAP] = "modifier map declaration",
+ [STMT_GROUP_COMPAT] = "group declaration",
+ [STMT_LED_MAP] = "indicator map declaration",
+ [STMT_LED_NAME] = "indicator name declaration",
+};
+
+const char *
+stmt_type_to_string(enum stmt_type type)
+{
+ if (type >= _STMT_NUM_VALUES)
+ return NULL;
+ return stmt_type_strings[type];
+}
+
+static const char *expr_op_type_strings[_EXPR_NUM_VALUES] = {
+ [EXPR_VALUE] = "literal",
+ [EXPR_IDENT] = "identifier",
+ [EXPR_ACTION_DECL] = "action declaration",
+ [EXPR_FIELD_REF] = "field reference",
+ [EXPR_ARRAY_REF] = "array reference",
+ [EXPR_KEYSYM_LIST] = "list of keysyms",
+ [EXPR_ACTION_LIST] = "list of actions",
+ [EXPR_ADD] = "addition",
+ [EXPR_SUBTRACT] = "subtraction",
+ [EXPR_MULTIPLY] = "multiplication",
+ [EXPR_DIVIDE] = "division",
+ [EXPR_ASSIGN] = "assignment",
+ [EXPR_NOT] = "logical negation",
+ [EXPR_NEGATE] = "arithmetic negation",
+ [EXPR_INVERT] = "bitwise inversion",
+ [EXPR_UNARY_PLUS] = "unary plus",
+};
+
+const char *
+expr_op_type_to_string(enum expr_op_type type)
+{
+ if (type >= _EXPR_NUM_VALUES)
+ return NULL;
+ return expr_op_type_strings[type];
+}
+
+static const char *expr_value_type_strings[_EXPR_TYPE_NUM_VALUES] = {
+ [EXPR_TYPE_UNKNOWN] = "unknown",
+ [EXPR_TYPE_BOOLEAN] = "boolean",
+ [EXPR_TYPE_INT] = "int",
+ [EXPR_TYPE_STRING] = "string",
+ [EXPR_TYPE_ACTION] = "action",
+ [EXPR_TYPE_KEYNAME] = "keyname",
+ [EXPR_TYPE_SYMBOLS] = "symbols",
+};
+
+const char *
+expr_value_type_to_string(enum expr_value_type type)
+{
+ if (type >= _EXPR_TYPE_NUM_VALUES)
+ return NULL;
+ return expr_value_type_strings[type];
+}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h
new file mode 100644
index 0000000000..0ecd124145
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h
@@ -0,0 +1,104 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#ifndef XKBCOMP_AST_BUILD_H
+#define XKBCOMP_AST_BUILD_H
+
+ParseCommon *
+AppendStmt(ParseCommon *to, ParseCommon *append);
+
+ExprDef *
+ExprCreate(enum expr_op_type op, enum expr_value_type type);
+
+ExprDef *
+ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
+ ExprDef *child);
+
+ExprDef *
+ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right);
+
+KeycodeDef *
+KeycodeCreate(xkb_atom_t name, int64_t value);
+
+KeyAliasDef *
+KeyAliasCreate(xkb_atom_t alias, xkb_atom_t real);
+
+VModDef *
+VModCreate(xkb_atom_t name, ExprDef *value);
+
+VarDef *
+VarCreate(ExprDef *name, ExprDef *value);
+
+VarDef *
+BoolVarCreate(xkb_atom_t nameToken, unsigned set);
+
+InterpDef *
+InterpCreate(char *sym, ExprDef *match);
+
+KeyTypeDef *
+KeyTypeCreate(xkb_atom_t name, VarDef *body);
+
+SymbolsDef *
+SymbolsCreate(xkb_atom_t keyName, ExprDef *symbols);
+
+GroupCompatDef *
+GroupCompatCreate(int group, ExprDef *def);
+
+ModMapDef *
+ModMapCreate(uint32_t modifier, ExprDef *keys);
+
+LedMapDef *
+LedMapCreate(xkb_atom_t name, VarDef *body);
+
+LedNameDef *
+LedNameCreate(int ndx, ExprDef *name, bool virtual);
+
+ExprDef *
+ActionCreate(xkb_atom_t name, ExprDef *args);
+
+ExprDef *
+CreateMultiKeysymList(ExprDef *list);
+
+ExprDef *
+CreateKeysymList(char *sym);
+
+ExprDef *
+AppendMultiKeysymList(ExprDef *list, ExprDef *append);
+
+ExprDef *
+AppendKeysymList(ExprDef *list, char *sym);
+
+IncludeStmt *
+IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge);
+
+XkbFile *
+XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name,
+ ParseCommon *defs, unsigned flags);
+
+void
+FreeStmt(ParseCommon *stmt);
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast.h b/src/3rdparty/xkbcommon/src/xkbcomp/ast.h
new file mode 100644
index 0000000000..c430a772ae
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast.h
@@ -0,0 +1,295 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+/*
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef XKBCOMP_AST_H
+#define XKBCOMP_AST_H
+
+enum xkb_file_type {
+ /* Component files, by order of compilation. */
+ FILE_TYPE_KEYCODES = 0,
+ FILE_TYPE_TYPES = 1,
+ FILE_TYPE_COMPAT = 2,
+ FILE_TYPE_SYMBOLS = 3,
+ /* Geometry is not compiled any more. */
+ FILE_TYPE_GEOMETRY = 4,
+
+ /* A top level file which includes the above files. */
+ FILE_TYPE_KEYMAP,
+
+/* File types which must be found in a keymap file. */
+#define FIRST_KEYMAP_FILE_TYPE FILE_TYPE_KEYCODES
+#define LAST_KEYMAP_FILE_TYPE FILE_TYPE_SYMBOLS
+
+ /* This one doesn't mix with the others, but useful here as well. */
+ FILE_TYPE_RULES,
+
+ _FILE_TYPE_NUM_ENTRIES
+};
+
+enum stmt_type {
+ STMT_UNKNOWN = 0,
+ STMT_INCLUDE,
+ STMT_KEYCODE,
+ STMT_ALIAS,
+ STMT_EXPR,
+ STMT_VAR,
+ STMT_TYPE,
+ STMT_INTERP,
+ STMT_VMOD,
+ STMT_SYMBOLS,
+ STMT_MODMAP,
+ STMT_GROUP_COMPAT,
+ STMT_LED_MAP,
+ STMT_LED_NAME,
+
+ _STMT_NUM_VALUES
+};
+
+enum expr_value_type {
+ EXPR_TYPE_UNKNOWN = 0,
+ EXPR_TYPE_BOOLEAN,
+ EXPR_TYPE_INT,
+ EXPR_TYPE_STRING,
+ EXPR_TYPE_ACTION,
+ EXPR_TYPE_KEYNAME,
+ EXPR_TYPE_SYMBOLS,
+
+ _EXPR_TYPE_NUM_VALUES
+};
+
+enum expr_op_type {
+ EXPR_VALUE,
+ EXPR_IDENT,
+ EXPR_ACTION_DECL,
+ EXPR_FIELD_REF,
+ EXPR_ARRAY_REF,
+ EXPR_KEYSYM_LIST,
+ EXPR_ACTION_LIST,
+ EXPR_ADD,
+ EXPR_SUBTRACT,
+ EXPR_MULTIPLY,
+ EXPR_DIVIDE,
+ EXPR_ASSIGN,
+ EXPR_NOT,
+ EXPR_NEGATE,
+ EXPR_INVERT,
+ EXPR_UNARY_PLUS,
+
+ _EXPR_NUM_VALUES
+};
+
+enum merge_mode {
+ MERGE_DEFAULT,
+ MERGE_AUGMENT,
+ MERGE_OVERRIDE,
+ MERGE_REPLACE,
+};
+
+const char *
+xkb_file_type_to_string(enum xkb_file_type type);
+
+const char *
+stmt_type_to_string(enum stmt_type type);
+
+const char *
+expr_op_type_to_string(enum expr_op_type type);
+
+const char *
+expr_value_type_to_string(enum expr_value_type type);
+
+typedef struct _ParseCommon {
+ enum stmt_type type;
+ struct _ParseCommon *next;
+} ParseCommon;
+
+typedef struct _IncludeStmt {
+ ParseCommon common;
+ enum merge_mode merge;
+ char *stmt;
+ char *file;
+ char *map;
+ char *modifier;
+ struct _IncludeStmt *next_incl;
+} IncludeStmt;
+
+typedef struct _Expr {
+ ParseCommon common;
+ enum expr_op_type op;
+ enum expr_value_type value_type;
+ union {
+ struct {
+ struct _Expr *left;
+ struct _Expr *right;
+ } binary;
+ struct {
+ xkb_atom_t element;
+ xkb_atom_t field;
+ } field;
+ struct {
+ xkb_atom_t element;
+ xkb_atom_t field;
+ struct _Expr *entry;
+ } array;
+ struct {
+ xkb_atom_t name;
+ struct _Expr *args;
+ } action;
+ struct {
+ darray(char *) syms;
+ darray(int) symsMapIndex;
+ darray(unsigned int) symsNumEntries;
+ } list;
+ struct _Expr *child;
+ xkb_atom_t str;
+ unsigned uval;
+ int ival;
+ xkb_atom_t keyName;
+ } value;
+} ExprDef;
+
+typedef struct {
+ ParseCommon common;
+ enum merge_mode merge;
+ ExprDef *name;
+ ExprDef *value;
+} VarDef;
+
+typedef struct {
+ ParseCommon common;
+ enum merge_mode merge;
+ xkb_atom_t name;
+ ExprDef *value;
+} VModDef;
+
+typedef struct {
+ ParseCommon common;
+ enum merge_mode merge;
+ xkb_atom_t name;
+ int64_t value;
+} KeycodeDef;
+
+typedef struct {
+ ParseCommon common;
+ enum merge_mode merge;
+ xkb_atom_t alias;
+ xkb_atom_t real;
+} KeyAliasDef;
+
+typedef struct {
+ ParseCommon common;
+ enum merge_mode merge;
+ xkb_atom_t name;
+ VarDef *body;
+} KeyTypeDef;
+
+typedef struct {
+ ParseCommon common;
+ enum merge_mode merge;
+ xkb_atom_t keyName;
+ ExprDef *symbols;
+} SymbolsDef;
+
+typedef struct {
+ ParseCommon common;
+ enum merge_mode merge;
+ xkb_atom_t modifier;
+ ExprDef *keys;
+} ModMapDef;
+
+typedef struct {
+ ParseCommon common;
+ enum merge_mode merge;
+ int group;
+ ExprDef *def;
+} GroupCompatDef;
+
+typedef struct {
+ ParseCommon common;
+ enum merge_mode merge;
+ char *sym;
+ ExprDef *match;
+ VarDef *def;
+} InterpDef;
+
+typedef struct {
+ ParseCommon common;
+ enum merge_mode merge;
+ int ndx;
+ ExprDef *name;
+ bool virtual;
+} LedNameDef;
+
+typedef struct {
+ ParseCommon common;
+ enum merge_mode merge;
+ xkb_atom_t name;
+ VarDef *body;
+} LedMapDef;
+
+enum xkb_map_flags {
+ MAP_IS_DEFAULT = (1 << 0),
+ MAP_IS_PARTIAL = (1 << 1),
+ MAP_IS_HIDDEN = (1 << 2),
+ MAP_HAS_ALPHANUMERIC = (1 << 3),
+ MAP_HAS_MODIFIER = (1 << 4),
+ MAP_HAS_KEYPAD = (1 << 5),
+ MAP_HAS_FN = (1 << 6),
+ MAP_IS_ALTGR = (1 << 7),
+};
+
+typedef struct {
+ ParseCommon common;
+ enum xkb_file_type file_type;
+ char *topName;
+ char *name;
+ ParseCommon *defs;
+ enum xkb_map_flags flags;
+} XkbFile;
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/compat.c b/src/3rdparty/xkbcommon/src/xkbcomp/compat.c
new file mode 100644
index 0000000000..5682895430
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/compat.c
@@ -0,0 +1,1078 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+/*
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "xkbcomp-priv.h"
+#include "text.h"
+#include "expr.h"
+#include "action.h"
+#include "vmod.h"
+#include "include.h"
+
+/*
+ * The xkb_compat section
+ * =====================
+ * This section is the third to be processed, after xkb_keycodes and
+ * xkb_types.
+ *
+ * Interpret statements
+ * --------------------
+ * Statements of the form:
+ * interpret Num_Lock+Any { ... }
+ * interpret Shift_Lock+AnyOf(Shift+Lock) { ... }
+ *
+ * The xkb_symbols section (see symbols.c) allows the keymap author to do,
+ * among other things, the following for each key:
+ * - Bind an action, like SetMods or LockGroup, to the key. Actions, like
+ * symbols, are specified for each level of each group in the key
+ * separately.
+ * - Add a virtual modifier to the key's virtual modifier mapping (vmodmap).
+ * - Specify whether the key should repeat or not.
+ *
+ * However, doing this for each key (or level) is tedious and inflexible.
+ * Interpret's are a mechanism to apply these settings to a bunch of
+ * keys/levels at once.
+ *
+ * Each interpret specifies a condition by which it attaches to certain
+ * levels. The condition consists of two parts:
+ * - A keysym. If the level has a different (or more than one) keysym, the
+ * match failes. Leaving out the keysym is equivalent to using the
+ * NoSymbol keysym, which always matches successfully.
+ * - A modifier predicate. The predicate consists of a matching operation
+ * and a mask of (real) modifiers. The modifers are matched against the
+ * key's modifier map (modmap). The matching operation can be one of the
+ * following:
+ * + AnyOfOrNone - The modmap must either be empty or include at least
+ * one of the specified modifiers.
+ * + AnyOf - The modmap must include at least one of the specified
+ * modifiers.
+ * + NoneOf - The modmap must not include any of the specified modifiers.
+ * + AllOf - The modmap must include all of the specified modifiers (but
+ * may include others as well).
+ * + Exactly - The modmap must be exactly the same as the specified
+ * modifiers.
+ * Leaving out the predicate is equivalent to usign AnyOfOrNone while
+ * specifying all modifiers. Leaving out just the matching condtition
+ * is equivalent to using Exactly.
+ * An interpret may also include "useModMapMods = level1;" - see below.
+ *
+ * If a level fulfils the conditions of several interpret's, only the
+ * most specific one is used:
+ * - A specific keysym will always match before a generic NoSymbol
+ * condition.
+ * - If the keysyms are the same, the interpret with the more specific
+ * matching operation is used. The above list is sorted from least to
+ * most specific.
+ * - If both the keysyms and the matching operations are the same (but the
+ * modifiers are different), the first interpret is used.
+ *
+ * As described above, once an interpret "attaches" to a level, it can bind
+ * an action to that level, add one virtual modifier to the key's vmodmap,
+ * or set the key's repeat setting. You should note the following:
+ * - The key repeat is a property of the entire key; it is not level-specific.
+ * In order to avoid confusion, it is only inspected for the first level of
+ * the first group; the interpret's repeat setting is ignored when applied
+ * to other levels.
+ * - If one of the above fields was set directly for a key in xkb_symbols,
+ * the explicit setting takes precedence over the interpret.
+ *
+ * The body of the statment may include statements of the following
+ * forms (all of which are optional):
+ *
+ * - useModMapMods statement:
+ * useModMapMods = level1;
+ *
+ * When set to 'level1', the interpret will only match levels which are
+ * the first level of the first group of the keys. This can be useful in
+ * conjunction with e.g. a virtualModifier statement.
+ *
+ * - action statement:
+ * action = LockMods(modifiers=NumLock);
+ *
+ * Bind this action to the matching levels.
+ *
+ * - virtual modifier statement:
+ * virtualModifier = NumLock;
+ *
+ * Add this virtual modifier to the key's vmodmap. The given virtual
+ * modifier must be declared at the top level of the file with a
+ * virtual_modifiers statement, e.g.:
+ * virtual_modifiers NumLock;
+ *
+ * - repeat statement:
+ * repeat = True;
+ *
+ * Set whether the key should repeat or not. Must be a boolean value.
+ *
+ * Led map statements
+ * ------------------------
+ * Statements of the form:
+ * indicator "Shift Lock" { ... }
+ *
+ * This statement specifies the behavior and binding of the LED (a.k.a
+ * indicator) with the given name ("Shift Lock" above). The name should
+ * have been declared previously in the xkb_keycodes section (see Led
+ * name statement), and given an index there. If it wasn't, it is created
+ * with the next free index.
+ * The body of the statement describes the conditions of the keyboard
+ * state which will cause the LED to be lit. It may include the following
+ * statements:
+ *
+ * - modifiers statment:
+ * modifiers = ScrollLock;
+ *
+ * If the given modifiers are in the required state (see below), the
+ * led is lit.
+ *
+ * - whichModifierState statment:
+ * whichModState = Latched + Locked;
+ *
+ * Can be any combination of:
+ * base, latched, locked, effective
+ * any (i.e. all of the above)
+ * none (i.e. none of the above)
+ * compat (legacy value, treated as effective)
+ * This will cause the respective portion of the modifer state (see
+ * struct xkb_state) to be matched against the modifiers given in the
+ * "modifiers" statement.
+ *
+ * Here's a simple example:
+ * indicator "Num Lock" {
+ * modifiers = NumLock;
+ * whichModState = Locked;
+ * };
+ * Whenever the NumLock modifier is locked, the Num Lock LED will light
+ * up.
+ *
+ * - groups statment:
+ * groups = All - group1;
+ *
+ * If the given groups are in the required state (see below), the led
+ * is lit.
+ *
+ * - whichGroupState statment:
+ * whichGroupState = Effective;
+ *
+ * Can be any combination of:
+ * base, latched, locked, effective
+ * any (i.e. all of the above)
+ * none (i.e. none of the above)
+ * This will cause the respective portion of the group state (see
+ * struct xkb_state) to be matched against the groups given in the
+ * "groups" statement.
+ *
+ * Note: the above conditions are disjunctive, i.e. if any of them are
+ * satisfied the led is lit.
+ *
+ * Virtual modifier statements
+ * ---------------------------
+ * Statements of the form:
+ * virtual_modifiers LControl;
+ *
+ * Can appear in the xkb_types, xkb_compat, xkb_symbols sections.
+ * TODO
+ *
+ * Effect on keymap
+ * ----------------
+ * After all of the xkb_compat sections have been compiled, the following
+ * members of struct xkb_keymap are finalized:
+ * darray(struct xkb_sym_interpret) sym_interprets;
+ * darray(struct xkb_led) leds;
+ * char *compat_section_name;
+ * TODO: virtual modifiers.
+ */
+
+enum si_field {
+ SI_FIELD_VIRTUAL_MOD = (1 << 0),
+ SI_FIELD_ACTION = (1 << 1),
+ SI_FIELD_AUTO_REPEAT = (1 << 2),
+ SI_FIELD_LEVEL_ONE_ONLY = (1 << 3),
+};
+
+typedef struct {
+ enum si_field defined;
+ enum merge_mode merge;
+
+ struct xkb_sym_interpret interp;
+} SymInterpInfo;
+
+enum led_field {
+ LED_FIELD_MODS = (1 << 0),
+ LED_FIELD_GROUPS = (1 << 1),
+ LED_FIELD_CTRLS = (1 << 2),
+};
+
+typedef struct {
+ enum led_field defined;
+ enum merge_mode merge;
+
+ struct xkb_led led;
+} LedInfo;
+
+typedef struct {
+ char *name;
+ int errorCount;
+ SymInterpInfo default_interp;
+ darray(SymInterpInfo) interps;
+ LedInfo default_led;
+ darray(LedInfo) leds;
+ ActionsInfo *actions;
+ struct xkb_keymap *keymap;
+} CompatInfo;
+
+static const char *
+siText(SymInterpInfo *si, CompatInfo *info)
+{
+ char *buf = xkb_context_get_buffer(info->keymap->ctx, 128);
+
+ if (si == &info->default_interp)
+ return "default";
+
+ snprintf(buf, 128, "%s+%s(%s)",
+ KeysymText(info->keymap->ctx, si->interp.sym),
+ SIMatchText(si->interp.match),
+ ModMaskText(info->keymap, si->interp.mods));
+
+ return buf;
+}
+
+static inline bool
+ReportSINotArray(CompatInfo *info, SymInterpInfo *si, const char *field)
+{
+ return ReportNotArray(info->keymap->ctx, "symbol interpretation", field,
+ siText(si, info));
+}
+
+static inline bool
+ReportSIBadType(CompatInfo *info, SymInterpInfo *si, const char *field,
+ const char *wanted)
+{
+ return ReportBadType(info->keymap->ctx, "symbol interpretation", field,
+ siText(si, info), wanted);
+}
+
+static inline bool
+ReportLedBadType(CompatInfo *info, LedInfo *ledi, const char *field,
+ const char *wanted)
+{
+ return ReportBadType(info->keymap->ctx, "indicator map", field,
+ xkb_atom_text(info->keymap->ctx, ledi->led.name),
+ wanted);
+}
+
+static inline bool
+ReportLedNotArray(CompatInfo *info, LedInfo *ledi, const char *field)
+{
+ return ReportNotArray(info->keymap->ctx, "indicator map", field,
+ xkb_atom_text(info->keymap->ctx, ledi->led.name));
+}
+
+static void
+InitCompatInfo(CompatInfo *info, struct xkb_keymap *keymap,
+ ActionsInfo *actions)
+{
+ memset(info, 0, sizeof(*info));
+ info->keymap = keymap;
+ info->actions = actions;
+ info->default_interp.merge = MERGE_OVERRIDE;
+ info->default_interp.interp.virtual_mod = XKB_MOD_INVALID;
+ info->default_led.merge = MERGE_OVERRIDE;
+}
+
+static void
+ClearCompatInfo(CompatInfo *info)
+{
+ free(info->name);
+ darray_free(info->interps);
+ darray_free(info->leds);
+}
+
+static SymInterpInfo *
+FindMatchingInterp(CompatInfo *info, SymInterpInfo *new)
+{
+ SymInterpInfo *old;
+
+ darray_foreach(old, info->interps)
+ if (old->interp.sym == new->interp.sym &&
+ old->interp.mods == new->interp.mods &&
+ old->interp.match == new->interp.match)
+ return old;
+
+ return NULL;
+}
+
+static bool
+UseNewInterpField(enum si_field field, SymInterpInfo *old, SymInterpInfo *new,
+ bool report, enum si_field *collide)
+{
+ if (!(old->defined & field))
+ return true;
+
+ if (new->defined & field) {
+ if (report)
+ *collide |= field;
+
+ if (new->merge != MERGE_AUGMENT)
+ return true;
+ }
+
+ return false;
+}
+
+static bool
+AddInterp(CompatInfo *info, SymInterpInfo *new, bool same_file)
+{
+ SymInterpInfo *old = FindMatchingInterp(info, new);
+ if (old) {
+ const int verbosity = xkb_context_get_log_verbosity(info->keymap->ctx);
+ const bool report = (same_file && verbosity > 0) || verbosity > 9;
+ enum si_field collide = 0;
+
+ if (new->merge == MERGE_REPLACE) {
+ if (report)
+ log_warn(info->keymap->ctx,
+ "Multiple definitions for \"%s\"; "
+ "Earlier interpretation ignored\n",
+ siText(new, info));
+ *old = *new;
+ return true;
+ }
+
+ if (UseNewInterpField(SI_FIELD_VIRTUAL_MOD, old, new, report,
+ &collide)) {
+ old->interp.virtual_mod = new->interp.virtual_mod;
+ old->defined |= SI_FIELD_VIRTUAL_MOD;
+ }
+ if (UseNewInterpField(SI_FIELD_ACTION, old, new, report,
+ &collide)) {
+ old->interp.action = new->interp.action;
+ old->defined |= SI_FIELD_ACTION;
+ }
+ if (UseNewInterpField(SI_FIELD_AUTO_REPEAT, old, new, report,
+ &collide)) {
+ old->interp.repeat = new->interp.repeat;
+ old->defined |= SI_FIELD_AUTO_REPEAT;
+ }
+ if (UseNewInterpField(SI_FIELD_LEVEL_ONE_ONLY, old, new, report,
+ &collide)) {
+ old->interp.level_one_only = new->interp.level_one_only;
+ old->defined |= SI_FIELD_LEVEL_ONE_ONLY;
+ }
+
+ if (collide) {
+ log_warn(info->keymap->ctx,
+ "Multiple interpretations of \"%s\"; "
+ "Using %s definition for duplicate fields\n",
+ siText(new, info),
+ (new->merge != MERGE_AUGMENT ? "last" : "first"));
+ }
+
+ return true;
+ }
+
+ darray_append(info->interps, *new);
+ return true;
+}
+
+/***====================================================================***/
+
+static bool
+ResolveStateAndPredicate(ExprDef *expr, enum xkb_match_operation *pred_rtrn,
+ xkb_mod_mask_t *mods_rtrn, CompatInfo *info)
+{
+ if (expr == NULL) {
+ *pred_rtrn = MATCH_ANY_OR_NONE;
+ *mods_rtrn = MOD_REAL_MASK_ALL;
+ return true;
+ }
+
+ *pred_rtrn = MATCH_EXACTLY;
+ if (expr->op == EXPR_ACTION_DECL) {
+ const char *pred_txt = xkb_atom_text(info->keymap->ctx,
+ expr->value.action.name);
+ if (!LookupString(symInterpretMatchMaskNames, pred_txt, pred_rtrn)) {
+ log_err(info->keymap->ctx,
+ "Illegal modifier predicate \"%s\"; Ignored\n", pred_txt);
+ return false;
+ }
+ expr = expr->value.action.args;
+ }
+ else if (expr->op == EXPR_IDENT) {
+ const char *pred_txt = xkb_atom_text(info->keymap->ctx,
+ expr->value.str);
+ if (pred_txt && istreq(pred_txt, "any")) {
+ *pred_rtrn = MATCH_ANY;
+ *mods_rtrn = MOD_REAL_MASK_ALL;
+ return true;
+ }
+ }
+
+ return ExprResolveModMask(info->keymap, expr, MOD_REAL, mods_rtrn);
+}
+
+/***====================================================================***/
+
+static bool
+UseNewLEDField(enum led_field field, LedInfo *old, LedInfo *new,
+ bool report, enum led_field *collide)
+{
+ if (!(old->defined & field))
+ return true;
+
+ if (new->defined & field) {
+ if (report)
+ *collide |= field;
+
+ if (new->merge != MERGE_AUGMENT)
+ return true;
+ }
+
+ return false;
+}
+
+static bool
+AddLedMap(CompatInfo *info, LedInfo *new, bool same_file)
+{
+ LedInfo *old;
+ enum led_field collide;
+ struct xkb_context *ctx = info->keymap->ctx;
+ const int verbosity = xkb_context_get_log_verbosity(ctx);
+ const bool report = (same_file && verbosity > 0) || verbosity > 9;
+
+ darray_foreach(old, info->leds) {
+ if (old->led.name != new->led.name)
+ continue;
+
+ if (old->led.mods.mods == new->led.mods.mods &&
+ old->led.groups == new->led.groups &&
+ old->led.ctrls == new->led.ctrls &&
+ old->led.which_mods == new->led.which_mods &&
+ old->led.which_groups == new->led.which_groups) {
+ old->defined |= new->defined;
+ return true;
+ }
+
+ if (new->merge == MERGE_REPLACE) {
+ if (report)
+ log_warn(info->keymap->ctx,
+ "Map for indicator %s redefined; "
+ "Earlier definition ignored\n",
+ xkb_atom_text(ctx, old->led.name));
+ *old = *new;
+ return true;
+ }
+
+ collide = 0;
+ if (UseNewLEDField(LED_FIELD_MODS, old, new, report, &collide)) {
+ old->led.which_mods = new->led.which_mods;
+ old->led.mods = new->led.mods;
+ old->defined |= LED_FIELD_MODS;
+ }
+ if (UseNewLEDField(LED_FIELD_GROUPS, old, new, report, &collide)) {
+ old->led.which_groups = new->led.which_groups;
+ old->led.groups = new->led.groups;
+ old->defined |= LED_FIELD_GROUPS;
+ }
+ if (UseNewLEDField(LED_FIELD_CTRLS, old, new, report, &collide)) {
+ old->led.ctrls = new->led.ctrls;
+ old->defined |= LED_FIELD_CTRLS;
+ }
+
+ if (collide) {
+ log_warn(info->keymap->ctx,
+ "Map for indicator %s redefined; "
+ "Using %s definition for duplicate fields\n",
+ xkb_atom_text(ctx, old->led.name),
+ (new->merge == MERGE_AUGMENT ? "first" : "last"));
+ }
+
+ return true;
+ }
+
+ darray_append(info->leds, *new);
+ return true;
+}
+
+static void
+MergeIncludedCompatMaps(CompatInfo *into, CompatInfo *from,
+ enum merge_mode merge)
+{
+ SymInterpInfo *si;
+ LedInfo *ledi;
+
+ if (from->errorCount > 0) {
+ into->errorCount += from->errorCount;
+ return;
+ }
+
+ if (into->name == NULL) {
+ into->name = from->name;
+ from->name = NULL;
+ }
+
+ darray_foreach(si, from->interps) {
+ si->merge = (merge == MERGE_DEFAULT ? si->merge : merge);
+ if (!AddInterp(into, si, false))
+ into->errorCount++;
+ }
+
+ darray_foreach(ledi, from->leds) {
+ ledi->merge = (merge == MERGE_DEFAULT ? ledi->merge : merge);
+ if (!AddLedMap(into, ledi, false))
+ into->errorCount++;
+ }
+}
+
+static void
+HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge);
+
+static bool
+HandleIncludeCompatMap(CompatInfo *info, IncludeStmt *include)
+{
+ CompatInfo included;
+
+ InitCompatInfo(&included, info->keymap, info->actions);
+ included.name = include->stmt;
+ include->stmt = NULL;
+
+ for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) {
+ CompatInfo next_incl;
+ XkbFile *file;
+
+ file = ProcessIncludeFile(info->keymap->ctx, stmt, FILE_TYPE_COMPAT);
+ if (!file) {
+ info->errorCount += 10;
+ ClearCompatInfo(&included);
+ return false;
+ }
+
+ InitCompatInfo(&next_incl, info->keymap, info->actions);
+ next_incl.default_interp = info->default_interp;
+ next_incl.default_interp.merge = stmt->merge;
+ next_incl.default_led = info->default_led;
+ next_incl.default_led.merge = stmt->merge;
+
+ HandleCompatMapFile(&next_incl, file, MERGE_OVERRIDE);
+
+ MergeIncludedCompatMaps(&included, &next_incl, stmt->merge);
+
+ ClearCompatInfo(&next_incl);
+ FreeXkbFile(file);
+ }
+
+ MergeIncludedCompatMaps(info, &included, include->merge);
+ ClearCompatInfo(&included);
+
+ return (info->errorCount == 0);
+}
+
+static bool
+SetInterpField(CompatInfo *info, SymInterpInfo *si, const char *field,
+ ExprDef *arrayNdx, ExprDef *value)
+{
+ struct xkb_keymap *keymap = info->keymap;
+ xkb_mod_index_t ndx;
+
+ if (istreq(field, "action")) {
+ if (arrayNdx)
+ return ReportSINotArray(info, si, field);
+
+ if (!HandleActionDef(value, keymap, &si->interp.action, info->actions))
+ return false;
+
+ si->defined |= SI_FIELD_ACTION;
+ }
+ else if (istreq(field, "virtualmodifier") ||
+ istreq(field, "virtualmod")) {
+ if (arrayNdx)
+ return ReportSINotArray(info, si, field);
+
+ if (!ExprResolveMod(keymap, value, MOD_VIRT, &ndx))
+ return ReportSIBadType(info, si, field, "virtual modifier");
+
+ si->interp.virtual_mod = ndx;
+ si->defined |= SI_FIELD_VIRTUAL_MOD;
+ }
+ else if (istreq(field, "repeat")) {
+ bool set;
+
+ if (arrayNdx)
+ return ReportSINotArray(info, si, field);
+
+ if (!ExprResolveBoolean(keymap->ctx, value, &set))
+ return ReportSIBadType(info, si, field, "boolean");
+
+ si->interp.repeat = set;
+
+ si->defined |= SI_FIELD_AUTO_REPEAT;
+ }
+ else if (istreq(field, "locking")) {
+ log_dbg(info->keymap->ctx,
+ "The \"locking\" field in symbol interpretation is unsupported; "
+ "Ignored\n");
+ }
+ else if (istreq(field, "usemodmap") ||
+ istreq(field, "usemodmapmods")) {
+ unsigned int val;
+
+ if (arrayNdx)
+ return ReportSINotArray(info, si, field);
+
+ if (!ExprResolveEnum(keymap->ctx, value, &val, useModMapValueNames))
+ return ReportSIBadType(info, si, field, "level specification");
+
+ si->interp.level_one_only = !!val;
+ si->defined |= SI_FIELD_LEVEL_ONE_ONLY;
+ }
+ else {
+ return ReportBadField(keymap->ctx, "symbol interpretation", field,
+ siText(si, info));
+ }
+
+ return true;
+}
+
+static bool
+SetLedMapField(CompatInfo *info, LedInfo *ledi, const char *field,
+ ExprDef *arrayNdx, ExprDef *value)
+{
+ bool ok = true;
+ struct xkb_keymap *keymap = info->keymap;
+
+ if (istreq(field, "modifiers") || istreq(field, "mods")) {
+ if (arrayNdx)
+ return ReportLedNotArray(info, ledi, field);
+
+ if (!ExprResolveModMask(keymap, value, MOD_BOTH, &ledi->led.mods.mods))
+ return ReportLedBadType(info, ledi, field, "modifier mask");
+
+ ledi->defined |= LED_FIELD_MODS;
+ }
+ else if (istreq(field, "groups")) {
+ unsigned int mask;
+
+ if (arrayNdx)
+ return ReportLedNotArray(info, ledi, field);
+
+ if (!ExprResolveMask(keymap->ctx, value, &mask, groupMaskNames))
+ return ReportLedBadType(info, ledi, field, "group mask");
+
+ ledi->led.groups = mask;
+ ledi->defined |= LED_FIELD_GROUPS;
+ }
+ else if (istreq(field, "controls") || istreq(field, "ctrls")) {
+ unsigned int mask;
+
+ if (arrayNdx)
+ return ReportLedNotArray(info, ledi, field);
+
+ if (!ExprResolveMask(keymap->ctx, value, &mask, ctrlMaskNames))
+ return ReportLedBadType(info, ledi, field, "controls mask");
+
+ ledi->led.ctrls = mask;
+ ledi->defined |= LED_FIELD_CTRLS;
+ }
+ else if (istreq(field, "allowexplicit")) {
+ log_dbg(info->keymap->ctx,
+ "The \"allowExplicit\" field in indicator statements is unsupported; "
+ "Ignored\n");
+ }
+ else if (istreq(field, "whichmodstate") ||
+ istreq(field, "whichmodifierstate")) {
+ unsigned int mask;
+
+ if (arrayNdx)
+ return ReportLedNotArray(info, ledi, field);
+
+ if (!ExprResolveMask(keymap->ctx, value, &mask,
+ modComponentMaskNames))
+ return ReportLedBadType(info, ledi, field,
+ "mask of modifier state components");
+
+ ledi->led.which_mods = mask;
+ }
+ else if (istreq(field, "whichgroupstate")) {
+ unsigned mask;
+
+ if (arrayNdx)
+ return ReportLedNotArray(info, ledi, field);
+
+ if (!ExprResolveMask(keymap->ctx, value, &mask,
+ groupComponentMaskNames))
+ return ReportLedBadType(info, ledi, field,
+ "mask of group state components");
+
+ ledi->led.which_groups = mask;
+ }
+ else if (istreq(field, "driveskbd") ||
+ istreq(field, "driveskeyboard") ||
+ istreq(field, "leddriveskbd") ||
+ istreq(field, "leddriveskeyboard") ||
+ istreq(field, "indicatordriveskbd") ||
+ istreq(field, "indicatordriveskeyboard")) {
+ log_dbg(info->keymap->ctx,
+ "The \"%s\" field in indicator statements is unsupported; "
+ "Ignored\n", field);
+ }
+ else if (istreq(field, "index")) {
+ /* Users should see this, it might cause unexpected behavior. */
+ log_err(info->keymap->ctx,
+ "The \"index\" field in indicator statements is unsupported; "
+ "Ignored\n");
+ }
+ else {
+ log_err(info->keymap->ctx,
+ "Unknown field %s in map for %s indicator; "
+ "Definition ignored\n",
+ field, xkb_atom_text(keymap->ctx, ledi->led.name));
+ ok = false;
+ }
+
+ return ok;
+}
+
+static bool
+HandleGlobalVar(CompatInfo *info, VarDef *stmt)
+{
+ const char *elem, *field;
+ ExprDef *ndx;
+ bool ret;
+
+ if (!ExprResolveLhs(info->keymap->ctx, stmt->name, &elem, &field, &ndx))
+ ret = false;
+ else if (elem && istreq(elem, "interpret"))
+ ret = SetInterpField(info, &info->default_interp, field, ndx,
+ stmt->value);
+ else if (elem && istreq(elem, "indicator"))
+ ret = SetLedMapField(info, &info->default_led, field, ndx,
+ stmt->value);
+ else
+ ret = SetActionField(info->keymap, elem, field, ndx, stmt->value,
+ info->actions);
+ return ret;
+}
+
+static bool
+HandleInterpBody(CompatInfo *info, VarDef *def, SymInterpInfo *si)
+{
+ bool ok = true;
+ const char *elem, *field;
+ ExprDef *arrayNdx;
+
+ for (; def; def = (VarDef *) def->common.next) {
+ if (def->name && def->name->op == EXPR_FIELD_REF) {
+ log_err(info->keymap->ctx,
+ "Cannot set a global default value from within an interpret statement; "
+ "Move statements to the global file scope\n");
+ ok = false;
+ continue;
+ }
+
+ ok = ExprResolveLhs(info->keymap->ctx, def->name, &elem, &field,
+ &arrayNdx);
+ if (!ok)
+ continue;
+
+ ok = SetInterpField(info, si, field, arrayNdx, def->value);
+ }
+
+ return ok;
+}
+
+static bool
+HandleInterpDef(CompatInfo *info, InterpDef *def, enum merge_mode merge)
+{
+ enum xkb_match_operation pred;
+ xkb_mod_mask_t mods;
+ SymInterpInfo si;
+
+ if (!ResolveStateAndPredicate(def->match, &pred, &mods, info)) {
+ log_err(info->keymap->ctx,
+ "Couldn't determine matching modifiers; "
+ "Symbol interpretation ignored\n");
+ return false;
+ }
+
+ si = info->default_interp;
+ si.merge = merge = (def->merge == MERGE_DEFAULT ? merge : def->merge);
+
+ if (!LookupKeysym(def->sym, &si.interp.sym)) {
+ log_err(info->keymap->ctx,
+ "Could not resolve keysym %s; "
+ "Symbol interpretation ignored\n",
+ def->sym);
+ return false;
+ }
+
+ si.interp.match = pred;
+ si.interp.mods = mods;
+
+ if (!HandleInterpBody(info, def->def, &si)) {
+ info->errorCount++;
+ return false;
+ }
+
+ if (!AddInterp(info, &si, true)) {
+ info->errorCount++;
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+HandleLedMapDef(CompatInfo *info, LedMapDef *def, enum merge_mode merge)
+{
+ LedInfo ledi;
+ VarDef *var;
+ bool ok;
+
+ if (def->merge != MERGE_DEFAULT)
+ merge = def->merge;
+
+ ledi = info->default_led;
+ ledi.merge = merge;
+ ledi.led.name = def->name;
+
+ ok = true;
+ for (var = def->body; var != NULL; var = (VarDef *) var->common.next) {
+ const char *elem, *field;
+ ExprDef *arrayNdx;
+ if (!ExprResolveLhs(info->keymap->ctx, var->name, &elem, &field,
+ &arrayNdx)) {
+ ok = false;
+ continue;
+ }
+
+ if (elem) {
+ log_err(info->keymap->ctx,
+ "Cannot set defaults for \"%s\" element in indicator map; "
+ "Assignment to %s.%s ignored\n", elem, elem, field);
+ ok = false;
+ }
+ else {
+ ok = SetLedMapField(info, &ledi, field, arrayNdx, var->value) && ok;
+ }
+ }
+
+ if (ok)
+ return AddLedMap(info, &ledi, true);
+
+ return false;
+}
+
+static void
+HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge)
+{
+ bool ok;
+
+ merge = (merge == MERGE_DEFAULT ? MERGE_AUGMENT : merge);
+
+ free(info->name);
+ info->name = strdup_safe(file->name);
+
+ for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) {
+ switch (stmt->type) {
+ case STMT_INCLUDE:
+ ok = HandleIncludeCompatMap(info, (IncludeStmt *) stmt);
+ break;
+ case STMT_INTERP:
+ ok = HandleInterpDef(info, (InterpDef *) stmt, merge);
+ break;
+ case STMT_GROUP_COMPAT:
+ log_dbg(info->keymap->ctx,
+ "The \"group\" statement in compat is unsupported; "
+ "Ignored\n");
+ ok = true;
+ break;
+ case STMT_LED_MAP:
+ ok = HandleLedMapDef(info, (LedMapDef *) stmt, merge);
+ break;
+ case STMT_VAR:
+ ok = HandleGlobalVar(info, (VarDef *) stmt);
+ break;
+ case STMT_VMOD:
+ ok = HandleVModDef(info->keymap, (VModDef *) stmt);
+ break;
+ default:
+ log_err(info->keymap->ctx,
+ "Interpretation files may not include other types; "
+ "Ignoring %s\n", stmt_type_to_string(stmt->type));
+ ok = false;
+ break;
+ }
+
+ if (!ok)
+ info->errorCount++;
+
+ if (info->errorCount > 10) {
+ log_err(info->keymap->ctx,
+ "Abandoning compatibility map \"%s\"\n", file->topName);
+ break;
+ }
+ }
+}
+
+static void
+CopyInterps(CompatInfo *info, bool needSymbol, enum xkb_match_operation pred)
+{
+ SymInterpInfo *si;
+
+ darray_foreach(si, info->interps)
+ if (si->interp.match == pred &&
+ (si->interp.sym != XKB_KEY_NoSymbol) == needSymbol)
+ darray_append(info->keymap->sym_interprets, si->interp);
+}
+
+static void
+CopyLedMapDefs(CompatInfo *info)
+{
+ LedInfo *ledi;
+ xkb_led_index_t i;
+ struct xkb_led *led;
+ struct xkb_keymap *keymap = info->keymap;
+
+ darray_foreach(ledi, info->leds) {
+ /*
+ * Find the LED with the given name, if it was already declared
+ * in keycodes.
+ */
+ darray_enumerate(i, led, keymap->leds)
+ if (led->name == ledi->led.name)
+ break;
+
+ /* Not previously declared; create it with next free index. */
+ if (i >= darray_size(keymap->leds)) {
+ log_dbg(keymap->ctx,
+ "Indicator name \"%s\" was not declared in the keycodes section; "
+ "Adding new indicator\n",
+ xkb_atom_text(keymap->ctx, ledi->led.name));
+
+ darray_enumerate(i, led, keymap->leds)
+ if (led->name == XKB_ATOM_NONE)
+ break;
+
+ if (i >= darray_size(keymap->leds)) {
+ /* Not place to put it; ignore. */
+ if (i >= XKB_MAX_LEDS) {
+ log_err(keymap->ctx,
+ "Too many indicators (maximum is %d); "
+ "Indicator name \"%s\" ignored\n",
+ XKB_MAX_LEDS,
+ xkb_atom_text(keymap->ctx, ledi->led.name));
+ continue;
+ }
+ /* Add a new LED. */
+ darray_resize(keymap->leds, i + 1);
+ led = &darray_item(keymap->leds, i);
+ }
+ }
+
+ *led = ledi->led;
+ if (led->groups != 0 && led->which_groups == 0)
+ led->which_groups = XKB_STATE_LAYOUT_EFFECTIVE;
+ if (led->mods.mods != 0 && led->which_mods == 0)
+ led->which_mods = XKB_STATE_MODS_EFFECTIVE;
+ }
+}
+
+static bool
+CopyCompatToKeymap(struct xkb_keymap *keymap, CompatInfo *info)
+{
+ keymap->compat_section_name = strdup_safe(info->name);
+
+ if (!darray_empty(info->interps)) {
+ /* Most specific to least specific. */
+ CopyInterps(info, true, MATCH_EXACTLY);
+ CopyInterps(info, true, MATCH_ALL);
+ CopyInterps(info, true, MATCH_NONE);
+ CopyInterps(info, true, MATCH_ANY);
+ CopyInterps(info, true, MATCH_ANY_OR_NONE);
+ CopyInterps(info, false, MATCH_EXACTLY);
+ CopyInterps(info, false, MATCH_ALL);
+ CopyInterps(info, false, MATCH_NONE);
+ CopyInterps(info, false, MATCH_ANY);
+ CopyInterps(info, false, MATCH_ANY_OR_NONE);
+ }
+
+ CopyLedMapDefs(info);
+
+ return true;
+}
+
+bool
+CompileCompatMap(XkbFile *file, struct xkb_keymap *keymap,
+ enum merge_mode merge)
+{
+ CompatInfo info;
+ ActionsInfo *actions;
+
+ actions = NewActionsInfo();
+ if (!actions)
+ return false;
+
+ InitCompatInfo(&info, keymap, actions);
+ info.default_interp.merge = merge;
+ info.default_led.merge = merge;
+
+ HandleCompatMapFile(&info, file, merge);
+ if (info.errorCount != 0)
+ goto err_info;
+
+ if (!CopyCompatToKeymap(keymap, &info))
+ goto err_info;
+
+ ClearCompatInfo(&info);
+ FreeActionsInfo(actions);
+ return true;
+
+err_info:
+ ClearCompatInfo(&info);
+ FreeActionsInfo(actions);
+ return false;
+}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/expr.c b/src/3rdparty/xkbcommon/src/xkbcomp/expr.c
new file mode 100644
index 0000000000..dc64d7891f
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/expr.c
@@ -0,0 +1,685 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#include "xkbcomp-priv.h"
+#include "text.h"
+#include "expr.h"
+
+typedef bool (*IdentLookupFunc)(struct xkb_context *ctx, const void *priv,
+ xkb_atom_t field, enum expr_value_type type,
+ unsigned int *val_rtrn);
+
+bool
+ExprResolveLhs(struct xkb_context *ctx, const ExprDef *expr,
+ const char **elem_rtrn, const char **field_rtrn,
+ ExprDef **index_rtrn)
+{
+ switch (expr->op) {
+ case EXPR_IDENT:
+ *elem_rtrn = NULL;
+ *field_rtrn = xkb_atom_text(ctx, expr->value.str);
+ *index_rtrn = NULL;
+ return true;
+ case EXPR_FIELD_REF:
+ *elem_rtrn = xkb_atom_text(ctx, expr->value.field.element);
+ *field_rtrn = xkb_atom_text(ctx, expr->value.field.field);
+ *index_rtrn = NULL;
+ return true;
+ case EXPR_ARRAY_REF:
+ *elem_rtrn = xkb_atom_text(ctx, expr->value.array.element);
+ *field_rtrn = xkb_atom_text(ctx, expr->value.array.field);
+ *index_rtrn = expr->value.array.entry;
+ return true;
+ default:
+ break;
+ }
+ log_wsgo(ctx, "Unexpected operator %d in ResolveLhs\n", expr->op);
+ return false;
+}
+
+static bool
+SimpleLookup(struct xkb_context *ctx, const void *priv, xkb_atom_t field,
+ enum expr_value_type type, unsigned int *val_rtrn)
+{
+ const LookupEntry *entry;
+ const char *str;
+
+ if (!priv || field == XKB_ATOM_NONE || type != EXPR_TYPE_INT)
+ return false;
+
+ str = xkb_atom_text(ctx, field);
+ for (entry = priv; entry && entry->name; entry++) {
+ if (istreq(str, entry->name)) {
+ *val_rtrn = entry->value;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Data passed in the *priv argument for LookupModMask. */
+typedef struct {
+ const struct xkb_keymap *keymap;
+ enum mod_type mod_type;
+} LookupModMaskPriv;
+
+static bool
+LookupModMask(struct xkb_context *ctx, const void *priv, xkb_atom_t field,
+ enum expr_value_type type, xkb_mod_mask_t *val_rtrn)
+{
+ const char *str;
+ xkb_mod_index_t ndx;
+ const LookupModMaskPriv *arg = priv;
+ const struct xkb_keymap *keymap = arg->keymap;
+ enum mod_type mod_type = arg->mod_type;
+
+ if (type != EXPR_TYPE_INT)
+ return false;
+
+ str = xkb_atom_text(ctx, field);
+
+ if (istreq(str, "all")) {
+ *val_rtrn = MOD_REAL_MASK_ALL;
+ return true;
+ }
+
+ if (istreq(str, "none")) {
+ *val_rtrn = 0;
+ return true;
+ }
+
+ ndx = ModNameToIndex(keymap, field, mod_type);
+ if (ndx == XKB_MOD_INVALID)
+ return false;
+
+ *val_rtrn = (1 << ndx);
+ return true;
+}
+
+bool
+ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr,
+ bool *set_rtrn)
+{
+ bool ok = false;
+ const char *ident;
+
+ switch (expr->op) {
+ case EXPR_VALUE:
+ if (expr->value_type != EXPR_TYPE_BOOLEAN) {
+ log_err(ctx,
+ "Found constant of type %s where boolean was expected\n",
+ expr_value_type_to_string(expr->value_type));
+ return false;
+ }
+ *set_rtrn = !!expr->value.ival;
+ return true;
+
+ case EXPR_IDENT:
+ ident = xkb_atom_text(ctx, expr->value.str);
+ if (ident) {
+ if (istreq(ident, "true") ||
+ istreq(ident, "yes") ||
+ istreq(ident, "on")) {
+ *set_rtrn = true;
+ return true;
+ }
+ else if (istreq(ident, "false") ||
+ istreq(ident, "no") ||
+ istreq(ident, "off")) {
+ *set_rtrn = false;
+ return true;
+ }
+ }
+ log_err(ctx, "Identifier \"%s\" of type boolean is unknown\n",
+ xkb_atom_text(ctx, expr->value.str));
+ return false;
+
+ case EXPR_FIELD_REF:
+ log_err(ctx, "Default \"%s.%s\" of type boolean is unknown\n",
+ xkb_atom_text(ctx, expr->value.field.element),
+ xkb_atom_text(ctx, expr->value.field.field));
+ return false;
+
+ case EXPR_INVERT:
+ case EXPR_NOT:
+ ok = ExprResolveBoolean(ctx, expr, set_rtrn);
+ if (ok)
+ *set_rtrn = !*set_rtrn;
+ return ok;
+ case EXPR_ADD:
+ case EXPR_SUBTRACT:
+ case EXPR_MULTIPLY:
+ case EXPR_DIVIDE:
+ case EXPR_ASSIGN:
+ case EXPR_NEGATE:
+ case EXPR_UNARY_PLUS:
+ log_err(ctx, "%s of boolean values not permitted\n",
+ expr_op_type_to_string(expr->op));
+ break;
+
+ default:
+ log_wsgo(ctx, "Unknown operator %d in ResolveBoolean\n", expr->op);
+ break;
+ }
+
+ return false;
+}
+
+bool
+ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr,
+ xkb_keycode_t *kc)
+{
+ xkb_keycode_t leftRtrn, rightRtrn;
+ ExprDef *left, *right;
+
+ switch (expr->op) {
+ case EXPR_VALUE:
+ if (expr->value_type != EXPR_TYPE_INT) {
+ log_err(ctx,
+ "Found constant of type %s where an int was expected\n",
+ expr_value_type_to_string(expr->value_type));
+ return false;
+ }
+
+ *kc = expr->value.uval;
+ return true;
+
+ case EXPR_ADD:
+ case EXPR_SUBTRACT:
+ case EXPR_MULTIPLY:
+ case EXPR_DIVIDE:
+ left = expr->value.binary.left;
+ right = expr->value.binary.right;
+
+ if (!ExprResolveKeyCode(ctx, left, &leftRtrn) ||
+ !ExprResolveKeyCode(ctx, right, &rightRtrn))
+ return false;
+
+ switch (expr->op) {
+ case EXPR_ADD:
+ *kc = leftRtrn + rightRtrn;
+ break;
+ case EXPR_SUBTRACT:
+ *kc = leftRtrn - rightRtrn;
+ break;
+ case EXPR_MULTIPLY:
+ *kc = leftRtrn * rightRtrn;
+ break;
+ case EXPR_DIVIDE:
+ if (rightRtrn == 0) {
+ log_err(ctx, "Cannot divide by zero: %d / %d\n",
+ leftRtrn, rightRtrn);
+ return false;
+ }
+
+ *kc = leftRtrn / rightRtrn;
+ break;
+ default:
+ break;
+ }
+
+ return true;
+
+ case EXPR_NEGATE:
+ left = expr->value.child;
+ if (!ExprResolveKeyCode(ctx, left, &leftRtrn))
+ return false;
+
+ *kc = ~leftRtrn;
+ return true;
+
+ case EXPR_UNARY_PLUS:
+ left = expr->value.child;
+ return ExprResolveKeyCode(ctx, left, kc);
+
+ default:
+ log_wsgo(ctx, "Unknown operator %d in ResolveKeyCode\n", expr->op);
+ break;
+ }
+
+ return false;
+}
+
+/**
+ * This function returns ... something. It's a bit of a guess, really.
+ *
+ * If an integer is given in value ctx, it will be returned in ival.
+ * If an ident or field reference is given, the lookup function (if given)
+ * will be called. At the moment, only SimpleLookup use this, and they both
+ * return the results in uval. And don't support field references.
+ *
+ * Cool.
+ */
+static bool
+ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr,
+ int *val_rtrn, IdentLookupFunc lookup,
+ const void *lookupPriv)
+{
+ bool ok = false;
+ int l, r;
+ unsigned u;
+ ExprDef *left, *right;
+
+ switch (expr->op) {
+ case EXPR_VALUE:
+ if (expr->value_type != EXPR_TYPE_INT) {
+ log_err(ctx,
+ "Found constant of type %s where an int was expected\n",
+ expr_value_type_to_string(expr->value_type));
+ return false;
+ }
+
+ *val_rtrn = expr->value.ival;
+ return true;
+
+ case EXPR_IDENT:
+ if (lookup)
+ ok = lookup(ctx, lookupPriv, expr->value.str, EXPR_TYPE_INT, &u);
+
+ if (!ok)
+ log_err(ctx, "Identifier \"%s\" of type int is unknown\n",
+ xkb_atom_text(ctx, expr->value.str));
+ else
+ *val_rtrn = (int) u;
+
+ return ok;
+
+ case EXPR_FIELD_REF:
+ log_err(ctx, "Default \"%s.%s\" of type int is unknown\n",
+ xkb_atom_text(ctx, expr->value.field.element),
+ xkb_atom_text(ctx, expr->value.field.field));
+ return false;
+
+ case EXPR_ADD:
+ case EXPR_SUBTRACT:
+ case EXPR_MULTIPLY:
+ case EXPR_DIVIDE:
+ left = expr->value.binary.left;
+ right = expr->value.binary.right;
+ if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv) ||
+ !ExprResolveIntegerLookup(ctx, right, &r, lookup, lookupPriv))
+ return false;
+
+ switch (expr->op) {
+ case EXPR_ADD:
+ *val_rtrn = l + r;
+ break;
+ case EXPR_SUBTRACT:
+ *val_rtrn = l - r;
+ break;
+ case EXPR_MULTIPLY:
+ *val_rtrn = l * r;
+ break;
+ case EXPR_DIVIDE:
+ if (r == 0) {
+ log_err(ctx, "Cannot divide by zero: %d / %d\n", l, r);
+ return false;
+ }
+ *val_rtrn = l / r;
+ break;
+ default:
+ break;
+ }
+
+ return true;
+
+ case EXPR_ASSIGN:
+ log_wsgo(ctx, "Assignment operator not implemented yet\n");
+ break;
+
+ case EXPR_NOT:
+ log_err(ctx, "The ! operator cannot be applied to an integer\n");
+ return false;
+
+ case EXPR_INVERT:
+ case EXPR_NEGATE:
+ left = expr->value.child;
+ if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv))
+ return false;
+
+ *val_rtrn = (expr->op == EXPR_NEGATE ? -l : ~l);
+ return true;
+
+ case EXPR_UNARY_PLUS:
+ left = expr->value.child;
+ return ExprResolveIntegerLookup(ctx, left, val_rtrn, lookup,
+ lookupPriv);
+
+ default:
+ log_wsgo(ctx, "Unknown operator %d in ResolveInteger\n", expr->op);
+ break;
+ }
+
+ return false;
+}
+
+bool
+ExprResolveInteger(struct xkb_context *ctx, const ExprDef *expr,
+ int *val_rtrn)
+{
+ return ExprResolveIntegerLookup(ctx, expr, val_rtrn, NULL, NULL);
+}
+
+bool
+ExprResolveGroup(struct xkb_context *ctx, const ExprDef *expr,
+ xkb_layout_index_t *group_rtrn)
+{
+ bool ok;
+ int result;
+
+ ok = ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup,
+ groupNames);
+ if (!ok)
+ return false;
+
+ if (result <= 0 || result > XKB_MAX_GROUPS) {
+ log_err(ctx, "Group index %u is out of range (1..%d)\n",
+ result, XKB_MAX_GROUPS);
+ return false;
+ }
+
+ *group_rtrn = (xkb_layout_index_t) result;
+ return true;
+}
+
+bool
+ExprResolveLevel(struct xkb_context *ctx, const ExprDef *expr,
+ xkb_level_index_t *level_rtrn)
+{
+ bool ok;
+ int result;
+
+ ok = ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup,
+ levelNames);
+ if (!ok)
+ return false;
+
+ if (result < 1) {
+ log_err(ctx, "Shift level %d is out of range\n", result);
+ return false;
+ }
+
+ /* Level is zero-indexed from now on. */
+ *level_rtrn = (unsigned int) (result - 1);
+ return true;
+}
+
+bool
+ExprResolveButton(struct xkb_context *ctx, const ExprDef *expr, int *btn_rtrn)
+{
+ int result;
+
+ if (!ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup,
+ buttonNames))
+ return false;
+
+ *btn_rtrn = result;
+ return true;
+}
+
+bool
+ExprResolveString(struct xkb_context *ctx, const ExprDef *expr,
+ xkb_atom_t *val_rtrn)
+{
+ switch (expr->op) {
+ case EXPR_VALUE:
+ if (expr->value_type != EXPR_TYPE_STRING) {
+ log_err(ctx, "Found constant of type %s, expected a string\n",
+ expr_value_type_to_string(expr->value_type));
+ return false;
+ }
+
+ *val_rtrn = expr->value.str;
+ return true;
+
+ case EXPR_IDENT:
+ log_err(ctx, "Identifier \"%s\" of type string not found\n",
+ xkb_atom_text(ctx, expr->value.str));
+ return false;
+
+ case EXPR_FIELD_REF:
+ log_err(ctx, "Default \"%s.%s\" of type string not found\n",
+ xkb_atom_text(ctx, expr->value.field.element),
+ xkb_atom_text(ctx, expr->value.field.field));
+ return false;
+
+ case EXPR_ADD:
+ case EXPR_SUBTRACT:
+ case EXPR_MULTIPLY:
+ case EXPR_DIVIDE:
+ case EXPR_ASSIGN:
+ case EXPR_NEGATE:
+ case EXPR_INVERT:
+ case EXPR_NOT:
+ case EXPR_UNARY_PLUS:
+ log_err(ctx, "%s of strings not permitted\n",
+ expr_op_type_to_string(expr->op));
+ return false;
+
+ default:
+ log_wsgo(ctx, "Unknown operator %d in ResolveString\n", expr->op);
+ break;
+ }
+ return false;
+}
+
+bool
+ExprResolveEnum(struct xkb_context *ctx, const ExprDef *expr,
+ unsigned int *val_rtrn, const LookupEntry *values)
+{
+ if (expr->op != EXPR_IDENT) {
+ log_err(ctx, "Found a %s where an enumerated value was expected\n",
+ expr_op_type_to_string(expr->op));
+ return false;
+ }
+
+ if (!SimpleLookup(ctx, values, expr->value.str, EXPR_TYPE_INT,
+ val_rtrn)) {
+ log_err(ctx, "Illegal identifier %s; expected one of:\n",
+ xkb_atom_text(ctx, expr->value.str));
+ while (values && values->name)
+ {
+ log_err(ctx, "\t%s\n", values->name);
+ values++;
+ }
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
+ unsigned int *val_rtrn, IdentLookupFunc lookup,
+ const void *lookupPriv)
+{
+ bool ok = 0;
+ unsigned int l, r;
+ int v;
+ ExprDef *left, *right;
+ const char *bogus = NULL;
+
+ switch (expr->op) {
+ case EXPR_VALUE:
+ if (expr->value_type != EXPR_TYPE_INT) {
+ log_err(ctx,
+ "Found constant of type %s where a mask was expected\n",
+ expr_value_type_to_string(expr->value_type));
+ return false;
+ }
+ *val_rtrn = (unsigned int) expr->value.ival;
+ return true;
+
+ case EXPR_IDENT:
+ ok = lookup(ctx, lookupPriv, expr->value.str, EXPR_TYPE_INT,
+ val_rtrn);
+ if (!ok)
+ log_err(ctx, "Identifier \"%s\" of type int is unknown\n",
+ xkb_atom_text(ctx, expr->value.str));
+ return ok;
+
+ case EXPR_FIELD_REF:
+ log_err(ctx, "Default \"%s.%s\" of type int is unknown\n",
+ xkb_atom_text(ctx, expr->value.field.element),
+ xkb_atom_text(ctx, expr->value.field.field));
+ return false;
+
+ case EXPR_ARRAY_REF:
+ bogus = "array reference";
+
+ case EXPR_ACTION_DECL:
+ if (bogus == NULL)
+ bogus = "function use";
+ log_err(ctx,
+ "Unexpected %s in mask expression; Expression Ignored\n",
+ bogus);
+ return false;
+
+ case EXPR_ADD:
+ case EXPR_SUBTRACT:
+ case EXPR_MULTIPLY:
+ case EXPR_DIVIDE:
+ left = expr->value.binary.left;
+ right = expr->value.binary.right;
+ if (!ExprResolveMaskLookup(ctx, left, &l, lookup, lookupPriv) ||
+ !ExprResolveMaskLookup(ctx, right, &r, lookup, lookupPriv))
+ return false;
+
+ switch (expr->op) {
+ case EXPR_ADD:
+ *val_rtrn = l | r;
+ break;
+ case EXPR_SUBTRACT:
+ *val_rtrn = l & (~r);
+ break;
+ case EXPR_MULTIPLY:
+ case EXPR_DIVIDE:
+ log_err(ctx, "Cannot %s masks; Illegal operation ignored\n",
+ (expr->op == EXPR_DIVIDE ? "divide" : "multiply"));
+ return false;
+ default:
+ break;
+ }
+
+ return true;
+
+ case EXPR_ASSIGN:
+ log_wsgo(ctx, "Assignment operator not implemented yet\n");
+ break;
+
+ case EXPR_INVERT:
+ left = expr->value.child;
+ if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv))
+ return false;
+
+ *val_rtrn = ~v;
+ return true;
+
+ case EXPR_UNARY_PLUS:
+ case EXPR_NEGATE:
+ case EXPR_NOT:
+ left = expr->value.child;
+ if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv))
+ log_err(ctx, "The %s operator cannot be used with a mask\n",
+ (expr->op == EXPR_NEGATE ? "-" : "!"));
+ return false;
+
+ default:
+ log_wsgo(ctx, "Unknown operator %d in ResolveMask\n", expr->op);
+ break;
+ }
+
+ return false;
+}
+
+bool
+ExprResolveMask(struct xkb_context *ctx, const ExprDef *expr,
+ unsigned int *mask_rtrn, const LookupEntry *values)
+{
+ return ExprResolveMaskLookup(ctx, expr, mask_rtrn, SimpleLookup, values);
+}
+
+bool
+ExprResolveModMask(struct xkb_keymap *keymap, const ExprDef *expr,
+ enum mod_type mod_type, xkb_mod_mask_t *mask_rtrn)
+{
+ LookupModMaskPriv priv = { .keymap = keymap, .mod_type = mod_type };
+ return ExprResolveMaskLookup(keymap->ctx, expr, mask_rtrn, LookupModMask,
+ &priv);
+}
+
+bool
+ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr,
+ xkb_keysym_t *sym_rtrn)
+{
+ int val;
+
+ if (expr->op == EXPR_IDENT) {
+ const char *str;
+ str = xkb_atom_text(ctx, expr->value.str);
+ *sym_rtrn = xkb_keysym_from_name(str, 0);
+ if (*sym_rtrn != XKB_KEY_NoSymbol)
+ return true;
+ }
+
+ if (!ExprResolveInteger(ctx, expr, &val))
+ return false;
+
+ if (val < 0 || val >= 10)
+ return false;
+
+ *sym_rtrn = ((xkb_keysym_t) val) + '0';
+ return true;
+}
+
+bool
+ExprResolveMod(struct xkb_keymap *keymap, const ExprDef *def,
+ enum mod_type mod_type, xkb_mod_index_t *ndx_rtrn)
+{
+ xkb_mod_index_t ndx;
+ xkb_atom_t name = def->value.str;
+
+ if (def->op != EXPR_IDENT) {
+ log_err(keymap->ctx,
+ "Cannot resolve virtual modifier: "
+ "found %s where a virtual modifier name was expected\n",
+ expr_op_type_to_string(def->op));
+ return false;
+ }
+
+ ndx = ModNameToIndex(keymap, name, mod_type);
+ if (ndx == XKB_MOD_INVALID) {
+ log_err(keymap->ctx,
+ "Cannot resolve virtual modifier: "
+ "\"%s\" was not previously declared\n",
+ xkb_atom_text(keymap->ctx, name));
+ return false;
+ }
+
+ *ndx_rtrn = ndx;
+ return true;
+}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/expr.h b/src/3rdparty/xkbcommon/src/xkbcomp/expr.h
new file mode 100644
index 0000000000..5434ad199e
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/expr.h
@@ -0,0 +1,83 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#ifndef XKBCOMP_EXPR_H
+#define XKBCOMP_EXPR_H
+
+bool
+ExprResolveLhs(struct xkb_context *ctx, const ExprDef *expr,
+ const char **elem_rtrn, const char **field_rtrn,
+ ExprDef **index_rtrn);
+
+bool
+ExprResolveModMask(struct xkb_keymap *keymap, const ExprDef *expr,
+ enum mod_type mod_type, xkb_mod_mask_t *mask_rtrn);
+
+bool
+ExprResolveMod(struct xkb_keymap *keymap, const ExprDef *def,
+ enum mod_type mod_type, xkb_mod_index_t *ndx_rtrn);
+
+bool
+ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr,
+ bool *set_rtrn);
+
+bool
+ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr,
+ xkb_keycode_t *kc);
+
+bool
+ExprResolveInteger(struct xkb_context *ctx, const ExprDef *expr,
+ int *val_rtrn);
+
+bool
+ExprResolveLevel(struct xkb_context *ctx, const ExprDef *expr,
+ xkb_level_index_t *level_rtrn);
+
+bool
+ExprResolveGroup(struct xkb_context *ctx, const ExprDef *expr,
+ xkb_layout_index_t *group_rtrn);
+
+bool
+ExprResolveButton(struct xkb_context *ctx, const ExprDef *expr,
+ int *btn_rtrn);
+
+bool
+ExprResolveString(struct xkb_context *ctx, const ExprDef *expr,
+ xkb_atom_t *val_rtrn);
+
+bool
+ExprResolveEnum(struct xkb_context *ctx, const ExprDef *expr,
+ unsigned int *val_rtrn, const LookupEntry *values);
+
+bool
+ExprResolveMask(struct xkb_context *ctx, const ExprDef *expr,
+ unsigned int *mask_rtrn, const LookupEntry *values);
+
+bool
+ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr,
+ xkb_keysym_t *sym_rtrn);
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/include.c b/src/3rdparty/xkbcommon/src/xkbcomp/include.c
new file mode 100644
index 0000000000..b4a4014635
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/include.c
@@ -0,0 +1,289 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+/*
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+
+#include "xkbcomp-priv.h"
+#include "include.h"
+
+/**
+ * Parse an include statement. Each call returns a file name, along with
+ * (possibly) a specific map in the file, an explicit group designator, and
+ * the separator from the next file, used to determine the merge mode.
+ *
+ * @param str_inout Input statement, modified in-place. Should be passed in
+ * repeatedly. If str_inout is NULL, the parsing has completed.
+ *
+ * @param file_rtrn Set to the name of the include file to be used. Combined
+ * with an enum xkb_file_type, this determines which file to look for in the
+ * include path.
+ *
+ * @param map_rtrn Set to the string between '(' and ')', if any. This will
+ * result in the compilation of a specific named map within the file (e.g.
+ * xkb_symbols "basic" { ... }) , as opposed to the default map of the file.
+ *
+ * @param nextop_rtrn Set to the next operation in the complete statement,
+ * which is '\0' if it's the last file or '+' or '|' if there are more.
+ * Separating the files with '+' sets the merge mode to MERGE_MODE_OVERRIDE,
+ * while '|' sets the merge mode to MERGE_MODE_AUGMENT.
+ *
+ * @param extra_data Set to the string after ':', if any. Currently the
+ * extra data is only used for setting an explicit group index for a symbols
+ * file.
+ *
+ * @return true if parsing was successful, false for an illegal string.
+ *
+ * Example: "evdev+aliases(qwerty):2"
+ * str_inout = "aliases(qwerty):2"
+ * file_rtrn = "evdev"
+ * map_rtrn = NULL
+ * nextop_retrn = "+"
+ * extra_data = NULL
+ *
+ * 2nd run with "aliases(qwerty):2"
+ * str_inout = NULL
+ * file_rtrn = "aliases"
+ * map_rtrn = "qwerty"
+ * nextop_retrn = ""
+ * extra_data = "2"
+ *
+ */
+bool
+ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
+ char *nextop_rtrn, char **extra_data)
+{
+ char *tmp, *str, *next;
+
+ str = *str_inout;
+
+ /*
+ * Find the position in the string where the next file is included,
+ * if there is more than one left in the statement.
+ */
+ next = strpbrk(str, "|+");
+ if (next) {
+ /* Got more files, this function will be called again. */
+ *nextop_rtrn = *next;
+ /* Separate the string, for strchr etc. to work on this file only. */
+ *next++ = '\0';
+ }
+ else {
+ /* This is the last file in this statement, won't be called again. */
+ *nextop_rtrn = '\0';
+ next = NULL;
+ }
+
+ /*
+ * Search for the explicit group designator, if any. If it's there,
+ * it goes after the file name and map.
+ */
+ tmp = strchr(str, ':');
+ if (tmp != NULL) {
+ *tmp++ = '\0';
+ *extra_data = strdup(tmp);
+ }
+ else {
+ *extra_data = NULL;
+ }
+
+ /* Look for a map, if any. */
+ tmp = strchr(str, '(');
+ if (tmp == NULL) {
+ /* No map. */
+ *file_rtrn = strdup(str);
+ *map_rtrn = NULL;
+ }
+ else if (str[0] == '(') {
+ /* Map without file - invalid. */
+ free(*extra_data);
+ return false;
+ }
+ else {
+ /* Got a map; separate the file and the map for the strdup's. */
+ *tmp++ = '\0';
+ *file_rtrn = strdup(str);
+ str = tmp;
+ tmp = strchr(str, ')');
+ if (tmp == NULL || tmp[1] != '\0') {
+ free(*file_rtrn);
+ free(*extra_data);
+ return false;
+ }
+ *tmp++ = '\0';
+ *map_rtrn = strdup(str);
+ }
+
+ /* Set up the next file for the next call, if any. */
+ if (*nextop_rtrn == '\0')
+ *str_inout = NULL;
+ else if (*nextop_rtrn == '|' || *nextop_rtrn == '+')
+ *str_inout = next;
+ else
+ return false;
+
+ return true;
+}
+
+static const char *xkb_file_type_include_dirs[_FILE_TYPE_NUM_ENTRIES] = {
+ [FILE_TYPE_KEYCODES] = "keycodes",
+ [FILE_TYPE_TYPES] = "types",
+ [FILE_TYPE_COMPAT] = "compat",
+ [FILE_TYPE_SYMBOLS] = "symbols",
+ [FILE_TYPE_GEOMETRY] = "geometry",
+ [FILE_TYPE_KEYMAP] = "keymap",
+ [FILE_TYPE_RULES] = "rules",
+};
+
+/**
+ * Return the xkb directory based on the type.
+ */
+static const char *
+DirectoryForInclude(enum xkb_file_type type)
+{
+ if (type >= _FILE_TYPE_NUM_ENTRIES)
+ return "";
+ return xkb_file_type_include_dirs[type];
+}
+
+FILE *
+FindFileInXkbPath(struct xkb_context *ctx, const char *name,
+ enum xkb_file_type type, char **pathRtrn)
+{
+ unsigned int i;
+ FILE *file = NULL;
+ char buf[PATH_MAX];
+ const char *typeDir;
+
+ typeDir = DirectoryForInclude(type);
+
+ for (i = 0; i < xkb_context_num_include_paths(ctx); i++) {
+ int ret = snprintf(buf, sizeof(buf), "%s/%s/%s",
+ xkb_context_include_path_get(ctx, i),
+ typeDir, name);
+ if (ret >= (ssize_t) sizeof(buf)) {
+ log_err(ctx, "File name (%s/%s/%s) too long\n",
+ xkb_context_include_path_get(ctx, i), typeDir, name);
+ continue;
+ }
+
+ file = fopen(buf, "r");
+ if (file)
+ break;
+ }
+
+ if (!file) {
+ log_err(ctx, "Couldn't find file \"%s/%s\" in include paths\n",
+ typeDir, name);
+
+ if (xkb_context_num_include_paths(ctx) > 0) {
+ log_err(ctx, "%d include paths searched:\n",
+ xkb_context_num_include_paths(ctx));
+ for (i = 0; i < xkb_context_num_include_paths(ctx); i++)
+ log_err(ctx, "\t%s\n",
+ xkb_context_include_path_get(ctx, i));
+ }
+ else {
+ log_err(ctx, "There are no include paths to search\n");
+ }
+
+ if (xkb_context_num_failed_include_paths(ctx) > 0) {
+ log_err(ctx, "%d include paths could not be added:\n",
+ xkb_context_num_failed_include_paths(ctx));
+ for (i = 0; i < xkb_context_num_failed_include_paths(ctx); i++)
+ log_err(ctx, "\t%s\n",
+ xkb_context_failed_include_path_get(ctx, i));
+ }
+
+ return NULL;
+ }
+
+ if (pathRtrn)
+ *pathRtrn = strdup(buf);
+ return file;
+}
+
+XkbFile *
+ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt,
+ enum xkb_file_type file_type)
+{
+ FILE *file;
+ XkbFile *xkb_file;
+
+ file = FindFileInXkbPath(ctx, stmt->file, file_type, NULL);
+ if (!file)
+ return false;
+
+ xkb_file = XkbParseFile(ctx, file, stmt->file, stmt->map);
+ fclose(file);
+ if (!xkb_file) {
+ if (stmt->map)
+ log_err(ctx, "Couldn't process include statement for '%s(%s)'\n",
+ stmt->file, stmt->map);
+ else
+ log_err(ctx, "Couldn't process include statement for '%s'\n",
+ stmt->file);
+ return NULL;
+ }
+
+ if (xkb_file->file_type != file_type) {
+ log_err(ctx,
+ "Include file wrong type (expected %s, got %s); "
+ "Include file \"%s\" ignored\n",
+ xkb_file_type_to_string(file_type),
+ xkb_file_type_to_string(xkb_file->file_type), stmt->file);
+ FreeXkbFile(xkb_file);
+ return NULL;
+ }
+
+ /* FIXME: we have to check recursive includes here (or somewhere) */
+
+ return xkb_file;
+}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/include.h b/src/3rdparty/xkbcommon/src/xkbcomp/include.h
new file mode 100644
index 0000000000..03e76ed5ce
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/include.h
@@ -0,0 +1,42 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#ifndef XKBCOMP_INCLUDE_H
+#define XKBCOMP_INCLUDE_H
+
+bool
+ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
+ char *nextop_rtrn, char **extra_data);
+
+FILE *
+FindFileInXkbPath(struct xkb_context *ctx, const char *name,
+ enum xkb_file_type type, char **pathRtrn);
+
+XkbFile *
+ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt,
+ enum xkb_file_type file_type);
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c b/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c
new file mode 100644
index 0000000000..edc54c94f3
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c
@@ -0,0 +1,692 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#include "xkbcomp-priv.h"
+#include "text.h"
+#include "expr.h"
+#include "include.h"
+
+/*
+ * The xkb_keycodes section
+ * ========================
+ *
+ * This is the simplest section type, and is the first one to be
+ * compiled. The purpose of this is mostly to map between the
+ * hardware/evdev scancodes and xkb keycodes. Each key is given a name
+ * by which it can be referred to later, e.g. in the symbols section.
+ *
+ * Keycode statements
+ * ------------------
+ * Statements of the form:
+ * <TLDE> = 49;
+ * <AE01> = 10;
+ *
+ * The above would let 49 and 10 be valid keycodes in the keymap, and
+ * assign them the names TLDE and AE01 respectively. The format <WXYZ> is
+ * always used to refer to a key by name.
+ *
+ * [ The naming convention <AE01> just denoted the position of the key
+ * in the main alphanumric section of the keyboard, with the two letters
+ * specifying the row and the two digits specifying the column, from
+ * the bottom left.]
+ *
+ * In the common case this just maps to the evdev scancodes from
+ * /usr/include/linux/input.h, e.g. the following definitions:
+ * #define KEY_GRAVE 41
+ * #define KEY_1 2
+ * Similar definitions appear in the xf86-input-keyboard driver. Note
+ * that in all current keymaps there's a constant offset of 8 (for
+ * historical reasons).
+ *
+ * If there's a conflict, like the same name given to different keycodes,
+ * or same keycode given different names, it is resolved according to the
+ * merge mode which applies to the definitions.
+ *
+ * Alias statements
+ * ----------------
+ * Statements of the form:
+ * alias <MENU> = <COMP>;
+ *
+ * Allows to refer to a previously defined key (here <COMP>) by another
+ * name (here <MENU>). Conflicts are handled similarly.
+ *
+ * LED name statements
+ * -------------------------
+ * Statements of the form:
+ * indicator 1 = "Caps Lock";
+ * indicator 2 = "Num Lock";
+ * indicator 3 = "Scroll Lock";
+ *
+ * Assigns a name to the keyboard LED (a.k.a indicator) with the given index.
+ * The led may be referred by this name later in the compat section
+ * and by the user.
+ *
+ * Effect on the keymap
+ * --------------------
+ * After all of the xkb_keycodes sections have been compiled, the
+ * following members of struct xkb_keymap are finalized:
+ * xkb_keycode_t min_key_code;
+ * xkb_keycode_t max_key_code;
+ * unsigned int num_aliases;
+ * struct xkb_key_alias *key_aliases;
+ * char *keycodes_section_name;
+ * The 'name' field of leds declared in xkb_keycodes:
+ * darray(struct xkb_led) leds;
+ * Further, the array of keys:
+ * struct xkb_key *keys;
+ * had been resized to its final size (i.e. all of the xkb_key objects are
+ * referable by their keycode). However the objects themselves do not
+ * contain any useful information besides the key name at this point.
+ */
+
+typedef struct {
+ enum merge_mode merge;
+
+ xkb_atom_t alias;
+ xkb_atom_t real;
+} AliasInfo;
+
+typedef struct {
+ enum merge_mode merge;
+
+ xkb_atom_t name;
+} LedNameInfo;
+
+typedef struct {
+ char *name;
+ int errorCount;
+
+ xkb_keycode_t min_key_code;
+ xkb_keycode_t max_key_code;
+ darray(xkb_atom_t) key_names;
+ darray(LedNameInfo) led_names;
+ darray(AliasInfo) aliases;
+
+ struct xkb_context *ctx;
+} KeyNamesInfo;
+
+/***====================================================================***/
+
+static void
+InitAliasInfo(AliasInfo *info, enum merge_mode merge,
+ xkb_atom_t alias, xkb_atom_t real)
+{
+ memset(info, 0, sizeof(*info));
+ info->merge = merge;
+ info->alias = alias;
+ info->real = real;
+}
+
+static LedNameInfo *
+FindLedByName(KeyNamesInfo *info, xkb_atom_t name,
+ xkb_led_index_t *idx_out)
+{
+ LedNameInfo *ledi;
+ xkb_led_index_t idx;
+
+ darray_enumerate(idx, ledi, info->led_names) {
+ if (ledi->name == name) {
+ *idx_out = idx;
+ return ledi;
+ }
+ }
+
+ return NULL;
+}
+
+static bool
+AddLedName(KeyNamesInfo *info, enum merge_mode merge, bool same_file,
+ LedNameInfo *new, xkb_led_index_t new_idx)
+{
+ xkb_led_index_t old_idx;
+ LedNameInfo *old;
+ const int verbosity = xkb_context_get_log_verbosity(info->ctx);
+ const bool report = (same_file && verbosity > 0) || verbosity > 9;
+ const bool replace = (merge == MERGE_REPLACE || merge == MERGE_OVERRIDE);
+
+ /* LED with the same name already exists. */
+ old = FindLedByName(info, new->name, &old_idx);
+ if (old) {
+ if (old_idx == new_idx) {
+ log_warn(info->ctx,
+ "Multiple indicators named \"%s\"; "
+ "Identical definitions ignored\n",
+ xkb_atom_text(info->ctx, new->name));
+ return true;
+ }
+
+ if (report) {
+ xkb_led_index_t use = (replace ? new_idx + 1 : old_idx + 1);
+ xkb_led_index_t ignore = (replace ? old_idx + 1 : new_idx + 1);
+ log_warn(info->ctx,
+ "Multiple indicators named %s; Using %d, ignoring %d\n",
+ xkb_atom_text(info->ctx, new->name), use, ignore);
+ }
+
+ if (replace)
+ *old = *new;
+
+ return true;
+ }
+
+ if (new_idx >= darray_size(info->led_names))
+ darray_resize0(info->led_names, new_idx + 1);
+
+ /* LED with the same index already exists. */
+ old = &darray_item(info->led_names, new_idx);
+ if (old->name != XKB_ATOM_NONE) {
+ if (report) {
+ const xkb_atom_t use = (replace ? new->name : old->name);
+ const xkb_atom_t ignore = (replace ? old->name : new->name);
+ log_warn(info->ctx, "Multiple names for indicator %d; "
+ "Using %s, ignoring %s\n", new_idx + 1,
+ xkb_atom_text(info->ctx, use),
+ xkb_atom_text(info->ctx, ignore));
+ }
+
+ if (replace)
+ *old = *new;
+
+ return true;
+ }
+
+ darray_item(info->led_names, new_idx) = *new;
+ return true;
+}
+
+static void
+ClearKeyNamesInfo(KeyNamesInfo *info)
+{
+ free(info->name);
+ darray_free(info->key_names);
+ darray_free(info->aliases);
+ darray_free(info->led_names);
+}
+
+static void
+InitKeyNamesInfo(KeyNamesInfo *info, struct xkb_context *ctx)
+{
+ memset(info, 0, sizeof(*info));
+ info->ctx = ctx;
+ info->min_key_code = XKB_KEYCODE_MAX;
+}
+
+static xkb_keycode_t
+FindKeyByName(KeyNamesInfo *info, xkb_atom_t name)
+{
+ xkb_keycode_t i;
+
+ for (i = info->min_key_code; i <= info->max_key_code; i++)
+ if (darray_item(info->key_names, i) == name)
+ return i;
+
+ return XKB_KEYCODE_INVALID;
+}
+
+static bool
+AddKeyName(KeyNamesInfo *info, xkb_keycode_t kc, xkb_atom_t name,
+ enum merge_mode merge, bool same_file, bool report)
+{
+ xkb_atom_t old_name;
+ xkb_keycode_t old_kc;
+ const int verbosity = xkb_context_get_log_verbosity(info->ctx);
+
+ report = report && ((same_file && verbosity > 0) || verbosity > 7);
+
+ if (kc >= darray_size(info->key_names))
+ darray_resize0(info->key_names, kc + 1);
+
+ info->min_key_code = MIN(info->min_key_code, kc);
+ info->max_key_code = MAX(info->max_key_code, kc);
+
+ /* There's already a key with this keycode. */
+ old_name = darray_item(info->key_names, kc);
+ if (old_name != XKB_ATOM_NONE) {
+ const char *lname = KeyNameText(info->ctx, old_name);
+ const char *kname = KeyNameText(info->ctx, name);
+
+ if (old_name == name) {
+ if (report)
+ log_warn(info->ctx,
+ "Multiple identical key name definitions; "
+ "Later occurrences of \"%s = %d\" ignored\n",
+ lname, kc);
+ return true;
+ }
+ else if (merge == MERGE_AUGMENT) {
+ if (report)
+ log_warn(info->ctx,
+ "Multiple names for keycode %d; "
+ "Using %s, ignoring %s\n", kc, lname, kname);
+ return true;
+ }
+ else {
+ if (report)
+ log_warn(info->ctx,
+ "Multiple names for keycode %d; "
+ "Using %s, ignoring %s\n", kc, kname, lname);
+ darray_item(info->key_names, kc) = XKB_ATOM_NONE;
+ }
+ }
+
+ /* There's already a key with this name. */
+ old_kc = FindKeyByName(info, name);
+ if (old_kc != XKB_KEYCODE_INVALID && old_kc != kc) {
+ const char *kname = KeyNameText(info->ctx, name);
+
+ if (merge == MERGE_OVERRIDE) {
+ darray_item(info->key_names, old_kc) = XKB_ATOM_NONE;
+ if (report)
+ log_warn(info->ctx,
+ "Key name %s assigned to multiple keys; "
+ "Using %d, ignoring %d\n", kname, kc, old_kc);
+ }
+ else {
+ if (report)
+ log_vrb(info->ctx, 3,
+ "Key name %s assigned to multiple keys; "
+ "Using %d, ignoring %d\n", kname, old_kc, kc);
+ return true;
+ }
+ }
+
+ darray_item(info->key_names, kc) = name;
+ return true;
+}
+
+/***====================================================================***/
+
+static int
+HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge);
+
+static void
+MergeIncludedKeycodes(KeyNamesInfo *into, KeyNamesInfo *from,
+ enum merge_mode merge)
+{
+ if (from->errorCount > 0) {
+ into->errorCount += from->errorCount;
+ return;
+ }
+
+ if (into->name == NULL) {
+ into->name = from->name;
+ from->name = NULL;
+ }
+
+ /* Merge key names. */
+ if (darray_empty(into->key_names)) {
+ into->key_names = from->key_names;
+ darray_init(from->key_names);
+ into->min_key_code = from->min_key_code;
+ into->max_key_code = from->max_key_code;
+ }
+ else {
+ if (darray_size(into->key_names) < darray_size(from->key_names))
+ darray_resize0(into->key_names, darray_size(from->key_names));
+
+ for (unsigned i = from->min_key_code; i <= from->max_key_code; i++) {
+ xkb_atom_t name = darray_item(from->key_names, i);
+ if (name == XKB_ATOM_NONE)
+ continue;
+
+ if (!AddKeyName(into, i, name, merge, true, false))
+ into->errorCount++;
+ }
+ }
+
+ /* Merge key aliases. */
+ if (darray_empty(into->aliases)) {
+ into->aliases = from->aliases;
+ darray_init(from->aliases);
+ }
+ else {
+ AliasInfo *alias;
+
+ darray_foreach(alias, from->aliases) {
+ KeyAliasDef def;
+
+ def.merge = (merge == MERGE_DEFAULT ? alias->merge : merge);
+ def.alias = alias->alias;
+ def.real = alias->real;
+
+ if (!HandleAliasDef(into, &def, def.merge))
+ into->errorCount++;
+ }
+ }
+
+ /* Merge LED names. */
+ if (darray_empty(into->led_names)) {
+ into->led_names = from->led_names;
+ darray_init(from->led_names);
+ }
+ else {
+ xkb_led_index_t idx;
+ LedNameInfo *ledi;
+
+ darray_enumerate(idx, ledi, from->led_names) {
+ if (ledi->name == XKB_ATOM_NONE)
+ continue;
+
+ ledi->merge = (merge == MERGE_DEFAULT ? ledi->merge : merge);
+ if (!AddLedName(into, ledi->merge, false, ledi, idx))
+ into->errorCount++;
+ }
+ }
+}
+
+static void
+HandleKeycodesFile(KeyNamesInfo *info, XkbFile *file, enum merge_mode merge);
+
+static bool
+HandleIncludeKeycodes(KeyNamesInfo *info, IncludeStmt *include)
+{
+ KeyNamesInfo included;
+
+ InitKeyNamesInfo(&included, info->ctx);
+ included.name = include->stmt;
+ include->stmt = NULL;
+
+ for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) {
+ KeyNamesInfo next_incl;
+ XkbFile *file;
+
+ file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_KEYCODES);
+ if (!file) {
+ info->errorCount += 10;
+ ClearKeyNamesInfo(&included);
+ return false;
+ }
+
+ InitKeyNamesInfo(&next_incl, info->ctx);
+
+ HandleKeycodesFile(&next_incl, file, MERGE_OVERRIDE);
+
+ MergeIncludedKeycodes(&included, &next_incl, stmt->merge);
+
+ ClearKeyNamesInfo(&next_incl);
+ FreeXkbFile(file);
+ }
+
+ MergeIncludedKeycodes(info, &included, include->merge);
+ ClearKeyNamesInfo(&included);
+
+ return (info->errorCount == 0);
+}
+
+static bool
+HandleKeycodeDef(KeyNamesInfo *info, KeycodeDef *stmt, enum merge_mode merge)
+{
+ if (stmt->merge != MERGE_DEFAULT) {
+ if (stmt->merge == MERGE_REPLACE)
+ merge = MERGE_OVERRIDE;
+ else
+ merge = stmt->merge;
+ }
+
+ if (stmt->value < 0 || stmt->value > XKB_KEYCODE_MAX) {
+ log_err(info->ctx,
+ "Illegal keycode %lld: must be between 0..%u; "
+ "Key ignored\n", (long long) stmt->value, XKB_KEYCODE_MAX);
+ return false;
+ }
+
+ return AddKeyName(info, stmt->value, stmt->name, merge, false, true);
+}
+
+static int
+HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge)
+{
+ AliasInfo *old, new;
+
+ darray_foreach(old, info->aliases) {
+ if (old->alias == def->alias) {
+ if (def->real == old->real) {
+ log_vrb(info->ctx, 1,
+ "Alias of %s for %s declared more than once; "
+ "First definition ignored\n",
+ KeyNameText(info->ctx, def->alias),
+ KeyNameText(info->ctx, def->real));
+ }
+ else {
+ xkb_atom_t use, ignore;
+
+ use = (merge == MERGE_AUGMENT ? old->real : def->real);
+ ignore = (merge == MERGE_AUGMENT ? def->real : old->real);
+
+ log_warn(info->ctx,
+ "Multiple definitions for alias %s; "
+ "Using %s, ignoring %s\n",
+ KeyNameText(info->ctx, old->alias),
+ KeyNameText(info->ctx, use),
+ KeyNameText(info->ctx, ignore));
+
+ old->real = use;
+ }
+
+ old->merge = merge;
+ return true;
+ }
+ }
+
+ InitAliasInfo(&new, merge, def->alias, def->real);
+ darray_append(info->aliases, new);
+ return true;
+}
+
+static int
+HandleKeyNameVar(KeyNamesInfo *info, VarDef *stmt)
+{
+ const char *elem, *field;
+ ExprDef *arrayNdx;
+
+ if (!ExprResolveLhs(info->ctx, stmt->name, &elem, &field, &arrayNdx))
+ return false;
+
+ if (elem) {
+ log_err(info->ctx, "Unknown element %s encountered; "
+ "Default for field %s ignored\n", elem, field);
+ return false;
+ }
+
+ if (!istreq(field, "minimum") && !istreq(field, "maximum")) {
+ log_err(info->ctx, "Unknown field encountered; "
+ "Assignment to field %s ignored\n", field);
+ return false;
+ }
+
+ /* We ignore explicit min/max statements, we always use computed. */
+ return true;
+}
+
+static int
+HandleLedNameDef(KeyNamesInfo *info, LedNameDef *def,
+ enum merge_mode merge)
+{
+ LedNameInfo ledi;
+ xkb_atom_t name;
+
+ if (def->ndx < 1 || def->ndx > XKB_MAX_LEDS) {
+ info->errorCount++;
+ log_err(info->ctx,
+ "Illegal indicator index (%d) specified; must be between 1 .. %d; "
+ "Ignored\n", def->ndx, XKB_MAX_LEDS);
+ return false;
+ }
+
+ if (!ExprResolveString(info->ctx, def->name, &name)) {
+ char buf[20];
+ snprintf(buf, sizeof(buf), "%d", def->ndx);
+ info->errorCount++;
+ return ReportBadType(info->ctx, "indicator", "name", buf, "string");
+ }
+
+ ledi.merge = merge;
+ ledi.name = name;
+ return AddLedName(info, merge, true, &ledi, def->ndx - 1);
+}
+
+static void
+HandleKeycodesFile(KeyNamesInfo *info, XkbFile *file, enum merge_mode merge)
+{
+ bool ok;
+
+ free(info->name);
+ info->name = strdup_safe(file->name);
+
+ for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) {
+ switch (stmt->type) {
+ case STMT_INCLUDE:
+ ok = HandleIncludeKeycodes(info, (IncludeStmt *) stmt);
+ break;
+ case STMT_KEYCODE:
+ ok = HandleKeycodeDef(info, (KeycodeDef *) stmt, merge);
+ break;
+ case STMT_ALIAS:
+ ok = HandleAliasDef(info, (KeyAliasDef *) stmt, merge);
+ break;
+ case STMT_VAR:
+ ok = HandleKeyNameVar(info, (VarDef *) stmt);
+ break;
+ case STMT_LED_NAME:
+ ok = HandleLedNameDef(info, (LedNameDef *) stmt, merge);
+ break;
+ default:
+ log_err(info->ctx,
+ "Keycode files may define key and indicator names only; "
+ "Ignoring %s\n", stmt_type_to_string(stmt->type));
+ ok = false;
+ break;
+ }
+
+ if (!ok)
+ info->errorCount++;
+
+ if (info->errorCount > 10) {
+ log_err(info->ctx, "Abandoning keycodes file \"%s\"\n",
+ file->topName);
+ break;
+ }
+ }
+}
+
+/***====================================================================***/
+
+static bool
+CopyKeyNamesToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info)
+{
+ xkb_keycode_t kc;
+ xkb_led_index_t idx;
+ LedNameInfo *ledi;
+ AliasInfo *alias;
+ unsigned i;
+
+ keymap->keycodes_section_name = strdup_safe(info->name);
+
+ keymap->min_key_code = info->min_key_code;
+ keymap->max_key_code = info->max_key_code;
+
+ /* Copy key names. */
+ keymap->keys = calloc(info->max_key_code + 1, sizeof(*keymap->keys));
+ for (kc = info->min_key_code; kc <= info->max_key_code; kc++) {
+ keymap->keys[kc].keycode = kc;
+ keymap->keys[kc].name = darray_item(info->key_names, kc);
+ }
+
+ /*
+ * Do some sanity checking on the aliases. We can't do it before
+ * because keys and their aliases may be added out-of-order.
+ */
+ keymap->num_key_aliases = 0;
+ darray_foreach(alias, info->aliases) {
+ /* Check that ->real is a key. */
+ if (!XkbKeyByName(keymap, alias->real, false)) {
+ log_vrb(info->ctx, 5,
+ "Attempt to alias %s to non-existent key %s; Ignored\n",
+ KeyNameText(info->ctx, alias->alias),
+ KeyNameText(info->ctx, alias->real));
+ alias->real = XKB_ATOM_NONE;
+ continue;
+ }
+
+ /* Check that ->alias is not a key. */
+ if (XkbKeyByName(keymap, alias->alias, false)) {
+ log_vrb(info->ctx, 5,
+ "Attempt to create alias with the name of a real key; "
+ "Alias \"%s = %s\" ignored\n",
+ KeyNameText(info->ctx, alias->alias),
+ KeyNameText(info->ctx, alias->real));
+ alias->real = XKB_ATOM_NONE;
+ continue;
+ }
+
+ keymap->num_key_aliases++;
+ }
+
+ /* Copy key aliases. */
+ keymap->key_aliases = calloc(keymap->num_key_aliases,
+ sizeof(*keymap->key_aliases));
+ i = 0;
+ darray_foreach(alias, info->aliases) {
+ if (alias->real != XKB_ATOM_NONE) {
+ keymap->key_aliases[i].alias = alias->alias;
+ keymap->key_aliases[i].real = alias->real;
+ i++;
+ }
+ }
+
+ /* Copy LED names. */
+ darray_resize0(keymap->leds, darray_size(info->led_names));
+ darray_enumerate(idx, ledi, info->led_names)
+ if (ledi->name != XKB_ATOM_NONE)
+ darray_item(keymap->leds, idx).name = ledi->name;
+
+ return true;
+}
+
+/***====================================================================***/
+
+bool
+CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap,
+ enum merge_mode merge)
+{
+ KeyNamesInfo info;
+
+ InitKeyNamesInfo(&info, keymap->ctx);
+
+ HandleKeycodesFile(&info, file, merge);
+ if (info.errorCount != 0)
+ goto err_info;
+
+ if (!CopyKeyNamesToKeymap(keymap, &info))
+ goto err_info;
+
+ ClearKeyNamesInfo(&info);
+ return true;
+
+err_info:
+ ClearKeyNamesInfo(&info);
+ return false;
+}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c b/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c
new file mode 100644
index 0000000000..034a8c1af3
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c
@@ -0,0 +1,662 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ */
+
+#include "xkbcomp-priv.h"
+#include "text.h"
+
+#define BUF_CHUNK_SIZE 4096
+
+struct buf {
+ char *buf;
+ size_t size;
+ size_t alloc;
+};
+
+static bool
+do_realloc(struct buf *buf, size_t at_least)
+{
+ char *new;
+
+ buf->alloc += BUF_CHUNK_SIZE;
+ if (at_least >= BUF_CHUNK_SIZE)
+ buf->alloc += at_least;
+
+ new = realloc(buf->buf, buf->alloc);
+ if (!new)
+ return false;
+
+ buf->buf = new;
+ return true;
+}
+
+ATTR_PRINTF(2, 3) static bool
+check_write_buf(struct buf *buf, const char *fmt, ...)
+{
+ va_list args;
+ int printed;
+ size_t available;
+
+ available = buf->alloc - buf->size;
+ va_start(args, fmt);
+ printed = vsnprintf(buf->buf + buf->size, available, fmt, args);
+ va_end(args);
+
+ if (printed < 0)
+ goto err;
+
+ if (printed >= available)
+ if (!do_realloc(buf, printed))
+ goto err;
+
+ /* The buffer has enough space now. */
+
+ available = buf->alloc - buf->size;
+ va_start(args, fmt);
+ printed = vsnprintf(buf->buf + buf->size, available, fmt, args);
+ va_end(args);
+
+ if (printed >= available || printed < 0)
+ goto err;
+
+ buf->size += printed;
+ return true;
+
+err:
+ free(buf->buf);
+ buf->buf = NULL;
+ return false;
+}
+
+#define write_buf(buf, ...) do { \
+ if (!check_write_buf(buf, __VA_ARGS__)) \
+ return false; \
+} while (0)
+
+static bool
+write_vmods(struct xkb_keymap *keymap, struct buf *buf)
+{
+ const struct xkb_mod *mod;
+ xkb_mod_index_t num_vmods = 0;
+
+ darray_foreach(mod, keymap->mods) {
+ if (mod->type != MOD_VIRT)
+ continue;
+
+ if (num_vmods == 0)
+ write_buf(buf, "\tvirtual_modifiers ");
+ else
+ write_buf(buf, ",");
+ write_buf(buf, "%s", xkb_atom_text(keymap->ctx, mod->name));
+ num_vmods++;
+ }
+
+ if (num_vmods > 0)
+ write_buf(buf, ";\n\n");
+
+ return true;
+}
+
+static bool
+write_keycodes(struct xkb_keymap *keymap, struct buf *buf)
+{
+ const struct xkb_key *key;
+ xkb_led_index_t idx;
+ const struct xkb_led *led;
+
+ if (keymap->keycodes_section_name)
+ write_buf(buf, "xkb_keycodes \"%s\" {\n",
+ keymap->keycodes_section_name);
+ else
+ write_buf(buf, "xkb_keycodes {\n");
+
+ xkb_foreach_key(key, keymap) {
+ if (key->name == XKB_ATOM_NONE)
+ continue;
+
+ write_buf(buf, "\t%-20s = %d;\n",
+ KeyNameText(keymap->ctx, key->name), key->keycode);
+ }
+
+ darray_enumerate(idx, led, keymap->leds)
+ if (led->name != XKB_ATOM_NONE)
+ write_buf(buf, "\tindicator %d = \"%s\";\n",
+ idx + 1, xkb_atom_text(keymap->ctx, led->name));
+
+
+ for (unsigned i = 0; i < keymap->num_key_aliases; i++)
+ write_buf(buf, "\talias %-14s = %s;\n",
+ KeyNameText(keymap->ctx, keymap->key_aliases[i].alias),
+ KeyNameText(keymap->ctx, keymap->key_aliases[i].real));
+
+ write_buf(buf, "};\n\n");
+ return true;
+}
+
+static bool
+write_types(struct xkb_keymap *keymap, struct buf *buf)
+{
+ if (keymap->types_section_name)
+ write_buf(buf, "xkb_types \"%s\" {\n",
+ keymap->types_section_name);
+ else
+ write_buf(buf, "xkb_types {\n");
+
+ write_vmods(keymap, buf);
+
+ for (unsigned i = 0; i < keymap->num_types; i++) {
+ const struct xkb_key_type *type = &keymap->types[i];
+
+ write_buf(buf, "\ttype \"%s\" {\n",
+ xkb_atom_text(keymap->ctx, type->name));
+
+ write_buf(buf, "\t\tmodifiers= %s;\n",
+ ModMaskText(keymap, type->mods.mods));
+
+ for (unsigned j = 0; j < type->num_entries; j++) {
+ const char *str;
+ const struct xkb_key_type_entry *entry = &type->entries[j];
+
+ /*
+ * Printing level 1 entries is redundant, it's the default,
+ * unless there's preserve info.
+ */
+ if (entry->level == 0 && entry->preserve.mods == 0)
+ continue;
+
+ str = ModMaskText(keymap, entry->mods.mods);
+ write_buf(buf, "\t\tmap[%s]= Level%d;\n",
+ str, entry->level + 1);
+
+ if (entry->preserve.mods)
+ write_buf(buf, "\t\tpreserve[%s]= %s;\n",
+ str, ModMaskText(keymap, entry->preserve.mods));
+ }
+
+ for (xkb_level_index_t n = 0; n < type->num_levels; n++)
+ if (type->level_names[n])
+ write_buf(buf, "\t\tlevel_name[Level%d]= \"%s\";\n", n + 1,
+ xkb_atom_text(keymap->ctx, type->level_names[n]));
+
+ write_buf(buf, "\t};\n");
+ }
+
+ write_buf(buf, "};\n\n");
+ return true;
+}
+
+static bool
+write_led_map(struct xkb_keymap *keymap, struct buf *buf,
+ const struct xkb_led *led)
+{
+ write_buf(buf, "\tindicator \"%s\" {\n",
+ xkb_atom_text(keymap->ctx, led->name));
+
+ if (led->which_groups) {
+ if (led->which_groups != XKB_STATE_LAYOUT_EFFECTIVE) {
+ write_buf(buf, "\t\twhichGroupState= %s;\n",
+ LedStateMaskText(keymap->ctx, led->which_groups));
+ }
+ write_buf(buf, "\t\tgroups= 0x%02x;\n",
+ led->groups);
+ }
+
+ if (led->which_mods) {
+ if (led->which_mods != XKB_STATE_MODS_EFFECTIVE) {
+ write_buf(buf, "\t\twhichModState= %s;\n",
+ LedStateMaskText(keymap->ctx, led->which_mods));
+ }
+ write_buf(buf, "\t\tmodifiers= %s;\n",
+ ModMaskText(keymap, led->mods.mods));
+ }
+
+ if (led->ctrls) {
+ write_buf(buf, "\t\tcontrols= %s;\n",
+ ControlMaskText(keymap->ctx, led->ctrls));
+ }
+
+ write_buf(buf, "\t};\n");
+ return true;
+}
+
+static bool
+write_action(struct xkb_keymap *keymap, struct buf *buf,
+ const union xkb_action *action,
+ const char *prefix, const char *suffix)
+{
+ const char *type;
+ const char *args = NULL;
+
+ if (!prefix)
+ prefix = "";
+ if (!suffix)
+ suffix = "";
+
+ type = ActionTypeText(action->type);
+
+ switch (action->type) {
+ case ACTION_TYPE_MOD_SET:
+ case ACTION_TYPE_MOD_LATCH:
+ case ACTION_TYPE_MOD_LOCK:
+ if (action->mods.flags & ACTION_MODS_LOOKUP_MODMAP)
+ args = "modMapMods";
+ else
+ args = ModMaskText(keymap, action->mods.mods.mods);
+ write_buf(buf, "%s%s(modifiers=%s%s%s)%s", prefix, type, args,
+ (action->type != ACTION_TYPE_MOD_LOCK &&
+ (action->mods.flags & ACTION_LOCK_CLEAR)) ?
+ ",clearLocks" : "",
+ (action->type != ACTION_TYPE_MOD_LOCK &&
+ (action->mods.flags & ACTION_LATCH_TO_LOCK)) ?
+ ",latchToLock" : "",
+ suffix);
+ break;
+
+ case ACTION_TYPE_GROUP_SET:
+ case ACTION_TYPE_GROUP_LATCH:
+ case ACTION_TYPE_GROUP_LOCK:
+ write_buf(buf, "%s%s(group=%s%d%s%s)%s", prefix, type,
+ (!(action->group.flags & ACTION_ABSOLUTE_SWITCH) &&
+ action->group.group > 0) ? "+" : "",
+ (action->group.flags & ACTION_ABSOLUTE_SWITCH) ?
+ action->group.group + 1 : action->group.group,
+ (action->type != ACTION_TYPE_GROUP_LOCK &&
+ (action->group.flags & ACTION_LOCK_CLEAR)) ?
+ ",clearLocks" : "",
+ (action->type != ACTION_TYPE_GROUP_LOCK &&
+ (action->group.flags & ACTION_LATCH_TO_LOCK)) ?
+ ",latchToLock" : "",
+ suffix);
+ break;
+
+ case ACTION_TYPE_TERMINATE:
+ write_buf(buf, "%s%s()%s", prefix, type, suffix);
+ break;
+
+ case ACTION_TYPE_PTR_MOVE:
+ write_buf(buf, "%s%s(x=%s%d,y=%s%d%s)%s", prefix, type,
+ (!(action->ptr.flags & ACTION_ABSOLUTE_X) &&
+ action->ptr.x >= 0) ? "+" : "",
+ action->ptr.x,
+ (!(action->ptr.flags & ACTION_ABSOLUTE_Y) &&
+ action->ptr.y >= 0) ? "+" : "",
+ action->ptr.y,
+ (action->ptr.flags & ACTION_NO_ACCEL) ? ",!accel" : "",
+ suffix);
+ break;
+
+ case ACTION_TYPE_PTR_LOCK:
+ switch (action->btn.flags &
+ (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK)) {
+ case ACTION_LOCK_NO_UNLOCK:
+ args = ",affect=lock";
+ break;
+
+ case ACTION_LOCK_NO_LOCK:
+ args = ",affect=unlock";
+ break;
+
+ case ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK:
+ args = ",affect=neither";
+ break;
+
+ default:
+ args = ",affect=both";
+ break;
+ }
+ case ACTION_TYPE_PTR_BUTTON:
+ write_buf(buf, "%s%s(button=", prefix, type);
+ if (action->btn.button > 0 && action->btn.button <= 5)
+ write_buf(buf, "%d", action->btn.button);
+ else
+ write_buf(buf, "default");
+ if (action->btn.count)
+ write_buf(buf, ",count=%d", action->btn.count);
+ if (args)
+ write_buf(buf, "%s", args);
+ write_buf(buf, ")%s", suffix);
+ break;
+
+ case ACTION_TYPE_PTR_DEFAULT:
+ write_buf(buf, "%s%s(", prefix, type);
+ write_buf(buf, "affect=button,button=%s%d",
+ (!(action->dflt.flags & ACTION_ABSOLUTE_SWITCH) &&
+ action->dflt.value >= 0) ? "+" : "",
+ action->dflt.value);
+ write_buf(buf, ")%s", suffix);
+ break;
+
+ case ACTION_TYPE_SWITCH_VT:
+ write_buf(buf, "%s%s(screen=%s%d,%ssame)%s", prefix, type,
+ (!(action->screen.flags & ACTION_ABSOLUTE_SWITCH) &&
+ action->screen.screen >= 0) ? "+" : "",
+ action->screen.screen,
+ (action->screen.flags & ACTION_SAME_SCREEN) ? "!" : "",
+ suffix);
+ break;
+
+ case ACTION_TYPE_CTRL_SET:
+ case ACTION_TYPE_CTRL_LOCK:
+ write_buf(buf, "%s%s(controls=%s)%s", prefix, type,
+ ControlMaskText(keymap->ctx, action->ctrls.ctrls), suffix);
+ break;
+
+ case ACTION_TYPE_NONE:
+ write_buf(buf, "%sNoAction()%s", prefix, suffix);
+ break;
+
+ default:
+ write_buf(buf,
+ "%s%s(type=0x%02x,data[0]=0x%02x,data[1]=0x%02x,data[2]=0x%02x,data[3]=0x%02x,data[4]=0x%02x,data[5]=0x%02x,data[6]=0x%02x)%s",
+ prefix, type, action->type, action->priv.data[0],
+ action->priv.data[1], action->priv.data[2],
+ action->priv.data[3], action->priv.data[4],
+ action->priv.data[5], action->priv.data[6],
+ suffix);
+ break;
+ }
+
+ return true;
+}
+
+static bool
+write_compat(struct xkb_keymap *keymap, struct buf *buf)
+{
+ const struct xkb_sym_interpret *si;
+ const struct xkb_led *led;
+
+ if (keymap->compat_section_name)
+ write_buf(buf, "xkb_compatibility \"%s\" {\n",
+ keymap->compat_section_name);
+ else
+ write_buf(buf, "xkb_compatibility {\n");
+
+ write_vmods(keymap, buf);
+
+ write_buf(buf, "\tinterpret.useModMapMods= AnyLevel;\n");
+ write_buf(buf, "\tinterpret.repeat= False;\n");
+
+ darray_foreach(si, keymap->sym_interprets) {
+ write_buf(buf, "\tinterpret %s+%s(%s) {\n",
+ si->sym ? KeysymText(keymap->ctx, si->sym) : "Any",
+ SIMatchText(si->match),
+ ModMaskText(keymap, si->mods));
+
+ if (si->virtual_mod != XKB_MOD_INVALID)
+ write_buf(buf, "\t\tvirtualModifier= %s;\n",
+ ModIndexText(keymap, si->virtual_mod));
+
+ if (si->level_one_only)
+ write_buf(buf, "\t\tuseModMapMods=level1;\n");
+
+ if (si->repeat)
+ write_buf(buf, "\t\trepeat= True;\n");
+
+ write_action(keymap, buf, &si->action, "\t\taction= ", ";\n");
+ write_buf(buf, "\t};\n");
+ }
+
+ darray_foreach(led, keymap->leds)
+ if (led->which_groups || led->groups || led->which_mods ||
+ led->mods.mods || led->ctrls)
+ write_led_map(keymap, buf, led);
+
+ write_buf(buf, "};\n\n");
+
+ return true;
+}
+
+static bool
+write_keysyms(struct xkb_keymap *keymap, struct buf *buf,
+ const struct xkb_key *key, xkb_layout_index_t group)
+{
+ for (xkb_level_index_t level = 0; level < XkbKeyGroupWidth(key, group);
+ level++) {
+ const xkb_keysym_t *syms;
+ int num_syms;
+
+ if (level != 0)
+ write_buf(buf, ", ");
+
+ num_syms = xkb_keymap_key_get_syms_by_level(keymap, key->keycode,
+ group, level, &syms);
+ if (num_syms == 0) {
+ write_buf(buf, "%15s", "NoSymbol");
+ }
+ else if (num_syms == 1) {
+ write_buf(buf, "%15s", KeysymText(keymap->ctx, syms[0]));
+ }
+ else {
+ write_buf(buf, "{ ");
+ for (int s = 0; s < num_syms; s++) {
+ if (s != 0)
+ write_buf(buf, ", ");
+ write_buf(buf, "%s", KeysymText(keymap->ctx, syms[s]));
+ }
+ write_buf(buf, " }");
+ }
+ }
+
+ return true;
+}
+
+static bool
+write_key(struct xkb_keymap *keymap, struct buf *buf,
+ const struct xkb_key *key)
+{
+ xkb_layout_index_t group;
+ bool simple = true;
+ bool explicit_types = false;
+ bool multi_type = false;
+ bool show_actions;
+
+ write_buf(buf, "\tkey %-20s {", KeyNameText(keymap->ctx, key->name));
+
+ for (group = 0; group < key->num_groups; group++) {
+ if (key->groups[group].explicit_type)
+ explicit_types = true;
+
+ if (group != 0 && key->groups[group].type != key->groups[0].type)
+ multi_type = true;
+ }
+
+ if (explicit_types) {
+ const struct xkb_key_type *type;
+ simple = false;
+
+ if (multi_type) {
+ for (group = 0; group < key->num_groups; group++) {
+ if (!key->groups[group].explicit_type)
+ continue;
+
+ type = key->groups[group].type;
+ write_buf(buf, "\n\t\ttype[group%u]= \"%s\",",
+ group + 1,
+ xkb_atom_text(keymap->ctx, type->name));
+ }
+ }
+ else {
+ type = key->groups[0].type;
+ write_buf(buf, "\n\t\ttype= \"%s\",",
+ xkb_atom_text(keymap->ctx, type->name));
+ }
+ }
+
+ if (key->explicit & EXPLICIT_REPEAT) {
+ if (key->repeats)
+ write_buf(buf, "\n\t\trepeat= Yes,");
+ else
+ write_buf(buf, "\n\t\trepeat= No,");
+ simple = false;
+ }
+
+ if (key->vmodmap && (key->explicit & EXPLICIT_VMODMAP))
+ write_buf(buf, "\n\t\tvirtualMods= %s,",
+ ModMaskText(keymap, key->vmodmap));
+
+ switch (key->out_of_range_group_action) {
+ case RANGE_SATURATE:
+ write_buf(buf, "\n\t\tgroupsClamp,");
+ break;
+
+ case RANGE_REDIRECT:
+ write_buf(buf, "\n\t\tgroupsRedirect= Group%u,",
+ key->out_of_range_group_number + 1);
+ break;
+
+ default:
+ break;
+ }
+
+ show_actions = !!(key->explicit & EXPLICIT_INTERP);
+
+ if (key->num_groups > 1 || show_actions)
+ simple = false;
+
+ if (simple) {
+ write_buf(buf, "\t[ ");
+ if (!write_keysyms(keymap, buf, key, 0))
+ return false;
+ write_buf(buf, " ] };\n");
+ }
+ else {
+ xkb_level_index_t level;
+
+ for (group = 0; group < key->num_groups; group++) {
+ if (group != 0)
+ write_buf(buf, ",");
+ write_buf(buf, "\n\t\tsymbols[Group%u]= [ ", group + 1);
+ if (!write_keysyms(keymap, buf, key, group))
+ return false;
+ write_buf(buf, " ]");
+ if (show_actions) {
+ write_buf(buf, ",\n\t\tactions[Group%u]= [ ", group + 1);
+ for (level = 0;
+ level < XkbKeyGroupWidth(key, group); level++) {
+ if (level != 0)
+ write_buf(buf, ", ");
+ write_action(keymap, buf,
+ &key->groups[group].levels[level].action,
+ NULL, NULL);
+ }
+ write_buf(buf, " ]");
+ }
+ }
+ write_buf(buf, "\n\t};\n");
+ }
+
+ return true;
+}
+
+static bool
+write_symbols(struct xkb_keymap *keymap, struct buf *buf)
+{
+ const struct xkb_key *key;
+ xkb_layout_index_t group;
+
+ if (keymap->symbols_section_name)
+ write_buf(buf, "xkb_symbols \"%s\" {\n",
+ keymap->symbols_section_name);
+ else
+ write_buf(buf, "xkb_symbols {\n");
+
+ for (group = 0; group < keymap->num_group_names; group++)
+ if (keymap->group_names[group])
+ write_buf(buf,
+ "\tname[group%d]=\"%s\";\n", group + 1,
+ xkb_atom_text(keymap->ctx, keymap->group_names[group]));
+ if (group > 0)
+ write_buf(buf, "\n");
+
+ xkb_foreach_key(key, keymap)
+ if (key->num_groups > 0)
+ write_key(keymap, buf, key);
+
+ xkb_foreach_key(key, keymap) {
+ xkb_mod_index_t i;
+ const struct xkb_mod *mod;
+
+ if (key->modmap == 0)
+ continue;
+
+ darray_enumerate(i, mod, keymap->mods)
+ if (key->modmap & (1 << i))
+ write_buf(buf, "\tmodifier_map %s { %s };\n",
+ xkb_atom_text(keymap->ctx, mod->name),
+ KeyNameText(keymap->ctx, key->name));
+ }
+
+ write_buf(buf, "};\n\n");
+ return true;
+}
+
+static bool
+write_keymap(struct xkb_keymap *keymap, struct buf *buf)
+{
+ return (check_write_buf(buf, "xkb_keymap {\n") &&
+ write_keycodes(keymap, buf) &&
+ write_types(keymap, buf) &&
+ write_compat(keymap, buf) &&
+ write_symbols(keymap, buf) &&
+ check_write_buf(buf, "};\n"));
+}
+
+char *
+text_v1_keymap_get_as_string(struct xkb_keymap *keymap)
+{
+ struct buf buf = { NULL, 0, 0 };
+
+ if (!write_keymap(keymap, &buf)) {
+ free(buf.buf);
+ return NULL;
+ }
+
+ return buf.buf;
+}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c b/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c
new file mode 100644
index 0000000000..bed3930be9
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c
@@ -0,0 +1,333 @@
+/*
+ * Copyright © 2009 Dan Nicholson
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Dan Nicholson <dbn.lists@gmail.com>
+ * Daniel Stone <daniel@fooishbar.org>
+ * Ran Benita <ran234@gmail.com>
+ */
+
+#include "xkbcomp-priv.h"
+
+static void
+ComputeEffectiveMask(struct xkb_keymap *keymap, struct xkb_mods *mods)
+{
+ const struct xkb_mod *mod;
+ xkb_mod_index_t i;
+
+ /* The effective mask is only real mods for now. */
+ mods->mask = mods->mods & MOD_REAL_MASK_ALL;
+
+ darray_enumerate(i, mod, keymap->mods)
+ if (mods->mods & (1 << i))
+ mods->mask |= mod->mapping;
+}
+
+static void
+UpdateActionMods(struct xkb_keymap *keymap, union xkb_action *act,
+ xkb_mod_mask_t modmap)
+{
+ switch (act->type) {
+ case ACTION_TYPE_MOD_SET:
+ case ACTION_TYPE_MOD_LATCH:
+ case ACTION_TYPE_MOD_LOCK:
+ if (act->mods.flags & ACTION_MODS_LOOKUP_MODMAP)
+ act->mods.mods.mods = modmap;
+ ComputeEffectiveMask(keymap, &act->mods.mods);
+ break;
+ default:
+ break;
+ }
+}
+
+static const struct xkb_sym_interpret default_interpret = {
+ .sym = XKB_KEY_NoSymbol,
+ .repeat = true,
+ .match = MATCH_ANY_OR_NONE,
+ .mods = 0,
+ .virtual_mod = XKB_MOD_INVALID,
+ .action = { .type = ACTION_TYPE_NONE },
+};
+
+/**
+ * Find an interpretation which applies to this particular level, either by
+ * finding an exact match for the symbol and modifier combination, or a
+ * generic XKB_KEY_NoSymbol match.
+ */
+static const struct xkb_sym_interpret *
+FindInterpForKey(struct xkb_keymap *keymap, const struct xkb_key *key,
+ xkb_layout_index_t group, xkb_level_index_t level)
+{
+ const struct xkb_sym_interpret *interp;
+ const xkb_keysym_t *syms;
+ int num_syms;
+
+ num_syms = xkb_keymap_key_get_syms_by_level(keymap, key->keycode, group,
+ level, &syms);
+ if (num_syms == 0)
+ return NULL;
+
+ /*
+ * There may be multiple matchings interprets; we should always return
+ * the most specific. Here we rely on compat.c to set up the
+ * sym_interprets array from the most specific to the least specific,
+ * such that when we find a match we return immediately.
+ */
+ darray_foreach(interp, keymap->sym_interprets) {
+ xkb_mod_mask_t mods;
+ bool found = false;
+
+ if ((num_syms > 1 || interp->sym != syms[0]) &&
+ interp->sym != XKB_KEY_NoSymbol)
+ continue;
+
+ if (interp->level_one_only && level != 0)
+ mods = 0;
+ else
+ mods = key->modmap;
+
+ switch (interp->match) {
+ case MATCH_NONE:
+ found = !(interp->mods & mods);
+ break;
+ case MATCH_ANY_OR_NONE:
+ found = (!mods || (interp->mods & mods));
+ break;
+ case MATCH_ANY:
+ found = !!(interp->mods & mods);
+ break;
+ case MATCH_ALL:
+ found = ((interp->mods & mods) == interp->mods);
+ break;
+ case MATCH_EXACTLY:
+ found = (interp->mods == mods);
+ break;
+ }
+
+ if (found)
+ return interp;
+ }
+
+ return &default_interpret;
+}
+
+static bool
+ApplyInterpsToKey(struct xkb_keymap *keymap, struct xkb_key *key)
+{
+ xkb_mod_mask_t vmodmap = 0;
+ xkb_layout_index_t group;
+ xkb_level_index_t level;
+
+ /* If we've been told not to bind interps to this key, then don't. */
+ if (key->explicit & EXPLICIT_INTERP)
+ return true;
+
+ for (group = 0; group < key->num_groups; group++) {
+ for (level = 0; level < XkbKeyGroupWidth(key, group); level++) {
+ const struct xkb_sym_interpret *interp;
+
+ interp = FindInterpForKey(keymap, key, group, level);
+ if (!interp)
+ continue;
+
+ /* Infer default key behaviours from the base level. */
+ if (group == 0 && level == 0)
+ if (!(key->explicit & EXPLICIT_REPEAT) && interp->repeat)
+ key->repeats = true;
+
+ if ((group == 0 && level == 0) || !interp->level_one_only)
+ if (interp->virtual_mod != XKB_MOD_INVALID)
+ vmodmap |= (1 << interp->virtual_mod);
+
+ if (interp->action.type != ACTION_TYPE_NONE)
+ key->groups[group].levels[level].action = interp->action;
+ }
+ }
+
+ if (!(key->explicit & EXPLICIT_VMODMAP))
+ key->vmodmap = vmodmap;
+
+ return true;
+}
+
+/**
+ * This collects a bunch of disparate functions which was done in the server
+ * at various points that really should've been done within xkbcomp. Turns out
+ * your actions and types are a lot more useful when any of your modifiers
+ * other than Shift actually do something ...
+ */
+static bool
+UpdateDerivedKeymapFields(struct xkb_keymap *keymap)
+{
+ struct xkb_mod *mod;
+ struct xkb_led *led;
+ unsigned int i, j;
+ struct xkb_key *key;
+
+ /* Find all the interprets for the key and bind them to actions,
+ * which will also update the vmodmap. */
+ xkb_foreach_key(key, keymap)
+ if (!ApplyInterpsToKey(keymap, key))
+ return false;
+
+ /* Update keymap->mods, the virtual -> real mod mapping. */
+ xkb_foreach_key(key, keymap)
+ darray_enumerate(i, mod, keymap->mods)
+ if (key->vmodmap & (1 << i))
+ mod->mapping |= key->modmap;
+
+ /* Now update the level masks for all the types to reflect the vmods. */
+ for (i = 0; i < keymap->num_types; i++) {
+ ComputeEffectiveMask(keymap, &keymap->types[i].mods);
+
+ for (j = 0; j < keymap->types[i].num_entries; j++) {
+ ComputeEffectiveMask(keymap, &keymap->types[i].entries[j].mods);
+ ComputeEffectiveMask(keymap, &keymap->types[i].entries[j].preserve);
+ }
+ }
+
+ /* Update action modifiers. */
+ xkb_foreach_key(key, keymap)
+ for (i = 0; i < key->num_groups; i++)
+ for (j = 0; j < XkbKeyGroupWidth(key, i); j++)
+ UpdateActionMods(keymap, &key->groups[i].levels[j].action,
+ key->modmap);
+
+ /* Update vmod -> led maps. */
+ darray_foreach(led, keymap->leds)
+ ComputeEffectiveMask(keymap, &led->mods);
+
+ /* Find maximum number of groups out of all keys in the keymap. */
+ xkb_foreach_key(key, keymap)
+ keymap->num_groups = MAX(keymap->num_groups, key->num_groups);
+
+ return true;
+}
+
+static bool
+UpdateBuiltinKeymapFields(struct xkb_keymap *keymap)
+{
+ struct xkb_context *ctx = keymap->ctx;
+
+ /*
+ * Add predefined (AKA real, core, X11) modifiers.
+ * The order is important!
+ */
+ darray_appends_t(keymap->mods, struct xkb_mod,
+ { .name = xkb_atom_intern(ctx, "Shift"), .type = MOD_REAL },
+ { .name = xkb_atom_intern(ctx, "Lock"), .type = MOD_REAL },
+ { .name = xkb_atom_intern(ctx, "Control"), .type = MOD_REAL },
+ { .name = xkb_atom_intern(ctx, "Mod1"), .type = MOD_REAL },
+ { .name = xkb_atom_intern(ctx, "Mod2"), .type = MOD_REAL },
+ { .name = xkb_atom_intern(ctx, "Mod3"), .type = MOD_REAL },
+ { .name = xkb_atom_intern(ctx, "Mod4"), .type = MOD_REAL },
+ { .name = xkb_atom_intern(ctx, "Mod5"), .type = MOD_REAL });
+
+ return true;
+}
+
+typedef bool (*compile_file_fn)(XkbFile *file,
+ struct xkb_keymap *keymap,
+ enum merge_mode merge);
+
+static const compile_file_fn compile_file_fns[LAST_KEYMAP_FILE_TYPE + 1] = {
+ [FILE_TYPE_KEYCODES] = CompileKeycodes,
+ [FILE_TYPE_TYPES] = CompileKeyTypes,
+ [FILE_TYPE_COMPAT] = CompileCompatMap,
+ [FILE_TYPE_SYMBOLS] = CompileSymbols,
+};
+
+bool
+CompileKeymap(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
+{
+ bool ok;
+ const char *main_name;
+ XkbFile *files[LAST_KEYMAP_FILE_TYPE + 1] = { NULL };
+ enum xkb_file_type type;
+ struct xkb_context *ctx = keymap->ctx;
+
+ main_name = file->name ? file->name : "(unnamed)";
+
+ /* Collect section files and check for duplicates. */
+ for (file = (XkbFile *) file->defs; file;
+ file = (XkbFile *) file->common.next) {
+ if (file->file_type < FIRST_KEYMAP_FILE_TYPE ||
+ file->file_type > LAST_KEYMAP_FILE_TYPE) {
+ log_err(ctx, "Cannot define %s in a keymap file\n",
+ xkb_file_type_to_string(file->file_type));
+ continue;
+ }
+
+ if (files[file->file_type]) {
+ log_err(ctx,
+ "More than one %s section in keymap file; "
+ "All sections after the first ignored\n",
+ xkb_file_type_to_string(file->file_type));
+ continue;
+ }
+
+ if (!file->topName) {
+ free(file->topName);
+ file->topName = strdup(main_name);
+ }
+
+ files[file->file_type] = file;
+ }
+
+ /*
+ * Check that all required section were provided.
+ * Report everything before failing.
+ */
+ ok = true;
+ for (type = FIRST_KEYMAP_FILE_TYPE;
+ type <= LAST_KEYMAP_FILE_TYPE;
+ type++) {
+ if (files[type] == NULL) {
+ log_err(ctx, "Required section %s missing from keymap\n",
+ xkb_file_type_to_string(type));
+ ok = false;
+ }
+ }
+ if (!ok)
+ return false;
+
+ if (!UpdateBuiltinKeymapFields(keymap))
+ return false;
+
+ /* Compile sections. */
+ for (type = FIRST_KEYMAP_FILE_TYPE;
+ type <= LAST_KEYMAP_FILE_TYPE;
+ type++) {
+ log_dbg(ctx, "Compiling %s \"%s\"\n",
+ xkb_file_type_to_string(type), files[type]->topName);
+
+ ok = compile_file_fns[type](files[type], keymap, merge);
+ if (!ok) {
+ log_err(ctx, "Failed to compile %s\n",
+ xkb_file_type_to_string(type));
+ return false;
+ }
+ }
+
+ return UpdateDerivedKeymapFields(keymap);
+}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h b/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h
new file mode 100644
index 0000000000..2e02db66a8
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h
@@ -0,0 +1,47 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#ifndef XKBCOMP_PARSER_PRIV_H
+#define XKBCOMP_PARSER_PRIV_H
+
+struct scanner_extra;
+struct parser_param;
+
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#pragma GCC diagnostic push
+#include "parser.h"
+#pragma GCC diagnostic pop
+
+void
+scanner_error(YYLTYPE *loc, void *scanner, const char *msg);
+
+int
+_xkbcommon_lex(YYSTYPE *val, YYLTYPE *loc, void *scanner);
+
+XkbFile *
+parse(struct xkb_context *ctx, void *scanner, const char *map);
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser.c b/src/3rdparty/xkbcommon/src/xkbcomp/parser.c
new file mode 100644
index 0000000000..e1280e9180
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser.c
@@ -0,0 +1,3674 @@
+/* A Bison parser, made by GNU Bison 2.5. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.5"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 1
+
+/* Substitute the variable and function names. */
+#define yyparse _xkbcommon_parse
+#define yylex _xkbcommon_lex
+#define yyerror _xkbcommon_error
+#define yylval _xkbcommon_lval
+#define yychar _xkbcommon_char
+#define yydebug _xkbcommon_debug
+#define yynerrs _xkbcommon_nerrs
+#define yylloc _xkbcommon_lloc
+
+/* Copy the first part of user declarations. */
+
+/* Line 268 of yacc.c */
+#line 27 "parser.y"
+
+#include "xkbcomp-priv.h"
+#include "ast-build.h"
+#include "parser-priv.h"
+
+struct parser_param {
+ struct xkb_context *ctx;
+ void *scanner;
+ XkbFile *rtrn;
+ bool more_maps;
+};
+
+static void
+_xkbcommon_error(struct YYLTYPE *loc, struct parser_param *param, const char *msg)
+{
+ scanner_error(loc, param->scanner, msg);
+}
+
+#define scanner param->scanner
+
+
+/* Line 268 of yacc.c */
+#line 101 "src/xkbcomp/parser.c"
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ END_OF_FILE = 0,
+ ERROR_TOK = 255,
+ XKB_KEYMAP = 1,
+ XKB_KEYCODES = 2,
+ XKB_TYPES = 3,
+ XKB_SYMBOLS = 4,
+ XKB_COMPATMAP = 5,
+ XKB_GEOMETRY = 6,
+ XKB_SEMANTICS = 7,
+ XKB_LAYOUT = 8,
+ INCLUDE = 10,
+ OVERRIDE = 11,
+ AUGMENT = 12,
+ REPLACE = 13,
+ ALTERNATE = 14,
+ VIRTUAL_MODS = 20,
+ TYPE = 21,
+ INTERPRET = 22,
+ ACTION_TOK = 23,
+ KEY = 24,
+ ALIAS = 25,
+ GROUP = 26,
+ MODIFIER_MAP = 27,
+ INDICATOR = 28,
+ SHAPE = 29,
+ KEYS = 30,
+ ROW = 31,
+ SECTION = 32,
+ OVERLAY = 33,
+ TEXT = 34,
+ OUTLINE = 35,
+ SOLID = 36,
+ LOGO = 37,
+ VIRTUAL = 38,
+ EQUALS = 40,
+ PLUS = 41,
+ MINUS = 42,
+ DIVIDE = 43,
+ TIMES = 44,
+ OBRACE = 45,
+ CBRACE = 46,
+ OPAREN = 47,
+ CPAREN = 48,
+ OBRACKET = 49,
+ CBRACKET = 50,
+ DOT = 51,
+ COMMA = 52,
+ SEMI = 53,
+ EXCLAM = 54,
+ INVERT = 55,
+ STRING = 60,
+ INTEGER = 61,
+ FLOAT = 62,
+ IDENT = 63,
+ KEYNAME = 64,
+ PARTIAL = 70,
+ DEFAULT = 71,
+ HIDDEN = 72,
+ ALPHANUMERIC_KEYS = 73,
+ MODIFIER_KEYS = 74,
+ KEYPAD_KEYS = 75,
+ FUNCTION_KEYS = 76,
+ ALTERNATE_GROUP = 77
+ };
+#endif
+/* Tokens. */
+#define END_OF_FILE 0
+#define ERROR_TOK 255
+#define XKB_KEYMAP 1
+#define XKB_KEYCODES 2
+#define XKB_TYPES 3
+#define XKB_SYMBOLS 4
+#define XKB_COMPATMAP 5
+#define XKB_GEOMETRY 6
+#define XKB_SEMANTICS 7
+#define XKB_LAYOUT 8
+#define INCLUDE 10
+#define OVERRIDE 11
+#define AUGMENT 12
+#define REPLACE 13
+#define ALTERNATE 14
+#define VIRTUAL_MODS 20
+#define TYPE 21
+#define INTERPRET 22
+#define ACTION_TOK 23
+#define KEY 24
+#define ALIAS 25
+#define GROUP 26
+#define MODIFIER_MAP 27
+#define INDICATOR 28
+#define SHAPE 29
+#define KEYS 30
+#define ROW 31
+#define SECTION 32
+#define OVERLAY 33
+#define TEXT 34
+#define OUTLINE 35
+#define SOLID 36
+#define LOGO 37
+#define VIRTUAL 38
+#define EQUALS 40
+#define PLUS 41
+#define MINUS 42
+#define DIVIDE 43
+#define TIMES 44
+#define OBRACE 45
+#define CBRACE 46
+#define OPAREN 47
+#define CPAREN 48
+#define OBRACKET 49
+#define CBRACKET 50
+#define DOT 51
+#define COMMA 52
+#define SEMI 53
+#define EXCLAM 54
+#define INVERT 55
+#define STRING 60
+#define INTEGER 61
+#define FLOAT 62
+#define IDENT 63
+#define KEYNAME 64
+#define PARTIAL 70
+#define DEFAULT 71
+#define HIDDEN 72
+#define ALPHANUMERIC_KEYS 73
+#define MODIFIER_KEYS 74
+#define KEYPAD_KEYS 75
+#define FUNCTION_KEYS 76
+#define ALTERNATE_GROUP 77
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 293 of yacc.c */
+#line 127 "parser.y"
+
+ int ival;
+ unsigned uval;
+ int64_t num;
+ enum xkb_file_type file_type;
+ char *str;
+ xkb_atom_t sval;
+ enum merge_mode merge;
+ enum xkb_map_flags mapFlags;
+ ParseCommon *any;
+ ExprDef *expr;
+ VarDef *var;
+ VModDef *vmod;
+ InterpDef *interp;
+ KeyTypeDef *keyType;
+ SymbolsDef *syms;
+ ModMapDef *modMask;
+ GroupCompatDef *groupCompat;
+ LedMapDef *ledMap;
+ LedNameDef *ledName;
+ KeycodeDef *keyCode;
+ KeyAliasDef *keyAlias;
+ void *geom;
+ XkbFile *file;
+
+
+
+/* Line 293 of yacc.c */
+#line 295 "src/xkbcomp/parser.c"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 343 of yacc.c */
+#line 320 "src/xkbcomp/parser.c"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+ int yyi;
+#endif
+{
+ return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+ YYLTYPE yyls_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 16
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 735
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 65
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 72
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 184
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 334
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 257
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 4, 5, 6, 7, 8, 9, 10, 11, 2,
+ 12, 13, 14, 15, 16, 2, 2, 2, 2, 2,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 2,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 2, 2, 2, 2,
+ 52, 53, 54, 55, 56, 2, 2, 2, 2, 2,
+ 57, 58, 59, 60, 61, 62, 63, 64, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 3, 1, 2
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint16 yyprhs[] =
+{
+ 0, 0, 3, 5, 7, 9, 17, 19, 21, 23,
+ 26, 28, 36, 38, 40, 42, 44, 46, 48, 49,
+ 52, 54, 56, 58, 60, 62, 64, 66, 68, 70,
+ 73, 74, 77, 80, 83, 86, 89, 92, 95, 98,
+ 101, 104, 107, 110, 113, 116, 119, 124, 127, 131,
+ 136, 142, 146, 150, 152, 154, 158, 165, 169, 171,
+ 174, 176, 183, 190, 194, 196, 197, 201, 205, 207,
+ 210, 212, 216, 220, 226, 233, 240, 246, 253, 260,
+ 267, 274, 277, 279, 285, 287, 289, 291, 293, 296,
+ 298, 304, 306, 310, 312, 314, 318, 325, 329, 331,
+ 335, 339, 341, 345, 351, 355, 359, 361, 367, 374,
+ 376, 378, 380, 382, 384, 386, 388, 390, 392, 394,
+ 396, 398, 400, 402, 404, 406, 408, 410, 411, 413,
+ 415, 417, 419, 421, 423, 424, 428, 430, 434, 438,
+ 442, 446, 450, 452, 455, 458, 461, 464, 466, 471,
+ 473, 477, 481, 483, 488, 490, 494, 499, 506, 508,
+ 510, 512, 514, 516, 517, 521, 525, 527, 529, 533,
+ 535, 537, 539, 542, 544, 546, 548, 550, 552, 554,
+ 556, 558, 560, 562, 563
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int16 yyrhs[] =
+{
+ 66, 0, -1, 67, -1, 70, -1, 0, -1, 72,
+ 68, 135, 41, 69, 42, 49, -1, 4, -1, 10,
+ -1, 11, -1, 69, 70, -1, 70, -1, 72, 71,
+ 135, 41, 75, 42, 49, -1, 5, -1, 6, -1,
+ 8, -1, 7, -1, 9, -1, 73, -1, -1, 73,
+ 74, -1, 74, -1, 57, -1, 58, -1, 59, -1,
+ 60, -1, 61, -1, 62, -1, 63, -1, 64, -1,
+ 75, 76, -1, -1, 114, 77, -1, 114, 80, -1,
+ 114, 83, -1, 114, 78, -1, 114, 79, -1, 114,
+ 86, -1, 114, 87, -1, 114, 92, -1, 114, 91,
+ -1, 114, 93, -1, 114, 94, -1, 114, 95, -1,
+ 114, 96, -1, 114, 110, -1, 115, 52, -1, 122,
+ 36, 118, 49, -1, 133, 49, -1, 50, 133, 49,
+ -1, 56, 36, 132, 49, -1, 22, 56, 36, 56,
+ 49, -1, 17, 81, 49, -1, 81, 48, 82, -1,
+ 82, -1, 133, -1, 133, 36, 118, -1, 19, 84,
+ 41, 85, 42, 49, -1, 127, 37, 118, -1, 127,
+ -1, 85, 77, -1, 77, -1, 18, 134, 41, 85,
+ 42, 49, -1, 21, 56, 41, 88, 42, 49, -1,
+ 88, 48, 89, -1, 89, -1, -1, 122, 36, 118,
+ -1, 122, 36, 90, -1, 133, -1, 50, 133, -1,
+ 90, -1, 45, 124, 46, -1, 45, 120, 46, -1,
+ 23, 131, 36, 118, 49, -1, 24, 133, 41, 117,
+ 42, 49, -1, 25, 134, 41, 85, 42, 49, -1,
+ 25, 131, 36, 118, 49, -1, 35, 25, 131, 36,
+ 118, 49, -1, 26, 134, 41, 106, 42, 49, -1,
+ 26, 134, 41, 108, 42, 49, -1, 29, 134, 41,
+ 97, 42, 49, -1, 97, 98, -1, 98, -1, 28,
+ 41, 99, 42, 49, -1, 77, -1, 110, -1, 93,
+ -1, 103, -1, 99, 100, -1, 100, -1, 27, 41,
+ 101, 42, 49, -1, 77, -1, 101, 48, 102, -1,
+ 102, -1, 56, -1, 41, 117, 42, -1, 30, 134,
+ 41, 104, 42, 49, -1, 104, 48, 105, -1, 105,
+ -1, 56, 36, 56, -1, 106, 48, 107, -1, 107,
+ -1, 41, 108, 42, -1, 133, 36, 41, 108, 42,
+ -1, 133, 36, 118, -1, 108, 48, 109, -1, 109,
+ -1, 45, 128, 48, 128, 46, -1, 111, 134, 41,
+ 85, 42, 49, -1, 31, -1, 32, -1, 33, -1,
+ 34, -1, 133, -1, 113, -1, 20, -1, 19, -1,
+ 18, -1, 21, -1, 23, -1, 24, -1, 25, -1,
+ 26, -1, 28, -1, 29, -1, 31, -1, 115, -1,
+ -1, 12, -1, 14, -1, 13, -1, 15, -1, 16,
+ -1, 117, -1, -1, 117, 48, 118, -1, 118, -1,
+ 118, 39, 118, -1, 118, 37, 118, -1, 118, 38,
+ 118, -1, 118, 40, 118, -1, 122, 36, 118, -1,
+ 119, -1, 38, 119, -1, 37, 119, -1, 50, 119,
+ -1, 51, 119, -1, 122, -1, 112, 43, 116, 44,
+ -1, 123, -1, 43, 118, 44, -1, 120, 48, 121,
+ -1, 121, -1, 112, 43, 116, 44, -1, 112, -1,
+ 112, 47, 112, -1, 112, 45, 118, 46, -1, 112,
+ 47, 112, 45, 118, 46, -1, 134, -1, 131, -1,
+ 130, -1, 56, -1, 125, -1, -1, 125, 48, 127,
+ -1, 125, 48, 126, -1, 127, -1, 126, -1, 41,
+ 125, 42, -1, 55, -1, 29, -1, 131, -1, 38,
+ 129, -1, 129, -1, 54, -1, 53, -1, 54, -1,
+ 53, -1, 53, -1, 55, -1, 58, -1, 52, -1,
+ 136, -1, -1, 52, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 198, 198, 200, 202, 206, 212, 213, 214, 217,
+ 224, 228, 243, 244, 245, 246, 247, 250, 251, 254,
+ 255, 258, 259, 260, 261, 262, 263, 264, 265, 268,
+ 270, 273, 278, 283, 288, 293, 298, 303, 308, 313,
+ 318, 323, 328, 329, 330, 331, 338, 340, 342, 346,
+ 350, 354, 358, 360, 364, 366, 370, 376, 378, 382,
+ 384, 388, 394, 400, 402, 404, 407, 408, 409, 410,
+ 411, 414, 416, 420, 424, 428, 432, 434, 438, 440,
+ 444, 448, 449, 452, 454, 456, 458, 460, 464, 465,
+ 468, 469, 473, 474, 477, 479, 483, 487, 488, 491,
+ 494, 496, 500, 502, 504, 508, 510, 514, 518, 522,
+ 523, 524, 525, 528, 529, 532, 534, 536, 538, 540,
+ 542, 544, 546, 548, 550, 552, 556, 557, 560, 561,
+ 562, 563, 564, 574, 575, 578, 580, 584, 586, 588,
+ 590, 592, 594, 598, 600, 602, 604, 606, 608, 610,
+ 612, 616, 618, 622, 626, 633, 641, 650, 661, 668,
+ 675, 679, 688, 689, 692, 694, 696, 698, 702, 706,
+ 707, 708, 722, 723, 726, 727, 730, 733, 736, 739,
+ 740, 743, 746, 747, 750
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "END_OF_FILE", "error", "$undefined", "ERROR_TOK", "XKB_KEYMAP",
+ "XKB_KEYCODES", "XKB_TYPES", "XKB_SYMBOLS", "XKB_COMPATMAP",
+ "XKB_GEOMETRY", "XKB_SEMANTICS", "XKB_LAYOUT", "INCLUDE", "OVERRIDE",
+ "AUGMENT", "REPLACE", "ALTERNATE", "VIRTUAL_MODS", "TYPE", "INTERPRET",
+ "ACTION_TOK", "KEY", "ALIAS", "GROUP", "MODIFIER_MAP", "INDICATOR",
+ "SHAPE", "KEYS", "ROW", "SECTION", "OVERLAY", "TEXT", "OUTLINE", "SOLID",
+ "LOGO", "VIRTUAL", "EQUALS", "PLUS", "MINUS", "DIVIDE", "TIMES",
+ "OBRACE", "CBRACE", "OPAREN", "CPAREN", "OBRACKET", "CBRACKET", "DOT",
+ "COMMA", "SEMI", "EXCLAM", "INVERT", "STRING", "INTEGER", "FLOAT",
+ "IDENT", "KEYNAME", "PARTIAL", "DEFAULT", "HIDDEN", "ALPHANUMERIC_KEYS",
+ "MODIFIER_KEYS", "KEYPAD_KEYS", "FUNCTION_KEYS", "ALTERNATE_GROUP",
+ "$accept", "XkbFile", "XkbCompositeMap", "XkbCompositeType",
+ "XkbMapConfigList", "XkbMapConfig", "FileType", "OptFlags", "Flags",
+ "Flag", "DeclList", "Decl", "VarDecl", "KeyNameDecl", "KeyAliasDecl",
+ "VModDecl", "VModDefList", "VModDef", "InterpretDecl", "InterpretMatch",
+ "VarDeclList", "KeyTypeDecl", "SymbolsDecl", "SymbolsBody",
+ "SymbolsVarDecl", "ArrayInit", "GroupCompatDecl", "ModMapDecl",
+ "LedMapDecl", "LedNameDecl", "ShapeDecl", "SectionDecl", "SectionBody",
+ "SectionBodyItem", "RowBody", "RowBodyItem", "Keys", "Key",
+ "OverlayDecl", "OverlayKeyList", "OverlayKey", "OutlineList",
+ "OutlineInList", "CoordList", "Coord", "DoodadDecl", "DoodadType",
+ "FieldSpec", "Element", "OptMergeMode", "MergeMode", "OptExprList",
+ "ExprList", "Expr", "Term", "ActionList", "Action", "Lhs", "Terminal",
+ "OptKeySymList", "KeySymList", "KeySyms", "KeySym", "SignedNumber",
+ "Number", "Float", "Integer", "KeyCode", "Ident", "String", "OptMapName",
+ "MapName", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 255, 1, 2, 3, 4, 5, 6,
+ 7, 8, 10, 11, 12, 13, 14, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 60, 61, 62, 63, 64, 70, 71, 72,
+ 73, 74, 75, 76, 77
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 65, 66, 66, 66, 67, 68, 68, 68, 69,
+ 69, 70, 71, 71, 71, 71, 71, 72, 72, 73,
+ 73, 74, 74, 74, 74, 74, 74, 74, 74, 75,
+ 75, 76, 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 77, 77, 77, 78,
+ 79, 80, 81, 81, 82, 82, 83, 84, 84, 85,
+ 85, 86, 87, 88, 88, 88, 89, 89, 89, 89,
+ 89, 90, 90, 91, 92, 93, 94, 94, 95, 95,
+ 96, 97, 97, 98, 98, 98, 98, 98, 99, 99,
+ 100, 100, 101, 101, 102, 102, 103, 104, 104, 105,
+ 106, 106, 107, 107, 107, 108, 108, 109, 110, 111,
+ 111, 111, 111, 112, 112, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 114, 114, 115, 115,
+ 115, 115, 115, 116, 116, 117, 117, 118, 118, 118,
+ 118, 118, 118, 119, 119, 119, 119, 119, 119, 119,
+ 119, 120, 120, 121, 122, 122, 122, 122, 123, 123,
+ 123, 123, 124, 124, 125, 125, 125, 125, 126, 127,
+ 127, 127, 128, 128, 129, 129, 130, 131, 132, 133,
+ 133, 134, 135, 135, 136
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 1, 1, 1, 7, 1, 1, 1, 2,
+ 1, 7, 1, 1, 1, 1, 1, 1, 0, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 4, 2, 3, 4,
+ 5, 3, 3, 1, 1, 3, 6, 3, 1, 2,
+ 1, 6, 6, 3, 1, 0, 3, 3, 1, 2,
+ 1, 3, 3, 5, 6, 6, 5, 6, 6, 6,
+ 6, 2, 1, 5, 1, 1, 1, 1, 2, 1,
+ 5, 1, 3, 1, 1, 3, 6, 3, 1, 3,
+ 3, 1, 3, 5, 3, 3, 1, 5, 6, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
+ 1, 1, 1, 1, 0, 3, 1, 3, 3, 3,
+ 3, 3, 1, 2, 2, 2, 2, 1, 4, 1,
+ 3, 3, 1, 4, 1, 3, 4, 6, 1, 1,
+ 1, 1, 1, 0, 3, 3, 1, 1, 3, 1,
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 18, 4, 21, 22, 23, 24, 25, 26, 27, 28,
+ 0, 2, 3, 0, 17, 20, 1, 6, 12, 13,
+ 15, 14, 16, 7, 8, 183, 183, 19, 184, 0,
+ 182, 0, 18, 30, 18, 10, 0, 127, 0, 9,
+ 128, 130, 129, 131, 132, 0, 29, 0, 126, 5,
+ 11, 0, 117, 116, 115, 118, 0, 119, 120, 121,
+ 122, 123, 124, 125, 110, 111, 112, 0, 0, 179,
+ 0, 180, 31, 34, 35, 32, 33, 36, 37, 39,
+ 38, 40, 41, 42, 43, 44, 0, 154, 114, 0,
+ 113, 45, 0, 53, 54, 181, 0, 170, 177, 169,
+ 0, 58, 171, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 47, 0,
+ 51, 0, 0, 0, 0, 65, 0, 0, 0, 0,
+ 0, 0, 0, 0, 48, 178, 0, 0, 117, 116,
+ 118, 119, 120, 121, 122, 124, 125, 0, 0, 0,
+ 0, 0, 176, 161, 154, 0, 142, 147, 149, 160,
+ 159, 113, 158, 155, 0, 52, 55, 60, 0, 0,
+ 57, 163, 0, 0, 64, 70, 0, 113, 0, 0,
+ 0, 136, 0, 0, 0, 0, 0, 101, 0, 106,
+ 0, 121, 123, 0, 84, 86, 0, 82, 87, 85,
+ 0, 49, 0, 144, 147, 143, 0, 145, 146, 134,
+ 0, 0, 0, 0, 156, 0, 0, 46, 0, 59,
+ 0, 170, 0, 169, 0, 0, 152, 0, 162, 167,
+ 166, 69, 0, 0, 0, 50, 73, 0, 0, 76,
+ 0, 0, 0, 175, 174, 0, 173, 0, 0, 0,
+ 0, 0, 0, 0, 0, 81, 0, 0, 150, 0,
+ 133, 138, 139, 137, 140, 141, 0, 61, 56, 0,
+ 134, 72, 0, 71, 0, 62, 63, 67, 66, 74,
+ 135, 75, 102, 172, 0, 78, 100, 79, 105, 0,
+ 104, 0, 91, 0, 89, 0, 80, 77, 108, 148,
+ 157, 168, 0, 151, 165, 164, 0, 0, 0, 0,
+ 88, 0, 0, 98, 153, 107, 103, 0, 94, 0,
+ 93, 83, 0, 0, 0, 0, 0, 0, 99, 96,
+ 97, 95, 90, 92
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 10, 11, 25, 34, 12, 26, 36, 14, 15,
+ 37, 46, 167, 73, 74, 75, 92, 93, 76, 100,
+ 168, 77, 78, 173, 174, 175, 79, 80, 195, 82,
+ 83, 84, 196, 197, 293, 294, 319, 320, 198, 312,
+ 313, 186, 187, 188, 189, 199, 86, 154, 88, 47,
+ 48, 259, 260, 181, 156, 225, 226, 157, 158, 227,
+ 228, 229, 230, 245, 246, 159, 160, 136, 161, 162,
+ 29, 30
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -182
+static const yytype_int16 yypact[] =
+{
+ 176, -182, -182, -182, -182, -182, -182, -182, -182, -182,
+ 6, -182, -182, 271, 227, -182, -182, -182, -182, -182,
+ -182, -182, -182, -182, -182, -38, -38, -182, -182, -24,
+ -182, 33, 227, -182, 210, -182, 353, 44, 5, -182,
+ -182, -182, -182, -182, -182, 32, -182, 13, 41, -182,
+ -182, -48, 55, 11, -182, 79, 87, 58, -48, -2,
+ 55, -182, 55, 72, -182, -182, -182, 107, -48, -182,
+ 110, -182, -182, -182, -182, -182, -182, -182, -182, -182,
+ -182, -182, -182, -182, -182, -182, 55, -18, -182, 127,
+ 121, -182, 66, -182, 138, -182, 136, -182, -182, -182,
+ 144, 147, -182, 152, 180, 182, 178, 184, 187, 188,
+ 190, 58, 198, 201, 214, 367, 677, 367, -182, -48,
+ -182, 367, 663, 663, 367, 494, 200, 367, 367, 367,
+ 663, 68, 449, 223, -182, -182, 212, 663, -182, -182,
+ -182, -182, -182, -182, -182, -182, -182, 367, 367, 367,
+ 367, 367, -182, -182, 57, 157, -182, 224, -182, -182,
+ -182, -182, -182, 218, 91, -182, 333, -182, 509, 537,
+ 333, 552, -48, 1, -182, -182, 228, 40, 216, 143,
+ 70, 333, 150, 593, 247, -30, 97, -182, 105, -182,
+ 261, 55, 259, 55, -182, -182, 408, -182, -182, -182,
+ 367, -182, 608, -182, -182, -182, 287, -182, -182, 367,
+ 367, 367, 367, 367, -182, 367, 367, -182, 252, -182,
+ 253, 264, 24, 269, 272, 163, -182, 273, 270, -182,
+ -182, -182, 280, 494, 285, -182, -182, 283, 367, -182,
+ 284, 112, 8, -182, -182, 294, -182, 299, -36, 304,
+ 247, 326, 649, 279, 307, -182, 204, 316, -182, 322,
+ 320, 111, 111, -182, -182, 333, 211, -182, -182, 116,
+ 367, -182, 677, -182, 24, -182, -182, -182, 333, -182,
+ 333, -182, -182, -182, -30, -182, -182, -182, -182, 247,
+ 333, 334, -182, 466, -182, 318, -182, -182, -182, -182,
+ -182, -182, 339, -182, -182, -182, 343, 120, 14, 345,
+ -182, 361, 124, -182, -182, -182, -182, 367, -182, 131,
+ -182, -182, 344, 350, 318, 166, 352, 14, -182, -182,
+ -182, -182, -182, -182
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -182, -182, -182, -182, -182, 181, -182, 402, -182, 389,
+ -182, -182, -35, -182, -182, -182, -182, 288, -182, -182,
+ -50, -182, -182, -182, 173, 174, -182, -182, 362, -182,
+ -182, -182, -182, 215, -182, 119, -182, 86, -182, -182,
+ 90, -182, 167, -181, 185, 369, -182, -27, -182, -182,
+ -182, 154, -126, 83, 76, -182, 158, -31, -182, -182,
+ 221, 170, -52, 161, 205, -182, -44, -182, -47, -34,
+ 420, -182
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -180
+static const yytype_int16 yytable[] =
+{
+ 90, 101, 180, 241, 94, 184, 16, 69, 242, 102,
+ 71, 106, 72, 105, 28, 107, 89, 32, 96, 69,
+ 87, 112, 71, 243, 244, 108, 109, 115, 110, 116,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 97, 61, 62, 232, 63, 64, 65, 66, 67, 233,
+ 95, 98, 114, 97, 49, 317, 40, 41, 42, 43,
+ 44, 243, 244, 68, 98, 222, 99, 133, 69, 70,
+ 318, 71, 94, 169, 33, 90, 90, 98, 177, 99,
+ 183, 50, -68, 90, 190, 90, 45, 202, -68, 163,
+ 90, 89, 89, 91, 176, 87, 87, 194, 87, 89,
+ 209, 89, 115, 87, 116, 87, 89, 95, 307, 184,
+ 87, 98, 237, 185, 119, 120, 204, 204, 238, 204,
+ 204, 90, 90, 69, -109, 231, 71, 102, 210, 211,
+ 212, 213, 111, 219, 219, 103, 90, 89, 89, 247,
+ 217, 87, 87, 104, 224, 248, 113, 249, 219, 90,
+ 212, 213, 89, 250, 282, 90, 87, 108, 301, 253,
+ 250, 194, 316, 117, 274, 89, 323, 219, 250, 87,
+ 118, 89, 324, 326, 121, 87, 1, 122, 102, 327,
+ 210, 211, 212, 213, 124, 123, 177, 210, 211, 212,
+ 213, 325, 236, 125, 210, 211, 212, 213, 155, 239,
+ 164, 190, 176, 214, 166, 90, 87, 170, 331, 271,
+ 179, 272, 182, 35, 238, 39, 126, 292, 127, 128,
+ 129, 89, 305, 203, 205, 87, 207, 208, 130, 131,
+ 102, 132, 206, 2, 3, 4, 5, 6, 7, 8,
+ 9, 210, 211, 212, 213, 224, 90, 134, 210, 211,
+ 212, 213, 38, 297, 135, 137, 178, 300, 292, 200,
+ 215, 201, 89, 216, 234, 235, 87, 2, 3, 4,
+ 5, 6, 7, 8, 9, 17, 18, 19, 20, 21,
+ 22, 23, 24, 256, 2, 3, 4, 5, 6, 7,
+ 8, 9, 185, 261, 262, 263, 264, 251, 265, 266,
+ 252, 267, 268, 138, 139, 54, 140, -124, 141, 142,
+ 143, 144, -179, 61, 145, 270, 146, 278, 274, 273,
+ 295, 280, 147, 148, 210, 211, 212, 213, 149, 275,
+ 171, 258, 279, 281, 290, 150, 151, 95, 98, 152,
+ 69, 153, 284, 71, 138, 139, 54, 140, 285, 141,
+ 142, 143, 144, 287, 61, 145, 296, 146, 18, 19,
+ 20, 21, 22, 147, 148, 298, 299, 289, 238, 149,
+ 210, 211, 212, 213, 311, 308, 150, 151, 95, 98,
+ 152, 69, 153, 314, 71, 138, 139, 54, 140, 315,
+ 141, 142, 143, 144, 321, 61, 145, 322, 146, 329,
+ 328, 332, 13, 27, 147, 148, 276, 165, 277, 81,
+ 149, 255, 310, 333, 330, 286, 85, 150, 151, 95,
+ 98, 152, 69, 153, 302, 71, 138, 139, 54, 140,
+ 303, 141, 142, 191, 144, 288, 192, 145, 193, 63,
+ 64, 65, 66, 269, 304, 306, 31, 283, 0, 0,
+ 254, 0, 0, 0, 0, 0, 0, 0, 68, 0,
+ 0, 0, 0, 69, 0, 0, 71, 138, 139, 54,
+ 140, 0, 141, 142, 191, 144, 0, 192, 145, 193,
+ 63, 64, 65, 66, 138, 139, 54, 140, 0, 141,
+ 142, 143, 144, 291, 61, 145, 0, 146, 0, 68,
+ 0, 0, 0, 0, 69, 0, 0, 71, 309, 0,
+ 0, 0, 138, 139, 54, 140, 68, 141, 142, 143,
+ 144, 69, 61, 145, 71, 146, 0, 138, 139, 54,
+ 140, 0, 141, 142, 143, 144, 0, 61, 145, 171,
+ 146, 0, 0, 0, 172, 0, 0, 0, 0, 69,
+ 0, 218, 71, 0, 0, 138, 139, 54, 140, 68,
+ 141, 142, 143, 144, 69, 61, 145, 71, 146, 0,
+ 138, 139, 54, 140, 0, 141, 142, 143, 144, 220,
+ 61, 221, 0, 146, 0, 0, 0, 68, 0, 0,
+ 0, 0, 69, 222, 0, 71, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 98, 0, 223, 0, 0,
+ 71, 138, 139, 54, 140, 0, 141, 142, 143, 144,
+ 0, 61, 145, 0, 146, 0, 138, 139, 54, 140,
+ 0, 141, 142, 143, 144, 240, 61, 145, 0, 146,
+ 0, 0, 0, 68, 0, 0, 0, 0, 69, 0,
+ 257, 71, 0, 0, 0, 0, 0, 0, 68, 0,
+ 0, 0, 0, 69, 0, 0, 71, 138, 139, 54,
+ 140, 0, 141, 142, 143, 144, 291, 61, 145, 0,
+ 146, 138, 139, 54, 140, 0, 141, 142, 143, 144,
+ 0, 61, 145, 0, 146, 138, 139, 54, 140, 68,
+ 141, 142, 143, 144, 69, 61, 145, 71, 146, 0,
+ 0, 0, 0, 68, 0, 0, 0, 0, 69, 0,
+ 0, 71, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 69, 0, 0, 71
+};
+
+#define yypact_value_is_default(yystate) \
+ ((yystate) == (-182))
+
+#define yytable_value_is_error(yytable_value) \
+ YYID (0)
+
+static const yytype_int16 yycheck[] =
+{
+ 47, 53, 128, 184, 51, 41, 0, 55, 38, 53,
+ 58, 58, 47, 57, 52, 59, 47, 41, 52, 55,
+ 47, 68, 58, 53, 54, 59, 60, 45, 62, 47,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 29, 28, 29, 42, 31, 32, 33, 34, 35, 48,
+ 52, 53, 86, 29, 49, 41, 12, 13, 14, 15,
+ 16, 53, 54, 50, 53, 41, 55, 111, 55, 56,
+ 56, 58, 119, 123, 41, 122, 123, 53, 125, 55,
+ 130, 49, 42, 130, 131, 132, 42, 137, 48, 116,
+ 137, 122, 123, 52, 125, 122, 123, 132, 125, 130,
+ 43, 132, 45, 130, 47, 132, 137, 52, 289, 41,
+ 137, 53, 42, 45, 48, 49, 147, 148, 48, 150,
+ 151, 168, 169, 55, 52, 172, 58, 171, 37, 38,
+ 39, 40, 25, 168, 169, 56, 183, 168, 169, 42,
+ 49, 168, 169, 56, 171, 48, 36, 42, 183, 196,
+ 39, 40, 183, 48, 42, 202, 183, 191, 42, 193,
+ 48, 196, 42, 36, 48, 196, 42, 202, 48, 196,
+ 49, 202, 48, 42, 36, 202, 0, 41, 222, 48,
+ 37, 38, 39, 40, 37, 41, 233, 37, 38, 39,
+ 40, 317, 49, 41, 37, 38, 39, 40, 115, 49,
+ 117, 248, 233, 46, 121, 252, 233, 124, 42, 46,
+ 127, 48, 129, 32, 48, 34, 36, 252, 36, 41,
+ 36, 252, 274, 147, 148, 252, 150, 151, 41, 41,
+ 274, 41, 149, 57, 58, 59, 60, 61, 62, 63,
+ 64, 37, 38, 39, 40, 272, 293, 49, 37, 38,
+ 39, 40, 42, 49, 53, 41, 56, 46, 293, 36,
+ 36, 49, 293, 45, 36, 49, 293, 57, 58, 59,
+ 60, 61, 62, 63, 64, 4, 5, 6, 7, 8,
+ 9, 10, 11, 200, 57, 58, 59, 60, 61, 62,
+ 63, 64, 45, 210, 211, 212, 213, 36, 215, 216,
+ 41, 49, 49, 18, 19, 20, 21, 43, 23, 24,
+ 25, 26, 43, 28, 29, 43, 31, 234, 48, 46,
+ 41, 238, 37, 38, 37, 38, 39, 40, 43, 49,
+ 45, 44, 49, 49, 251, 50, 51, 52, 53, 54,
+ 55, 56, 48, 58, 18, 19, 20, 21, 49, 23,
+ 24, 25, 26, 49, 28, 29, 49, 31, 5, 6,
+ 7, 8, 9, 37, 38, 49, 44, 41, 48, 43,
+ 37, 38, 39, 40, 56, 41, 50, 51, 52, 53,
+ 54, 55, 56, 44, 58, 18, 19, 20, 21, 46,
+ 23, 24, 25, 26, 49, 28, 29, 36, 31, 49,
+ 56, 49, 0, 14, 37, 38, 233, 119, 234, 47,
+ 43, 196, 293, 327, 324, 248, 47, 50, 51, 52,
+ 53, 54, 55, 56, 270, 58, 18, 19, 20, 21,
+ 272, 23, 24, 25, 26, 250, 28, 29, 30, 31,
+ 32, 33, 34, 222, 274, 284, 26, 242, -1, -1,
+ 42, -1, -1, -1, -1, -1, -1, -1, 50, -1,
+ -1, -1, -1, 55, -1, -1, 58, 18, 19, 20,
+ 21, -1, 23, 24, 25, 26, -1, 28, 29, 30,
+ 31, 32, 33, 34, 18, 19, 20, 21, -1, 23,
+ 24, 25, 26, 27, 28, 29, -1, 31, -1, 50,
+ -1, -1, -1, -1, 55, -1, -1, 58, 42, -1,
+ -1, -1, 18, 19, 20, 21, 50, 23, 24, 25,
+ 26, 55, 28, 29, 58, 31, -1, 18, 19, 20,
+ 21, -1, 23, 24, 25, 26, -1, 28, 29, 45,
+ 31, -1, -1, -1, 50, -1, -1, -1, -1, 55,
+ -1, 42, 58, -1, -1, 18, 19, 20, 21, 50,
+ 23, 24, 25, 26, 55, 28, 29, 58, 31, -1,
+ 18, 19, 20, 21, -1, 23, 24, 25, 26, 42,
+ 28, 29, -1, 31, -1, -1, -1, 50, -1, -1,
+ -1, -1, 55, 41, -1, 58, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 53, -1, 55, -1, -1,
+ 58, 18, 19, 20, 21, -1, 23, 24, 25, 26,
+ -1, 28, 29, -1, 31, -1, 18, 19, 20, 21,
+ -1, 23, 24, 25, 26, 42, 28, 29, -1, 31,
+ -1, -1, -1, 50, -1, -1, -1, -1, 55, -1,
+ 42, 58, -1, -1, -1, -1, -1, -1, 50, -1,
+ -1, -1, -1, 55, -1, -1, 58, 18, 19, 20,
+ 21, -1, 23, 24, 25, 26, 27, 28, 29, -1,
+ 31, 18, 19, 20, 21, -1, 23, 24, 25, 26,
+ -1, 28, 29, -1, 31, 18, 19, 20, 21, 50,
+ 23, 24, 25, 26, 55, 28, 29, 58, 31, -1,
+ -1, -1, -1, 50, -1, -1, -1, -1, 55, -1,
+ -1, 58, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 55, -1, -1, 58
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 0, 57, 58, 59, 60, 61, 62, 63, 64,
+ 66, 67, 70, 72, 73, 74, 0, 4, 5, 6,
+ 7, 8, 9, 10, 11, 68, 71, 74, 52, 135,
+ 136, 135, 41, 41, 69, 70, 72, 75, 42, 70,
+ 12, 13, 14, 15, 16, 42, 76, 114, 115, 49,
+ 49, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 28, 29, 31, 32, 33, 34, 35, 50, 55,
+ 56, 58, 77, 78, 79, 80, 83, 86, 87, 91,
+ 92, 93, 94, 95, 96, 110, 111, 112, 113, 122,
+ 133, 52, 81, 82, 133, 52, 134, 29, 53, 55,
+ 84, 127, 131, 56, 56, 131, 133, 131, 134, 134,
+ 134, 25, 133, 36, 134, 45, 47, 36, 49, 48,
+ 49, 36, 41, 41, 37, 41, 36, 36, 41, 36,
+ 41, 41, 41, 131, 49, 53, 132, 41, 18, 19,
+ 21, 23, 24, 25, 26, 29, 31, 37, 38, 43,
+ 50, 51, 54, 56, 112, 118, 119, 122, 123, 130,
+ 131, 133, 134, 112, 118, 82, 118, 77, 85, 85,
+ 118, 45, 50, 88, 89, 90, 122, 133, 56, 118,
+ 117, 118, 118, 85, 41, 45, 106, 107, 108, 109,
+ 133, 25, 28, 30, 77, 93, 97, 98, 103, 110,
+ 36, 49, 85, 119, 122, 119, 118, 119, 119, 43,
+ 37, 38, 39, 40, 46, 36, 45, 49, 42, 77,
+ 42, 29, 41, 55, 112, 120, 121, 124, 125, 126,
+ 127, 133, 42, 48, 36, 49, 49, 42, 48, 49,
+ 42, 108, 38, 53, 54, 128, 129, 42, 48, 42,
+ 48, 36, 41, 134, 42, 98, 118, 42, 44, 116,
+ 117, 118, 118, 118, 118, 118, 118, 49, 49, 125,
+ 43, 46, 48, 46, 48, 49, 89, 90, 118, 49,
+ 118, 49, 42, 129, 48, 49, 107, 49, 109, 41,
+ 118, 27, 77, 99, 100, 41, 49, 49, 49, 44,
+ 46, 42, 116, 121, 126, 127, 128, 108, 41, 42,
+ 100, 56, 104, 105, 44, 46, 42, 41, 56, 101,
+ 102, 49, 36, 42, 48, 117, 42, 48, 56, 49,
+ 105, 42, 49, 102
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. However,
+ YYFAIL appears to be in use. Nevertheless, it is formally deprecated
+ in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+ discussed. */
+
+#define YYFAIL goto yyerrlab
+#if defined YYFAIL
+ /* This is here to suppress warnings from the GCC cpp's
+ -Wunused-macros. Normally we don't worry about that warning, but
+ some users do, and we want to make it easy for users to remove
+ YYFAIL uses, which will produce warnings from Bison 2.5. */
+#endif
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (1); \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (&yylloc, param, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval, &yylloc, scanner)
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value, Location, param); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct parser_param *param)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, param)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+ struct parser_param *param;
+#endif
+{
+ if (!yyvaluep)
+ return;
+ YYUSE (yylocationp);
+ YYUSE (param);
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct parser_param *param)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, param)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+ struct parser_param *param;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ YY_LOCATION_PRINT (yyoutput, *yylocationp);
+ YYFPRINTF (yyoutput, ": ");
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, param);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+ yytype_int16 *yybottom;
+ yytype_int16 *yytop;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct parser_param *param)
+#else
+static void
+yy_reduce_print (yyvsp, yylsp, yyrule, param)
+ YYSTYPE *yyvsp;
+ YYLTYPE *yylsp;
+ int yyrule;
+ struct parser_param *param;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ , &(yylsp[(yyi + 1) - (yynrhs)]) , param);
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, yylsp, Rule, param); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+ about the unexpected token YYTOKEN for the state stack whose top is
+ YYSSP.
+
+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
+ not large enough to hold the message. In that case, also set
+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the
+ required number of bytes is too large to store. */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ yytype_int16 *yyssp, int yytoken)
+{
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ /* Internationalized format string. */
+ const char *yyformat = 0;
+ /* Arguments of yyformat. */
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ /* Number of reported tokens (one for the "unexpected", one per
+ "expected"). */
+ int yycount = 0;
+
+ /* There are many possibilities here to consider:
+ - Assume YYFAIL is not used. It's too flawed to consider. See
+ <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+ for details. YYERROR is fine as it does not invoke this
+ function.
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yychar) is if
+ this state is a consistent state with a default action. Thus,
+ detecting the absence of a lookahead is sufficient to determine
+ that there is no unexpected or expected token to report. In that
+ case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is a
+ consistent state with a default action. There might have been a
+ previous inconsistent state, consistent state with a non-default
+ action, or user semantic action that manipulated yychar.
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state merging
+ (from LALR or IELR) and default reductions corrupt the expected
+ token list. However, the list is correct for canonical LR with
+ one exception: it will still contain any token that will not be
+ accepted due to an error action in a later state.
+ */
+ if (yytoken != YYEMPTY)
+ {
+ int yyn = yypact[*yyssp];
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yyx;
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+ && !yytable_value_is_error (yytable[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+ }
+ }
+
+ switch (yycount)
+ {
+# define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+ }
+
+ yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+
+ if (*yymsg_alloc < yysize)
+ {
+ *yymsg_alloc = 2 * yysize;
+ if (! (yysize <= *yymsg_alloc
+ && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+ *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+ return 1;
+ }
+
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ {
+ char *yyp = *yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyformat) != '\0')
+ if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyformat += 2;
+ }
+ else
+ {
+ yyp++;
+ yyformat++;
+ }
+ }
+ return 0;
+}
+#endif /* YYERROR_VERBOSE */
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct parser_param *param)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp, param)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+ YYLTYPE *yylocationp;
+ struct parser_param *param;
+#endif
+{
+ YYUSE (yyvaluep);
+ YYUSE (yylocationp);
+ YYUSE (param);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes. */
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (struct parser_param *param);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (struct parser_param *param)
+#else
+int
+yyparse (param)
+ struct parser_param *param;
+#endif
+#endif
+{
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Location data for the lookahead symbol. */
+YYLTYPE yylloc;
+
+ /* Number of syntax errors so far. */
+ int yynerrs;
+
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ `yyss': related to states.
+ `yyvs': related to semantic values.
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ /* The location stack. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls;
+ YYLTYPE *yylsp;
+
+ /* The locations where the error started and ended. */
+ YYLTYPE yyerror_range[3];
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+ YYLTYPE yyloc;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yytoken = 0;
+ yyss = yyssa;
+ yyvs = yyvsa;
+ yyls = yylsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+ yyssp = yyss;
+ yyvsp = yyvs;
+ yylsp = yyls;
+
+#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+ /* Initialize the default location before parsing starts. */
+ yylloc.first_line = yylloc.last_line = 1;
+ yylloc.first_column = yylloc.last_column = 1;
+#endif
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+ YYLTYPE *yyls1 = yyls;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yyls1, yysize * sizeof (*yylsp),
+ &yystacksize);
+
+ yyls = yyls1;
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+ YYSTACK_RELOCATE (yyls_alloc, yyls);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+ yylsp = yyls + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default (yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ *++yyvsp = yylval;
+ *++yylsp = yylloc;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+ /* Default location. */
+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 2:
+
+/* Line 1806 of yacc.c */
+#line 199 "parser.y"
+ { (yyval.file) = param->rtrn = (yyvsp[(1) - (1)].file); param->more_maps = true; }
+ break;
+
+ case 3:
+
+/* Line 1806 of yacc.c */
+#line 201 "parser.y"
+ { (yyval.file) = param->rtrn = (yyvsp[(1) - (1)].file); param->more_maps = true; YYACCEPT; }
+ break;
+
+ case 4:
+
+/* Line 1806 of yacc.c */
+#line 203 "parser.y"
+ { (yyval.file) = param->rtrn = NULL; param->more_maps = false; }
+ break;
+
+ case 5:
+
+/* Line 1806 of yacc.c */
+#line 209 "parser.y"
+ { (yyval.file) = XkbFileCreate(param->ctx, (yyvsp[(2) - (7)].file_type), (yyvsp[(3) - (7)].str), &(yyvsp[(5) - (7)].file)->common, (yyvsp[(1) - (7)].mapFlags)); }
+ break;
+
+ case 6:
+
+/* Line 1806 of yacc.c */
+#line 212 "parser.y"
+ { (yyval.file_type) = FILE_TYPE_KEYMAP; }
+ break;
+
+ case 7:
+
+/* Line 1806 of yacc.c */
+#line 213 "parser.y"
+ { (yyval.file_type) = FILE_TYPE_KEYMAP; }
+ break;
+
+ case 8:
+
+/* Line 1806 of yacc.c */
+#line 214 "parser.y"
+ { (yyval.file_type) = FILE_TYPE_KEYMAP; }
+ break;
+
+ case 9:
+
+/* Line 1806 of yacc.c */
+#line 218 "parser.y"
+ {
+ if (!(yyvsp[(2) - (2)].file))
+ (yyval.file) = (yyvsp[(1) - (2)].file);
+ else
+ (yyval.file) = (XkbFile *)AppendStmt(&(yyvsp[(1) - (2)].file)->common, &(yyvsp[(2) - (2)].file)->common);
+ }
+ break;
+
+ case 10:
+
+/* Line 1806 of yacc.c */
+#line 225 "parser.y"
+ { (yyval.file) = (yyvsp[(1) - (1)].file); }
+ break;
+
+ case 11:
+
+/* Line 1806 of yacc.c */
+#line 231 "parser.y"
+ {
+ if ((yyvsp[(2) - (7)].file_type) == FILE_TYPE_GEOMETRY) {
+ free((yyvsp[(3) - (7)].str));
+ FreeStmt((yyvsp[(5) - (7)].any));
+ (yyval.file) = NULL;
+ }
+ else {
+ (yyval.file) = XkbFileCreate(param->ctx, (yyvsp[(2) - (7)].file_type), (yyvsp[(3) - (7)].str), (yyvsp[(5) - (7)].any), (yyvsp[(1) - (7)].mapFlags));
+ }
+ }
+ break;
+
+ case 12:
+
+/* Line 1806 of yacc.c */
+#line 243 "parser.y"
+ { (yyval.file_type) = FILE_TYPE_KEYCODES; }
+ break;
+
+ case 13:
+
+/* Line 1806 of yacc.c */
+#line 244 "parser.y"
+ { (yyval.file_type) = FILE_TYPE_TYPES; }
+ break;
+
+ case 14:
+
+/* Line 1806 of yacc.c */
+#line 245 "parser.y"
+ { (yyval.file_type) = FILE_TYPE_COMPAT; }
+ break;
+
+ case 15:
+
+/* Line 1806 of yacc.c */
+#line 246 "parser.y"
+ { (yyval.file_type) = FILE_TYPE_SYMBOLS; }
+ break;
+
+ case 16:
+
+/* Line 1806 of yacc.c */
+#line 247 "parser.y"
+ { (yyval.file_type) = FILE_TYPE_GEOMETRY; }
+ break;
+
+ case 17:
+
+/* Line 1806 of yacc.c */
+#line 250 "parser.y"
+ { (yyval.mapFlags) = (yyvsp[(1) - (1)].mapFlags); }
+ break;
+
+ case 18:
+
+/* Line 1806 of yacc.c */
+#line 251 "parser.y"
+ { (yyval.mapFlags) = 0; }
+ break;
+
+ case 19:
+
+/* Line 1806 of yacc.c */
+#line 254 "parser.y"
+ { (yyval.mapFlags) = ((yyvsp[(1) - (2)].mapFlags) | (yyvsp[(2) - (2)].mapFlags)); }
+ break;
+
+ case 20:
+
+/* Line 1806 of yacc.c */
+#line 255 "parser.y"
+ { (yyval.mapFlags) = (yyvsp[(1) - (1)].mapFlags); }
+ break;
+
+ case 21:
+
+/* Line 1806 of yacc.c */
+#line 258 "parser.y"
+ { (yyval.mapFlags) = MAP_IS_PARTIAL; }
+ break;
+
+ case 22:
+
+/* Line 1806 of yacc.c */
+#line 259 "parser.y"
+ { (yyval.mapFlags) = MAP_IS_DEFAULT; }
+ break;
+
+ case 23:
+
+/* Line 1806 of yacc.c */
+#line 260 "parser.y"
+ { (yyval.mapFlags) = MAP_IS_HIDDEN; }
+ break;
+
+ case 24:
+
+/* Line 1806 of yacc.c */
+#line 261 "parser.y"
+ { (yyval.mapFlags) = MAP_HAS_ALPHANUMERIC; }
+ break;
+
+ case 25:
+
+/* Line 1806 of yacc.c */
+#line 262 "parser.y"
+ { (yyval.mapFlags) = MAP_HAS_MODIFIER; }
+ break;
+
+ case 26:
+
+/* Line 1806 of yacc.c */
+#line 263 "parser.y"
+ { (yyval.mapFlags) = MAP_HAS_KEYPAD; }
+ break;
+
+ case 27:
+
+/* Line 1806 of yacc.c */
+#line 264 "parser.y"
+ { (yyval.mapFlags) = MAP_HAS_FN; }
+ break;
+
+ case 28:
+
+/* Line 1806 of yacc.c */
+#line 265 "parser.y"
+ { (yyval.mapFlags) = MAP_IS_ALTGR; }
+ break;
+
+ case 29:
+
+/* Line 1806 of yacc.c */
+#line 269 "parser.y"
+ { (yyval.any) = AppendStmt((yyvsp[(1) - (2)].any), (yyvsp[(2) - (2)].any)); }
+ break;
+
+ case 30:
+
+/* Line 1806 of yacc.c */
+#line 270 "parser.y"
+ { (yyval.any) = NULL; }
+ break;
+
+ case 31:
+
+/* Line 1806 of yacc.c */
+#line 274 "parser.y"
+ {
+ (yyvsp[(2) - (2)].var)->merge = (yyvsp[(1) - (2)].merge);
+ (yyval.any) = &(yyvsp[(2) - (2)].var)->common;
+ }
+ break;
+
+ case 32:
+
+/* Line 1806 of yacc.c */
+#line 279 "parser.y"
+ {
+ (yyvsp[(2) - (2)].vmod)->merge = (yyvsp[(1) - (2)].merge);
+ (yyval.any) = &(yyvsp[(2) - (2)].vmod)->common;
+ }
+ break;
+
+ case 33:
+
+/* Line 1806 of yacc.c */
+#line 284 "parser.y"
+ {
+ (yyvsp[(2) - (2)].interp)->merge = (yyvsp[(1) - (2)].merge);
+ (yyval.any) = &(yyvsp[(2) - (2)].interp)->common;
+ }
+ break;
+
+ case 34:
+
+/* Line 1806 of yacc.c */
+#line 289 "parser.y"
+ {
+ (yyvsp[(2) - (2)].keyCode)->merge = (yyvsp[(1) - (2)].merge);
+ (yyval.any) = &(yyvsp[(2) - (2)].keyCode)->common;
+ }
+ break;
+
+ case 35:
+
+/* Line 1806 of yacc.c */
+#line 294 "parser.y"
+ {
+ (yyvsp[(2) - (2)].keyAlias)->merge = (yyvsp[(1) - (2)].merge);
+ (yyval.any) = &(yyvsp[(2) - (2)].keyAlias)->common;
+ }
+ break;
+
+ case 36:
+
+/* Line 1806 of yacc.c */
+#line 299 "parser.y"
+ {
+ (yyvsp[(2) - (2)].keyType)->merge = (yyvsp[(1) - (2)].merge);
+ (yyval.any) = &(yyvsp[(2) - (2)].keyType)->common;
+ }
+ break;
+
+ case 37:
+
+/* Line 1806 of yacc.c */
+#line 304 "parser.y"
+ {
+ (yyvsp[(2) - (2)].syms)->merge = (yyvsp[(1) - (2)].merge);
+ (yyval.any) = &(yyvsp[(2) - (2)].syms)->common;
+ }
+ break;
+
+ case 38:
+
+/* Line 1806 of yacc.c */
+#line 309 "parser.y"
+ {
+ (yyvsp[(2) - (2)].modMask)->merge = (yyvsp[(1) - (2)].merge);
+ (yyval.any) = &(yyvsp[(2) - (2)].modMask)->common;
+ }
+ break;
+
+ case 39:
+
+/* Line 1806 of yacc.c */
+#line 314 "parser.y"
+ {
+ (yyvsp[(2) - (2)].groupCompat)->merge = (yyvsp[(1) - (2)].merge);
+ (yyval.any) = &(yyvsp[(2) - (2)].groupCompat)->common;
+ }
+ break;
+
+ case 40:
+
+/* Line 1806 of yacc.c */
+#line 319 "parser.y"
+ {
+ (yyvsp[(2) - (2)].ledMap)->merge = (yyvsp[(1) - (2)].merge);
+ (yyval.any) = &(yyvsp[(2) - (2)].ledMap)->common;
+ }
+ break;
+
+ case 41:
+
+/* Line 1806 of yacc.c */
+#line 324 "parser.y"
+ {
+ (yyvsp[(2) - (2)].ledName)->merge = (yyvsp[(1) - (2)].merge);
+ (yyval.any) = &(yyvsp[(2) - (2)].ledName)->common;
+ }
+ break;
+
+ case 42:
+
+/* Line 1806 of yacc.c */
+#line 328 "parser.y"
+ { (yyval.any) = NULL; }
+ break;
+
+ case 43:
+
+/* Line 1806 of yacc.c */
+#line 329 "parser.y"
+ { (yyval.any) = NULL; }
+ break;
+
+ case 44:
+
+/* Line 1806 of yacc.c */
+#line 330 "parser.y"
+ { (yyval.any) = NULL; }
+ break;
+
+ case 45:
+
+/* Line 1806 of yacc.c */
+#line 332 "parser.y"
+ {
+ (yyval.any) = &IncludeCreate(param->ctx, (yyvsp[(2) - (2)].str), (yyvsp[(1) - (2)].merge))->common;
+ free((yyvsp[(2) - (2)].str));
+ }
+ break;
+
+ case 46:
+
+/* Line 1806 of yacc.c */
+#line 339 "parser.y"
+ { (yyval.var) = VarCreate((yyvsp[(1) - (4)].expr), (yyvsp[(3) - (4)].expr)); }
+ break;
+
+ case 47:
+
+/* Line 1806 of yacc.c */
+#line 341 "parser.y"
+ { (yyval.var) = BoolVarCreate((yyvsp[(1) - (2)].sval), 1); }
+ break;
+
+ case 48:
+
+/* Line 1806 of yacc.c */
+#line 343 "parser.y"
+ { (yyval.var) = BoolVarCreate((yyvsp[(2) - (3)].sval), 0); }
+ break;
+
+ case 49:
+
+/* Line 1806 of yacc.c */
+#line 347 "parser.y"
+ { (yyval.keyCode) = KeycodeCreate((yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].num)); }
+ break;
+
+ case 50:
+
+/* Line 1806 of yacc.c */
+#line 351 "parser.y"
+ { (yyval.keyAlias) = KeyAliasCreate((yyvsp[(2) - (5)].sval), (yyvsp[(4) - (5)].sval)); }
+ break;
+
+ case 51:
+
+/* Line 1806 of yacc.c */
+#line 355 "parser.y"
+ { (yyval.vmod) = (yyvsp[(2) - (3)].vmod); }
+ break;
+
+ case 52:
+
+/* Line 1806 of yacc.c */
+#line 359 "parser.y"
+ { (yyval.vmod) = (VModDef *)AppendStmt(&(yyvsp[(1) - (3)].vmod)->common, &(yyvsp[(3) - (3)].vmod)->common); }
+ break;
+
+ case 53:
+
+/* Line 1806 of yacc.c */
+#line 361 "parser.y"
+ { (yyval.vmod) = (yyvsp[(1) - (1)].vmod); }
+ break;
+
+ case 54:
+
+/* Line 1806 of yacc.c */
+#line 365 "parser.y"
+ { (yyval.vmod) = VModCreate((yyvsp[(1) - (1)].sval), NULL); }
+ break;
+
+ case 55:
+
+/* Line 1806 of yacc.c */
+#line 367 "parser.y"
+ { (yyval.vmod) = VModCreate((yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].expr)); }
+ break;
+
+ case 56:
+
+/* Line 1806 of yacc.c */
+#line 373 "parser.y"
+ { (yyvsp[(2) - (6)].interp)->def = (yyvsp[(4) - (6)].var); (yyval.interp) = (yyvsp[(2) - (6)].interp); }
+ break;
+
+ case 57:
+
+/* Line 1806 of yacc.c */
+#line 377 "parser.y"
+ { (yyval.interp) = InterpCreate((yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].expr)); }
+ break;
+
+ case 58:
+
+/* Line 1806 of yacc.c */
+#line 379 "parser.y"
+ { (yyval.interp) = InterpCreate((yyvsp[(1) - (1)].str), NULL); }
+ break;
+
+ case 59:
+
+/* Line 1806 of yacc.c */
+#line 383 "parser.y"
+ { (yyval.var) = (VarDef *)AppendStmt(&(yyvsp[(1) - (2)].var)->common, &(yyvsp[(2) - (2)].var)->common); }
+ break;
+
+ case 60:
+
+/* Line 1806 of yacc.c */
+#line 385 "parser.y"
+ { (yyval.var) = (yyvsp[(1) - (1)].var); }
+ break;
+
+ case 61:
+
+/* Line 1806 of yacc.c */
+#line 391 "parser.y"
+ { (yyval.keyType) = KeyTypeCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].var)); }
+ break;
+
+ case 62:
+
+/* Line 1806 of yacc.c */
+#line 397 "parser.y"
+ { (yyval.syms) = SymbolsCreate((yyvsp[(2) - (6)].sval), (ExprDef *)(yyvsp[(4) - (6)].var)); }
+ break;
+
+ case 63:
+
+/* Line 1806 of yacc.c */
+#line 401 "parser.y"
+ { (yyval.var) = (VarDef *)AppendStmt(&(yyvsp[(1) - (3)].var)->common, &(yyvsp[(3) - (3)].var)->common); }
+ break;
+
+ case 64:
+
+/* Line 1806 of yacc.c */
+#line 403 "parser.y"
+ { (yyval.var) = (yyvsp[(1) - (1)].var); }
+ break;
+
+ case 65:
+
+/* Line 1806 of yacc.c */
+#line 404 "parser.y"
+ { (yyval.var) = NULL; }
+ break;
+
+ case 66:
+
+/* Line 1806 of yacc.c */
+#line 407 "parser.y"
+ { (yyval.var) = VarCreate((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
+ break;
+
+ case 67:
+
+/* Line 1806 of yacc.c */
+#line 408 "parser.y"
+ { (yyval.var) = VarCreate((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
+ break;
+
+ case 68:
+
+/* Line 1806 of yacc.c */
+#line 409 "parser.y"
+ { (yyval.var) = BoolVarCreate((yyvsp[(1) - (1)].sval), 1); }
+ break;
+
+ case 69:
+
+/* Line 1806 of yacc.c */
+#line 410 "parser.y"
+ { (yyval.var) = BoolVarCreate((yyvsp[(2) - (2)].sval), 0); }
+ break;
+
+ case 70:
+
+/* Line 1806 of yacc.c */
+#line 411 "parser.y"
+ { (yyval.var) = VarCreate(NULL, (yyvsp[(1) - (1)].expr)); }
+ break;
+
+ case 71:
+
+/* Line 1806 of yacc.c */
+#line 415 "parser.y"
+ { (yyval.expr) = (yyvsp[(2) - (3)].expr); }
+ break;
+
+ case 72:
+
+/* Line 1806 of yacc.c */
+#line 417 "parser.y"
+ { (yyval.expr) = ExprCreateUnary(EXPR_ACTION_LIST, EXPR_TYPE_ACTION, (yyvsp[(2) - (3)].expr)); }
+ break;
+
+ case 73:
+
+/* Line 1806 of yacc.c */
+#line 421 "parser.y"
+ { (yyval.groupCompat) = GroupCompatCreate((yyvsp[(2) - (5)].ival), (yyvsp[(4) - (5)].expr)); }
+ break;
+
+ case 74:
+
+/* Line 1806 of yacc.c */
+#line 425 "parser.y"
+ { (yyval.modMask) = ModMapCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].expr)); }
+ break;
+
+ case 75:
+
+/* Line 1806 of yacc.c */
+#line 429 "parser.y"
+ { (yyval.ledMap) = LedMapCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].var)); }
+ break;
+
+ case 76:
+
+/* Line 1806 of yacc.c */
+#line 433 "parser.y"
+ { (yyval.ledName) = LedNameCreate((yyvsp[(2) - (5)].ival), (yyvsp[(4) - (5)].expr), false); }
+ break;
+
+ case 77:
+
+/* Line 1806 of yacc.c */
+#line 435 "parser.y"
+ { (yyval.ledName) = LedNameCreate((yyvsp[(3) - (6)].ival), (yyvsp[(5) - (6)].expr), true); }
+ break;
+
+ case 78:
+
+/* Line 1806 of yacc.c */
+#line 439 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 79:
+
+/* Line 1806 of yacc.c */
+#line 441 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 80:
+
+/* Line 1806 of yacc.c */
+#line 445 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 81:
+
+/* Line 1806 of yacc.c */
+#line 448 "parser.y"
+ { (yyval.geom) = NULL;}
+ break;
+
+ case 82:
+
+/* Line 1806 of yacc.c */
+#line 449 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 83:
+
+/* Line 1806 of yacc.c */
+#line 453 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 84:
+
+/* Line 1806 of yacc.c */
+#line 455 "parser.y"
+ { FreeStmt(&(yyvsp[(1) - (1)].var)->common); (yyval.geom) = NULL; }
+ break;
+
+ case 85:
+
+/* Line 1806 of yacc.c */
+#line 457 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 86:
+
+/* Line 1806 of yacc.c */
+#line 459 "parser.y"
+ { FreeStmt(&(yyvsp[(1) - (1)].ledMap)->common); (yyval.geom) = NULL; }
+ break;
+
+ case 87:
+
+/* Line 1806 of yacc.c */
+#line 461 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 88:
+
+/* Line 1806 of yacc.c */
+#line 464 "parser.y"
+ { (yyval.geom) = NULL;}
+ break;
+
+ case 89:
+
+/* Line 1806 of yacc.c */
+#line 465 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 90:
+
+/* Line 1806 of yacc.c */
+#line 468 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 91:
+
+/* Line 1806 of yacc.c */
+#line 470 "parser.y"
+ { FreeStmt(&(yyvsp[(1) - (1)].var)->common); (yyval.geom) = NULL; }
+ break;
+
+ case 92:
+
+/* Line 1806 of yacc.c */
+#line 473 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 93:
+
+/* Line 1806 of yacc.c */
+#line 474 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 94:
+
+/* Line 1806 of yacc.c */
+#line 478 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 95:
+
+/* Line 1806 of yacc.c */
+#line 480 "parser.y"
+ { FreeStmt(&(yyvsp[(2) - (3)].expr)->common); (yyval.geom) = NULL; }
+ break;
+
+ case 96:
+
+/* Line 1806 of yacc.c */
+#line 484 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 97:
+
+/* Line 1806 of yacc.c */
+#line 487 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 98:
+
+/* Line 1806 of yacc.c */
+#line 488 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 99:
+
+/* Line 1806 of yacc.c */
+#line 491 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 100:
+
+/* Line 1806 of yacc.c */
+#line 495 "parser.y"
+ { (yyval.geom) = NULL;}
+ break;
+
+ case 101:
+
+/* Line 1806 of yacc.c */
+#line 497 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 102:
+
+/* Line 1806 of yacc.c */
+#line 501 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 103:
+
+/* Line 1806 of yacc.c */
+#line 503 "parser.y"
+ { (yyval.geom) = NULL; }
+ break;
+
+ case 104:
+
+/* Line 1806 of yacc.c */
+#line 505 "parser.y"
+ { FreeStmt(&(yyvsp[(3) - (3)].expr)->common); (yyval.geom) = NULL; }
+ break;
+
+ case 105:
+
+/* Line 1806 of yacc.c */
+#line 509 "parser.y"
+ { (yyval.expr) = NULL; }
+ break;
+
+ case 106:
+
+/* Line 1806 of yacc.c */
+#line 511 "parser.y"
+ { (yyval.expr) = NULL; }
+ break;
+
+ case 107:
+
+/* Line 1806 of yacc.c */
+#line 515 "parser.y"
+ { (yyval.expr) = NULL; }
+ break;
+
+ case 108:
+
+/* Line 1806 of yacc.c */
+#line 519 "parser.y"
+ { FreeStmt(&(yyvsp[(4) - (6)].var)->common); (yyval.geom) = NULL; }
+ break;
+
+ case 109:
+
+/* Line 1806 of yacc.c */
+#line 522 "parser.y"
+ { (yyval.uval) = 0; }
+ break;
+
+ case 110:
+
+/* Line 1806 of yacc.c */
+#line 523 "parser.y"
+ { (yyval.uval) = 0; }
+ break;
+
+ case 111:
+
+/* Line 1806 of yacc.c */
+#line 524 "parser.y"
+ { (yyval.uval) = 0; }
+ break;
+
+ case 112:
+
+/* Line 1806 of yacc.c */
+#line 525 "parser.y"
+ { (yyval.uval) = 0; }
+ break;
+
+ case 113:
+
+/* Line 1806 of yacc.c */
+#line 528 "parser.y"
+ { (yyval.sval) = (yyvsp[(1) - (1)].sval); }
+ break;
+
+ case 114:
+
+/* Line 1806 of yacc.c */
+#line 529 "parser.y"
+ { (yyval.sval) = (yyvsp[(1) - (1)].sval); }
+ break;
+
+ case 115:
+
+/* Line 1806 of yacc.c */
+#line 533 "parser.y"
+ { (yyval.sval) = xkb_atom_intern(param->ctx, "action"); }
+ break;
+
+ case 116:
+
+/* Line 1806 of yacc.c */
+#line 535 "parser.y"
+ { (yyval.sval) = xkb_atom_intern(param->ctx, "interpret"); }
+ break;
+
+ case 117:
+
+/* Line 1806 of yacc.c */
+#line 537 "parser.y"
+ { (yyval.sval) = xkb_atom_intern(param->ctx, "type"); }
+ break;
+
+ case 118:
+
+/* Line 1806 of yacc.c */
+#line 539 "parser.y"
+ { (yyval.sval) = xkb_atom_intern(param->ctx, "key"); }
+ break;
+
+ case 119:
+
+/* Line 1806 of yacc.c */
+#line 541 "parser.y"
+ { (yyval.sval) = xkb_atom_intern(param->ctx, "group"); }
+ break;
+
+ case 120:
+
+/* Line 1806 of yacc.c */
+#line 543 "parser.y"
+ {(yyval.sval) = xkb_atom_intern(param->ctx, "modifier_map");}
+ break;
+
+ case 121:
+
+/* Line 1806 of yacc.c */
+#line 545 "parser.y"
+ { (yyval.sval) = xkb_atom_intern(param->ctx, "indicator"); }
+ break;
+
+ case 122:
+
+/* Line 1806 of yacc.c */
+#line 547 "parser.y"
+ { (yyval.sval) = XKB_ATOM_NONE; }
+ break;
+
+ case 123:
+
+/* Line 1806 of yacc.c */
+#line 549 "parser.y"
+ { (yyval.sval) = XKB_ATOM_NONE; }
+ break;
+
+ case 124:
+
+/* Line 1806 of yacc.c */
+#line 551 "parser.y"
+ { (yyval.sval) = XKB_ATOM_NONE; }
+ break;
+
+ case 125:
+
+/* Line 1806 of yacc.c */
+#line 553 "parser.y"
+ { (yyval.sval) = XKB_ATOM_NONE; }
+ break;
+
+ case 126:
+
+/* Line 1806 of yacc.c */
+#line 556 "parser.y"
+ { (yyval.merge) = (yyvsp[(1) - (1)].merge); }
+ break;
+
+ case 127:
+
+/* Line 1806 of yacc.c */
+#line 557 "parser.y"
+ { (yyval.merge) = MERGE_DEFAULT; }
+ break;
+
+ case 128:
+
+/* Line 1806 of yacc.c */
+#line 560 "parser.y"
+ { (yyval.merge) = MERGE_DEFAULT; }
+ break;
+
+ case 129:
+
+/* Line 1806 of yacc.c */
+#line 561 "parser.y"
+ { (yyval.merge) = MERGE_AUGMENT; }
+ break;
+
+ case 130:
+
+/* Line 1806 of yacc.c */
+#line 562 "parser.y"
+ { (yyval.merge) = MERGE_OVERRIDE; }
+ break;
+
+ case 131:
+
+/* Line 1806 of yacc.c */
+#line 563 "parser.y"
+ { (yyval.merge) = MERGE_REPLACE; }
+ break;
+
+ case 132:
+
+/* Line 1806 of yacc.c */
+#line 565 "parser.y"
+ {
+ /*
+ * This used to be MERGE_ALT_FORM. This functionality was
+ * unused and has been removed.
+ */
+ (yyval.merge) = MERGE_DEFAULT;
+ }
+ break;
+
+ case 133:
+
+/* Line 1806 of yacc.c */
+#line 574 "parser.y"
+ { (yyval.expr) = (yyvsp[(1) - (1)].expr); }
+ break;
+
+ case 134:
+
+/* Line 1806 of yacc.c */
+#line 575 "parser.y"
+ { (yyval.expr) = NULL; }
+ break;
+
+ case 135:
+
+/* Line 1806 of yacc.c */
+#line 579 "parser.y"
+ { (yyval.expr) = (ExprDef *)AppendStmt(&(yyvsp[(1) - (3)].expr)->common, &(yyvsp[(3) - (3)].expr)->common); }
+ break;
+
+ case 136:
+
+/* Line 1806 of yacc.c */
+#line 581 "parser.y"
+ { (yyval.expr) = (yyvsp[(1) - (1)].expr); }
+ break;
+
+ case 137:
+
+/* Line 1806 of yacc.c */
+#line 585 "parser.y"
+ { (yyval.expr) = ExprCreateBinary(EXPR_DIVIDE, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
+ break;
+
+ case 138:
+
+/* Line 1806 of yacc.c */
+#line 587 "parser.y"
+ { (yyval.expr) = ExprCreateBinary(EXPR_ADD, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
+ break;
+
+ case 139:
+
+/* Line 1806 of yacc.c */
+#line 589 "parser.y"
+ { (yyval.expr) = ExprCreateBinary(EXPR_SUBTRACT, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
+ break;
+
+ case 140:
+
+/* Line 1806 of yacc.c */
+#line 591 "parser.y"
+ { (yyval.expr) = ExprCreateBinary(EXPR_MULTIPLY, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
+ break;
+
+ case 141:
+
+/* Line 1806 of yacc.c */
+#line 593 "parser.y"
+ { (yyval.expr) = ExprCreateBinary(EXPR_ASSIGN, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
+ break;
+
+ case 142:
+
+/* Line 1806 of yacc.c */
+#line 595 "parser.y"
+ { (yyval.expr) = (yyvsp[(1) - (1)].expr); }
+ break;
+
+ case 143:
+
+/* Line 1806 of yacc.c */
+#line 599 "parser.y"
+ { (yyval.expr) = ExprCreateUnary(EXPR_NEGATE, (yyvsp[(2) - (2)].expr)->value_type, (yyvsp[(2) - (2)].expr)); }
+ break;
+
+ case 144:
+
+/* Line 1806 of yacc.c */
+#line 601 "parser.y"
+ { (yyval.expr) = ExprCreateUnary(EXPR_UNARY_PLUS, (yyvsp[(2) - (2)].expr)->value_type, (yyvsp[(2) - (2)].expr)); }
+ break;
+
+ case 145:
+
+/* Line 1806 of yacc.c */
+#line 603 "parser.y"
+ { (yyval.expr) = ExprCreateUnary(EXPR_NOT, EXPR_TYPE_BOOLEAN, (yyvsp[(2) - (2)].expr)); }
+ break;
+
+ case 146:
+
+/* Line 1806 of yacc.c */
+#line 605 "parser.y"
+ { (yyval.expr) = ExprCreateUnary(EXPR_INVERT, (yyvsp[(2) - (2)].expr)->value_type, (yyvsp[(2) - (2)].expr)); }
+ break;
+
+ case 147:
+
+/* Line 1806 of yacc.c */
+#line 607 "parser.y"
+ { (yyval.expr) = (yyvsp[(1) - (1)].expr); }
+ break;
+
+ case 148:
+
+/* Line 1806 of yacc.c */
+#line 609 "parser.y"
+ { (yyval.expr) = ActionCreate((yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].expr)); }
+ break;
+
+ case 149:
+
+/* Line 1806 of yacc.c */
+#line 611 "parser.y"
+ { (yyval.expr) = (yyvsp[(1) - (1)].expr); }
+ break;
+
+ case 150:
+
+/* Line 1806 of yacc.c */
+#line 613 "parser.y"
+ { (yyval.expr) = (yyvsp[(2) - (3)].expr); }
+ break;
+
+ case 151:
+
+/* Line 1806 of yacc.c */
+#line 617 "parser.y"
+ { (yyval.expr) = (ExprDef *)AppendStmt(&(yyvsp[(1) - (3)].expr)->common, &(yyvsp[(3) - (3)].expr)->common); }
+ break;
+
+ case 152:
+
+/* Line 1806 of yacc.c */
+#line 619 "parser.y"
+ { (yyval.expr) = (yyvsp[(1) - (1)].expr); }
+ break;
+
+ case 153:
+
+/* Line 1806 of yacc.c */
+#line 623 "parser.y"
+ { (yyval.expr) = ActionCreate((yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].expr)); }
+ break;
+
+ case 154:
+
+/* Line 1806 of yacc.c */
+#line 627 "parser.y"
+ {
+ ExprDef *expr;
+ expr = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
+ expr->value.str = (yyvsp[(1) - (1)].sval);
+ (yyval.expr) = expr;
+ }
+ break;
+
+ case 155:
+
+/* Line 1806 of yacc.c */
+#line 634 "parser.y"
+ {
+ ExprDef *expr;
+ expr = ExprCreate(EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN);
+ expr->value.field.element = (yyvsp[(1) - (3)].sval);
+ expr->value.field.field = (yyvsp[(3) - (3)].sval);
+ (yyval.expr) = expr;
+ }
+ break;
+
+ case 156:
+
+/* Line 1806 of yacc.c */
+#line 642 "parser.y"
+ {
+ ExprDef *expr;
+ expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN);
+ expr->value.array.element = XKB_ATOM_NONE;
+ expr->value.array.field = (yyvsp[(1) - (4)].sval);
+ expr->value.array.entry = (yyvsp[(3) - (4)].expr);
+ (yyval.expr) = expr;
+ }
+ break;
+
+ case 157:
+
+/* Line 1806 of yacc.c */
+#line 651 "parser.y"
+ {
+ ExprDef *expr;
+ expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN);
+ expr->value.array.element = (yyvsp[(1) - (6)].sval);
+ expr->value.array.field = (yyvsp[(3) - (6)].sval);
+ expr->value.array.entry = (yyvsp[(5) - (6)].expr);
+ (yyval.expr) = expr;
+ }
+ break;
+
+ case 158:
+
+/* Line 1806 of yacc.c */
+#line 662 "parser.y"
+ {
+ ExprDef *expr;
+ expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_STRING);
+ expr->value.str = (yyvsp[(1) - (1)].sval);
+ (yyval.expr) = expr;
+ }
+ break;
+
+ case 159:
+
+/* Line 1806 of yacc.c */
+#line 669 "parser.y"
+ {
+ ExprDef *expr;
+ expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_INT);
+ expr->value.ival = (yyvsp[(1) - (1)].ival);
+ (yyval.expr) = expr;
+ }
+ break;
+
+ case 160:
+
+/* Line 1806 of yacc.c */
+#line 676 "parser.y"
+ {
+ (yyval.expr) = NULL;
+ }
+ break;
+
+ case 161:
+
+/* Line 1806 of yacc.c */
+#line 680 "parser.y"
+ {
+ ExprDef *expr;
+ expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_KEYNAME);
+ expr->value.keyName = (yyvsp[(1) - (1)].sval);
+ (yyval.expr) = expr;
+ }
+ break;
+
+ case 162:
+
+/* Line 1806 of yacc.c */
+#line 688 "parser.y"
+ { (yyval.expr) = (yyvsp[(1) - (1)].expr); }
+ break;
+
+ case 163:
+
+/* Line 1806 of yacc.c */
+#line 689 "parser.y"
+ { (yyval.expr) = NULL; }
+ break;
+
+ case 164:
+
+/* Line 1806 of yacc.c */
+#line 693 "parser.y"
+ { (yyval.expr) = AppendKeysymList((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].str)); }
+ break;
+
+ case 165:
+
+/* Line 1806 of yacc.c */
+#line 695 "parser.y"
+ { (yyval.expr) = AppendMultiKeysymList((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
+ break;
+
+ case 166:
+
+/* Line 1806 of yacc.c */
+#line 697 "parser.y"
+ { (yyval.expr) = CreateKeysymList((yyvsp[(1) - (1)].str)); }
+ break;
+
+ case 167:
+
+/* Line 1806 of yacc.c */
+#line 699 "parser.y"
+ { (yyval.expr) = CreateMultiKeysymList((yyvsp[(1) - (1)].expr)); }
+ break;
+
+ case 168:
+
+/* Line 1806 of yacc.c */
+#line 703 "parser.y"
+ { (yyval.expr) = (yyvsp[(2) - (3)].expr); }
+ break;
+
+ case 169:
+
+/* Line 1806 of yacc.c */
+#line 706 "parser.y"
+ { (yyval.str) = (yyvsp[(1) - (1)].str); }
+ break;
+
+ case 170:
+
+/* Line 1806 of yacc.c */
+#line 707 "parser.y"
+ { (yyval.str) = strdup("section"); }
+ break;
+
+ case 171:
+
+/* Line 1806 of yacc.c */
+#line 709 "parser.y"
+ {
+ if ((yyvsp[(1) - (1)].ival) < 10) { /* XK_0 .. XK_9 */
+ (yyval.str) = malloc(2);
+ (yyval.str)[0] = (yyvsp[(1) - (1)].ival) + '0';
+ (yyval.str)[1] = '\0';
+ }
+ else {
+ (yyval.str) = malloc(17);
+ snprintf((yyval.str), 17, "0x%x", (yyvsp[(1) - (1)].ival));
+ }
+ }
+ break;
+
+ case 172:
+
+/* Line 1806 of yacc.c */
+#line 722 "parser.y"
+ { (yyval.ival) = -(yyvsp[(2) - (2)].ival); }
+ break;
+
+ case 173:
+
+/* Line 1806 of yacc.c */
+#line 723 "parser.y"
+ { (yyval.ival) = (yyvsp[(1) - (1)].ival); }
+ break;
+
+ case 174:
+
+/* Line 1806 of yacc.c */
+#line 726 "parser.y"
+ { (yyval.ival) = (yyvsp[(1) - (1)].num); }
+ break;
+
+ case 175:
+
+/* Line 1806 of yacc.c */
+#line 727 "parser.y"
+ { (yyval.ival) = (yyvsp[(1) - (1)].num); }
+ break;
+
+ case 176:
+
+/* Line 1806 of yacc.c */
+#line 730 "parser.y"
+ { (yyval.ival) = 0; }
+ break;
+
+ case 177:
+
+/* Line 1806 of yacc.c */
+#line 733 "parser.y"
+ { (yyval.ival) = (yyvsp[(1) - (1)].num); }
+ break;
+
+ case 178:
+
+/* Line 1806 of yacc.c */
+#line 736 "parser.y"
+ { (yyval.num) = (yyvsp[(1) - (1)].num); }
+ break;
+
+ case 179:
+
+/* Line 1806 of yacc.c */
+#line 739 "parser.y"
+ { (yyval.sval) = xkb_atom_steal(param->ctx, (yyvsp[(1) - (1)].str)); }
+ break;
+
+ case 180:
+
+/* Line 1806 of yacc.c */
+#line 740 "parser.y"
+ { (yyval.sval) = xkb_atom_intern(param->ctx, "default"); }
+ break;
+
+ case 181:
+
+/* Line 1806 of yacc.c */
+#line 743 "parser.y"
+ { (yyval.sval) = xkb_atom_steal(param->ctx, (yyvsp[(1) - (1)].str)); }
+ break;
+
+ case 182:
+
+/* Line 1806 of yacc.c */
+#line 746 "parser.y"
+ { (yyval.str) = (yyvsp[(1) - (1)].str); }
+ break;
+
+ case 183:
+
+/* Line 1806 of yacc.c */
+#line 747 "parser.y"
+ { (yyval.str) = NULL; }
+ break;
+
+ case 184:
+
+/* Line 1806 of yacc.c */
+#line 750 "parser.y"
+ { (yyval.str) = (yyvsp[(1) - (1)].str); }
+ break;
+
+
+
+/* Line 1806 of yacc.c */
+#line 3386 "src/xkbcomp/parser.c"
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+ *++yylsp = yyloc;
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (&yylloc, param, YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+ yyssp, yytoken)
+ {
+ char const *yymsgp = YY_("syntax error");
+ int yysyntax_error_status;
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ if (yysyntax_error_status == 0)
+ yymsgp = yymsg;
+ else if (yysyntax_error_status == 1)
+ {
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+ if (!yymsg)
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ yysyntax_error_status = 2;
+ }
+ else
+ {
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ yymsgp = yymsg;
+ }
+ }
+ yyerror (&yylloc, param, yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
+ }
+# undef YYSYNTAX_ERROR
+#endif
+ }
+
+ yyerror_range[1] = yylloc;
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval, &yylloc, param);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ yyerror_range[1] = yylsp[1-yylen];
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default (yyn))
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ yyerror_range[1] = *yylsp;
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp, yylsp, param);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ *++yyvsp = yylval;
+
+ yyerror_range[2] = yylloc;
+ /* Using YYLLOC is tempting, but would change the location of
+ the lookahead. YYLOC is available though. */
+ YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
+ *++yylsp = yyloc;
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined(yyoverflow) || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (&yylloc, param, YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval, &yylloc, param);
+ }
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp, yylsp, param);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+
+/* Line 2067 of yacc.c */
+#line 753 "parser.y"
+
+
+#undef scanner
+
+XkbFile *
+parse(struct xkb_context *ctx, void *scanner, const char *map)
+{
+ struct parser_param param;
+ int ret;
+ XkbFile *first = NULL;
+
+ param.scanner = scanner;
+ param.ctx = ctx;
+
+ /*
+ * If we got a specific map, we look for it exclusively and return
+ * immediately upon finding it. Otherwise, we need to get the
+ * default map. If we find a map marked as default, we return it
+ * immediately. If there are no maps marked as default, we return
+ * the first map in the file.
+ */
+
+ while ((ret = yyparse(&param)) == 0 && param.more_maps) {
+ if (map) {
+ if (streq_not_null(map, param.rtrn->name))
+ return param.rtrn;
+ else
+ FreeXkbFile(param.rtrn);
+ }
+ else {
+ if (param.rtrn->flags & MAP_IS_DEFAULT) {
+ FreeXkbFile(first);
+ return param.rtrn;
+ }
+ else if (!first) {
+ first = param.rtrn;
+ }
+ else {
+ FreeXkbFile(param.rtrn);
+ }
+ }
+ }
+
+ if (ret != 0) {
+ FreeXkbFile(first);
+ return NULL;
+ }
+
+ return first;
+}
+
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser.h b/src/3rdparty/xkbcommon/src/xkbcomp/parser.h
new file mode 100644
index 0000000000..fba3f4ebd0
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser.h
@@ -0,0 +1,230 @@
+/* A Bison parser, made by GNU Bison 2.5. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ END_OF_FILE = 0,
+ ERROR_TOK = 255,
+ XKB_KEYMAP = 1,
+ XKB_KEYCODES = 2,
+ XKB_TYPES = 3,
+ XKB_SYMBOLS = 4,
+ XKB_COMPATMAP = 5,
+ XKB_GEOMETRY = 6,
+ XKB_SEMANTICS = 7,
+ XKB_LAYOUT = 8,
+ INCLUDE = 10,
+ OVERRIDE = 11,
+ AUGMENT = 12,
+ REPLACE = 13,
+ ALTERNATE = 14,
+ VIRTUAL_MODS = 20,
+ TYPE = 21,
+ INTERPRET = 22,
+ ACTION_TOK = 23,
+ KEY = 24,
+ ALIAS = 25,
+ GROUP = 26,
+ MODIFIER_MAP = 27,
+ INDICATOR = 28,
+ SHAPE = 29,
+ KEYS = 30,
+ ROW = 31,
+ SECTION = 32,
+ OVERLAY = 33,
+ TEXT = 34,
+ OUTLINE = 35,
+ SOLID = 36,
+ LOGO = 37,
+ VIRTUAL = 38,
+ EQUALS = 40,
+ PLUS = 41,
+ MINUS = 42,
+ DIVIDE = 43,
+ TIMES = 44,
+ OBRACE = 45,
+ CBRACE = 46,
+ OPAREN = 47,
+ CPAREN = 48,
+ OBRACKET = 49,
+ CBRACKET = 50,
+ DOT = 51,
+ COMMA = 52,
+ SEMI = 53,
+ EXCLAM = 54,
+ INVERT = 55,
+ STRING = 60,
+ INTEGER = 61,
+ FLOAT = 62,
+ IDENT = 63,
+ KEYNAME = 64,
+ PARTIAL = 70,
+ DEFAULT = 71,
+ HIDDEN = 72,
+ ALPHANUMERIC_KEYS = 73,
+ MODIFIER_KEYS = 74,
+ KEYPAD_KEYS = 75,
+ FUNCTION_KEYS = 76,
+ ALTERNATE_GROUP = 77
+ };
+#endif
+/* Tokens. */
+#define END_OF_FILE 0
+#define ERROR_TOK 255
+#define XKB_KEYMAP 1
+#define XKB_KEYCODES 2
+#define XKB_TYPES 3
+#define XKB_SYMBOLS 4
+#define XKB_COMPATMAP 5
+#define XKB_GEOMETRY 6
+#define XKB_SEMANTICS 7
+#define XKB_LAYOUT 8
+#define INCLUDE 10
+#define OVERRIDE 11
+#define AUGMENT 12
+#define REPLACE 13
+#define ALTERNATE 14
+#define VIRTUAL_MODS 20
+#define TYPE 21
+#define INTERPRET 22
+#define ACTION_TOK 23
+#define KEY 24
+#define ALIAS 25
+#define GROUP 26
+#define MODIFIER_MAP 27
+#define INDICATOR 28
+#define SHAPE 29
+#define KEYS 30
+#define ROW 31
+#define SECTION 32
+#define OVERLAY 33
+#define TEXT 34
+#define OUTLINE 35
+#define SOLID 36
+#define LOGO 37
+#define VIRTUAL 38
+#define EQUALS 40
+#define PLUS 41
+#define MINUS 42
+#define DIVIDE 43
+#define TIMES 44
+#define OBRACE 45
+#define CBRACE 46
+#define OPAREN 47
+#define CPAREN 48
+#define OBRACKET 49
+#define CBRACKET 50
+#define DOT 51
+#define COMMA 52
+#define SEMI 53
+#define EXCLAM 54
+#define INVERT 55
+#define STRING 60
+#define INTEGER 61
+#define FLOAT 62
+#define IDENT 63
+#define KEYNAME 64
+#define PARTIAL 70
+#define DEFAULT 71
+#define HIDDEN 72
+#define ALPHANUMERIC_KEYS 73
+#define MODIFIER_KEYS 74
+#define KEYPAD_KEYS 75
+#define FUNCTION_KEYS 76
+#define ALTERNATE_GROUP 77
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 2068 of yacc.c */
+#line 127 "parser.y"
+
+ int ival;
+ unsigned uval;
+ int64_t num;
+ enum xkb_file_type file_type;
+ char *str;
+ xkb_atom_t sval;
+ enum merge_mode merge;
+ enum xkb_map_flags mapFlags;
+ ParseCommon *any;
+ ExprDef *expr;
+ VarDef *var;
+ VModDef *vmod;
+ InterpDef *interp;
+ KeyTypeDef *keyType;
+ SymbolsDef *syms;
+ ModMapDef *modMask;
+ GroupCompatDef *groupCompat;
+ LedMapDef *ledMap;
+ LedNameDef *ledName;
+ KeycodeDef *keyCode;
+ KeyAliasDef *keyAlias;
+ void *geom;
+ XkbFile *file;
+
+
+
+/* Line 2068 of yacc.c */
+#line 208 "src/xkbcomp/parser.h"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/rules.c b/src/3rdparty/xkbcommon/src/xkbcomp/rules.c
new file mode 100644
index 0000000000..3f717600fd
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/rules.c
@@ -0,0 +1,1231 @@
+/************************************************************
+ * Copyright (c) 1996 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+/*
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "xkbcomp-priv.h"
+#include "rules.h"
+#include "include.h"
+
+/*
+ * The rules file
+ * ==============
+ * The purpose of this file is to map between configuration values that
+ * are easy for a user to specify and understand, and the configuration
+ * values xkbcomp uses and understands.
+ * xkbcomp uses the xkb_component_names struct, which maps directly to
+ * include statements of the appropriate sections, called for short
+ * KcCGST (see keycodes.c, types.c, compat.c, symbols.c; geometry.c was
+ * removed). These are not really intuitive or straight-forward for
+ * the uninitiated.
+ * Instead, the user passes in a xkb_rule_names struct, which consists
+ * of the name of a rules file (in Linux this is usually "evdev"), a
+ * keyboard model (e.g. "pc105"), a set of layouts (which will end up
+ * in different groups, e.g. "us,fr"), variants (used to alter/augment
+ * the respective layout, e.g. "intl,dvorak"), and a set of options
+ * (used to tweak some general behavior of the keyboard, e.g.
+ * "ctrl:nocaps,compose:menu" to make the Caps Lock key act like Ctrl
+ * and the Menu key like Compose). We call these RMLVO.
+ *
+ * Format of the file
+ * ------------------
+ * The file consists of rule sets, each consisting of rules (one per
+ * line), which match the MLVO values on the left hand side, and, if
+ * the values match to the values the user passed in, results in the
+ * values on the right hand side being added to the resulting KcCGST.
+ * Since some values are related and repeated often, it is possible
+ * to group them together and refer to them by a group name in the
+ * rules.
+ * Along with matching values by simple string equality, and for
+ * membership in a group defined previously, rules may also contain
+ * "wildcard" values - "*" - which always match. These usually appear
+ * near the end.
+ *
+ * Grammer
+ * -------
+ * (It might be helpful to look at a file like rules/evdev along with
+ * this grammer. Comments, whitespace, etc. are not shown.)
+ *
+ * File ::= { "!" (Group | RuleSet) }
+ *
+ * Group ::= GroupName "=" { GroupElement } "\n"
+ * GroupName ::= "$"<ident>
+ * GroupElement ::= <ident>
+ *
+ * RuleSet ::= Mapping { Rule }
+ *
+ * Mapping ::= { Mlvo } "=" { Kccgst } "\n"
+ * Mlvo ::= "model" | "option" | ("layout" | "variant") [ Index ]
+ * Index ::= "[" 1..XKB_NUM_GROUPS "]"
+ * Kccgst ::= "keycodes" | "symbols" | "types" | "compat" | "geometry"
+ *
+ * Rule ::= { MlvoValue } "=" { KccgstValue } "\n"
+ * MlvoValue ::= "*" | GroupName | <ident>
+ * KccgstValue ::= <ident>
+ *
+ * Notes:
+ * - The order of values in a Rule must be the same as the Mapping it
+ * follows. The mapping line determines the meaning of the values in
+ * the rules which follow in the RuleSet.
+ * - If a Rule is matched, %-expansion is performed on the KccgstValue,
+ * as follows:
+ * %m, %l, %v:
+ * The model, layout or variant, if only one was given (e.g.
+ * %l for "us,il" is invalid).
+ * %l[1], %v[1]:
+ * Layout or variant for the specified group Index, if more than
+ * one was given (e.g. %l[1] for "us" is invalid).
+ * %+m, %+l, %+v, %+l[1], %+v[1]
+ * As above, but prefixed with '+'. Similarly, '|', '-', '_' may be
+ * used instead of '+'.
+ * %(m), %(l), %(l[1]), %(v), %(v[1]):
+ * As above, but prefixed by '(' and suffixed by ')'.
+ * In case the expansion is invalid, as described above, it is
+ * skipped (the rest of the string is still processed); this includes
+ * the prefix and suffix (that's why you shouldn't use e.g. "(%v[1])").
+ */
+
+/* Scanner / Lexer */
+
+/* Point to some substring in the file; used to avoid copying. */
+struct sval {
+ const char *start;
+ unsigned int len;
+};
+typedef darray(struct sval) darray_sval;
+
+static inline bool
+svaleq(struct sval s1, struct sval s2)
+{
+ return s1.len == s2.len && strncmp(s1.start, s2.start, s1.len) == 0;
+}
+
+static inline bool
+svaleq_prefix(struct sval s1, struct sval s2)
+{
+ return s1.len <= s2.len && strncmp(s1.start, s2.start, s1.len) == 0;
+}
+
+/* Values returned with some tokens, like yylval. */
+union lvalue {
+ struct sval string;
+};
+
+/*
+ * Holds the location in the file of the last processed token,
+ * like yylloc.
+ */
+struct location {
+ int line, column;
+};
+
+struct scanner {
+ const char *s;
+ size_t pos;
+ size_t len;
+ int line, column;
+ const char *file_name;
+ struct xkb_context *ctx;
+};
+
+enum rules_token {
+ TOK_END_OF_FILE = 0,
+ TOK_END_OF_LINE,
+ TOK_IDENTIFIER,
+ TOK_GROUP_NAME,
+ TOK_BANG,
+ TOK_EQUALS,
+ TOK_STAR,
+ TOK_ERROR
+};
+
+static void
+scanner_init(struct scanner *s, struct xkb_context *ctx,
+ const char *string, size_t len, const char *file_name)
+{
+ s->s = string;
+ s->len = len;
+ s->pos = 0;
+ s->line = s->column = 1;
+ s->file_name = file_name;
+ s->ctx = ctx;
+}
+
+/* C99 is stupid. Just use the 1 variant when there are no args. */
+#define scanner_error1(scanner, loc, msg) \
+ log_warn(scanner->ctx, "rules/%s:%d:%d: " msg "\n", \
+ scanner->file_name, loc->line, loc->column)
+#define scanner_error(scanner, loc, fmt, ...) \
+ log_warn(scanner->ctx, "rules/%s:%d:%d: " fmt "\n", \
+ scanner->file_name, loc->line, loc->column, __VA_ARGS__)
+
+static char
+peek(struct scanner *s)
+{
+ return s->pos < s->len ? s->s[s->pos] : '\0';
+}
+
+static bool
+eof(struct scanner *s)
+{
+ return peek(s) == '\0';
+}
+
+static bool
+eol(struct scanner *s)
+{
+ return peek(s) == '\n';
+}
+
+static char
+next(struct scanner *s)
+{
+ if (eof(s))
+ return '\0';
+ if (eol(s)) {
+ s->line++;
+ s->column = 1;
+ }
+ else {
+ s->column++;
+ }
+ return s->s[s->pos++];
+}
+
+static bool
+chr(struct scanner *s, char ch)
+{
+ if (peek(s) != ch)
+ return false;
+ s->pos++; s->column++;
+ return true;
+}
+
+static bool
+str(struct scanner *s, const char *string, size_t len)
+{
+ if (s->len - s->pos < len)
+ return false;
+ if (strncasecmp(s->s + s->pos, string, len) != 0)
+ return false;
+ s->pos += len; s->column += len;
+ return true;
+}
+
+#define lit(s, literal) str(s, literal, sizeof(literal) - 1)
+
+static enum rules_token
+lex(struct scanner *s, union lvalue *val, struct location *loc)
+{
+skip_more_whitespace_and_comments:
+ /* Skip spaces. */
+ while (chr(s, ' ') || chr(s, '\t'));
+
+ /* Skip comments. */
+ if (lit(s, "//")) {
+ while (!eof(s) && !eol(s)) next(s);
+ }
+
+ /* New line. */
+ if (eol(s)) {
+ while (eol(s)) next(s);
+ return TOK_END_OF_LINE;
+ }
+
+ /* Escaped line continuation. */
+ if (chr(s, '\\')) {
+ if (!eol(s)) {
+ scanner_error1(s, loc,
+ "illegal new line escape; must appear at end of line");
+ return TOK_ERROR;
+ }
+ next(s);
+ goto skip_more_whitespace_and_comments;
+ }
+
+ /* See if we're done. */
+ if (eof(s)) return TOK_END_OF_FILE;
+
+ /* New token. */
+ loc->line = s->line;
+ loc->column = s->column;
+
+ /* Operators and punctuation. */
+ if (chr(s, '!')) return TOK_BANG;
+ if (chr(s, '=')) return TOK_EQUALS;
+ if (chr(s, '*')) return TOK_STAR;
+
+ /* Group name. */
+ if (chr(s, '$')) {
+ val->string.start = s->s + s->pos;
+ val->string.len = 0;
+ while (isgraph(peek(s))) {
+ next(s);
+ val->string.len++;
+ }
+ if (val->string.len == 0) {
+ scanner_error1(s, loc,
+ "unexpected character after \'$\'; expected name");
+ return TOK_ERROR;
+ }
+ return TOK_GROUP_NAME;
+ }
+
+ /* Identifier. */
+ if (isgraph(peek(s))) {
+ val->string.start = s->s + s->pos;
+ val->string.len = 0;
+ while (isgraph(peek(s))) {
+ next(s);
+ val->string.len++;
+ }
+ return TOK_IDENTIFIER;
+ }
+
+ scanner_error1(s, loc, "unrecognized token");
+ return TOK_ERROR;
+}
+
+/***====================================================================***/
+
+enum rules_mlvo {
+ MLVO_MODEL,
+ MLVO_LAYOUT,
+ MLVO_VARIANT,
+ MLVO_OPTION,
+ _MLVO_NUM_ENTRIES
+};
+
+#define SVAL_LIT(literal) { literal, sizeof(literal) - 1 }
+
+static const struct sval rules_mlvo_svals[_MLVO_NUM_ENTRIES] = {
+ [MLVO_MODEL] = SVAL_LIT("model"),
+ [MLVO_LAYOUT] = SVAL_LIT("layout"),
+ [MLVO_VARIANT] = SVAL_LIT("variant"),
+ [MLVO_OPTION] = SVAL_LIT("option"),
+};
+
+enum rules_kccgst {
+ KCCGST_KEYCODES,
+ KCCGST_TYPES,
+ KCCGST_COMPAT,
+ KCCGST_SYMBOLS,
+ KCCGST_GEOMETRY,
+ _KCCGST_NUM_ENTRIES
+};
+
+static const struct sval rules_kccgst_svals[_KCCGST_NUM_ENTRIES] = {
+ [KCCGST_KEYCODES] = SVAL_LIT("keycodes"),
+ [KCCGST_TYPES] = SVAL_LIT("types"),
+ [KCCGST_COMPAT] = SVAL_LIT("compat"),
+ [KCCGST_SYMBOLS] = SVAL_LIT("symbols"),
+ [KCCGST_GEOMETRY] = SVAL_LIT("geometry"),
+};
+
+/*
+ * A broken-down version of xkb_rule_names (without the rules,
+ * obviously).
+ */
+struct rule_names {
+ struct sval model;
+ darray_sval layouts;
+ darray_sval variants;
+ darray_sval options;
+};
+
+struct group {
+ struct sval name;
+ darray_sval elements;
+};
+
+struct mapping {
+ int mlvo_at_pos[_MLVO_NUM_ENTRIES];
+ unsigned int num_mlvo;
+ unsigned int defined_mlvo_mask;
+ xkb_layout_index_t layout_idx, variant_idx;
+ int kccgst_at_pos[_KCCGST_NUM_ENTRIES];
+ unsigned int num_kccgst;
+ unsigned int defined_kccgst_mask;
+ bool skip;
+};
+
+enum mlvo_match_type {
+ MLVO_MATCH_NORMAL = 0,
+ MLVO_MATCH_WILDCARD,
+ MLVO_MATCH_GROUP,
+};
+
+struct rule {
+ struct sval mlvo_value_at_pos[_MLVO_NUM_ENTRIES];
+ enum mlvo_match_type match_type_at_pos[_MLVO_NUM_ENTRIES];
+ unsigned int num_mlvo_values;
+ struct sval kccgst_value_at_pos[_KCCGST_NUM_ENTRIES];
+ unsigned int num_kccgst_values;
+ bool skip;
+};
+
+/*
+ * This is the main object used to match a given RMLVO against a rules
+ * file and aggragate the results in a KcCGST. It goes through a simple
+ * matching state machine, with tokens as transitions (see
+ * matcher_match()).
+ */
+struct matcher {
+ struct xkb_context *ctx;
+ /* Input.*/
+ struct rule_names rmlvo;
+ struct location loc;
+ union lvalue val;
+ struct scanner scanner;
+ darray(struct group) groups;
+ /* Current mapping. */
+ struct mapping mapping;
+ /* Current rule. */
+ struct rule rule;
+ /* Output. */
+ darray_char kccgst[_KCCGST_NUM_ENTRIES];
+};
+
+static struct sval
+strip_spaces(struct sval v)
+{
+ while (v.len > 0 && isspace(v.start[0])) { v.len--; v.start++; }
+ while (v.len > 0 && isspace(v.start[v.len - 1])) v.len--;
+ return v;
+}
+
+static darray_sval
+split_comma_separated_string(const char *s)
+{
+ darray_sval arr = darray_new();
+ struct sval val = { NULL, 0 };
+
+ /*
+ * Make sure the array returned by this function always includes at
+ * least one value, e.g. "" -> { "" } and "," -> { "", "" }.
+ */
+
+ if (!s) {
+ darray_append(arr, val);
+ return arr;
+ }
+
+ while (true) {
+ val.start = s; val.len = 0;
+ while (*s != '\0' && *s != ',') { s++; val.len++; }
+ darray_append(arr, strip_spaces(val));
+ if (*s == '\0') break;
+ if (*s == ',') s++;
+ }
+
+ return arr;
+}
+
+static struct matcher *
+matcher_new(struct xkb_context *ctx,
+ const struct xkb_rule_names *rmlvo)
+{
+ struct matcher *m = calloc(1, sizeof(*m));
+ if (!m)
+ return NULL;
+
+ m->ctx = ctx;
+ m->rmlvo.model.start = rmlvo->model;
+ m->rmlvo.model.len = rmlvo->model ? strlen(rmlvo->model) : 0;
+ m->rmlvo.layouts = split_comma_separated_string(rmlvo->layout);
+ m->rmlvo.variants = split_comma_separated_string(rmlvo->variant);
+ m->rmlvo.options = split_comma_separated_string(rmlvo->options);
+
+ return m;
+}
+
+static void
+matcher_free(struct matcher *m)
+{
+ struct group *group;
+ if (!m)
+ return;
+ darray_free(m->rmlvo.layouts);
+ darray_free(m->rmlvo.variants);
+ darray_free(m->rmlvo.options);
+ darray_foreach(group, m->groups)
+ darray_free(group->elements);
+ darray_free(m->groups);
+ free(m);
+}
+
+/* C99 is stupid. Just use the 1 variant when there are no args. */
+#define matcher_error1(matcher, msg) \
+ log_warn(matcher->ctx, "rules/%s:%d:%d: " msg "\n", \
+ matcher->scanner.file_name, matcher->loc.line, \
+ matcher->loc.column)
+#define matcher_error(matcher, fmt, ...) \
+ log_warn(matcher->ctx, "rules/%s:%d:%d: " fmt "\n", \
+ matcher->scanner.file_name, matcher->loc.line, \
+ matcher->loc.column, __VA_ARGS__)
+
+static void
+matcher_group_start_new(struct matcher *m, struct sval name)
+{
+ struct group group = { .name = name, .elements = darray_new() };
+ darray_append(m->groups, group);
+}
+
+static void
+matcher_group_add_element(struct matcher *m, struct sval element)
+{
+ darray_append(darray_item(m->groups, darray_size(m->groups) - 1).elements,
+ element);
+}
+
+static void
+matcher_mapping_start_new(struct matcher *m)
+{
+ unsigned int i;
+ for (i = 0; i < _MLVO_NUM_ENTRIES; i++)
+ m->mapping.mlvo_at_pos[i] = -1;
+ for (i = 0; i < _KCCGST_NUM_ENTRIES; i++)
+ m->mapping.kccgst_at_pos[i] = -1;
+ m->mapping.layout_idx = m->mapping.variant_idx = XKB_LAYOUT_INVALID;
+ m->mapping.num_mlvo = m->mapping.num_kccgst = 0;
+ m->mapping.defined_mlvo_mask = 0;
+ m->mapping.defined_kccgst_mask = 0;
+ m->mapping.skip = false;
+}
+
+static int
+extract_layout_index(const char *s, size_t max_len, xkb_layout_index_t *out)
+{
+ /* This function is pretty stupid, but works for now. */
+ *out = XKB_LAYOUT_INVALID;
+ if (max_len < 3)
+ return -1;
+ if (s[0] != '[' || !isdigit(s[1]) || s[2] != ']')
+ return -1;
+ if (s[1] - '0' < 1 || s[1] - '0' > XKB_MAX_GROUPS)
+ return -1;
+ /* To zero-based index. */
+ *out = s[1] - '0' - 1;
+ return 3;
+}
+
+static void
+matcher_mapping_set_mlvo(struct matcher *m, struct sval ident)
+{
+ enum rules_mlvo mlvo;
+ struct sval mlvo_sval;
+ xkb_layout_index_t idx;
+ int consumed;
+
+ for (mlvo = 0; mlvo < _MLVO_NUM_ENTRIES; mlvo++) {
+ mlvo_sval = rules_mlvo_svals[mlvo];
+
+ if (svaleq_prefix(mlvo_sval, ident))
+ break;
+ }
+
+ /* Not found. */
+ if (mlvo >= _MLVO_NUM_ENTRIES) {
+ matcher_error(m,
+ "invalid mapping: %.*s is not a valid value here; "
+ "ignoring rule set",
+ ident.len, ident.start);
+ m->mapping.skip = true;
+ return;
+ }
+
+ if (m->mapping.defined_mlvo_mask & (1 << mlvo)) {
+ matcher_error(m,
+ "invalid mapping: %.*s appears twice on the same line; "
+ "ignoring rule set",
+ mlvo_sval.len, mlvo_sval.start);
+ m->mapping.skip = true;
+ return;
+ }
+
+ /* If there are leftovers still, it must be an index. */
+ if (mlvo_sval.len < ident.len) {
+ consumed = extract_layout_index(ident.start + mlvo_sval.len,
+ ident.len - mlvo_sval.len, &idx);
+ if ((int) (ident.len - mlvo_sval.len) != consumed) {
+ matcher_error(m,
+ "invalid mapping:\" %.*s\" may only be followed by a valid group index; "
+ "ignoring rule set",
+ mlvo_sval.len, mlvo_sval.start);
+ m->mapping.skip = true;
+ return;
+ }
+
+ if (mlvo == MLVO_LAYOUT) {
+ m->mapping.layout_idx = idx;
+ }
+ else if (mlvo == MLVO_VARIANT) {
+ m->mapping.variant_idx = idx;
+ }
+ else {
+ matcher_error(m,
+ "invalid mapping: \"%.*s\" cannot be followed by a group index; "
+ "ignoring rule set",
+ mlvo_sval.len, mlvo_sval.start);
+ m->mapping.skip = true;
+ return;
+ }
+ }
+
+ m->mapping.mlvo_at_pos[m->mapping.num_mlvo] = mlvo;
+ m->mapping.defined_mlvo_mask |= 1 << mlvo;
+ m->mapping.num_mlvo++;
+}
+
+static void
+matcher_mapping_set_kccgst(struct matcher *m, struct sval ident)
+{
+ enum rules_kccgst kccgst;
+ struct sval kccgst_sval;
+
+ for (kccgst = 0; kccgst < _KCCGST_NUM_ENTRIES; kccgst++) {
+ kccgst_sval = rules_kccgst_svals[kccgst];
+
+ if (svaleq(rules_kccgst_svals[kccgst], ident))
+ break;
+ }
+
+ /* Not found. */
+ if (kccgst >= _KCCGST_NUM_ENTRIES) {
+ matcher_error(m,
+ "invalid mapping: %.*s is not a valid value here; "
+ "ignoring rule set",
+ ident.len, ident.start);
+ m->mapping.skip = true;
+ return;
+ }
+
+ if (m->mapping.defined_kccgst_mask & (1 << kccgst)) {
+ matcher_error(m,
+ "invalid mapping: %.*s appears twice on the same line; "
+ "ignoring rule set",
+ kccgst_sval.len, kccgst_sval.start);
+ m->mapping.skip = true;
+ return;
+ }
+
+ m->mapping.kccgst_at_pos[m->mapping.num_kccgst] = kccgst;
+ m->mapping.defined_kccgst_mask |= 1 << kccgst;
+ m->mapping.num_kccgst++;
+}
+
+static void
+matcher_mapping_verify(struct matcher *m)
+{
+ if (m->mapping.num_mlvo == 0) {
+ matcher_error1(m,
+ "invalid mapping: must have at least one value on the left hand side; "
+ "ignoring rule set");
+ goto skip;
+ }
+
+ if (m->mapping.num_kccgst == 0) {
+ matcher_error1(m,
+ "invalid mapping: must have at least one value on the right hand side; "
+ "ignoring rule set");
+ goto skip;
+ }
+
+ /*
+ * This following is very stupid, but this is how it works.
+ * See the "Notes" section in the overview above.
+ */
+
+ if (m->mapping.defined_mlvo_mask & (1 << MLVO_LAYOUT)) {
+ if (m->mapping.layout_idx == XKB_LAYOUT_INVALID) {
+ if (darray_size(m->rmlvo.layouts) > 1)
+ goto skip;
+ }
+ else {
+ if (darray_size(m->rmlvo.layouts) == 1 ||
+ m->mapping.layout_idx >= darray_size(m->rmlvo.layouts))
+ goto skip;
+ }
+ }
+
+ if (m->mapping.defined_mlvo_mask & (1 << MLVO_VARIANT)) {
+ if (m->mapping.variant_idx == XKB_LAYOUT_INVALID) {
+ if (darray_size(m->rmlvo.variants) > 1)
+ goto skip;
+ }
+ else {
+ if (darray_size(m->rmlvo.variants) == 1 ||
+ m->mapping.variant_idx >= darray_size(m->rmlvo.variants))
+ goto skip;
+ }
+ }
+
+ return;
+
+skip:
+ m->mapping.skip = true;
+}
+
+static void
+matcher_rule_start_new(struct matcher *m)
+{
+ memset(&m->rule, 0, sizeof(m->rule));
+ m->rule.skip = m->mapping.skip;
+}
+
+static void
+matcher_rule_set_mlvo_common(struct matcher *m, struct sval ident,
+ enum mlvo_match_type match_type)
+{
+ if (m->rule.num_mlvo_values + 1 > m->mapping.num_mlvo) {
+ matcher_error1(m,
+ "invalid rule: has more values than the mapping line; "
+ "ignoring rule");
+ m->rule.skip = true;
+ return;
+ }
+ m->rule.match_type_at_pos[m->rule.num_mlvo_values] = match_type;
+ m->rule.mlvo_value_at_pos[m->rule.num_mlvo_values] = ident;
+ m->rule.num_mlvo_values++;
+}
+
+static void
+matcher_rule_set_mlvo_wildcard(struct matcher *m)
+{
+ struct sval dummy = { NULL, 0 };
+ matcher_rule_set_mlvo_common(m, dummy, MLVO_MATCH_WILDCARD);
+}
+
+static void
+matcher_rule_set_mlvo_group(struct matcher *m, struct sval ident)
+{
+ matcher_rule_set_mlvo_common(m, ident, MLVO_MATCH_GROUP);
+}
+
+static void
+matcher_rule_set_mlvo(struct matcher *m, struct sval ident)
+{
+ matcher_rule_set_mlvo_common(m, ident, MLVO_MATCH_NORMAL);
+}
+
+static void
+matcher_rule_set_kccgst(struct matcher *m, struct sval ident)
+{
+ if (m->rule.num_kccgst_values + 1 > m->mapping.num_kccgst) {
+ matcher_error1(m,
+ "invalid rule: has more values than the mapping line; "
+ "ignoring rule");
+ m->rule.skip = true;
+ return;
+ }
+ m->rule.kccgst_value_at_pos[m->rule.num_kccgst_values] = ident;
+ m->rule.num_kccgst_values++;
+}
+
+static bool
+match_group(struct matcher *m, struct sval group_name, struct sval to)
+{
+ struct group *group;
+ struct sval *element;
+ bool found = false;
+
+ darray_foreach(group, m->groups) {
+ if (svaleq(group->name, group_name)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ /*
+ * rules/evdev intentionally uses some undeclared group names
+ * in rules (e.g. commented group definitions which may be
+ * uncommented if needed). So we continue silently.
+ */
+ return false;
+ }
+
+ darray_foreach(element, group->elements)
+ if (svaleq(to, *element))
+ return true;
+
+ return false;
+}
+
+static bool
+match_value(struct matcher *m, struct sval val, struct sval to,
+ enum mlvo_match_type match_type)
+{
+ if (match_type == MLVO_MATCH_WILDCARD)
+ return true;
+ if (match_type == MLVO_MATCH_GROUP)
+ return match_group(m, val, to);
+ return svaleq(val, to);
+}
+
+/*
+ * This function performs %-expansion on @value (see overview above),
+ * and appends the result to @to.
+ */
+static bool
+append_expanded_kccgst_value(struct matcher *m, darray_char *to,
+ struct sval value)
+{
+ unsigned int i;
+ size_t original_size = darray_size(*to);
+ const char *s = value.start;
+ xkb_layout_index_t idx;
+ int consumed;
+ enum rules_mlvo mlv;
+ struct sval expanded;
+ char pfx, sfx;
+
+ /*
+ * Appending bar to foo -> foo (not an error if this happens)
+ * Appending +bar to foo -> foo+bar
+ * Appending bar to +foo -> bar+foo
+ * Appending +bar to +foo -> +foo+bar
+ */
+ if (!darray_empty(*to) && s[0] != '+' && s[0] != '|') {
+ if (darray_item(*to, 0) == '+' || darray_item(*to, 0) == '|')
+ darray_prepend_items_nullterminate(*to, value.start, value.len);
+ return true;
+ }
+
+ /*
+ * Some ugly hand-lexing here, but going through the scanner is more
+ * trouble than it's worth, and the format is ugly on its own merit.
+ */
+ for (i = 0; i < value.len; ) {
+ /* Check if that's a start of an expansion. */
+ if (s[i] != '%') {
+ /* Just a normal character. */
+ darray_append_items_nullterminate(*to, &s[i++], 1);
+ continue;
+ }
+ if (++i >= value.len) goto error;
+
+ pfx = sfx = 0;
+
+ /* Check for prefix. */
+ if (s[i] == '(' || s[i] == '+' || s[i] == '|' ||
+ s[i] == '_' || s[i] == '-') {
+ pfx = s[i];
+ if (s[i] == '(') sfx = ')';
+ if (++i >= value.len) goto error;
+ }
+
+ /* Mandatory model/layout/variant specifier. */
+ switch (s[i++]) {
+ case 'm': mlv = MLVO_MODEL; break;
+ case 'l': mlv = MLVO_LAYOUT; break;
+ case 'v': mlv = MLVO_VARIANT; break;
+ default: goto error;
+ }
+
+ /* Check for index. */
+ idx = XKB_LAYOUT_INVALID;
+ if (i < value.len) {
+ if (s[i] == '[') {
+ if (mlv != MLVO_LAYOUT && mlv != MLVO_VARIANT) {
+ matcher_error1(m,
+ "invalid index in %%-expansion; "
+ "may only index layout or variant");
+ goto error;
+ }
+
+ consumed = extract_layout_index(s + i, value.len - i, &idx);
+ if (consumed == -1) goto error;
+ i += consumed;
+ }
+ else {
+ idx = XKB_LAYOUT_INVALID;
+ }
+ }
+
+ /* Check for suffix, if there supposed to be one. */
+ if (sfx != 0) {
+ if (i >= value.len) goto error;
+ if (s[i++] != sfx) goto error;
+ }
+
+ /* Get the expanded value. */
+ expanded.len = 0;
+
+ if (mlv == MLVO_LAYOUT) {
+ if (idx != XKB_LAYOUT_INVALID &&
+ idx < darray_size(m->rmlvo.layouts) &&
+ darray_size(m->rmlvo.layouts) > 1)
+ expanded = darray_item(m->rmlvo.layouts, idx);
+ else if (idx == XKB_LAYOUT_INVALID &&
+ darray_size(m->rmlvo.layouts) == 1)
+ expanded = darray_item(m->rmlvo.layouts, 0);
+ }
+ else if (mlv == MLVO_VARIANT) {
+ if (idx != XKB_LAYOUT_INVALID &&
+ idx < darray_size(m->rmlvo.variants) &&
+ darray_size(m->rmlvo.variants) > 1)
+ expanded = darray_item(m->rmlvo.variants, idx);
+ else if (idx == XKB_LAYOUT_INVALID &&
+ darray_size(m->rmlvo.variants) == 1)
+ expanded = darray_item(m->rmlvo.variants, 0);
+ }
+ else if (mlv == MLVO_MODEL) {
+ expanded = m->rmlvo.model;
+ }
+
+ /* If we didn't get one, skip silently. */
+ if (expanded.len <= 0)
+ continue;
+
+ if (pfx != 0)
+ darray_append_items_nullterminate(*to, &pfx, 1);
+ darray_append_items_nullterminate(*to, expanded.start, expanded.len);
+ if (sfx != 0)
+ darray_append_items_nullterminate(*to, &sfx, 1);
+ }
+
+ return true;
+
+error:
+ matcher_error1(m, "invalid %%-expansion in value; not used");
+ darray_resize(*to, original_size);
+ return false;
+}
+
+static void
+matcher_rule_verify(struct matcher *m)
+{
+ if (m->rule.num_mlvo_values != m->mapping.num_mlvo ||
+ m->rule.num_kccgst_values != m->mapping.num_kccgst) {
+ matcher_error1(m,
+ "invalid rule: must have same number of values as mapping line;"
+ "ignoring rule");
+ m->rule.skip = true;
+ }
+}
+
+static void
+matcher_rule_apply_if_matches(struct matcher *m)
+{
+ unsigned int i;
+ enum rules_mlvo mlvo;
+ enum rules_kccgst kccgst;
+ struct sval value, *option;
+ enum mlvo_match_type match_type;
+ bool matched = false;
+ xkb_layout_index_t idx;
+
+ for (i = 0; i < m->mapping.num_mlvo; i++) {
+ mlvo = m->mapping.mlvo_at_pos[i];
+ value = m->rule.mlvo_value_at_pos[i];
+ match_type = m->rule.match_type_at_pos[i];
+
+ if (mlvo == MLVO_MODEL) {
+ matched = match_value(m, value, m->rmlvo.model, match_type);
+ }
+ else if (mlvo == MLVO_LAYOUT) {
+ idx = m->mapping.layout_idx;
+ idx = (idx == XKB_LAYOUT_INVALID ? 0 : idx);
+ matched = match_value(m, value,
+ darray_item(m->rmlvo.layouts, idx),
+ match_type);
+ }
+ else if (mlvo == MLVO_VARIANT) {
+ idx = m->mapping.layout_idx;
+ idx = (idx == XKB_LAYOUT_INVALID ? 0 : idx);
+ matched = match_value(m, value,
+ darray_item(m->rmlvo.variants, idx),
+ match_type);
+ }
+ else if (mlvo == MLVO_OPTION) {
+ darray_foreach(option, m->rmlvo.options) {
+ matched = match_value(m, value, *option, match_type);
+ if (matched)
+ break;
+ }
+ }
+
+ if (!matched)
+ return;
+ }
+
+ for (i = 0; i < m->mapping.num_kccgst; i++) {
+ kccgst = m->mapping.kccgst_at_pos[i];
+ value = m->rule.kccgst_value_at_pos[i];
+ append_expanded_kccgst_value(m, &m->kccgst[kccgst], value);
+ }
+
+ /*
+ * If a rule matches in a rule set, the rest of the set should be
+ * skipped. However, rule sets matching against options may contain
+ * several legitimate rules, so they are processed entirely.
+ */
+ if (!(m->mapping.defined_mlvo_mask & (1 << MLVO_OPTION)))
+ m->mapping.skip = true;
+}
+
+static enum rules_token
+gettok(struct matcher *m)
+{
+ return lex(&m->scanner, &m->val, &m->loc);
+}
+
+static bool
+matcher_match(struct matcher *m, const char *string, size_t len,
+ const char *file_name, struct xkb_component_names *out)
+{
+ enum rules_token tok;
+
+ if (!m)
+ return false;
+
+ scanner_init(&m->scanner, m->ctx, string, len, file_name);
+
+initial:
+ switch (tok = gettok(m)) {
+ case TOK_BANG:
+ goto bang;
+ case TOK_END_OF_LINE:
+ goto initial;
+ case TOK_END_OF_FILE:
+ goto finish;
+ default:
+ goto unexpected;
+ }
+
+bang:
+ switch (tok = gettok(m)) {
+ case TOK_GROUP_NAME:
+ matcher_group_start_new(m, m->val.string);
+ goto group_name;
+ case TOK_IDENTIFIER:
+ matcher_mapping_start_new(m);
+ matcher_mapping_set_mlvo(m, m->val.string);
+ goto mapping_mlvo;
+ default:
+ goto unexpected;
+ }
+
+group_name:
+ switch (tok = gettok(m)) {
+ case TOK_EQUALS:
+ goto group_element;
+ default:
+ goto unexpected;
+ }
+
+group_element:
+ switch (tok = gettok(m)) {
+ case TOK_IDENTIFIER:
+ matcher_group_add_element(m, m->val.string);
+ goto group_element;
+ case TOK_END_OF_LINE:
+ goto initial;
+ default:
+ goto unexpected;
+ }
+
+mapping_mlvo:
+ switch (tok = gettok(m)) {
+ case TOK_IDENTIFIER:
+ if (!m->mapping.skip)
+ matcher_mapping_set_mlvo(m, m->val.string);
+ goto mapping_mlvo;
+ case TOK_EQUALS:
+ goto mapping_kccgst;
+ default:
+ goto unexpected;
+ }
+
+mapping_kccgst:
+ switch (tok = gettok(m)) {
+ case TOK_IDENTIFIER:
+ if (!m->mapping.skip)
+ matcher_mapping_set_kccgst(m, m->val.string);
+ goto mapping_kccgst;
+ case TOK_END_OF_LINE:
+ if (!m->mapping.skip)
+ matcher_mapping_verify(m);
+ goto rule_mlvo_first;
+ default:
+ goto unexpected;
+ }
+
+rule_mlvo_first:
+ switch (tok = gettok(m)) {
+ case TOK_BANG:
+ goto bang;
+ case TOK_END_OF_LINE:
+ goto rule_mlvo_first;
+ case TOK_END_OF_FILE:
+ goto finish;
+ default:
+ matcher_rule_start_new(m);
+ goto rule_mlvo_no_tok;
+ }
+
+rule_mlvo:
+ tok = gettok(m);
+rule_mlvo_no_tok:
+ switch (tok) {
+ case TOK_IDENTIFIER:
+ if (!m->rule.skip)
+ matcher_rule_set_mlvo(m, m->val.string);
+ goto rule_mlvo;
+ case TOK_STAR:
+ if (!m->rule.skip)
+ matcher_rule_set_mlvo_wildcard(m);
+ goto rule_mlvo;
+ case TOK_GROUP_NAME:
+ if (!m->rule.skip)
+ matcher_rule_set_mlvo_group(m, m->val.string);
+ goto rule_mlvo;
+ case TOK_EQUALS:
+ goto rule_kccgst;
+ default:
+ goto unexpected;
+ }
+
+rule_kccgst:
+ switch (tok = gettok(m)) {
+ case TOK_IDENTIFIER:
+ if (!m->rule.skip)
+ matcher_rule_set_kccgst(m, m->val.string);
+ goto rule_kccgst;
+ case TOK_END_OF_LINE:
+ if (!m->rule.skip)
+ matcher_rule_verify(m);
+ if (!m->rule.skip)
+ matcher_rule_apply_if_matches(m);
+ goto rule_mlvo_first;
+ default:
+ goto unexpected;
+ }
+
+unexpected:
+ switch (tok) {
+ case TOK_ERROR:
+ goto error;
+ default:
+ goto state_error;
+ }
+
+finish:
+ if (darray_empty(m->kccgst[KCCGST_KEYCODES]) ||
+ darray_empty(m->kccgst[KCCGST_TYPES]) ||
+ darray_empty(m->kccgst[KCCGST_COMPAT]) ||
+ /* darray_empty(m->kccgst[KCCGST_GEOMETRY]) || */
+ darray_empty(m->kccgst[KCCGST_SYMBOLS]))
+ goto error;
+
+ out->keycodes = darray_mem(m->kccgst[KCCGST_KEYCODES], 0);
+ out->types = darray_mem(m->kccgst[KCCGST_TYPES], 0);
+ out->compat = darray_mem(m->kccgst[KCCGST_COMPAT], 0);
+ /* out->geometry = darray_mem(m->kccgst[KCCGST_GEOMETRY], 0); */
+ darray_free(m->kccgst[KCCGST_GEOMETRY]);
+ out->symbols = darray_mem(m->kccgst[KCCGST_SYMBOLS], 0);
+
+ return true;
+
+state_error:
+ matcher_error1(m, "unexpected token");
+error:
+ return false;
+}
+
+bool
+xkb_components_from_rules(struct xkb_context *ctx,
+ const struct xkb_rule_names *rmlvo,
+ struct xkb_component_names *out)
+{
+ bool ret = false;
+ FILE *file;
+ char *path;
+ int fd;
+ struct stat stat_buf;
+ char *string;
+ struct matcher *matcher;
+
+ file = FindFileInXkbPath(ctx, rmlvo->rules, FILE_TYPE_RULES, &path);
+ if (!file)
+ goto err_out;
+
+ fd = fileno(file);
+
+ if (fstat(fd, &stat_buf) != 0) {
+ log_err(ctx, "Couldn't stat rules file\n");
+ goto err_file;
+ }
+
+ string = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (string == MAP_FAILED) {
+ log_err(ctx, "Couldn't mmap rules file (%lld bytes)\n",
+ (long long) stat_buf.st_size);
+ goto err_file;
+ }
+
+ matcher = matcher_new(ctx, rmlvo);
+ ret = matcher_match(matcher, string, stat_buf.st_size, rmlvo->rules, out);
+ if (!ret)
+ log_err(ctx, "No components returned from XKB rules \"%s\"\n", path);
+ matcher_free(matcher);
+
+ munmap(string, stat_buf.st_size);
+err_file:
+ free(path);
+ fclose(file);
+err_out:
+ return ret;
+}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/rules.h b/src/3rdparty/xkbcommon/src/xkbcomp/rules.h
new file mode 100644
index 0000000000..5381b1562f
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/rules.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright © 2009 Dan Nicholson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef XKBCOMP_RULES_H
+#define XKBCOMP_RULES_H
+
+bool
+xkb_components_from_rules(struct xkb_context *ctx,
+ const struct xkb_rule_names *rmlvo,
+ struct xkb_component_names *out);
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c b/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c
new file mode 100644
index 0000000000..4731107b85
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c
@@ -0,0 +1,2861 @@
+#line 2 "src/xkbcomp/scanner.c"
+
+#line 4 "src/xkbcomp/scanner.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE _xkbcommon_restart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+ * access to the local variable yy_act. Since yyless() is a macro, it would break
+ * existing scanners that call yyless() from OUTSIDE _xkbcommon_lex.
+ * One obvious solution it to make yy_act a global. I tried that, and saw
+ * a 5% performance hit in a non-yylineno scanner, because yy_act is
+ * normally declared as a register variable-- so it is not worth it.
+ */
+ #define YY_LESS_LINENO(n) \
+ do { \
+ int yyl;\
+ for ( yyl = n; yyl < yyleng; ++yyl )\
+ if ( yytext[yyl] == '\n' )\
+ --yylineno;\
+ }while(0)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = yyg->yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via _xkbcommon_restart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
+ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void _xkbcommon_restart (FILE *input_file ,yyscan_t yyscanner );
+void _xkbcommon__switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE _xkbcommon__create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void _xkbcommon__delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void _xkbcommon__flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void _xkbcommon_push_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void _xkbcommon_pop_buffer_state (yyscan_t yyscanner );
+
+static void _xkbcommon_ensure_buffer_stack (yyscan_t yyscanner );
+static void _xkbcommon__load_buffer_state (yyscan_t yyscanner );
+static void _xkbcommon__init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER _xkbcommon__flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE _xkbcommon__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE _xkbcommon__scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE _xkbcommon__scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *_xkbcommon_alloc (yy_size_t ,yyscan_t yyscanner );
+void *_xkbcommon_realloc (void *,yy_size_t ,yyscan_t yyscanner );
+void _xkbcommon_free (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer _xkbcommon__create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ _xkbcommon_ensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ _xkbcommon__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ _xkbcommon_ensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ _xkbcommon__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define _xkbcommon_wrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
+static int yy_get_next_buffer (yyscan_t yyscanner );
+static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yyg->yytext_ptr = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ yyg->yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yyg->yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 83
+#define YY_END_OF_BUFFER 84
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[336] =
+ { 0,
+ 0, 0, 0, 0, 84, 82, 81, 81, 79, 3,
+ 2, 72, 73, 69, 66, 77, 67, 76, 68, 63,
+ 63, 78, 82, 65, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 74, 75, 70, 71, 80, 14, 83, 4, 14,
+ 81, 2, 1, 0, 63, 0, 0, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 5, 6, 10, 13, 11, 7, 9, 8, 12,
+ 1, 64, 62, 15, 61, 61, 61, 61, 61, 61,
+
+ 61, 61, 61, 61, 61, 61, 39, 61, 61, 61,
+ 61, 61, 61, 47, 61, 61, 61, 61, 61, 61,
+ 61, 5, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 48, 54, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 51, 36, 61,
+ 61, 5, 61, 40, 61, 61, 61, 61, 61, 41,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 46, 53, 61, 61, 61, 61,
+ 61, 61, 61, 38, 61, 61, 61, 61, 61, 34,
+ 61, 61, 61, 61, 61, 42, 61, 61, 61, 61,
+
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 29, 33, 61, 27, 61, 61, 61,
+ 61, 43, 52, 50, 61, 32, 30, 49, 55, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 28, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 31, 61, 45, 37, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 18, 61,
+ 61, 61, 61, 61, 61, 61, 20, 61, 61, 16,
+ 26, 61, 61, 61, 61, 61, 58, 61, 61, 61,
+ 61, 61, 61, 61, 61, 19, 61, 61, 61, 61,
+
+ 44, 61, 61, 61, 24, 17, 61, 61, 61, 59,
+ 57, 61, 61, 61, 25, 61, 61, 61, 61, 21,
+ 61, 60, 61, 61, 61, 61, 61, 56, 35, 22,
+ 61, 61, 61, 23, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 2, 1, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 5, 6, 1, 1, 1, 1, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 16,
+ 16, 16, 16, 16, 16, 17, 17, 1, 18, 19,
+ 20, 21, 1, 1, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 31, 38, 39, 40, 41, 42, 43, 44, 45, 31,
+ 46, 47, 48, 1, 49, 1, 50, 51, 52, 53,
+
+ 54, 55, 56, 57, 58, 31, 59, 60, 61, 62,
+ 63, 64, 31, 65, 66, 67, 68, 69, 70, 71,
+ 72, 31, 73, 1, 74, 75, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[76] =
+ { 0,
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 3,
+ 1, 3, 1, 1, 4, 4, 4, 1, 1, 1,
+ 1, 4, 4, 4, 4, 4, 4, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 1, 1, 1, 5, 4,
+ 4, 4, 4, 4, 4, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 1, 1, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[342] =
+ { 0,
+ 0, 0, 73, 74, 263, 695, 78, 80, 695, 695,
+ 0, 695, 695, 695, 695, 695, 695, 695, 203, 71,
+ 76, 695, 0, 695, 66, 0, 59, 54, 58, 67,
+ 65, 75, 67, 68, 64, 86, 83, 109, 98, 81,
+ 82, 695, 695, 695, 695, 695, 695, 695, 695, 158,
+ 114, 0, 0, 132, 138, 0, 158, 0, 100, 128,
+ 100, 123, 109, 124, 136, 166, 131, 141, 152, 140,
+ 156, 150, 157, 156, 159, 179, 171, 164, 177, 178,
+ 179, 221, 229, 695, 695, 695, 695, 695, 695, 695,
+ 0, 232, 0, 695, 192, 202, 199, 206, 200, 217,
+
+ 216, 201, 226, 220, 224, 229, 220, 222, 232, 231,
+ 227, 230, 238, 0, 232, 236, 244, 236, 251, 247,
+ 115, 279, 252, 250, 256, 263, 278, 266, 268, 272,
+ 284, 271, 289, 279, 296, 0, 0, 292, 298, 288,
+ 293, 292, 296, 305, 301, 307, 312, 0, 0, 288,
+ 342, 347, 305, 0, 307, 310, 315, 320, 313, 0,
+ 323, 335, 346, 336, 351, 348, 346, 357, 349, 364,
+ 357, 367, 366, 356, 0, 0, 371, 359, 371, 373,
+ 381, 379, 367, 0, 372, 394, 380, 383, 390, 0,
+ 402, 390, 394, 113, 408, 0, 399, 411, 396, 413,
+
+ 409, 417, 410, 413, 414, 413, 407, 409, 421, 424,
+ 423, 427, 424, 0, 0, 432, 0, 434, 448, 445,
+ 440, 0, 0, 0, 454, 0, 0, 0, 110, 446,
+ 450, 462, 453, 468, 469, 467, 472, 473, 108, 457,
+ 461, 477, 63, 0, 472, 485, 483, 476, 491, 474,
+ 482, 483, 485, 487, 61, 497, 0, 0, 485, 500,
+ 500, 498, 500, 518, 508, 507, 508, 516, 0, 520,
+ 525, 528, 519, 529, 538, 537, 538, 526, 540, 0,
+ 0, 539, 534, 546, 539, 534, 0, 535, 547, 556,
+ 566, 558, 548, 556, 575, 0, 53, 565, 563, 564,
+
+ 0, 578, 578, 587, 0, 0, 573, 581, 574, 0,
+ 0, 580, 583, 581, 0, 595, 586, 598, 595, 0,
+ 586, 0, 594, 594, 596, 602, 599, 0, 0, 49,
+ 612, 604, 610, 0, 695, 674, 679, 682, 684, 689,
+ 90
+ } ;
+
+static yyconst flex_int16_t yy_def[342] =
+ { 0,
+ 335, 1, 336, 336, 335, 335, 335, 335, 335, 335,
+ 337, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 338, 335, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 337, 340, 335, 335, 341, 338, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 340, 335, 341, 335, 339, 339, 339, 339, 339, 339,
+
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 335, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 335, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 0, 335, 335, 335, 335, 335,
+ 335
+ } ;
+
+static yyconst flex_int16_t yy_nxt[771] =
+ { 0,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 21, 22, 23, 24,
+ 6, 25, 26, 26, 27, 26, 28, 29, 30, 31,
+ 26, 32, 33, 34, 26, 35, 36, 37, 38, 39,
+ 26, 40, 26, 41, 26, 42, 6, 43, 26, 25,
+ 26, 26, 27, 26, 28, 29, 30, 31, 32, 33,
+ 34, 26, 35, 36, 37, 38, 39, 26, 40, 26,
+ 41, 26, 44, 45, 46, 48, 48, 49, 49, 51,
+ 51, 51, 51, 54, 62, 55, 55, 55, 54, 59,
+ 55, 55, 55, 93, 63, 64, 65, 331, 60, 66,
+
+ 67, 308, 68, 69, 70, 71, 61, 72, 73, 271,
+ 80, 260, 62, 81, 56, 51, 51, 59, 74, 50,
+ 50, 63, 64, 78, 65, 60, 66, 99, 67, 68,
+ 69, 70, 71, 61, 75, 72, 73, 76, 80, 95,
+ 81, 56, 79, 101, 77, 74, 92, 92, 92, 100,
+ 54, 78, 55, 55, 55, 99, 256, 96, 245, 102,
+ 103, 220, 75, 151, 97, 76, 95, 98, 108, 79,
+ 101, 77, 82, 82, 83, 107, 109, 100, 94, 110,
+ 84, 111, 115, 85, 86, 96, 102, 112, 103, 104,
+ 105, 97, 87, 113, 98, 88, 108, 89, 114, 90,
+
+ 116, 121, 107, 117, 109, 106, 110, 118, 84, 111,
+ 115, 85, 86, 119, 112, 120, 53, 104, 105, 87,
+ 113, 123, 88, 124, 89, 114, 90, 125, 116, 121,
+ 117, 126, 106, 127, 118, 122, 122, 83, 128, 129,
+ 119, 130, 120, 83, 83, 83, 92, 92, 92, 123,
+ 131, 124, 132, 133, 134, 125, 135, 137, 136, 126,
+ 127, 138, 335, 141, 142, 139, 128, 129, 130, 143,
+ 144, 145, 146, 147, 335, 148, 149, 155, 131, 132,
+ 140, 133, 134, 135, 137, 136, 150, 153, 154, 138,
+ 141, 142, 139, 152, 152, 83, 143, 144, 145, 146,
+
+ 156, 147, 148, 157, 149, 155, 158, 159, 160, 161,
+ 335, 162, 163, 150, 153, 154, 164, 165, 166, 167,
+ 335, 168, 169, 335, 170, 172, 173, 156, 177, 171,
+ 174, 157, 175, 158, 159, 160, 176, 161, 162, 184,
+ 163, 185, 189, 164, 186, 165, 166, 167, 168, 187,
+ 169, 170, 188, 172, 173, 177, 171, 190, 174, 191,
+ 175, 83, 83, 83, 176, 178, 184, 192, 185, 179,
+ 189, 186, 193, 180, 181, 194, 187, 195, 197, 188,
+ 182, 183, 196, 198, 190, 199, 200, 191, 201, 202,
+ 335, 203, 204, 178, 205, 192, 206, 179, 207, 193,
+
+ 180, 181, 208, 194, 209, 195, 197, 182, 183, 196,
+ 198, 211, 212, 199, 200, 213, 201, 202, 203, 214,
+ 204, 205, 215, 210, 206, 216, 207, 217, 335, 218,
+ 208, 219, 209, 221, 335, 222, 223, 225, 211, 212,
+ 224, 226, 227, 213, 228, 229, 214, 230, 231, 215,
+ 210, 232, 216, 233, 234, 217, 218, 235, 219, 236,
+ 237, 221, 222, 238, 223, 225, 239, 224, 226, 240,
+ 227, 228, 229, 241, 230, 231, 242, 243, 232, 244,
+ 233, 234, 246, 247, 235, 248, 236, 237, 250, 251,
+ 238, 252, 253, 239, 257, 249, 240, 254, 255, 335,
+
+ 258, 241, 259, 242, 243, 261, 262, 244, 263, 246,
+ 247, 264, 265, 248, 266, 250, 267, 251, 268, 252,
+ 253, 257, 249, 269, 270, 254, 255, 258, 272, 273,
+ 259, 274, 261, 275, 262, 276, 263, 277, 264, 278,
+ 265, 266, 279, 267, 280, 268, 281, 282, 283, 284,
+ 269, 270, 285, 286, 288, 272, 273, 287, 274, 289,
+ 275, 290, 276, 293, 277, 294, 278, 291, 295, 297,
+ 279, 280, 296, 281, 282, 283, 298, 284, 299, 300,
+ 285, 286, 288, 301, 287, 302, 292, 289, 303, 290,
+ 293, 304, 305, 294, 306, 291, 295, 297, 307, 296,
+
+ 309, 310, 311, 298, 312, 299, 300, 313, 314, 318,
+ 301, 315, 316, 302, 317, 319, 303, 320, 304, 305,
+ 321, 306, 322, 323, 324, 333, 307, 309, 310, 311,
+ 325, 326, 312, 327, 328, 313, 314, 318, 315, 316,
+ 329, 317, 319, 330, 320, 332, 334, 335, 321, 322,
+ 335, 323, 324, 333, 335, 335, 335, 325, 326, 335,
+ 327, 328, 335, 335, 335, 335, 335, 329, 335, 335,
+ 330, 335, 332, 334, 47, 47, 47, 47, 47, 52,
+ 335, 52, 52, 52, 57, 57, 57, 58, 58, 91,
+ 335, 91, 91, 91, 5, 335, 335, 335, 335, 335,
+
+ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335
+ } ;
+
+static yyconst flex_int16_t yy_chk[771] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 3, 4, 3, 4, 7,
+ 7, 8, 8, 20, 27, 20, 20, 20, 21, 25,
+ 21, 21, 21, 341, 28, 29, 30, 330, 25, 31,
+
+ 32, 297, 33, 34, 35, 35, 25, 36, 37, 255,
+ 40, 243, 27, 41, 20, 51, 51, 25, 37, 3,
+ 4, 28, 29, 39, 30, 25, 31, 61, 32, 33,
+ 34, 35, 35, 25, 38, 36, 37, 38, 40, 59,
+ 41, 20, 39, 63, 38, 37, 54, 54, 54, 62,
+ 55, 39, 55, 55, 55, 61, 239, 60, 229, 64,
+ 65, 194, 38, 121, 60, 38, 59, 60, 68, 39,
+ 63, 38, 50, 50, 50, 67, 69, 62, 57, 70,
+ 50, 71, 75, 50, 50, 60, 64, 72, 65, 66,
+ 66, 60, 50, 73, 60, 50, 68, 50, 74, 50,
+
+ 76, 81, 67, 77, 69, 66, 70, 78, 50, 71,
+ 75, 50, 50, 79, 72, 80, 19, 66, 66, 50,
+ 73, 95, 50, 96, 50, 74, 50, 97, 76, 81,
+ 77, 98, 66, 99, 78, 82, 82, 82, 100, 101,
+ 79, 102, 80, 83, 83, 83, 92, 92, 92, 95,
+ 103, 96, 104, 105, 106, 97, 107, 108, 107, 98,
+ 99, 109, 5, 110, 111, 109, 100, 101, 102, 112,
+ 113, 115, 116, 117, 0, 118, 119, 125, 103, 104,
+ 109, 105, 106, 107, 108, 107, 120, 123, 124, 109,
+ 110, 111, 109, 122, 122, 122, 112, 113, 115, 116,
+
+ 126, 117, 118, 127, 119, 125, 128, 129, 130, 131,
+ 0, 132, 133, 120, 123, 124, 134, 135, 138, 139,
+ 0, 140, 141, 0, 142, 143, 144, 126, 150, 142,
+ 145, 127, 146, 128, 129, 130, 147, 131, 132, 153,
+ 133, 155, 159, 134, 156, 135, 138, 139, 140, 157,
+ 141, 142, 158, 143, 144, 150, 142, 161, 145, 162,
+ 146, 152, 152, 152, 147, 151, 153, 163, 155, 151,
+ 159, 156, 164, 151, 151, 165, 157, 166, 168, 158,
+ 151, 151, 167, 169, 161, 170, 171, 162, 172, 173,
+ 0, 174, 177, 151, 178, 163, 179, 151, 180, 164,
+
+ 151, 151, 181, 165, 182, 166, 168, 151, 151, 167,
+ 169, 183, 185, 170, 171, 186, 172, 173, 174, 187,
+ 177, 178, 188, 182, 179, 189, 180, 191, 0, 192,
+ 181, 193, 182, 195, 0, 197, 198, 200, 183, 185,
+ 199, 201, 202, 186, 203, 204, 187, 205, 206, 188,
+ 182, 207, 189, 208, 209, 191, 192, 210, 193, 211,
+ 212, 195, 197, 213, 198, 200, 216, 199, 201, 218,
+ 202, 203, 204, 219, 205, 206, 220, 221, 207, 225,
+ 208, 209, 230, 231, 210, 232, 211, 212, 233, 234,
+ 213, 235, 236, 216, 240, 232, 218, 237, 238, 0,
+
+ 241, 219, 242, 220, 221, 245, 246, 225, 247, 230,
+ 231, 248, 249, 232, 250, 233, 251, 234, 252, 235,
+ 236, 240, 232, 253, 254, 237, 238, 241, 256, 259,
+ 242, 260, 245, 260, 246, 261, 247, 262, 248, 263,
+ 249, 250, 264, 251, 265, 252, 266, 267, 268, 270,
+ 253, 254, 271, 272, 274, 256, 259, 273, 260, 275,
+ 260, 276, 261, 278, 262, 279, 263, 277, 282, 284,
+ 264, 265, 283, 266, 267, 268, 285, 270, 286, 288,
+ 271, 272, 274, 289, 273, 290, 277, 275, 291, 276,
+ 278, 292, 293, 279, 294, 277, 282, 284, 295, 283,
+
+ 298, 299, 300, 285, 302, 286, 288, 303, 304, 312,
+ 289, 307, 308, 290, 309, 313, 291, 314, 292, 293,
+ 316, 294, 317, 318, 319, 332, 295, 298, 299, 300,
+ 321, 323, 302, 324, 325, 303, 304, 312, 307, 308,
+ 326, 309, 313, 327, 314, 331, 333, 0, 316, 317,
+ 0, 318, 319, 332, 0, 0, 0, 321, 323, 0,
+ 324, 325, 0, 0, 0, 0, 0, 326, 0, 0,
+ 327, 0, 331, 333, 336, 336, 336, 336, 336, 337,
+ 0, 337, 337, 337, 338, 338, 338, 339, 339, 340,
+ 0, 340, 340, 340, 335, 335, 335, 335, 335, 335,
+
+ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335
+ } ;
+
+/* Table of booleans, true if rule could match eol. */
+static yyconst flex_int32_t yy_rule_can_match_eol[84] =
+ { 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, };
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+#line 1 "scanner.l"
+/************************************************************
+ Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+
+ Permission to use, copy, modify, and distribute this
+ software and its documentation for any purpose and without
+ fee is hereby granted, provided that the above copyright
+ notice appear in all copies and that both that copyright
+ notice and this permission notice appear in supporting
+ documentation, and that the name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ********************************************************/
+#line 28 "scanner.l"
+#include "xkbcomp-priv.h"
+#include "parser-priv.h"
+
+#pragma GCC diagnostic ignored "-Wmissing-noreturn"
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#pragma GCC diagnostic push
+
+struct scanner_extra {
+ struct xkb_context *ctx;
+ const char *file_name;
+ char scanBuf[1024];
+ char *s;
+};
+
+static void
+scanner_error_extra(struct YYLTYPE *loc, struct scanner_extra *extra,
+ const char *msg);
+
+#define YY_USER_ACTION { \
+ yylloc->first_line = yylineno; \
+ yylloc->last_line = yylineno; \
+}
+
+#define APPEND_S(ch) do { \
+ if (yyextra->s - yyextra->scanBuf >= sizeof(yyextra->scanBuf) - 1) \
+ return ERROR_TOK; \
+ *yyextra->s++ = ch; \
+} while (0)
+#define YY_NO_UNISTD_H 1
+#define YY_NO_INPUT 1
+
+#line 803 "src/xkbcomp/scanner.c"
+
+#define INITIAL 0
+#define S_STR 1
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#define YY_EXTRA_TYPE struct scanner_extra *
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+ {
+
+ /* User-defined. Not touched by flex. */
+ YY_EXTRA_TYPE yyextra_r;
+
+ /* The rest are the same as the globals declared in the non-reentrant scanner. */
+ FILE *yyin_r, *yyout_r;
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+ int yy_n_chars;
+ int yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+ int yy_start;
+ int yy_did_buffer_switch_on_eof;
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int *yy_start_stack;
+ yy_state_type yy_last_accepting_state;
+ char* yy_last_accepting_cpos;
+
+ int yylineno_r;
+ int yy_flex_debug_r;
+
+ char *yytext_r;
+ int yy_more_flag;
+ int yy_more_len;
+
+ YYSTYPE * yylval_r;
+
+ YYLTYPE * yylloc_r;
+
+ }; /* end struct yyguts_t */
+
+static int yy_init_globals (yyscan_t yyscanner );
+
+ /* This must go here because YYSTYPE and YYLTYPE are included
+ * from bison output in section 1.*/
+ # define yylval yyg->yylval_r
+
+ # define yylloc yyg->yylloc_r
+
+int _xkbcommon_lex_init (yyscan_t* scanner);
+
+int _xkbcommon_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int _xkbcommon_lex_destroy (yyscan_t yyscanner );
+
+int _xkbcommon_get_debug (yyscan_t yyscanner );
+
+void _xkbcommon_set_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE _xkbcommon_get_extra (yyscan_t yyscanner );
+
+void _xkbcommon_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *_xkbcommon_get_in (yyscan_t yyscanner );
+
+void _xkbcommon_set_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *_xkbcommon_get_out (yyscan_t yyscanner );
+
+void _xkbcommon_set_out (FILE * out_str ,yyscan_t yyscanner );
+
+int _xkbcommon_get_leng (yyscan_t yyscanner );
+
+char *_xkbcommon_get_text (yyscan_t yyscanner );
+
+int _xkbcommon_get_lineno (yyscan_t yyscanner );
+
+void _xkbcommon_set_lineno (int line_number ,yyscan_t yyscanner );
+
+YYSTYPE * _xkbcommon_get_lval (yyscan_t yyscanner );
+
+void _xkbcommon_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+
+ YYLTYPE *_xkbcommon_get_lloc (yyscan_t yyscanner );
+
+ void _xkbcommon_set_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int _xkbcommon_wrap (yyscan_t yyscanner );
+#else
+extern int _xkbcommon_wrap (yyscan_t yyscanner );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (yyscan_t yyscanner );
+#else
+static int input (yyscan_t yyscanner );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int _xkbcommon_lex \
+ (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
+
+#define YY_DECL int _xkbcommon_lex \
+ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+#line 69 "scanner.l"
+
+
+#line 1049 "src/xkbcomp/scanner.c"
+
+ yylval = yylval_param;
+
+ yylloc = yylloc_param;
+
+ if ( !yyg->yy_init )
+ {
+ yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yyg->yy_start )
+ yyg->yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ _xkbcommon_ensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ _xkbcommon__create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ _xkbcommon__load_buffer_state(yyscanner );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yyg->yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yyg->yy_start;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 336 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_current_state != 335 );
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+ if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
+ {
+ int yyl;
+ for ( yyl = 0; yyl < yyleng; ++yyl )
+ if ( yytext[yyl] == '\n' )
+
+ do{ yylineno++;
+ yycolumn=0;
+ }while(0)
+;
+ }
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yyg->yy_hold_char;
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 71 "scanner.l"
+
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 72 "scanner.l"
+
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 74 "scanner.l"
+yyextra->s = yyextra->scanBuf; BEGIN(S_STR);
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 76 "scanner.l"
+{
+ BEGIN(INITIAL);
+ *yyextra->s = '\0';
+ yylval->str = strdup(yyextra->scanBuf);
+ return STRING;
+ }
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 83 "scanner.l"
+{
+ /* octal escape sequence */
+ unsigned int result;
+
+ (void) sscanf( yytext + 1, "%o", &result );
+
+ if (result > 0xff) {
+ scanner_error_extra(yylloc, yyextra,
+ "Illegal octal escape");
+ return ERROR_TOK;
+ }
+
+ APPEND_S(result);
+ }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 98 "scanner.l"
+{
+ scanner_error_extra(yylloc, yyextra,
+ "Illegal octal escape");
+ return ERROR_TOK;
+ }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 104 "scanner.l"
+APPEND_S('\n');
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 105 "scanner.l"
+APPEND_S('\t');
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 106 "scanner.l"
+APPEND_S('\r');
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 107 "scanner.l"
+APPEND_S('\b');
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 108 "scanner.l"
+APPEND_S('\f');
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 109 "scanner.l"
+APPEND_S('\v');
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 110 "scanner.l"
+APPEND_S('\033');
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 112 "scanner.l"
+APPEND_S(yytext[0]);
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 114 "scanner.l"
+{
+ /* We don't want the brackets. */
+ yytext[yyleng - 1] = '\0';
+ yytext++;
+ yylval->sval = xkb_atom_intern(yyextra->ctx, yytext);
+ return KEYNAME;
+ }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 122 "scanner.l"
+return XKB_KEYMAP;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 123 "scanner.l"
+return XKB_KEYCODES;
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 124 "scanner.l"
+return XKB_TYPES;
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 125 "scanner.l"
+return XKB_SYMBOLS;
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 126 "scanner.l"
+return XKB_COMPATMAP;
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 127 "scanner.l"
+return XKB_COMPATMAP;
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 128 "scanner.l"
+return XKB_COMPATMAP;
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 129 "scanner.l"
+return XKB_COMPATMAP;
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 130 "scanner.l"
+return XKB_GEOMETRY;
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 131 "scanner.l"
+return XKB_SEMANTICS;
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 132 "scanner.l"
+return XKB_LAYOUT;
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 133 "scanner.l"
+return INCLUDE;
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 134 "scanner.l"
+return OVERRIDE;
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 135 "scanner.l"
+return AUGMENT;
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 136 "scanner.l"
+return REPLACE;
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 137 "scanner.l"
+return ALTERNATE;
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 138 "scanner.l"
+return PARTIAL;
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 139 "scanner.l"
+return DEFAULT;
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 140 "scanner.l"
+return HIDDEN;
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 141 "scanner.l"
+return VIRTUAL_MODS;
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 142 "scanner.l"
+return TYPE;
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 143 "scanner.l"
+return INTERPRET;
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 144 "scanner.l"
+return ACTION_TOK;
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 145 "scanner.l"
+return KEY;
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 146 "scanner.l"
+return ALIAS;
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 147 "scanner.l"
+return GROUP;
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 148 "scanner.l"
+return MODIFIER_MAP;
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 149 "scanner.l"
+return MODIFIER_MAP;
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 150 "scanner.l"
+return MODIFIER_MAP;
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 151 "scanner.l"
+return INDICATOR;
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 152 "scanner.l"
+return SHAPE;
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 153 "scanner.l"
+return ROW;
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 154 "scanner.l"
+return KEYS;
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 155 "scanner.l"
+return SECTION;
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 156 "scanner.l"
+return OVERLAY;
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 157 "scanner.l"
+return TEXT;
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 158 "scanner.l"
+return OUTLINE;
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 159 "scanner.l"
+return SOLID;
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 160 "scanner.l"
+return LOGO;
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 161 "scanner.l"
+return VIRTUAL;
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 162 "scanner.l"
+return ALPHANUMERIC_KEYS;
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 163 "scanner.l"
+return MODIFIER_KEYS;
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 164 "scanner.l"
+return KEYPAD_KEYS;
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 165 "scanner.l"
+return FUNCTION_KEYS;
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 166 "scanner.l"
+return ALTERNATE_GROUP;
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 168 "scanner.l"
+yylval->str = strdup(yytext); return IDENT;
+ YY_BREAK
+case 62:
+#line 171 "scanner.l"
+case 63:
+YY_RULE_SETUP
+#line 171 "scanner.l"
+{
+ char *end;
+ yylval->num = strtoul(yytext, &end, 0);
+
+ return INTEGER;
+ }
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 177 "scanner.l"
+{
+ char *end;
+ yylval->num = strtod(yytext, &end);
+
+ return FLOAT;
+ }
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 184 "scanner.l"
+return EQUALS;
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 185 "scanner.l"
+return PLUS;
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 186 "scanner.l"
+return MINUS;
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 187 "scanner.l"
+return DIVIDE;
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 188 "scanner.l"
+return TIMES;
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 189 "scanner.l"
+return OBRACE;
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 190 "scanner.l"
+return CBRACE;
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 191 "scanner.l"
+return OPAREN;
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 192 "scanner.l"
+return CPAREN;
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 193 "scanner.l"
+return OBRACKET;
+ YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 194 "scanner.l"
+return CBRACKET;
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 195 "scanner.l"
+return DOT;
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 196 "scanner.l"
+return COMMA;
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 197 "scanner.l"
+return SEMI;
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 198 "scanner.l"
+return EXCLAM;
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 199 "scanner.l"
+return INVERT;
+ YY_BREAK
+case 81:
+/* rule 81 can match eol */
+YY_RULE_SETUP
+#line 201 "scanner.l"
+
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(S_STR):
+#line 203 "scanner.l"
+return END_OF_FILE;
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 205 "scanner.l"
+return ERROR_TOK;
+ YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 207 "scanner.l"
+ECHO;
+ YY_BREAK
+#line 1600 "src/xkbcomp/scanner.c"
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yyg->yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * _xkbcommon_lex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
+
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yyg->yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yyg->yy_did_buffer_switch_on_eof = 0;
+
+ if ( _xkbcommon_wrap(yyscanner ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p =
+ yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yyg->yy_c_buf_p =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of _xkbcommon_lex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = yyg->yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ _xkbcommon_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ yyg->yy_n_chars, (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ if ( yyg->yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ _xkbcommon_restart(yyin ,yyscanner);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) _xkbcommon_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ yyg->yy_n_chars += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+
+ for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 336 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
+{
+ register int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+ register char *yy_cp = yyg->yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 336 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 335);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (yyscan_t yyscanner)
+#else
+ static int input (yyscan_t yyscanner)
+#endif
+
+{
+ int c;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+ if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ /* This was really a NUL. */
+ *yyg->yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ ++yyg->yy_c_buf_p;
+
+ switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ _xkbcommon_restart(yyin ,yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( _xkbcommon_wrap(yyscanner ) )
+ return EOF;
+
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput(yyscanner);
+#else
+ return input(yyscanner);
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
+ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
+ yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+ if ( c == '\n' )
+
+ do{ yylineno++;
+ yycolumn=0;
+ }while(0)
+;
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void _xkbcommon_restart (FILE * input_file , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! YY_CURRENT_BUFFER ){
+ _xkbcommon_ensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ _xkbcommon__create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ _xkbcommon__init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+ _xkbcommon__load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+ void _xkbcommon__switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * _xkbcommon_pop_buffer_state();
+ * _xkbcommon_push_buffer_state(new_buffer);
+ */
+ _xkbcommon_ensure_buffer_stack (yyscanner);
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ _xkbcommon__load_buffer_state(yyscanner );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (_xkbcommon_wrap()) processing, but the only time this flag
+ * is looked at is after _xkbcommon_wrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void _xkbcommon__load_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE _xkbcommon__create_buffer (FILE * file, int size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) _xkbcommon_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in _xkbcommon__create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) _xkbcommon_alloc(b->yy_buf_size + 2 ,yyscanner );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in _xkbcommon__create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ _xkbcommon__init_buffer(b,file ,yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with _xkbcommon__create_buffer()
+ * @param yyscanner The scanner object.
+ */
+ void _xkbcommon__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ _xkbcommon_free((void *) b->yy_ch_buf ,yyscanner );
+
+ _xkbcommon_free((void *) b ,yyscanner );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a _xkbcommon_restart() or at EOF.
+ */
+ static void _xkbcommon__init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ _xkbcommon__flush_buffer(b ,yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then _xkbcommon__init_buffer was _probably_
+ * called from _xkbcommon_restart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+ void _xkbcommon__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ _xkbcommon__load_buffer_state(yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ * @param yyscanner The scanner object.
+ */
+void _xkbcommon_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ _xkbcommon_ensure_buffer_stack(yyscanner);
+
+ /* This block is copied from _xkbcommon__switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ yyg->yy_buffer_stack_top++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from _xkbcommon__switch_to_buffer. */
+ _xkbcommon__load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ * @param yyscanner The scanner object.
+ */
+void _xkbcommon_pop_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ _xkbcommon__delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if (yyg->yy_buffer_stack_top > 0)
+ --yyg->yy_buffer_stack_top;
+
+ if (YY_CURRENT_BUFFER) {
+ _xkbcommon__load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void _xkbcommon_ensure_buffer_stack (yyscan_t yyscanner)
+{
+ int num_to_alloc;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (!yyg->yy_buffer_stack) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)_xkbcommon_alloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in _xkbcommon_ensure_buffer_stack()" );
+
+ memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ yyg->yy_buffer_stack_top = 0;
+ return;
+ }
+
+ if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)_xkbcommon_realloc
+ (yyg->yy_buffer_stack,
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in _xkbcommon_ensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE _xkbcommon__scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) _xkbcommon_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in _xkbcommon__scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ _xkbcommon__switch_to_buffer(b ,yyscanner );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to _xkbcommon_lex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * _xkbcommon__scan_bytes() instead.
+ */
+YY_BUFFER_STATE _xkbcommon__scan_string (yyconst char * yystr , yyscan_t yyscanner)
+{
+
+ return _xkbcommon__scan_bytes(yystr,strlen(yystr) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to _xkbcommon_lex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE _xkbcommon__scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) _xkbcommon_alloc(n ,yyscanner );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in _xkbcommon__scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = _xkbcommon__scan_buffer(buf,n ,yyscanner);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in _xkbcommon__scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = yyg->yy_hold_char; \
+ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+ yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+ *yyg->yy_c_buf_p = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE _xkbcommon_get_extra (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int _xkbcommon_get_lineno (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int _xkbcommon_get_column (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *_xkbcommon_get_in (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *_xkbcommon_get_out (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int _xkbcommon_get_leng (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *_xkbcommon_get_text (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void _xkbcommon_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void _xkbcommon_set_lineno (int line_number , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* lineno is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "_xkbcommon_set_lineno called with no buffer" , yyscanner);
+
+ yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void _xkbcommon_set_column (int column_no , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* column is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "_xkbcommon_set_column called with no buffer" , yyscanner);
+
+ yycolumn = column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see _xkbcommon__switch_to_buffer
+ */
+void _xkbcommon_set_in (FILE * in_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyin = in_str ;
+}
+
+void _xkbcommon_set_out (FILE * out_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyout = out_str ;
+}
+
+int _xkbcommon_get_debug (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yy_flex_debug;
+}
+
+void _xkbcommon_set_debug (int bdebug , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yy_flex_debug = bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+YYSTYPE * _xkbcommon_get_lval (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yylval;
+}
+
+void _xkbcommon_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yylval = yylval_param;
+}
+
+YYLTYPE *_xkbcommon_get_lloc (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yylloc;
+}
+
+void _xkbcommon_set_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yylloc = yylloc_param;
+}
+
+/* User-visible API */
+
+/* _xkbcommon_lex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+
+int _xkbcommon_lex_init(yyscan_t* ptr_yy_globals)
+
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) _xkbcommon_alloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* _xkbcommon_lex_init_extra has the same functionality as _xkbcommon_lex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to _xkbcommon_alloc in
+ * the yyextra field.
+ */
+
+int _xkbcommon_lex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+ struct yyguts_t dummy_yyguts;
+
+ _xkbcommon_set_extra (yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) _xkbcommon_alloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in
+ yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ _xkbcommon_set_extra (yy_user_defined, *ptr_yy_globals);
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from _xkbcommon_lex_destroy(), so don't allocate here.
+ */
+
+ yyg->yy_buffer_stack = 0;
+ yyg->yy_buffer_stack_top = 0;
+ yyg->yy_buffer_stack_max = 0;
+ yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_init = 0;
+ yyg->yy_start = 0;
+
+ yyg->yy_start_stack_ptr = 0;
+ yyg->yy_start_stack_depth = 0;
+ yyg->yy_start_stack = NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * _xkbcommon_lex_init()
+ */
+ return 0;
+}
+
+/* _xkbcommon_lex_destroy is for both reentrant and non-reentrant scanners. */
+int _xkbcommon_lex_destroy (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ _xkbcommon__delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ _xkbcommon_pop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ _xkbcommon_free(yyg->yy_buffer_stack ,yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ _xkbcommon_free(yyg->yy_start_stack ,yyscanner );
+ yyg->yy_start_stack = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * _xkbcommon_lex() is called, initialization will occur. */
+ yy_init_globals( yyscanner);
+
+ /* Destroy the main struct (reentrant only). */
+ _xkbcommon_free ( yyscanner , yyscanner );
+ yyscanner = NULL;
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *_xkbcommon_alloc (yy_size_t size , yyscan_t yyscanner)
+{
+ return (void *) malloc( size );
+}
+
+void *_xkbcommon_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void _xkbcommon_free (void * ptr , yyscan_t yyscanner)
+{
+ free( (char *) ptr ); /* see _xkbcommon_realloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 207 "scanner.l"
+
+
+
+#pragma GCC diagnostic pop
+
+static void
+scanner_error_extra(struct YYLTYPE *loc, struct scanner_extra *extra,
+ const char *msg)
+{
+ log_err(extra->ctx, "%s: line %d of %s\n", msg,
+ loc->first_line,
+ extra->file_name ? extra->file_name : "(unknown)");
+}
+
+void
+scanner_error(struct YYLTYPE *loc, void *scanner, const char *msg)
+{
+ struct scanner_extra *extra = _xkbcommon_get_extra(scanner);
+ scanner_error_extra(loc, extra, msg);
+}
+
+static bool
+init_scanner(yyscan_t *scanner, struct scanner_extra *extra,
+ struct xkb_context *ctx, const char *file_name)
+{
+ memset(extra, 0, sizeof(*extra));
+
+ if (_xkbcommon_lex_init_extra(extra,scanner) != 0)
+ return false;
+
+ extra->ctx = ctx;
+ extra->file_name = file_name;
+
+ return true;
+}
+
+static void
+clear_scanner(yyscan_t scanner)
+{
+ _xkbcommon_lex_destroy(scanner);
+}
+
+XkbFile *
+XkbParseString(struct xkb_context *ctx, const char *string,
+ const char *file_name)
+{
+ yyscan_t scanner;
+ struct scanner_extra extra;
+ YY_BUFFER_STATE state;
+ XkbFile *xkb_file;
+
+ if (!init_scanner(&scanner, &extra, ctx, file_name))
+ return NULL;
+
+ state = _xkbcommon__scan_string(string,scanner);
+
+ xkb_file = parse(ctx, scanner, NULL);
+
+ _xkbcommon__delete_buffer(state,scanner);
+ clear_scanner(scanner);
+
+ return xkb_file;
+}
+
+/*
+ * _xkbcommon__scan_buffer() requires the last two bytes of \buf to be 0. These two bytes
+ * are not scanned. Other zero bytes in the buffer are scanned normally, though.
+ * Due to these terminating zeroes, \length must be greater than 2.
+ * Furthermore, the buffer must be writable and you cannot make any assumptions
+ * about it after the scanner finished.
+ * All this must be guaranteed by the caller of this function!
+ */
+XkbFile *
+XkbParseBuffer(struct xkb_context *ctx, char *buf, size_t length,
+ const char *file_name)
+{
+ yyscan_t scanner;
+ struct scanner_extra extra;
+ YY_BUFFER_STATE state;
+ XkbFile *xkb_file;
+
+ if (!init_scanner(&scanner, &extra, ctx, file_name))
+ return NULL;
+
+ xkb_file = NULL;
+ state = _xkbcommon__scan_buffer(buf,length,scanner);
+ if (state) {
+ xkb_file = parse(ctx, scanner, NULL);
+ _xkbcommon__delete_buffer(state,scanner);
+ }
+
+ clear_scanner(scanner);
+
+ return xkb_file;
+}
+
+XkbFile *
+XkbParseFile(struct xkb_context *ctx, FILE *file,
+ const char *file_name, const char *map)
+{
+ yyscan_t scanner;
+ struct scanner_extra extra;
+ YY_BUFFER_STATE state;
+ XkbFile *xkb_file;
+
+ if (!init_scanner(&scanner, &extra, ctx, file_name))
+ return NULL;
+
+ state = _xkbcommon__create_buffer(file,YY_BUF_SIZE,scanner);
+ _xkbcommon__switch_to_buffer(state,scanner);
+
+ xkb_file = parse(ctx, scanner, map);
+
+ _xkbcommon__delete_buffer(state,scanner);
+ clear_scanner(scanner);
+
+ return xkb_file;
+}
+
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c b/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c
new file mode 100644
index 0000000000..a2970f5004
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c
@@ -0,0 +1,1638 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+/*
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ * Ran Benita <ran234@gmail.com>
+ */
+
+#include "xkbcomp-priv.h"
+#include "text.h"
+#include "expr.h"
+#include "action.h"
+#include "vmod.h"
+#include "include.h"
+#include "keysym.h"
+
+enum key_repeat {
+ KEY_REPEAT_UNDEFINED = 0,
+ KEY_REPEAT_YES = 1,
+ KEY_REPEAT_NO = 2,
+};
+
+enum group_field {
+ GROUP_FIELD_SYMS = (1 << 0),
+ GROUP_FIELD_ACTS = (1 << 1),
+ GROUP_FIELD_TYPE = (1 << 2),
+};
+
+enum key_field {
+ KEY_FIELD_REPEAT = (1 << 0),
+ KEY_FIELD_DEFAULT_TYPE = (1 << 1),
+ KEY_FIELD_GROUPINFO = (1 << 2),
+ KEY_FIELD_VMODMAP = (1 << 3),
+};
+
+typedef struct {
+ enum group_field defined;
+ darray(struct xkb_level) levels;
+ xkb_atom_t type;
+} GroupInfo;
+
+typedef struct {
+ enum key_field defined;
+ enum merge_mode merge;
+
+ xkb_atom_t name;
+
+ darray(GroupInfo) groups;
+
+ enum key_repeat repeat;
+ xkb_mod_mask_t vmodmap;
+ xkb_atom_t default_type;
+
+ enum xkb_range_exceed_type out_of_range_group_action;
+ xkb_layout_index_t out_of_range_group_number;
+} KeyInfo;
+
+static void
+ClearLevelInfo(struct xkb_level *leveli)
+{
+ if (leveli->num_syms > 1)
+ free(leveli->u.syms);
+}
+
+static void
+InitGroupInfo(GroupInfo *groupi)
+{
+ memset(groupi, 0, sizeof(*groupi));
+}
+
+static void
+ClearGroupInfo(GroupInfo *groupi)
+{
+ struct xkb_level *leveli;
+ darray_foreach(leveli, groupi->levels)
+ ClearLevelInfo(leveli);
+ darray_free(groupi->levels);
+}
+
+static void
+CopyGroupInfo(GroupInfo *to, const GroupInfo *from)
+{
+ xkb_level_index_t j;
+ to->defined = from->defined;
+ to->type = from->type;
+ darray_init(to->levels);
+ darray_copy(to->levels, from->levels);
+ for (j = 0; j < darray_size(to->levels); j++)
+ if (darray_item(from->levels, j).num_syms > 1)
+ darray_item(to->levels, j).u.syms =
+ memdup(darray_item(from->levels, j).u.syms,
+ darray_item(from->levels, j).num_syms,
+ sizeof(xkb_keysym_t));
+}
+
+static void
+InitKeyInfo(struct xkb_context *ctx, KeyInfo *keyi)
+{
+ memset(keyi, 0, sizeof(*keyi));
+ keyi->merge = MERGE_OVERRIDE;
+ keyi->name = xkb_atom_intern(ctx, "*");
+ keyi->out_of_range_group_action = RANGE_WRAP;
+}
+
+static void
+ClearKeyInfo(KeyInfo *keyi)
+{
+ GroupInfo *groupi;
+ darray_foreach(groupi, keyi->groups)
+ ClearGroupInfo(groupi);
+ darray_free(keyi->groups);
+}
+
+/***====================================================================***/
+
+typedef struct {
+ enum merge_mode merge;
+ bool haveSymbol;
+ xkb_mod_index_t modifier;
+ union {
+ xkb_atom_t keyName;
+ xkb_keysym_t keySym;
+ } u;
+} ModMapEntry;
+
+typedef struct {
+ char *name; /* e.g. pc+us+inet(evdev) */
+ int errorCount;
+ enum merge_mode merge;
+ xkb_layout_index_t explicit_group;
+ darray(KeyInfo) keys;
+ KeyInfo default_key;
+ ActionsInfo *actions;
+ darray(xkb_atom_t) group_names;
+ darray(ModMapEntry) modMaps;
+
+ struct xkb_keymap *keymap;
+} SymbolsInfo;
+
+static void
+InitSymbolsInfo(SymbolsInfo *info, struct xkb_keymap *keymap,
+ ActionsInfo *actions)
+{
+ memset(info, 0, sizeof(*info));
+ info->keymap = keymap;
+ info->merge = MERGE_OVERRIDE;
+ InitKeyInfo(keymap->ctx, &info->default_key);
+ info->actions = actions;
+ info->explicit_group = XKB_LAYOUT_INVALID;
+}
+
+static void
+ClearSymbolsInfo(SymbolsInfo *info)
+{
+ KeyInfo *keyi;
+ free(info->name);
+ darray_foreach(keyi, info->keys)
+ ClearKeyInfo(keyi);
+ darray_free(info->keys);
+ darray_free(info->group_names);
+ darray_free(info->modMaps);
+ ClearKeyInfo(&info->default_key);
+}
+
+static const char *
+KeyInfoText(SymbolsInfo *info, KeyInfo *keyi)
+{
+ return KeyNameText(info->keymap->ctx, keyi->name);
+}
+
+static bool
+MergeGroups(SymbolsInfo *info, GroupInfo *into, GroupInfo *from, bool clobber,
+ bool report, xkb_layout_index_t group, xkb_atom_t key_name)
+{
+ xkb_level_index_t i, levels_in_both;
+ struct xkb_context *ctx = info->keymap->ctx;
+
+ /* First find the type of the merged group. */
+ if (into->type != from->type) {
+ if (from->type == XKB_ATOM_NONE) {
+ }
+ else if (into->type == XKB_ATOM_NONE) {
+ into->type = from->type;
+ }
+ else {
+ xkb_atom_t use = (clobber ? from->type : into->type);
+ xkb_atom_t ignore = (clobber ? into->type : from->type);
+
+ if (report)
+ log_warn(info->keymap->ctx,
+ "Multiple definitions for group %d type of key %s; "
+ "Using %s, ignoring %s\n",
+ group + 1, KeyNameText(ctx, key_name),
+ xkb_atom_text(ctx, use), xkb_atom_text(ctx, ignore));
+
+ into->type = use;
+ }
+ }
+ into->defined |= (from->defined & GROUP_FIELD_TYPE);
+
+ /* Now look at the levels. */
+
+ if (darray_empty(from->levels)) {
+ InitGroupInfo(from);
+ return true;
+ }
+
+ if (darray_empty(into->levels)) {
+ from->type = into->type;
+ *into = *from;
+ InitGroupInfo(from);
+ return true;
+ }
+
+ /* Merge the actions and syms. */
+ levels_in_both = MIN(darray_size(into->levels), darray_size(from->levels));
+ for (i = 0; i < levels_in_both; i++) {
+ struct xkb_level *intoLevel = &darray_item(into->levels, i);
+ struct xkb_level *fromLevel = &darray_item(from->levels, i);
+
+ if (fromLevel->action.type == ACTION_TYPE_NONE) {
+ }
+ else if (intoLevel->action.type == ACTION_TYPE_NONE) {
+ intoLevel->action = fromLevel->action;
+ }
+ else {
+ union xkb_action *use, *ignore;
+ use = (clobber ? &fromLevel->action : &intoLevel->action);
+ ignore = (clobber ? &intoLevel->action : &fromLevel->action);
+
+ if (report)
+ log_warn(ctx,
+ "Multiple actions for level %d/group %u on key %s; "
+ "Using %s, ignoring %s\n",
+ i + 1, group + 1, KeyNameText(ctx, key_name),
+ ActionTypeText(use->type),
+ ActionTypeText(ignore->type));
+
+ intoLevel->action = *use;
+ }
+
+ if (fromLevel->num_syms == 0) {
+ }
+ else if (intoLevel->num_syms == 0) {
+ intoLevel->num_syms = fromLevel->num_syms;
+ if (fromLevel->num_syms > 1)
+ intoLevel->u.syms = fromLevel->u.syms;
+ else
+ intoLevel->u.sym = fromLevel->u.sym;
+ fromLevel->num_syms = 0;
+ }
+ else {
+ if (report)
+ log_warn(ctx,
+ "Multiple symbols for level %d/group %u on key %s; "
+ "Using %s, ignoring %s\n",
+ i + 1, group + 1, KeyNameText(ctx, key_name),
+ (clobber ? "from" : "to"),
+ (clobber ? "to" : "from"));
+
+ if (clobber) {
+ ClearLevelInfo(intoLevel);
+ intoLevel->num_syms = fromLevel->num_syms;
+ if (fromLevel->num_syms > 1)
+ intoLevel->u.syms = fromLevel->u.syms;
+ else
+ intoLevel->u.sym = fromLevel->u.sym;
+ fromLevel->num_syms = 0;
+ }
+ }
+ }
+ /* If @from has extra levels, get them as well. */
+ for (i = levels_in_both; i < darray_size(from->levels); i++) {
+ darray_append(into->levels, darray_item(from->levels, i));
+ darray_item(from->levels, i).num_syms = 0;
+ }
+ into->defined |= (from->defined & GROUP_FIELD_ACTS);
+ into->defined |= (from->defined & GROUP_FIELD_SYMS);
+
+ return true;
+}
+
+static bool
+UseNewKeyField(enum key_field field, enum key_field old, enum key_field new,
+ bool clobber, bool report, enum key_field *collide)
+{
+ if (!(old & field))
+ return (new & field);
+
+ if (new & field) {
+ if (report)
+ *collide |= field;
+
+ if (clobber)
+ return true;
+ }
+
+ return false;
+}
+
+static bool
+MergeKeys(SymbolsInfo *info, KeyInfo *into, KeyInfo *from, bool same_file)
+{
+ xkb_layout_index_t i;
+ xkb_layout_index_t groups_in_both;
+ enum key_field collide = 0;
+ const int verbosity = xkb_context_get_log_verbosity(info->keymap->ctx);
+ const bool clobber = (from->merge != MERGE_AUGMENT);
+ const bool report = (same_file && verbosity > 0) || verbosity > 9;
+
+ if (from->merge == MERGE_REPLACE) {
+ ClearKeyInfo(into);
+ *into = *from;
+ InitKeyInfo(info->keymap->ctx, from);
+ return true;
+ }
+
+ groups_in_both = MIN(darray_size(into->groups), darray_size(from->groups));
+ for (i = 0; i < groups_in_both; i++)
+ MergeGroups(info,
+ &darray_item(into->groups, i),
+ &darray_item(from->groups, i),
+ clobber, report, i, into->name);
+ /* If @from has extra groups, just move them to @into. */
+ for (i = groups_in_both; i < darray_size(from->groups); i++) {
+ darray_append(into->groups, darray_item(from->groups, i));
+ InitGroupInfo(&darray_item(from->groups, i));
+ }
+
+ if (UseNewKeyField(KEY_FIELD_VMODMAP, into->defined, from->defined,
+ clobber, report, &collide)) {
+ into->vmodmap = from->vmodmap;
+ into->defined |= KEY_FIELD_VMODMAP;
+ }
+ if (UseNewKeyField(KEY_FIELD_REPEAT, into->defined, from->defined,
+ clobber, report, &collide)) {
+ into->repeat = from->repeat;
+ into->defined |= KEY_FIELD_REPEAT;
+ }
+ if (UseNewKeyField(KEY_FIELD_DEFAULT_TYPE, into->defined, from->defined,
+ clobber, report, &collide)) {
+ into->default_type = from->default_type;
+ into->defined |= KEY_FIELD_DEFAULT_TYPE;
+ }
+ if (UseNewKeyField(KEY_FIELD_GROUPINFO, into->defined, from->defined,
+ clobber, report, &collide)) {
+ into->out_of_range_group_action = from->out_of_range_group_action;
+ into->out_of_range_group_number = from->out_of_range_group_number;
+ into->defined |= KEY_FIELD_GROUPINFO;
+ }
+
+ if (collide)
+ log_warn(info->keymap->ctx,
+ "Symbol map for key %s redefined; "
+ "Using %s definition for conflicting fields\n",
+ KeyNameText(info->keymap->ctx, into->name),
+ (clobber ? "first" : "last"));
+
+ ClearKeyInfo(from);
+ InitKeyInfo(info->keymap->ctx, from);
+ return true;
+}
+
+static bool
+AddKeySymbols(SymbolsInfo *info, KeyInfo *keyi, bool same_file)
+{
+ xkb_atom_t real_name;
+ KeyInfo *iter;
+
+ /*
+ * Don't keep aliases in the keys array; this guarantees that
+ * searching for keys to merge with by straight comparison (see the
+ * following loop) is enough, and we won't get multiple KeyInfo's
+ * for the same key because of aliases.
+ */
+ real_name = XkbResolveKeyAlias(info->keymap, keyi->name);
+ if (real_name != XKB_ATOM_NONE)
+ keyi->name = real_name;
+
+ darray_foreach(iter, info->keys)
+ if (iter->name == keyi->name)
+ return MergeKeys(info, iter, keyi, same_file);
+
+ darray_append(info->keys, *keyi);
+ InitKeyInfo(info->keymap->ctx, keyi);
+ return true;
+}
+
+static bool
+AddModMapEntry(SymbolsInfo *info, ModMapEntry *new)
+{
+ ModMapEntry *old;
+ bool clobber = (new->merge != MERGE_AUGMENT);
+
+ darray_foreach(old, info->modMaps) {
+ xkb_mod_index_t use, ignore;
+
+ if ((new->haveSymbol != old->haveSymbol) ||
+ (new->haveSymbol && new->u.keySym != old->u.keySym) ||
+ (!new->haveSymbol && new->u.keyName != old->u.keyName))
+ continue;
+
+ if (new->modifier == old->modifier)
+ return true;
+
+ use = (clobber ? new->modifier : old->modifier);
+ ignore = (clobber ? old->modifier : new->modifier);
+
+ if (new->haveSymbol)
+ log_err(info->keymap->ctx,
+ "Symbol \"%s\" added to modifier map for multiple modifiers; "
+ "Using %s, ignoring %s\n",
+ KeysymText(info->keymap->ctx, new->u.keySym),
+ ModIndexText(info->keymap, use),
+ ModIndexText(info->keymap, ignore));
+ else
+ log_err(info->keymap->ctx,
+ "Key \"%s\" added to modifier map for multiple modifiers; "
+ "Using %s, ignoring %s\n",
+ KeyNameText(info->keymap->ctx, new->u.keyName),
+ ModIndexText(info->keymap, use),
+ ModIndexText(info->keymap, ignore));
+
+ old->modifier = use;
+ return true;
+ }
+
+ darray_append(info->modMaps, *new);
+ return true;
+}
+
+/***====================================================================***/
+
+static void
+MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from,
+ enum merge_mode merge)
+{
+ unsigned int i;
+ KeyInfo *keyi;
+ ModMapEntry *mm;
+ xkb_atom_t *group_name;
+ xkb_layout_index_t group_names_in_both;
+
+ if (from->errorCount > 0) {
+ into->errorCount += from->errorCount;
+ return;
+ }
+
+ if (into->name == NULL) {
+ into->name = from->name;
+ from->name = NULL;
+ }
+
+ group_names_in_both = MIN(darray_size(into->group_names),
+ darray_size(from->group_names));
+ for (i = 0; i < group_names_in_both; i++) {
+ if (!darray_item(from->group_names, i))
+ continue;
+
+ if (merge == MERGE_AUGMENT && darray_item(into->group_names, i))
+ continue;
+
+ darray_item(into->group_names, i) = darray_item(from->group_names, i);
+ }
+ /* If @from has more, get them as well. */
+ darray_foreach_from(group_name, from->group_names, group_names_in_both)
+ darray_append(into->group_names, *group_name);
+
+ darray_foreach(keyi, from->keys) {
+ keyi->merge = (merge == MERGE_DEFAULT ? keyi->merge : merge);
+ if (!AddKeySymbols(into, keyi, false))
+ into->errorCount++;
+ }
+
+ darray_foreach(mm, from->modMaps) {
+ mm->merge = (merge == MERGE_DEFAULT ? mm->merge : merge);
+ if (!AddModMapEntry(into, mm))
+ into->errorCount++;
+ }
+}
+
+static void
+HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge);
+
+static bool
+HandleIncludeSymbols(SymbolsInfo *info, IncludeStmt *include)
+{
+ SymbolsInfo included;
+
+ InitSymbolsInfo(&included, info->keymap, info->actions);
+ included.name = include->stmt;
+ include->stmt = NULL;
+
+ for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) {
+ SymbolsInfo next_incl;
+ XkbFile *file;
+
+ file = ProcessIncludeFile(info->keymap->ctx, stmt, FILE_TYPE_SYMBOLS);
+ if (!file) {
+ info->errorCount += 10;
+ ClearSymbolsInfo(&included);
+ return false;
+ }
+
+ InitSymbolsInfo(&next_incl, info->keymap, info->actions);
+ if (stmt->modifier) {
+ next_incl.explicit_group = atoi(stmt->modifier) - 1;
+ if (next_incl.explicit_group >= XKB_MAX_GROUPS) {
+ log_err(info->keymap->ctx,
+ "Cannot set explicit group to %d - must be between 1..%d; "
+ "Ignoring group number\n",
+ next_incl.explicit_group + 1, XKB_MAX_GROUPS);
+ next_incl.explicit_group = info->explicit_group;
+ }
+ }
+ else {
+ next_incl.explicit_group = info->explicit_group;
+ }
+
+ HandleSymbolsFile(&next_incl, file, MERGE_OVERRIDE);
+
+ MergeIncludedSymbols(&included, &next_incl, stmt->merge);
+
+ ClearSymbolsInfo(&next_incl);
+ FreeXkbFile(file);
+ }
+
+ MergeIncludedSymbols(info, &included, include->merge);
+ ClearSymbolsInfo(&included);
+
+ return (info->errorCount == 0);
+}
+
+#define SYMBOLS 1
+#define ACTIONS 2
+
+static bool
+GetGroupIndex(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
+ unsigned what, xkb_layout_index_t *ndx_rtrn)
+{
+ const char *name = (what == SYMBOLS ? "symbols" : "actions");
+
+ if (arrayNdx == NULL) {
+ xkb_layout_index_t i;
+ GroupInfo *groupi;
+ enum group_field field = (what == SYMBOLS ?
+ GROUP_FIELD_SYMS : GROUP_FIELD_ACTS);
+
+ darray_enumerate(i, groupi, keyi->groups) {
+ if (!(groupi->defined & field)) {
+ *ndx_rtrn = i;
+ return true;
+ }
+ }
+
+ if (i >= XKB_MAX_GROUPS) {
+ log_err(info->keymap->ctx,
+ "Too many groups of %s for key %s (max %u); "
+ "Ignoring %s defined for extra groups\n",
+ name, KeyInfoText(info, keyi), XKB_MAX_GROUPS, name);
+ return false;
+ }
+
+ darray_resize0(keyi->groups, darray_size(keyi->groups) + 1);
+ *ndx_rtrn = darray_size(keyi->groups) - 1;
+ return true;
+ }
+
+ if (!ExprResolveGroup(info->keymap->ctx, arrayNdx, ndx_rtrn)) {
+ log_err(info->keymap->ctx,
+ "Illegal group index for %s of key %s\n"
+ "Definition with non-integer array index ignored\n",
+ name, KeyInfoText(info, keyi));
+ return false;
+ }
+
+ (*ndx_rtrn)--;
+ if (*ndx_rtrn >= darray_size(keyi->groups))
+ darray_resize0(keyi->groups, *ndx_rtrn + 1);
+
+ return true;
+}
+
+bool
+LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn)
+{
+ xkb_keysym_t sym;
+
+ if (!str || istreq(str, "any") || istreq(str, "nosymbol")) {
+ *sym_rtrn = XKB_KEY_NoSymbol;
+ return 1;
+ }
+
+ if (istreq(str, "none") || istreq(str, "voidsymbol")) {
+ *sym_rtrn = XKB_KEY_VoidSymbol;
+ return 1;
+ }
+
+ sym = xkb_keysym_from_name(str, 0);
+ if (sym != XKB_KEY_NoSymbol) {
+ *sym_rtrn = sym;
+ return 1;
+ }
+
+ return 0;
+}
+
+static bool
+AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
+ ExprDef *value)
+{
+ xkb_layout_index_t ndx;
+ GroupInfo *groupi;
+ xkb_level_index_t nLevels;
+ xkb_level_index_t i;
+ int j;
+
+ if (!GetGroupIndex(info, keyi, arrayNdx, SYMBOLS, &ndx))
+ return false;
+
+ groupi = &darray_item(keyi->groups, ndx);
+
+ if (value == NULL) {
+ groupi->defined |= GROUP_FIELD_SYMS;
+ return true;
+ }
+
+ if (value->op != EXPR_KEYSYM_LIST) {
+ log_err(info->keymap->ctx,
+ "Expected a list of symbols, found %s; "
+ "Ignoring symbols for group %u of %s\n",
+ expr_op_type_to_string(value->op), ndx + 1,
+ KeyInfoText(info, keyi));
+ return false;
+ }
+
+ if (groupi->defined & GROUP_FIELD_SYMS) {
+ log_err(info->keymap->ctx,
+ "Symbols for key %s, group %u already defined; "
+ "Ignoring duplicate definition\n",
+ KeyInfoText(info, keyi), ndx + 1);
+ return false;
+ }
+
+ nLevels = darray_size(value->value.list.symsMapIndex);
+ if (darray_size(groupi->levels) < nLevels)
+ darray_resize0(groupi->levels, nLevels);
+
+ groupi->defined |= GROUP_FIELD_SYMS;
+
+ for (i = 0; i < nLevels; i++) {
+ unsigned int sym_index;
+ struct xkb_level *leveli = &darray_item(groupi->levels, i);
+
+ sym_index = darray_item(value->value.list.symsMapIndex, i);
+ leveli->num_syms = darray_item(value->value.list.symsNumEntries, i);
+ if (leveli->num_syms > 1)
+ leveli->u.syms = calloc(leveli->num_syms, sizeof(*leveli->u.syms));
+
+ for (j = 0; j < leveli->num_syms; j++) {
+ char *sym_name = darray_item(value->value.list.syms,
+ sym_index + j);
+ xkb_keysym_t keysym;
+
+ if (!LookupKeysym(sym_name, &keysym)) {
+ const char *group_name = "unnamed";
+
+ if (ndx < darray_size(info->group_names) &&
+ darray_item(info->group_names, ndx))
+ group_name = xkb_atom_text(info->keymap->ctx,
+ darray_item(info->group_names,
+ ndx));
+
+ log_warn(info->keymap->ctx,
+ "Could not resolve keysym %s for key %s, group %u (%s), level %u\n",
+ sym_name, KeyInfoText(info, keyi), ndx + 1,
+ group_name, i);
+
+ ClearLevelInfo(leveli);
+ leveli->num_syms = 0;
+ break;
+ }
+
+ if (leveli->num_syms == 1) {
+ if (keysym == XKB_KEY_NoSymbol)
+ leveli->num_syms = 0;
+ else
+ leveli->u.sym = keysym;
+ }
+ else if (leveli->num_syms > 1) {
+ leveli->u.syms[j] = keysym;
+ }
+ }
+ }
+
+ return true;
+}
+
+static bool
+AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
+ ExprDef *value)
+{
+ unsigned int i;
+ xkb_layout_index_t ndx;
+ GroupInfo *groupi;
+ unsigned int nActs;
+ ExprDef *act;
+ union xkb_action *toAct;
+
+ if (!GetGroupIndex(info, keyi, arrayNdx, ACTIONS, &ndx))
+ return false;
+
+ groupi = &darray_item(keyi->groups, ndx);
+
+ if (value == NULL) {
+ groupi->defined |= GROUP_FIELD_ACTS;
+ return true;
+ }
+
+ if (value->op != EXPR_ACTION_LIST) {
+ log_wsgo(info->keymap->ctx,
+ "Bad expression type (%d) for action list value; "
+ "Ignoring actions for group %u of %s\n",
+ value->op, ndx, KeyInfoText(info, keyi));
+ return false;
+ }
+
+ if (groupi->defined & GROUP_FIELD_ACTS) {
+ log_wsgo(info->keymap->ctx,
+ "Actions for key %s, group %u already defined\n",
+ KeyInfoText(info, keyi), ndx);
+ return false;
+ }
+
+ nActs = 0;
+ for (act = value->value.child; act; act = (ExprDef *) act->common.next)
+ nActs++;
+
+ if (darray_size(groupi->levels) < nActs)
+ darray_resize0(groupi->levels, nActs);
+
+ groupi->defined |= GROUP_FIELD_ACTS;
+
+ act = value->value.child;
+ for (i = 0; i < nActs; i++) {
+ toAct = &darray_item(groupi->levels, i).action;
+
+ if (!HandleActionDef(act, info->keymap, toAct, info->actions))
+ log_err(info->keymap->ctx,
+ "Illegal action definition for %s; "
+ "Action for group %u/level %u ignored\n",
+ KeyInfoText(info, keyi), ndx + 1, i + 1);
+
+ act = (ExprDef *) act->common.next;
+ }
+
+ return true;
+}
+
+static const LookupEntry repeatEntries[] = {
+ { "true", KEY_REPEAT_YES },
+ { "yes", KEY_REPEAT_YES },
+ { "on", KEY_REPEAT_YES },
+ { "false", KEY_REPEAT_NO },
+ { "no", KEY_REPEAT_NO },
+ { "off", KEY_REPEAT_NO },
+ { "default", KEY_REPEAT_UNDEFINED },
+ { NULL, 0 }
+};
+
+static bool
+SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field,
+ ExprDef *arrayNdx, ExprDef *value)
+{
+ bool ok = true;
+ struct xkb_context *ctx = info->keymap->ctx;
+
+ if (istreq(field, "type")) {
+ xkb_layout_index_t ndx;
+ xkb_atom_t val;
+
+ if (!ExprResolveString(ctx, value, &val))
+ log_vrb(ctx, 1,
+ "The type field of a key symbol map must be a string; "
+ "Ignoring illegal type definition\n");
+
+ if (arrayNdx == NULL) {
+ keyi->default_type = val;
+ keyi->defined |= KEY_FIELD_DEFAULT_TYPE;
+ }
+ else if (!ExprResolveGroup(ctx, arrayNdx, &ndx)) {
+ log_err(ctx,
+ "Illegal group index for type of key %s; "
+ "Definition with non-integer array index ignored\n",
+ KeyInfoText(info, keyi));
+ return false;
+ }
+ else {
+ ndx--;
+ if (ndx >= darray_size(keyi->groups))
+ darray_resize0(keyi->groups, ndx + 1);
+ darray_item(keyi->groups, ndx).type = val;
+ darray_item(keyi->groups, ndx).defined |= GROUP_FIELD_TYPE;
+ }
+ }
+ else if (istreq(field, "symbols"))
+ return AddSymbolsToKey(info, keyi, arrayNdx, value);
+ else if (istreq(field, "actions"))
+ return AddActionsToKey(info, keyi, arrayNdx, value);
+ else if (istreq(field, "vmods") ||
+ istreq(field, "virtualmods") ||
+ istreq(field, "virtualmodifiers")) {
+ xkb_mod_mask_t mask;
+
+ ok = ExprResolveModMask(info->keymap, value, MOD_VIRT, &mask);
+ if (ok) {
+ keyi->vmodmap = mask;
+ keyi->defined |= KEY_FIELD_VMODMAP;
+ }
+ else {
+ log_err(info->keymap->ctx,
+ "Expected a virtual modifier mask, found %s; "
+ "Ignoring virtual modifiers definition for key %s\n",
+ expr_op_type_to_string(value->op),
+ KeyInfoText(info, keyi));
+ }
+ }
+ else if (istreq(field, "locking") ||
+ istreq(field, "lock") ||
+ istreq(field, "locks")) {
+ log_err(info->keymap->ctx,
+ "Key behaviors not supported; "
+ "Ignoring locking specification for key %s\n",
+ KeyInfoText(info, keyi));
+ }
+ else if (istreq(field, "radiogroup") ||
+ istreq(field, "permanentradiogroup") ||
+ istreq(field, "allownone")) {
+ log_err(info->keymap->ctx,
+ "Radio groups not supported; "
+ "Ignoring radio group specification for key %s\n",
+ KeyInfoText(info, keyi));
+ }
+ else if (istreq_prefix("overlay", field) ||
+ istreq_prefix("permanentoverlay", field)) {
+ log_err(info->keymap->ctx,
+ "Overlays not supported; "
+ "Ignoring overlay specification for key %s\n",
+ KeyInfoText(info, keyi));
+ }
+ else if (istreq(field, "repeating") ||
+ istreq(field, "repeats") ||
+ istreq(field, "repeat")) {
+ unsigned int val;
+
+ ok = ExprResolveEnum(ctx, value, &val, repeatEntries);
+ if (!ok) {
+ log_err(info->keymap->ctx,
+ "Illegal repeat setting for %s; "
+ "Non-boolean repeat setting ignored\n",
+ KeyInfoText(info, keyi));
+ return false;
+ }
+ keyi->repeat = val;
+ keyi->defined |= KEY_FIELD_REPEAT;
+ }
+ else if (istreq(field, "groupswrap") ||
+ istreq(field, "wrapgroups")) {
+ bool set;
+
+ if (!ExprResolveBoolean(ctx, value, &set)) {
+ log_err(info->keymap->ctx,
+ "Illegal groupsWrap setting for %s; "
+ "Non-boolean value ignored\n",
+ KeyInfoText(info, keyi));
+ return false;
+ }
+
+ if (set)
+ keyi->out_of_range_group_action = RANGE_WRAP;
+ else
+ keyi->out_of_range_group_action = RANGE_SATURATE;
+
+ keyi->defined |= KEY_FIELD_GROUPINFO;
+ }
+ else if (istreq(field, "groupsclamp") ||
+ istreq(field, "clampgroups")) {
+ bool set;
+
+ if (!ExprResolveBoolean(ctx, value, &set)) {
+ log_err(info->keymap->ctx,
+ "Illegal groupsClamp setting for %s; "
+ "Non-boolean value ignored\n",
+ KeyInfoText(info, keyi));
+ return false;
+ }
+
+ if (set)
+ keyi->out_of_range_group_action = RANGE_SATURATE;
+ else
+ keyi->out_of_range_group_action = RANGE_WRAP;
+
+ keyi->defined |= KEY_FIELD_GROUPINFO;
+ }
+ else if (istreq(field, "groupsredirect") ||
+ istreq(field, "redirectgroups")) {
+ xkb_layout_index_t grp;
+
+ if (!ExprResolveGroup(ctx, value, &grp)) {
+ log_err(info->keymap->ctx,
+ "Illegal group index for redirect of key %s; "
+ "Definition with non-integer group ignored\n",
+ KeyInfoText(info, keyi));
+ return false;
+ }
+
+ keyi->out_of_range_group_action = RANGE_REDIRECT;
+ keyi->out_of_range_group_number = grp - 1;
+ keyi->defined |= KEY_FIELD_GROUPINFO;
+ }
+ else {
+ log_err(info->keymap->ctx,
+ "Unknown field %s in a symbol interpretation; "
+ "Definition ignored\n",
+ field);
+ ok = false;
+ }
+
+ return ok;
+}
+
+static int
+SetGroupName(SymbolsInfo *info, ExprDef *arrayNdx, ExprDef *value)
+{
+ xkb_layout_index_t group, group_to_use;
+ xkb_atom_t name;
+
+ if (!arrayNdx) {
+ log_vrb(info->keymap->ctx, 1,
+ "You must specify an index when specifying a group name; "
+ "Group name definition without array subscript ignored\n");
+ return false;
+ }
+
+ if (!ExprResolveGroup(info->keymap->ctx, arrayNdx, &group)) {
+ log_err(info->keymap->ctx,
+ "Illegal index in group name definition; "
+ "Definition with non-integer array index ignored\n");
+ return false;
+ }
+
+ if (!ExprResolveString(info->keymap->ctx, value, &name)) {
+ log_err(info->keymap->ctx,
+ "Group name must be a string; "
+ "Illegal name for group %d ignored\n", group);
+ return false;
+ }
+
+ if (info->explicit_group == XKB_LAYOUT_INVALID) {
+ group_to_use = group - 1;
+ }
+ else if (group - 1 == 0) {
+ group_to_use = info->explicit_group;
+ }
+ else {
+ log_warn(info->keymap->ctx,
+ "An explicit group was specified for the '%s' map, "
+ "but it provides a name for a group other than Group1 (%d); "
+ "Ignoring group name '%s'\n",
+ info->name, group,
+ xkb_atom_text(info->keymap->ctx, name));
+ return false;
+ }
+
+ if (group_to_use >= darray_size(info->group_names))
+ darray_resize0(info->group_names, group_to_use + 1);
+ darray_item(info->group_names, group_to_use) = name;
+
+ return true;
+}
+
+static int
+HandleGlobalVar(SymbolsInfo *info, VarDef *stmt)
+{
+ const char *elem, *field;
+ ExprDef *arrayNdx;
+ bool ret;
+
+ if (ExprResolveLhs(info->keymap->ctx, stmt->name, &elem, &field,
+ &arrayNdx) == 0)
+ return 0; /* internal error, already reported */
+ if (elem && istreq(elem, "key")) {
+ ret = SetSymbolsField(info, &info->default_key, field, arrayNdx,
+ stmt->value);
+ }
+ else if (!elem && (istreq(field, "name") ||
+ istreq(field, "groupname"))) {
+ ret = SetGroupName(info, arrayNdx, stmt->value);
+ }
+ else if (!elem && (istreq(field, "groupswrap") ||
+ istreq(field, "wrapgroups"))) {
+ log_err(info->keymap->ctx,
+ "Global \"groupswrap\" not supported; Ignored\n");
+ ret = true;
+ }
+ else if (!elem && (istreq(field, "groupsclamp") ||
+ istreq(field, "clampgroups"))) {
+ log_err(info->keymap->ctx,
+ "Global \"groupsclamp\" not supported; Ignored\n");
+ ret = true;
+ }
+ else if (!elem && (istreq(field, "groupsredirect") ||
+ istreq(field, "redirectgroups"))) {
+ log_err(info->keymap->ctx,
+ "Global \"groupsredirect\" not supported; Ignored\n");
+ ret = true;
+ }
+ else if (!elem && istreq(field, "allownone")) {
+ log_err(info->keymap->ctx,
+ "Radio groups not supported; "
+ "Ignoring \"allownone\" specification\n");
+ ret = true;
+ }
+ else {
+ ret = SetActionField(info->keymap, elem, field, arrayNdx, stmt->value,
+ info->actions);
+ }
+
+ return ret;
+}
+
+static bool
+HandleSymbolsBody(SymbolsInfo *info, VarDef *def, KeyInfo *keyi)
+{
+ bool ok = true;
+ const char *elem, *field;
+ ExprDef *arrayNdx;
+
+ for (; def; def = (VarDef *) def->common.next) {
+ if (def->name && def->name->op == EXPR_FIELD_REF) {
+ log_err(info->keymap->ctx,
+ "Cannot set a global default value from within a key statement; "
+ "Move statements to the global file scope\n");
+ continue;
+ }
+
+ if (!def->name) {
+ if (!def->value || def->value->op == EXPR_KEYSYM_LIST)
+ field = "symbols";
+ else
+ field = "actions";
+ arrayNdx = NULL;
+ }
+ else {
+ ok = ExprResolveLhs(info->keymap->ctx, def->name, &elem, &field,
+ &arrayNdx);
+ }
+
+ if (ok)
+ ok = SetSymbolsField(info, keyi, field, arrayNdx, def->value);
+ }
+
+ return ok;
+}
+
+static bool
+SetExplicitGroup(SymbolsInfo *info, KeyInfo *keyi)
+{
+ xkb_layout_index_t i;
+ GroupInfo *groupi;
+ bool warn = false;
+
+ if (info->explicit_group == XKB_LAYOUT_INVALID)
+ return true;
+
+ darray_enumerate_from(i, groupi, keyi->groups, 1) {
+ if (groupi->defined) {
+ warn = true;
+ ClearGroupInfo(groupi);
+ InitGroupInfo(groupi);
+ }
+ }
+
+ if (warn)
+ log_warn(info->keymap->ctx,
+ "For the map %s an explicit group specified, "
+ "but key %s has more than one group defined; "
+ "All groups except first one will be ignored\n",
+ info->name, KeyInfoText(info, keyi));
+
+ darray_resize0(keyi->groups, info->explicit_group + 1);
+ if (info->explicit_group > 0) {
+ darray_item(keyi->groups, info->explicit_group) =
+ darray_item(keyi->groups, 0);
+ InitGroupInfo(&darray_item(keyi->groups, 0));
+ }
+
+ return true;
+}
+
+static int
+HandleSymbolsDef(SymbolsInfo *info, SymbolsDef *stmt)
+{
+ KeyInfo keyi;
+ xkb_layout_index_t i;
+
+ keyi = info->default_key;
+ darray_init(keyi.groups);
+ darray_copy(keyi.groups, info->default_key.groups);
+ for (i = 0; i < darray_size(keyi.groups); i++)
+ CopyGroupInfo(&darray_item(keyi.groups, i),
+ &darray_item(info->default_key.groups, i));
+ keyi.merge = stmt->merge;
+ keyi.name = stmt->keyName;
+
+ if (!HandleSymbolsBody(info, (VarDef *) stmt->symbols, &keyi)) {
+ info->errorCount++;
+ return false;
+ }
+
+ if (!SetExplicitGroup(info, &keyi)) {
+ info->errorCount++;
+ return false;
+ }
+
+ if (!AddKeySymbols(info, &keyi, true)) {
+ info->errorCount++;
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+HandleModMapDef(SymbolsInfo *info, ModMapDef *def)
+{
+ ExprDef *key;
+ ModMapEntry tmp;
+ xkb_mod_index_t ndx;
+ bool ok;
+ struct xkb_context *ctx = info->keymap->ctx;
+
+ ndx = ModNameToIndex(info->keymap, def->modifier, MOD_REAL);
+ if (ndx == XKB_MOD_INVALID) {
+ log_err(info->keymap->ctx,
+ "Illegal modifier map definition; "
+ "Ignoring map for non-modifier \"%s\"\n",
+ xkb_atom_text(ctx, def->modifier));
+ return false;
+ }
+
+ ok = true;
+ tmp.modifier = ndx;
+
+ for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next) {
+ xkb_keysym_t sym;
+
+ if (key->op == EXPR_VALUE && key->value_type == EXPR_TYPE_KEYNAME) {
+ tmp.haveSymbol = false;
+ tmp.u.keyName = key->value.keyName;
+ }
+ else if (ExprResolveKeySym(ctx, key, &sym)) {
+ tmp.haveSymbol = true;
+ tmp.u.keySym = sym;
+ }
+ else {
+ log_err(info->keymap->ctx,
+ "Modmap entries may contain only key names or keysyms; "
+ "Illegal definition for %s modifier ignored\n",
+ ModIndexText(info->keymap, tmp.modifier));
+ continue;
+ }
+
+ ok = AddModMapEntry(info, &tmp) && ok;
+ }
+ return ok;
+}
+
+static void
+HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge)
+{
+ bool ok;
+
+ free(info->name);
+ info->name = strdup_safe(file->name);
+
+ for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) {
+ switch (stmt->type) {
+ case STMT_INCLUDE:
+ ok = HandleIncludeSymbols(info, (IncludeStmt *) stmt);
+ break;
+ case STMT_SYMBOLS:
+ ok = HandleSymbolsDef(info, (SymbolsDef *) stmt);
+ break;
+ case STMT_VAR:
+ ok = HandleGlobalVar(info, (VarDef *) stmt);
+ break;
+ case STMT_VMOD:
+ ok = HandleVModDef(info->keymap, (VModDef *) stmt);
+ break;
+ case STMT_MODMAP:
+ ok = HandleModMapDef(info, (ModMapDef *) stmt);
+ break;
+ default:
+ log_err(info->keymap->ctx,
+ "Interpretation files may not include other types; "
+ "Ignoring %s\n", stmt_type_to_string(stmt->type));
+ ok = false;
+ break;
+ }
+
+ if (!ok)
+ info->errorCount++;
+
+ if (info->errorCount > 10) {
+ log_err(info->keymap->ctx, "Abandoning symbols file \"%s\"\n",
+ file->topName);
+ break;
+ }
+ }
+}
+
+/**
+ * Given a keysym @sym, return a key which generates it, or NULL.
+ * This is used for example in a modifier map definition, such as:
+ * modifier_map Lock { Caps_Lock };
+ * where we want to add the Lock modifier to the modmap of the key
+ * which matches the keysym Caps_Lock.
+ * Since there can be many keys which generates the keysym, the key
+ * is chosen first by lowest group in which the keysym appears, than
+ * by lowest level and than by lowest key code.
+ */
+static struct xkb_key *
+FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym)
+{
+ struct xkb_key *key, *ret = NULL;
+ xkb_layout_index_t group, min_group = UINT32_MAX;
+ xkb_level_index_t level, min_level = UINT16_MAX;
+
+ xkb_foreach_key(key, keymap) {
+ for (group = 0; group < key->num_groups; group++) {
+ for (level = 0; level < XkbKeyGroupWidth(key, group); level++) {
+ if (key->groups[group].levels[level].num_syms != 1 ||
+ key->groups[group].levels[level].u.sym != sym)
+ continue;
+
+ /*
+ * If the keysym was found in a group or level > 0, we must
+ * keep looking since we might find a key in which the keysym
+ * is in a lower group or level.
+ */
+ if (group < min_group ||
+ (group == min_group && level < min_level)) {
+ ret = key;
+ if (group == 0 && level == 0) {
+ return ret;
+ }
+ else {
+ min_group = group;
+ min_level = level;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Find an appropriate type for a group and return its name.
+ *
+ * Simple recipe:
+ * - ONE_LEVEL for width 0/1
+ * - ALPHABETIC for 2 shift levels, with lower/upercase keysyms
+ * - KEYPAD for keypad keys.
+ * - TWO_LEVEL for other 2 shift level keys.
+ * and the same for four level keys.
+ *
+ * FIXME: Decide how to handle multiple-syms-per-level, and do it.
+ */
+static xkb_atom_t
+FindAutomaticType(struct xkb_context *ctx, GroupInfo *groupi)
+{
+ xkb_keysym_t sym0, sym1, sym2, sym3;
+ xkb_level_index_t width = darray_size(groupi->levels);
+
+#define GET_SYM(level) \
+ (darray_item(groupi->levels, level).num_syms == 0 ? \
+ XKB_KEY_NoSymbol : \
+ darray_item(groupi->levels, level).num_syms == 1 ? \
+ darray_item(groupi->levels, level).u.sym : \
+ /* num_syms > 1 */ \
+ darray_item(groupi->levels, level).u.syms[0])
+
+ if (width == 1 || width <= 0)
+ return xkb_atom_intern(ctx, "ONE_LEVEL");
+
+ sym0 = GET_SYM(0);
+ sym1 = GET_SYM(1);
+
+ if (width == 2) {
+ if (xkb_keysym_is_lower(sym0) && xkb_keysym_is_upper(sym1))
+ return xkb_atom_intern(ctx, "ALPHABETIC");
+
+ if (xkb_keysym_is_keypad(sym0) || xkb_keysym_is_keypad(sym1))
+ return xkb_atom_intern(ctx, "KEYPAD");
+
+ return xkb_atom_intern(ctx, "TWO_LEVEL");
+ }
+
+ if (width <= 4) {
+ if (xkb_keysym_is_lower(sym0) && xkb_keysym_is_upper(sym1)) {
+ sym2 = GET_SYM(2);
+ sym3 = (width == 4 ? GET_SYM(3) : XKB_KEY_NoSymbol);
+
+ if (xkb_keysym_is_lower(sym2) && xkb_keysym_is_upper(sym3))
+ return xkb_atom_intern(ctx, "FOUR_LEVEL_ALPHABETIC");
+
+ return xkb_atom_intern(ctx, "FOUR_LEVEL_SEMIALPHABETIC");
+ }
+
+ if (xkb_keysym_is_keypad(sym0) || xkb_keysym_is_keypad(sym1))
+ return xkb_atom_intern(ctx, "FOUR_LEVEL_KEYPAD");
+
+ return xkb_atom_intern(ctx, "FOUR_LEVEL");
+ }
+
+ return XKB_ATOM_NONE;
+
+#undef GET_SYM
+}
+
+static const struct xkb_key_type *
+FindTypeForGroup(struct xkb_keymap *keymap, KeyInfo *keyi,
+ xkb_layout_index_t group, bool *explicit_type)
+{
+ unsigned int i;
+ GroupInfo *groupi = &darray_item(keyi->groups, group);
+ xkb_atom_t type_name = groupi->type;
+
+ *explicit_type = true;
+
+ if (type_name == XKB_ATOM_NONE) {
+ if (keyi->default_type != XKB_ATOM_NONE) {
+ type_name = keyi->default_type;
+ }
+ else {
+ type_name = FindAutomaticType(keymap->ctx, groupi);
+ if (type_name != XKB_ATOM_NONE)
+ *explicit_type = false;
+ }
+ }
+
+ if (type_name == XKB_ATOM_NONE) {
+ log_warn(keymap->ctx,
+ "Couldn't find an automatic type for key '%s' group %d with %lu levels; "
+ "Using the default type\n",
+ KeyNameText(keymap->ctx, keyi->name), group + 1,
+ (unsigned long) darray_size(groupi->levels));
+ goto use_default;
+ }
+
+ for (i = 0; i < keymap->num_types; i++)
+ if (keymap->types[i].name == type_name)
+ break;
+
+ if (i >= keymap->num_types) {
+ log_warn(keymap->ctx,
+ "The type \"%s\" for key '%s' group %d was not previously defined; "
+ "Using the default type\n",
+ xkb_atom_text(keymap->ctx, type_name),
+ KeyNameText(keymap->ctx, keyi->name), group + 1);
+ goto use_default;
+ }
+
+ return &keymap->types[i];
+
+use_default:
+ /*
+ * Index 0 is guaranteed to contain something, usually
+ * ONE_LEVEL or at least some default one-level type.
+ */
+ return &keymap->types[0];
+}
+
+static bool
+CopySymbolsDef(SymbolsInfo *info, KeyInfo *keyi)
+{
+ struct xkb_keymap *keymap = info->keymap;
+ struct xkb_key *key;
+ GroupInfo *groupi;
+ const GroupInfo *group0;
+ xkb_layout_index_t i;
+
+ /*
+ * The name is guaranteed to be real and not an alias (see
+ * AddKeySymbols), so 'false' is safe here.
+ */
+ key = XkbKeyByName(keymap, keyi->name, false);
+ if (!key) {
+ log_vrb(info->keymap->ctx, 5,
+ "Key %s not found in keycodes; Symbols ignored\n",
+ KeyInfoText(info, keyi));
+ return false;
+ }
+
+ /* Find the range of groups we need. */
+ key->num_groups = 0;
+ darray_enumerate(i, groupi, keyi->groups)
+ if (groupi->defined)
+ key->num_groups = i + 1;
+
+ if (key->num_groups <= 0)
+ return false; /* WSGO */
+
+ darray_resize(keyi->groups, key->num_groups);
+
+ /*
+ * If there are empty groups between non-empty ones, fill them with data
+ * from the first group.
+ * We can make a wrong assumption here. But leaving gaps is worse.
+ */
+ group0 = &darray_item(keyi->groups, 0);
+ darray_foreach_from(groupi, keyi->groups, 1) {
+ if (groupi->defined)
+ continue;
+
+ CopyGroupInfo(groupi, group0);
+ }
+
+ key->groups = calloc(key->num_groups, sizeof(*key->groups));
+
+ /* Find and assign the groups' types in the keymap. */
+ darray_enumerate(i, groupi, keyi->groups) {
+ const struct xkb_key_type *type;
+ bool explicit_type;
+
+ type = FindTypeForGroup(keymap, keyi, i, &explicit_type);
+
+ /* Always have as many levels as the type specifies. */
+ if (type->num_levels < darray_size(groupi->levels)) {
+ struct xkb_level *leveli;
+
+ log_vrb(info->keymap->ctx, 1,
+ "Type \"%s\" has %d levels, but %s has %d levels; "
+ "Ignoring extra symbols\n",
+ xkb_atom_text(keymap->ctx, type->name), type->num_levels,
+ KeyInfoText(info, keyi),
+ (int) darray_size(groupi->levels));
+
+ darray_foreach_from(leveli, groupi->levels, type->num_levels)
+ ClearLevelInfo(leveli);
+ }
+ darray_resize0(groupi->levels, type->num_levels);
+
+ key->groups[i].explicit_type = explicit_type;
+ key->groups[i].type = type;
+ }
+
+ /* Copy levels. */
+ darray_enumerate(i, groupi, keyi->groups) {
+ key->groups[i].levels = darray_mem(groupi->levels, 0);
+ darray_init(groupi->levels);
+ }
+
+ key->out_of_range_group_number = keyi->out_of_range_group_number;
+ key->out_of_range_group_action = keyi->out_of_range_group_action;
+
+ if (keyi->defined & KEY_FIELD_VMODMAP) {
+ key->vmodmap = keyi->vmodmap;
+ key->explicit |= EXPLICIT_VMODMAP;
+ }
+
+ if (keyi->repeat != KEY_REPEAT_UNDEFINED) {
+ key->repeats = (keyi->repeat == KEY_REPEAT_YES);
+ key->explicit |= EXPLICIT_REPEAT;
+ }
+
+ darray_foreach(groupi, keyi->groups) {
+ if (groupi->defined & GROUP_FIELD_ACTS) {
+ key->explicit |= EXPLICIT_INTERP;
+ break;
+ }
+ }
+
+ return true;
+}
+
+static bool
+CopyModMapDef(SymbolsInfo *info, ModMapEntry *entry)
+{
+ struct xkb_key *key;
+ struct xkb_keymap *keymap = info->keymap;
+
+ if (!entry->haveSymbol) {
+ key = XkbKeyByName(keymap, entry->u.keyName, true);
+ if (!key) {
+ log_vrb(info->keymap->ctx, 5,
+ "Key %s not found in keycodes; "
+ "Modifier map entry for %s not updated\n",
+ KeyNameText(keymap->ctx, entry->u.keyName),
+ ModIndexText(info->keymap, entry->modifier));
+ return false;
+ }
+ }
+ else {
+ key = FindKeyForSymbol(keymap, entry->u.keySym);
+ if (!key) {
+ log_vrb(info->keymap->ctx, 5,
+ "Key \"%s\" not found in symbol map; "
+ "Modifier map entry for %s not updated\n",
+ KeysymText(info->keymap->ctx, entry->u.keySym),
+ ModIndexText(info->keymap, entry->modifier));
+ return false;
+ }
+ }
+
+ key->modmap |= (1 << entry->modifier);
+ return true;
+}
+
+static bool
+CopySymbolsToKeymap(struct xkb_keymap *keymap, SymbolsInfo *info)
+{
+ KeyInfo *keyi;
+ ModMapEntry *mm;
+ struct xkb_key *key;
+
+ keymap->symbols_section_name = strdup_safe(info->name);
+
+ keymap->num_group_names = darray_size(info->group_names);
+ keymap->group_names = darray_mem(info->group_names, 0);
+ darray_init(info->group_names);
+
+ darray_foreach(keyi, info->keys)
+ if (!CopySymbolsDef(info, keyi))
+ info->errorCount++;
+
+ if (xkb_context_get_log_verbosity(keymap->ctx) > 3) {
+ xkb_foreach_key(key, keymap) {
+ if (key->name == XKB_ATOM_NONE)
+ continue;
+
+ if (key->num_groups < 1)
+ log_info(keymap->ctx,
+ "No symbols defined for %s\n",
+ KeyNameText(keymap->ctx, key->name));
+ }
+ }
+
+ darray_foreach(mm, info->modMaps)
+ if (!CopyModMapDef(info, mm))
+ info->errorCount++;
+
+ /* XXX: If we don't ignore errorCount, things break. */
+ return true;
+}
+
+bool
+CompileSymbols(XkbFile *file, struct xkb_keymap *keymap,
+ enum merge_mode merge)
+{
+ SymbolsInfo info;
+ ActionsInfo *actions;
+
+ actions = NewActionsInfo();
+ if (!actions)
+ return false;
+
+ InitSymbolsInfo(&info, keymap, actions);
+ info.default_key.merge = merge;
+
+ HandleSymbolsFile(&info, file, merge);
+
+ if (darray_empty(info.keys))
+ goto err_info;
+
+ if (info.errorCount != 0)
+ goto err_info;
+
+ if (!CopySymbolsToKeymap(keymap, &info))
+ goto err_info;
+
+ ClearSymbolsInfo(&info);
+ FreeActionsInfo(actions);
+ return true;
+
+err_info:
+ FreeActionsInfo(actions);
+ ClearSymbolsInfo(&info);
+ return false;
+}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/types.c b/src/3rdparty/xkbcommon/src/xkbcomp/types.c
new file mode 100644
index 0000000000..1eb1b73205
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/types.c
@@ -0,0 +1,842 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#include "xkbcomp-priv.h"
+#include "text.h"
+#include "vmod.h"
+#include "expr.h"
+#include "include.h"
+
+/*
+ * The xkb_types section
+ * =====================
+ * This section is the second to be processesed, after xkb_keycodes.
+ * However, it is completely independent and could have been the first
+ * to be processed (it does not refer to specific keys as specified in
+ * the xkb_keycodes section).
+ *
+ * This section defines key types, which, given a key and a keyboard
+ * state (i.e. modifier state and group), determine the shift level to
+ * be used in translating the key to keysyms. These types are assigned
+ * to each group in each key, in the xkb_symbols section.
+ *
+ * Key types are called this way because, in a way, they really describe
+ * the "type" of the key (or more correctly, a specific group of the
+ * key). For example, an ordinary keymap will provide a type called
+ * "KEYPAD", which consists of two levels, with the second level being
+ * chosen according to the state of the Num Lock (or Shift) modifiers.
+ * Another example is a type called "ONE_LEVEL", which is usually
+ * assigned to keys such as Escape; these have just one level and are
+ * not affected by the modifier state. Yet more common examples are
+ * "TWO_LEVEL" (with Shift choosing the second level), "ALPHABETIC"
+ * (where Caps Lock may also choose the second level), etc.
+ *
+ * Type definitions
+ * ----------------
+ * Statements of the form:
+ * type "FOUR_LEVEL" { ... }
+ *
+ * The above would create a new type named "FOUR_LEVEL".
+ * The body of the definition may include statements of the following
+ * forms:
+ *
+ * - level_name statements (mandatory for each level in the type):
+ * level_name[Level1] = "Base";
+ *
+ * Gives each level in this type a descriptive name. It isn't used
+ * for any thing.
+ * Note: A level may be specified as Level[1-8] or just a number (can
+ * be more than 8).
+ *
+ * - modifiers statement (mandatory, should be specified only once):
+ * modifiers = Shift+Lock+LevelThree;
+ *
+ * A mask of real and virtual modifiers. These are the only modifiers
+ * being considered when matching the modifier state against the type.
+ * The other modifiers, whether active or not, are masked out in the
+ * calculation.
+ *
+ * - map entry statements (should have at least as many mappings as there
+ * are levels in the type):
+ * map[Shift+LevelThree] = Level4;
+ *
+ * If the active modifiers, masked with the type's modifiers (as stated
+ * above), match (i.e. equal) the modifiers inside the map[] statement,
+ * then the level in the right hand side is chosen. For example, in the
+ * above, if in the current keyboard state the Shift and LevelThree
+ * modifiers are active, while the Lock modifier is not, then the
+ * keysym(s) in the 4th level of the group will be returned to the
+ * user.
+ *
+ * - preserve statements:
+ * map[Shift+Lock+LevelThree] = Level5;
+ * preserve[Shift+Lock+LevelThree] = Lock;
+ *
+ * When a map entry matches the active modifiers and the level it
+ * specified is chosen, then these modifiers are said to be "consumed";
+ * for example, in a simple US keymap where the "g" key is assigned an
+ * ordinary ALPHABETIC key type, if the Lock (Caps Lock) modifier is
+ * active and the key is pressed, then a "G" keysym is produced (as
+ * opposed to lower-case "g"). This is because the type definition has
+ * a map entry like the following:
+ * map[Lock] = Level2;
+ * And as such the Lock modifier is consumed. This information is
+ * relevant for applications which further process the modifiers,
+ * since by then the consumed modifiers have already "done their part"
+ * and should be masked out.
+ *
+ * However, sometimes even if a modifier is actually used to choose
+ * the shift level (as Lock above), it should *not* be reported as
+ * consumed, for various reasons. In this case, a preserve[] statement
+ * can be used to augment the map entry. The modifiers inside the square
+ * brackets should match one of the map[] statements in the type. The
+ * right hand side should consists of modifiers from the left hand
+ * side; these modifiers are then "preserved" and not reported as
+ * consumed.
+ *
+ * Virtual modifier statements
+ * ---------------------------
+ * Statements of the form:
+ * virtual_modifiers LControl;
+ *
+ * Can appear in the xkb_types, xkb_compat, xkb_symbols sections.
+ * TODO
+ *
+ * Effect on keymap
+ * ----------------
+ * After all of the xkb_types sections have been compiled, the following
+ * members of struct xkb_keymap are finalized:
+ * struct xkb_key_type *types;
+ * unsigned int num_types;
+ * char *types_section_name;
+ * TODO: virtual modifiers.
+ */
+
+enum type_field {
+ TYPE_FIELD_MASK = (1 << 0),
+ TYPE_FIELD_MAP = (1 << 1),
+ TYPE_FIELD_PRESERVE = (1 << 2),
+ TYPE_FIELD_LEVEL_NAME = (1 << 3),
+};
+
+typedef struct {
+ enum type_field defined;
+ enum merge_mode merge;
+
+ xkb_atom_t name;
+ xkb_mod_mask_t mods;
+ xkb_level_index_t num_levels;
+ darray(struct xkb_key_type_entry) entries;
+ darray(xkb_atom_t) level_names;
+} KeyTypeInfo;
+
+typedef struct {
+ char *name;
+ int errorCount;
+
+ darray(KeyTypeInfo) types;
+ struct xkb_keymap *keymap;
+} KeyTypesInfo;
+
+/***====================================================================***/
+
+static inline const char *
+MapEntryTxt(KeyTypesInfo *info, struct xkb_key_type_entry *entry)
+{
+ return ModMaskText(info->keymap, entry->mods.mods);
+}
+
+static inline const char *
+TypeTxt(KeyTypesInfo *info, KeyTypeInfo *type)
+{
+ return xkb_atom_text(info->keymap->ctx, type->name);
+}
+
+static inline const char *
+TypeMaskTxt(KeyTypesInfo *info, KeyTypeInfo *type)
+{
+ return ModMaskText(info->keymap, type->mods);
+}
+
+static inline bool
+ReportTypeShouldBeArray(KeyTypesInfo *info, KeyTypeInfo *type,
+ const char *field)
+{
+ return ReportShouldBeArray(info->keymap->ctx, "key type", field,
+ TypeTxt(info, type));
+}
+
+static inline bool
+ReportTypeBadType(KeyTypesInfo *info, KeyTypeInfo *type,
+ const char *field, const char *wanted)
+{
+ return ReportBadType(info->keymap->ctx, "key type", field,
+ TypeTxt(info, type), wanted);
+}
+
+static inline bool
+ReportTypeBadWidth(KeyTypesInfo *info, const char *type, int has, int needs)
+{
+ log_err(info->keymap->ctx,
+ "Key type \"%s\" has %d levels, must have %d; "
+ "Illegal type definition ignored\n",
+ type, has, needs);
+ return false;
+}
+
+/***====================================================================***/
+
+static void
+InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_keymap *keymap)
+{
+ memset(info, 0, sizeof(*info));
+ info->keymap = keymap;
+}
+
+static void
+ClearKeyTypeInfo(KeyTypeInfo *type)
+{
+ darray_free(type->entries);
+ darray_free(type->level_names);
+}
+
+static void
+ClearKeyTypesInfo(KeyTypesInfo *info)
+{
+ free(info->name);
+ darray_free(info->types);
+}
+
+static KeyTypeInfo *
+FindMatchingKeyType(KeyTypesInfo *info, xkb_atom_t name)
+{
+ KeyTypeInfo *old;
+
+ darray_foreach(old, info->types)
+ if (old->name == name)
+ return old;
+
+ return NULL;
+}
+
+static bool
+AddKeyType(KeyTypesInfo *info, KeyTypeInfo *new, bool same_file)
+{
+ KeyTypeInfo *old;
+ const int verbosity = xkb_context_get_log_verbosity(info->keymap->ctx);
+
+ old = FindMatchingKeyType(info, new->name);
+ if (old) {
+ if (new->merge == MERGE_REPLACE || new->merge == MERGE_OVERRIDE) {
+ if ((same_file && verbosity > 0) || verbosity > 9) {
+ log_warn(info->keymap->ctx,
+ "Multiple definitions of the %s key type; "
+ "Earlier definition ignored\n",
+ xkb_atom_text(info->keymap->ctx, new->name));
+ }
+
+ ClearKeyTypeInfo(old);
+ *old = *new;
+ darray_init(new->entries);
+ darray_init(new->level_names);
+ return true;
+ }
+
+ if (same_file)
+ log_vrb(info->keymap->ctx, 4,
+ "Multiple definitions of the %s key type; "
+ "Later definition ignored\n",
+ xkb_atom_text(info->keymap->ctx, new->name));
+
+ ClearKeyTypeInfo(new);
+ return true;
+ }
+
+ darray_append(info->types, *new);
+ return true;
+}
+
+/***====================================================================***/
+
+static void
+MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
+ enum merge_mode merge)
+{
+ KeyTypeInfo *type;
+
+ if (from->errorCount > 0) {
+ into->errorCount += from->errorCount;
+ return;
+ }
+
+ if (into->name == NULL) {
+ into->name = from->name;
+ from->name = NULL;
+ }
+
+ darray_foreach(type, from->types) {
+ type->merge = (merge == MERGE_DEFAULT ? type->merge : merge);
+ if (!AddKeyType(into, type, false))
+ into->errorCount++;
+ }
+}
+
+static void
+HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge);
+
+static bool
+HandleIncludeKeyTypes(KeyTypesInfo *info, IncludeStmt *include)
+{
+ KeyTypesInfo included;
+
+ InitKeyTypesInfo(&included, info->keymap);
+ included.name = include->stmt;
+ include->stmt = NULL;
+
+ for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) {
+ KeyTypesInfo next_incl;
+ XkbFile *file;
+
+ file = ProcessIncludeFile(info->keymap->ctx, stmt, FILE_TYPE_TYPES);
+ if (!file) {
+ info->errorCount += 10;
+ ClearKeyTypesInfo(&included);
+ return false;
+ }
+
+ InitKeyTypesInfo(&next_incl, info->keymap);
+
+ HandleKeyTypesFile(&next_incl, file, stmt->merge);
+
+ MergeIncludedKeyTypes(&included, &next_incl, stmt->merge);
+
+ ClearKeyTypesInfo(&next_incl);
+ FreeXkbFile(file);
+ }
+
+ MergeIncludedKeyTypes(info, &included, include->merge);
+ ClearKeyTypesInfo(&included);
+
+ return (info->errorCount == 0);
+}
+
+/***====================================================================***/
+
+static bool
+SetModifiers(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
+ ExprDef *value)
+{
+ xkb_mod_mask_t mods;
+
+ if (arrayNdx)
+ log_warn(info->keymap->ctx,
+ "The modifiers field of a key type is not an array; "
+ "Illegal array subscript ignored\n");
+
+ if (!ExprResolveModMask(info->keymap, value, MOD_BOTH, &mods)) {
+ log_err(info->keymap->ctx,
+ "Key type mask field must be a modifier mask; "
+ "Key type definition ignored\n");
+ return false;
+ }
+
+ if (type->defined & TYPE_FIELD_MASK) {
+ log_warn(info->keymap->ctx,
+ "Multiple modifier mask definitions for key type %s; "
+ "Using %s, ignoring %s\n",
+ xkb_atom_text(info->keymap->ctx, type->name),
+ TypeMaskTxt(info, type),
+ ModMaskText(info->keymap, mods));
+ return false;
+ }
+
+ type->mods = mods;
+ return true;
+}
+
+/***====================================================================***/
+
+static struct xkb_key_type_entry *
+FindMatchingMapEntry(KeyTypeInfo *type, xkb_mod_mask_t mods)
+{
+ struct xkb_key_type_entry *entry;
+
+ darray_foreach(entry, type->entries)
+ if (entry->mods.mods == mods)
+ return entry;
+
+ return NULL;
+}
+
+static bool
+AddMapEntry(KeyTypesInfo *info, KeyTypeInfo *type,
+ struct xkb_key_type_entry *new, bool clobber, bool report)
+{
+ struct xkb_key_type_entry *old;
+
+ old = FindMatchingMapEntry(type, new->mods.mods);
+ if (old) {
+ if (report && old->level != new->level) {
+ log_warn(info->keymap->ctx,
+ "Multiple map entries for %s in %s; "
+ "Using %d, ignoring %d\n",
+ MapEntryTxt(info, new), TypeTxt(info, type),
+ (clobber ? new->level : old->level) + 1,
+ (clobber ? old->level : new->level) + 1);
+ }
+ else {
+ log_vrb(info->keymap->ctx, 10,
+ "Multiple occurrences of map[%s]= %d in %s; Ignored\n",
+ MapEntryTxt(info, new), new->level + 1,
+ TypeTxt(info, type));
+ return true;
+ }
+
+ if (clobber) {
+ if (new->level >= type->num_levels)
+ type->num_levels = new->level + 1;
+ old->level = new->level;
+ }
+
+ return true;
+ }
+
+ if (new->level >= type->num_levels)
+ type->num_levels = new->level + 1;
+
+ darray_append(type->entries, *new);
+ return true;
+}
+
+static bool
+SetMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
+ ExprDef *value)
+{
+ struct xkb_key_type_entry entry;
+
+ if (arrayNdx == NULL)
+ return ReportTypeShouldBeArray(info, type, "map entry");
+
+ if (!ExprResolveModMask(info->keymap, arrayNdx, MOD_BOTH, &entry.mods.mods))
+ return ReportTypeBadType(info, type, "map entry", "modifier mask");
+
+ if (entry.mods.mods & (~type->mods)) {
+ log_vrb(info->keymap->ctx, 1,
+ "Map entry for unused modifiers in %s; "
+ "Using %s instead of %s\n",
+ TypeTxt(info, type),
+ ModMaskText(info->keymap, entry.mods.mods & type->mods),
+ MapEntryTxt(info, &entry));
+ entry.mods.mods &= type->mods;
+ }
+
+ if (!ExprResolveLevel(info->keymap->ctx, value, &entry.level)) {
+ log_err(info->keymap->ctx,
+ "Level specifications in a key type must be integer; "
+ "Ignoring malformed level specification\n");
+ return false;
+ }
+
+ entry.preserve.mods = 0;
+
+ return AddMapEntry(info, type, &entry, true, true);
+}
+
+/***====================================================================***/
+
+static bool
+AddPreserve(KeyTypesInfo *info, KeyTypeInfo *type,
+ xkb_mod_mask_t mods, xkb_mod_mask_t preserve_mods)
+{
+ struct xkb_key_type_entry *entry;
+ struct xkb_key_type_entry new;
+
+ darray_foreach(entry, type->entries) {
+ if (entry->mods.mods != mods)
+ continue;
+
+ /* Map exists without previous preserve (or "None"); override. */
+ if (entry->preserve.mods == 0) {
+ entry->preserve.mods = preserve_mods;
+ return true;
+ }
+
+ /* Map exists with same preserve; do nothing. */
+ if (entry->preserve.mods == preserve_mods) {
+ log_vrb(info->keymap->ctx, 10,
+ "Identical definitions for preserve[%s] in %s; "
+ "Ignored\n",
+ ModMaskText(info->keymap, mods),
+ TypeTxt(info, type));
+ return true;
+ }
+
+ /* Map exists with different preserve; latter wins. */
+ log_vrb(info->keymap->ctx, 1,
+ "Multiple definitions for preserve[%s] in %s; "
+ "Using %s, ignoring %s\n",
+ ModMaskText(info->keymap, mods),
+ TypeTxt(info, type),
+ ModMaskText(info->keymap, preserve_mods),
+ ModMaskText(info->keymap, entry->preserve.mods));
+
+ entry->preserve.mods = preserve_mods;
+ return true;
+ }
+
+ /*
+ * Map does not exist, i.e. preserve[] came before map[].
+ * Create a map with the specified mask mapping to Level1. The level
+ * may be overridden later with an explicit map[] statement.
+ */
+ new.level = 0;
+ new.mods.mods = mods;
+ new.preserve.mods = preserve_mods;
+ darray_append(type->entries, new);
+ return true;
+}
+
+static bool
+SetPreserve(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
+ ExprDef *value)
+{
+ xkb_mod_mask_t mods, preserve_mods;
+
+ if (arrayNdx == NULL)
+ return ReportTypeShouldBeArray(info, type, "preserve entry");
+
+ if (!ExprResolveModMask(info->keymap, arrayNdx, MOD_BOTH, &mods))
+ return ReportTypeBadType(info, type, "preserve entry",
+ "modifier mask");
+
+ if (mods & ~type->mods) {
+ const char *before, *after;
+
+ before = ModMaskText(info->keymap, mods);
+ mods &= type->mods;
+ after = ModMaskText(info->keymap, mods);
+
+ log_vrb(info->keymap->ctx, 1,
+ "Preserve for modifiers not used by the %s type; "
+ "Index %s converted to %s\n",
+ TypeTxt(info, type), before, after);
+ }
+
+ if (!ExprResolveModMask(info->keymap, value, MOD_BOTH, &preserve_mods)) {
+ log_err(info->keymap->ctx,
+ "Preserve value in a key type is not a modifier mask; "
+ "Ignoring preserve[%s] in type %s\n",
+ ModMaskText(info->keymap, mods),
+ TypeTxt(info, type));
+ return false;
+ }
+
+ if (preserve_mods & ~mods) {
+ const char *before, *after;
+
+ before = ModMaskText(info->keymap, preserve_mods);
+ preserve_mods &= mods;
+ after = ModMaskText(info->keymap, preserve_mods);
+
+ log_vrb(info->keymap->ctx, 1,
+ "Illegal value for preserve[%s] in type %s; "
+ "Converted %s to %s\n",
+ ModMaskText(info->keymap, mods),
+ TypeTxt(info, type), before, after);
+ }
+
+ return AddPreserve(info, type, mods, preserve_mods);
+}
+
+/***====================================================================***/
+
+static bool
+AddLevelName(KeyTypesInfo *info, KeyTypeInfo *type,
+ xkb_level_index_t level, xkb_atom_t name, bool clobber)
+{
+ /* New name. */
+ if (level >= darray_size(type->level_names)) {
+ darray_resize0(type->level_names, level + 1);
+ goto finish;
+ }
+
+ /* Same level, same name. */
+ if (darray_item(type->level_names, level) == name) {
+ log_vrb(info->keymap->ctx, 10,
+ "Duplicate names for level %d of key type %s; Ignored\n",
+ level + 1, TypeTxt(info, type));
+ return true;
+ }
+
+ /* Same level, different name. */
+ if (darray_item(type->level_names, level) != XKB_ATOM_NONE) {
+ const char *old, *new;
+ old = xkb_atom_text(info->keymap->ctx,
+ darray_item(type->level_names, level));
+ new = xkb_atom_text(info->keymap->ctx, name);
+ log_vrb(info->keymap->ctx, 1,
+ "Multiple names for level %d of key type %s; "
+ "Using %s, ignoring %s\n",
+ level + 1, TypeTxt(info, type),
+ (clobber ? new : old), (clobber ? old : new));
+
+ if (!clobber)
+ return true;
+ }
+
+ /* XXX: What about different level, same name? */
+
+finish:
+ darray_item(type->level_names, level) = name;
+ return true;
+}
+
+static bool
+SetLevelName(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
+ ExprDef *value)
+{
+ xkb_level_index_t level;
+ xkb_atom_t level_name;
+ struct xkb_context *ctx = info->keymap->ctx;
+
+ if (arrayNdx == NULL)
+ return ReportTypeShouldBeArray(info, type, "level name");
+
+ if (!ExprResolveLevel(ctx, arrayNdx, &level))
+ return ReportTypeBadType(info, type, "level name", "integer");
+
+ if (!ExprResolveString(ctx, value, &level_name)) {
+ log_err(info->keymap->ctx,
+ "Non-string name for level %d in key type %s; "
+ "Ignoring illegal level name definition\n",
+ level + 1, xkb_atom_text(ctx, type->name));
+ return false;
+ }
+
+ return AddLevelName(info, type, level, level_name, true);
+}
+
+/***====================================================================***/
+
+static bool
+SetKeyTypeField(KeyTypesInfo *info, KeyTypeInfo *type,
+ const char *field, ExprDef *arrayNdx, ExprDef *value)
+{
+ bool ok = false;
+ enum type_field type_field = 0;
+
+ if (istreq(field, "modifiers")) {
+ type_field = TYPE_FIELD_MASK;
+ ok = SetModifiers(info, type, arrayNdx, value);
+ }
+ else if (istreq(field, "map")) {
+ type_field = TYPE_FIELD_MAP;
+ ok = SetMapEntry(info, type, arrayNdx, value);
+ }
+ else if (istreq(field, "preserve")) {
+ type_field = TYPE_FIELD_PRESERVE;
+ ok = SetPreserve(info, type, arrayNdx, value);
+ }
+ else if (istreq(field, "levelname") || istreq(field, "level_name")) {
+ type_field = TYPE_FIELD_LEVEL_NAME;
+ ok = SetLevelName(info, type, arrayNdx, value);
+ } else {
+ log_err(info->keymap->ctx,
+ "Unknown field %s in key type %s; Definition ignored\n",
+ field, TypeTxt(info, type));
+ }
+
+ type->defined |= type_field;
+ return ok;
+}
+
+static bool
+HandleKeyTypeBody(KeyTypesInfo *info, VarDef *def, KeyTypeInfo *type)
+{
+ bool ok = true;
+ const char *elem, *field;
+ ExprDef *arrayNdx;
+
+ for (; def; def = (VarDef *) def->common.next) {
+ ok = ExprResolveLhs(info->keymap->ctx, def->name, &elem, &field,
+ &arrayNdx);
+ if (!ok)
+ continue;
+
+ if (elem && istreq(elem, "type")) {
+ log_err(info->keymap->ctx,
+ "Support for changing the default type has been removed; "
+ "Statement ignored\n");
+ continue;
+ }
+
+ ok = SetKeyTypeField(info, type, field, arrayNdx, def->value);
+ }
+
+ return ok;
+}
+
+static bool
+HandleKeyTypeDef(KeyTypesInfo *info, KeyTypeDef *def, enum merge_mode merge)
+{
+ KeyTypeInfo type = {
+ .defined = 0,
+ .merge = (def->merge == MERGE_DEFAULT ? merge : def->merge),
+ .name = def->name,
+ .mods = 0,
+ .num_levels = 1,
+ .entries = darray_new(),
+ .level_names = darray_new(),
+ };
+
+ if (!HandleKeyTypeBody(info, def->body, &type)) {
+ info->errorCount++;
+ return false;
+ }
+
+ if (!AddKeyType(info, &type, true)) {
+ info->errorCount++;
+ return false;
+ }
+
+ return true;
+}
+
+static void
+HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge)
+{
+ bool ok;
+
+ free(info->name);
+ info->name = strdup_safe(file->name);
+
+ for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) {
+ switch (stmt->type) {
+ case STMT_INCLUDE:
+ ok = HandleIncludeKeyTypes(info, (IncludeStmt *) stmt);
+ break;
+ case STMT_TYPE:
+ ok = HandleKeyTypeDef(info, (KeyTypeDef *) stmt, merge);
+ break;
+ case STMT_VAR:
+ log_err(info->keymap->ctx,
+ "Support for changing the default type has been removed; "
+ "Statement ignored\n");
+ ok = true;
+ break;
+ case STMT_VMOD:
+ ok = HandleVModDef(info->keymap, (VModDef *) stmt);
+ break;
+ default:
+ log_err(info->keymap->ctx,
+ "Key type files may not include other declarations; "
+ "Ignoring %s\n", stmt_type_to_string(stmt->type));
+ ok = false;
+ break;
+ }
+
+ if (!ok)
+ info->errorCount++;
+
+ if (info->errorCount > 10) {
+ log_err(info->keymap->ctx,
+ "Abandoning keytypes file \"%s\"\n", file->topName);
+ break;
+ }
+ }
+}
+
+/***====================================================================***/
+
+static bool
+CopyKeyTypesToKeymap(struct xkb_keymap *keymap, KeyTypesInfo *info)
+{
+ keymap->types_section_name = strdup_safe(info->name);
+
+ keymap->num_types = darray_size(info->types);
+ if (keymap->num_types == 0)
+ keymap->num_types = 1;
+
+ keymap->types = calloc(keymap->num_types, sizeof(*keymap->types));
+
+ /*
+ * If no types were specified, a default unnamed one-level type is
+ * used for all keys.
+ */
+ if (darray_empty(info->types)) {
+ struct xkb_key_type *type = &keymap->types[0];
+
+ type->mods.mods = 0;
+ type->num_levels = 1;
+ type->entries = NULL;
+ type->num_entries = 0;
+ type->name = xkb_atom_intern(keymap->ctx, "default");
+ type->level_names = NULL;
+
+ return true;
+ }
+
+ for (unsigned i = 0; i < keymap->num_types; i++) {
+ KeyTypeInfo *def = &darray_item(info->types, i);
+ struct xkb_key_type *type = &keymap->types[i];
+
+ type->mods.mods = def->mods;
+ type->num_levels = def->num_levels;
+ type->entries = darray_mem(def->entries, 0);
+ type->num_entries = darray_size(def->entries);
+ darray_init(def->entries);
+ type->name = def->name;
+ type->level_names = darray_mem(def->level_names, 0);
+ darray_init(def->level_names);
+ }
+
+ return true;
+}
+
+/***====================================================================***/
+
+bool
+CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap,
+ enum merge_mode merge)
+{
+ KeyTypesInfo info;
+
+ InitKeyTypesInfo(&info, keymap);
+
+ HandleKeyTypesFile(&info, file, merge);
+ if (info.errorCount != 0)
+ goto err_info;
+
+ if (!CopyKeyTypesToKeymap(keymap, &info))
+ goto err_info;
+
+ ClearKeyTypesInfo(&info);
+ return true;
+
+err_info:
+ ClearKeyTypesInfo(&info);
+ return false;
+}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c
new file mode 100644
index 0000000000..206e1624e6
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c
@@ -0,0 +1,69 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#include "xkbcomp-priv.h"
+#include "text.h"
+#include "expr.h"
+#include "vmod.h"
+
+bool
+HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt)
+{
+ xkb_mod_index_t i;
+ const struct xkb_mod *mod;
+ struct xkb_mod new;
+
+ if (stmt->value)
+ log_err(keymap->ctx,
+ "Support for setting a value in a virtual_modifiers statement has been removed; "
+ "Value ignored\n");
+
+ darray_enumerate(i, mod, keymap->mods) {
+ if (mod->name == stmt->name) {
+ if (mod->type == MOD_VIRT)
+ return true;
+
+ log_err(keymap->ctx,
+ "Can't add a virtual modifier named \"%s\"; "
+ "there is already a non-virtual modifier with this name! Ignored\n",
+ xkb_atom_text(keymap->ctx, mod->name));
+ return false;
+ }
+ }
+
+ if (darray_size(keymap->mods) >= XKB_MAX_MODS) {
+ log_err(keymap->ctx,
+ "Too many modifiers defined (maximum %d)\n",
+ XKB_MAX_MODS);
+ return false;
+ }
+
+ new.name = stmt->name;
+ new.mapping = 0;
+ new.type = MOD_VIRT;
+ darray_append(keymap->mods, new);
+ return true;
+}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h
new file mode 100644
index 0000000000..991550735f
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h
@@ -0,0 +1,33 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#ifndef XKBCOMP_VMOD_H
+#define XKBCOMP_VMOD_H
+
+bool
+HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt);
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h b/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h
new file mode 100644
index 0000000000..4d421b5f2f
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h
@@ -0,0 +1,130 @@
+/************************************************************
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+#ifndef XKBCOMP_PRIV_H
+#define XKBCOMP_PRIV_H
+
+#include "keymap.h"
+#include "ast.h"
+
+struct xkb_component_names {
+ char *keycodes;
+ char *types;
+ char *compat;
+ char *symbols;
+};
+
+char *
+text_v1_keymap_get_as_string(struct xkb_keymap *keymap);
+
+XkbFile *
+XkbParseFile(struct xkb_context *ctx, FILE *file,
+ const char *file_name, const char *map);
+
+XkbFile *
+XkbParseString(struct xkb_context *ctx, const char *string,
+ const char *file_name);
+
+XkbFile *
+XkbParseBuffer(struct xkb_context *ctx, char *buf, size_t length,
+ const char *file_name);
+
+void
+FreeXkbFile(XkbFile *file);
+
+XkbFile *
+XkbFileFromComponents(struct xkb_context *ctx,
+ const struct xkb_component_names *kkctgs);
+
+bool
+CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap,
+ enum merge_mode merge);
+
+bool
+CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap,
+ enum merge_mode merge);
+
+bool
+CompileCompatMap(XkbFile *file, struct xkb_keymap *keymap,
+ enum merge_mode merge);
+
+bool
+CompileSymbols(XkbFile *file, struct xkb_keymap *keymap,
+ enum merge_mode merge);
+
+bool
+CompileKeymap(XkbFile *file, struct xkb_keymap *keymap,
+ enum merge_mode merge);
+
+bool
+LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn);
+
+/***====================================================================***/
+
+static inline bool
+ReportNotArray(struct xkb_context *ctx, const char *type, const char *field,
+ const char *name)
+{
+ log_err(ctx,
+ "The %s %s field is not an array; "
+ "Ignoring illegal assignment in %s\n",
+ type, field, name);
+ return false;
+}
+
+static inline bool
+ReportShouldBeArray(struct xkb_context *ctx, const char *type,
+ const char *field, const char *name)
+{
+ log_err(ctx,
+ "Missing subscript for %s %s; "
+ "Ignoring illegal assignment in %s\n",
+ type, field, name);
+ return false;
+}
+
+static inline bool
+ReportBadType(struct xkb_context *ctx, const char *type, const char *field,
+ const char *name, const char *wanted)
+{
+ log_err(ctx, "The %s %s field must be a %s; "
+ "Ignoring illegal assignment in %s\n",
+ type, field, wanted, name);
+ return false;
+}
+
+static inline bool
+ReportBadField(struct xkb_context *ctx, const char *type, const char *field,
+ const char *name)
+{
+ log_err(ctx,
+ "Unknown %s field %s in %s; "
+ "Ignoring assignment to unknown field in %s\n",
+ type, field, name, name);
+ return false;
+}
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c b/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c
new file mode 100644
index 0000000000..b9a1b5ffa6
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright © 2009 Dan Nicholson
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dan Nicholson <dbn.lists@gmail.com>
+ * Ran Benita <ran234@gmail.com>
+ * Daniel Stone <daniel@fooishbar.org>
+ */
+
+#include "xkbcomp-priv.h"
+#include "rules.h"
+
+static bool
+compile_keymap_file(struct xkb_keymap *keymap, XkbFile *file)
+{
+ if (file->file_type != FILE_TYPE_KEYMAP) {
+ log_err(keymap->ctx,
+ "Cannot compile a %s file alone into a keymap\n",
+ xkb_file_type_to_string(file->file_type));
+ return false;
+ }
+
+ if (!CompileKeymap(file, keymap, MERGE_OVERRIDE)) {
+ log_err(keymap->ctx,
+ "Failed to compile keymap\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+text_v1_keymap_new_from_names(struct xkb_keymap *keymap,
+ const struct xkb_rule_names *rmlvo)
+{
+ bool ok;
+ struct xkb_component_names kccgst;
+ XkbFile *file;
+
+ log_dbg(keymap->ctx,
+ "Compiling from RMLVO: rules '%s', model '%s', layout '%s', "
+ "variant '%s', options '%s'\n",
+ rmlvo->rules, rmlvo->model, rmlvo->layout, rmlvo->variant,
+ rmlvo->options);
+
+ ok = xkb_components_from_rules(keymap->ctx, rmlvo, &kccgst);
+ if (!ok) {
+ log_err(keymap->ctx,
+ "Couldn't look up rules '%s', model '%s', layout '%s', "
+ "variant '%s', options '%s'\n",
+ rmlvo->rules, rmlvo->model, rmlvo->layout, rmlvo->variant,
+ rmlvo->options);
+ return false;
+ }
+
+ log_dbg(keymap->ctx,
+ "Compiling from KcCGST: keycodes '%s', types '%s', "
+ "compat '%s', symbols '%s'\n",
+ kccgst.keycodes, kccgst.types, kccgst.compat, kccgst.symbols);
+
+ file = XkbFileFromComponents(keymap->ctx, &kccgst);
+
+ free(kccgst.keycodes);
+ free(kccgst.types);
+ free(kccgst.compat);
+ free(kccgst.symbols);
+
+ if (!file) {
+ log_err(keymap->ctx,
+ "Failed to generate parsed XKB file from components\n");
+ return false;
+ }
+
+ ok = compile_keymap_file(keymap, file);
+ FreeXkbFile(file);
+ return ok;
+}
+
+static bool
+text_v1_keymap_new_from_string(struct xkb_keymap *keymap, const char *string)
+{
+ bool ok;
+ XkbFile *xkb_file;
+
+ xkb_file = XkbParseString(keymap->ctx, string, "(input string)");
+ if (!xkb_file) {
+ log_err(keymap->ctx, "Failed to parse input xkb string\n");
+ return NULL;
+ }
+
+ ok = compile_keymap_file(keymap, xkb_file);
+ FreeXkbFile(xkb_file);
+ return ok;
+}
+
+static bool
+text_v1_keymap_new_from_buffer(struct xkb_keymap *keymap,
+ const char *buffer, size_t length)
+{
+ bool ok;
+ XkbFile *xkb_file;
+ char *buf;
+
+ buf = malloc(length + 2);
+ if (!buf) {
+ log_err(keymap->ctx, "Cannot allocate memory for keymap\n");
+ return NULL;
+ }
+
+ /* yy_scan_buffer requires two terminating zero bytes */
+ memcpy(buf, buffer, length);
+ buf[length] = 0;
+ buf[length + 1] = 0;
+
+ xkb_file = XkbParseBuffer(keymap->ctx, buf, length + 2, "input");
+ if (!xkb_file) {
+ log_err(keymap->ctx, "Failed to parse input xkb file\n");
+ free(buf);
+ return NULL;
+ }
+
+ ok = compile_keymap_file(keymap, xkb_file);
+ FreeXkbFile(xkb_file);
+ free(buf);
+ return ok;
+}
+
+static bool
+text_v1_keymap_new_from_file(struct xkb_keymap *keymap, FILE *file)
+{
+ bool ok;
+ XkbFile *xkb_file;
+
+ xkb_file = XkbParseFile(keymap->ctx, file, "(unknown file)", NULL);
+ if (!xkb_file) {
+ log_err(keymap->ctx, "Failed to parse input xkb file\n");
+ return false;
+ }
+
+ ok = compile_keymap_file(keymap, xkb_file);
+ FreeXkbFile(xkb_file);
+ return ok;
+}
+
+const struct xkb_keymap_format_ops text_v1_keymap_format_ops = {
+ .keymap_new_from_names = text_v1_keymap_new_from_names,
+ .keymap_new_from_string = text_v1_keymap_new_from_string,
+ .keymap_new_from_buffer = text_v1_keymap_new_from_buffer,
+ .keymap_new_from_file = text_v1_keymap_new_from_file,
+ .keymap_get_as_string = text_v1_keymap_get_as_string,
+};