kc3-lang/libxkbcommon/src/xkbcomp/keymap-dump.c

Branch :


Log

Author Commit Date CI Message
e73d1a4d 2025-07-01 13:05:44 Add support for all layout indices to GroupN constants This commit enables to use the pattern `Group<INDEX>` for any valid group index `<INDEX>`. Note that the original code in xkbcomp allows constants up to `Group8`, but then will fail if the resulting group is > 4. There does not seem to be any use case for this for such “feature”; it seems rather to be a relic from times were the 4-groups limit was not hopelessly fixed in X. So for consistency in our code base, starting with this commit we now disallow `Group5`..`Group8` for keymap format v1, since it is limited to 4 groups. Also fixed a regression in the serialization of group action, when the group is relative.
3d00222e 2025-06-21 18:26:34 keymap: Add option `unlockOnPress` for LatchMods() It mirrors the feature of `SetMods()`, so that `StickyKeys` can be implemented.
d192b3b6 2025-06-19 21:57:46 keymap: Add option `unlockOnPress` for SetMods() It enables e.g. to deactivate `CapsLock` *on press* rather than on release, as in other platforms such as Windows. It fixes a [18-year old issue] inherited from the X11 ecosystem, by extending the [XKB protocol key actions]. As it is incompatible with X11, this feature is available only using the keymap text format v2. [18-year old issue]: https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/issues/74 [XKB protocol key actions]: https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Key_Actions
7a7a3b38 2024-02-14 09:47:15 keymap: Canonically map unmapped virtual modifiers Traditionally, *virtual* modifiers were merely name aliases for *real* modifiers (X *core* modifiers), e.g. `NumLock` was usually mapped to `Mod2` (see `modifier_map` statement). Virtual modifiers that were never mapped to a real ones had no effect on the keymap state. xkbcommon already supports the concept of “pure” virtual modifiers, i.e. virtual modifiers that are *encoded* using the full 32-bit range, not just the first 8 bits corresponding to the real modifiers. But until this commit, one had to declare such mapping *explicitly*: e.g. `virtual_modifiers M = 0x100;`. This has at least two drawbacks: - Numerical values may look quite arbitrary and are not user-friendly. It’s OK in the resulting compiled keymap, but it requires careful sync between sections when developing KcCGST files. - If the modifier is *also* mapped *implicitly* using the traditional `vmodmap`/`modifier_map`, then both mappings are OR-combined. This patch enables to automatically map unmapped virtual modifiers to their *canonical* mapping, i.e. themselves: their corresponding virtual and real modifier masks are identical: `1u << mod_index`. Since this feature is incompatible with X11, this is guarded by requiring at least keymap text format **v2**. Note that for now, canonical virtual modifiers cannot be used in an interpret action’s `AnyOf()`. An interpret action for a canonical virtual modifier must be `AnyOfOrNone()` to take effect: virtual_modifiers APureMod, …; interpret a+AnyOfOrNone(all) { virtualModifier= APureMod; action= SetMods(modifiers=APureMod); }; The above adds a virtual modifier `APureMod` for keysym `a`. It will be canonical iff it is not mapped implicitly.
69c3d257 2025-06-17 16:43:05 keymap: Add parameter `latchOnPress` for LatchMods() Some keyboard layouts use `ISO_Level3_Latch` or `ISO_Level5_Latch` to define “built-in” dead keys: - they do not rely on the installation of custom Compose file; - they do not clash with other layouts. However, layout projects usually want the exact same behavior on all OS, but the XKB latch behavior (often misunderstood) also acts as a *set* modifier, which is not expected. The usual behavior of a dead key on Linux, macOS and Windows is: - latch on press; - deactivate as soon as another (non-modifier) key is pressed. Added the parameter `latchOnPress` to `LatchMods()` to enable the aforementioned behavior. As it is incompatible with X11, this feature is available only using the keymap text format v2. [XKB protocol key actions]: https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Key_Actions
c58c7df1 2025-06-17 21:05:08 Serialize multiple actions per level to VoidAction() in v1 format When using `XKB_KEYMAP_FORMAT_TEXT_V1`, multiple actions per level are now serialized using `VoidAction()`, in order to maintain compatibility with X11.
4f2fa718 2025-06-17 16:47:20 dump: Fix typo Fixed copy-paste error. It worked for now, as both struct have the same first fields, but it is obviously semantically incorrect and not future-proof.
ee50e0c9 2025-06-12 20:14:50 keymap: Add option `unlockOnPress` for LockMods() It enables e.g. to deactivate CapsLock on press rather than on release, as in other platforms such as Windows. The specification of `LockMods()` is changed to: - On key *press*: - If `unlockOnPress` is true and some of the target modifiers were *locked* before the key press, then unlock them if `noUnlock` false. - Otherwise: - add target modifiers to *depressed* modifiers; - if `noLock` is false, add target modifiers to the *locked* modifiers. - On key *release*: - If `unlockOnPress` is true and triggered unlocking on key press, do nothing. - Otherwise: - remove modifiers from the *depressed* modifiers, if no other key that affect the same modifiers is down; - if `noUnlock` is false and if any target modifiers was locked before the key press, *unlock* them. It fixes a [12-year old issue] inherited from the X11 ecosystem, by extending the [XKB protocol key actions]. As it is incompatible with X11, this feature is available only using the keymap text format v2. [12-year old issue]: https://gitlab.freedesktop.org/xorg/xserver/-/issues/312 [XKB protocol key actions]: https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Key_Actions
d9d82355 2025-06-12 09:13:27 keymap: Add option `lockOnRelease` for LockGroup() It enables to use e.g. the combination `Control + Shift` *alone* to switch layouts, while keeping the use of `Control + Shift + other key` (typically for keyboard shortcuts). The specification of `LockGroup()` is changed to: - On key *press*: - If `lockOnRelease` is set, then key press has no effect. - Otherwise: - if the `group` is absolute, key press sets the *locked* keyboard group to `group`; - otherwise, key press adds `group` to the *locked* keyboard group. In either case, the resulting *locked* and *effective* group is brought back into range depending on the value of the `GroupsWrap` control for the keyboard. - On key *release*: - If `lockOnRelease` is not set, then key release has no effect. - Otherwise, if any other key was *pressed* after the locking key, then key release has no effect. - Otherwise, it has the same effect than a key press *without* `lockOnRelease` set. This is really useful for people coming from other platforms, such as Windows. It fixes a [20-year old issue] inherited from the X11 ecosystem, by extending the [XKB protocol key actions]. As it is incompatible with X11, this feature is available only using the keymap text format v2. [20-year old issue]: https://gitlab.freedesktop.org/xorg/xserver/-/issues/258 [XKB protocol key actions]: https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Key_Actions
80b8d9d1 2025-06-10 17:34:15 dump: Adapt groups count to keymap format
9f3078eb 2025-06-10 15:46:31 dump: Use explicit format
0f89ad97 2025-06-09 19:26:13 dump: Always use numeric group indexes The upcoming raise of the maximum groups count will require to use numeric group indexes instead of the syntax `GroupN` if groups > 8. Let’s not bother with handling two cases (group count ≤ 8 or > 8) and always serialize group indexes as numeric values.
61d8ec67 2025-05-12 18:20:47 misc: Fix string format specifiers Ensure better portability.
556d00a0 2025-05-12 17:52:12 keymap: Ensure proper type for layouts count
903c16da 2025-05-12 07:42:32 keymap: Ensure proper type for key types counts
c3953a96 2025-05-12 07:37:29 keymap: Ensure proper type for key codes aliases
10457563 2025-05-12 06:41:28 keymap: Ensure proper type for actions count
3911f786 2025-05-12 07:06:42 keymap: Ensure proper type for num_sym_interprets
d239a3f0 2025-05-11 11:42:20 actions: Improve unsupported legacy X11 actions handling - Display a warning - Document drawbacks of degrading to `NoAction()`
b4c89600 2025-05-09 15:15:10 actions: Add VoidAction(), mirroring NoSymbol/VoidSymbol. Added `VoidAction()` action to match the keysym pair `NoSymbol` / `VoidSymbol`. It enables overriding a previous action and breaks latches. This is a libxkbcommon extension. When serializing it will be converted to `LockControls(controls=none,affect=neither)` for backward compatibility. We cannot serialize it to `NoAction()`, as it would be dropped in e.g. the context of multiple actions.
662ce937 2024-12-03 10:09:10 state: Avoid keycode lookup when key ref is available
d5b779e1 2025-05-06 21:07:28 keymap: Fix empty compat interpretation map serialization X11’s `xkbcomp` requires at least one compat interpretation entry.
87f9ac76 2025-05-06 21:02:23 keymap: Fix empty compat interpretation statement serialization Statements such as `interpret VoidSymbol {};` can cannot be parsed by X11’s `xkbcomp`. Fixed by using a dummy action.
8bc60ee3 2025-05-05 13:20:45 modifiers: Minor optimization It has low impact, but it also adds better semantics.
9e93e5e5 2025-04-13 10:25:02 symbols: Restrict the number of actions and keysyms per level In preparation to support capitalization in `xkb_state_key_get_syms()`, this commit reduces the number of supported actions and keysyms per level, going from UINT_MAX to UINT16_MAX. This is most likely still more than enough and could be even reduced further, but deemed unnecessary at the moment: alignment of `struct xkb_level` is driven by the fields `a` and `s`. - Switched the item count type from `unsigned int` to `uint16_t`. - Introduced `xkb_{action,keysym}_count_t` type for the respective item count for exact typing. - Added relevant bounds checks.
af5296cf 2025-03-19 13:11:35 xkbcomp: Fix virtual mods merge modes
102f4ba1 2025-04-06 19:38:53 Fix integer conversion warnings
36442baa 2025-04-03 15:01:46 xkbcomp: Support multiple actions in interpret Before this commit we supported multiple actions per level, but not in *interpret* statements. Let’s fix this asymmetry, so we can equivalently assign all actions sets either implicitly or explicitly.
6d4cc135 2025-04-05 13:39:30 xkbcomp: Escape ASCII control characters
23bbec96 2025-03-29 12:33:53 xkbcomp: Add escape sequence \" `\"` seems like a very natural extension. However it is not supported by Xorg xkbcomp, so do not emit it when serializing.
7d91a753 2025-03-29 12:24:39 xkbcomp: Enable xkbcomp-style octal escape sequences Xorg xkbcomp only parses octal sequences with `\0`, while xkbcommon does not force the `0` prefix of the numeric part. However, we only parsed up to to 3 digits, which does not allow to parse e.g. `\0377` while `\377` parses fine. Fixed by parsing up to 4 octal digits, while checking the result fits into a byte.
3d026436 2025-04-05 14:32:34 keymap serialization: Fix unchecked allocation failures The previous commit enabled clang-tidy to detect some missing checks.
aa8b572e 2025-03-29 12:04:26 keymap serialization: Ensure escaping relevant chars Previously we would write characters without any escaping in some cases (e.g.: names of indicators, types and groups). E.g. the string "new\nline" would be serialized as: "new line" which would raise a syntax error if parsed. Fixed by escaping any string that was not escaped after parsing (e.g. the section names are safe already).
e09cbe66 2025-04-02 10:46:06 symbols: Fix handling of empty keys Before this commit, the following symbols: ```c xkb_symbols { virtual_modifiers M1, M2; key <A> {}; key <B> { [] }; key.vmods = M1; key <C> {}; key <D> { vmods = M2 }; }; ``` would be equivalent to: ```c xkb_symbols { virtual_modifiers M1,M2; key <B> { [ NoSymbol ] }; }; ``` `<B>` entry could be skipped but is harmless. However, `<C>` and `<D>` are missing, which would lead to the mapping resolution of `M1` and `M2` failing. After this commit, it is equivalent to: ```c virtual_modifiers M1,M2; key <C> { vmods = M1 }; key <D> { vmods = M2 }; ``` Empty keys are skipped entirely, but any explicit field: - is taken into account: previously they would be skipped if there were no group; - forces the key to be printed at serialization.
cc95f217 2025-03-25 11:15:45 xkbcomp: Fix whichGroupState serialization This indicator field was previously looked up in the wrong table, resulting the erroneous serialization `(null)`.
4e90cb9c 2025-03-17 07:02:07 xkbcomp: Improve logging of virtual modifiers When logging about virtual modifier *explicit* mappings, we should always use only real modifiers or hexadecimal numbers to print the mask. Consider: ``` virtual_modifiers M1, M2=0x200, M2=0x400; ``` Before this commit we would get the following warning: ``` WARNING: Virtual modifier M2 defined multiple times; Using M2, ignoring M1 ``` while we would prefer the less confusing: ``` WARNING: Virtual modifier M2 defined multiple times; Using 0x400, ignoring 0x200 ```
a4038a47 2025-02-12 09:50:36 Miscellaneous int types fixes
e120807b 2025-01-29 15:35:22 Update license notices to SDPX short identifiers + update LICENSE Fix #628. Signed-off-by: Ran Benita <ran@unusedvar.com>
357ab0cb 2025-01-23 16:42:30 clang-tidy: Fix missing default case in switch statement
425dc634 2025-01-21 15:40:33 Fix some implicit integers casts
c0762c49 2025-01-20 16:33:50 keymap: Fix buffer unnecessary written twice When dumping the keymap, we first try to write to the buffer and get the min size requirement. Then we reallocate if necessary. However, we should not write it again if we got enough space previously!
24fe4bac 2025-01-20 16:31:44 Fix undefined behaviours with NULL pointer Issues detected by the sanitizers: - fix indexing NULL pointer - fix zero offset to NULL pointer
b0d9a790 2025-01-15 12:03:10 vmods: Fix explicit vmods not dumped
c7fdf506 2025-01-16 20:23:28 Use portable integer literal suffixes
fdf2c525 2024-10-08 19:43:30 actions: Add support for multiple actions per level This makes 1 keysym == 1 action holds also for multiple keysyms per level. The motivation of this new feature are: - Make multiple keysyms per level more intuitive. - Explore how to fix the issue with shortcuts in multi-layout settings (see the xkeyboard-config issue[^1]). The idea is to use e.g.: ```c key <LCTL> { symbols[1] = [ {Control_L, ISO_First_Group } ], actions[1] = [ {SetMods(modifiers=Control), SetGroup(group=-4) } ] }; ``` in order to switch temporarily to a reference layout in order to get the same shortcuts on every layout. When no action is specified, `interpret` statements are used to find an action corresponding for *each* keysym, as expected. For an interpretation matching Any keysym, we may get the same interpretation for multiple keysyms. This may result in unwanted duplicate actions. So set this interpretation only if no previous keysym was matched with this interpret at this level, else set the default interpretation. For now, at most one action of each following categories is allowed per level: - modifier actions: `SetMods`, `LatchMods`, `LockMods`; - group actions: `SetGroup`, `LatchGroup`, `LockGroup`. Some examples: - `SetMods` + `SetGroup`: ok - `SetMods` + `SetMods`: error - `SetMods` + `LockMods`: error - `SetMods` + `LockGroup`: ok [^1]: https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/issues/416
948f7a59 2024-10-09 08:34:27 symbols: Skip interprets only for groups with explicit actions Previously setting explicit actions for a group in symbols files made the parser skip compatibility interpretations for the corresponding *whole* key, so the other groups with *no* explicit actions could result broken on some levels. In the following example, `<RALT>` would have an action on group 2, because it is explicit, but none on group 1 because interpretation are also skipped there as a side effect: ```c key <RALT> { symbols[1]= [ ISO_Level3_Shift ], symbols[2]= [ ISO_Level3_Shift ], actions[2]= [ SetMods(modifiers=LevelThree) ] }; ``` Fixed by skipping interpretations *only* for groups with explicit actions. We still set `key->explicit |= EXPLICIT_INTERP` if at least one group has explicit actions. In such case, when dumping a keymap, we will write explicit actions for *all* groups, in order to ensure that X11 and previous versions of libxkbcommon can parse the keymap as intended. One side effect is that no interpretation will be run on this key anymore, so we may have to set some extra fields explicitly: repeat, virtualMods. Thus the previous example would be bumped as: ```c key <RALT> { repeat= No, symbols[1]= [ ISO_Level3_Shift ], actions[1]= [ SetMods(modifiers=LevelThree,clearLocks) ], symbols[2]= [ ISO_Level3_Shift ], actions[2]= [ SetMods(modifiers=LevelThree) ] }; ```
fbf087ea 2020-11-23 19:51:04 keymap-dump: follow xkbcomp in printing affect=both in pointer actions It is equivalent to nothing but good to match up. Signed-off-by: Ran Benita <ran@unusedvar.com>
40aab05e 2019-12-27 13:03:20 build: include config.h manually Previously we included it with an `-include` compiler directive. But that's not portable. And it's better to be explicit anyway. Every .c file should have `include "config.h"` first thing. Signed-off-by: Ran Benita <ran@unusedvar.com>
34122f9f 2019-12-27 12:34:49 utils: use MIN/MAX instead of min/max min/max symbols conflict on some systems (msvc), so just use the macros. Signed-off-by: Ran Benita <ran@unusedvar.com>
076047b2 2019-10-16 10:32:19 keymap-dump: use consistent capitalization for "Group<N>" It's used capitalized everywhere except a couple places. Signed-off-by: Ran Benita <ran@unusedvar.com>
a6ed0304 2019-10-16 10:27:12 keymap-dump: fix invalid names used for levels above 8 xkbcomp only accepts the "Level" prefix for a level name for levels 1 to 8, but the keymap dumping code added it always, e.g. "Level15". The plain integer, e.g. "8", "15" is always accepted, so just use that. Fixes https://github.com/xkbcommon/libxkbcommon/issues/113 Signed-off-by: Ran Benita <ran@unusedvar.com> Reported-by: progandy
26453b84 2017-12-12 14:30:21 keymap: fix NULL dereference when dumping the default fallback type The default fallback type uses type->level_names = NULL but the keymap-dump code was not checking this case. Instead of adding more workarounds and possible bugs (e.g. previous commit), let's just keep the number of level names separately. This has the additional advantage retains extraneous level name if someone adds them for some reason. Signed-off-by: Ran Benita <ran234@gmail.com>
0dd610fb 2016-06-09 16:32:05 keymap-dump: use consistent order set/latch/lock (style) Signed-off-by: Ran Benita <ran234@gmail.com>
725ae134 2014-09-25 22:01:17 keymap: rename XkbKeyGroupWidth to XkbKeyNumLevels The "width" terminology comes from the group*width+level layout of the keysyms in a key, as used in the old implementations. We don't keep all the keysyms of a key in one array so change it to a more accurate name. Signed-off-by: Ran Benita <ran234@gmail.com>
68962aa1 2014-09-21 23:54:34 keymap-dump: combine modifier_map's with the same modifier A bit less efficient, but makes for shorter, nicer output. Signed-off-by: Ran Benita <ran234@gmail.com>
67d884ec 2014-06-01 15:24:10 Remove unnecessary !!(expressions) _Bool already does that. Signed-off-by: Ran Benita <ran234@gmail.com>
9014cf8c 2014-04-22 13:15:21 keymap, keycodes, compat: don't use darray for LEDs Use a static array of size XKB_MAX_LEDS instead, as in xkb_mod_set. Signed-off-by: Ran Benita <ran234@gmail.com>
6b1cdee1 2014-04-22 11:47:23 keymap: add and use xkb_mods_{foreach,enumerate}() To iterate over an xkb_mod_set. Slightly nicer interface and makes transitioning from darray easier. Signed-off-by: Ran Benita <ran234@gmail.com>
0f6bca2b 2014-04-22 11:33:47 keymap: rename xkb_foreach_key to xkb_keys_foreach We'll use the format xkb_foos_foreach and xkb_foos_enumerate for the various iterators. Signed-off-by: Ran Benita <ran234@gmail.com>
edc0aef5 2013-02-08 13:21:27 text: take xkb_mod_set instead of the entire keymap The modifier printing functions only need the modifier information, they don't care about keys or leds, etc. Signed-off-by: Ran Benita <ran234@gmail.com>
ca3170ad 2013-02-08 13:09:33 Add struct xkb_mod_set The only thing that the compilation phase needs the keymap for currently is for access to the modifier information (it also modifies it in place!). We want to only pass along the neccessary information, to make it more tractable and testable, so instead of passing the entire keymap we add a new 'mod_set' object and pass a (const) reference to that. The new object is just the old array of 'struct xkb_mod'. Signed-off-by: Ran Benita <ran234@gmail.com>
18191702 2014-02-16 10:59:42 keymap: change action flag NO_ACCEL -> ACCEL It's easier to deal with, but we need to set it as "factory default". Signed-off-by: Ran Benita <ran234@gmail.com>
af261cb6 2014-02-16 10:22:32 action: fix SwitchScreen "same" field handling This used to *unset* a flag called "SwitchApplication"; we changed the flag to "same" but forgot to switch the cases. Signed-off-by: Ran Benita <ran234@gmail.com>
8d3db622 2014-02-15 23:50:21 keymap-dump: add missing support for NoLock and NoUnlock flags Based on a libxkbfile patch by Andreas Wettstein. Signed-off-by: Ran Benita <ran234@gmail.com>
11a9f76b 2014-02-15 23:27:23 keymap-dump: don't print "affect=lock" in PtrLock It's the same as no flags, so might as well not print it. (In fact it is slightly harmful, because it actively *clears* the affect flags, which might have been set in some other manner. But in practice this cannot happen). Signed-off-by: Ran Benita <ran234@gmail.com>
be27b603 2014-02-15 23:13:21 keymap-dump: unbreak some complex lines It's very hard to read as-is. Apologies for those reading over a VT100. Signed-off-by: Ran Benita <ran234@gmail.com>
769b91c5 2014-02-08 15:30:05 Use (1u << idx) instead of (1 << idx) where appropriate It doesn't matter (I think), since the implicit conversion doesn't have any effect (e.g. sign-extension). But it's better to be aware of the type. Signed-off-by: Ran Benita <ran234@gmail.com>
623b10f8 2014-02-08 00:27:54 Fix sign-compare warnings Signed-off-by: Ran Benita <ran234@gmail.com>
d2383d38 2013-08-01 20:44:46 keymap-dump: use correct format specifiers For keycodes, groups, levels, etc, which are unsigned. The really proper inttypes.h ones seem a bit much though. Signed-off-by: Ran Benita <ran234@gmail.com>
9ffe9dae 2013-07-21 09:48:12 keymap: don't use darray for sym_interprets We want xkb_keymap to be easy to handle everywhere. Signed-off-by: Ran Benita <ran234@gmail.com>
17a956d8 2013-05-09 14:47:09 Widen keycode range to 8/255 if possible (bug #63390) If the keycode range is smaller than 8 → 255, artifically widen it when dumping the keymap as not to displease X. Signed-off-by: Daniel Stone <daniel@fooishbar.org>
57bfde3a 2013-03-04 18:41:13 keymap: rename xkb_kt_map_entry to xkb_key_type_entry That's a better name and fits more nicely. Also change type->map to type->entries. Signed-off-by: Ran Benita <ran234@gmail.com>
f8d3ec9f 2013-03-04 12:27:06 keymap: don't use darray for key aliases With a little tweak to the copy-to-keymap routine in keycodes.c we can use a normal array. Signed-off-by: Ran Benita <ran234@gmail.com>
14842d6d 2013-03-01 21:48:02 keymap: abstract a bit over the keymap format Make it a bit easier to experiment with other formats. Add a struct xkb_keymap_format_operations, which currently contains the keymap compilation and _get_as_string functions. Each format can implement whatever it wants from these. The current public entry points become wrappers which do some error reporting, allocation etc., and calling to the specific format. The wrappers are all moved to src/keymap.c, so there are no XKB_EXPORT's under src/xkbcomp/ anymore. The only format available now is normal text_v1. This is all not very KISS, and adds some indirection, but it is helpful and somewhat cleaner. Signed-off-by: Ran Benita <ran234@gmail.com>