diff options
author | Haibo Huang <hhb@google.com> | 2020-11-24 20:52:35 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2021-01-25 10:21:07 -0800 |
commit | 91f38399c2ea2fca0a88d624fc72d203df0e108a (patch) | |
tree | fb7f4b6e3a06f43f823ea3e298418084e0a7175b | |
parent | cda6b377eb5ce92136d53566702110c00b76cff8 (diff) | |
download | libxkbcommon-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.yml | 2 | ||||
-rw-r--r-- | Android.bp | 4 | ||||
-rw-r--r-- | METADATA | 8 | ||||
-rw-r--r-- | NEWS | 19 | ||||
-rw-r--r-- | bench/x11.c | 108 | ||||
l---------[-rw-r--r--] | config.h | 62 | ||||
-rw-r--r-- | config/config.h | 61 | ||||
-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.build | 29 | ||||
-rw-r--r-- | src/context.c | 3 | ||||
-rw-r--r-- | src/context.h | 3 | ||||
-rw-r--r-- | src/x11/keymap.c | 47 | ||||
-rw-r--r-- | src/x11/util.c | 55 | ||||
-rw-r--r-- | src/xkbcomp/.gitignore | 2 | ||||
-rw-r--r-- | src/xkbcomp/keymap-dump.c | 10 | ||||
-rw-r--r-- | src/xkbcomp/parser.y | 4 | ||||
-rw-r--r-- | test/data/keymaps/host.xkb | 630 | ||||
-rw-r--r-- | test/data/keymaps/stringcomp.data | 8 | ||||
-rw-r--r-- | test/data/symbols/garbage | 14 | ||||
-rw-r--r-- | test/keymap.c | 56 | ||||
-rwxr-xr-x | test/xkeyboard-config-test.py.in | 7 | ||||
-rw-r--r-- | xkbcommon/xkbcommon.h | 12 |
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: | @@ -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, @@ -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 } } @@ -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; +} @@ -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 |