aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2020-11-24 20:52:35 -0800
committerElliott Hughes <enh@google.com>2021-01-25 10:21:07 -0800
commit91f38399c2ea2fca0a88d624fc72d203df0e108a (patch)
treefb7f4b6e3a06f43f823ea3e298418084e0a7175b
parentcda6b377eb5ce92136d53566702110c00b76cff8 (diff)
downloadlibxkbcommon-91f38399c2ea2fca0a88d624fc72d203df0e108a.tar.gz
Upgrade libxkbcommon to xkbcommon-1.0.3
1. Run meson build locally: meson config -Denable-x11=false -Denable-wayland=false -Denable-docs=false cd config ninja 2. Remove #defines for missing functions Test: make Change-Id: Ia109e0203569acb6380e2147c095fae57782fb72
-rw-r--r--.github/workflows/main.yml2
-rw-r--r--Android.bp4
-rw-r--r--METADATA8
-rw-r--r--NEWS19
-rw-r--r--bench/x11.c108
l---------[-rw-r--r--]config.h62
-rw-r--r--config/config.h61
-rw-r--r--config/libxkbcommon.so.0.0.0.p/parser.c (renamed from src/xkbcomp/parser.c)74
-rw-r--r--config/libxkbcommon.so.0.0.0.p/parser.h (renamed from src/xkbcomp/parser.h)0
-rw-r--r--meson.build29
-rw-r--r--src/context.c3
-rw-r--r--src/context.h3
-rw-r--r--src/x11/keymap.c47
-rw-r--r--src/x11/util.c55
-rw-r--r--src/xkbcomp/.gitignore2
-rw-r--r--src/xkbcomp/keymap-dump.c10
-rw-r--r--src/xkbcomp/parser.y4
-rw-r--r--test/data/keymaps/host.xkb630
-rw-r--r--test/data/keymaps/stringcomp.data8
-rw-r--r--test/data/symbols/garbage14
-rw-r--r--test/keymap.c56
-rwxr-xr-xtest/xkeyboard-config-test.py.in7
-rw-r--r--xkbcommon/xkbcommon.h12
23 files changed, 746 insertions, 472 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index eb4e74f..c864097 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -76,7 +76,7 @@ jobs:
Invoke-WebRequest -Uri https://github.com/lexxmark/winflexbison/releases/download/v2.5.23/win_flex_bison-2.5.23.zip -OutFile win_flex_bison.zip
Expand-Archive -Path win_flex_bison.zip -DestinationPath bin
Expand-Archive -Path ninja.zip -DestinationPath bin
- Write-Output ("::add-path::" + (Get-Location) + "./bin")
+ Write-Output ((Get-Location).ToString() + "./bin") | Out-File -Append -FilePath $env:GITHUB_PATH -Encoding utf8
- name: Setup
shell: cmd
run: |
diff --git a/Android.bp b/Android.bp
index 9524262..8101b6f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -14,6 +14,7 @@
cc_library_static {
srcs: [
+ "config/libxkbcommon.so.0.0.0.p/parser.c",
"src/compose/parser.c",
"src/compose/paths.c",
"src/compose/state.c",
@@ -27,7 +28,6 @@ cc_library_static {
"src/xkbcomp/keymap.c",
"src/xkbcomp/keymap-dump.c",
"src/xkbcomp/keywords.c",
- "src/xkbcomp/parser.c",
"src/xkbcomp/rules.c",
"src/xkbcomp/scanner.c",
"src/xkbcomp/symbols.c",
@@ -55,7 +55,7 @@ cc_library_static {
// Needed because libxkbcommon uses GNU extension asprintf().
"-D_GNU_SOURCE",
],
- local_include_dirs: ["src"],
+ local_include_dirs: ["src", "config/libxkbcommon.so.0.0.0.p"],
export_include_dirs: ["."],
vendor_available: true,
host_supported: true,
diff --git a/METADATA b/METADATA
index 255d91d..88a7c15 100644
--- a/METADATA
+++ b/METADATA
@@ -7,14 +7,14 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://github.com/xkbcommon/libxkbcommon/archive/xkbcommon-1.0.1.tar.gz"
+ value: "https://github.com/xkbcommon/libxkbcommon/archive/xkbcommon-1.0.3.tar.gz"
}
- version: "xkbcommon-1.0.1"
+ version: "xkbcommon-1.0.3"
# would be NOTICE save for test/evdev-scancodes.h
license_type: RESTRICTED
last_upgrade_date {
year: 2020
- month: 10
- day: 28
+ month: 11
+ day: 24
}
}
diff --git a/NEWS b/NEWS
index fee6a59..968f183 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,22 @@
+libxkbcommon 1.0.3 - 2020-11-23
+==================
+
+- Fix (hopefully) a segfault in xkb_x11_keymap_new_from_device() in some
+ unclear situation (bug introduced in 1.0.2).
+
+- Fix keymaps created with xkb_x11_keymap_new_from_device() don't have level
+ names (bug introduced in 0.8.0).
+
+libxkbcommon 1.0.2 - 2020-11-20
+==================
+
+- Fix a bug where a keysym that cannot be resolved in a keymap gets compiled to
+ a garbage keysym. Now it is set to XKB_KEY_NoSymbol instead.
+
+- Improve the speed of xkb_x11_keymap_new_from_device() on repeated calls in the
+ same xkb_context().
+
+
libxkbcommon 1.0.1 - 2020-09-11
==================
diff --git a/bench/x11.c b/bench/x11.c
new file mode 100644
index 0000000..2849385
--- /dev/null
+++ b/bench/x11.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright © 2020 Ran Benita <ran@unusedvar.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 "config.h"
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include <xcb/xkb.h>
+
+#include "xkbcommon/xkbcommon.h"
+#include "xkbcommon/xkbcommon-x11.h"
+
+#include "bench.h"
+
+#define BENCHMARK_ITERATIONS 2500
+
+int
+main(void)
+{
+ int ret;
+ xcb_connection_t *conn;
+ int32_t device_id;
+ struct xkb_context *ctx;
+ struct bench bench;
+ char *elapsed;
+
+ conn = xcb_connect(NULL, NULL);
+ if (!conn || xcb_connection_has_error(conn)) {
+ fprintf(stderr, "Couldn't connect to X server: error code %d\n",
+ conn ? xcb_connection_has_error(conn) : -1);
+ ret = -1;
+ goto err_out;
+ }
+
+ ret = xkb_x11_setup_xkb_extension(conn,
+ XKB_X11_MIN_MAJOR_XKB_VERSION,
+ XKB_X11_MIN_MINOR_XKB_VERSION,
+ XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS,
+ NULL, NULL, NULL, NULL);
+ if (!ret) {
+ fprintf(stderr, "Couldn't setup XKB extension\n");
+ goto err_conn;
+ }
+
+ device_id = xkb_x11_get_core_keyboard_device_id(conn);
+ if (device_id == -1) {
+ ret = -1;
+ fprintf(stderr, "Couldn't find core keyboard device\n");
+ goto err_conn;
+ }
+
+ ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
+ if (!ctx) {
+ ret = -1;
+ fprintf(stderr, "Couldn't create xkb context\n");
+ goto err_conn;
+ }
+
+ bench_start(&bench);
+ for (int i = 0; i < BENCHMARK_ITERATIONS; i++) {
+ struct xkb_keymap *keymap;
+ struct xkb_state *state;
+
+ keymap = xkb_x11_keymap_new_from_device(ctx, conn, device_id,
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
+ assert(keymap);
+
+ state = xkb_x11_state_new_from_device(keymap, conn, device_id);
+ assert(state);
+
+ xkb_state_unref(state);
+ xkb_keymap_unref(keymap);
+ }
+ bench_stop(&bench);
+ ret = 0;
+
+ elapsed = bench_elapsed_str(&bench);
+ fprintf(stderr, "retrieved %d keymaps from X in %ss\n",
+ BENCHMARK_ITERATIONS, elapsed);
+ free(elapsed);
+
+ xkb_context_unref(ctx);
+err_conn:
+ xcb_disconnect(conn);
+err_out:
+ return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/config.h b/config.h
index 145bce1..2d4dea9 100644..120000
--- a/config.h
+++ b/config.h
@@ -1,61 +1 @@
-/*
- * Autogenerated by the Meson build system.
- * Do not edit, your changes will be lost.
- */
-
-#pragma once
-
-#define DEFAULT_XKB_LAYOUT "us"
-
-#define DEFAULT_XKB_MODEL "pc105"
-
-#define DEFAULT_XKB_OPTIONS NULL
-
-#define DEFAULT_XKB_RULES "evdev"
-
-#define DEFAULT_XKB_VARIANT NULL
-
-#define DFLT_XKB_CONFIG_EXTRA_PATH "/usr/local/etc/xkb"
-
-#define DFLT_XKB_CONFIG_ROOT "/usr/share/X11/xkb"
-
-#define EXIT_INVALID_USAGE 2
-
-#define HAVE_ASPRINTF 1
-
-#define HAVE_MKOSTEMP 1
-
-#define HAVE_MMAP 1
-
-#define HAVE_POSIX_FALLOCATE 1
-
-#define HAVE_STRNDUP 1
-
-#define HAVE_UNISTD_H 1
-
-#define HAVE_XKBCLI_COMPILE_KEYMAP 1
-
-#define HAVE_XKBCLI_HOW_TO_TYPE 1
-
-#define HAVE_XKBCLI_INTERACTIVE_EVDEV 1
-
-#define HAVE_XKBCLI_LIST 1
-
-#define HAVE___BUILTIN_EXPECT 1
-
-#define LIBXKBCOMMON_TOOL_PATH "/usr/local/libexec/xkbcommon"
-
-#define LIBXKBCOMMON_VERSION "1.0.1"
-
-#define WIN32_LEAN_AND_MEAN 1
-
-#define XLOCALEDIR "/usr/local/share/X11/locale"
-
-#define _CRT_NONSTDC_NO_DEPRECATE 1
-
-#define _CRT_NONSTDC_NO_WARNINGS 1
-
-#define _CRT_SECURE_NO_WARNINGS 1
-
-#define _GNU_SOURCE 1
-
+config/config.h \ No newline at end of file
diff --git a/config/config.h b/config/config.h
new file mode 100644
index 0000000..76ab62a
--- /dev/null
+++ b/config/config.h
@@ -0,0 +1,61 @@
+/*
+ * Autogenerated by the Meson build system.
+ * Do not edit, your changes will be lost.
+ */
+
+#pragma once
+
+#define DEFAULT_XKB_LAYOUT "us"
+
+#define DEFAULT_XKB_MODEL "pc105"
+
+#define DEFAULT_XKB_OPTIONS NULL
+
+#define DEFAULT_XKB_RULES "evdev"
+
+#define DEFAULT_XKB_VARIANT NULL
+
+#define DFLT_XKB_CONFIG_EXTRA_PATH "/usr/local/etc/xkb"
+
+#define DFLT_XKB_CONFIG_ROOT "/usr/share/X11/xkb"
+
+#define EXIT_INVALID_USAGE 2
+
+#define HAVE_ASPRINTF 1
+
+#define HAVE_MKOSTEMP 1
+
+#define HAVE_MMAP 1
+
+#define HAVE_POSIX_FALLOCATE 1
+
+#define HAVE_STRNDUP 1
+
+#define HAVE_UNISTD_H 1
+
+#define HAVE_XKBCLI_COMPILE_KEYMAP 1
+
+#define HAVE_XKBCLI_HOW_TO_TYPE 1
+
+#define HAVE_XKBCLI_INTERACTIVE_EVDEV 1
+
+#define HAVE_XKBCLI_LIST 1
+
+#define HAVE___BUILTIN_EXPECT 1
+
+#define LIBXKBCOMMON_TOOL_PATH "/usr/local/libexec/xkbcommon"
+
+#define LIBXKBCOMMON_VERSION "1.0.3"
+
+#define WIN32_LEAN_AND_MEAN 1
+
+#define XLOCALEDIR "/usr/local/share/X11/locale"
+
+#define _CRT_NONSTDC_NO_DEPRECATE 1
+
+#define _CRT_NONSTDC_NO_WARNINGS 1
+
+#define _CRT_SECURE_NO_WARNINGS 1
+
+#define _GNU_SOURCE 1
+
diff --git a/src/xkbcomp/parser.c b/config/libxkbcommon.so.0.0.0.p/parser.c
index 5cc10e4..921673f 100644
--- a/src/xkbcomp/parser.c
+++ b/config/libxkbcommon.so.0.0.0.p/parser.c
@@ -675,8 +675,8 @@ static const yytype_int16 yyrline[] =
653, 655, 657, 661, 663, 665, 667, 669, 671, 673,
675, 679, 681, 685, 689, 691, 693, 695, 699, 701,
703, 705, 709, 710, 713, 715, 717, 719, 723, 727,
- 733, 734, 754, 755, 758, 759, 762, 765, 768, 771,
- 772, 775, 778, 779, 782
+ 735, 736, 756, 757, 760, 761, 764, 767, 770, 773,
+ 774, 777, 780, 781, 784
};
#endif
@@ -2890,21 +2890,23 @@ yyreduce:
case 169: /* KeySym: IDENT */
#line 728 "../src/xkbcomp/parser.y"
{
- if (!resolve_keysym((yyvsp[0].str), &(yyval.keysym)))
+ if (!resolve_keysym((yyvsp[0].str), &(yyval.keysym))) {
parser_warn(param, "unrecognized keysym \"%s\"", (yyvsp[0].str));
+ (yyval.keysym) = XKB_KEY_NoSymbol;
+ }
free((yyvsp[0].str));
}
-#line 2898 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 2900 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 170: /* KeySym: SECTION */
-#line 733 "../src/xkbcomp/parser.y"
+#line 735 "../src/xkbcomp/parser.y"
{ (yyval.keysym) = XKB_KEY_section; }
-#line 2904 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 2906 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 171: /* KeySym: Integer */
-#line 735 "../src/xkbcomp/parser.y"
+#line 737 "../src/xkbcomp/parser.y"
{
if ((yyvsp[0].num) < 0) {
parser_warn(param, "unrecognized keysym \"%"PRId64"\"", (yyvsp[0].num));
@@ -2922,89 +2924,89 @@ yyreduce:
}
}
}
-#line 2926 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 2928 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 172: /* SignedNumber: MINUS Number */
-#line 754 "../src/xkbcomp/parser.y"
+#line 756 "../src/xkbcomp/parser.y"
{ (yyval.num) = -(yyvsp[0].num); }
-#line 2932 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 2934 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 173: /* SignedNumber: Number */
-#line 755 "../src/xkbcomp/parser.y"
+#line 757 "../src/xkbcomp/parser.y"
{ (yyval.num) = (yyvsp[0].num); }
-#line 2938 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 2940 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 174: /* Number: FLOAT */
-#line 758 "../src/xkbcomp/parser.y"
+#line 760 "../src/xkbcomp/parser.y"
{ (yyval.num) = (yyvsp[0].num); }
-#line 2944 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 2946 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 175: /* Number: INTEGER */
-#line 759 "../src/xkbcomp/parser.y"
+#line 761 "../src/xkbcomp/parser.y"
{ (yyval.num) = (yyvsp[0].num); }
-#line 2950 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 2952 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 176: /* Float: FLOAT */
-#line 762 "../src/xkbcomp/parser.y"
+#line 764 "../src/xkbcomp/parser.y"
{ (yyval.num) = 0; }
-#line 2956 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 2958 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 177: /* Integer: INTEGER */
-#line 765 "../src/xkbcomp/parser.y"
+#line 767 "../src/xkbcomp/parser.y"
{ (yyval.num) = (yyvsp[0].num); }
-#line 2962 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 2964 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 178: /* KeyCode: INTEGER */
-#line 768 "../src/xkbcomp/parser.y"
+#line 770 "../src/xkbcomp/parser.y"
{ (yyval.num) = (yyvsp[0].num); }
-#line 2968 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 2970 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 179: /* Ident: IDENT */
-#line 771 "../src/xkbcomp/parser.y"
+#line 773 "../src/xkbcomp/parser.y"
{ (yyval.atom) = xkb_atom_intern(param->ctx, (yyvsp[0].str), strlen((yyvsp[0].str))); free((yyvsp[0].str)); }
-#line 2974 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 2976 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 180: /* Ident: DEFAULT */
-#line 772 "../src/xkbcomp/parser.y"
+#line 774 "../src/xkbcomp/parser.y"
{ (yyval.atom) = xkb_atom_intern_literal(param->ctx, "default"); }
-#line 2980 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 2982 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 181: /* String: STRING */
-#line 775 "../src/xkbcomp/parser.y"
+#line 777 "../src/xkbcomp/parser.y"
{ (yyval.atom) = xkb_atom_intern(param->ctx, (yyvsp[0].str), strlen((yyvsp[0].str))); free((yyvsp[0].str)); }
-#line 2986 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 2988 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 182: /* OptMapName: MapName */
-#line 778 "../src/xkbcomp/parser.y"
+#line 780 "../src/xkbcomp/parser.y"
{ (yyval.str) = (yyvsp[0].str); }
-#line 2992 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 2994 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 183: /* OptMapName: %empty */
-#line 779 "../src/xkbcomp/parser.y"
+#line 781 "../src/xkbcomp/parser.y"
{ (yyval.str) = NULL; }
-#line 2998 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 3000 "libxkbcommon.so.0.0.0.p/parser.c"
break;
case 184: /* MapName: STRING */
-#line 782 "../src/xkbcomp/parser.y"
+#line 784 "../src/xkbcomp/parser.y"
{ (yyval.str) = (yyvsp[0].str); }
-#line 3004 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 3006 "libxkbcommon.so.0.0.0.p/parser.c"
break;
-#line 3008 "libxkbcommon.so.0.0.0.p/parser.c"
+#line 3010 "libxkbcommon.so.0.0.0.p/parser.c"
default: break;
}
@@ -3198,7 +3200,7 @@ yyreturn:
return yyresult;
}
-#line 785 "../src/xkbcomp/parser.y"
+#line 787 "../src/xkbcomp/parser.y"
XkbFile *
diff --git a/src/xkbcomp/parser.h b/config/libxkbcommon.so.0.0.0.p/parser.h
index 3d9dcaf..3d9dcaf 100644
--- a/src/xkbcomp/parser.h
+++ b/config/libxkbcommon.so.0.0.0.p/parser.h
diff --git a/meson.build b/meson.build
index 6e433f4..47c436f 100644
--- a/meson.build
+++ b/meson.build
@@ -1,7 +1,7 @@
project(
'libxkbcommon',
'c',
- version: '1.0.1',
+ version: '1.0.3',
default_options: [
'c_std=c99',
'warning_level=2',
@@ -515,6 +515,8 @@ libxkbcommon_test_internal = static_library(
'test/common.c',
'test/test.h',
'test/evdev-scancodes.h',
+ 'bench/bench.c',
+ 'bench/bench.h',
libxkbcommon_sources,
include_directories: include_directories('src'),
)
@@ -677,38 +679,35 @@ executable('fuzz-compose', 'fuzz/compose/target.c', dependencies: test_dep)
# Benchmarks.
-libxkbcommon_bench_internal = static_library(
- 'xkbcommon-bench-internal',
- 'bench/bench.c',
- 'bench/bench.h',
- link_with: libxkbcommon_test_internal,
-)
-bench_dep = declare_dependency(
- include_directories: include_directories('src'),
- link_with: libxkbcommon_bench_internal,
-)
bench_env = environment()
bench_env.set('top_srcdir', meson.source_root())
benchmark(
'key-proc',
- executable('bench-key-proc', 'bench/key-proc.c', dependencies: bench_dep),
+ executable('bench-key-proc', 'bench/key-proc.c', dependencies: test_dep),
env: bench_env,
)
benchmark(
'rules',
- executable('bench-rules', 'bench/rules.c', dependencies: bench_dep),
+ executable('bench-rules', 'bench/rules.c', dependencies: test_dep),
env: bench_env,
)
benchmark(
'rulescomp',
- executable('bench-rulescomp', 'bench/rulescomp.c', dependencies: bench_dep),
+ executable('bench-rulescomp', 'bench/rulescomp.c', dependencies: test_dep),
env: bench_env,
)
benchmark(
'compose',
- executable('bench-compose', 'bench/compose.c', dependencies: bench_dep),
+ executable('bench-compose', 'bench/compose.c', dependencies: test_dep),
env: bench_env,
)
+if get_option('enable-x11')
+ benchmark(
+ 'x11',
+ executable('bench-x11', 'bench/x11.c', dependencies: x11_test_dep),
+ env: bench_env,
+ )
+endif
# Documentation.
diff --git a/src/context.c b/src/context.c
index 4a6ac8e..71c2275 100644
--- a/src/context.c
+++ b/src/context.c
@@ -210,6 +210,7 @@ xkb_context_unref(struct xkb_context *ctx)
if (!ctx || --ctx->refcnt > 0)
return;
+ free(ctx->x11_atom_cache);
xkb_context_include_path_clear(ctx);
atom_table_free(ctx->atom_table);
free(ctx);
@@ -323,6 +324,8 @@ xkb_context_new(enum xkb_context_flags flags)
return NULL;
}
+ ctx->x11_atom_cache = NULL;
+
return ctx;
}
diff --git a/src/context.h b/src/context.h
index ead2508..44367cc 100644
--- a/src/context.h
+++ b/src/context.h
@@ -45,6 +45,9 @@ struct xkb_context {
struct atom_table *atom_table;
+ /* Used and allocated by xkbcommon-x11, free()d with the context. */
+ void *x11_atom_cache;
+
/* Buffer for the *Text() functions. */
char text_buffer[2048];
size_t text_next;
diff --git a/src/x11/keymap.c b/src/x11/keymap.c
index 7369d5d..f5b368f 100644
--- a/src/x11/keymap.c
+++ b/src/x11/keymap.c
@@ -445,19 +445,19 @@ get_sym_maps(struct xkb_keymap *keymap, xcb_connection_t *conn,
FAIL_UNLESS((unsigned) syms_length == wire_sym_map->width * key->num_groups);
- for (int j = 0; j < syms_length; j++) {
- xcb_keysym_t wire_keysym = *syms_iter;
- const xkb_layout_index_t group = j / wire_sym_map->width;
- const xkb_level_index_t level = j % wire_sym_map->width;
-
- assert(key->groups[group].type != NULL);
- if (level < key->groups[group].type->num_levels &&
- wire_keysym != XKB_KEY_NoSymbol) {
- key->groups[group].levels[level].num_syms = 1;
- key->groups[group].levels[level].u.sym = wire_keysym;
+ for (xkb_layout_index_t group = 0; group < key->num_groups; group++) {
+ for (xkb_level_index_t level = 0; level < wire_sym_map->width; level++) {
+ xcb_keysym_t wire_keysym = *syms_iter;
+
+ assert(key->groups[group].type != NULL);
+ if (level < key->groups[group].type->num_levels &&
+ wire_keysym != XKB_KEY_NoSymbol) {
+ key->groups[group].levels[level].num_syms = 1;
+ key->groups[group].levels[level].u.sym = wire_keysym;
+ }
+
+ syms_iter++;
}
-
- syms_iter++;
}
}
@@ -492,21 +492,23 @@ get_actions(struct xkb_keymap *keymap, xcb_connection_t *conn,
uint8_t wire_count = *acts_count_iter;
struct xkb_key *key = &keymap->keys[reply->firstKeyAction + i];
+ FAIL_UNLESS((unsigned) syms_length == wire_sym_map->width * key->num_groups);
FAIL_UNLESS(wire_count == 0 || wire_count == syms_length);
- for (int j = 0; j < wire_count; j++) {
- xcb_xkb_action_t *wire_action = acts_iter.data;
- const xkb_layout_index_t group = j / wire_sym_map->width;
- const xkb_level_index_t level = j % wire_sym_map->width;
+ if (wire_count != 0) {
+ for (xkb_layout_index_t group = 0; group < key->num_groups; group++) {
+ for (xkb_level_index_t level = 0; level < wire_sym_map->width; level++) {
+ xcb_xkb_action_t *wire_action = acts_iter.data;
- if (level < key->groups[group].type->num_levels) {
- union xkb_action *action =
- &key->groups[group].levels[level].action;
+ if (level < key->groups[group].type->num_levels) {
+ union xkb_action *action = &key->groups[group].levels[level].action;
- translate_action(action, wire_action);
- }
+ translate_action(action, wire_action);
+ }
- xcb_xkb_action_next(&acts_iter);
+ xcb_xkb_action_next(&acts_iter);
+ }
+ }
}
acts_count_iter++;
@@ -886,6 +888,7 @@ get_type_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
wire_num_levels))
goto fail;
+ type->num_level_names = type->num_levels;
kt_level_names_iter += wire_num_levels;
key_type_names_iter++;
n_levels_per_type_iter++;
diff --git a/src/x11/util.c b/src/x11/util.c
index 3959a5a..660d885 100644
--- a/src/x11/util.c
+++ b/src/x11/util.c
@@ -155,6 +155,20 @@ get_atom_name(xcb_connection_t *conn, xcb_atom_t atom, char **out)
return true;
}
+struct x11_atom_cache {
+ /*
+ * Invalidate the cache based on the XCB connection.
+ * X11 atoms are actually not per connection or client, but per X server
+ * session. But better be safe just in case we survive an X server restart.
+ */
+ xcb_connection_t *conn;
+ struct {
+ xcb_atom_t from;
+ xkb_atom_t to;
+ } cache[256];
+ size_t len;
+};
+
bool
adopt_atoms(struct xkb_context *ctx, xcb_connection_t *conn,
const xcb_atom_t *from, xkb_atom_t *to, const size_t count)
@@ -163,24 +177,49 @@ adopt_atoms(struct xkb_context *ctx, xcb_connection_t *conn,
xcb_get_atom_name_cookie_t cookies[SIZE];
const size_t num_batches = ROUNDUP(count, SIZE) / SIZE;
+ if (!ctx->x11_atom_cache) {
+ ctx->x11_atom_cache = calloc(1, sizeof(struct x11_atom_cache));
+ }
+ /* Can be NULL in case the malloc failed. */
+ struct x11_atom_cache *cache = ctx->x11_atom_cache;
+ if (cache && cache->conn != conn) {
+ cache->conn = conn;
+ cache->len = 0;
+ }
+
+ memset(to, 0, count * sizeof(*to));
+
/* Send and collect the atoms in batches of reasonable SIZE. */
for (size_t batch = 0; batch < num_batches; batch++) {
const size_t start = batch * SIZE;
const size_t stop = MIN((batch + 1) * SIZE, count);
/* Send. */
- for (size_t i = start; i < stop; i++)
- if (from[i] != XCB_ATOM_NONE)
+ for (size_t i = start; i < stop; i++) {
+ bool cache_hit = false;
+ if (cache) {
+ for (size_t c = 0; c < cache->len; c++) {
+ if (cache->cache[c].from == from[i]) {
+ to[i] = cache->cache[c].to;
+ cache_hit = true;
+ break;
+ }
+ }
+ }
+ if (!cache_hit && from[i] != XCB_ATOM_NONE)
cookies[i % SIZE] = xcb_get_atom_name(conn, from[i]);
+ }
/* Collect. */
for (size_t i = start; i < stop; i++) {
xcb_get_atom_name_reply_t *reply;
- if (from[i] == XCB_ATOM_NONE) {
- to[i] = XKB_ATOM_NONE;
+ if (from[i] == XCB_ATOM_NONE)
+ continue;
+
+ /* Was filled from cache. */
+ if (to[i] != 0)
continue;
- }
reply = xcb_get_atom_name_reply(conn, cookies[i % SIZE], NULL);
if (!reply)
@@ -194,6 +233,12 @@ adopt_atoms(struct xkb_context *ctx, xcb_connection_t *conn,
if (to[i] == XKB_ATOM_NONE)
goto err_discard;
+ if (cache && cache->len < ARRAY_SIZE(cache->cache)) {
+ size_t idx = cache->len++;
+ cache->cache[idx].from = from[i];
+ cache->cache[idx].to = to[i];
+ }
+
continue;
/*
diff --git a/src/xkbcomp/.gitignore b/src/xkbcomp/.gitignore
index e69de29..d7814e4 100644
--- a/src/xkbcomp/.gitignore
+++ b/src/xkbcomp/.gitignore
@@ -0,0 +1,2 @@
+parser.c
+parser.h
diff --git a/src/xkbcomp/keymap-dump.c b/src/xkbcomp/keymap-dump.c
index e6b438a..b7828bf 100644
--- a/src/xkbcomp/keymap-dump.c
+++ b/src/xkbcomp/keymap-dump.c
@@ -277,9 +277,11 @@ write_led_map(struct xkb_keymap *keymap, struct buf *buf,
}
static const char *
-affect_lock_text(enum xkb_action_flags flags)
+affect_lock_text(enum xkb_action_flags flags, bool show_both)
{
switch (flags & (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK)) {
+ case 0:
+ return show_both ? ",affect=both" : "";
case ACTION_LOCK_NO_UNLOCK:
return ",affect=lock";
case ACTION_LOCK_NO_LOCK:
@@ -317,7 +319,7 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
write_buf(buf, "%s%s(modifiers=%s%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" : "",
- (action->type == ACTION_TYPE_MOD_LOCK) ? affect_lock_text(action->mods.flags) : "",
+ (action->type == ACTION_TYPE_MOD_LOCK) ? affect_lock_text(action->mods.flags, false) : "",
suffix);
break;
@@ -347,7 +349,7 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
break;
case ACTION_TYPE_PTR_LOCK:
- args = affect_lock_text(action->btn.flags);
+ args = affect_lock_text(action->btn.flags, true);
/* fallthrough */
case ACTION_TYPE_PTR_BUTTON:
write_buf(buf, "%s%s(button=", prefix, type);
@@ -382,7 +384,7 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
case ACTION_TYPE_CTRL_LOCK:
write_buf(buf, "%s%s(controls=%s%s)%s", prefix, type,
ControlMaskText(keymap->ctx, action->ctrls.ctrls),
- (action->type == ACTION_TYPE_CTRL_LOCK) ? affect_lock_text(action->ctrls.flags) : "",
+ (action->type == ACTION_TYPE_CTRL_LOCK) ? affect_lock_text(action->ctrls.flags, false) : "",
suffix);
break;
diff --git a/src/xkbcomp/parser.y b/src/xkbcomp/parser.y
index 6dcb523..87dea65 100644
--- a/src/xkbcomp/parser.y
+++ b/src/xkbcomp/parser.y
@@ -726,8 +726,10 @@ KeySyms : OBRACE KeySymList CBRACE
KeySym : IDENT
{
- if (!resolve_keysym($1, &$$))
+ if (!resolve_keysym($1, &$$)) {
parser_warn(param, "unrecognized keysym \"%s\"", $1);
+ $$ = XKB_KEY_NoSymbol;
+ }
free($1);
}
| SECTION { $$ = XKB_KEY_section; }
diff --git a/test/data/keymaps/host.xkb b/test/data/keymaps/host.xkb
index c7d606f..dcaa677 100644
--- a/test/data/keymaps/host.xkb
+++ b/test/data/keymaps/host.xkb
@@ -300,300 +300,300 @@ xkb_types "complete" {
type "ONE_LEVEL" {
modifiers= none;
- level_name[Level1]= "Any";
+ level_name[1]= "Any";
};
type "TWO_LEVEL" {
modifiers= Shift;
- map[Shift]= Level2;
- level_name[Level1]= "Base";
- level_name[Level2]= "Shift";
+ map[Shift]= 2;
+ level_name[1]= "Base";
+ level_name[2]= "Shift";
};
type "ALPHABETIC" {
modifiers= Shift+Lock;
- map[Shift]= Level2;
- map[Lock]= Level2;
- level_name[Level1]= "Base";
- level_name[Level2]= "Caps";
+ map[Shift]= 2;
+ map[Lock]= 2;
+ level_name[1]= "Base";
+ level_name[2]= "Caps";
};
type "KEYPAD" {
modifiers= Shift+NumLock;
- map[Shift]= Level2;
- map[NumLock]= Level2;
- level_name[Level1]= "Base";
- level_name[Level2]= "Number";
+ map[Shift]= 2;
+ map[NumLock]= 2;
+ level_name[1]= "Base";
+ level_name[2]= "Number";
};
type "SHIFT+ALT" {
modifiers= Shift+Alt;
- map[Shift+Alt]= Level2;
- level_name[Level1]= "Base";
- level_name[Level2]= "Shift+Alt";
+ map[Shift+Alt]= 2;
+ level_name[1]= "Base";
+ level_name[2]= "Shift+Alt";
};
type "PC_SUPER_LEVEL2" {
modifiers= Mod4;
- map[Mod4]= Level2;
- level_name[Level1]= "Base";
- level_name[Level2]= "Super";
+ map[Mod4]= 2;
+ level_name[1]= "Base";
+ level_name[2]= "Super";
};
type "PC_CONTROL_LEVEL2" {
modifiers= Control;
- map[Control]= Level2;
- level_name[Level1]= "Base";
- level_name[Level2]= "Control";
+ map[Control]= 2;
+ level_name[1]= "Base";
+ level_name[2]= "Control";
};
type "PC_LCONTROL_LEVEL2" {
modifiers= LControl;
- map[LControl]= Level2;
- level_name[Level1]= "Base";
- level_name[Level2]= "LControl";
+ map[LControl]= 2;
+ level_name[1]= "Base";
+ level_name[2]= "LControl";
};
type "PC_RCONTROL_LEVEL2" {
modifiers= RControl;
- map[RControl]= Level2;
- level_name[Level1]= "Base";
- level_name[Level2]= "RControl";
+ map[RControl]= 2;
+ level_name[1]= "Base";
+ level_name[2]= "RControl";
};
type "PC_ALT_LEVEL2" {
modifiers= Alt;
- map[Alt]= Level2;
- level_name[Level1]= "Base";
- level_name[Level2]= "Alt";
+ map[Alt]= 2;
+ level_name[1]= "Base";
+ level_name[2]= "Alt";
};
type "PC_LALT_LEVEL2" {
modifiers= LAlt;
- map[LAlt]= Level2;
- level_name[Level1]= "Base";
- level_name[Level2]= "LAlt";
+ map[LAlt]= 2;
+ level_name[1]= "Base";
+ level_name[2]= "LAlt";
};
type "PC_RALT_LEVEL2" {
modifiers= RAlt;
- map[RAlt]= Level2;
- level_name[Level1]= "Base";
- level_name[Level2]= "RAlt";
+ map[RAlt]= 2;
+ level_name[1]= "Base";
+ level_name[2]= "RAlt";
};
type "CTRL+ALT" {
modifiers= Shift+Control+Alt+LevelThree;
- map[Shift]= Level2;
+ map[Shift]= 2;
preserve[Shift]= Shift;
- map[LevelThree]= Level3;
- map[Shift+LevelThree]= Level4;
+ map[LevelThree]= 3;
+ map[Shift+LevelThree]= 4;
preserve[Shift+LevelThree]= Shift;
- map[Control+Alt]= Level5;
- level_name[Level1]= "Base";
- level_name[Level2]= "Shift";
- level_name[Level3]= "Alt Base";
- level_name[Level4]= "Shift Alt";
- level_name[Level5]= "Ctrl+Alt";
+ map[Control+Alt]= 5;
+ level_name[1]= "Base";
+ level_name[2]= "Shift";
+ level_name[3]= "Alt Base";
+ level_name[4]= "Shift Alt";
+ level_name[5]= "Ctrl+Alt";
};
type "LOCAL_EIGHT_LEVEL" {
modifiers= Shift+Lock+Control+LevelThree;
- map[Shift]= Level2;
- map[Lock]= Level2;
- map[LevelThree]= Level3;
- map[Shift+Lock+LevelThree]= Level3;
- map[Shift+LevelThree]= Level4;
- map[Lock+LevelThree]= Level4;
- map[Control]= Level5;
- map[Shift+Lock+Control]= Level5;
- map[Shift+Control]= Level6;
- map[Lock+Control]= Level6;
- map[Control+LevelThree]= Level7;
- map[Shift+Lock+Control+LevelThree]= Level7;
- map[Shift+Control+LevelThree]= Level8;
- map[Lock+Control+LevelThree]= Level8;
- level_name[Level1]= "Base";
- level_name[Level2]= "Shift";
- level_name[Level3]= "Level3";
- level_name[Level4]= "Shift Level3";
- level_name[Level5]= "Ctrl";
- level_name[Level6]= "Shift Ctrl";
- level_name[Level7]= "Level3 Ctrl";
- level_name[Level8]= "Shift Level3 Ctrl";
+ map[Shift]= 2;
+ map[Lock]= 2;
+ map[LevelThree]= 3;
+ map[Shift+Lock+LevelThree]= 3;
+ map[Shift+LevelThree]= 4;
+ map[Lock+LevelThree]= 4;
+ map[Control]= 5;
+ map[Shift+Lock+Control]= 5;
+ map[Shift+Control]= 6;
+ map[Lock+Control]= 6;
+ map[Control+LevelThree]= 7;
+ map[Shift+Lock+Control+LevelThree]= 7;
+ map[Shift+Control+LevelThree]= 8;
+ map[Lock+Control+LevelThree]= 8;
+ level_name[1]= "Base";
+ level_name[2]= "Shift";
+ level_name[3]= "3";
+ level_name[4]= "Shift 3";
+ level_name[5]= "Ctrl";
+ level_name[6]= "Shift Ctrl";
+ level_name[7]= "3 Ctrl";
+ level_name[8]= "Shift 3 Ctrl";
};
type "THREE_LEVEL" {
modifiers= Shift+LevelThree;
- map[Shift]= Level2;
- map[LevelThree]= Level3;
- map[Shift+LevelThree]= Level3;
- level_name[Level1]= "Base";
- level_name[Level2]= "Shift";
- level_name[Level3]= "Level3";
+ map[Shift]= 2;
+ map[LevelThree]= 3;
+ map[Shift+LevelThree]= 3;
+ level_name[1]= "Base";
+ level_name[2]= "Shift";
+ level_name[3]= "3";
};
type "EIGHT_LEVEL" {
modifiers= Shift+LevelThree+LevelFive;
- map[Shift]= Level2;
- map[LevelThree]= Level3;
- map[Shift+LevelThree]= Level4;
- map[LevelFive]= Level5;
- map[Shift+LevelFive]= Level6;
- map[LevelThree+LevelFive]= Level7;
- map[Shift+LevelThree+LevelFive]= Level8;
- level_name[Level1]= "Base";
- level_name[Level2]= "Shift";
- level_name[Level3]= "Alt Base";
- level_name[Level4]= "Shift Alt";
- level_name[Level5]= "X";
- level_name[Level6]= "X Shift";
- level_name[Level7]= "X Alt Base";
- level_name[Level8]= "X Shift Alt";
+ map[Shift]= 2;
+ map[LevelThree]= 3;
+ map[Shift+LevelThree]= 4;
+ map[LevelFive]= 5;
+ map[Shift+LevelFive]= 6;
+ map[LevelThree+LevelFive]= 7;
+ map[Shift+LevelThree+LevelFive]= 8;
+ level_name[1]= "Base";
+ level_name[2]= "Shift";
+ level_name[3]= "Alt Base";
+ level_name[4]= "Shift Alt";
+ level_name[5]= "X";
+ level_name[6]= "X Shift";
+ level_name[7]= "X Alt Base";
+ level_name[8]= "X Shift Alt";
};
type "EIGHT_LEVEL_ALPHABETIC" {
modifiers= Shift+Lock+LevelThree+LevelFive;
- map[Shift]= Level2;
- map[Lock]= Level2;
- map[LevelThree]= Level3;
- map[Shift+LevelThree]= Level4;
- map[Lock+LevelThree]= Level4;
- map[Shift+Lock+LevelThree]= Level3;
- map[LevelFive]= Level5;
- map[Shift+LevelFive]= Level6;
- map[Lock+LevelFive]= Level6;
- map[LevelThree+LevelFive]= Level7;
- map[Shift+LevelThree+LevelFive]= Level8;
- map[Lock+LevelThree+LevelFive]= Level8;
- map[Shift+Lock+LevelThree+LevelFive]= Level7;
- level_name[Level1]= "Base";
- level_name[Level2]= "Shift";
- level_name[Level3]= "Alt Base";
- level_name[Level4]= "Shift Alt";
- level_name[Level5]= "X";
- level_name[Level6]= "X Shift";
- level_name[Level7]= "X Alt Base";
- level_name[Level8]= "X Shift Alt";
+ map[Shift]= 2;
+ map[Lock]= 2;
+ map[LevelThree]= 3;
+ map[Shift+LevelThree]= 4;
+ map[Lock+LevelThree]= 4;
+ map[Shift+Lock+LevelThree]= 3;
+ map[LevelFive]= 5;
+ map[Shift+LevelFive]= 6;
+ map[Lock+LevelFive]= 6;
+ map[LevelThree+LevelFive]= 7;
+ map[Shift+LevelThree+LevelFive]= 8;
+ map[Lock+LevelThree+LevelFive]= 8;
+ map[Shift+Lock+LevelThree+LevelFive]= 7;
+ level_name[1]= "Base";
+ level_name[2]= "Shift";
+ level_name[3]= "Alt Base";
+ level_name[4]= "Shift Alt";
+ level_name[5]= "X";
+ level_name[6]= "X Shift";
+ level_name[7]= "X Alt Base";
+ level_name[8]= "X Shift Alt";
};
type "EIGHT_LEVEL_SEMIALPHABETIC" {
modifiers= Shift+Lock+LevelThree+LevelFive;
- map[Shift]= Level2;
- map[Lock]= Level2;
- map[LevelThree]= Level3;
- map[Shift+LevelThree]= Level4;
- map[Lock+LevelThree]= Level3;
+ map[Shift]= 2;
+ map[Lock]= 2;
+ map[LevelThree]= 3;
+ map[Shift+LevelThree]= 4;
+ map[Lock+LevelThree]= 3;
preserve[Lock+LevelThree]= Lock;
- map[Shift+Lock+LevelThree]= Level4;
+ map[Shift+Lock+LevelThree]= 4;
preserve[Shift+Lock+LevelThree]= Lock;
- map[LevelFive]= Level5;
- map[Shift+LevelFive]= Level6;
- map[Lock+LevelFive]= Level6;
+ map[LevelFive]= 5;
+ map[Shift+LevelFive]= 6;
+ map[Lock+LevelFive]= 6;
preserve[Lock+LevelFive]= Lock;
- map[Shift+Lock+LevelFive]= Level6;
+ map[Shift+Lock+LevelFive]= 6;
preserve[Shift+Lock+LevelFive]= Lock;
- map[LevelThree+LevelFive]= Level7;
- map[Shift+LevelThree+LevelFive]= Level8;
- map[Lock+LevelThree+LevelFive]= Level7;
+ map[LevelThree+LevelFive]= 7;
+ map[Shift+LevelThree+LevelFive]= 8;
+ map[Lock+LevelThree+LevelFive]= 7;
preserve[Lock+LevelThree+LevelFive]= Lock;
- map[Shift+Lock+LevelThree+LevelFive]= Level8;
+ map[Shift+Lock+LevelThree+LevelFive]= 8;
preserve[Shift+Lock+LevelThree+LevelFive]= Lock;
- level_name[Level1]= "Base";
- level_name[Level2]= "Shift";
- level_name[Level3]= "Alt Base";
- level_name[Level4]= "Shift Alt";
- level_name[Level5]= "X";
- level_name[Level6]= "X Shift";
- level_name[Level7]= "X Alt Base";
- level_name[Level8]= "X Shift Alt";
+ level_name[1]= "Base";
+ level_name[2]= "Shift";
+ level_name[3]= "Alt Base";
+ level_name[4]= "Shift Alt";
+ level_name[5]= "X";
+ level_name[6]= "X Shift";
+ level_name[7]= "X Alt Base";
+ level_name[8]= "X Shift Alt";
};
type "FOUR_LEVEL" {
modifiers= Shift+LevelThree;
- map[Shift]= Level2;
- map[LevelThree]= Level3;
- map[Shift+LevelThree]= Level4;
- level_name[Level1]= "Base";
- level_name[Level2]= "Shift";
- level_name[Level3]= "Alt Base";
- level_name[Level4]= "Shift Alt";
+ map[Shift]= 2;
+ map[LevelThree]= 3;
+ map[Shift+LevelThree]= 4;
+ level_name[1]= "Base";
+ level_name[2]= "Shift";
+ level_name[3]= "Alt Base";
+ level_name[4]= "Shift Alt";
};
type "FOUR_LEVEL_ALPHABETIC" {
modifiers= Shift+Lock+LevelThree;
- map[Shift]= Level2;
- map[Lock]= Level2;
- map[LevelThree]= Level3;
- map[Shift+LevelThree]= Level4;
- map[Lock+LevelThree]= Level4;
- map[Shift+Lock+LevelThree]= Level3;
- level_name[Level1]= "Base";
- level_name[Level2]= "Shift";
- level_name[Level3]= "Alt Base";
- level_name[Level4]= "Shift Alt";
+ map[Shift]= 2;
+ map[Lock]= 2;
+ map[LevelThree]= 3;
+ map[Shift+LevelThree]= 4;
+ map[Lock+LevelThree]= 4;
+ map[Shift+Lock+LevelThree]= 3;
+ level_name[1]= "Base";
+ level_name[2]= "Shift";
+ level_name[3]= "Alt Base";
+ level_name[4]= "Shift Alt";
};
type "FOUR_LEVEL_SEMIALPHABETIC" {
modifiers= Shift+Lock+LevelThree;
- map[Shift]= Level2;
- map[Lock]= Level2;
- map[LevelThree]= Level3;
- map[Shift+LevelThree]= Level4;
- map[Lock+LevelThree]= Level3;
+ map[Shift]= 2;
+ map[Lock]= 2;
+ map[LevelThree]= 3;
+ map[Shift+LevelThree]= 4;
+ map[Lock+LevelThree]= 3;
preserve[Lock+LevelThree]= Lock;
- map[Shift+Lock+LevelThree]= Level4;
+ map[Shift+Lock+LevelThree]= 4;
preserve[Shift+Lock+LevelThree]= Lock;
- level_name[Level1]= "Base";
- level_name[Level2]= "Shift";
- level_name[Level3]= "Alt Base";
- level_name[Level4]= "Shift Alt";
+ level_name[1]= "Base";
+ level_name[2]= "Shift";
+ level_name[3]= "Alt Base";
+ level_name[4]= "Shift Alt";
};
type "FOUR_LEVEL_MIXED_KEYPAD" {
modifiers= Shift+NumLock+LevelThree;
- map[NumLock]= Level2;
- map[Shift]= Level2;
- map[LevelThree]= Level3;
- map[NumLock+LevelThree]= Level3;
- map[Shift+LevelThree]= Level4;
- map[Shift+NumLock+LevelThree]= Level4;
- level_name[Level1]= "Base";
- level_name[Level2]= "Number";
- level_name[Level3]= "Alt Base";
- level_name[Level4]= "Shift Alt";
+ map[NumLock]= 2;
+ map[Shift]= 2;
+ map[LevelThree]= 3;
+ map[NumLock+LevelThree]= 3;
+ map[Shift+LevelThree]= 4;
+ map[Shift+NumLock+LevelThree]= 4;
+ level_name[1]= "Base";
+ level_name[2]= "Number";
+ level_name[3]= "Alt Base";
+ level_name[4]= "Shift Alt";
};
type "FOUR_LEVEL_X" {
modifiers= Shift+Control+Alt+LevelThree;
- map[LevelThree]= Level2;
- map[Shift+LevelThree]= Level3;
- map[Control+Alt]= Level4;
- level_name[Level1]= "Base";
- level_name[Level2]= "Alt Base";
- level_name[Level3]= "Shift Alt";
- level_name[Level4]= "Ctrl+Alt";
+ map[LevelThree]= 2;
+ map[Shift+LevelThree]= 3;
+ map[Control+Alt]= 4;
+ level_name[1]= "Base";
+ level_name[2]= "Alt Base";
+ level_name[3]= "Shift Alt";
+ level_name[4]= "Ctrl+Alt";
};
type "SEPARATE_CAPS_AND_SHIFT_ALPHABETIC" {
modifiers= Shift+Lock+LevelThree;
- map[Shift]= Level2;
- map[Lock]= Level4;
+ map[Shift]= 2;
+ map[Lock]= 4;
preserve[Lock]= Lock;
- map[LevelThree]= Level3;
- map[Shift+LevelThree]= Level4;
- map[Lock+LevelThree]= Level3;
+ map[LevelThree]= 3;
+ map[Shift+LevelThree]= 4;
+ map[Lock+LevelThree]= 3;
preserve[Lock+LevelThree]= Lock;
- map[Shift+Lock+LevelThree]= Level3;
- level_name[Level1]= "Base";
- level_name[Level2]= "Shift";
- level_name[Level3]= "AltGr Base";
- level_name[Level4]= "Shift AltGr";
+ map[Shift+Lock+LevelThree]= 3;
+ level_name[1]= "Base";
+ level_name[2]= "Shift";
+ level_name[3]= "AltGr Base";
+ level_name[4]= "Shift AltGr";
};
type "FOUR_LEVEL_PLUS_LOCK" {
modifiers= Shift+Lock+LevelThree;
- map[Shift]= Level2;
- map[LevelThree]= Level3;
- map[Shift+LevelThree]= Level4;
- map[Lock]= Level5;
- map[Shift+Lock]= Level2;
- map[Lock+LevelThree]= Level3;
- map[Shift+Lock+LevelThree]= Level4;
- level_name[Level1]= "Base";
- level_name[Level2]= "Shift";
- level_name[Level3]= "Alt Base";
- level_name[Level4]= "Shift Alt";
- level_name[Level5]= "Lock";
+ map[Shift]= 2;
+ map[LevelThree]= 3;
+ map[Shift+LevelThree]= 4;
+ map[Lock]= 5;
+ map[Shift+Lock]= 2;
+ map[Lock+LevelThree]= 3;
+ map[Shift+Lock+LevelThree]= 4;
+ level_name[1]= "Base";
+ level_name[2]= "Shift";
+ level_name[3]= "Alt Base";
+ level_name[4]= "Shift Alt";
+ level_name[5]= "Lock";
};
type "FOUR_LEVEL_KEYPAD" {
modifiers= Shift+NumLock+LevelThree;
- map[Shift]= Level2;
- map[NumLock]= Level2;
- map[LevelThree]= Level3;
- map[Shift+LevelThree]= Level4;
- map[NumLock+LevelThree]= Level4;
- map[Shift+NumLock+LevelThree]= Level3;
- level_name[Level1]= "Base";
- level_name[Level2]= "Number";
- level_name[Level3]= "Alt Base";
- level_name[Level4]= "Alt Number";
+ map[Shift]= 2;
+ map[NumLock]= 2;
+ map[LevelThree]= 3;
+ map[Shift+LevelThree]= 4;
+ map[NumLock+LevelThree]= 4;
+ map[Shift+NumLock+LevelThree]= 3;
+ level_name[1]= "Base";
+ level_name[2]= "Number";
+ level_name[3]= "Alt Base";
+ level_name[4]= "Alt Number";
};
};
@@ -887,16 +887,16 @@ xkb_compatibility "complete" {
action= PtrBtn(button=3,count=2);
};
interpret Pointer_Drag_Dflt+AnyOfOrNone(all) {
- action= LockPtrBtn(button=default);
+ action= LockPtrBtn(button=default,affect=both);
};
interpret Pointer_Drag1+AnyOfOrNone(all) {
- action= LockPtrBtn(button=1);
+ action= LockPtrBtn(button=1,affect=both);
};
interpret Pointer_Drag2+AnyOfOrNone(all) {
- action= LockPtrBtn(button=2);
+ action= LockPtrBtn(button=2,affect=both);
};
interpret Pointer_Drag3+AnyOfOrNone(all) {
- action= LockPtrBtn(button=3);
+ action= LockPtrBtn(button=3,affect=both);
};
interpret Pointer_EnableKeys+AnyOfOrNone(all) {
action= LockControls(controls=MouseKeys);
@@ -1080,79 +1080,79 @@ xkb_compatibility "complete" {
};
xkb_symbols "pc_us_pt_2_us_3_inet(evdev)_group(shift_caps_toggle)_compose(ralt)" {
- name[group1]="English (US)";
- name[group2]="Portuguese";
- name[group3]="English (US)";
+ name[Group1]="English (US)";
+ name[Group2]="Portuguese";
+ name[Group3]="English (US)";
key <ESC> { [ Escape ] };
key <AE01> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ 1, exclam ],
symbols[Group2]= [ 1, exclam, onesuperior, exclamdown ],
symbols[Group3]= [ 1, exclam ]
};
key <AE02> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ 2, at ],
symbols[Group2]= [ 2, quotedbl, at, oneeighth ],
symbols[Group3]= [ 2, at ]
};
key <AE03> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ 3, numbersign ],
symbols[Group2]= [ 3, numbersign, sterling, sterling ],
symbols[Group3]= [ 3, numbersign ]
};
key <AE04> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ 4, dollar ],
symbols[Group2]= [ 4, dollar, section, dollar ],
symbols[Group3]= [ 4, dollar ]
};
key <AE05> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ 5, percent ],
symbols[Group2]= [ 5, percent, onehalf, threeeighths ],
symbols[Group3]= [ 5, percent ]
};
key <AE06> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ 6, asciicircum ],
symbols[Group2]= [ 6, ampersand, notsign, fiveeighths ],
symbols[Group3]= [ 6, asciicircum ]
};
key <AE07> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ 7, ampersand ],
symbols[Group2]= [ 7, slash, braceleft, seveneighths ],
symbols[Group3]= [ 7, ampersand ]
};
key <AE08> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ 8, asterisk ],
symbols[Group2]= [ 8, parenleft, bracketleft, trademark ],
symbols[Group3]= [ 8, asterisk ]
};
key <AE09> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ 9, parenleft ],
symbols[Group2]= [ 9, parenright, bracketright, plusminus ],
symbols[Group3]= [ 9, parenleft ]
};
key <AE10> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ 0, parenright ],
symbols[Group2]= [ 0, equal, braceright, degree ],
symbols[Group3]= [ 0, parenright ]
};
key <AE11> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ minus, underscore ],
symbols[Group2]= [ apostrophe, question, backslash, questiondown ],
symbols[Group3]= [ minus, underscore ]
};
key <AE12> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ equal, plus ],
symbols[Group2]= [ guillemotleft, guillemotright, dead_cedilla, dead_ogonek ],
symbols[Group3]= [ equal, plus ]
@@ -1160,93 +1160,93 @@ xkb_symbols "pc_us_pt_2_us_3_inet(evdev)_group(shift_caps_toggle)_compose(ralt)"
key <BKSP> { [ BackSpace, BackSpace ] };
key <TAB> { [ Tab, ISO_Left_Tab ] };
key <AD01> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ q, Q ],
symbols[Group2]= [ q, Q, at, Greek_OMEGA ],
symbols[Group3]= [ q, Q ]
};
key <AD02> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_ALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_ALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ w, W ],
symbols[Group2]= [ w, W, lstroke, Lstroke ],
symbols[Group3]= [ w, W ]
};
key <AD03> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ e, E ],
symbols[Group2]= [ e, E, EuroSign, cent ],
symbols[Group3]= [ e, E ]
};
key <AD04> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ r, R ],
symbols[Group2]= [ r, R, paragraph, registered ],
symbols[Group3]= [ r, R ]
};
key <AD05> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_ALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_ALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ t, T ],
symbols[Group2]= [ t, T, tslash, Tslash ],
symbols[Group3]= [ t, T ]
};
key <AD06> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ y, Y ],
symbols[Group2]= [ y, Y, leftarrow, yen ],
symbols[Group3]= [ y, Y ]
};
key <AD07> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ u, U ],
symbols[Group2]= [ u, U, downarrow, uparrow ],
symbols[Group3]= [ u, U ]
};
key <AD08> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ i, I ],
symbols[Group2]= [ i, I, rightarrow, idotless ],
symbols[Group3]= [ i, I ]
};
key <AD09> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_ALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_ALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ o, O ],
symbols[Group2]= [ o, O, oslash, Oslash ],
symbols[Group3]= [ o, O ]
};
key <AD10> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_ALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_ALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ p, P ],
symbols[Group2]= [ p, P, thorn, THORN ],
symbols[Group3]= [ p, P ]
};
key <AD11> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ bracketleft, braceleft ],
symbols[Group2]= [ plus, asterisk, dead_diaeresis, dead_abovering ],
symbols[Group3]= [ bracketleft, braceleft ]
};
key <AD12> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ bracketright, braceright ],
symbols[Group2]= [ dead_acute, dead_grave, dead_tilde, dead_macron ],
symbols[Group3]= [ bracketright, braceright ]
@@ -1254,172 +1254,172 @@ xkb_symbols "pc_us_pt_2_us_3_inet(evdev)_group(shift_caps_toggle)_compose(ralt)"
key <RTRN> { [ Return ] };
key <LCTL> { [ Control_L ] };
key <AC01> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_ALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_ALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ a, A ],
symbols[Group2]= [ a, A, ae, AE ],
symbols[Group3]= [ a, A ]
};
key <AC02> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ s, S ],
symbols[Group2]= [ s, S, ssharp, section ],
symbols[Group3]= [ s, S ]
};
key <AC03> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_ALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_ALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ d, D ],
symbols[Group2]= [ d, D, eth, ETH ],
symbols[Group3]= [ d, D ]
};
key <AC04> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ f, F ],
symbols[Group2]= [ f, F, dstroke, ordfeminine ],
symbols[Group3]= [ f, F ]
};
key <AC05> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_ALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_ALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ g, G ],
symbols[Group2]= [ g, G, eng, ENG ],
symbols[Group3]= [ g, G ]
};
key <AC06> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_ALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_ALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ h, H ],
symbols[Group2]= [ h, H, hstroke, Hstroke ],
symbols[Group3]= [ h, H ]
};
key <AC07> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ j, J ],
symbols[Group2]= [ j, J, dead_hook, dead_horn ],
symbols[Group3]= [ j, J ]
};
key <AC08> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ k, K ],
symbols[Group2]= [ k, K, kra, ampersand ],
symbols[Group3]= [ k, K ]
};
key <AC09> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_ALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_ALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ l, L ],
symbols[Group2]= [ l, L, lstroke, Lstroke ],
symbols[Group3]= [ l, L ]
};
key <AC10> {
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
symbols[Group1]= [ semicolon, colon ],
symbols[Group2]= [ ccedilla, Ccedilla, dead_acute, dead_doubleacute ],
symbols[Group3]= [ semicolon, colon ]
};
key <AC11> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ apostrophe, quotedbl ],
symbols[Group2]= [ masculine, ordfeminine, dead_circumflex, dead_caron ],
symbols[Group3]= [ apostrophe, quotedbl ]
};
key <TLDE> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ grave, asciitilde ],
symbols[Group2]= [ backslash, bar, notsign, notsign ],
symbols[Group3]= [ grave, asciitilde ]
};
key <LFSH> { [ Shift_L ] };
key <BKSL> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ backslash, bar ],
symbols[Group2]= [ dead_tilde, dead_circumflex, dead_grave, dead_breve ],
symbols[Group3]= [ backslash, bar ]
};
key <AB01> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ z, Z ],
symbols[Group2]= [ z, Z, guillemotleft, less ],
symbols[Group3]= [ z, Z ]
};
key <AB02> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ x, X ],
symbols[Group2]= [ x, X, guillemotright, greater ],
symbols[Group3]= [ x, X ]
};
key <AB03> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ c, C ],
symbols[Group2]= [ c, C, cent, copyright ],
symbols[Group3]= [ c, C ]
};
key <AB04> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ v, V ],
symbols[Group2]= [ v, V, leftdoublequotemark, leftsinglequotemark ],
symbols[Group3]= [ v, V ]
};
key <AB05> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ b, B ],
symbols[Group2]= [ b, B, rightdoublequotemark, rightsinglequotemark ],
symbols[Group3]= [ b, B ]
};
key <AB06> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_ALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_ALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ n, N ],
symbols[Group2]= [ n, N, n, N ],
symbols[Group3]= [ n, N ]
};
key <AB07> {
- type[group1]= "ALPHABETIC",
- type[group2]= "FOUR_LEVEL_SEMIALPHABETIC",
- type[group3]= "ALPHABETIC",
+ type[Group1]= "ALPHABETIC",
+ type[Group2]= "FOUR_LEVEL_SEMIALPHABETIC",
+ type[Group3]= "ALPHABETIC",
symbols[Group1]= [ m, M ],
symbols[Group2]= [ m, M, mu, masculine ],
symbols[Group3]= [ m, M ]
};
key <AB08> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ comma, less ],
symbols[Group2]= [ comma, semicolon, horizconnector, multiply ],
symbols[Group3]= [ comma, less ]
};
key <AB09> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ period, greater ],
symbols[Group2]= [ period, colon, periodcentered, division ],
symbols[Group3]= [ period, greater ]
};
key <AB10> {
- type[group2]= "FOUR_LEVEL",
+ type[Group2]= "FOUR_LEVEL",
symbols[Group1]= [ slash, question ],
symbols[Group2]= [ minus, underscore, dead_belowdot, dead_abovedot ],
symbols[Group3]= [ slash, question ]
@@ -1526,8 +1526,8 @@ xkb_symbols "pc_us_pt_2_us_3_inet(evdev)_group(shift_caps_toggle)_compose(ralt)"
symbols[Group1]= [ Print, Sys_Req ]
};
key <RALT> {
- type[group1]= "TWO_LEVEL",
- type[group2]= "ONE_LEVEL",
+ type[Group1]= "TWO_LEVEL",
+ type[Group2]= "ONE_LEVEL",
symbols[Group1]= [ Multi_key, Multi_key ],
symbols[Group2]= [ ISO_Level3_Shift ]
};
diff --git a/test/data/keymaps/stringcomp.data b/test/data/keymaps/stringcomp.data
index 2fd27df..bc9b6ab 100644
--- a/test/data/keymaps/stringcomp.data
+++ b/test/data/keymaps/stringcomp.data
@@ -880,16 +880,16 @@ xkb_compatibility "complete_caps(caps_lock)_4_misc(assign_shift_left_action)_4_l
action= PtrBtn(button=3,count=2);
};
interpret Pointer_Drag_Dflt+AnyOfOrNone(all) {
- action= LockPtrBtn(button=default);
+ action= LockPtrBtn(button=default,affect=both);
};
interpret Pointer_Drag1+AnyOfOrNone(all) {
- action= LockPtrBtn(button=1);
+ action= LockPtrBtn(button=1,affect=both);
};
interpret Pointer_Drag2+AnyOfOrNone(all) {
- action= LockPtrBtn(button=2);
+ action= LockPtrBtn(button=2,affect=both);
};
interpret Pointer_Drag3+AnyOfOrNone(all) {
- action= LockPtrBtn(button=3);
+ action= LockPtrBtn(button=3,affect=both);
};
interpret Pointer_EnableKeys+AnyOfOrNone(all) {
action= LockControls(controls=MouseKeys);
diff --git a/test/data/symbols/garbage b/test/data/symbols/garbage
new file mode 100644
index 0000000..98c5e28
--- /dev/null
+++ b/test/data/symbols/garbage
@@ -0,0 +1,14 @@
+default alphanumeric_keys
+xkb_symbols "garbage" {
+ include "us"
+
+ name[Group1]= "My garbage Layout";
+
+ // The garbage keysym will *not* override the corresponding symbol from the
+ // 'us' layout
+ key <TLDE> { [ keysym_is_garbage, exclam ] };
+
+ // AE13 is unused by 'us', use it to avoid fallback to the 'us' definition.
+ // Define with 2 levels but first level is a garbage symbol.
+ key <AE13> { [ keysym_is_garbage, asciitilde ] };
+};
diff --git a/test/keymap.c b/test/keymap.c
index a6bade8..816c2e4 100644
--- a/test/keymap.c
+++ b/test/keymap.c
@@ -31,8 +31,51 @@
#include "test.h"
-int
-main(void)
+static void
+test_garbage_key(void)
+{
+ struct xkb_context *context = test_get_context(0);
+ struct xkb_keymap *keymap;
+ xkb_keycode_t kc;
+ int nsyms;
+ const xkb_keysym_t *syms;
+ const xkb_layout_index_t first_layout = 0;
+ xkb_level_index_t nlevels;
+
+ assert(context);
+
+ keymap = test_compile_rules(context, NULL, NULL, "garbage", NULL, NULL);
+ assert(keymap);
+
+ /* TLDE uses the 'us' sym on the first level and is thus [grave, exclam] */
+ kc = xkb_keymap_key_by_name(keymap, "TLDE");
+ assert(kc != XKB_KEYCODE_INVALID);
+ nlevels = xkb_keymap_num_levels_for_key(keymap, kc, first_layout);
+ assert(nlevels == 2);
+ nsyms = xkb_keymap_key_get_syms_by_level(keymap, kc, first_layout, 0, &syms);
+ assert(nsyms == 1);
+ assert(*syms == XKB_KEY_grave); /* fallback from 'us' */
+ nsyms = xkb_keymap_key_get_syms_by_level(keymap, kc, first_layout, 1, &syms);
+ assert(nsyms == 1);
+ assert(*syms == XKB_KEY_exclam);
+
+ /* AE13 has no 'us' fallback and ends up as [NoSymbol, asciitilde] */
+ kc = xkb_keymap_key_by_name(keymap, "AE13");
+ assert(kc != XKB_KEYCODE_INVALID);
+ nlevels = xkb_keymap_num_levels_for_key(keymap, kc, first_layout);
+ assert(nlevels == 2);
+ nsyms = xkb_keymap_key_get_syms_by_level(keymap, kc, first_layout, 0, &syms);
+ assert(nsyms == 0);
+ nsyms = xkb_keymap_key_get_syms_by_level(keymap, kc, first_layout, 1, &syms);
+ assert(nsyms == 1);
+ assert(*syms == XKB_KEY_asciitilde);
+
+ xkb_keymap_unref(keymap);
+ xkb_context_unref(context);
+}
+
+static void
+test_keymap(void)
{
struct xkb_context *context = test_get_context(0);
struct xkb_keymap *keymap;
@@ -105,3 +148,12 @@ main(void)
xkb_keymap_unref(keymap);
xkb_context_unref(context);
}
+
+int
+main(void)
+{
+ test_garbage_key();
+ test_keymap();
+
+ return 0;
+}
diff --git a/test/xkeyboard-config-test.py.in b/test/xkeyboard-config-test.py.in
index ed37d7e..001f1b6 100755
--- a/test/xkeyboard-config-test.py.in
+++ b/test/xkeyboard-config-test.py.in
@@ -42,6 +42,7 @@ def xkbcommontool(rmlvo):
o = rmlvo.get('o', None)
args = [
'xkbcli-compile-keymap', # this is run in the builddir
+ '--verbose',
'--rules', r,
'--model', m,
'--layout', l,
@@ -61,6 +62,12 @@ def xkbcommontool(rmlvo):
universal_newlines=True)
if verbose:
print(output, file=out)
+
+ if "unrecognized keysym" in output:
+ for line in output.split('\n'):
+ if "unrecognized keysym" in line:
+ print('ERROR: {}'.format(line))
+ success = False
except subprocess.CalledProcessError as err:
print('ERROR: Failed to compile: {}'.format(' '.join(args)), file=out)
print(err.output, file=out)
diff --git a/xkbcommon/xkbcommon.h b/xkbcommon/xkbcommon.h
index d6a02a7..ee7143c 100644
--- a/xkbcommon/xkbcommon.h
+++ b/xkbcommon/xkbcommon.h
@@ -208,6 +208,15 @@ typedef uint32_t xkb_keysym_t;
* Therefore, it is not safe to use the name as a unique identifier for a
* layout. Layout names are case-sensitive.
*
+ * Layout names are specified in the layout's definition, for example
+ * "English (US)". These are different from the (conventionally) short names
+ * which are used to locate the layout, for example "us" or "us(intl)". These
+ * names are not present in a compiled keymap.
+ *
+ * If the user selects layouts from a list generated from the XKB registry
+ * (using libxkbregistry or directly), and this metadata is needed later on, it
+ * is recommended to store it along with the keymap.
+ *
* Layouts are also called "groups" by XKB.
*
* @sa xkb_keymap_num_layouts() xkb_keymap_num_layouts_for_key()
@@ -1087,6 +1096,7 @@ xkb_keymap_num_layouts(struct xkb_keymap *keymap);
* a name, returns NULL.
*
* @sa xkb_layout_index_t
+ * For notes on layout names.
* @memberof xkb_keymap
*/
const char *
@@ -1099,6 +1109,8 @@ xkb_keymap_layout_get_name(struct xkb_keymap *keymap, xkb_layout_index_t idx);
* XKB_LAYOUT_INVALID. If more than one layout in the keymap has this name,
* returns the lowest index among them.
*
+ * @sa xkb_layout_index_t
+ * For notes on layout names.
* @memberof xkb_keymap
*/
xkb_layout_index_t