Add xkeyboard-config: X11 keyboard layouts compiled to Zig
Turn a keycode + modifiers into a character. The input module delivers HID
usage keycodes but nothing mapped them to characters; rather than hand-maintain
layout tables, vendor the X11 xkeyboard-config database and compile it to native
Zig at build time (no X11 runtime), the way make-initial-ramdisk.py packs the
ramdisk.
- tools/make-xkeyboard-config.py: `fetch` downloads the pinned xkeyboard-config
release (2.44, sha256-verified), resolves the include graph for the configured
layouts, and vendors only the reached symbols files + keysymdef.h + COPYING +
PROVENANCE into library/xkeyboard-config/vendor/. `generate` parses that
(keycodes via a HID->xkb-name table, symbols with include/augment/override and
per-key type, keysymdef for keysym->Unicode) and emits generated/layouts.zig
deterministically.
- library/xkeyboard-config/xkeyboard-config.zig: the API over the generated data
— map(layout, hid_usage, mods) -> { keysym, character }, byName, and the
level-selection semantics (the generated tables stay pure data). Host tests
assert US letters/digits with Shift/Caps, GB £ vs US # on Shift+3, and French
AZERTY q-where-US-has-a — the end-to-end proof of the parse->emit->lookup path.
- build.zig: `xkeyboard-config` + `layouts` modules, the test wired into
`zig build test`, and a `zig build gen-xkeyboard-config` convenience step.
- Layouts: us, gb, de, fr, es, dvorak. Scope (documented): group 1, no dead-key
composition, curated key types. Standalone library; wiring it into the input
path to fill KeyEvent.character is a documented follow-up.
zig build test green (incl. the new keymap tests); regeneration is byte-identical;
full QEMU suite 48/48 (unaffected — no kernel/runtime/service change).
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# xkeyboard-config — X11 keyboard layouts, compiled to Zig
|
||||
|
||||
This module turns a physical key (a **USB HID usage**, as the [input module](../../docs/input.md)
|
||||
delivers in `KeyEvent.keycode`) plus a modifier state into a **keysym** and, when the key
|
||||
produces one, a **character** (a Unicode scalar). It is what lets a `keycode` become a
|
||||
`character` — a keymap — without danos shipping an X11 runtime.
|
||||
|
||||
The layout data comes from the X11 [xkeyboard-config](https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config)
|
||||
database, but it is **compiled to native Zig at build time** rather than parsed at runtime.
|
||||
`tools/make-xkeyboard-config.py` reads the vendored xkb data and emits pure-data tables into
|
||||
`generated/layouts.zig`; `xkeyboard-config.zig` is the hand-written API over them. This is
|
||||
the same build-time-codegen pattern as `tools/make-initial-ramdisk.py`.
|
||||
|
||||
## Using it
|
||||
|
||||
```zig
|
||||
const xkb = @import("xkeyboard-config");
|
||||
|
||||
const m = xkb.map(xkb.us, key_event.keycode, .{ .shift = shift_held, .caps_lock = caps });
|
||||
if (m.character) |ch| { /* a printable Unicode scalar */ }
|
||||
// m.keysym is always set (e.g. an X11 keysym for Return / F1 / a dead key).
|
||||
|
||||
const layout = xkb.byName("gb") orelse xkb.us; // choose a layout by name
|
||||
for (xkb.all) |l| { /* enumerate available layouts */ }
|
||||
```
|
||||
|
||||
`Modifiers` carries `shift`, `caps_lock`, `level3` (AltGr), and `control`. `map` selects the
|
||||
level from the key's XKB *type* (the generated data) and those modifiers (the policy, in
|
||||
`xkeyboard-config.zig`), so data and semantics stay separable.
|
||||
|
||||
Layouts: **us, gb, de, fr, es, dvorak**.
|
||||
|
||||
## Regenerating
|
||||
|
||||
```sh
|
||||
python3 tools/make-xkeyboard-config.py fetch # network: download + vendor the data subset
|
||||
python3 tools/make-xkeyboard-config.py generate # offline: emit generated/layouts.zig
|
||||
# or, from the build:
|
||||
zig build gen-xkeyboard-config
|
||||
```
|
||||
|
||||
- **`fetch`** downloads the pinned xkeyboard-config release (version + sha256 in the script),
|
||||
resolves the `include` graph for the configured layouts, and vendors *only* the symbols
|
||||
files actually reached (plus `keysymdef.h`, `COPYING`, and `PROVENANCE.md`) into `vendor/`.
|
||||
Run it when bumping the version or adding a layout.
|
||||
- **`generate`** is deterministic and offline — same vendored input produces byte-identical
|
||||
output. To add a layout, extend `TARGETS` (and `HID_TO_NAME` if a new physical key is
|
||||
involved), then re-run `fetch` (to vendor any new includes) and `generate`.
|
||||
|
||||
## Scope
|
||||
|
||||
A pragmatic subset, enough for real Latin-script typing:
|
||||
|
||||
- **Group 1 only** — no multi-layout group switching.
|
||||
- **No dead-key / compose composition** — a dead key returns its keysym with no `character`
|
||||
(composing `´` + `e` → `é` is a higher layer's job).
|
||||
- **Curated key types** — the common XKB types (one/two-level, alphabetic, four-level, …);
|
||||
unmapped keys and unknown types fall back to level-by-shift.
|
||||
- **6 layouts** — extend via `TARGETS` as above.
|
||||
|
||||
## Licensing
|
||||
|
||||
xkeyboard-config and `keysymdef.h` (xorgproto) are MIT/X11 licensed. The vendored data
|
||||
subset carries the upstream `vendor/COPYING`, and `vendor/PROVENANCE.md` records the exact
|
||||
version, source URL, and sha256. The generated tables are a derived work under the same terms.
|
||||
File diff suppressed because it is too large
Load Diff
+190
@@ -0,0 +1,190 @@
|
||||
Copyright 1996 by Joseph Moss
|
||||
Copyright (C) 2002-2007 Free Software Foundation, Inc.
|
||||
Copyright (C) Dmitry Golubev <lastguru@mail.ru>, 2003-2004
|
||||
Copyright (C) 2004, Gregory Mokhin <mokhin@bog.msu.ru>
|
||||
Copyright (C) 2006 Erdal Ronahî
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation, and that the name of the copyright holder(s) not be used in
|
||||
advertising or publicity pertaining to distribution of the software without
|
||||
specific, written prior permission. The copyright holder(s) makes no
|
||||
representations about the suitability of this software for any purpose. It
|
||||
is provided "as is" without express or implied warranty.
|
||||
|
||||
THE COPYRIGHT HOLDER(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
Copyright (c) 1996 Digital Equipment Corporation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
|
||||
THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the Digital Equipment
|
||||
Corporation shall not be used in advertising or otherwise to promote
|
||||
the sale, use or other dealings in this Software without prior written
|
||||
authorization from Digital Equipment Corporation.
|
||||
|
||||
|
||||
Copyright 1996, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from The Open Group.
|
||||
|
||||
|
||||
Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Copyright (c) 1996 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
Copyright (c) 1996 X Consortium
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the X Consortium shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the X Consortium.
|
||||
|
||||
|
||||
Copyright (C) 2004, 2006 Ævar Arnfjörð Bjarmason <avarab@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of a copyright holder shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization of
|
||||
the copyright holder.
|
||||
|
||||
|
||||
Copyright (C) 1999, 2000 by Anton Zinoviev <anton@lml.bas.bg>
|
||||
|
||||
This software may be used, modified, copied, distributed, and sold,
|
||||
in both source and binary form provided that the above copyright
|
||||
and these terms are retained. Under no circumstances is the author
|
||||
responsible for the proper functioning of this software, nor does
|
||||
the author assume any responsibility for damages incurred with its
|
||||
use.
|
||||
|
||||
Permission is granted to anyone to use, distribute and modify
|
||||
this file in any way, provided that the above copyright notice
|
||||
is left intact and the author of the modification summarizes
|
||||
the changes in this header.
|
||||
|
||||
This file is distributed without any expressed or implied warranty.
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
# Vendored xkeyboard-config subset
|
||||
|
||||
- **Package**: xkeyboard-config 2.44
|
||||
- **Source**: https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/archive/xkeyboard-config-2.44/xkeyboard-config-2.44.tar.gz
|
||||
- **sha256**: `35e34edeaf4e8da8d0696ff6b241ee11ddb1b8c6730bac7252d4d0a88ea5f05b`
|
||||
- **keysymdef.h**: xorgproto, copied from `/opt/homebrew/include/X11/keysymdef.h`
|
||||
- **License**: MIT/X11 (see COPYING)
|
||||
|
||||
Only the symbols files reachable from the generated layouts (tools/make-xkeyboard-config.py `TARGETS`) are vendored; regenerate with
|
||||
`python3 tools/make-xkeyboard-config.py fetch` then `... generate`.
|
||||
|
||||
Vendored symbols files:
|
||||
|
||||
- `symbols/de`
|
||||
- `symbols/es`
|
||||
- `symbols/fr`
|
||||
- `symbols/gb`
|
||||
- `symbols/kpdl`
|
||||
- `symbols/latin`
|
||||
- `symbols/level3`
|
||||
- `symbols/us`
|
||||
+2584
File diff suppressed because it is too large
Load Diff
+1232
File diff suppressed because it is too large
Load Diff
+250
@@ -0,0 +1,250 @@
|
||||
// Keyboard layouts for Spain.
|
||||
|
||||
// Modified for a real Spanish keyboard by Jon Tombs.
|
||||
default partial alphanumeric_keys
|
||||
xkb_symbols "basic" {
|
||||
|
||||
include "latin(type4)"
|
||||
|
||||
name[Group1]="Spanish";
|
||||
|
||||
key <TLDE> { [ masculine, ordfeminine, backslash, backslash ] };
|
||||
key <AE01> { [ 1, exclam, bar, exclamdown ] };
|
||||
key <AE03> { [ 3, periodcentered, numbersign, sterling ] };
|
||||
key <AE04> { [ 4, dollar, asciitilde, dollar ] };
|
||||
key <AE11> { [apostrophe, question, backslash, questiondown ] };
|
||||
key <AE12> { [exclamdown, questiondown, dead_cedilla, dead_ogonek] };
|
||||
|
||||
key <AD11> { [dead_grave, dead_circumflex, bracketleft, dead_abovering ] };
|
||||
key <AD12> { [ plus, asterisk, bracketright, dead_macron ] };
|
||||
|
||||
key <AC10> { [ ntilde, Ntilde, dead_tilde, dead_doubleacute ] };
|
||||
key <AC11> { [dead_acute, dead_diaeresis, braceleft, dead_caron ] };
|
||||
key <BKSL> { [ ccedilla, Ccedilla, braceright, dead_breve ] };
|
||||
|
||||
include "level3(ralt_switch)"
|
||||
};
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "winkeys" {
|
||||
|
||||
include "es(basic)"
|
||||
name[Group1]="Spanish (Windows)";
|
||||
include "eurosign(5)"
|
||||
};
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "nodeadkeys" {
|
||||
|
||||
include "es(basic)"
|
||||
|
||||
name[Group1]="Spanish (no dead keys)";
|
||||
|
||||
key <AE12> { [exclamdown, questiondown, cedilla, ogonek ] };
|
||||
key <AD11> { [ grave, asciicircum, bracketleft, degree ] };
|
||||
key <AD12> { [ plus, asterisk, bracketright, macron ] };
|
||||
key <AC07> { [ j, J, ezh, EZH ] };
|
||||
key <AC10> { [ ntilde, Ntilde, asciitilde, doubleacute ] };
|
||||
key <AC11> { [ acute, diaeresis, braceleft, caron ] };
|
||||
key <BKSL> { [ ccedilla, Ccedilla, braceright, breve ] };
|
||||
key <AB10> { [ minus, underscore, ellipsis, abovedot ] };
|
||||
};
|
||||
|
||||
// Spanish Dvorak mapping (note R-H exchange)
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "dvorak" {
|
||||
|
||||
name[Group1]="Spanish (Dvorak)";
|
||||
|
||||
key <TLDE> {[ masculine, ordfeminine, backslash, degree ]};
|
||||
key <AE01> {[ 1, exclam, bar, onesuperior ]};
|
||||
key <AE02> {[ 2, quotedbl, at, twosuperior ]};
|
||||
key <AE03> {[ 3, periodcentered, numbersign, threesuperior ]};
|
||||
key <AE04> {[ 4, dollar, asciitilde, onequarter ]};
|
||||
key <AE05> {[ 5, percent, brokenbar, fiveeighths ]};
|
||||
key <AE06> {[ 6, ampersand, notsign, threequarters ]};
|
||||
key <AE07> {[ 7, slash, onehalf, seveneighths ]};
|
||||
key <AE08> {[ 8, parenleft, oneeighth, threeeighths ]};
|
||||
key <AE09> {[ 9, parenright, asciicircum ]};
|
||||
key <AE10> {[ 0, equal, grave, dead_doubleacute ]};
|
||||
key <AE11> {[ apostrophe, question, dead_macron, dead_ogonek ]};
|
||||
key <AE12> {[ exclamdown, questiondown, dead_breve, dead_abovedot ]};
|
||||
|
||||
key <AD01> {[ period, colon, less, guillemotleft ]};
|
||||
key <AD02> {[ comma, semicolon, greater, guillemotright ]};
|
||||
key <AD03> {[ ntilde, Ntilde, lstroke, Lstroke ]};
|
||||
key <AD04> {[ p, P, paragraph ]};
|
||||
key <AD05> {[ y, Y, yen ]};
|
||||
key <AD06> {[ f, F, tslash, Tslash ]};
|
||||
key <AD07> {[ g, G, dstroke, Dstroke ]};
|
||||
key <AD08> {[ c, C, cent, copyright ]};
|
||||
key <AD09> {[ h, H, hstroke, Hstroke ]};
|
||||
key <AD10> {[ l, L, sterling ]};
|
||||
key <AD11> {[ dead_grave, dead_circumflex, bracketleft, dead_caron ]};
|
||||
key <AD12> {[ plus, asterisk, bracketright, plusminus ]};
|
||||
|
||||
key <AC01> {[ a, A, ae, AE ]};
|
||||
key <AC02> {[ o, O, oslash, Oslash ]};
|
||||
key <AC03> {[ e, E, EuroSign ]};
|
||||
key <AC04> {[ u, U, aring, Aring ]};
|
||||
key <AC05> {[ i, I, oe, OE ]};
|
||||
key <AC06> {[ d, D, eth, ETH ]};
|
||||
key <AC07> {[ r, R, registered, trademark ]};
|
||||
key <AC08> {[ t, T, thorn, THORN ]};
|
||||
key <AC09> {[ n, N, eng, ENG ]};
|
||||
key <AC10> {[ s, S, ssharp, section ]};
|
||||
key <AC11> {[ dead_acute, dead_diaeresis, braceleft, dead_tilde ]};
|
||||
key <BKSL> {[ ccedilla, Ccedilla, braceright, dead_cedilla ]};
|
||||
|
||||
key <LSGT> {[ less, greater, guillemotleft, guillemotright ]};
|
||||
key <AB01> {[ minus, underscore, hyphen, macron ]};
|
||||
key <AB02> {[ q, Q, currency ]};
|
||||
key <AB03> {[ j, J ]};
|
||||
key <AB04> {[ k, K, kra ]};
|
||||
key <AB05> {[ x, X, multiply, division ]};
|
||||
key <AB06> {[ b, B ]};
|
||||
key <AB07> {[ m, M, mu ]};
|
||||
key <AB08> {[ w, W ]};
|
||||
key <AB09> {[ v, V ]};
|
||||
key <AB10> {[ z, Z ]};
|
||||
|
||||
include "level3(ralt_switch)"
|
||||
};
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "cat" {
|
||||
|
||||
include "es(basic)"
|
||||
|
||||
name[Group1]="Catalan (Spain, with middle-dot L)";
|
||||
|
||||
key <AC09> { [ l, L, 0x1000140, 0x100013F ] };
|
||||
};
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "ast" {
|
||||
|
||||
include "es(basic)"
|
||||
|
||||
name[Group1]="Asturian (Spain, with bottom-dot H and L)";
|
||||
|
||||
key <AC06> { [ h, H, 0x1001E25, 0x1001E24 ] };
|
||||
key <AC09> { [ l, L, 0x1001E37, 0x1001E36 ] };
|
||||
};
|
||||
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "olpc" {
|
||||
|
||||
// #HW-SPECIFIC
|
||||
|
||||
// http://wiki.laptop.org/go/OLPC_Spanish_Keyboard
|
||||
|
||||
include "us(basic)"
|
||||
name[Group1]="Spanish";
|
||||
|
||||
key <AE00> { [ masculine, ordfeminine ] };
|
||||
key <AE01> { [ 1, exclam, bar ] };
|
||||
key <AE02> { [ 2, quotedbl, at ] };
|
||||
key <AE03> { [ 3, dead_grave, numbersign, grave ] };
|
||||
key <AE05> { [ 5, percent, asciicircum, dead_circumflex ] };
|
||||
key <AE06> { [ 6, ampersand, notsign ] };
|
||||
key <AE07> { [ 7, slash, backslash ] };
|
||||
key <AE08> { [ 8, parenleft ] };
|
||||
key <AE09> { [ 9, parenright ] };
|
||||
key <AE10> { [ 0, equal ] };
|
||||
key <AE11> { [ apostrophe, question ] };
|
||||
key <AE12> { [ exclamdown, questiondown ] };
|
||||
|
||||
key <AD03> { [ e, E, EuroSign ] };
|
||||
key <AD11> { [ dead_acute, dead_diaeresis, acute, dead_abovering ] };
|
||||
key <AD12> { [ bracketleft, braceleft ] };
|
||||
|
||||
key <AC10> { [ ntilde, Ntilde ] };
|
||||
key <AC11> { [ plus, asterisk, dead_tilde ] };
|
||||
key <AC12> { [ bracketright, braceright, section ] };
|
||||
|
||||
key <AB08> { [ comma, semicolon ] };
|
||||
key <AB09> { [ period, colon ] };
|
||||
key <AB10> { [ minus, underscore ] };
|
||||
|
||||
key <I219> { [ less, greater, ISO_Next_Group ] };
|
||||
|
||||
include "level3(ralt_switch)"
|
||||
};
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "olpcm" {
|
||||
|
||||
// #HW-SPECIFIC
|
||||
|
||||
// Mechanical (non-membrane) OLPC Spanish keyboard layout.
|
||||
// See: http://wiki.laptop.org/go/OLPC_Spanish_Non-membrane_Keyboard
|
||||
|
||||
include "us(basic)"
|
||||
name[Group1]="Spanish";
|
||||
|
||||
key <AE00> { [ questiondown, exclamdown, backslash ] };
|
||||
key <AE01> { [ 1, exclam, bar ] };
|
||||
key <AE02> { [ 2, quotedbl, at ] };
|
||||
key <AE03> { [ 3, dead_grave, numbersign, grave ] };
|
||||
key <AE04> { [ 4, dollar, asciitilde, dead_tilde ] };
|
||||
key <AE05> { [ 5, percent, asciicircum, dead_circumflex ] };
|
||||
key <AE06> { [ 6, ampersand, notsign ] };
|
||||
key <AE07> { [ 7, slash, backslash ] }; // no '\' label on olpcm, leave for compatibility
|
||||
key <AE08> { [ 8, parenleft, masculine ] };
|
||||
key <AE09> { [ 9, parenright, ordfeminine ] };
|
||||
key <AE10> { [ 0, equal ] };
|
||||
key <AE11> { [ apostrophe, question ] };
|
||||
|
||||
key <AD03> { [ e, E, EuroSign ] };
|
||||
key <AD11> { [ dead_acute, dead_diaeresis, dead_abovering, acute ] };
|
||||
key <AD12> { [ plus, asterisk ] };
|
||||
|
||||
key <AC10> { [ ntilde, Ntilde ] };
|
||||
// no AC11 or AC12 on olpcm
|
||||
|
||||
key <AB08> { [ comma, semicolon ] };
|
||||
key <AB09> { [ period, colon ] };
|
||||
key <AB10> { [ minus, underscore ] };
|
||||
|
||||
key <AA02> { [ less, greater ] };
|
||||
key <AA06> { [ bracketleft, braceleft, ccedilla, Ccedilla ] };
|
||||
key <AA07> { [ bracketright, braceright ] };
|
||||
|
||||
include "level3(ralt_switch)"
|
||||
};
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "deadtilde" {
|
||||
|
||||
include "es(basic)"
|
||||
|
||||
name[Group1]="Spanish (dead tilde)";
|
||||
|
||||
key <AE04> { [ 4, dollar, dead_tilde, dollar ] };
|
||||
key <AC10> { [ ntilde, Ntilde, asciitilde, dead_doubleacute ] };
|
||||
};
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "olpc2" {
|
||||
// #HW-SPECIFIC
|
||||
|
||||
// Modified variant of US International layout, specifically for Peru
|
||||
// Contact: Sayamindu Dasgupta <sayamindu@laptop.org>
|
||||
|
||||
include "us(olpc)"
|
||||
name[Group1]="Spanish";
|
||||
|
||||
key <AE03> { [ 3, numbersign, dead_grave, dead_grave] }; // combining grave
|
||||
key <I236> { [ XF86Start ] };
|
||||
|
||||
include "level3(ralt_switch)"
|
||||
};
|
||||
|
||||
// EXTRAS:
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "sun_type6" {
|
||||
include "sun_vndr/es(sun_type6)"
|
||||
};
|
||||
+1404
File diff suppressed because it is too large
Load Diff
+249
@@ -0,0 +1,249 @@
|
||||
// Keyboard layouts for Great Britain.
|
||||
|
||||
default partial alphanumeric_keys
|
||||
xkb_symbols "basic" {
|
||||
|
||||
// The basic UK layout, also known as the IBM 166 layout,
|
||||
// but with the useless brokenbar pushed two levels up.
|
||||
|
||||
include "latin"
|
||||
|
||||
name[Group1]="English (UK)";
|
||||
|
||||
key <TLDE> { [ grave, notsign, bar, bar ] };
|
||||
key <AE02> { [ 2, quotedbl, twosuperior, oneeighth ] };
|
||||
key <AE03> { [ 3, sterling, threesuperior, sterling ] };
|
||||
key <AE04> { [ 4, dollar, EuroSign, onequarter ] };
|
||||
|
||||
key <AC11> { [apostrophe, at, dead_circumflex, dead_caron] };
|
||||
key <BKSL> { [numbersign, asciitilde, dead_grave, dead_breve ] };
|
||||
|
||||
key <LSGT> { [ backslash, bar, bar, brokenbar ] };
|
||||
|
||||
include "level3(ralt_switch)"
|
||||
};
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "intl" {
|
||||
|
||||
// A UK layout but with five accents made into dead keys:
|
||||
// grave, diaeresis, circumflex, acute, and tilde.
|
||||
// By Phil Jones <philjones1 at blueyonder.co.uk>.
|
||||
|
||||
include "latin"
|
||||
|
||||
name[Group1]="English (UK, intl., with dead keys)";
|
||||
|
||||
key <TLDE> { [ dead_grave, notsign, bar, bar ] };
|
||||
key <AE02> { [ 2, dead_diaeresis, twosuperior, onehalf ] };
|
||||
key <AE03> { [ 3, sterling, threesuperior, onethird ] };
|
||||
key <AE04> { [ 4, dollar, EuroSign, onequarter ] };
|
||||
key <AE06> { [ 6, dead_circumflex, threequarters, onesixth ] };
|
||||
|
||||
key <AC11> { [ dead_acute, at, apostrophe, bar ] };
|
||||
key <BKSL> { [ numbersign, dead_tilde, bar, bar ] };
|
||||
|
||||
key <LSGT> { [ backslash, bar, bar, bar ] };
|
||||
key <AB08> { [ comma, less, ccedilla, Ccedilla ] };
|
||||
|
||||
include "level3(ralt_switch)"
|
||||
};
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "extd" {
|
||||
// Clone of the Microsoft "United Kingdom Extended" layout, which
|
||||
// includes dead keys for: grave; diaeresis; circumflex; tilde; and
|
||||
// accute. It also enables direct access to accute characters using
|
||||
// the Multi_key (Alt Gr).
|
||||
//
|
||||
// Taken from...
|
||||
// "Windows Keyboard Layouts"
|
||||
// https://docs.microsoft.com/en-gb/globalization/windows-keyboard-layouts#U
|
||||
//
|
||||
// -- Jonathan Miles <jon@cybah.co.uk>
|
||||
|
||||
include "latin"
|
||||
|
||||
name[Group1]="English (UK, extended, Windows)";
|
||||
|
||||
key <TLDE> { [ dead_grave, notsign, brokenbar, NoSymbol ] };
|
||||
key <AE02> { [ 2, quotedbl, dead_diaeresis, onehalf ] };
|
||||
key <AE03> { [ 3, sterling, threesuperior, onethird ] };
|
||||
key <AE04> { [ 4, dollar, EuroSign, onequarter ] };
|
||||
key <AE06> { [ 6, asciicircum, dead_circumflex, NoSymbol ] };
|
||||
|
||||
key <AD02> { [ w, W, wacute, Wacute ] };
|
||||
key <AD03> { [ e, E, eacute, Eacute ] };
|
||||
key <AD06> { [ y, Y, yacute, Yacute ] };
|
||||
key <AD07> { [ u, U, uacute, Uacute ] };
|
||||
key <AD08> { [ i, I, iacute, Iacute ] };
|
||||
key <AD09> { [ o, O, oacute, Oacute ] };
|
||||
key <AD12> { [ bracketright, braceright, NoSymbol, bar ] };
|
||||
|
||||
key <AC01> { [ a, A, aacute, Aacute ] };
|
||||
key <AC11> { [ apostrophe, at, dead_acute, grave ] };
|
||||
key <BKSL> { [ numbersign, asciitilde, dead_tilde, backslash ] };
|
||||
|
||||
key <LSGT> { [ backslash, bar, NoSymbol, NoSymbol ] };
|
||||
key <AB03> { [ c, C, ccedilla, Ccedilla ] };
|
||||
|
||||
include "level3(ralt_switch)"
|
||||
};
|
||||
|
||||
// Describe the differences between the US Colemak layout
|
||||
// and a UK variant. By Andy Buckley (andy@insectnation.org)
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "colemak" {
|
||||
include "us(colemak)"
|
||||
|
||||
name[Group1]="English (UK, Colemak)";
|
||||
|
||||
key <TLDE> { [ grave, notsign, bar, asciitilde ] };
|
||||
key <AE02> { [ 2, quotedbl, twosuperior, oneeighth ] };
|
||||
key <AE03> { [ 3, sterling, threesuperior, sterling ] };
|
||||
key <AE04> { [ 4, dollar, EuroSign, onequarter ] };
|
||||
|
||||
key <AC11> { [apostrophe, at, dead_circumflex, dead_caron] };
|
||||
key <BKSL> { [numbersign, asciitilde, dead_grave, dead_breve ] };
|
||||
|
||||
key <LSGT> { [ backslash, bar, asciitilde, brokenbar ] };
|
||||
};
|
||||
|
||||
// Colemak-DH (ISO) layout, UK Variant, https://colemakmods.github.io/mod-dh/
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "colemak_dh" {
|
||||
include "us(colemak_dh)"
|
||||
|
||||
name[Group1]="English (UK, Colemak-DH)";
|
||||
|
||||
key <TLDE> { [ grave, notsign, bar, asciitilde ] };
|
||||
key <AE02> { [ 2, quotedbl, twosuperior, oneeighth ] };
|
||||
key <AE03> { [ 3, sterling, threesuperior, sterling ] };
|
||||
key <AE04> { [ 4, dollar, EuroSign, onequarter ] };
|
||||
|
||||
key <AC11> { [apostrophe, at, dead_circumflex, dead_caron] };
|
||||
key <BKSL> { [numbersign, asciitilde, dead_grave, dead_breve ] };
|
||||
|
||||
key <AB05> { [ backslash, bar, asciitilde, brokenbar ] };
|
||||
};
|
||||
|
||||
|
||||
// Dvorak (UK) keymap (by odaen) allowing the usage of
|
||||
// the £ and ? key and swapping the @ and " keys.
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "dvorak" {
|
||||
include "us(dvorak-alt-intl)"
|
||||
|
||||
name[Group1]="English (UK, Dvorak)";
|
||||
|
||||
key <TLDE> { [ grave, notsign, bar, bar ] };
|
||||
key <AE02> { [ 2, quotedbl, twosuperior, NoSymbol ] };
|
||||
key <AE03> { [ 3, sterling, threesuperior, NoSymbol ] };
|
||||
key <AD01> { [ apostrophe, at ] };
|
||||
key <BKSL> { [ numbersign, asciitilde ] };
|
||||
key <LSGT> { [ backslash, bar ] };
|
||||
};
|
||||
|
||||
// Dvorak letter positions, but punctuation all in the normal UK positions.
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "dvorakukp" {
|
||||
include "gb(dvorak)"
|
||||
|
||||
name[Group1]="English (UK, Dvorak, with UK punctuation)";
|
||||
|
||||
key <AE11> { [ minus, underscore ] };
|
||||
key <AE12> { [ equal, plus ] };
|
||||
key <AD11> { [ bracketleft, braceleft ] };
|
||||
key <AD12> { [ bracketright, braceright ] };
|
||||
key <AD01> { [ slash, question ] };
|
||||
key <AC11> { [apostrophe, at, dead_circumflex, dead_caron] };
|
||||
};
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "mac" {
|
||||
|
||||
include "latin"
|
||||
|
||||
name[Group1]= "English (UK, Macintosh)";
|
||||
|
||||
key <TLDE> { [ section, plusminus ] };
|
||||
key <AE02> { [ 2, at, EuroSign ] };
|
||||
key <AE03> { [ 3, sterling, numbersign ] };
|
||||
key <LSGT> { [ grave, asciitilde ] };
|
||||
|
||||
include "level3(ralt_switch)"
|
||||
include "level3(enter_switch)"
|
||||
};
|
||||
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "mac_intl" {
|
||||
|
||||
include "latin"
|
||||
|
||||
name[Group1]="English (UK, Macintosh, intl.)";
|
||||
|
||||
key <TLDE> { [ section, plusminus, notsign, notsign ] }; //dead_grave
|
||||
key <AE02> { [ 2, at, EuroSign, onehalf ] };
|
||||
key <AE03> { [ 3, sterling, twosuperior, onethird ] };
|
||||
key <AE04> { [ 4, dollar, threesuperior, onequarter ] };
|
||||
key <AE06> { [ 6, dead_circumflex, NoSymbol, onesixth ] };
|
||||
key <AD09> { [ o, O, oe, OE ] };
|
||||
|
||||
key <AC11> { [ dead_acute, dead_diaeresis, dead_diaeresis, bar ] }; //dead_doubleacute
|
||||
key <BKSL> { [ backslash, bar, numbersign, bar ] };
|
||||
|
||||
key <LSGT> { [ dead_grave, dead_tilde, brokenbar, bar ] };
|
||||
|
||||
include "level3(ralt_switch)"
|
||||
};
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "pl" {
|
||||
|
||||
// Polish accented letters on upper levels of corresponding base letters.
|
||||
// Idea from Wawrzyniec Niewodniczański, adapted by Aleksander Kowalski.
|
||||
|
||||
include "gb(basic)"
|
||||
|
||||
name[Group1]="Polish (British keyboard)";
|
||||
|
||||
key <AD03> { [ e, E, eogonek, Eogonek ] };
|
||||
key <AD09> { [ o, O, oacute, Oacute ] };
|
||||
|
||||
key <AC01> { [ a, A, aogonek, Aogonek ] };
|
||||
key <AC02> { [ s, S, sacute, Sacute ] };
|
||||
|
||||
key <AB01> { [ z, Z, zabovedot, Zabovedot ] };
|
||||
key <AB02> { [ x, X, zacute, Zacute ] };
|
||||
key <AB03> { [ c, C, cacute, Cacute ] };
|
||||
key <AB06> { [ n, N, nacute, Nacute ] };
|
||||
};
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "gla" {
|
||||
|
||||
// Grave-accented letters on the upper levels of the relevant vowels.
|
||||
|
||||
include "gb(basic)"
|
||||
|
||||
name[Group1]="Scottish Gaelic";
|
||||
|
||||
key <AD03> { [ e, E, egrave, Egrave ] };
|
||||
key <AD07> { [ u, U, ugrave, Ugrave ] };
|
||||
key <AD08> { [ i, I, igrave, Igrave ] };
|
||||
key <AD09> { [ o, O, ograve, Ograve ] };
|
||||
|
||||
key <AC01> { [ a, A, agrave, Agrave ] };
|
||||
};
|
||||
|
||||
// EXTRAS:
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "sun_type6" {
|
||||
include "sun_vndr/gb(sun_type6)"
|
||||
};
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
// The <KPDL> key is a mess.
|
||||
// It was probably originally meant to be a decimal separator.
|
||||
// Except since it was declared by USA people it didn't use the original
|
||||
// SI separator "," but a "." (since then the USA managed to f-up the SI
|
||||
// by making "." an accepted alternative, but standards still use "," as
|
||||
// default)
|
||||
// As a result users of SI-abiding countries expect either a "." or a ","
|
||||
// or a "decimal_separator" which may or may not be translated in one of the
|
||||
// above depending on applications.
|
||||
// It's not possible to define a default per-country since user expectations
|
||||
// depend on the conflicting choices of their most-used applications,
|
||||
// operating system, etc. Therefore it needs to be a configuration setting
|
||||
// Copyright © 2007 Nicolas Mailhot <nicolas.mailhot @ laposte.net>
|
||||
|
||||
|
||||
// Legacy <KPDL> #1
|
||||
// This assumes KP_Decimal will be translated in a dot
|
||||
partial keypad_keys
|
||||
xkb_symbols "dot" {
|
||||
|
||||
key.type[Group1]="KEYPAD" ;
|
||||
|
||||
key <KPDL> { [ KP_Delete, KP_Decimal ] }; // <delete> <separator>
|
||||
};
|
||||
|
||||
|
||||
// Legacy <KPDL> #2
|
||||
// This assumes KP_Separator will be translated in a comma
|
||||
partial keypad_keys
|
||||
xkb_symbols "comma" {
|
||||
|
||||
key.type[Group1]="KEYPAD" ;
|
||||
|
||||
key <KPDL> { [ KP_Delete, KP_Separator ] }; // <delete> <separator>
|
||||
};
|
||||
|
||||
|
||||
// Period <KPDL>, usual keyboard serigraphy in most countries
|
||||
partial keypad_keys
|
||||
xkb_symbols "dotoss" {
|
||||
|
||||
key.type[Group1]="FOUR_LEVEL_MIXED_KEYPAD" ;
|
||||
|
||||
key <KPDL> { [ KP_Delete, period, comma, 0x100202F ] }; // <delete> . , ⍽ (narrow no-break space)
|
||||
};
|
||||
|
||||
|
||||
// Period <KPDL>, usual keyboard serigraphy in most countries, latin-9 restriction
|
||||
partial keypad_keys
|
||||
xkb_symbols "dotoss_latin9" {
|
||||
|
||||
key.type[Group1]="FOUR_LEVEL_MIXED_KEYPAD" ;
|
||||
|
||||
key <KPDL> { [ KP_Delete, period, comma, nobreakspace ] }; // <delete> . , ⍽ (no-break space)
|
||||
};
|
||||
|
||||
|
||||
// Comma <KPDL>, what most non anglo-saxon people consider the real separator
|
||||
partial keypad_keys
|
||||
xkb_symbols "commaoss" {
|
||||
|
||||
key.type[Group1]="FOUR_LEVEL_MIXED_KEYPAD" ;
|
||||
|
||||
key <KPDL> { [ KP_Delete, comma, period, 0x100202F ] }; // <delete> , . ⍽ (narrow no-break space)
|
||||
};
|
||||
|
||||
|
||||
// Momayyez <KPDL>: Bahrain, Iran, Iraq, Kuwait, Oman, Qatar, Saudi Arabia, Syria, UAE
|
||||
partial keypad_keys
|
||||
xkb_symbols "momayyezoss" {
|
||||
|
||||
key.type[Group1]="FOUR_LEVEL_MIXED_KEYPAD" ;
|
||||
|
||||
key <KPDL> { [ KP_Delete, 0x100066B, comma, 0x100202F ] }; // <delete> ? , ⍽ (narrow no-break space)
|
||||
};
|
||||
|
||||
|
||||
// Abstracted <KPDL>, pray everything will work out (it usually does not)
|
||||
partial keypad_keys
|
||||
xkb_symbols "kposs" {
|
||||
|
||||
key.type[Group1]="FOUR_LEVEL_MIXED_KEYPAD" ;
|
||||
|
||||
key <KPDL> { [ KP_Delete, KP_Decimal, KP_Separator, 0x100202F ] }; // <delete> ? ? ⍽ (narrow no-break space)
|
||||
};
|
||||
|
||||
// Spreadsheets may be configured to use the dot as decimal
|
||||
// punctuation, comma as a thousands separator and then semi-colon as
|
||||
// the list separator. Of these, dot and semi-colon is most important
|
||||
// when entering data by the keyboard; the comma can then be inferred
|
||||
// and added to the presentation afterwards. Using semi-colon as a
|
||||
// general separator may in fact be preferred to avoid ambiguities
|
||||
// in data files. Most times a decimal separator is hard-coded, it
|
||||
// seems to be period, probably since this is the syntax used in
|
||||
// (most) programming languages.
|
||||
partial keypad_keys
|
||||
xkb_symbols "semi" {
|
||||
|
||||
key.type[Group1]="FOUR_LEVEL_MIXED_KEYPAD" ;
|
||||
|
||||
key <KPDL> { [ NoSymbol, NoSymbol, semicolon ] };
|
||||
};
|
||||
+255
@@ -0,0 +1,255 @@
|
||||
// Common Latin alphabet layout
|
||||
|
||||
default partial
|
||||
xkb_symbols "basic" {
|
||||
|
||||
key <AE01> { [ 1, exclam, onesuperior, exclamdown ] };
|
||||
key <AE02> { [ 2, at, twosuperior, oneeighth ] };
|
||||
key <AE03> { [ 3, numbersign, threesuperior, sterling ] };
|
||||
key <AE04> { [ 4, dollar, onequarter, dollar ] };
|
||||
key <AE05> { [ 5, percent, onehalf, threeeighths ] };
|
||||
key <AE06> { [ 6, asciicircum, threequarters, fiveeighths ] };
|
||||
key <AE07> { [ 7, ampersand, braceleft, seveneighths ] };
|
||||
key <AE08> { [ 8, asterisk, bracketleft, trademark ] };
|
||||
key <AE09> { [ 9, parenleft, bracketright, plusminus ] };
|
||||
key <AE10> { [ 0, parenright, braceright, degree ] };
|
||||
key <AE11> { [ minus, underscore, backslash, questiondown ] };
|
||||
key <AE12> { [ equal, plus, dead_cedilla, dead_ogonek ] };
|
||||
|
||||
key <AD01> { [ q, Q, at, Greek_OMEGA ] };
|
||||
key <AD02> { [ w, W, U017F, section ] };
|
||||
key <AD03> { [ e, E, e, E ] };
|
||||
key <AD04> { [ r, R, paragraph, registered ] };
|
||||
key <AD05> { [ t, T, tslash, Tslash ] };
|
||||
key <AD06> { [ y, Y, leftarrow, yen ] };
|
||||
key <AD07> { [ u, U, downarrow, uparrow ] };
|
||||
key <AD08> { [ i, I, rightarrow, idotless ] };
|
||||
key <AD09> { [ o, O, oslash, Oslash ] };
|
||||
key <AD10> { [ p, P, thorn, THORN ] };
|
||||
key <AD11> { [bracketleft, braceleft, dead_diaeresis, dead_abovering ] };
|
||||
key <AD12> { [bracketright, braceright, dead_tilde, dead_macron ] };
|
||||
|
||||
key <AC01> { [ a, A, ae, AE ] };
|
||||
key <AC02> { [ s, S, ssharp, U1E9E ] };
|
||||
key <AC03> { [ d, D, eth, ETH ] };
|
||||
key <AC04> { [ f, F, dstroke, ordfeminine ] };
|
||||
key <AC05> { [ g, G, eng, ENG ] };
|
||||
key <AC06> { [ h, H, hstroke, Hstroke ] };
|
||||
key <AC07> { [ j, J, dead_hook, dead_horn ] };
|
||||
key <AC08> { [ k, K, kra, ampersand ] };
|
||||
key <AC09> { [ l, L, lstroke, Lstroke ] };
|
||||
key <AC10> { [ semicolon, colon, dead_acute, dead_doubleacute ] };
|
||||
key <AC11> { [apostrophe, quotedbl, dead_circumflex, dead_caron ] };
|
||||
key <TLDE> { [ grave, asciitilde, notsign, notsign ] };
|
||||
|
||||
key <BKSL> { [ backslash, bar, dead_grave, dead_breve ] };
|
||||
key <AB01> { [ z, Z, guillemotleft, less ] };
|
||||
key <AB02> { [ x, X, guillemotright, greater ] };
|
||||
key <AB03> { [ c, C, cent, copyright ] };
|
||||
key <AB04> { [ v, V, doublelowquotemark, singlelowquotemark ] };
|
||||
key <AB05> { [ b, B, leftdoublequotemark, leftsinglequotemark ] };
|
||||
key <AB06> { [ n, N, rightdoublequotemark, rightsinglequotemark ] };
|
||||
key <AB07> { [ m, M, mu, masculine ] };
|
||||
key <AB08> { [ comma, less, U2022, multiply ] }; // bullet
|
||||
key <AB09> { [ period, greater, periodcentered, division ] };
|
||||
key <AB10> { [ slash, question, dead_belowdot, dead_abovedot ] };
|
||||
};
|
||||
|
||||
// Northern Europe ( Danish, Finnish, Norwegian, Swedish) common layout
|
||||
|
||||
partial
|
||||
xkb_symbols "type2" {
|
||||
|
||||
include "latin"
|
||||
|
||||
key <AE01> { [ 1, exclam, exclamdown, onesuperior ] };
|
||||
key <AE02> { [ 2, quotedbl, at, twosuperior ] };
|
||||
key <AE03> { [ 3, numbersign, sterling, threesuperior] };
|
||||
key <AE04> { [ 4, currency, dollar, onequarter ] };
|
||||
key <AE05> { [ 5, percent, onehalf, cent ] };
|
||||
key <AE06> { [ 6, ampersand, yen, fiveeighths ] };
|
||||
key <AE07> { [ 7, slash, braceleft, division ] };
|
||||
key <AE08> { [ 8, parenleft, bracketleft, guillemotleft] };
|
||||
key <AE09> { [ 9, parenright, bracketright, guillemotright] };
|
||||
key <AE10> { [ 0, equal, braceright, degree ] };
|
||||
|
||||
key <AD03> { [ e, E, EuroSign, cent ] };
|
||||
key <AD04> { [ r, R, registered, registered ] };
|
||||
key <AD05> { [ t, T, thorn, THORN ] };
|
||||
key <AD09> { [ o, O, oe, OE ] };
|
||||
key <AD11> { [ aring, Aring, dead_diaeresis, dead_abovering ] };
|
||||
key <AD12> { [dead_diaeresis, dead_circumflex, dead_tilde, dead_caron ] };
|
||||
|
||||
key <AC01> { [ a, A, ordfeminine, masculine ] };
|
||||
|
||||
key <AB03> { [ c, C, copyright, copyright ] };
|
||||
key <AB08> { [ comma, semicolon, dead_cedilla, dead_ogonek ] };
|
||||
key <AB09> { [ period, colon, periodcentered, dead_abovedot ] };
|
||||
key <AB10> { [ minus, underscore, dead_belowdot, dead_abovedot ] };
|
||||
};
|
||||
|
||||
// Slavic Latin ( Albanian, Croatian, Polish, Slovene, Yugoslav)
|
||||
// common layout
|
||||
|
||||
partial
|
||||
xkb_symbols "type3" {
|
||||
|
||||
include "latin"
|
||||
|
||||
key <AD01> { [ q, Q, backslash, Greek_OMEGA ] };
|
||||
key <AD02> { [ w, W, bar, section ] };
|
||||
key <AD06> { [ z, Z, leftarrow, yen ] };
|
||||
|
||||
key <AC04> { [ f, F, bracketleft, ordfeminine ] };
|
||||
key <AC05> { [ g, G, bracketright, ENG ] };
|
||||
key <AC08> { [ k, K, lstroke, ampersand ] };
|
||||
|
||||
key <AB01> { [ y, Y, guillemotleft, less ] };
|
||||
key <AB04> { [ v, V, at, grave ] };
|
||||
key <AB05> { [ b, B, braceleft, apostrophe ] };
|
||||
key <AB06> { [ n, N, braceright, acute ] };
|
||||
key <AB07> { [ m, M, section, masculine ] };
|
||||
key <AB08> { [ comma, semicolon, less, multiply ] };
|
||||
key <AB09> { [ period, colon, greater, division ] };
|
||||
};
|
||||
|
||||
// Another common Latin layout
|
||||
// (German, Estonian, Spanish, Icelandic, Italian, Latin American, Portuguese)
|
||||
|
||||
partial
|
||||
xkb_symbols "type4" {
|
||||
|
||||
include "latin"
|
||||
|
||||
key <AE02> { [ 2, quotedbl, at, oneeighth ] };
|
||||
key <AE06> { [ 6, ampersand, notsign, fiveeighths ] };
|
||||
key <AE07> { [ 7, slash, braceleft, seveneighths ] };
|
||||
key <AE08> { [ 8, parenleft, bracketleft, trademark ] };
|
||||
key <AE09> { [ 9, parenright, bracketright, plusminus ] };
|
||||
key <AE10> { [ 0, equal, braceright, degree ] };
|
||||
|
||||
key <AD03> { [ e, E, EuroSign, cent ] };
|
||||
|
||||
key <AB08> { [ comma, semicolon, U2022, multiply ] }; // bullet
|
||||
key <AB09> { [ period, colon, periodcentered, division ] };
|
||||
key <AB10> { [ minus, underscore, dead_belowdot, dead_abovedot ] };
|
||||
};
|
||||
|
||||
partial
|
||||
xkb_symbols "nodeadkeys" {
|
||||
|
||||
key <AE12> { [ equal, plus, cedilla, ogonek ] };
|
||||
key <AD11> { [bracketleft, braceleft, diaeresis, degree ] };
|
||||
key <AD12> { [bracketright, braceright, asciitilde, macron ] };
|
||||
key <AC07> { [ j, J, ezh, EZH ] };
|
||||
key <AC10> { [ semicolon, colon, acute, doubleacute ] };
|
||||
key <AC11> { [apostrophe, quotedbl, asciicircum, caron ] };
|
||||
key <BKSL> { [ backslash, bar, grave, breve ] };
|
||||
key <AB10> { [ slash, question, ellipsis, abovedot ] };
|
||||
};
|
||||
|
||||
partial
|
||||
xkb_symbols "type2_nodeadkeys" {
|
||||
|
||||
include "latin(nodeadkeys)"
|
||||
|
||||
key <AD11> { [ aring, Aring, diaeresis, degree ] };
|
||||
key <AD12> { [ diaeresis, asciicircum, asciitilde, caron ] };
|
||||
key <AB08> { [ comma, semicolon, cedilla, ogonek ] };
|
||||
key <AB09> { [ period, colon, periodcentered, abovedot ] };
|
||||
key <AB10> { [ minus, underscore, ellipsis, abovedot ] };
|
||||
};
|
||||
|
||||
partial
|
||||
xkb_symbols "type3_nodeadkeys" {
|
||||
|
||||
include "latin(nodeadkeys)"
|
||||
};
|
||||
|
||||
partial
|
||||
xkb_symbols "type4_nodeadkeys" {
|
||||
|
||||
include "latin(nodeadkeys)"
|
||||
|
||||
key <AB10> { [ minus, underscore, ellipsis, abovedot ] };
|
||||
};
|
||||
|
||||
// Added 2008.03.05 by Marcin Woliński
|
||||
// See http://marcinwolinski.pl/keyboard/ for a description.
|
||||
// Used by pl(intl)
|
||||
//
|
||||
// ┌─────┐
|
||||
// │ 2 4 │ 2 = Shift, 4 = Level3 + Shift
|
||||
// │ 1 3 │ 1 = Normal, 3 = Level3
|
||||
// └─────┘
|
||||
// ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┲━━━━━━━━━┓
|
||||
// │ ~ ~ │ ! ' │ @ " │ # ˝ │ $ ¸ │ % ˇ │ ^ ^ │ & ˘ │ * ̇ │ ( ̣ │ ) ° │ _ ¯ │ + ˛ ┃ ⌫ Back- ┃
|
||||
// │ ` ` │ 1 ¡ │ 2 © │ 3 • │ 4 § │ 5 € │ 6 ¢ │ 7 − │ 8 × │ 9 ÷ │ 0 ° │ - – │ = — ┃ space ┃
|
||||
// ┢━━━━━┷━┱───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┺━┳━━━━━━━┫
|
||||
// ┃ ┃ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { « │ } » ┃ Enter ┃
|
||||
// ┃Tab ↹ ┃ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ [ ‹ │ ] › ┃ ⏎ ┃
|
||||
// ┣━━━━━━━┻┱────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┺┓ ┃
|
||||
// ┃ ┃ A │ S │ D │ F │ G │ H │ J │ K │ L │ : “ │ " ” │ | ¶ ┃ ┃
|
||||
// ┃Caps ⇬ ┃ a │ s │ d │ f │ g │ h │ j │ k │ l │ ; ‘ │ ' ’ │ \ ┃ ┃
|
||||
// ┣━━━━━━━━┹────┬┴────┬┴────┬┴────┬┴────┬┴────┬┴────┬┴────┬┴────┬┴────┬┴────┲┷━━━━━┻━━━━━━┫
|
||||
// ┃ │ Z │ X │ C │ V │ B │ N │ M │ < „ │ > · │ ? ¿ ┃ ┃
|
||||
// ┃Shift ⇧ │ z │ x │ c │ v │ b │ n │ m │ , ‚ │ . … │ / ⁄ ┃Shift ⇧ ┃
|
||||
// ┣━━━━━━━┳━━━━━┷━┳━━━┷━━━┱─┴─────┴─────┴─────┴─────┴─────┴───┲━┷━━━━━╈━━━━━┻━┳━━━━━━━┳━━━┛
|
||||
// ┃ ┃ ┃ ┃ ␣ ⍽ ┃ ┃ ┃ ┃
|
||||
// ┃Ctrl ┃Meta ┃Alt ┃ ␣ Space ⍽ ┃AltGr ⇮┃Menu ┃Ctrl ┃
|
||||
// ┗━━━━━━━┻━━━━━━━┻━━━━━━━┹───────────────────────────────────┺━━━━━━━┻━━━━━━━┻━━━━━━━┛
|
||||
|
||||
partial
|
||||
xkb_symbols "intl" {
|
||||
|
||||
key <TLDE> { [ grave, asciitilde, dead_grave, dead_tilde ] };
|
||||
key <AE01> { [ 1, exclam, exclamdown, dead_acute ] };
|
||||
key <AE02> { [ 2, at, copyright, dead_diaeresis ] };
|
||||
key <AE03> { [ 3, numbersign, U2022, dead_doubleacute ] }; // U+2022 is bullet (the name bullet does not work)
|
||||
key <AE04> { [ 4, dollar, section, dead_cedilla ] };
|
||||
key <AE05> { [ 5, percent, EuroSign, dead_caron ] };
|
||||
key <AE06> { [ 6, asciicircum, cent, dead_circumflex ] };
|
||||
key <AE07> { [ 7, ampersand, U2212, dead_breve ] }; // U+2212 is MINUS SIGN
|
||||
key <AE08> { [ 8, asterisk, multiply, dead_abovedot ] };
|
||||
key <AE09> { [ 9, parenleft, division, dead_belowdot ] };
|
||||
key <AE10> { [ 0, parenright, degree, dead_abovering ] };
|
||||
key <AE11> { [ minus, underscore, endash, dead_macron ] };
|
||||
key <AE12> { [ equal, plus, emdash, dead_ogonek ] };
|
||||
|
||||
key <AD01> { [ q, Q ] };
|
||||
key <AD02> { [ w, W ] };
|
||||
key <AD03> { [ e, E ] };
|
||||
key <AD04> { [ r, R ] };
|
||||
key <AD05> { [ t, T ] };
|
||||
key <AD06> { [ y, Y ] };
|
||||
key <AD07> { [ u, U ] };
|
||||
key <AD08> { [ i, I ] };
|
||||
key <AD09> { [ o, O ] };
|
||||
key <AD10> { [ p, P ] };
|
||||
key <AD11> { [bracketleft, braceleft, U2039, guillemotleft ] };
|
||||
key <AD12> { [bracketright, braceright, U203A, guillemotright ] };
|
||||
|
||||
key <AC01> { [ a, A ] };
|
||||
key <AC02> { [ s, S ] };
|
||||
key <AC03> { [ d, D ] };
|
||||
key <AC04> { [ f, F ] };
|
||||
key <AC05> { [ g, G ] };
|
||||
key <AC06> { [ h, H ] };
|
||||
key <AC07> { [ j, J ] };
|
||||
key <AC08> { [ k, K ] };
|
||||
key <AC09> { [ l, L ] };
|
||||
key <AC10> { [ semicolon, colon, leftsinglequotemark, leftdoublequotemark ] };
|
||||
key <AC11> { [apostrophe, quotedbl, rightsinglequotemark, rightdoublequotemark ] };
|
||||
|
||||
key <BKSL> { [ backslash, bar, NoSymbol, paragraph ] };
|
||||
key <AB01> { [ z, Z ] };
|
||||
key <AB02> { [ x, X ] };
|
||||
key <AB03> { [ c, C ] };
|
||||
key <AB04> { [ v, V ] };
|
||||
key <AB05> { [ b, B ] };
|
||||
key <AB06> { [ n, N ] };
|
||||
key <AB07> { [ m, M ] };
|
||||
key <AB08> { [ comma, less, singlelowquotemark, doublelowquotemark ] };
|
||||
key <AB09> { [ period, greater, ellipsis, periodcentered ] };
|
||||
key <AB10> { [ slash, question, U2044, questiondown ] }; // U+2044 is FRACTION SLASH
|
||||
};
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
// These variants assign ISO_Level3_Shift to various keys
|
||||
// so that levels 3 and 4 can be reached.
|
||||
|
||||
// The default behaviour:
|
||||
// the right Alt key (AltGr) chooses the third symbol engraved on a key.
|
||||
default partial modifier_keys
|
||||
xkb_symbols "ralt_switch" {
|
||||
key <RALT> {[ ISO_Level3_Shift ], type[group1]="ONE_LEVEL" };
|
||||
};
|
||||
|
||||
// The right Alt key never chooses the third level.
|
||||
// This option attempts to undo the effect of a layout's inclusion of
|
||||
// 'ralt_switch'. You may want to also select another level3 option
|
||||
// to map the level3 shift to some other key.
|
||||
partial modifier_keys
|
||||
xkb_symbols "ralt_alt" {
|
||||
key <RALT> {[ Alt_R, Meta_R ], type[group1]="TWO_LEVEL" };
|
||||
modifier_map Mod1 { <RALT> };
|
||||
};
|
||||
|
||||
// The right Alt key (while pressed) chooses the third shift level,
|
||||
// and Compose is mapped to its second level.
|
||||
partial modifier_keys
|
||||
xkb_symbols "ralt_switch_multikey" {
|
||||
key <RALT> {[ ISO_Level3_Shift, Multi_key ], type[group1]="TWO_LEVEL" };
|
||||
};
|
||||
|
||||
// Either Alt key (while pressed) chooses the third shift level.
|
||||
// (To be used mostly to imitate Mac OS functionality.)
|
||||
partial modifier_keys
|
||||
xkb_symbols "alt_switch" {
|
||||
include "level3(lalt_switch)"
|
||||
include "level3(ralt_switch)"
|
||||
};
|
||||
|
||||
// The left Alt key (while pressed) chooses the third shift level.
|
||||
partial modifier_keys
|
||||
xkb_symbols "lalt_switch" {
|
||||
key <LALT> {[ ISO_Level3_Shift ], type[group1]="ONE_LEVEL" };
|
||||
};
|
||||
|
||||
// The right Ctrl key (while pressed) chooses the third shift level.
|
||||
partial modifier_keys
|
||||
xkb_symbols "switch" {
|
||||
key <RCTL> {[ ISO_Level3_Shift ], type[group1]="ONE_LEVEL" };
|
||||
};
|
||||
|
||||
// The Menu key (while pressed) chooses the third shift level.
|
||||
partial modifier_keys
|
||||
xkb_symbols "menu_switch" {
|
||||
key <MENU> {[ ISO_Level3_Shift ], type[group1]="ONE_LEVEL" };
|
||||
};
|
||||
|
||||
// Either Win key (while pressed) chooses the third shift level.
|
||||
partial modifier_keys
|
||||
xkb_symbols "win_switch" {
|
||||
include "level3(lwin_switch)"
|
||||
include "level3(rwin_switch)"
|
||||
};
|
||||
|
||||
// The left Win key (while pressed) chooses the third shift level.
|
||||
partial modifier_keys
|
||||
xkb_symbols "lwin_switch" {
|
||||
key <LWIN> {[ ISO_Level3_Shift ], type[group1]="ONE_LEVEL" };
|
||||
};
|
||||
|
||||
// The right Win key (while pressed) chooses the third shift level.
|
||||
partial modifier_keys
|
||||
xkb_symbols "rwin_switch" {
|
||||
key <RWIN> {[ ISO_Level3_Shift ], type[group1]="ONE_LEVEL" };
|
||||
};
|
||||
|
||||
// The Enter key on the kepypad (while pressed) chooses the third shift level.
|
||||
// (This is especially useful for Mac laptops which miss the right Alt key.)
|
||||
partial modifier_keys
|
||||
xkb_symbols "enter_switch" {
|
||||
key <KPEN> {[ ISO_Level3_Shift ], type[group1]="ONE_LEVEL" };
|
||||
};
|
||||
|
||||
// The CapsLock key (while pressed) chooses the third shift level.
|
||||
partial modifier_keys
|
||||
xkb_symbols "caps_switch" {
|
||||
key <CAPS> {[ ISO_Level3_Shift ], type[group1]="ONE_LEVEL" };
|
||||
};
|
||||
|
||||
// The CapsLock key (while pressed) chooses the third shift level and
|
||||
// Ctrl + CapsLock has the original CapsLock function.
|
||||
// The 2023 DIN standard for German keyboards recommends it as an option:
|
||||
// - https://de.wikipedia.org/wiki/E1_(Tastaturbelegung)#Feststelltaste/Umschaltsperre
|
||||
// - https://en.wikipedia.org/wiki/Caps_Lock#Abolition
|
||||
partial modifier_keys
|
||||
xkb_symbols "caps_switch_capslock_with_ctrl" {
|
||||
virtual_modifiers LevelThree;
|
||||
|
||||
key <CAPS> {
|
||||
type[Group1] = "PC_CONTROL_LEVEL2",
|
||||
symbols[Group1] = [ ISO_Level3_Shift, Caps_Lock ],
|
||||
// Explicit actions are preferred over modMap None/Mod5 { Caps_Lock }
|
||||
// because they have no side effect
|
||||
actions[Group1] = [ SetMods(modifiers = LevelThree), LockMods(modifiers = Lock) ]
|
||||
};
|
||||
};
|
||||
|
||||
// The Backslash key (while pressed) chooses the third shift level.
|
||||
partial modifier_keys
|
||||
xkb_symbols "bksl_switch" {
|
||||
key <BKSL> {[ ISO_Level3_Shift ], type[group1]="ONE_LEVEL" };
|
||||
};
|
||||
|
||||
// The AC11 key (while pressed) chooses the third shift level.
|
||||
partial modifier_keys
|
||||
xkb_symbols "ac11_switch" {
|
||||
key <AC11> {[ ISO_Level3_Shift ], type[Group1]="ONE_LEVEL" };
|
||||
};
|
||||
|
||||
// The Less/Greater key (while pressed) chooses the third shift level.
|
||||
partial modifier_keys
|
||||
xkb_symbols "lsgt_switch" {
|
||||
key <LSGT> {[ ISO_Level3_Shift ], type[group1]="ONE_LEVEL" };
|
||||
};
|
||||
|
||||
// The CapsLock key (while pressed) chooses the third shift level,
|
||||
// and latches when pressed together with another third-level chooser.
|
||||
partial modifier_keys
|
||||
xkb_symbols "caps_switch_latch" {
|
||||
key <CAPS> {[ ISO_Level3_Shift, ISO_Level3_Shift, ISO_Level3_Latch ],
|
||||
type[group1]="THREE_LEVEL" };
|
||||
};
|
||||
|
||||
// The Backslash key (while pressed) chooses the third shift level,
|
||||
// and latches when pressed together with another third-level chooser.
|
||||
partial modifier_keys
|
||||
xkb_symbols "bksl_switch_latch" {
|
||||
key <BKSL> {[ ISO_Level3_Shift, ISO_Level3_Shift, ISO_Level3_Latch ],
|
||||
type[group1]="THREE_LEVEL" };
|
||||
};
|
||||
|
||||
// The Less/Greater key (while pressed) chooses the third shift level,
|
||||
// and latches when pressed together with another third-level chooser.
|
||||
partial modifier_keys
|
||||
xkb_symbols "lsgt_switch_latch" {
|
||||
key <LSGT> {[ ISO_Level3_Shift, ISO_Level3_Shift, ISO_Level3_Latch ],
|
||||
type[group1]="THREE_LEVEL" };
|
||||
};
|
||||
|
||||
// Top-row digit key 4 chooses third shift level when pressed alone.
|
||||
partial modifier_keys
|
||||
xkb_symbols "4_switch_isolated" {
|
||||
override key <AE04> {[ ISO_Level3_Shift ]};
|
||||
};
|
||||
|
||||
// Top-row digit key 9 chooses third shift level when pressed alone.
|
||||
partial modifier_keys
|
||||
xkb_symbols "9_switch_isolated" {
|
||||
override key <AE09> {[ ISO_Level3_Shift ]};
|
||||
};
|
||||
+2238
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,153 @@
|
||||
//! xkeyboard-config — keyboard layouts, compiled from the X11 xkeyboard-config database
|
||||
//! into native Zig. It turns a physical key (a USB HID usage, as the input module delivers)
|
||||
//! plus a modifier state into a **keysym** and, when the key produces one, a **character**
|
||||
//! (a Unicode scalar). This is the piece that lets a `KeyEvent.keycode` become a
|
||||
//! `KeyEvent.character`, without shipping an X11 runtime.
|
||||
//!
|
||||
//! The layout tables in `generated/layouts.zig` are produced by
|
||||
//! `tools/make-xkeyboard-config.py` (see ./README.md to regenerate). Those tables are
|
||||
//! deliberately pure data — each key carries its up-to-four levels and an XKB *type*. The
|
||||
//! type -> level selection semantics (which modifier picks which level) live here, so the
|
||||
//! data and the policy are separable.
|
||||
//!
|
||||
//! Scope (documented in README.md): group 1 only, no dead-key/compose composition (a dead
|
||||
//! key returns its keysym with no character), and a curated set of key types. Layouts:
|
||||
//! us, gb, de, fr, es, dvorak.
|
||||
//!
|
||||
//! Upstream xkeyboard-config and keysymdef.h are MIT/X11 licensed; see vendor/COPYING and
|
||||
//! vendor/PROVENANCE.md.
|
||||
|
||||
const std = @import("std");
|
||||
const generated = @import("layouts");
|
||||
|
||||
pub const Level = generated.Level;
|
||||
pub const KeyType = generated.KeyType;
|
||||
pub const Key = generated.Key;
|
||||
pub const Layout = generated.Layout;
|
||||
|
||||
/// The generated layouts, by name — as pointers, so they share identity with `all` and
|
||||
/// `byName` (and match the `*const Layout` that `map` takes).
|
||||
pub const us: *const Layout = &generated.us;
|
||||
pub const gb: *const Layout = &generated.gb;
|
||||
pub const de: *const Layout = &generated.de;
|
||||
pub const fr: *const Layout = &generated.fr;
|
||||
pub const es: *const Layout = &generated.es;
|
||||
pub const dvorak: *const Layout = &generated.dvorak;
|
||||
|
||||
/// Every generated layout, for enumeration (e.g. a settings UI).
|
||||
pub const all = generated.all;
|
||||
|
||||
/// The modifier state that selects a key's level. `level3` is AltGr (ISO Level3 Shift);
|
||||
/// `control` is accepted for completeness but does not affect level selection here.
|
||||
pub const Modifiers = struct {
|
||||
shift: bool = false,
|
||||
caps_lock: bool = false,
|
||||
level3: bool = false,
|
||||
control: bool = false,
|
||||
};
|
||||
|
||||
/// The result of a lookup: the X11 `keysym`, and the `character` it produces (a Unicode
|
||||
/// scalar) when it is a printable key — null for keys that produce none (Return, F1, a
|
||||
/// bare dead key, an unmapped key).
|
||||
pub const Mapping = struct {
|
||||
keysym: u32,
|
||||
character: ?u21,
|
||||
};
|
||||
|
||||
/// Which level (0..3) a key of `kind` selects under `mods`. XKB's canonical semantics:
|
||||
/// Shift picks the odd level, AltGr (level3) adds 2, and Caps acts like Shift for the
|
||||
/// alphabetic types. See the XKB "key types" — this covers the ones the vendored layouts
|
||||
/// use; anything else falls back to shift-or-not.
|
||||
fn selectLevel(kind: KeyType, mods: Modifiers) usize {
|
||||
const shift_or_caps = mods.shift != mods.caps_lock; // XOR: Caps behaves like Shift
|
||||
const low: usize = if (mods.shift) 1 else 0;
|
||||
const high: usize = if (mods.level3) 2 else 0;
|
||||
return switch (kind) {
|
||||
.one_level => 0,
|
||||
.two_level, .keypad, .other => low,
|
||||
.alphabetic => if (shift_or_caps) 1 else 0,
|
||||
.four_level => low + high,
|
||||
.four_level_alphabetic => (if (shift_or_caps) @as(usize, 1) else 0) + high,
|
||||
// Caps affects only the base pair, not the AltGr pair.
|
||||
.four_level_semialphabetic => if (mods.level3) 2 + low else (if (shift_or_caps) @as(usize, 1) else 0),
|
||||
};
|
||||
}
|
||||
|
||||
/// Map a physical key (`hid_usage`, a USB HID keyboard-page usage) under `mods` on
|
||||
/// `layout` to its keysym and character. Falls back gracefully when the selected level is
|
||||
/// undefined for the key: it drops the AltGr component, then the shift component, so a key
|
||||
/// with only a base/shift pair still yields something sensible under AltGr.
|
||||
pub fn map(layout: *const Layout, hid_usage: u8, mods: Modifiers) Mapping {
|
||||
const key = &layout.keys[hid_usage];
|
||||
var level = selectLevel(key.kind, mods);
|
||||
// Fall back to a defined level: full -> without AltGr -> base.
|
||||
if (key.levels[level].keysym == 0 and key.levels[level].unicode == 0) {
|
||||
const candidates = [_]usize{ level & 1, 0 };
|
||||
for (candidates) |candidate| {
|
||||
if (key.levels[candidate].keysym != 0 or key.levels[candidate].unicode != 0) {
|
||||
level = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
const chosen = key.levels[level];
|
||||
return .{
|
||||
.keysym = chosen.keysym,
|
||||
.character = if (chosen.unicode != 0) @intCast(chosen.unicode) else null,
|
||||
};
|
||||
}
|
||||
|
||||
/// Look up a layout by its name (`"us"`, `"gb"`, ...), or null if unknown.
|
||||
pub fn byName(name: []const u8) ?*const Layout {
|
||||
for (all) |layout| {
|
||||
if (std.mem.eql(u8, layout.name, name)) return layout;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// --- tests (host-run via `zig build test`) ---------------------------------
|
||||
|
||||
const testing = std.testing;
|
||||
|
||||
// USB HID usages used in the tests (keyboard page 0x07).
|
||||
const hid_a: u8 = 0x04;
|
||||
const hid_1: u8 = 0x1e;
|
||||
const hid_3: u8 = 0x20;
|
||||
|
||||
test "us: letters obey shift and caps" {
|
||||
try testing.expectEqual(@as(?u21, 'a'), map(us, hid_a, .{}).character);
|
||||
try testing.expectEqual(@as(?u21, 'A'), map(us, hid_a, .{ .shift = true }).character);
|
||||
try testing.expectEqual(@as(?u21, 'A'), map(us, hid_a, .{ .caps_lock = true }).character);
|
||||
// Shift + Caps cancels for an alphabetic key.
|
||||
try testing.expectEqual(@as(?u21, 'a'), map(us, hid_a, .{ .shift = true, .caps_lock = true }).character);
|
||||
}
|
||||
|
||||
test "us: digits and their shifted symbols" {
|
||||
try testing.expectEqual(@as(?u21, '1'), map(us, hid_1, .{}).character);
|
||||
try testing.expectEqual(@as(?u21, '!'), map(us, hid_1, .{ .shift = true }).character);
|
||||
try testing.expectEqual(@as(?u21, '3'), map(us, hid_3, .{}).character);
|
||||
try testing.expectEqual(@as(?u21, '#'), map(us, hid_3, .{ .shift = true }).character);
|
||||
// A digit is not alphabetic: Caps alone must not shift it.
|
||||
try testing.expectEqual(@as(?u21, '3'), map(us, hid_3, .{ .caps_lock = true }).character);
|
||||
}
|
||||
|
||||
test "layouts differ: GB pound vs US hash on shift+3" {
|
||||
try testing.expectEqual(@as(?u21, '#'), map(us, hid_3, .{ .shift = true }).character);
|
||||
try testing.expectEqual(@as(?u21, '£'), map(gb, hid_3, .{ .shift = true }).character);
|
||||
}
|
||||
|
||||
test "french azerty places q where us has a" {
|
||||
try testing.expectEqual(@as(?u21, 'q'), map(fr, hid_a, .{}).character);
|
||||
try testing.expectEqual(@as(?u21, 'Q'), map(fr, hid_a, .{ .shift = true }).character);
|
||||
}
|
||||
|
||||
test "byName resolves and rejects" {
|
||||
try testing.expect(byName("us") == us);
|
||||
try testing.expect(byName("gb") == gb);
|
||||
try testing.expect(byName("nonsense") == null);
|
||||
}
|
||||
|
||||
test "unmapped key yields no character" {
|
||||
// HID 0x00 is not a key; every level is empty.
|
||||
try testing.expectEqual(@as(?u21, null), map(us, 0x00, .{}).character);
|
||||
}
|
||||
Reference in New Issue
Block a user