From bd40a7cc446cafb8c9922d7d19845da580868859 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 28 Mar 2014 16:22:14 +0100 Subject: Update bundled libxkbcommon version to 0.4.1 This is the latest version, released on Mar 27 2014. It includes: https://bugs.freedesktop.org/show_bug.cgi?id=75798 https://bugs.freedesktop.org/show_bug.cgi?id=75892 Required for fixing input when running Qt application on Mac OS X with XQuartz and for fixing QTBUG-36281. Change-Id: Idc4d3c99a4008a10b91ab51c8910b36909974703 Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- src/3rdparty/xkbcommon.pri | 5 +- src/3rdparty/xkbcommon/NEWS | 43 ++ src/3rdparty/xkbcommon/README | 114 ----- src/3rdparty/xkbcommon/README.md | 109 +++++ src/3rdparty/xkbcommon/src/context-priv.c | 41 +- src/3rdparty/xkbcommon/src/context.c | 6 +- src/3rdparty/xkbcommon/src/context.h | 17 +- src/3rdparty/xkbcommon/src/darray.h | 250 ++--------- src/3rdparty/xkbcommon/src/keymap-priv.c | 16 +- src/3rdparty/xkbcommon/src/keymap.h | 6 +- src/3rdparty/xkbcommon/src/keysym-utf.c | 48 +-- src/3rdparty/xkbcommon/src/keysym.c | 6 +- src/3rdparty/xkbcommon/src/scanner-utils.h | 159 +++++++ src/3rdparty/xkbcommon/src/state.c | 308 +++++++++++--- src/3rdparty/xkbcommon/src/text.c | 14 +- src/3rdparty/xkbcommon/src/utf8.c | 142 +++++++ src/3rdparty/xkbcommon/src/utf8.h | 36 ++ src/3rdparty/xkbcommon/src/utils.h | 22 +- src/3rdparty/xkbcommon/src/x11/x11-keymap.c | 73 ++-- src/3rdparty/xkbcommon/src/x11/x11-priv.h | 2 +- src/3rdparty/xkbcommon/src/xkb-keymap.c | 33 +- src/3rdparty/xkbcommon/src/xkbcomp/action.c | 427 ++++++++----------- src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c | 59 ++- src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h | 10 +- src/3rdparty/xkbcommon/src/xkbcomp/ast.h | 10 +- src/3rdparty/xkbcommon/src/xkbcomp/compat.c | 203 +-------- src/3rdparty/xkbcommon/src/xkbcomp/expr.c | 12 +- src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c | 81 +--- src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c | 91 ++-- src/3rdparty/xkbcommon/src/xkbcomp/keymap.c | 8 +- src/3rdparty/xkbcommon/src/xkbcomp/keywords.c | 5 +- src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h | 12 +- src/3rdparty/xkbcommon/src/xkbcomp/parser.c | 472 +++++++++++---------- src/3rdparty/xkbcommon/src/xkbcomp/parser.h | 2 +- src/3rdparty/xkbcommon/src/xkbcomp/rules.c | 259 ++++------- src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h | 145 ------- src/3rdparty/xkbcommon/src/xkbcomp/scanner.c | 54 +-- src/3rdparty/xkbcommon/src/xkbcomp/symbols.c | 129 +++--- src/3rdparty/xkbcommon/src/xkbcomp/types.c | 121 +----- src/3rdparty/xkbcommon/src/xkbcomp/vmod.c | 63 ++- src/3rdparty/xkbcommon/src/xkbcomp/vmod.h | 3 +- .../xkbcommon/xkbcommon/xkbcommon-compat.h | 4 + src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h | 8 + src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h | 140 +++++- src/plugins/platforms/xcb/qxcbkeyboard.h | 3 - 45 files changed, 1788 insertions(+), 1983 deletions(-) delete mode 100644 src/3rdparty/xkbcommon/README create mode 100644 src/3rdparty/xkbcommon/README.md create mode 100644 src/3rdparty/xkbcommon/src/scanner-utils.h create mode 100644 src/3rdparty/xkbcommon/src/utf8.c create mode 100644 src/3rdparty/xkbcommon/src/utf8.h delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h (limited to 'src') diff --git a/src/3rdparty/xkbcommon.pri b/src/3rdparty/xkbcommon.pri index eb34403746..eaef4749db 100644 --- a/src/3rdparty/xkbcommon.pri +++ b/src/3rdparty/xkbcommon.pri @@ -26,7 +26,8 @@ SOURCES += \ $$PWD/xkbcommon/src/text.c \ $$PWD/xkbcommon/src/context-priv.c \ $$PWD/xkbcommon/src/keymap-priv.c \ - $$PWD/xkbcommon/src/utils.c + $$PWD/xkbcommon/src/utils.c \ + $$PWD/xkbcommon/src/utf8.c SOURCES += \ $$PWD/xkbcommon/src/xkbcomp/action.c \ @@ -54,7 +55,7 @@ SOURCES += \ SOURCES += \ $$PWD/xkbcommon/src/x11/util.c \ $$PWD/xkbcommon/src/x11/x11-keymap.c \ # renamed: keymap.c -> x11-keymap.c - $$PWD/xkbcommon/src/x11/x11-state.c # renamed: state.c -> x11-keymap.c + $$PWD/xkbcommon/src/x11/x11-state.c # renamed: state.c -> x11-state.c } TR_EXCLUDE += $$PWD/* diff --git a/src/3rdparty/xkbcommon/NEWS b/src/3rdparty/xkbcommon/NEWS index 450b7535ee..07ebdd97e3 100644 --- a/src/3rdparty/xkbcommon/NEWS +++ b/src/3rdparty/xkbcommon/NEWS @@ -1,3 +1,46 @@ +libxkbcommon 0.4.1 +================== + +- Converted README to markdown and added a Quick Guide to the + documentation, which breezes through the most common parts of + xkbcommon. + +- Added two new functions, xkb_state_key_get_utf{8,32}(). They + combine the operations of xkb_state_key_get_syms() and + xkb_keysym_to_utf{8,32}(), and provide a nicer interface for it + (espcially for multiple-keysyms-per-level). + +- The xkb_state_key_get_utf{8,32}() functions now apply Control + transformation: when the Control modifier is active, the string + is converted to an appropriate control character. + This matches the behavior of libX11's XLookupString(3), and + required by the XKB specification: + http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier + + https://bugs.freedesktop.org/show_bug.cgi?id=75892 + +- The consumed modifiers for a key are now calculated similarly + to libX11. The previous behavior caused a bug where Shift would + not cancel an active Caps Lock. + +- Make xkbcommon-x11 work with the keymap reported by the XQuartz + X server. + + https://bugs.freedesktop.org/show_bug.cgi?id=75798 + +- Reduce memory usage during keymap compilation some more. + +- New API: + xkb_state_key_get_consumed_mods() + xkb_state_key_get_utf8() + xkb_state_key_get_utf32() + +- Deprecated API: + XKB_MAP_COMPILE_PLACEHOLDER, XKB_MAP_NO_FLAGS + use XKB_KEYMAP_NO_FLAGS instead. + +- Bug fixes. + libxkbcommon 0.4.0 ================== diff --git a/src/3rdparty/xkbcommon/README b/src/3rdparty/xkbcommon/README deleted file mode 100644 index 6b99c46620..0000000000 --- a/src/3rdparty/xkbcommon/README +++ /dev/null @@ -1,114 +0,0 @@ -Overview {#mainpage} -======== - -xkbcommon is a keymap compiler and support library which processes a -reduced subset of keymaps as defined by the XKB specification. Primarily, -a keymap is created from a set of Rules/Model/Layout/Variant/Options names, -processed through an XKB ruleset, and compiled into a struct xkb_keymap, -which is the base type for all xkbcommon operations. - -From an xkb_keymap, an xkb_state object is created which holds the current -state of all modifiers, groups, LEDs, etc, relating to that keymap. All -key events must be fed into the xkb_state object using xkb_state_update_key(). -Once this is done, the xkb_state object will be properly updated, and the -keysyms to use can be obtained with xkb_state_key_get_syms(). - -libxkbcommon does not distribute a dataset itself, other than for testing -purposes. The most common dataset is xkeyboard-config, as used by all -current distributions for their X11 XKB data. More information on -xkeyboard-config is available here: - http://www.freedesktop.org/wiki/Software/XKeyboardConfig - - -API -=== - -While xkbcommon's API is somewhat derived from the classic XKB API as found -in and friends, it has been substantially reworked to -expose fewer internal details to clients. The supported API is available -in the files. Additional support is provided for -X11 (XCB) clients, in the xkbcommon-x11 library, . - -The xkbcommon API and ABI are stable. We will attempt to not break ABI during -a minor release series, so applications written against 0.1.0 should be -completely compatible with 0.5.3, but not necessarily with 1.0.0. However, new -symbols may be introduced in any release. Thus, anyone packaging xkbcommon -should make sure any package depending on it depends on a release greater than -or equal to the version it was built against (or earlier, if it doesn't use -any newly-introduced symbols), but less than the next major release. - - -Relation to X11 -=============== - -Relative to the XKB 1.1 specification implemented in current X servers, -xkbcommon has removed support for some parts of the specification which -introduced unnecessary complications. Many of these removals were in fact -not implemented, or half-implemented at best, as well as being totally -unused in the standard dataset. - -Notable removals: - - geometry support - + there were very few geometry definitions available, and while - xkbcommon was responsible for parsing this insanely complex format, - it never actually did anything with it - + hopefully someone will develop a companion library which supports - keyboard geometries in a more useful format - - KcCGST (keycodes/compat/geometry/symbols/types) API - + use RMLVO instead; KcCGST is now an implementation detail - + including pre-defined keymap files - - XKM support - + may come in an optional X11 support/compatibility library - - around half of the interpret actions - + pointer device, message and redirect actions in particular - - non-virtual modifiers - + core and virtual modifiers have been collapsed into the same - namespace, with a 'significant' flag that largely parallels the - core/virtual split - - radio groups - + completely unused in current keymaps, never fully implemented - - overlays - + almost completely unused in current keymaps - - key behaviors - + used to implement radio groups and overlays, and to deal with things - like keys that physically lock; unused in current keymaps - - indicator behaviours such as LED-controls-key - + the only supported LED behaviour is key-controls-LED; again this - was never really used in current keymaps - -Notable additions: - - 32-bit keycodes - - extended number of modifiers - - extended number of groups - - multiple keysyms per level - + this requires incompatible dataset changes, such that X11 would - not be able to parse these - - -Development -=========== - -An extremely rudimentary homepage can be found at: - http://xkbcommon.org - -xkbcommon is maintained in git at github.com: - https://github.com/xkbcommon/libxkbcommon - -Patches are always welcome, and may be sent to either xorg-devel@lists.x.org, -or wayland-devel@lists.freedesktop.org. - -Bugs are tracked in Bugzilla at: - https://bugs.freedesktop.org/describecomponents.cgi?product=libxkbcommon -Or in github at: - https://github.com/xkbcommon/libxkbcommon/issues - -The maintainers are Daniel Stone and Ran Benita, who can be reached at: - - - - -Credits -======= - -Many thanks are due to Dan Nicholson for his heroic work in getting xkbcommon -off the ground initially. diff --git a/src/3rdparty/xkbcommon/README.md b/src/3rdparty/xkbcommon/README.md new file mode 100644 index 0000000000..2627a324a6 --- /dev/null +++ b/src/3rdparty/xkbcommon/README.md @@ -0,0 +1,109 @@ +# libxkbcommon + +xkbcommon is a keymap compiler and support library which processes a +reduced subset of keymaps as defined by the XKB specification. Primarily, +a keymap is created from a set of Rules/Model/Layout/Variant/Options names, +processed through an XKB ruleset, and compiled into a struct xkb_keymap, +which is the base type for all xkbcommon operations. + +From an xkb_keymap, an xkb_state object is created which holds the current +state of all modifiers, groups, LEDs, etc, relating to that keymap. All +key events must be fed into the xkb_state object using xkb_state_update_key(). +Once this is done, the xkb_state object will be properly updated, and the +keysyms to use can be obtained with xkb_state_key_get_syms(). + +libxkbcommon does not distribute a dataset itself, other than for testing +purposes. The most common dataset is xkeyboard-config, as used by all +current distributions for their X11 XKB data. More information on +xkeyboard-config is available here: + http://www.freedesktop.org/wiki/Software/XKeyboardConfig + +## Quick Guide + +See [Quick Guide](doc/quick-guide.md). + +## API + +While xkbcommon's API is somewhat derived from the classic XKB API as found +in X11/extensions/XKB.h and friends, it has been substantially reworked to +expose fewer internal details to clients. The supported API is available +in the xkbcommon/xkbcommon-*.h files. Additional support is provided for +X11 (XCB) clients, in the xkbcommon-x11 library, xkbcommon/xkbcommon-x11.h. + +The xkbcommon API and ABI are stable. We will attempt to not break ABI during +a minor release series, so applications written against 0.1.0 should be +completely compatible with 0.5.3, but not necessarily with 1.0.0. However, new +symbols may be introduced in any release. Thus, anyone packaging xkbcommon +should make sure any package depending on it depends on a release greater than +or equal to the version it was built against (or earlier, if it doesn't use +any newly-introduced symbols), but less than the next major release. + +## Relation to X11 + +Relative to the XKB 1.1 specification implemented in current X servers, +xkbcommon has removed support for some parts of the specification which +introduced unnecessary complications. Many of these removals were in fact +not implemented, or half-implemented at best, as well as being totally +unused in the standard dataset. + +Notable removals: +- geometry support + + there were very few geometry definitions available, and while + xkbcommon was responsible for parsing this insanely complex format, + it never actually did anything with it + + hopefully someone will develop a companion library which supports + keyboard geometries in a more useful format +- KcCGST (keycodes/compat/geometry/symbols/types) API + + use RMLVO instead; KcCGST is now an implementation detail + + including pre-defined keymap files +- XKM support + + may come in an optional X11 support/compatibility library +- around half of the interpret actions + + pointer device, message and redirect actions in particular +- non-virtual modifiers + + core and virtual modifiers have been collapsed into the same + namespace, with a 'significant' flag that largely parallels the + core/virtual split +- radio groups + + completely unused in current keymaps, never fully implemented +- overlays + + almost completely unused in current keymaps +- key behaviors + + used to implement radio groups and overlays, and to deal with things + like keys that physically lock; unused in current keymaps +- indicator behaviours such as LED-controls-key + + the only supported LED behaviour is key-controls-LED; again this + was never really used in current keymaps + +Notable additions: +- 32-bit keycodes +- extended number of modifiers +- extended number of groups +- multiple keysyms per level + + this requires incompatible dataset changes, such that X11 would + not be able to parse these + +## Development + +An extremely rudimentary homepage can be found at + http://xkbcommon.org + +xkbcommon is maintained in git at + https://github.com/xkbcommon/libxkbcommon + +Patches are always welcome, and may be sent to either + or + +Bugs are also welcome, and may be reported either at + Bugzilla https://bugs.freedesktop.org/describecomponents.cgi?product=libxkbcommon +or + Github https://github.com/xkbcommon/libxkbcommon/issues + +The maintainers are +- Daniel Stone +- Ran Benita + +## Credits + +Many thanks are due to Dan Nicholson for his heroic work in getting xkbcommon +off the ground initially. diff --git a/src/3rdparty/xkbcommon/src/context-priv.c b/src/3rdparty/xkbcommon/src/context-priv.c index 4d7b2ed110..c934201685 100644 --- a/src/3rdparty/xkbcommon/src/context-priv.c +++ b/src/3rdparty/xkbcommon/src/context-priv.c @@ -112,60 +112,79 @@ xkb_context_get_buffer(struct xkb_context *ctx, size_t size) #define DEFAULT_XKB_OPTIONS NULL #endif -const char * +static const char * xkb_context_get_default_rules(struct xkb_context *ctx) { const char *env = NULL; if (ctx->use_environment_names) - env = getenv("XKB_DEFAULT_RULES"); + env = secure_getenv("XKB_DEFAULT_RULES"); return env ? env : DEFAULT_XKB_RULES; } -const char * +static const char * xkb_context_get_default_model(struct xkb_context *ctx) { const char *env = NULL; if (ctx->use_environment_names) - env = getenv("XKB_DEFAULT_MODEL"); + env = secure_getenv("XKB_DEFAULT_MODEL"); return env ? env : DEFAULT_XKB_MODEL; } -const char * +static const char * xkb_context_get_default_layout(struct xkb_context *ctx) { const char *env = NULL; if (ctx->use_environment_names) - env = getenv("XKB_DEFAULT_LAYOUT"); + env = secure_getenv("XKB_DEFAULT_LAYOUT"); return env ? env : DEFAULT_XKB_LAYOUT; } -const char * +static const char * xkb_context_get_default_variant(struct xkb_context *ctx) { const char *env = NULL; - const char *layout = getenv("XKB_DEFAULT_VARIANT"); + const char *layout = secure_getenv("XKB_DEFAULT_LAYOUT"); /* We don't want to inherit the variant if they haven't also set a * layout, since they're so closely paired. */ if (layout && ctx->use_environment_names) - env = getenv("XKB_DEFAULT_VARIANT"); + env = secure_getenv("XKB_DEFAULT_VARIANT"); return env ? env : DEFAULT_XKB_VARIANT; } -const char * +static const char * xkb_context_get_default_options(struct xkb_context *ctx) { const char *env = NULL; if (ctx->use_environment_names) - env = getenv("XKB_DEFAULT_OPTIONS"); + env = secure_getenv("XKB_DEFAULT_OPTIONS"); return env ? env : DEFAULT_XKB_OPTIONS; } + +void +xkb_context_sanitize_rule_names(struct xkb_context *ctx, + struct xkb_rule_names *rmlvo) +{ + if (isempty(rmlvo->rules)) + rmlvo->rules = xkb_context_get_default_rules(ctx); + if (isempty(rmlvo->model)) + rmlvo->model = xkb_context_get_default_model(ctx); + /* Layout and variant are tied together, so don't try to use one from + * the caller and one from the environment. */ + if (isempty(rmlvo->layout)) { + rmlvo->layout = xkb_context_get_default_layout(ctx); + rmlvo->variant = xkb_context_get_default_variant(ctx); + } + /* Options can be empty, so respect that if passed in. */ + if (rmlvo->options == NULL) + rmlvo->options = xkb_context_get_default_options(ctx); +} diff --git a/src/3rdparty/xkbcommon/src/context.c b/src/3rdparty/xkbcommon/src/context.c index e64b91542f..e9c52ebeee 100644 --- a/src/3rdparty/xkbcommon/src/context.c +++ b/src/3rdparty/xkbcommon/src/context.c @@ -82,7 +82,7 @@ xkb_context_include_path_append_default(struct xkb_context *ctx) ret |= xkb_context_include_path_append(ctx, DFLT_XKB_CONFIG_ROOT); - home = getenv("HOME"); + home = secure_getenv("HOME"); if (!home) return ret; err = asprintf(&user_path, "%s/.xkb", home); @@ -252,11 +252,11 @@ xkb_context_new(enum xkb_context_flags flags) ctx->log_verbosity = 0; /* Environment overwrites defaults. */ - env = getenv("XKB_LOG_LEVEL"); + env = secure_getenv("XKB_LOG_LEVEL"); if (env) xkb_context_set_log_level(ctx, log_level(env)); - env = getenv("XKB_LOG_VERBOSITY"); + env = secure_getenv("XKB_LOG_VERBOSITY"); if (env) xkb_context_set_log_verbosity(ctx, log_verbosity(env)); diff --git a/src/3rdparty/xkbcommon/src/context.h b/src/3rdparty/xkbcommon/src/context.h index 486f4085a6..03e6d50abb 100644 --- a/src/3rdparty/xkbcommon/src/context.h +++ b/src/3rdparty/xkbcommon/src/context.h @@ -91,20 +91,9 @@ ATTR_PRINTF(4, 5) void xkb_log(struct xkb_context *ctx, enum xkb_log_level level, int verbosity, const char *fmt, ...); -const char * -xkb_context_get_default_rules(struct xkb_context *ctx); - -const char * -xkb_context_get_default_model(struct xkb_context *ctx); - -const char * -xkb_context_get_default_layout(struct xkb_context *ctx); - -const char * -xkb_context_get_default_variant(struct xkb_context *ctx); - -const char * -xkb_context_get_default_options(struct xkb_context *ctx); +void +xkb_context_sanitize_rule_names(struct xkb_context *ctx, + struct xkb_rule_names *rmlvo); /* * The format is not part of the argument list in order to avoid the diff --git a/src/3rdparty/xkbcommon/src/darray.h b/src/3rdparty/xkbcommon/src/darray.h index 0cf3747be7..d3fe37b089 100644 --- a/src/3rdparty/xkbcommon/src/darray.h +++ b/src/3rdparty/xkbcommon/src/darray.h @@ -23,93 +23,15 @@ #ifndef CCAN_DARRAY_H #define CCAN_DARRAY_H +/* Originally taken from: http://ccodearchive.net/info/darray.html + * But modified for libxkbcommon. */ + #include #include +#include +#include -/* - * SYNOPSIS - * - * Life cycle of a darray (dynamically-allocated array): - * - * darray(int) a = darray_new(); - * darray_free(a); - * - * struct {darray(int) a;} foo; - * darray_init(foo.a); - * darray_free(foo.a); - * - * Typedefs for darrays of common types: - * - * darray_char, darray_schar, darray_uchar - * darray_short, darray_int, darray_long - * darray_ushort, darray_uint, darray_ulong - * - * Access: - * - * T darray_item(darray(T) arr, size_t index); - * size_t darray_size(darray(T) arr); - * size_t darray_alloc(darray(T) arr); - * bool darray_empty(darray(T) arr); - * - * // Access raw memory, starting from the item in offset. - * // Not safe, be careful, etc. - * T* darray_mem(darray(T) arr, size_t offset); - * - * Insertion (single item): - * - * void darray_append(darray(T) arr, T item); - * void darray_prepend(darray(T) arr, T item); - * void darray_push(darray(T) arr, T item); // same as darray_append - * - * Insertion (multiple items): - * - * void darray_append_items(darray(T) arr, T *items, size_t count); - * void darray_prepend_items(darray(T) arr, T *items, size_t count); - * - * void darray_appends(darray(T) arr, [T item, [...]]); - * void darray_prepends(darray(T) arr, [T item, [...]]); - * - * Removal: - * - * T darray_pop(darray(T) arr | darray_size(arr) != 0); - * T* darray_pop_check(darray(T*) arr); - * - * Replacement: - * - * void darray_from_items(darray(T) arr, T *items, size_t count); - * void darray_from_c(darray(T) arr, T c_array[N]); - * - * String buffer: - * - * void darray_append_string(darray(char) arr, const char *str); - * void darray_append_lit(darray(char) arr, char stringLiteral[N+1]); - * - * void darray_prepend_string(darray(char) arr, const char *str); - * void darray_prepend_lit(darray(char) arr, char stringLiteral[N+1]); - * - * void darray_from_string(darray(T) arr, const char *str); - * void darray_from_lit(darray(char) arr, char stringLiteral[N+1]); - * - * Size management: - * - * void darray_resize(darray(T) arr, size_t newSize); - * void darray_resize0(darray(T) arr, size_t newSize); - * - * void darray_realloc(darray(T) arr, size_t newAlloc); - * void darray_growalloc(darray(T) arr, size_t newAlloc); - * - * Traversal: - * - * darray_foreach(T *&i, darray(T) arr) {...} - * darray_foreach_reverse(T *&i, darray(T) arr) {...} - * - * Except for darray_foreach and darray_foreach_reverse, - * all macros evaluate their non-darray arguments only once. - */ - -/*** Life cycle ***/ - -#define darray(type) struct { type *item; size_t size; size_t alloc; } +#define darray(type) struct { type *item; unsigned size; unsigned alloc; } #define darray_new() { 0, 0, 0 } @@ -118,7 +40,8 @@ } while (0) #define darray_free(arr) do { \ - free((arr).item); darray_init(arr); \ + free((arr).item); \ + darray_init(arr); \ } while (0) /* @@ -154,11 +77,8 @@ typedef darray (unsigned long) darray_ulong; #define darray_item(arr, i) ((arr).item[i]) #define darray_size(arr) ((arr).size) -#define darray_alloc(arr) ((arr).alloc) #define darray_empty(arr) ((arr).size == 0) - #define darray_mem(arr, offset) ((arr).item + (offset)) -#define darray_same(arr1, arr2) ((arr1).item == (arr2).item) /*** Insertion (single item) ***/ @@ -167,74 +87,20 @@ typedef darray (unsigned long) darray_ulong; (arr).item[(arr).size - 1] = (__VA_ARGS__); \ } while (0) -#define darray_prepend(arr, ...) do { \ - darray_resize(arr, (arr).size + 1); \ - memmove((arr).item + 1, (arr).item, \ - ((arr).size - 1) * sizeof(*(arr).item)); \ - (arr).item[0] = (__VA_ARGS__); \ -} while (0) - -#define darray_push(arr, ...) darray_append(arr, __VA_ARGS__) - /*** Insertion (multiple items) ***/ #define darray_append_items(arr, items, count) do { \ - size_t __count = (count), __oldSize = (arr).size; \ + unsigned __count = (count), __oldSize = (arr).size; \ darray_resize(arr, __oldSize + __count); \ memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \ } while (0) -#define darray_prepend_items(arr, items, count) do { \ - size_t __count = (count), __oldSize = (arr).size; \ - darray_resize(arr, __count + __oldSize); \ - memmove((arr).item + __count, (arr).item, \ - __oldSize * sizeof(*(arr).item)); \ - memcpy((arr).item, items, __count * sizeof(*(arr).item)); \ -} while (0) - -#define darray_append_items_nullterminate(arr, items, count) do { \ - size_t __count = (count), __oldSize = (arr).size; \ - darray_resize(arr, __oldSize + __count + 1); \ - memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \ - (arr).item[--(arr).size] = 0; \ -} while (0) - -#define darray_prepend_items_nullterminate(arr, items, count) do { \ - size_t __count = (count), __oldSize = (arr).size; \ - darray_resize(arr, __count + __oldSize + 1); \ - memmove((arr).item + __count, (arr).item, \ - __oldSize * sizeof(*(arr).item)); \ - memcpy((arr).item, items, __count * sizeof(*(arr).item)); \ - (arr).item[--(arr).size] = 0; \ -} while (0) - -#define darray_appends_t(arr, type, ...) do { \ - type __src[] = { __VA_ARGS__ }; \ - darray_append_items(arr, __src, sizeof(__src) / sizeof(*__src)); \ -} while (0) - -#define darray_prepends_t(arr, type, ...) do { \ - type __src[] = { __VA_ARGS__ }; \ - darray_prepend_items(arr, __src, sizeof(__src) / sizeof(*__src)); \ -} while (0) - -/*** Removal ***/ - -/* Warning: Do not call darray_pop on an empty darray. */ -#define darray_pop(arr) ((arr).item[--(arr).size]) -#define darray_pop_check(arr) ((arr).size ? darray_pop(arr) : NULL) - -/*** Replacement ***/ - #define darray_from_items(arr, items, count) do { \ - size_t __count = (count); \ + unsigned __count = (count); \ darray_resize(arr, __count); \ memcpy((arr).item, items, __count * sizeof(*(arr).item)); \ } while (0) -#define darray_from_c(arr, c_array) \ - darray_from_items(arr, c_array, sizeof(c_array) / sizeof(*(c_array))) - #define darray_copy(arr_to, arr_from) \ darray_from_items((arr_to), (arr_from).item, (arr_from).size) @@ -251,24 +117,20 @@ typedef darray (unsigned long) darray_ulong; (arr).size--; \ } while (0) -#define darray_prepend_string(arr, str) do { \ - const char *__str = (str); \ - darray_prepend_items_nullterminate(arr, __str, strlen(__str)); \ -} while (0) - -#define darray_prepend_lit(arr, stringLiteral) \ - darray_prepend_items_nullterminate(arr, stringLiteral, \ - sizeof(stringLiteral) - 1) - -#define darray_from_string(arr, str) do { \ - const char *__str = (str); \ - darray_from_items(arr, __str, strlen(__str) + 1); \ - (arr).size--; \ +#define darray_appends_nullterminate(arr, items, count) do { \ + unsigned __count = (count), __oldSize = (arr).size; \ + darray_resize(arr, __oldSize + __count + 1); \ + memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \ + (arr).item[--(arr).size] = 0; \ } while (0) -#define darray_from_lit(arr, stringLiteral) do { \ - darray_from_items(arr, stringLiteral, sizeof(stringLiteral)); \ - (arr).size--; \ +#define darray_prepends_nullterminate(arr, items, count) do { \ + unsigned __count = (count), __oldSize = (arr).size; \ + darray_resize(arr, __count + __oldSize + 1); \ + memmove((arr).item + __count, (arr).item, \ + __oldSize * sizeof(*(arr).item)); \ + memcpy((arr).item, items, __count * sizeof(*(arr).item)); \ + (arr).item[--(arr).size] = 0; \ } while (0) /*** Size management ***/ @@ -277,7 +139,7 @@ typedef darray (unsigned long) darray_ulong; darray_growalloc(arr, (arr).size = (newSize)) #define darray_resize0(arr, newSize) do { \ - size_t __oldSize = (arr).size, __newSize = (newSize); \ + unsigned __oldSize = (arr).size, __newSize = (newSize); \ (arr).size = __newSize; \ if (__newSize > __oldSize) { \ darray_growalloc(arr, __newSize); \ @@ -292,14 +154,16 @@ typedef darray (unsigned long) darray_ulong; } while (0) #define darray_growalloc(arr, need) do { \ - size_t __need = (need); \ + unsigned __need = (need); \ if (__need > (arr).alloc) \ - darray_realloc(arr, darray_next_alloc((arr).alloc, __need)); \ + darray_realloc(arr, darray_next_alloc((arr).alloc, __need, \ + sizeof(*(arr).item))); \ } while (0) -static inline size_t -darray_next_alloc(size_t alloc, size_t need) +static inline unsigned +darray_next_alloc(unsigned alloc, unsigned need, unsigned itemSize) { + assert(need < UINT_MAX / itemSize / 2); /* Overflow. */ if (alloc == 0) alloc = 4; while (alloc < need) @@ -309,11 +173,6 @@ darray_next_alloc(size_t alloc, size_t need) /*** Traversal ***/ -/* - * darray_foreach(T *&i, darray(T) arr) {...} - * - * Traverse a darray. `i` must be declared in advance as a pointer to an item. - */ #define darray_foreach(i, arr) \ for ((i) = &(arr).item[0]; (i) < &(arr).item[(arr).size]; (i)++) @@ -331,58 +190,7 @@ darray_next_alloc(size_t alloc, size_t need) (idx) < (arr).size; \ (idx)++, (val)++) -/* - * darray_foreach_reverse(T *&i, darray(T) arr) {...} - * - * Like darray_foreach, but traverse in reverse order. - */ #define darray_foreach_reverse(i, arr) \ for ((i) = &(arr).item[(arr).size]; (i)-- > &(arr).item[0]; ) #endif /* CCAN_DARRAY_H */ - -/* - * - * darray_growalloc(arr, newAlloc) sees if the darray can currently hold newAlloc items; - * if not, it increases the alloc to satisfy this requirement, allocating slack - * space to avoid having to reallocate for every size increment. - * - * darray_from_string(arr, str) copies a string to an darray_char. - * - * darray_push(arr, item) pushes an item to the end of the darray. - * darray_pop(arr) pops it back out. Be sure there is at least one item in the darray before calling. - * darray_pop_check(arr) does the same as darray_pop, but returns NULL if there are no more items left in the darray. - * - * darray_make_room(arr, room) ensures there's 'room' elements of space after the end of the darray, and it returns a pointer to this space. - * Currently requires HAVE_STATEMENT_EXPR, but I plan to remove this dependency by creating an inline function. - * - * The following require HAVE_TYPEOF==1 : - * - * darray_appends(arr, item0, item1...) appends a collection of comma-delimited items to the darray. - * darray_prepends(arr, item0, item1...) prepends a collection of comma-delimited items to the darray.\ - * - * - * Examples: - * - * darray(int) arr; - * int *i; - * - * darray_appends(arr, 0,1,2,3,4); - * darray_appends(arr, -5,-4,-3,-2,-1); - * darray_foreach(i, arr) - * printf("%d ", *i); - * printf("\n"); - * - * darray_free(arr); - * - * - * typedef struct {int n,d;} Fraction; - * darray(Fraction) fractions; - * Fraction *i; - * - * darray_appends(fractions, {3,4}, {3,5}, {2,1}); - * darray_foreach(i, fractions) - * printf("%d/%d\n", i->n, i->d); - * - * darray_free(fractions); - */ diff --git a/src/3rdparty/xkbcommon/src/keymap-priv.c b/src/3rdparty/xkbcommon/src/keymap-priv.c index 9f42040828..2b3f8cde0c 100644 --- a/src/3rdparty/xkbcommon/src/keymap-priv.c +++ b/src/3rdparty/xkbcommon/src/keymap-priv.c @@ -30,12 +30,7 @@ static void update_builtin_keymap_fields(struct xkb_keymap *keymap) { struct xkb_context *ctx = keymap->ctx; - - /* - * Add predefined (AKA real, core, X11) modifiers. - * The order is important! - */ - darray_appends_t(keymap->mods, struct xkb_mod, + const struct xkb_mod builtin_mods[] = { { .name = xkb_atom_intern_literal(ctx, "Shift"), .type = MOD_REAL }, { .name = xkb_atom_intern_literal(ctx, "Lock"), .type = MOD_REAL }, { .name = xkb_atom_intern_literal(ctx, "Control"), .type = MOD_REAL }, @@ -43,7 +38,14 @@ update_builtin_keymap_fields(struct xkb_keymap *keymap) { .name = xkb_atom_intern_literal(ctx, "Mod2"), .type = MOD_REAL }, { .name = xkb_atom_intern_literal(ctx, "Mod3"), .type = MOD_REAL }, { .name = xkb_atom_intern_literal(ctx, "Mod4"), .type = MOD_REAL }, - { .name = xkb_atom_intern_literal(ctx, "Mod5"), .type = MOD_REAL }); + { .name = xkb_atom_intern_literal(ctx, "Mod5"), .type = MOD_REAL }, + }; + + /* + * Add predefined (AKA real, core, X11) modifiers. + * The order is important! + */ + darray_append_items(keymap->mods, builtin_mods, ARRAY_SIZE(builtin_mods)); } struct xkb_keymap * diff --git a/src/3rdparty/xkbcommon/src/keymap.h b/src/3rdparty/xkbcommon/src/keymap.h index 5f514ec779..39ac4209ae 100644 --- a/src/3rdparty/xkbcommon/src/keymap.h +++ b/src/3rdparty/xkbcommon/src/keymap.h @@ -146,7 +146,7 @@ enum xkb_action_flags { ACTION_ABSOLUTE_SWITCH = (1 << 5), ACTION_ABSOLUTE_X = (1 << 6), ACTION_ABSOLUTE_Y = (1 << 7), - ACTION_NO_ACCEL = (1 << 8), + ACTION_ACCEL = (1 << 8), ACTION_SAME_SCREEN = (1 << 9), }; @@ -223,7 +223,7 @@ struct xkb_pointer_button_action { enum xkb_action_type type; enum xkb_action_flags flags; uint8_t count; - int8_t button; + uint8_t button; }; struct xkb_private_action { @@ -262,10 +262,10 @@ struct xkb_key_type { struct xkb_sym_interpret { xkb_keysym_t sym; enum xkb_match_operation match; - bool level_one_only; xkb_mod_mask_t mods; xkb_mod_index_t virtual_mod; union xkb_action action; + bool level_one_only; bool repeat; }; diff --git a/src/3rdparty/xkbcommon/src/keysym-utf.c b/src/3rdparty/xkbcommon/src/keysym-utf.c index 129da15cf8..ffe2cea48e 100644 --- a/src/3rdparty/xkbcommon/src/keysym-utf.c +++ b/src/3rdparty/xkbcommon/src/keysym-utf.c @@ -37,6 +37,7 @@ #include "xkbcommon/xkbcommon.h" #include "utils.h" +#include "utf8.h" /* We don't use the uint32_t types here, to save some space. */ struct codepair { @@ -838,15 +839,15 @@ static const struct codepair keysymtab[] = { static uint32_t bin_search(const struct codepair *table, size_t length, xkb_keysym_t keysym) { - int first = 0; - int last = length; + size_t first = 0; + size_t last = length; if (keysym < table[0].keysym || keysym > table[length].keysym) return 0; /* binary search in table */ while (last >= first) { - int mid = (first + last) / 2; + size_t mid = (first + last) / 2; if (table[mid].keysym < keysym) first = mid + 1; else if (table[mid].keysym > keysym) @@ -912,47 +913,6 @@ xkb_keysym_to_utf32(xkb_keysym_t keysym) * Author: Rob Bradford */ -static int -utf32_to_utf8(uint32_t unichar, char *buffer) -{ - int count, shift, length; - uint8_t head; - - if (unichar <= 0x007f) { - buffer[0] = unichar; - buffer[1] = '\0'; - return 2; - } - else if (unichar <= 0x07FF) { - length = 2; - head = 0xc0; - } - else if (unichar <= 0xffff) { - length = 3; - head = 0xe0; - } - else if (unichar <= 0x1fffff) { - length = 4; - head = 0xf0; - } - else if (unichar <= 0x3ffffff) { - length = 5; - head = 0xf8; - } - else { - length = 6; - head = 0xfc; - } - - for (count = length - 1, shift = 0; count > 0; count--, shift += 6) - buffer[count] = 0x80 | ((unichar >> shift) & 0x3f); - - buffer[0] = head | ((unichar >> shift) & 0x3f); - buffer[length] = '\0'; - - return length + 1; -} - XKB_EXPORT int xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size) { diff --git a/src/3rdparty/xkbcommon/src/keysym.c b/src/3rdparty/xkbcommon/src/keysym.c index f52d751973..e8fa5e12ba 100644 --- a/src/3rdparty/xkbcommon/src/keysym.c +++ b/src/3rdparty/xkbcommon/src/keysym.c @@ -64,7 +64,11 @@ compare_by_keysym(const void *a, const void *b) { const xkb_keysym_t *key = a; const struct name_keysym *entry = b; - return *key - (int32_t) entry->keysym; + if (*key < entry->keysym) + return -1; + if (*key > entry->keysym) + return 1; + return 0; } static int diff --git a/src/3rdparty/xkbcommon/src/scanner-utils.h b/src/3rdparty/xkbcommon/src/scanner-utils.h new file mode 100644 index 0000000000..e4e90eb0b6 --- /dev/null +++ b/src/3rdparty/xkbcommon/src/scanner-utils.h @@ -0,0 +1,159 @@ +/* + * Copyright © 2012 Ran Benita + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef XKBCOMP_SCANNER_UTILS_H +#define XKBCOMP_SCANNER_UTILS_H + +/* Point to some substring in the file; used to avoid copying. */ +struct sval { + const char *start; + unsigned int len; +}; +typedef darray(struct sval) darray_sval; + +static inline bool +svaleq(struct sval s1, struct sval s2) +{ + return s1.len == s2.len && strncmp(s1.start, s2.start, s1.len) == 0; +} + +static inline bool +svaleq_prefix(struct sval s1, struct sval s2) +{ + return s1.len <= s2.len && strncmp(s1.start, s2.start, s1.len) == 0; +} + +struct scanner { + const char *s; + size_t pos; + size_t len; + char buf[1024]; + size_t buf_pos; + unsigned line, column; + /* The line/column of the start of the current token. */ + unsigned token_line, token_column; + const char *file_name; + struct xkb_context *ctx; +}; + +#define scanner_log(scanner, level, fmt, ...) \ + xkb_log((scanner)->ctx, (level), 0, \ + "%s:%u:%u: " fmt "\n", \ + (scanner)->file_name, \ + (scanner)->token_line, (scanner)->token_column, ##__VA_ARGS__) + +#define scanner_err(scanner, fmt, ...) \ + scanner_log(scanner, XKB_LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__) + +#define scanner_warn(scanner, fmt, ...) \ + scanner_log(scanner, XKB_LOG_LEVEL_WARNING, fmt, ##__VA_ARGS__) + +static inline void +scanner_init(struct scanner *s, struct xkb_context *ctx, + const char *string, size_t len, const char *file_name) +{ + s->s = string; + s->len = len; + s->pos = 0; + s->line = s->column = 1; + s->token_line = s->token_column = 1; + s->file_name = file_name; + s->ctx = ctx; +} + +static inline char +peek(struct scanner *s) +{ + if (unlikely(s->pos >= s->len)) + return '\0'; + return s->s[s->pos]; +} + +static inline bool +eof(struct scanner *s) +{ + return s->pos >= s->len; +} + +static inline bool +eol(struct scanner *s) +{ + return peek(s) == '\n'; +} + +static inline char +next(struct scanner *s) +{ + if (unlikely(eof(s))) + return '\0'; + if (unlikely(eol(s))) { + s->line++; + s->column = 1; + } + else { + s->column++; + } + return s->s[s->pos++]; +} + +static inline bool +chr(struct scanner *s, char ch) +{ + if (likely(peek(s) != ch)) + return false; + s->pos++; s->column++; + return true; +} + +static inline bool +str(struct scanner *s, const char *string, size_t len) +{ + if (s->len - s->pos < len) + return false; + if (strncasecmp(s->s + s->pos, string, len) != 0) + return false; + s->pos += len; s->column += len; + return true; +} + +#define lit(s, literal) str(s, literal, sizeof(literal) - 1) + +static inline bool +buf_append(struct scanner *s, char ch) +{ + if (s->buf_pos + 1 >= sizeof(s->buf)) + return false; + s->buf[s->buf_pos++] = ch; + return true; +} + +static inline bool +oct(struct scanner *s, uint8_t *out) +{ + int i; + for (i = 0, *out = 0; peek(s) >= '0' && peek(s) <= '7' && i < 3; i++) + *out = *out * 8 + next(s) - '0'; + return i > 0; +} + +#endif diff --git a/src/3rdparty/xkbcommon/src/state.c b/src/3rdparty/xkbcommon/src/state.c index 768d47c182..0f9ea79264 100644 --- a/src/3rdparty/xkbcommon/src/state.c +++ b/src/3rdparty/xkbcommon/src/state.c @@ -61,6 +61,7 @@ #include "keymap.h" #include "keysym.h" +#include "utf8.h" struct xkb_filter { union xkb_action action; @@ -108,7 +109,7 @@ struct xkb_state { * < Left Shift down, Right Shift down, Left Shift Up > * the modifier should still be set. This keeps the count. */ - int16_t mod_key_count[sizeof(xkb_mod_mask_t) * 8]; + int16_t mod_key_count[XKB_MAX_MODS]; int refcnt; darray(struct xkb_filter) filters; @@ -121,9 +122,8 @@ get_entry_for_key_state(struct xkb_state *state, const struct xkb_key *key, { const struct xkb_key_type *type = key->groups[group].type; xkb_mod_mask_t active_mods = state->components.mods & type->mods.mask; - unsigned int i; - for (i = 0; i < type->num_entries; i++) { + for (unsigned i = 0; i < type->num_entries; i++) { /* * If the virtual modifiers are not bound to anything, we're * supposed to skip the entry (xserver does this with cached @@ -170,7 +170,7 @@ wrap_group_into_range(int32_t group, if (num_groups == 0) return XKB_LAYOUT_INVALID; - if (group < num_groups) + if (group >= 0 && (xkb_layout_index_t) group < num_groups) return group; switch (out_of_range_group_action) { @@ -623,30 +623,42 @@ xkb_state_led_update_all(struct xkb_state *state) xkb_mod_mask_t mod_mask = 0; xkb_layout_mask_t group_mask = 0; - if (led->which_mods & XKB_STATE_MODS_EFFECTIVE) - mod_mask |= state->components.mods; - if (led->which_mods & XKB_STATE_MODS_DEPRESSED) - mod_mask |= state->components.base_mods; - if (led->which_mods & XKB_STATE_MODS_LATCHED) - mod_mask |= state->components.latched_mods; - if (led->which_mods & XKB_STATE_MODS_LOCKED) - mod_mask |= state->components.locked_mods; - if (led->mods.mask & mod_mask) - state->components.leds |= (1 << idx); - - if (led->which_groups & XKB_STATE_LAYOUT_EFFECTIVE) - group_mask |= (1 << state->components.group); - if (led->which_groups & XKB_STATE_LAYOUT_DEPRESSED) - group_mask |= (1 << state->components.base_group); - if (led->which_groups & XKB_STATE_LAYOUT_LATCHED) - group_mask |= (1 << state->components.latched_group); - if (led->which_groups & XKB_STATE_LAYOUT_LOCKED) - group_mask |= (1 << state->components.locked_group); - if (led->groups & group_mask) - state->components.leds |= (1 << idx); - - if (led->ctrls & state->keymap->enabled_ctrls) - state->components.leds |= (1 << idx); + if (led->which_mods != 0 && led->mods.mask != 0) { + if (led->which_mods & XKB_STATE_MODS_EFFECTIVE) + mod_mask |= state->components.mods; + if (led->which_mods & XKB_STATE_MODS_DEPRESSED) + mod_mask |= state->components.base_mods; + if (led->which_mods & XKB_STATE_MODS_LATCHED) + mod_mask |= state->components.latched_mods; + if (led->which_mods & XKB_STATE_MODS_LOCKED) + mod_mask |= state->components.locked_mods; + + if (led->mods.mask & mod_mask) { + state->components.leds |= (1u << idx); + continue; + } + } + + if (led->which_groups != 0 && led->groups != 0) { + if (led->which_groups & XKB_STATE_LAYOUT_EFFECTIVE) + group_mask |= (1u << state->components.group); + if (led->which_groups & XKB_STATE_LAYOUT_DEPRESSED) + group_mask |= (1u << state->components.base_group); + if (led->which_groups & XKB_STATE_LAYOUT_LATCHED) + group_mask |= (1u << state->components.latched_group); + if (led->which_groups & XKB_STATE_LAYOUT_LOCKED) + group_mask |= (1u << state->components.locked_group); + + if (led->groups & group_mask) { + state->components.leds |= (1u << idx); + continue; + } + } + + if (led->ctrls & state->keymap->enabled_ctrls) { + state->components.leds |= (1u << idx); + continue; + } } } @@ -657,23 +669,27 @@ xkb_state_led_update_all(struct xkb_state *state) static void xkb_state_update_derived(struct xkb_state *state) { + xkb_layout_index_t wrapped; + state->components.mods = (state->components.base_mods | state->components.latched_mods | state->components.locked_mods); /* TODO: Use groups_wrap control instead of always RANGE_WRAP. */ + wrapped = wrap_group_into_range(state->components.locked_group, + state->keymap->num_groups, + RANGE_WRAP, 0); state->components.locked_group = - wrap_group_into_range(state->components.locked_group, - state->keymap->num_groups, - RANGE_WRAP, 0); + (wrapped == XKB_LAYOUT_INVALID ? 0 : wrapped); + wrapped = wrap_group_into_range(state->components.base_group + + state->components.latched_group + + state->components.locked_group, + state->keymap->num_groups, + RANGE_WRAP, 0); state->components.group = - wrap_group_into_range(state->components.base_group + - state->components.latched_group + - state->components.locked_group, - state->keymap->num_groups, - RANGE_WRAP, 0); + (wrapped == XKB_LAYOUT_INVALID ? 0 : wrapped); xkb_state_led_update_all(state); } @@ -781,7 +797,7 @@ xkb_state_update_mask(struct xkb_state *state, num_mods = xkb_keymap_num_mods(state->keymap); for (idx = 0; idx < num_mods; idx++) { - xkb_mod_mask_t mod = (1 << idx); + xkb_mod_mask_t mod = (1u << idx); if (base_mods & mod) state->components.base_mods |= mod; if (latched_mods & mod) @@ -826,6 +842,53 @@ err: return 0; } +/* + * http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier + */ +static bool +should_do_caps_transformation(struct xkb_state *state, xkb_keycode_t kc) +{ + xkb_mod_index_t caps = + xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CAPS); + + return + xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) > 0 && + xkb_state_mod_index_is_consumed(state, kc, caps) == 0; +} + +/* + * http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier + */ +static bool +should_do_ctrl_transformation(struct xkb_state *state, xkb_keycode_t kc) +{ + xkb_mod_index_t ctrl = + xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CTRL); + + return + xkb_state_mod_index_is_active(state, ctrl, XKB_STATE_MODS_EFFECTIVE) > 0 && + xkb_state_mod_index_is_consumed(state, kc, ctrl) == 0; +} + +/* Verbatim from libX11:src/xkb/XKBBind.c */ +static char +XkbToControl(char ch) +{ + char c = ch; + + if ((c >= '@' && c < '\177') || c == ' ') + c &= 0x1F; + else if (c == '2') + c = '\000'; + else if (c >= '3' && c <= '7') + c -= ('3' - '\033'); + else if (c == '8') + c = '\177'; + else if (c == '/') + c = '_' & 0x1F; + return c; +} + /** * Provides either exactly one symbol, or XKB_KEY_NoSymbol. */ @@ -835,7 +898,6 @@ xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t kc) const xkb_keysym_t *syms; xkb_keysym_t sym; int num_syms; - xkb_mod_index_t caps; num_syms = xkb_state_key_get_syms(state, kc, &syms); if (num_syms != 1) @@ -843,18 +905,135 @@ xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t kc) sym = syms[0]; - /* - * Perform capitalization transformation, see: - * http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier - */ - caps = xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CAPS); - if (xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) > 0 && - xkb_state_mod_index_is_consumed(state, kc, caps) == 0) + if (should_do_caps_transformation(state, kc)) + sym = xkb_keysym_to_upper(sym); + + return sym; +} + +/* + * The caps and ctrl transformations require some special handling, + * so we cannot simply use xkb_state_get_one_sym() for them. + * In particular, if Control is set, we must try very hard to find + * some layout in which the keysym is ASCII and thus can be (maybe) + * converted to a control character. libX11 allows to disable this + * behavior with the XkbLC_ControlFallback (see XkbSetXlibControls(3)), + * but it is enabled by default, yippee. + */ +static xkb_keysym_t +get_one_sym_for_string(struct xkb_state *state, xkb_keycode_t kc) +{ + xkb_level_index_t level; + xkb_layout_index_t layout, num_layouts; + const xkb_keysym_t *syms; + int nsyms; + xkb_keysym_t sym; + + layout = xkb_state_key_get_layout(state, kc); + num_layouts = xkb_keymap_num_layouts_for_key(state->keymap, kc); + level = xkb_state_key_get_level(state, kc, layout); + if (layout == XKB_LAYOUT_INVALID || num_layouts == 0 || + level == XKB_LEVEL_INVALID) + return XKB_KEY_NoSymbol; + + nsyms = xkb_keymap_key_get_syms_by_level(state->keymap, kc, + layout, level, &syms); + if (nsyms != 1) + return XKB_KEY_NoSymbol; + sym = syms[0]; + + if (should_do_ctrl_transformation(state, kc) && sym > 127u) { + for (xkb_layout_index_t i = 0; i < num_layouts; i++) { + level = xkb_state_key_get_level(state, kc, i); + if (level == XKB_LEVEL_INVALID) + continue; + + nsyms = xkb_keymap_key_get_syms_by_level(state->keymap, kc, + i, level, &syms); + if (nsyms == 1 && syms[0] <= 127u) { + sym = syms[0]; + break; + } + } + } + + if (should_do_caps_transformation(state, kc)) { sym = xkb_keysym_to_upper(sym); + } return sym; } +XKB_EXPORT int +xkb_state_key_get_utf8(struct xkb_state *state, xkb_keycode_t kc, + char *buffer, size_t size) +{ + xkb_keysym_t sym; + const xkb_keysym_t *syms; + int nsyms; + int offset; + char tmp[7]; + + sym = get_one_sym_for_string(state, kc); + if (sym != XKB_KEY_NoSymbol) { + nsyms = 1; syms = &sym; + } + else { + nsyms = xkb_state_key_get_syms(state, kc, &syms); + } + + /* Make sure not to truncate in the middle of a UTF-8 sequence. */ + offset = 0; + for (int i = 0; i < nsyms; i++) { + int ret = xkb_keysym_to_utf8(syms[i], tmp, sizeof(tmp)); + if (ret <= 0) + goto err_bad; + + ret--; + if ((size_t) (offset + ret) <= size) + memcpy(buffer + offset, tmp, ret); + offset += ret; + } + + if ((size_t) offset >= size) + goto err_trunc; + buffer[offset] = '\0'; + + if (!is_valid_utf8(buffer, offset)) + goto err_bad; + + if (offset == 1 && (unsigned int) buffer[0] <= 127u && + should_do_ctrl_transformation(state, kc)) + buffer[0] = XkbToControl(buffer[0]); + + return offset; + +err_trunc: + if (size > 0) + buffer[size - 1] = '\0'; + return offset; + +err_bad: + if (size > 0) + buffer[0] = '\0'; + return 0; +} + +XKB_EXPORT uint32_t +xkb_state_key_get_utf32(struct xkb_state *state, xkb_keycode_t kc) +{ + xkb_keysym_t sym; + uint32_t cp; + + sym = get_one_sym_for_string(state, kc); + cp = xkb_keysym_to_utf32(sym); + + if (cp <= 127u && should_do_ctrl_transformation(state, kc)) + cp = (uint32_t) XkbToControl((char) cp); + + return cp; +} + /** * Serialises the requested modifier state into an xkb_mod_mask_t, with all * the same disclaimers as in xkb_state_update_mask. @@ -913,7 +1092,7 @@ xkb_state_mod_index_is_active(struct xkb_state *state, if (idx >= xkb_keymap_num_mods(state->keymap)) return -1; - return !!(xkb_state_serialize_mods(state, type) & (1 << idx)); + return !!(xkb_state_serialize_mods(state, type) & (1u << idx)); } /** @@ -964,7 +1143,7 @@ xkb_state_mod_indices_are_active(struct xkb_state *state, ret = -1; break; } - wanted |= (1 << idx); + wanted |= (1u << idx); } va_end(ap); @@ -1015,7 +1194,7 @@ xkb_state_mod_names_are_active(struct xkb_state *state, ret = -1; break; } - wanted |= (1 << idx); + wanted |= (1u << idx); } va_end(ap); @@ -1042,11 +1221,11 @@ xkb_state_layout_index_is_active(struct xkb_state *state, if (type & XKB_STATE_LAYOUT_EFFECTIVE) ret |= (state->components.group == idx); if (type & XKB_STATE_LAYOUT_DEPRESSED) - ret |= (state->components.base_group == idx); + ret |= (state->components.base_group == (int32_t) idx); if (type & XKB_STATE_LAYOUT_LATCHED) - ret |= (state->components.latched_group == idx); + ret |= (state->components.latched_group == (int32_t) idx); if (type & XKB_STATE_LAYOUT_LOCKED) - ret |= (state->components.locked_group == idx); + ret |= (state->components.locked_group == (int32_t) idx); return ret; } @@ -1077,7 +1256,7 @@ xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx) darray_item(state->keymap->leds, idx).name == XKB_ATOM_NONE) return -1; - return !!(state->components.leds & (1 << idx)); + return !!(state->components.leds & (1u << idx)); } /** @@ -1097,18 +1276,24 @@ xkb_state_led_name_is_active(struct xkb_state *state, const char *name) static xkb_mod_mask_t key_get_consumed(struct xkb_state *state, const struct xkb_key *key) { + const struct xkb_key_type *type; const struct xkb_key_type_entry *entry; + xkb_mod_mask_t preserve; xkb_layout_index_t group; group = xkb_state_key_get_layout(state, key->keycode); if (group == XKB_LAYOUT_INVALID) return 0; + type = key->groups[group].type; + entry = get_entry_for_key_state(state, key, group); - if (!entry) - return 0; + if (entry) + preserve = entry->preserve.mask; + else + preserve = 0; - return entry->mods.mask & ~entry->preserve.mask; + return type->mods.mask & ~preserve; } /** @@ -1132,7 +1317,7 @@ xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t kc, if (!key || idx >= xkb_keymap_num_mods(state->keymap)) return -1; - return !!((1 << idx) & key_get_consumed(state, key)); + return !!((1u << idx) & key_get_consumed(state, key)); } /** @@ -1154,3 +1339,14 @@ xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t kc, return mask & ~key_get_consumed(state, key); } + +XKB_EXPORT xkb_mod_mask_t +xkb_state_key_get_consumed_mods(struct xkb_state *state, xkb_keycode_t kc) +{ + const struct xkb_key *key = XkbKey(state->keymap, kc); + + if (!key) + return 0; + + return key_get_consumed(state, key); +} diff --git a/src/3rdparty/xkbcommon/src/text.c b/src/3rdparty/xkbcommon/src/text.c index 59d6c775cb..f3a09e843d 100644 --- a/src/3rdparty/xkbcommon/src/text.c +++ b/src/3rdparty/xkbcommon/src/text.c @@ -280,7 +280,7 @@ ModMaskText(const struct xkb_keymap *keymap, xkb_mod_mask_t mask) darray_enumerate(i, mod, keymap->mods) { int ret; - if (!(mask & (1 << i))) + if (!(mask & (1u << i))) continue; ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", @@ -307,14 +307,14 @@ LedStateMaskText(struct xkb_context *ctx, enum xkb_state_component mask) for (unsigned i = 0; mask; i++) { int ret; - if (!(mask & (1 << i))) + if (!(mask & (1u << i))) continue; - mask &= ~(1 << i); + mask &= ~(1u << i); ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", pos == 0 ? "" : "+", - LookupValue(modComponentMaskNames, 1 << i)); + LookupValue(modComponentMaskNames, 1u << i)); if (ret <= 0 || pos + ret >= sizeof(buf)) break; else @@ -339,14 +339,14 @@ ControlMaskText(struct xkb_context *ctx, enum xkb_action_controls mask) for (unsigned i = 0; mask; i++) { int ret; - if (!(mask & (1 << i))) + if (!(mask & (1u << i))) continue; - mask &= ~(1 << i); + mask &= ~(1u << i); ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", pos == 0 ? "" : "+", - LookupValue(ctrlMaskNames, 1 << i)); + LookupValue(ctrlMaskNames, 1u << i)); if (ret <= 0 || pos + ret >= sizeof(buf)) break; else diff --git a/src/3rdparty/xkbcommon/src/utf8.c b/src/3rdparty/xkbcommon/src/utf8.c new file mode 100644 index 0000000000..11382c809d --- /dev/null +++ b/src/3rdparty/xkbcommon/src/utf8.c @@ -0,0 +1,142 @@ +/* + * Copyright © 2012 Intel Corporation + * Copyright © 2014 Ran Benita + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Rob Bradford + */ + +#include +#include +#include + +#include "utf8.h" + +int +utf32_to_utf8(uint32_t unichar, char *buffer) +{ + int count, shift, length; + uint8_t head; + + if (unichar <= 0x007f) { + buffer[0] = unichar; + buffer[1] = '\0'; + return 2; + } + else if (unichar <= 0x07FF) { + length = 2; + head = 0xc0; + } + else if (unichar <= 0xffff) { + length = 3; + head = 0xe0; + } + else if (unichar <= 0x1fffff) { + length = 4; + head = 0xf0; + } + else if (unichar <= 0x3ffffff) { + length = 5; + head = 0xf8; + } + else { + length = 6; + head = 0xfc; + } + + for (count = length - 1, shift = 0; count > 0; count--, shift += 6) + buffer[count] = 0x80 | ((unichar >> shift) & 0x3f); + + buffer[0] = head | ((unichar >> shift) & 0x3f); + buffer[length] = '\0'; + + return length + 1; +} + +bool +is_valid_utf8(const char *ss, size_t len) +{ + size_t i = 0; + size_t tail_bytes = 0; + const uint8_t *s = (const uint8_t *) ss; + + /* This beauty is from: + * The Unicode Standard Version 6.2 - Core Specification, Table 3.7 + * http://www.unicode.org/versions/Unicode6.2.0/ch03.pdf#G7404 + * We can optimize if needed. */ + while (i < len) + { + if (s[i] <= 0x7F) { + tail_bytes = 0; + } + else if (s[i] >= 0xC2 && s[i] <= 0xDF) { + tail_bytes = 1; + } + else if (s[i] == 0xE0) { + i++; + if (i >= len || !(s[i] >= 0xA0 && s[i] <= 0xBF)) + return false; + tail_bytes = 1; + } + else if (s[i] >= 0xE1 && s[i] <= 0xEC) { + tail_bytes = 2; + } + else if (s[i] == 0xED) { + i++; + if (i >= len || !(s[i] >= 0x80 && s[i] <= 0x9F)) + return false; + tail_bytes = 1; + } + else if (s[i] >= 0xEE && s[i] <= 0xEF) { + tail_bytes = 2; + } + else if (s[i] == 0xF0) { + i++; + if (i >= len || !(s[i] >= 0x90 && s[i] <= 0xBF)) + return false; + tail_bytes = 2; + } + else if (s[i] >= 0xF1 && s[i] <= 0xF3) { + tail_bytes = 3; + } + else if (s[i] == 0xF4) { + i++; + if (i >= len || !(s[i] >= 0x80 && s[i] <= 0x8F)) + return false; + tail_bytes = 2; + } + else { + return false; + } + + i++; + + while (i < len && tail_bytes > 0 && s[i] >= 0x80 && s[i] <= 0xBF) { + i++; + tail_bytes--; + } + + if (tail_bytes != 0) + return false; + } + + return true; +} diff --git a/src/3rdparty/xkbcommon/src/utf8.h b/src/3rdparty/xkbcommon/src/utf8.h new file mode 100644 index 0000000000..6371cb5596 --- /dev/null +++ b/src/3rdparty/xkbcommon/src/utf8.h @@ -0,0 +1,36 @@ +/* + * Copyright © 2012 Intel Corporation + * Copyright © 2014 Ran Benita + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Rob Bradford + */ + +#ifndef XKBCOMMON_UTF8_H +#define XKBCOMMON_UTF8_H + +int +utf32_to_utf8(uint32_t unichar, char *buffer); + +bool +is_valid_utf8(const char *ss, size_t len); + +#endif diff --git a/src/3rdparty/xkbcommon/src/utils.h b/src/3rdparty/xkbcommon/src/utils.h index 81d1cc9412..878c2ac1e3 100644 --- a/src/3rdparty/xkbcommon/src/utils.h +++ b/src/3rdparty/xkbcommon/src/utils.h @@ -163,13 +163,13 @@ is_graph(char ch) * Note: this is 1-based! It's more useful this way, and returns 0 when * mask is all 0s. */ -static inline int +static inline unsigned msb_pos(uint32_t mask) { - int pos = 0; + unsigned pos = 0; while (mask) { pos++; - mask >>= 1; + mask >>= 1u; } return pos; } @@ -187,6 +187,22 @@ unmap_file(const char *str, size_t size); #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX3(a, b, c) MAX(MAX((a), (b)), (c)) +#if defined(HAVE_SECURE_GETENV) +# define secure_getenv secure_getenv +#elif defined(HAVE___SECURE_GETENV) +# define secure_getenv __secure_getenv +#else +# define secure_getenv getenv +#endif + +#if defined(HAVE___BUILTIN_EXPECT) +# define likely(x) __builtin_expect(!!(x), 1) +# define unlikely(x) __builtin_expect(!!(x), 0) +#else +# define likely(x) (x) +# define unlikely(x) (x) +#endif + /* Compiler Attributes */ #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__CYGWIN__) diff --git a/src/3rdparty/xkbcommon/src/x11/x11-keymap.c b/src/3rdparty/xkbcommon/src/x11/x11-keymap.c index 968f187621..76adf7428d 100644 --- a/src/3rdparty/xkbcommon/src/x11/x11-keymap.c +++ b/src/3rdparty/xkbcommon/src/x11/x11-keymap.c @@ -43,13 +43,13 @@ /* Constants from /usr/include/X11/extensions/XKB.h */ /* XkbNumModifiers. */ -#define NUM_REAL_MODS 8 +#define NUM_REAL_MODS 8u /* XkbNumVirtualMods. */ -#define NUM_VMODS 16 +#define NUM_VMODS 16u /* XkbNoModifier. */ #define NO_MODIFIER 0xff /* XkbNumIndicators. */ -#define NUM_INDICATORS 32 +#define NUM_INDICATORS 32u /* XkbAllIndicatorsMask. */ #define ALL_INDICATORS_MASK 0xffffffff @@ -92,11 +92,14 @@ translate_mods(uint8_t rmods, uint16_t vmods_low, uint16_t vmods_high) { /* We represent mod masks in a single uint32_t value, with real mods * first and vmods after (though we don't make these distinctions). */ - return rmods | (vmods_low << 8) | (vmods_high << 16); + return + ((xkb_mod_mask_t) rmods) | + ((xkb_mod_mask_t) vmods_low << 8) | + ((xkb_mod_mask_t) vmods_high << 16); } static enum xkb_action_controls -translate_controls_mask(uint16_t wire) +translate_controls_mask(uint32_t wire) { enum xkb_action_controls ret = 0; if (wire & XCB_XKB_BOOL_CTRL_REPEAT_KEYS) @@ -218,8 +221,8 @@ translate_action(union xkb_action *action, const xcb_xkb_action_t *wire) action->ptr.x = (wire->moveptr.xLow | (wire->moveptr.xHigh << 8)); action->ptr.y = (wire->moveptr.yLow | (wire->moveptr.yHigh << 8)); - if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_NO_ACCELERATION) - action->ptr.flags |= ACTION_NO_ACCEL; + if (!(wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_NO_ACCELERATION)) + action->ptr.flags |= ACTION_ACCEL; if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_X) action->ptr.flags |= ACTION_ABSOLUTE_X; if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_Y) @@ -263,7 +266,7 @@ translate_action(union xkb_action *action, const xcb_xkb_action_t *wire) action->screen.screen = wire->switchscreen.newScreen; - if (wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_APPLICATION) + if (!(wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_APPLICATION)) action->screen.flags |= ACTION_SAME_SCREEN; if (wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_ABSOLUTE) action->screen.flags |= ACTION_ABSOLUTE_SWITCH; @@ -351,7 +354,7 @@ get_types(struct xkb_keymap *keymap, xcb_connection_t *conn, xcb_xkb_mod_def_iterator_t preserves_iter = xcb_xkb_key_type_preserve_iterator(wire_type); - FAIL_UNLESS(preserves_length <= type->num_entries); + FAIL_UNLESS((unsigned) preserves_length <= type->num_entries); for (int j = 0; j < preserves_length; j++) { xcb_xkb_mod_def_t *wire_preserve = preserves_iter.data; @@ -402,7 +405,7 @@ get_sym_maps(struct xkb_keymap *keymap, xcb_connection_t *conn, FAIL_UNLESS(key->num_groups <= ARRAY_SIZE(wire_sym_map->kt_index)); ALLOC_OR_FAIL(key->groups, key->num_groups); - for (int j = 0; j < key->num_groups; j++) { + for (unsigned j = 0; j < key->num_groups; j++) { FAIL_UNLESS(wire_sym_map->kt_index[j] < keymap->num_types); key->groups[j].type = &keymap->types[wire_sym_map->kt_index[j]]; @@ -424,7 +427,7 @@ get_sym_maps(struct xkb_keymap *keymap, xcb_connection_t *conn, int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map); xcb_keysym_t *syms_iter = xcb_xkb_key_sym_map_syms(wire_sym_map); - FAIL_UNLESS(syms_length == wire_sym_map->width * key->num_groups); + 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; @@ -468,9 +471,12 @@ get_actions(struct xkb_keymap *keymap, xcb_connection_t *conn, for (int i = 0; i < acts_count_length; i++) { xcb_xkb_key_sym_map_t *wire_sym_map = sym_maps_iter.data; + int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map); uint8_t wire_count = *acts_count_iter; struct xkb_key *key = &keymap->keys[reply->firstKeyAction + i]; + 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; @@ -505,8 +511,8 @@ get_vmods(struct xkb_keymap *keymap, xcb_connection_t *conn, darray_resize0(keymap->mods, NUM_REAL_MODS + msb_pos(reply->virtualMods)); - for (int i = 0; i < NUM_VMODS; i++) { - if (reply->virtualMods & (1 << i)) { + for (unsigned i = 0; i < NUM_VMODS; i++) { + if (reply->virtualMods & (1u << i)) { uint8_t wire = *iter; struct xkb_mod *mod = &darray_item(keymap->mods, NUM_REAL_MODS + i); @@ -530,11 +536,13 @@ get_explicits(struct xkb_keymap *keymap, xcb_connection_t *conn, for (int i = 0; i < length; i++) { xcb_xkb_set_explicit_t *wire = iter.data; - struct xkb_key *key = &keymap->keys[wire->keycode]; + struct xkb_key *key; FAIL_UNLESS(wire->keycode >= keymap->min_key_code && wire->keycode <= keymap->max_key_code); + key = &keymap->keys[wire->keycode]; + if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_1) && key->num_groups > 0) key->groups[0].explicit_type = true; @@ -573,11 +581,12 @@ get_modmaps(struct xkb_keymap *keymap, xcb_connection_t *conn, for (int i = 0; i < length; i++) { xcb_xkb_key_mod_map_t *wire = iter.data; - struct xkb_key *key = &keymap->keys[wire->keycode]; + struct xkb_key *key; FAIL_UNLESS(wire->keycode >= keymap->min_key_code && wire->keycode <= keymap->max_key_code); + key = &keymap->keys[wire->keycode]; key->modmap = wire->mods; xcb_xkb_key_mod_map_next(&iter); @@ -599,11 +608,12 @@ get_vmodmaps(struct xkb_keymap *keymap, xcb_connection_t *conn, for (int i = 0; i < length; i++) { xcb_xkb_key_v_mod_map_t *wire = iter.data; - struct xkb_key *key = &keymap->keys[wire->keycode]; + struct xkb_key *key; FAIL_UNLESS(wire->keycode >= keymap->min_key_code && wire->keycode <= keymap->max_key_code); + key = &keymap->keys[wire->keycode]; key->vmodmap = translate_mods(0, wire->vmods, 0); xcb_xkb_key_v_mod_map_next(&iter); @@ -677,8 +687,8 @@ get_indicators(struct xkb_keymap *keymap, xcb_connection_t *conn, darray_resize0(keymap->leds, msb_pos(reply->which)); - for (int i = 0; i < NUM_INDICATORS; i++) { - if (reply->which & (1 << i)) { + for (unsigned i = 0; i < NUM_INDICATORS; i++) { + if (reply->which & (1u << i)) { xcb_xkb_indicator_map_t *wire = iter.data; struct xkb_led *led = &darray_item(keymap->leds, i); @@ -879,8 +889,8 @@ get_indicator_names(struct xkb_keymap *keymap, xcb_connection_t *conn, FAIL_UNLESS(msb_pos(reply->indicators) <= darray_size(keymap->leds)); - for (int i = 0; i < NUM_INDICATORS; i++) { - if (reply->indicators & (1 << i)) { + for (unsigned i = 0; i < NUM_INDICATORS; i++) { + if (reply->indicators & (1u << i)) { xcb_atom_t wire = *iter; struct xkb_led *led = &darray_item(keymap->leds, i); @@ -911,8 +921,8 @@ get_vmod_names(struct xkb_keymap *keymap, xcb_connection_t *conn, */ darray_resize0(keymap->mods, NUM_REAL_MODS + msb_pos(reply->virtualMods)); - for (int i = 0; i < NUM_VMODS; i++) { - if (reply->virtualMods & (1 << i)) { + for (unsigned i = 0; i < NUM_VMODS; i++) { + if (reply->virtualMods & (1u << i)) { xcb_atom_t wire = *iter; struct xkb_mod *mod = &darray_item(keymap->mods, NUM_REAL_MODS + i); @@ -959,7 +969,7 @@ get_key_names(struct xkb_keymap *keymap, xcb_connection_t *conn, FAIL_UNLESS(reply->minKeyCode == keymap->min_key_code); FAIL_UNLESS(reply->maxKeyCode == keymap->max_key_code); FAIL_UNLESS(reply->firstKey == keymap->min_key_code); - FAIL_UNLESS(reply->firstKey + reply->nKeys - 1 == keymap->max_key_code); + FAIL_UNLESS(reply->firstKey + reply->nKeys - 1U == keymap->max_key_code); for (int i = 0; i < length; i++) { xcb_xkb_key_name_t *wire = iter.data; @@ -1023,7 +1033,7 @@ static bool get_names(struct xkb_keymap *keymap, xcb_connection_t *conn, uint16_t device_id) { - static const xcb_xkb_name_detail_t required_names = + static const xcb_xkb_name_detail_t wanted = (XCB_XKB_NAME_DETAIL_KEYCODES | XCB_XKB_NAME_DETAIL_SYMBOLS | XCB_XKB_NAME_DETAIL_TYPES | @@ -1035,17 +1045,21 @@ get_names(struct xkb_keymap *keymap, xcb_connection_t *conn, XCB_XKB_NAME_DETAIL_KEY_ALIASES | XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES | XCB_XKB_NAME_DETAIL_GROUP_NAMES); + static const xcb_xkb_name_detail_t required = + (XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES | + XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES | + XCB_XKB_NAME_DETAIL_KEY_NAMES | + XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES); xcb_xkb_get_names_cookie_t cookie = - xcb_xkb_get_names(conn, device_id, required_names); + xcb_xkb_get_names(conn, device_id, wanted); xcb_xkb_get_names_reply_t *reply = xcb_xkb_get_names_reply(conn, cookie, NULL); xcb_xkb_get_names_value_list_t list; FAIL_IF_BAD_REPLY(reply, "XkbGetNames"); - if ((reply->which & required_names) != required_names) - goto fail; + FAIL_UNLESS((reply->which & required) == required); xcb_xkb_get_names_value_list_unpack(xcb_xkb_get_names_value_list(reply), reply->nTypes, @@ -1093,13 +1107,14 @@ get_controls(struct xkb_keymap *keymap, xcb_connection_t *conn, xcb_xkb_get_controls_reply(conn, cookie, NULL); FAIL_IF_BAD_REPLY(reply, "XkbGetControls"); + FAIL_UNLESS(reply->numGroups > 0 && reply->numGroups <= 4); keymap->enabled_ctrls = translate_controls_mask(reply->enabledControls); keymap->num_groups = reply->numGroups; FAIL_UNLESS(keymap->max_key_code < XCB_XKB_CONST_PER_KEY_BIT_ARRAY_SIZE * 8); - for (int i = keymap->min_key_code; i <= keymap->max_key_code; i++) + for (xkb_keycode_t i = keymap->min_key_code; i <= keymap->max_key_code; i++) keymap->keys[i].repeats = !!(reply->perKeyRepeat[i / 8] & (1 << (i % 8))); free(reply); @@ -1119,7 +1134,7 @@ xkb_x11_keymap_new_from_device(struct xkb_context *ctx, struct xkb_keymap *keymap; const enum xkb_keymap_format format = XKB_KEYMAP_FORMAT_TEXT_V1; - if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) { + if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) { log_err_func(ctx, "unrecognized flags: %#x\n", flags); return NULL; } diff --git a/src/3rdparty/xkbcommon/src/x11/x11-priv.h b/src/3rdparty/xkbcommon/src/x11/x11-priv.h index 03f9ee6710..3a19e99c04 100644 --- a/src/3rdparty/xkbcommon/src/x11/x11-priv.h +++ b/src/3rdparty/xkbcommon/src/x11/x11-priv.h @@ -26,8 +26,8 @@ #include -#include "xkbcommon/xkbcommon-x11.h" #include "keymap.h" +#include "xkbcommon/xkbcommon-x11.h" /* Get a strdup'd name of an X atom. */ bool diff --git a/src/3rdparty/xkbcommon/src/xkb-keymap.c b/src/3rdparty/xkbcommon/src/xkb-keymap.c index 7d991d535d..892b7cf198 100644 --- a/src/3rdparty/xkbcommon/src/xkb-keymap.c +++ b/src/3rdparty/xkbcommon/src/xkb-keymap.c @@ -110,10 +110,10 @@ get_keymap_format_ops(enum xkb_keymap_format format) [XKB_KEYMAP_FORMAT_TEXT_V1] = &text_v1_keymap_format_ops, }; - if ((int) format < 0 || (int) format >= ARRAY_SIZE(keymap_format_ops)) + if ((int) format < 0 || (int) format >= (int) ARRAY_SIZE(keymap_format_ops)) return NULL; - return keymap_format_ops[format]; + return keymap_format_ops[(int) format]; } XKB_EXPORT struct xkb_keymap * @@ -132,33 +132,20 @@ xkb_keymap_new_from_names(struct xkb_context *ctx, return NULL; } - if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) { + if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) { log_err_func(ctx, "unrecognized flags: %#x\n", flags); return NULL; } + keymap = xkb_keymap_new(ctx, format, flags); + if (!keymap) + return NULL; + if (rmlvo_in) rmlvo = *rmlvo_in; else memset(&rmlvo, 0, sizeof(rmlvo)); - - if (isempty(rmlvo.rules)) - rmlvo.rules = xkb_context_get_default_rules(ctx); - if (isempty(rmlvo.model)) - rmlvo.model = xkb_context_get_default_model(ctx); - /* Layout and variant are tied together, so don't try to use one from - * the caller and one from the environment. */ - if (isempty(rmlvo.layout)) { - rmlvo.layout = xkb_context_get_default_layout(ctx); - rmlvo.variant = xkb_context_get_default_variant(ctx); - } - /* Options can be empty, so respect that if passed in. */ - if (rmlvo.options == NULL) - rmlvo.options = xkb_context_get_default_options(ctx); - - keymap = xkb_keymap_new(ctx, format, flags); - if (!keymap) - return NULL; + xkb_context_sanitize_rule_names(ctx, &rmlvo); if (!ops->keymap_new_from_names(keymap, &rmlvo)) { xkb_keymap_unref(keymap); @@ -193,7 +180,7 @@ xkb_keymap_new_from_buffer(struct xkb_context *ctx, return NULL; } - if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) { + if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) { log_err_func(ctx, "unrecognized flags: %#x\n", flags); return NULL; } @@ -230,7 +217,7 @@ xkb_keymap_new_from_file(struct xkb_context *ctx, return NULL; } - if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) { + if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) { log_err_func(ctx, "unrecognized flags: %#x\n", flags); return NULL; } diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/action.c b/src/3rdparty/xkbcommon/src/xkbcomp/action.c index 2bd0bd1589..eb3d37fbbe 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/action.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/action.c @@ -118,6 +118,8 @@ NewActionsInfo(void) /* Increment default button. */ info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.flags = 0; info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.value = 1; + info->actions[ACTION_TYPE_PTR_MOVE].ptr.flags = ACTION_ACCEL; + info->actions[ACTION_TYPE_SWITCH_VT].screen.flags = ACTION_SAME_SCREEN; return info; } @@ -186,10 +188,10 @@ fieldText(enum action_field field) /***====================================================================***/ static inline bool -ReportMismatch(struct xkb_keymap *keymap, enum xkb_action_type action, +ReportMismatch(struct xkb_context *ctx, enum xkb_action_type action, enum action_field field, const char *type) { - log_err(keymap->ctx, + log_err(ctx, "Value of %s field must be of type %s; " "Action %s definition ignored\n", fieldText(field), type, ActionTypeText(action)); @@ -197,10 +199,10 @@ ReportMismatch(struct xkb_keymap *keymap, enum xkb_action_type action, } static inline bool -ReportIllegal(struct xkb_keymap *keymap, enum xkb_action_type action, +ReportIllegal(struct xkb_context *ctx, enum xkb_action_type action, enum action_field field) { - log_err(keymap->ctx, + log_err(ctx, "Field %s is not defined for an action of type %s; " "Action definition ignored\n", fieldText(field), ActionTypeText(action)); @@ -208,10 +210,10 @@ ReportIllegal(struct xkb_keymap *keymap, enum xkb_action_type action, } static inline bool -ReportActionNotArray(struct xkb_keymap *keymap, enum xkb_action_type action, +ReportActionNotArray(struct xkb_context *ctx, enum xkb_action_type action, enum action_field field) { - log_err(keymap->ctx, + log_err(ctx, "The %s field in the %s action is not an array; " "Action definition ignored\n", fieldText(field), ActionTypeText(action)); @@ -228,42 +230,40 @@ HandleNoAction(struct xkb_keymap *keymap, union xkb_action *action, } static bool -CheckLatchLockFlags(struct xkb_keymap *keymap, enum xkb_action_type action, - enum action_field field, const ExprDef *value, - enum xkb_action_flags *flags_inout) +CheckBooleanFlag(struct xkb_context *ctx, enum xkb_action_type action, + enum action_field field, enum xkb_action_flags flag, + const ExprDef *array_ndx, const ExprDef *value, + enum xkb_action_flags *flags_inout) { - enum xkb_action_flags tmp; - bool result; + bool set; - if (field == ACTION_FIELD_CLEAR_LOCKS) - tmp = ACTION_LOCK_CLEAR; - else if (field == ACTION_FIELD_LATCH_TO_LOCK) - tmp = ACTION_LATCH_TO_LOCK; - else - return false; /* WSGO! */ + if (array_ndx) + return ReportActionNotArray(ctx, action, field); - if (!ExprResolveBoolean(keymap->ctx, value, &result)) - return ReportMismatch(keymap, action, field, "boolean"); + if (!ExprResolveBoolean(ctx, value, &set)) + return ReportMismatch(ctx, action, field, "boolean"); - if (result) - *flags_inout |= tmp; + if (set) + *flags_inout |= flag; else - *flags_inout &= ~tmp; + *flags_inout &= ~flag; return true; } static bool CheckModifierField(struct xkb_keymap *keymap, enum xkb_action_type action, - const ExprDef *value, enum xkb_action_flags *flags_inout, - xkb_mod_mask_t *mods_rtrn) + const ExprDef *array_ndx, const ExprDef *value, + enum xkb_action_flags *flags_inout, xkb_mod_mask_t *mods_rtrn) { + if (array_ndx) + return ReportActionNotArray(keymap->ctx, action, ACTION_FIELD_MODIFIERS); + if (value->expr.op == EXPR_IDENT) { const char *valStr; valStr = xkb_atom_text(keymap->ctx, value->ident.ident); if (valStr && (istreq(valStr, "usemodmapmods") || istreq(valStr, "modmapmods"))) { - *mods_rtrn = 0; *flags_inout |= ACTION_MODS_LOOKUP_MODMAP; return true; @@ -271,184 +271,130 @@ CheckModifierField(struct xkb_keymap *keymap, enum xkb_action_type action, } if (!ExprResolveModMask(keymap, value, MOD_BOTH, mods_rtrn)) - return ReportMismatch(keymap, action, + return ReportMismatch(keymap->ctx, action, ACTION_FIELD_MODIFIERS, "modifier mask"); *flags_inout &= ~ACTION_MODS_LOOKUP_MODMAP; return true; } +static const LookupEntry lockWhich[] = { + { "both", 0 }, + { "lock", ACTION_LOCK_NO_UNLOCK }, + { "neither", (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK) }, + { "unlock", ACTION_LOCK_NO_LOCK }, + { NULL, 0 } +}; + static bool -HandleSetLatchMods(struct xkb_keymap *keymap, union xkb_action *action, - enum action_field field, const ExprDef *array_ndx, - const ExprDef *value) +CheckAffectField(struct xkb_context *ctx, enum xkb_action_type action, + const ExprDef *array_ndx, const ExprDef *value, + enum xkb_action_flags *flags_inout) { - struct xkb_mod_action *act = &action->mods; - enum xkb_action_flags rtrn, t1; - xkb_mod_mask_t t2; - - if (array_ndx != NULL) { - switch (field) { - case ACTION_FIELD_CLEAR_LOCKS: - case ACTION_FIELD_LATCH_TO_LOCK: - case ACTION_FIELD_MODIFIERS: - return ReportActionNotArray(keymap, action->type, field); - default: - break; - } - } - - switch (field) { - case ACTION_FIELD_CLEAR_LOCKS: - case ACTION_FIELD_LATCH_TO_LOCK: - rtrn = act->flags; - if (CheckLatchLockFlags(keymap, action->type, field, value, &rtrn)) { - act->flags = rtrn; - return true; - } - return false; + enum xkb_action_flags flags; - case ACTION_FIELD_MODIFIERS: - t1 = act->flags; - if (CheckModifierField(keymap, action->type, value, &t1, &t2)) { - act->flags = t1; - act->mods.mods = t2; - return true; - } - return false; + if (array_ndx) + return ReportActionNotArray(ctx, action, ACTION_FIELD_AFFECT); - default: - break; - } + if (!ExprResolveEnum(ctx, value, &flags, lockWhich)) + return ReportMismatch(ctx, action, ACTION_FIELD_AFFECT, + "lock, unlock, both, neither"); - return ReportIllegal(keymap, action->type, field); + *flags_inout &= ~(ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK); + *flags_inout |= flags; + return true; } static bool -HandleLockMods(struct xkb_keymap *keymap, union xkb_action *action, - enum action_field field, const ExprDef *array_ndx, - const ExprDef *value) +HandleSetLatchLockMods(struct xkb_keymap *keymap, union xkb_action *action, + enum action_field field, const ExprDef *array_ndx, + const ExprDef *value) { struct xkb_mod_action *act = &action->mods; - enum xkb_action_flags t1; - xkb_mod_mask_t t2; - - if (array_ndx && field == ACTION_FIELD_MODIFIERS) - return ReportActionNotArray(keymap, action->type, field); - - switch (field) { - case ACTION_FIELD_MODIFIERS: - t1 = act->flags; - if (CheckModifierField(keymap, action->type, value, &t1, &t2)) { - act->flags = t1; - act->mods.mods = t2; - return true; - } - return false; - - default: - break; - } - - return ReportIllegal(keymap, action->type, field); + const enum xkb_action_type type = action->type; + + if (field == ACTION_FIELD_MODIFIERS) + return CheckModifierField(keymap, action->type, array_ndx, value, + &act->flags, &act->mods.mods); + if ((type == ACTION_TYPE_MOD_SET || type == ACTION_TYPE_MOD_LATCH) && + field == ACTION_FIELD_CLEAR_LOCKS) + return CheckBooleanFlag(keymap->ctx, action->type, field, + ACTION_LOCK_CLEAR, array_ndx, value, + &act->flags); + if (type == ACTION_TYPE_MOD_LATCH && + field == ACTION_FIELD_LATCH_TO_LOCK) + return CheckBooleanFlag(keymap->ctx, action->type, field, + ACTION_LATCH_TO_LOCK, array_ndx, value, + &act->flags); + if (type == ACTION_TYPE_MOD_LOCK && + field == ACTION_FIELD_AFFECT) + return CheckAffectField(keymap->ctx, action->type, array_ndx, value, + &act->flags); + + return ReportIllegal(keymap->ctx, action->type, field); } static bool -CheckGroupField(struct xkb_keymap *keymap, unsigned action, - const ExprDef *value, enum xkb_action_flags *flags_inout, - xkb_layout_index_t *grp_rtrn) +CheckGroupField(struct xkb_context *ctx, unsigned action, + const ExprDef *array_ndx, const ExprDef *value, + enum xkb_action_flags *flags_inout, int32_t *group_rtrn) { const ExprDef *spec; + xkb_layout_index_t idx; + enum xkb_action_flags flags = *flags_inout; + + if (array_ndx) + return ReportActionNotArray(ctx, action, ACTION_FIELD_GROUP); if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) { - *flags_inout &= ~ACTION_ABSOLUTE_SWITCH; + flags &= ~ACTION_ABSOLUTE_SWITCH; spec = value->unary.child; } else { - *flags_inout |= ACTION_ABSOLUTE_SWITCH; + flags |= ACTION_ABSOLUTE_SWITCH; spec = value; } - if (!ExprResolveGroup(keymap->ctx, spec, grp_rtrn)) - return ReportMismatch(keymap, action, ACTION_FIELD_GROUP, + if (!ExprResolveGroup(ctx, spec, &idx)) + return ReportMismatch(ctx, action, ACTION_FIELD_GROUP, "integer (range 1..8)"); - if (value->expr.op == EXPR_NEGATE) - *grp_rtrn = -*grp_rtrn; - else if (value->expr.op != EXPR_UNARY_PLUS) - (*grp_rtrn)--; - - return true; -} - -static bool -HandleSetLatchGroup(struct xkb_keymap *keymap, union xkb_action *action, - enum action_field field, const ExprDef *array_ndx, - const ExprDef *value) -{ - struct xkb_group_action *act = &action->group; - enum xkb_action_flags rtrn, t1; - xkb_layout_index_t t2; - - if (array_ndx != NULL) { - switch (field) { - case ACTION_FIELD_CLEAR_LOCKS: - case ACTION_FIELD_LATCH_TO_LOCK: - case ACTION_FIELD_GROUP: - return ReportActionNotArray(keymap, action->type, field); - - default: - break; - } + /* +n, -n are relative, n is absolute. */ + if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) { + *group_rtrn = (int32_t) idx; + if (value->expr.op == EXPR_NEGATE) + *group_rtrn = -*group_rtrn; } - - switch (field) { - case ACTION_FIELD_CLEAR_LOCKS: - case ACTION_FIELD_LATCH_TO_LOCK: - rtrn = act->flags; - if (CheckLatchLockFlags(keymap, action->type, field, value, &rtrn)) { - act->flags = rtrn; - return true; - } - return false; - - case ACTION_FIELD_GROUP: - t1 = act->flags; - if (CheckGroupField(keymap, action->type, value, &t1, &t2)) { - act->flags = t1; - act->group = t2; - return true; - } - return false; - - default: - break; + else { + *group_rtrn = (int32_t) (idx - 1); } - - return ReportIllegal(keymap, action->type, field); + *flags_inout = flags; + return true; } static bool -HandleLockGroup(struct xkb_keymap *keymap, union xkb_action *action, - enum action_field field, const ExprDef *array_ndx, - const ExprDef *value) +HandleSetLatchLockGroup(struct xkb_keymap *keymap, union xkb_action *action, + enum action_field field, const ExprDef *array_ndx, + const ExprDef *value) { struct xkb_group_action *act = &action->group; - enum xkb_action_flags t1; - xkb_layout_index_t t2; - - if ((array_ndx != NULL) && (field == ACTION_FIELD_GROUP)) - return ReportActionNotArray(keymap, action->type, field); - if (field == ACTION_FIELD_GROUP) { - t1 = act->flags; - if (CheckGroupField(keymap, action->type, value, &t1, &t2)) { - act->flags = t1; - act->group = t2; - return true; - } - return false; - } - return ReportIllegal(keymap, action->type, field); + const enum xkb_action_type type = action->type; + + if (field == ACTION_FIELD_GROUP) + return CheckGroupField(keymap->ctx, action->type, array_ndx, value, + &act->flags, &act->group); + if ((type == ACTION_TYPE_GROUP_SET || type == ACTION_TYPE_GROUP_LATCH) && + field == ACTION_FIELD_CLEAR_LOCKS) + return CheckBooleanFlag(keymap->ctx, action->type, field, + ACTION_LOCK_CLEAR, array_ndx, value, + &act->flags); + if (type == ACTION_TYPE_GROUP_LATCH && + field == ACTION_FIELD_LATCH_TO_LOCK) + return CheckBooleanFlag(keymap->ctx, action->type, field, + ACTION_LATCH_TO_LOCK, array_ndx, value, + &act->flags); + + return ReportIllegal(keymap->ctx, action->type, field); } static bool @@ -458,53 +404,47 @@ HandleMovePtr(struct xkb_keymap *keymap, union xkb_action *action, { struct xkb_pointer_action *act = &action->ptr; - if (array_ndx && (field == ACTION_FIELD_X || field == ACTION_FIELD_Y)) - return ReportActionNotArray(keymap, action->type, field); - if (field == ACTION_FIELD_X || field == ACTION_FIELD_Y) { int val; const bool absolute = (value->expr.op != EXPR_NEGATE && value->expr.op != EXPR_UNARY_PLUS); + if (array_ndx) + return ReportActionNotArray(keymap->ctx, action->type, field); + if (!ExprResolveInteger(keymap->ctx, value, &val)) - return ReportMismatch(keymap, action->type, field, "integer"); + return ReportMismatch(keymap->ctx, action->type, field, "integer"); + + if (val < INT16_MIN || val > INT16_MAX) { + log_err(keymap->ctx, + "The %s field in the %s action must be in range %d..%d; " + "Action definition ignored\n", + fieldText(field), ActionTypeText(action->type), + INT16_MIN, INT16_MAX); + return false; + } if (field == ACTION_FIELD_X) { if (absolute) act->flags |= ACTION_ABSOLUTE_X; - act->x = val; + act->x = (int16_t) val; } else { if (absolute) act->flags |= ACTION_ABSOLUTE_Y; - act->y = val; + act->y = (int16_t) val; } return true; } else if (field == ACTION_FIELD_ACCEL) { - bool set; - - if (!ExprResolveBoolean(keymap->ctx, value, &set)) - return ReportMismatch(keymap, action->type, field, "boolean"); - - if (set) - act->flags &= ~ACTION_NO_ACCEL; - else - act->flags |= ACTION_NO_ACCEL; + return CheckBooleanFlag(keymap->ctx, action->type, field, + ACTION_ACCEL, array_ndx, value, &act->flags); } - return ReportIllegal(keymap, action->type, field); + return ReportIllegal(keymap->ctx, action->type, field); } -static const LookupEntry lockWhich[] = { - { "both", 0 }, - { "lock", ACTION_LOCK_NO_UNLOCK }, - { "neither", (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK) }, - { "unlock", ACTION_LOCK_NO_LOCK }, - { NULL, 0 } -}; - static bool HandlePtrBtn(struct xkb_keymap *keymap, union xkb_action *action, enum action_field field, const ExprDef *array_ndx, @@ -516,10 +456,10 @@ HandlePtrBtn(struct xkb_keymap *keymap, union xkb_action *action, int btn; if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); + return ReportActionNotArray(keymap->ctx, action->type, field); if (!ExprResolveButton(keymap->ctx, value, &btn)) - return ReportMismatch(keymap, action->type, field, + return ReportMismatch(keymap->ctx, action->type, field, "integer (range 1..5)"); if (btn < 0 || btn > 5) { @@ -534,40 +474,30 @@ HandlePtrBtn(struct xkb_keymap *keymap, union xkb_action *action, } else if (action->type == ACTION_TYPE_PTR_LOCK && field == ACTION_FIELD_AFFECT) { - enum xkb_action_flags val; - - if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); - - if (!ExprResolveEnum(keymap->ctx, value, &val, lockWhich)) - return ReportMismatch(keymap, action->type, field, - "lock or unlock"); - - act->flags &= ~(ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK); - act->flags |= val; - return true; + return CheckAffectField(keymap->ctx, action->type, array_ndx, value, + &act->flags); } else if (field == ACTION_FIELD_COUNT) { - int btn; + int val; if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); + return ReportActionNotArray(keymap->ctx, action->type, field); - /* XXX: Should this actually be ResolveButton? */ - if (!ExprResolveButton(keymap->ctx, value, &btn)) - return ReportMismatch(keymap, action->type, field, "integer"); + if (!ExprResolveInteger(keymap->ctx, value, &val)) + return ReportMismatch(keymap->ctx, action->type, field, "integer"); - if (btn < 0 || btn > 255) { + if (val < 0 || val > 255) { log_err(keymap->ctx, "The count field must have a value in the range 0..255; " - "Illegal count %d ignored\n", btn); + "Illegal count %d ignored\n", val); return false; } - act->count = btn; + act->count = (uint8_t) val; return true; } - return ReportIllegal(keymap, action->type, field); + + return ReportIllegal(keymap->ctx, action->type, field); } static const LookupEntry ptrDflts[] = { @@ -588,10 +518,10 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action, unsigned int val; if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); + return ReportActionNotArray(keymap->ctx, action->type, field); if (!ExprResolveEnum(keymap->ctx, value, &val, ptrDflts)) - return ReportMismatch(keymap, action->type, field, + return ReportMismatch(keymap->ctx, action->type, field, "pointer component"); return true; } @@ -600,7 +530,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action, int btn; if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); + return ReportActionNotArray(keymap->ctx, action->type, field); if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) { @@ -613,7 +543,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action, } if (!ExprResolveButton(keymap->ctx, button, &btn)) - return ReportMismatch(keymap, action->type, field, + return ReportMismatch(keymap->ctx, action->type, field, "integer (range 1..5)"); if (btn < 0 || btn > 5) { @@ -633,7 +563,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action, return true; } - return ReportIllegal(keymap, action->type, field); + return ReportIllegal(keymap->ctx, action->type, field); } static bool @@ -648,7 +578,7 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action, int val; if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); + return ReportActionNotArray(keymap->ctx, action->type, field); if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) { @@ -661,7 +591,7 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action, } if (!ExprResolveInteger(keymap->ctx, scrn, &val)) - return ReportMismatch(keymap, action->type, field, + return ReportMismatch(keymap->ctx, action->type, field, "integer (0..255)"); if (val < 0 || val > 255) { @@ -675,23 +605,12 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action, return true; } else if (field == ACTION_FIELD_SAME) { - bool set; - - if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); - - if (!ExprResolveBoolean(keymap->ctx, value, &set)) - return ReportMismatch(keymap, action->type, field, "boolean"); - - if (set) - act->flags &= ~ACTION_SAME_SCREEN; - else - act->flags |= ACTION_SAME_SCREEN; - - return true; + return CheckBooleanFlag(keymap->ctx, action->type, field, + ACTION_SAME_SCREEN, array_ndx, value, + &act->flags); } - return ReportIllegal(keymap, action->type, field); + return ReportIllegal(keymap->ctx, action->type, field); } static bool @@ -705,17 +624,21 @@ HandleSetLockControls(struct xkb_keymap *keymap, union xkb_action *action, unsigned int mask; if (array_ndx) - return ReportActionNotArray(keymap, action->type, field); + return ReportActionNotArray(keymap->ctx, action->type, field); if (!ExprResolveMask(keymap->ctx, value, &mask, ctrlMaskNames)) - return ReportMismatch(keymap, action->type, field, + return ReportMismatch(keymap->ctx, action->type, field, "controls mask"); act->ctrls = mask; return true; } + else if (field == ACTION_FIELD_AFFECT) { + return CheckAffectField(keymap->ctx, action->type, array_ndx, value, + &act->flags); + } - return ReportIllegal(keymap, action->type, field); + return ReportIllegal(keymap->ctx, action->type, field); } static bool @@ -728,8 +651,11 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action, if (field == ACTION_FIELD_TYPE) { int type; + if (array_ndx) + return ReportActionNotArray(keymap->ctx, action->type, field); + if (!ExprResolveInteger(keymap->ctx, value, &type)) - return ReportMismatch(keymap, ACTION_TYPE_PRIVATE, field, "integer"); + return ReportMismatch(keymap->ctx, ACTION_TYPE_PRIVATE, field, "integer"); if (type < 0 || type > 255) { log_err(keymap->ctx, @@ -764,17 +690,17 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action, if (array_ndx == NULL) { xkb_atom_t val; const char *str; - int len; + size_t len; if (!ExprResolveString(keymap->ctx, value, &val)) - return ReportMismatch(keymap, action->type, field, "string"); + return ReportMismatch(keymap->ctx, action->type, field, "string"); str = xkb_atom_text(keymap->ctx, val); len = strlen(str); if (len < 1 || len > 7) { log_warn(keymap->ctx, "A private action has 7 data bytes; " - "Extra %d bytes ignored\n", len - 6); + "Illegal data ignored\n"); return false; } @@ -791,7 +717,7 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action, return false; } - if (ndx < 0 || ndx >= sizeof(act->data)) { + if (ndx < 0 || (size_t) ndx >= sizeof(act->data)) { log_err(keymap->ctx, "The data for a private action is %lu bytes long; " "Attempt to use data[%d] ignored\n", @@ -800,7 +726,7 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action, } if (!ExprResolveInteger(keymap->ctx, value, &datum)) - return ReportMismatch(keymap, act->type, field, "integer"); + return ReportMismatch(keymap->ctx, act->type, field, "integer"); if (datum < 0 || datum > 255) { log_err(keymap->ctx, @@ -814,7 +740,7 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action, } } - return ReportIllegal(keymap, ACTION_TYPE_NONE, field); + return ReportIllegal(keymap->ctx, ACTION_TYPE_NONE, field); } typedef bool (*actionHandler)(struct xkb_keymap *keymap, @@ -825,12 +751,12 @@ typedef bool (*actionHandler)(struct xkb_keymap *keymap, static const actionHandler handleAction[_ACTION_TYPE_NUM_ENTRIES] = { [ACTION_TYPE_NONE] = HandleNoAction, - [ACTION_TYPE_MOD_SET] = HandleSetLatchMods, - [ACTION_TYPE_MOD_LATCH] = HandleSetLatchMods, - [ACTION_TYPE_MOD_LOCK] = HandleLockMods, - [ACTION_TYPE_GROUP_SET] = HandleSetLatchGroup, - [ACTION_TYPE_GROUP_LATCH] = HandleSetLatchGroup, - [ACTION_TYPE_GROUP_LOCK] = HandleLockGroup, + [ACTION_TYPE_MOD_SET] = HandleSetLatchLockMods, + [ACTION_TYPE_MOD_LATCH] = HandleSetLatchLockMods, + [ACTION_TYPE_MOD_LOCK] = HandleSetLatchLockMods, + [ACTION_TYPE_GROUP_SET] = HandleSetLatchLockGroup, + [ACTION_TYPE_GROUP_LATCH] = HandleSetLatchLockGroup, + [ACTION_TYPE_GROUP_LOCK] = HandleSetLatchLockGroup, [ACTION_TYPE_PTR_MOVE] = HandleMovePtr, [ACTION_TYPE_PTR_BUTTON] = HandlePtrBtn, [ACTION_TYPE_PTR_LOCK] = HandlePtrBtn, @@ -921,7 +847,6 @@ HandleActionDef(ExprDef *def, struct xkb_keymap *keymap, return true; } - bool SetActionField(struct xkb_keymap *keymap, const char *elem, const char *field, ExprDef *array_ndx, ExprDef *value, ActionsInfo *info) diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c index d470884e78..11bc0912d1 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c @@ -53,7 +53,6 @@ #include "xkbcomp-priv.h" #include "ast-build.h" -#include "parser-priv.h" #include "include.h" ParseCommon * @@ -202,7 +201,7 @@ ExprCreateKeysymList(xkb_keysym_t sym) ExprDef * ExprCreateMultiKeysymList(ExprDef *expr) { - size_t nLevels = darray_size(expr->keysym_list.symsMapIndex); + unsigned nLevels = darray_size(expr->keysym_list.symsMapIndex); darray_resize(expr->keysym_list.symsMapIndex, 1); darray_resize(expr->keysym_list.symsNumEntries, 1); @@ -215,7 +214,7 @@ ExprCreateMultiKeysymList(ExprDef *expr) ExprDef * ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym) { - size_t nSyms = darray_size(expr->keysym_list.syms); + unsigned nSyms = darray_size(expr->keysym_list.syms); darray_append(expr->keysym_list.symsMapIndex, nSyms); darray_append(expr->keysym_list.symsNumEntries, 1); @@ -227,8 +226,8 @@ ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym) ExprDef * ExprAppendMultiKeysymList(ExprDef *expr, ExprDef *append) { - size_t nSyms = darray_size(expr->keysym_list.syms); - size_t numEntries = darray_size(append->keysym_list.syms); + unsigned nSyms = darray_size(expr->keysym_list.syms); + unsigned numEntries = darray_size(append->keysym_list.syms); darray_append(expr->keysym_list.symsMapIndex, nSyms); darray_append(expr->keysym_list.symsNumEntries, numEntries); @@ -356,7 +355,7 @@ SymbolsCreate(xkb_atom_t keyName, VarDef *symbols) } GroupCompatDef * -GroupCompatCreate(int group, ExprDef *val) +GroupCompatCreate(unsigned group, ExprDef *val) { GroupCompatDef *def = malloc(sizeof(*def)); if (!def) @@ -372,7 +371,7 @@ GroupCompatCreate(int group, ExprDef *val) } ModMapDef * -ModMapCreate(uint32_t modifier, ExprDef *keys) +ModMapCreate(xkb_atom_t modifier, ExprDef *keys) { ModMapDef *def = malloc(sizeof(*def)); if (!def) @@ -404,7 +403,7 @@ LedMapCreate(xkb_atom_t name, VarDef *body) } LedNameDef * -LedNameCreate(int ndx, ExprDef *name, bool virtual) +LedNameCreate(unsigned ndx, ExprDef *name, bool virtual) { LedNameDef *def = malloc(sizeof(*def)); if (!def) @@ -496,8 +495,8 @@ err: } XkbFile * -XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name, - ParseCommon *defs, enum xkb_map_flags flags) +XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs, + enum xkb_map_flags flags) { XkbFile *file; @@ -533,7 +532,7 @@ XkbFileFromComponents(struct xkb_context *ctx, if (!include) goto err; - file = XkbFileCreate(ctx, type, NULL, &include->common, 0); + file = XkbFileCreate(type, NULL, (ParseCommon *) include, 0); if (!file) { FreeInclude(include); goto err; @@ -542,7 +541,7 @@ XkbFileFromComponents(struct xkb_context *ctx, defs = AppendStmt(defs, &file->common); } - file = XkbFileCreate(ctx, FILE_TYPE_KEYMAP, NULL, defs, 0); + file = XkbFileCreate(FILE_TYPE_KEYMAP, NULL, defs, 0); if (!file) goto err; @@ -565,7 +564,7 @@ FreeExpr(ExprDef *expr) case EXPR_UNARY_PLUS: case EXPR_NOT: case EXPR_INVERT: - FreeStmt(&expr->unary.child->common); + FreeStmt((ParseCommon *) expr->unary.child); break; case EXPR_DIVIDE: @@ -573,16 +572,16 @@ FreeExpr(ExprDef *expr) case EXPR_SUBTRACT: case EXPR_MULTIPLY: case EXPR_ASSIGN: - FreeStmt(&expr->binary.left->common); - FreeStmt(&expr->binary.right->common); + FreeStmt((ParseCommon *) expr->binary.left); + FreeStmt((ParseCommon *) expr->binary.right); break; case EXPR_ACTION_DECL: - FreeStmt(&expr->action.args->common); + FreeStmt((ParseCommon *) expr->action.args); break; case EXPR_ARRAY_REF: - FreeStmt(&expr->array_ref.entry->common); + FreeStmt((ParseCommon *) expr->array_ref.entry); break; case EXPR_KEYSYM_LIST: @@ -619,12 +618,10 @@ void FreeStmt(ParseCommon *stmt) { ParseCommon *next; - YYSTYPE u; while (stmt) { next = stmt->next; - u.any = stmt; switch (stmt->type) { case STMT_INCLUDE: @@ -633,36 +630,36 @@ FreeStmt(ParseCommon *stmt) stmt = NULL; break; case STMT_EXPR: - FreeExpr(u.expr); + FreeExpr((ExprDef *) stmt); break; case STMT_VAR: - FreeStmt(&u.var->name->common); - FreeStmt(&u.var->value->common); + FreeStmt((ParseCommon *) ((VarDef *) stmt)->name); + FreeStmt((ParseCommon *) ((VarDef *) stmt)->value); break; case STMT_TYPE: - FreeStmt(&u.keyType->body->common); + FreeStmt((ParseCommon *) ((KeyTypeDef *) stmt)->body); break; case STMT_INTERP: - FreeStmt(&u.interp->match->common); - FreeStmt(&u.interp->def->common); + FreeStmt((ParseCommon *) ((InterpDef *) stmt)->match); + FreeStmt((ParseCommon *) ((InterpDef *) stmt)->def); break; case STMT_VMOD: - FreeStmt(&u.vmod->value->common); + FreeStmt((ParseCommon *) ((VModDef *) stmt)->value); break; case STMT_SYMBOLS: - FreeStmt(&u.syms->symbols->common); + FreeStmt((ParseCommon *) ((SymbolsDef *) stmt)->symbols); break; case STMT_MODMAP: - FreeStmt(&u.modMask->keys->common); + FreeStmt((ParseCommon *) ((ModMapDef *) stmt)->keys); break; case STMT_GROUP_COMPAT: - FreeStmt(&u.groupCompat->def->common); + FreeStmt((ParseCommon *) ((GroupCompatDef *) stmt)->def); break; case STMT_LED_MAP: - FreeStmt(&u.ledMap->body->common); + FreeStmt((ParseCommon *) ((LedMapDef *) stmt)->body); break; case STMT_LED_NAME: - FreeStmt(&u.ledName->name->common); + FreeStmt((ParseCommon *) ((LedNameDef *) stmt)->name); break; default: break; diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h index 8146b066d1..b57e4cdce1 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h +++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h @@ -98,23 +98,23 @@ SymbolsDef * SymbolsCreate(xkb_atom_t keyName, VarDef *symbols); GroupCompatDef * -GroupCompatCreate(int group, ExprDef *def); +GroupCompatCreate(unsigned group, ExprDef *def); ModMapDef * -ModMapCreate(uint32_t modifier, ExprDef *keys); +ModMapCreate(xkb_atom_t modifier, ExprDef *keys); LedMapDef * LedMapCreate(xkb_atom_t name, VarDef *body); LedNameDef * -LedNameCreate(int ndx, ExprDef *name, bool virtual); +LedNameCreate(unsigned ndx, ExprDef *name, bool virtual); IncludeStmt * IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge); XkbFile * -XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name, - ParseCommon *defs, enum xkb_map_flags flags); +XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs, + enum xkb_map_flags flags); void FreeStmt(ParseCommon *stmt); diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast.h b/src/3rdparty/xkbcommon/src/xkbcomp/ast.h index 489b33193c..26cbb3a3e4 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/ast.h +++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast.h @@ -143,9 +143,7 @@ expr_op_type_to_string(enum expr_op_type type); const char * expr_value_type_to_string(enum expr_value_type type); -/* This struct contains fields common to all other AST nodes. It is only - * ever embedded in other structs, so save some memory by packing it. */ -typedef struct ATTR_PACKED _ParseCommon { +typedef struct _ParseCommon { struct _ParseCommon *next; enum stmt_type type; } ParseCommon; @@ -226,7 +224,7 @@ typedef struct { typedef struct { ExprCommon expr; darray(xkb_keysym_t) syms; - darray(int) symsMapIndex; + darray(unsigned int) symsMapIndex; darray(unsigned int) symsNumEntries; } ExprKeysymList; @@ -299,7 +297,7 @@ typedef struct { typedef struct { ParseCommon common; enum merge_mode merge; - int group; + unsigned group; ExprDef *def; } GroupCompatDef; @@ -314,7 +312,7 @@ typedef struct { typedef struct { ParseCommon common; enum merge_mode merge; - int ndx; + unsigned ndx; ExprDef *name; bool virtual; } LedNameDef; diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/compat.c b/src/3rdparty/xkbcommon/src/xkbcomp/compat.c index fffb2d34b2..475895c6c1 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/compat.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/compat.c @@ -54,179 +54,6 @@ #include "vmod.h" #include "include.h" -/* - * The xkb_compat section - * ===================== - * This section is the third to be processed, after xkb_keycodes and - * xkb_types. - * - * Interpret statements - * -------------------- - * Statements of the form: - * interpret Num_Lock+Any { ... } - * interpret Shift_Lock+AnyOf(Shift+Lock) { ... } - * - * The xkb_symbols section (see symbols.c) allows the keymap author to do, - * among other things, the following for each key: - * - Bind an action, like SetMods or LockGroup, to the key. Actions, like - * symbols, are specified for each level of each group in the key - * separately. - * - Add a virtual modifier to the key's virtual modifier mapping (vmodmap). - * - Specify whether the key should repeat or not. - * - * However, doing this for each key (or level) is tedious and inflexible. - * Interpret's are a mechanism to apply these settings to a bunch of - * keys/levels at once. - * - * Each interpret specifies a condition by which it attaches to certain - * levels. The condition consists of two parts: - * - A keysym. If the level has a different (or more than one) keysym, the - * match failes. Leaving out the keysym is equivalent to using the - * NoSymbol keysym, which always matches successfully. - * - A modifier predicate. The predicate consists of a matching operation - * and a mask of (real) modifiers. The modifers are matched against the - * key's modifier map (modmap). The matching operation can be one of the - * following: - * + AnyOfOrNone - The modmap must either be empty or include at least - * one of the specified modifiers. - * + AnyOf - The modmap must include at least one of the specified - * modifiers. - * + NoneOf - The modmap must not include any of the specified modifiers. - * + AllOf - The modmap must include all of the specified modifiers (but - * may include others as well). - * + Exactly - The modmap must be exactly the same as the specified - * modifiers. - * Leaving out the predicate is equivalent to usign AnyOfOrNone while - * specifying all modifiers. Leaving out just the matching condtition - * is equivalent to using Exactly. - * An interpret may also include "useModMapMods = level1;" - see below. - * - * If a level fulfils the conditions of several interpret's, only the - * most specific one is used: - * - A specific keysym will always match before a generic NoSymbol - * condition. - * - If the keysyms are the same, the interpret with the more specific - * matching operation is used. The above list is sorted from least to - * most specific. - * - If both the keysyms and the matching operations are the same (but the - * modifiers are different), the first interpret is used. - * - * As described above, once an interpret "attaches" to a level, it can bind - * an action to that level, add one virtual modifier to the key's vmodmap, - * or set the key's repeat setting. You should note the following: - * - The key repeat is a property of the entire key; it is not level-specific. - * In order to avoid confusion, it is only inspected for the first level of - * the first group; the interpret's repeat setting is ignored when applied - * to other levels. - * - If one of the above fields was set directly for a key in xkb_symbols, - * the explicit setting takes precedence over the interpret. - * - * The body of the statment may include statements of the following - * forms (all of which are optional): - * - * - useModMapMods statement: - * useModMapMods = level1; - * - * When set to 'level1', the interpret will only match levels which are - * the first level of the first group of the keys. This can be useful in - * conjunction with e.g. a virtualModifier statement. - * - * - action statement: - * action = LockMods(modifiers=NumLock); - * - * Bind this action to the matching levels. - * - * - virtual modifier statement: - * virtualModifier = NumLock; - * - * Add this virtual modifier to the key's vmodmap. The given virtual - * modifier must be declared at the top level of the file with a - * virtual_modifiers statement, e.g.: - * virtual_modifiers NumLock; - * - * - repeat statement: - * repeat = True; - * - * Set whether the key should repeat or not. Must be a boolean value. - * - * Led map statements - * ------------------------ - * Statements of the form: - * indicator "Shift Lock" { ... } - * - * This statement specifies the behavior and binding of the LED (a.k.a - * indicator) with the given name ("Shift Lock" above). The name should - * have been declared previously in the xkb_keycodes section (see Led - * name statement), and given an index there. If it wasn't, it is created - * with the next free index. - * The body of the statement describes the conditions of the keyboard - * state which will cause the LED to be lit. It may include the following - * statements: - * - * - modifiers statment: - * modifiers = ScrollLock; - * - * If the given modifiers are in the required state (see below), the - * led is lit. - * - * - whichModifierState statment: - * whichModState = Latched + Locked; - * - * Can be any combination of: - * base, latched, locked, effective - * any (i.e. all of the above) - * none (i.e. none of the above) - * compat (legacy value, treated as effective) - * This will cause the respective portion of the modifer state (see - * struct xkb_state) to be matched against the modifiers given in the - * "modifiers" statement. - * - * Here's a simple example: - * indicator "Num Lock" { - * modifiers = NumLock; - * whichModState = Locked; - * }; - * Whenever the NumLock modifier is locked, the Num Lock LED will light - * up. - * - * - groups statment: - * groups = All - group1; - * - * If the given groups are in the required state (see below), the led - * is lit. - * - * - whichGroupState statment: - * whichGroupState = Effective; - * - * Can be any combination of: - * base, latched, locked, effective - * any (i.e. all of the above) - * none (i.e. none of the above) - * This will cause the respective portion of the group state (see - * struct xkb_state) to be matched against the groups given in the - * "groups" statement. - * - * Note: the above conditions are disjunctive, i.e. if any of them are - * satisfied the led is lit. - * - * Virtual modifier statements - * --------------------------- - * Statements of the form: - * virtual_modifiers LControl; - * - * Can appear in the xkb_types, xkb_compat, xkb_symbols sections. - * TODO - * - * Effect on keymap - * ---------------- - * After all of the xkb_compat sections have been compiled, the following - * members of struct xkb_keymap are finalized: - * darray(struct xkb_sym_interpret) sym_interprets; - * darray(struct xkb_led) leds; - * char *compat_section_name; - * TODO: virtual modifiers. - */ - enum si_field { SI_FIELD_VIRTUAL_MOD = (1 << 0), SI_FIELD_ACTION = (1 << 1), @@ -555,16 +382,28 @@ MergeIncludedCompatMaps(CompatInfo *into, CompatInfo *from, from->name = NULL; } - darray_foreach(si, from->interps) { - si->merge = (merge == MERGE_DEFAULT ? si->merge : merge); - if (!AddInterp(into, si, false)) - into->errorCount++; + if (darray_empty(into->interps)) { + into->interps = from->interps; + darray_init(from->interps); + } + else { + darray_foreach(si, from->interps) { + si->merge = (merge == MERGE_DEFAULT ? si->merge : merge); + if (!AddInterp(into, si, false)) + into->errorCount++; + } } - darray_foreach(ledi, from->leds) { - ledi->merge = (merge == MERGE_DEFAULT ? ledi->merge : merge); - if (!AddLedMap(into, ledi, false)) - into->errorCount++; + if (darray_empty(into->leds)) { + into->leds = from->leds; + darray_init(from->leds); + } + else { + darray_foreach(ledi, from->leds) { + ledi->merge = (merge == MERGE_DEFAULT ? ledi->merge : merge); + if (!AddLedMap(into, ledi, false)) + into->errorCount++; + } } } @@ -929,7 +768,7 @@ HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge) ok = HandleGlobalVar(info, (VarDef *) stmt); break; case STMT_VMOD: - ok = HandleVModDef(info->keymap, (VModDef *) stmt); + ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge); break; default: log_err(info->keymap->ctx, diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/expr.c b/src/3rdparty/xkbcommon/src/xkbcomp/expr.c index ba71208f7e..c514f8d54c 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/expr.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/expr.c @@ -116,7 +116,7 @@ LookupModMask(struct xkb_context *ctx, const void *priv, xkb_atom_t field, if (ndx == XKB_MOD_INVALID) return false; - *val_rtrn = (1 << ndx); + *val_rtrn = (1u << ndx); return true; } @@ -427,14 +427,8 @@ ExprResolveLevel(struct xkb_context *ctx, const ExprDef *expr, bool ExprResolveButton(struct xkb_context *ctx, const ExprDef *expr, int *btn_rtrn) { - int result; - - if (!ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup, - buttonNames)) - return false; - - *btn_rtrn = result; - return true; + return ExprResolveIntegerLookup(ctx, expr, btn_rtrn, SimpleLookup, + buttonNames); } bool diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c b/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c index 59916b7266..d90f6a4465 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c @@ -29,79 +29,6 @@ #include "expr.h" #include "include.h" -/* - * The xkb_keycodes section - * ======================== - * - * This is the simplest section type, and is the first one to be - * compiled. The purpose of this is mostly to map between the - * hardware/evdev scancodes and xkb keycodes. Each key is given a name - * by which it can be referred to later, e.g. in the symbols section. - * - * Keycode statements - * ------------------ - * Statements of the form: - * = 49; - * = 10; - * - * The above would let 49 and 10 be valid keycodes in the keymap, and - * assign them the names TLDE and AE01 respectively. The format is - * always used to refer to a key by name. - * - * [ The naming convention just denoted the position of the key - * in the main alphanumric section of the keyboard, with the two letters - * specifying the row and the two digits specifying the column, from - * the bottom left.] - * - * In the common case this just maps to the evdev scancodes from - * /usr/include/linux/input.h, e.g. the following definitions: - * #define KEY_GRAVE 41 - * #define KEY_1 2 - * Similar definitions appear in the xf86-input-keyboard driver. Note - * that in all current keymaps there's a constant offset of 8 (for - * historical reasons). - * - * If there's a conflict, like the same name given to different keycodes, - * or same keycode given different names, it is resolved according to the - * merge mode which applies to the definitions. - * - * Alias statements - * ---------------- - * Statements of the form: - * alias = ; - * - * Allows to refer to a previously defined key (here ) by another - * name (here ). Conflicts are handled similarly. - * - * LED name statements - * ------------------------- - * Statements of the form: - * indicator 1 = "Caps Lock"; - * indicator 2 = "Num Lock"; - * indicator 3 = "Scroll Lock"; - * - * Assigns a name to the keyboard LED (a.k.a indicator) with the given index. - * The led may be referred by this name later in the compat section - * and by the user. - * - * Effect on the keymap - * -------------------- - * After all of the xkb_keycodes sections have been compiled, the - * following members of struct xkb_keymap are finalized: - * xkb_keycode_t min_key_code; - * xkb_keycode_t max_key_code; - * unsigned int num_aliases; - * struct xkb_key_alias *key_aliases; - * char *keycodes_section_name; - * The 'name' field of leds declared in xkb_keycodes: - * darray(struct xkb_led) leds; - * Further, the array of keys: - * struct xkb_key *keys; - * had been resized to its final size (i.e. all of the xkb_key objects are - * referable by their keycode). However the objects themselves do not - * contain any useful information besides the key name at this point. - */ - typedef struct { enum merge_mode merge; @@ -322,7 +249,7 @@ AddKeyName(KeyNamesInfo *info, xkb_keycode_t kc, xkb_atom_t name, /***====================================================================***/ -static int +static bool HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge); static void @@ -459,7 +386,7 @@ HandleKeycodeDef(KeyNamesInfo *info, KeycodeDef *stmt, enum merge_mode merge) return AddKeyName(info, stmt->value, stmt->name, merge, false, true); } -static int +static bool HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge) { AliasInfo *old, new; @@ -499,7 +426,7 @@ HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge) return true; } -static int +static bool HandleKeyNameVar(KeyNamesInfo *info, VarDef *stmt) { const char *elem, *field; @@ -524,7 +451,7 @@ HandleKeyNameVar(KeyNamesInfo *info, VarDef *stmt) return true; } -static int +static bool HandleLedNameDef(KeyNamesInfo *info, LedNameDef *def, enum merge_mode merge) { diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c b/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c index 6b4c266ec0..7f70ca3481 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c @@ -92,7 +92,7 @@ check_write_buf(struct buf *buf, const char *fmt, ...) if (printed < 0) goto err; - if (printed >= available) + if ((size_t) printed >= available) if (!do_realloc(buf, printed)) goto err; @@ -103,7 +103,7 @@ check_write_buf(struct buf *buf, const char *fmt, ...) printed = vsnprintf(buf->buf + buf->size, available, fmt, args); va_end(args); - if (printed >= available || printed < 0) + if (printed < 0 || (size_t) printed >= available) goto err; buf->size += printed; @@ -273,6 +273,20 @@ write_led_map(struct xkb_keymap *keymap, struct buf *buf, return true; } +static const char * +affect_lock_text(enum xkb_action_flags flags) +{ + switch (flags & (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK)) { + case ACTION_LOCK_NO_UNLOCK: + return ",affect=lock"; + case ACTION_LOCK_NO_LOCK: + return ",affect=unlock"; + case ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK: + return ",affect=neither"; + } + return ""; +} + static bool write_action(struct xkb_keymap *keymap, struct buf *buf, const union xkb_action *action, @@ -289,20 +303,17 @@ write_action(struct xkb_keymap *keymap, struct buf *buf, type = ActionTypeText(action->type); switch (action->type) { + case ACTION_TYPE_MOD_LOCK: case ACTION_TYPE_MOD_SET: case ACTION_TYPE_MOD_LATCH: - case ACTION_TYPE_MOD_LOCK: if (action->mods.flags & ACTION_MODS_LOOKUP_MODMAP) args = "modMapMods"; else args = ModMaskText(keymap, action->mods.mods.mods); - write_buf(buf, "%s%s(modifiers=%s%s%s)%s", prefix, type, args, - (action->type != ACTION_TYPE_MOD_LOCK && - (action->mods.flags & ACTION_LOCK_CLEAR)) ? - ",clearLocks" : "", - (action->type != ACTION_TYPE_MOD_LOCK && - (action->mods.flags & ACTION_LATCH_TO_LOCK)) ? - ",latchToLock" : "", + 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) : "", suffix); break; @@ -310,16 +321,10 @@ write_action(struct xkb_keymap *keymap, struct buf *buf, case ACTION_TYPE_GROUP_LATCH: case ACTION_TYPE_GROUP_LOCK: write_buf(buf, "%s%s(group=%s%d%s%s)%s", prefix, type, - (!(action->group.flags & ACTION_ABSOLUTE_SWITCH) && - action->group.group > 0) ? "+" : "", - (action->group.flags & ACTION_ABSOLUTE_SWITCH) ? - action->group.group + 1 : action->group.group, - (action->type != ACTION_TYPE_GROUP_LOCK && - (action->group.flags & ACTION_LOCK_CLEAR)) ? - ",clearLocks" : "", - (action->type != ACTION_TYPE_GROUP_LOCK && - (action->group.flags & ACTION_LATCH_TO_LOCK)) ? - ",latchToLock" : "", + (!(action->group.flags & ACTION_ABSOLUTE_SWITCH) && action->group.group > 0) ? "+" : "", + (action->group.flags & ACTION_ABSOLUTE_SWITCH) ? action->group.group + 1 : action->group.group, + (action->type != ACTION_TYPE_GROUP_LOCK && (action->group.flags & ACTION_LOCK_CLEAR)) ? ",clearLocks" : "", + (action->type != ACTION_TYPE_GROUP_LOCK && (action->group.flags & ACTION_LATCH_TO_LOCK)) ? ",latchToLock" : "", suffix); break; @@ -329,35 +334,17 @@ write_action(struct xkb_keymap *keymap, struct buf *buf, case ACTION_TYPE_PTR_MOVE: write_buf(buf, "%s%s(x=%s%d,y=%s%d%s)%s", prefix, type, - (!(action->ptr.flags & ACTION_ABSOLUTE_X) && - action->ptr.x >= 0) ? "+" : "", + (!(action->ptr.flags & ACTION_ABSOLUTE_X) && action->ptr.x >= 0) ? "+" : "", action->ptr.x, - (!(action->ptr.flags & ACTION_ABSOLUTE_Y) && - action->ptr.y >= 0) ? "+" : "", + (!(action->ptr.flags & ACTION_ABSOLUTE_Y) && action->ptr.y >= 0) ? "+" : "", action->ptr.y, - (action->ptr.flags & ACTION_NO_ACCEL) ? ",!accel" : "", + (action->ptr.flags & ACTION_ACCEL) ? "" : ",!accel", suffix); break; case ACTION_TYPE_PTR_LOCK: - switch (action->btn.flags & - (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK)) { - case ACTION_LOCK_NO_UNLOCK: - args = ",affect=lock"; - break; - - case ACTION_LOCK_NO_LOCK: - args = ",affect=unlock"; - break; - - case ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK: - args = ",affect=neither"; - break; - - default: - args = ",affect=both"; - break; - } + args = affect_lock_text(action->btn.flags); + /* fallthrough */ case ACTION_TYPE_PTR_BUTTON: write_buf(buf, "%s%s(button=", prefix, type); if (action->btn.button > 0 && action->btn.button <= 5) @@ -374,25 +361,25 @@ write_action(struct xkb_keymap *keymap, struct buf *buf, case ACTION_TYPE_PTR_DEFAULT: write_buf(buf, "%s%s(", prefix, type); write_buf(buf, "affect=button,button=%s%d", - (!(action->dflt.flags & ACTION_ABSOLUTE_SWITCH) && - action->dflt.value >= 0) ? "+" : "", + (!(action->dflt.flags & ACTION_ABSOLUTE_SWITCH) && action->dflt.value >= 0) ? "+" : "", action->dflt.value); write_buf(buf, ")%s", suffix); break; case ACTION_TYPE_SWITCH_VT: write_buf(buf, "%s%s(screen=%s%d,%ssame)%s", prefix, type, - (!(action->screen.flags & ACTION_ABSOLUTE_SWITCH) && - action->screen.screen >= 0) ? "+" : "", + (!(action->screen.flags & ACTION_ABSOLUTE_SWITCH) && action->screen.screen >= 0) ? "+" : "", action->screen.screen, - (action->screen.flags & ACTION_SAME_SCREEN) ? "!" : "", + (action->screen.flags & ACTION_SAME_SCREEN) ? "" : "!", suffix); break; case ACTION_TYPE_CTRL_SET: case ACTION_TYPE_CTRL_LOCK: - write_buf(buf, "%s%s(controls=%s)%s", prefix, type, - ControlMaskText(keymap->ctx, action->ctrls.ctrls), suffix); + 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) : "", + suffix); break; case ACTION_TYPE_NONE: @@ -429,7 +416,7 @@ write_compat(struct xkb_keymap *keymap, struct buf *buf) write_buf(buf, "\tinterpret.useModMapMods= AnyLevel;\n"); write_buf(buf, "\tinterpret.repeat= False;\n"); - for (int i = 0; i < keymap->num_sym_interprets; i++) { + for (unsigned i = 0; i < keymap->num_sym_interprets; i++) { const struct xkb_sym_interpret *si = &keymap->sym_interprets[i]; write_buf(buf, "\tinterpret %s+%s(%s) {\n", @@ -635,7 +622,7 @@ write_symbols(struct xkb_keymap *keymap, struct buf *buf) continue; darray_enumerate(i, mod, keymap->mods) - if (key->modmap & (1 << i)) + if (key->modmap & (1u << i)) write_buf(buf, "\tmodifier_map %s { %s };\n", xkb_atom_text(keymap->ctx, mod->name), KeyNameText(keymap->ctx, key->name)); diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c b/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c index 549cf05da6..8a70577faf 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c @@ -39,7 +39,7 @@ ComputeEffectiveMask(struct xkb_keymap *keymap, struct xkb_mods *mods) mods->mask = mods->mods & MOD_REAL_MASK_ALL; darray_enumerate(i, mod, keymap->mods) - if (mods->mods & (1 << i)) + if (mods->mods & (1u << i)) mods->mask |= mod->mapping; } @@ -92,7 +92,7 @@ FindInterpForKey(struct xkb_keymap *keymap, const struct xkb_key *key, * sym_interprets array from the most specific to the least specific, * such that when we find a match we return immediately. */ - for (int i = 0; i < keymap->num_sym_interprets; i++) { + for (unsigned i = 0; i < keymap->num_sym_interprets; i++) { const struct xkb_sym_interpret *interp = &keymap->sym_interprets[i]; xkb_mod_mask_t mods; @@ -158,7 +158,7 @@ ApplyInterpsToKey(struct xkb_keymap *keymap, struct xkb_key *key) if ((group == 0 && level == 0) || !interp->level_one_only) if (interp->virtual_mod != XKB_MOD_INVALID) - vmodmap |= (1 << interp->virtual_mod); + vmodmap |= (1u << interp->virtual_mod); if (interp->action.type != ACTION_TYPE_NONE) key->groups[group].levels[level].action = interp->action; @@ -194,7 +194,7 @@ UpdateDerivedKeymapFields(struct xkb_keymap *keymap) /* Update keymap->mods, the virtual -> real mod mapping. */ xkb_foreach_key(key, keymap) darray_enumerate(i, mod, keymap->mods) - if (key->vmodmap & (1 << i)) + if (key->vmodmap & (1u << i)) mod->mapping |= key->modmap; /* Now update the level masks for all the types to reflect the vmods. */ diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c b/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c index c19d66ffde..abab7fe266 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c @@ -339,10 +339,9 @@ keyword_gperf_lookup (register const char *str, register unsigned int len) int -keyword_to_token(const char *string) +keyword_to_token(const char *string, unsigned int len) { - const struct keyword_tok *kt; - kt = keyword_gperf_lookup(string, strlen(string)); + const struct keyword_tok *kt = keyword_gperf_lookup(string, len); if (!kt) return -1; return kt->tok; diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h b/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h index 05e725eb00..0675e55a8f 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h +++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h @@ -27,24 +27,18 @@ #ifndef XKBCOMP_PARSER_PRIV_H #define XKBCOMP_PARSER_PRIV_H -struct scanner; struct parser_param; +#include "scanner-utils.h" #include "parser.h" -int -scanner_error(struct scanner *scanner, const char *msg); - -void -scanner_warn(struct scanner *s, const char *msg); - int _xkbcommon_lex(YYSTYPE *yylval, struct scanner *scanner); XkbFile * -parse(struct xkb_context *ctx, void *scanner, const char *map); +parse(struct xkb_context *ctx, struct scanner *scanner, const char *map); int -keyword_to_token(const char *string); +keyword_to_token(const char *string, unsigned int len); #endif diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser.c b/src/3rdparty/xkbcommon/src/xkbcomp/parser.c index 26bbf30be8..eaa7384369 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/parser.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser.c @@ -82,27 +82,21 @@ struct parser_param { struct xkb_context *ctx; - void *scanner; + struct scanner *scanner; XkbFile *rtrn; bool more_maps; }; -static void -parser_error(struct parser_param *param, const char *msg) -{ - scanner_error(param->scanner, msg); -} +#define parser_err(param, fmt, ...) \ + scanner_err((param)->scanner, fmt, ##__VA_ARGS__) -static void -parser_warn(struct parser_param *param, const char *msg) -{ - scanner_warn(param->scanner, msg); -} +#define parser_warn(param, fmt, ...) \ + scanner_warn((param)->scanner, fmt, ##__VA_ARGS__) static void _xkbcommon_error(struct parser_param *param, const char *msg) { - parser_error(param, msg); + parser_err(param, "%s", msg); } static bool @@ -129,11 +123,11 @@ resolve_keysym(const char *str, xkb_keysym_t *sym_rtrn) return false; } -#define scanner param->scanner +#define param_scanner param->scanner /* Line 268 of yacc.c */ -#line 137 "src/xkbcomp/parser.c" +#line 131 "src/xkbcomp/parser.c" /* Enabling traces. */ #ifndef YYDEBUG @@ -298,7 +292,7 @@ typedef union YYSTYPE { /* Line 293 of yacc.c */ -#line 167 "parser.y" +#line 161 "parser.y" int ival; int64_t num; @@ -327,7 +321,7 @@ typedef union YYSTYPE /* Line 293 of yacc.c */ -#line 331 "src/xkbcomp/parser.c" +#line 325 "src/xkbcomp/parser.c" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -339,7 +333,7 @@ typedef union YYSTYPE /* Line 343 of yacc.c */ -#line 343 "src/xkbcomp/parser.c" +#line 337 "src/xkbcomp/parser.c" #ifdef short # undef short @@ -698,25 +692,25 @@ static const yytype_int16 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 238, 238, 240, 242, 246, 252, 253, 254, 257, - 264, 268, 283, 284, 285, 286, 287, 290, 291, 294, - 295, 298, 299, 300, 301, 302, 303, 304, 305, 308, - 310, 313, 318, 323, 328, 333, 338, 343, 348, 353, - 358, 363, 368, 369, 370, 371, 378, 380, 382, 386, - 390, 394, 398, 400, 404, 406, 410, 416, 418, 422, - 424, 428, 434, 440, 442, 444, 447, 448, 449, 450, - 451, 454, 456, 460, 464, 468, 472, 474, 478, 480, - 484, 488, 489, 492, 494, 496, 498, 500, 504, 505, - 508, 509, 513, 514, 517, 519, 523, 527, 528, 531, - 534, 536, 540, 542, 544, 548, 550, 554, 558, 562, - 563, 564, 565, 568, 569, 572, 574, 576, 578, 580, - 582, 584, 586, 588, 590, 592, 596, 597, 600, 601, - 602, 603, 604, 614, 615, 618, 620, 624, 626, 628, - 630, 632, 634, 638, 640, 642, 644, 646, 648, 650, - 652, 656, 658, 662, 666, 668, 670, 672, 676, 678, + 0, 232, 232, 234, 236, 240, 246, 247, 248, 251, + 259, 263, 278, 279, 280, 281, 282, 285, 286, 289, + 290, 293, 294, 295, 296, 297, 298, 299, 300, 303, + 305, 308, 313, 318, 323, 328, 333, 338, 343, 348, + 353, 358, 363, 364, 365, 366, 373, 375, 377, 381, + 385, 389, 393, 396, 400, 402, 406, 412, 414, 418, + 421, 425, 431, 437, 440, 442, 445, 446, 447, 448, + 449, 452, 454, 458, 462, 466, 470, 472, 476, 478, + 482, 486, 487, 490, 492, 494, 496, 498, 502, 503, + 506, 507, 511, 512, 515, 517, 521, 525, 526, 529, + 532, 534, 538, 540, 542, 546, 548, 552, 556, 560, + 561, 562, 563, 566, 567, 570, 572, 574, 576, 578, + 580, 582, 584, 586, 588, 590, 594, 595, 598, 599, + 600, 601, 602, 612, 613, 616, 619, 623, 625, 627, + 629, 631, 633, 637, 639, 641, 643, 645, 647, 649, + 651, 655, 658, 662, 666, 668, 670, 672, 676, 678, 680, 682, 686, 687, 690, 692, 694, 696, 700, 704, - 710, 711, 725, 726, 729, 730, 733, 736, 739, 742, - 743, 746, 749, 750, 753 + 710, 711, 731, 732, 735, 736, 739, 742, 745, 748, + 749, 752, 755, 756, 759 }; #endif @@ -1217,7 +1211,7 @@ while (YYID (0)) #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else -# define YYLEX yylex (&yylval, scanner) +# define YYLEX yylex (&yylval, param_scanner) #endif /* Enable debugging if requested. */ @@ -1970,75 +1964,76 @@ yyreduce: case 2: /* Line 1806 of yacc.c */ -#line 239 "parser.y" +#line 233 "parser.y" { (yyval.file) = param->rtrn = (yyvsp[(1) - (1)].file); param->more_maps = true; } break; case 3: /* Line 1806 of yacc.c */ -#line 241 "parser.y" +#line 235 "parser.y" { (yyval.file) = param->rtrn = (yyvsp[(1) - (1)].file); param->more_maps = true; YYACCEPT; } break; case 4: /* Line 1806 of yacc.c */ -#line 243 "parser.y" +#line 237 "parser.y" { (yyval.file) = param->rtrn = NULL; param->more_maps = false; } break; case 5: /* Line 1806 of yacc.c */ -#line 249 "parser.y" - { (yyval.file) = XkbFileCreate(param->ctx, (yyvsp[(2) - (7)].file_type), (yyvsp[(3) - (7)].str), &(yyvsp[(5) - (7)].file)->common, (yyvsp[(1) - (7)].mapFlags)); } +#line 243 "parser.y" + { (yyval.file) = XkbFileCreate((yyvsp[(2) - (7)].file_type), (yyvsp[(3) - (7)].str), (ParseCommon *) (yyvsp[(5) - (7)].file), (yyvsp[(1) - (7)].mapFlags)); } break; case 6: /* Line 1806 of yacc.c */ -#line 252 "parser.y" +#line 246 "parser.y" { (yyval.file_type) = FILE_TYPE_KEYMAP; } break; case 7: /* Line 1806 of yacc.c */ -#line 253 "parser.y" +#line 247 "parser.y" { (yyval.file_type) = FILE_TYPE_KEYMAP; } break; case 8: /* Line 1806 of yacc.c */ -#line 254 "parser.y" +#line 248 "parser.y" { (yyval.file_type) = FILE_TYPE_KEYMAP; } break; case 9: /* Line 1806 of yacc.c */ -#line 258 "parser.y" +#line 252 "parser.y" { if (!(yyvsp[(2) - (2)].file)) (yyval.file) = (yyvsp[(1) - (2)].file); else - (yyval.file) = (XkbFile *)AppendStmt(&(yyvsp[(1) - (2)].file)->common, &(yyvsp[(2) - (2)].file)->common); + (yyval.file) = (XkbFile *) AppendStmt((ParseCommon *) (yyvsp[(1) - (2)].file), + (ParseCommon *) (yyvsp[(2) - (2)].file)); } break; case 10: /* Line 1806 of yacc.c */ -#line 265 "parser.y" +#line 260 "parser.y" { (yyval.file) = (yyvsp[(1) - (1)].file); } break; case 11: /* Line 1806 of yacc.c */ -#line 271 "parser.y" +#line 266 "parser.y" { if ((yyvsp[(2) - (7)].file_type) == FILE_TYPE_GEOMETRY) { free((yyvsp[(3) - (7)].str)); @@ -2046,7 +2041,7 @@ yyreduce: (yyval.file) = NULL; } else { - (yyval.file) = XkbFileCreate(param->ctx, (yyvsp[(2) - (7)].file_type), (yyvsp[(3) - (7)].str), (yyvsp[(5) - (7)].any), (yyvsp[(1) - (7)].mapFlags)); + (yyval.file) = XkbFileCreate((yyvsp[(2) - (7)].file_type), (yyvsp[(3) - (7)].str), (yyvsp[(5) - (7)].any), (yyvsp[(1) - (7)].mapFlags)); } } break; @@ -2054,273 +2049,273 @@ yyreduce: case 12: /* Line 1806 of yacc.c */ -#line 283 "parser.y" +#line 278 "parser.y" { (yyval.file_type) = FILE_TYPE_KEYCODES; } break; case 13: /* Line 1806 of yacc.c */ -#line 284 "parser.y" +#line 279 "parser.y" { (yyval.file_type) = FILE_TYPE_TYPES; } break; case 14: /* Line 1806 of yacc.c */ -#line 285 "parser.y" +#line 280 "parser.y" { (yyval.file_type) = FILE_TYPE_COMPAT; } break; case 15: /* Line 1806 of yacc.c */ -#line 286 "parser.y" +#line 281 "parser.y" { (yyval.file_type) = FILE_TYPE_SYMBOLS; } break; case 16: /* Line 1806 of yacc.c */ -#line 287 "parser.y" +#line 282 "parser.y" { (yyval.file_type) = FILE_TYPE_GEOMETRY; } break; case 17: /* Line 1806 of yacc.c */ -#line 290 "parser.y" +#line 285 "parser.y" { (yyval.mapFlags) = (yyvsp[(1) - (1)].mapFlags); } break; case 18: /* Line 1806 of yacc.c */ -#line 291 "parser.y" +#line 286 "parser.y" { (yyval.mapFlags) = 0; } break; case 19: /* Line 1806 of yacc.c */ -#line 294 "parser.y" +#line 289 "parser.y" { (yyval.mapFlags) = ((yyvsp[(1) - (2)].mapFlags) | (yyvsp[(2) - (2)].mapFlags)); } break; case 20: /* Line 1806 of yacc.c */ -#line 295 "parser.y" +#line 290 "parser.y" { (yyval.mapFlags) = (yyvsp[(1) - (1)].mapFlags); } break; case 21: /* Line 1806 of yacc.c */ -#line 298 "parser.y" +#line 293 "parser.y" { (yyval.mapFlags) = MAP_IS_PARTIAL; } break; case 22: /* Line 1806 of yacc.c */ -#line 299 "parser.y" +#line 294 "parser.y" { (yyval.mapFlags) = MAP_IS_DEFAULT; } break; case 23: /* Line 1806 of yacc.c */ -#line 300 "parser.y" +#line 295 "parser.y" { (yyval.mapFlags) = MAP_IS_HIDDEN; } break; case 24: /* Line 1806 of yacc.c */ -#line 301 "parser.y" +#line 296 "parser.y" { (yyval.mapFlags) = MAP_HAS_ALPHANUMERIC; } break; case 25: /* Line 1806 of yacc.c */ -#line 302 "parser.y" +#line 297 "parser.y" { (yyval.mapFlags) = MAP_HAS_MODIFIER; } break; case 26: /* Line 1806 of yacc.c */ -#line 303 "parser.y" +#line 298 "parser.y" { (yyval.mapFlags) = MAP_HAS_KEYPAD; } break; case 27: /* Line 1806 of yacc.c */ -#line 304 "parser.y" +#line 299 "parser.y" { (yyval.mapFlags) = MAP_HAS_FN; } break; case 28: /* Line 1806 of yacc.c */ -#line 305 "parser.y" +#line 300 "parser.y" { (yyval.mapFlags) = MAP_IS_ALTGR; } break; case 29: /* Line 1806 of yacc.c */ -#line 309 "parser.y" +#line 304 "parser.y" { (yyval.any) = AppendStmt((yyvsp[(1) - (2)].any), (yyvsp[(2) - (2)].any)); } break; case 30: /* Line 1806 of yacc.c */ -#line 310 "parser.y" +#line 305 "parser.y" { (yyval.any) = NULL; } break; case 31: /* Line 1806 of yacc.c */ -#line 314 "parser.y" +#line 309 "parser.y" { (yyvsp[(2) - (2)].var)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].var)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].var); } break; case 32: /* Line 1806 of yacc.c */ -#line 319 "parser.y" +#line 314 "parser.y" { (yyvsp[(2) - (2)].vmod)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].vmod)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].vmod); } break; case 33: /* Line 1806 of yacc.c */ -#line 324 "parser.y" +#line 319 "parser.y" { (yyvsp[(2) - (2)].interp)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].interp)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].interp); } break; case 34: /* Line 1806 of yacc.c */ -#line 329 "parser.y" +#line 324 "parser.y" { (yyvsp[(2) - (2)].keyCode)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].keyCode)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].keyCode); } break; case 35: /* Line 1806 of yacc.c */ -#line 334 "parser.y" +#line 329 "parser.y" { (yyvsp[(2) - (2)].keyAlias)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].keyAlias)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].keyAlias); } break; case 36: /* Line 1806 of yacc.c */ -#line 339 "parser.y" +#line 334 "parser.y" { (yyvsp[(2) - (2)].keyType)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].keyType)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].keyType); } break; case 37: /* Line 1806 of yacc.c */ -#line 344 "parser.y" +#line 339 "parser.y" { (yyvsp[(2) - (2)].syms)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].syms)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].syms); } break; case 38: /* Line 1806 of yacc.c */ -#line 349 "parser.y" +#line 344 "parser.y" { (yyvsp[(2) - (2)].modMask)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].modMask)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].modMask); } break; case 39: /* Line 1806 of yacc.c */ -#line 354 "parser.y" +#line 349 "parser.y" { (yyvsp[(2) - (2)].groupCompat)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].groupCompat)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].groupCompat); } break; case 40: /* Line 1806 of yacc.c */ -#line 359 "parser.y" +#line 354 "parser.y" { (yyvsp[(2) - (2)].ledMap)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].ledMap)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].ledMap); } break; case 41: /* Line 1806 of yacc.c */ -#line 364 "parser.y" +#line 359 "parser.y" { (yyvsp[(2) - (2)].ledName)->merge = (yyvsp[(1) - (2)].merge); - (yyval.any) = &(yyvsp[(2) - (2)].ledName)->common; + (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].ledName); } break; case 42: /* Line 1806 of yacc.c */ -#line 368 "parser.y" +#line 363 "parser.y" { (yyval.any) = NULL; } break; case 43: /* Line 1806 of yacc.c */ -#line 369 "parser.y" +#line 364 "parser.y" { (yyval.any) = NULL; } break; case 44: /* Line 1806 of yacc.c */ -#line 370 "parser.y" +#line 365 "parser.y" { (yyval.any) = NULL; } break; case 45: /* Line 1806 of yacc.c */ -#line 372 "parser.y" +#line 367 "parser.y" { - (yyval.any) = &IncludeCreate(param->ctx, (yyvsp[(2) - (2)].str), (yyvsp[(1) - (2)].merge))->common; + (yyval.any) = (ParseCommon *) IncludeCreate(param->ctx, (yyvsp[(2) - (2)].str), (yyvsp[(1) - (2)].merge)); free((yyvsp[(2) - (2)].str)); } break; @@ -2328,609 +2323,612 @@ yyreduce: case 46: /* Line 1806 of yacc.c */ -#line 379 "parser.y" +#line 374 "parser.y" { (yyval.var) = VarCreate((yyvsp[(1) - (4)].expr), (yyvsp[(3) - (4)].expr)); } break; case 47: /* Line 1806 of yacc.c */ -#line 381 "parser.y" +#line 376 "parser.y" { (yyval.var) = BoolVarCreate((yyvsp[(1) - (2)].sval), true); } break; case 48: /* Line 1806 of yacc.c */ -#line 383 "parser.y" +#line 378 "parser.y" { (yyval.var) = BoolVarCreate((yyvsp[(2) - (3)].sval), false); } break; case 49: /* Line 1806 of yacc.c */ -#line 387 "parser.y" +#line 382 "parser.y" { (yyval.keyCode) = KeycodeCreate((yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].num)); } break; case 50: /* Line 1806 of yacc.c */ -#line 391 "parser.y" +#line 386 "parser.y" { (yyval.keyAlias) = KeyAliasCreate((yyvsp[(2) - (5)].sval), (yyvsp[(4) - (5)].sval)); } break; case 51: /* Line 1806 of yacc.c */ -#line 395 "parser.y" +#line 390 "parser.y" { (yyval.vmod) = (yyvsp[(2) - (3)].vmod); } break; case 52: /* Line 1806 of yacc.c */ -#line 399 "parser.y" - { (yyval.vmod) = (VModDef *)AppendStmt(&(yyvsp[(1) - (3)].vmod)->common, &(yyvsp[(3) - (3)].vmod)->common); } +#line 394 "parser.y" + { (yyval.vmod) = (VModDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (3)].vmod), + (ParseCommon *) (yyvsp[(3) - (3)].vmod)); } break; case 53: /* Line 1806 of yacc.c */ -#line 401 "parser.y" +#line 397 "parser.y" { (yyval.vmod) = (yyvsp[(1) - (1)].vmod); } break; case 54: /* Line 1806 of yacc.c */ -#line 405 "parser.y" +#line 401 "parser.y" { (yyval.vmod) = VModCreate((yyvsp[(1) - (1)].sval), NULL); } break; case 55: /* Line 1806 of yacc.c */ -#line 407 "parser.y" +#line 403 "parser.y" { (yyval.vmod) = VModCreate((yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].expr)); } break; case 56: /* Line 1806 of yacc.c */ -#line 413 "parser.y" +#line 409 "parser.y" { (yyvsp[(2) - (6)].interp)->def = (yyvsp[(4) - (6)].var); (yyval.interp) = (yyvsp[(2) - (6)].interp); } break; case 57: /* Line 1806 of yacc.c */ -#line 417 "parser.y" +#line 413 "parser.y" { (yyval.interp) = InterpCreate((yyvsp[(1) - (3)].keysym), (yyvsp[(3) - (3)].expr)); } break; case 58: /* Line 1806 of yacc.c */ -#line 419 "parser.y" +#line 415 "parser.y" { (yyval.interp) = InterpCreate((yyvsp[(1) - (1)].keysym), NULL); } break; case 59: /* Line 1806 of yacc.c */ -#line 423 "parser.y" - { (yyval.var) = (VarDef *)AppendStmt(&(yyvsp[(1) - (2)].var)->common, &(yyvsp[(2) - (2)].var)->common); } +#line 419 "parser.y" + { (yyval.var) = (VarDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (2)].var), + (ParseCommon *) (yyvsp[(2) - (2)].var)); } break; case 60: /* Line 1806 of yacc.c */ -#line 425 "parser.y" +#line 422 "parser.y" { (yyval.var) = (yyvsp[(1) - (1)].var); } break; case 61: /* Line 1806 of yacc.c */ -#line 431 "parser.y" +#line 428 "parser.y" { (yyval.keyType) = KeyTypeCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].var)); } break; case 62: /* Line 1806 of yacc.c */ -#line 437 "parser.y" +#line 434 "parser.y" { (yyval.syms) = SymbolsCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].var)); } break; case 63: /* Line 1806 of yacc.c */ -#line 441 "parser.y" - { (yyval.var) = (VarDef *)AppendStmt(&(yyvsp[(1) - (3)].var)->common, &(yyvsp[(3) - (3)].var)->common); } +#line 438 "parser.y" + { (yyval.var) = (VarDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (3)].var), + (ParseCommon *) (yyvsp[(3) - (3)].var)); } break; case 64: /* Line 1806 of yacc.c */ -#line 443 "parser.y" +#line 441 "parser.y" { (yyval.var) = (yyvsp[(1) - (1)].var); } break; case 65: /* Line 1806 of yacc.c */ -#line 444 "parser.y" +#line 442 "parser.y" { (yyval.var) = NULL; } break; case 66: /* Line 1806 of yacc.c */ -#line 447 "parser.y" +#line 445 "parser.y" { (yyval.var) = VarCreate((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; case 67: /* Line 1806 of yacc.c */ -#line 448 "parser.y" +#line 446 "parser.y" { (yyval.var) = VarCreate((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; case 68: /* Line 1806 of yacc.c */ -#line 449 "parser.y" +#line 447 "parser.y" { (yyval.var) = BoolVarCreate((yyvsp[(1) - (1)].sval), true); } break; case 69: /* Line 1806 of yacc.c */ -#line 450 "parser.y" +#line 448 "parser.y" { (yyval.var) = BoolVarCreate((yyvsp[(2) - (2)].sval), false); } break; case 70: /* Line 1806 of yacc.c */ -#line 451 "parser.y" +#line 449 "parser.y" { (yyval.var) = VarCreate(NULL, (yyvsp[(1) - (1)].expr)); } break; case 71: /* Line 1806 of yacc.c */ -#line 455 "parser.y" +#line 453 "parser.y" { (yyval.expr) = (yyvsp[(2) - (3)].expr); } break; case 72: /* Line 1806 of yacc.c */ -#line 457 "parser.y" +#line 455 "parser.y" { (yyval.expr) = ExprCreateUnary(EXPR_ACTION_LIST, EXPR_TYPE_ACTION, (yyvsp[(2) - (3)].expr)); } break; case 73: /* Line 1806 of yacc.c */ -#line 461 "parser.y" +#line 459 "parser.y" { (yyval.groupCompat) = GroupCompatCreate((yyvsp[(2) - (5)].ival), (yyvsp[(4) - (5)].expr)); } break; case 74: /* Line 1806 of yacc.c */ -#line 465 "parser.y" +#line 463 "parser.y" { (yyval.modMask) = ModMapCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].expr)); } break; case 75: /* Line 1806 of yacc.c */ -#line 469 "parser.y" +#line 467 "parser.y" { (yyval.ledMap) = LedMapCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].var)); } break; case 76: /* Line 1806 of yacc.c */ -#line 473 "parser.y" +#line 471 "parser.y" { (yyval.ledName) = LedNameCreate((yyvsp[(2) - (5)].ival), (yyvsp[(4) - (5)].expr), false); } break; case 77: /* Line 1806 of yacc.c */ -#line 475 "parser.y" +#line 473 "parser.y" { (yyval.ledName) = LedNameCreate((yyvsp[(3) - (6)].ival), (yyvsp[(5) - (6)].expr), true); } break; case 78: /* Line 1806 of yacc.c */ -#line 479 "parser.y" +#line 477 "parser.y" { (yyval.geom) = NULL; } break; case 79: /* Line 1806 of yacc.c */ -#line 481 "parser.y" +#line 479 "parser.y" { (yyval.geom) = NULL; } break; case 80: /* Line 1806 of yacc.c */ -#line 485 "parser.y" +#line 483 "parser.y" { (yyval.geom) = NULL; } break; case 81: /* Line 1806 of yacc.c */ -#line 488 "parser.y" +#line 486 "parser.y" { (yyval.geom) = NULL;} break; case 82: /* Line 1806 of yacc.c */ -#line 489 "parser.y" +#line 487 "parser.y" { (yyval.geom) = NULL; } break; case 83: /* Line 1806 of yacc.c */ -#line 493 "parser.y" +#line 491 "parser.y" { (yyval.geom) = NULL; } break; case 84: /* Line 1806 of yacc.c */ -#line 495 "parser.y" - { FreeStmt(&(yyvsp[(1) - (1)].var)->common); (yyval.geom) = NULL; } +#line 493 "parser.y" + { FreeStmt((ParseCommon *) (yyvsp[(1) - (1)].var)); (yyval.geom) = NULL; } break; case 85: /* Line 1806 of yacc.c */ -#line 497 "parser.y" +#line 495 "parser.y" { (yyval.geom) = NULL; } break; case 86: /* Line 1806 of yacc.c */ -#line 499 "parser.y" - { FreeStmt(&(yyvsp[(1) - (1)].ledMap)->common); (yyval.geom) = NULL; } +#line 497 "parser.y" + { FreeStmt((ParseCommon *) (yyvsp[(1) - (1)].ledMap)); (yyval.geom) = NULL; } break; case 87: /* Line 1806 of yacc.c */ -#line 501 "parser.y" +#line 499 "parser.y" { (yyval.geom) = NULL; } break; case 88: /* Line 1806 of yacc.c */ -#line 504 "parser.y" +#line 502 "parser.y" { (yyval.geom) = NULL;} break; case 89: /* Line 1806 of yacc.c */ -#line 505 "parser.y" +#line 503 "parser.y" { (yyval.geom) = NULL; } break; case 90: /* Line 1806 of yacc.c */ -#line 508 "parser.y" +#line 506 "parser.y" { (yyval.geom) = NULL; } break; case 91: /* Line 1806 of yacc.c */ -#line 510 "parser.y" - { FreeStmt(&(yyvsp[(1) - (1)].var)->common); (yyval.geom) = NULL; } +#line 508 "parser.y" + { FreeStmt((ParseCommon *) (yyvsp[(1) - (1)].var)); (yyval.geom) = NULL; } break; case 92: /* Line 1806 of yacc.c */ -#line 513 "parser.y" +#line 511 "parser.y" { (yyval.geom) = NULL; } break; case 93: /* Line 1806 of yacc.c */ -#line 514 "parser.y" +#line 512 "parser.y" { (yyval.geom) = NULL; } break; case 94: /* Line 1806 of yacc.c */ -#line 518 "parser.y" +#line 516 "parser.y" { (yyval.geom) = NULL; } break; case 95: /* Line 1806 of yacc.c */ -#line 520 "parser.y" - { FreeStmt(&(yyvsp[(2) - (3)].expr)->common); (yyval.geom) = NULL; } +#line 518 "parser.y" + { FreeStmt((ParseCommon *) (yyvsp[(2) - (3)].expr)); (yyval.geom) = NULL; } break; case 96: /* Line 1806 of yacc.c */ -#line 524 "parser.y" +#line 522 "parser.y" { (yyval.geom) = NULL; } break; case 97: /* Line 1806 of yacc.c */ -#line 527 "parser.y" +#line 525 "parser.y" { (yyval.geom) = NULL; } break; case 98: /* Line 1806 of yacc.c */ -#line 528 "parser.y" +#line 526 "parser.y" { (yyval.geom) = NULL; } break; case 99: /* Line 1806 of yacc.c */ -#line 531 "parser.y" +#line 529 "parser.y" { (yyval.geom) = NULL; } break; case 100: /* Line 1806 of yacc.c */ -#line 535 "parser.y" +#line 533 "parser.y" { (yyval.geom) = NULL;} break; case 101: /* Line 1806 of yacc.c */ -#line 537 "parser.y" +#line 535 "parser.y" { (yyval.geom) = NULL; } break; case 102: /* Line 1806 of yacc.c */ -#line 541 "parser.y" +#line 539 "parser.y" { (yyval.geom) = NULL; } break; case 103: /* Line 1806 of yacc.c */ -#line 543 "parser.y" +#line 541 "parser.y" { (yyval.geom) = NULL; } break; case 104: /* Line 1806 of yacc.c */ -#line 545 "parser.y" - { FreeStmt(&(yyvsp[(3) - (3)].expr)->common); (yyval.geom) = NULL; } +#line 543 "parser.y" + { FreeStmt((ParseCommon *) (yyvsp[(3) - (3)].expr)); (yyval.geom) = NULL; } break; case 105: /* Line 1806 of yacc.c */ -#line 549 "parser.y" +#line 547 "parser.y" { (yyval.expr) = NULL; } break; case 106: /* Line 1806 of yacc.c */ -#line 551 "parser.y" +#line 549 "parser.y" { (yyval.expr) = NULL; } break; case 107: /* Line 1806 of yacc.c */ -#line 555 "parser.y" +#line 553 "parser.y" { (yyval.expr) = NULL; } break; case 108: /* Line 1806 of yacc.c */ -#line 559 "parser.y" - { FreeStmt(&(yyvsp[(4) - (6)].var)->common); (yyval.geom) = NULL; } +#line 557 "parser.y" + { FreeStmt((ParseCommon *) (yyvsp[(4) - (6)].var)); (yyval.geom) = NULL; } break; case 109: /* Line 1806 of yacc.c */ -#line 562 "parser.y" +#line 560 "parser.y" { (yyval.ival) = 0; } break; case 110: /* Line 1806 of yacc.c */ -#line 563 "parser.y" +#line 561 "parser.y" { (yyval.ival) = 0; } break; case 111: /* Line 1806 of yacc.c */ -#line 564 "parser.y" +#line 562 "parser.y" { (yyval.ival) = 0; } break; case 112: /* Line 1806 of yacc.c */ -#line 565 "parser.y" +#line 563 "parser.y" { (yyval.ival) = 0; } break; case 113: /* Line 1806 of yacc.c */ -#line 568 "parser.y" +#line 566 "parser.y" { (yyval.sval) = (yyvsp[(1) - (1)].sval); } break; case 114: /* Line 1806 of yacc.c */ -#line 569 "parser.y" +#line 567 "parser.y" { (yyval.sval) = (yyvsp[(1) - (1)].sval); } break; case 115: /* Line 1806 of yacc.c */ -#line 573 "parser.y" +#line 571 "parser.y" { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "action"); } break; case 116: /* Line 1806 of yacc.c */ -#line 575 "parser.y" +#line 573 "parser.y" { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "interpret"); } break; case 117: /* Line 1806 of yacc.c */ -#line 577 "parser.y" +#line 575 "parser.y" { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "type"); } break; case 118: /* Line 1806 of yacc.c */ -#line 579 "parser.y" +#line 577 "parser.y" { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "key"); } break; case 119: /* Line 1806 of yacc.c */ -#line 581 "parser.y" +#line 579 "parser.y" { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "group"); } break; case 120: /* Line 1806 of yacc.c */ -#line 583 "parser.y" +#line 581 "parser.y" {(yyval.sval) = xkb_atom_intern_literal(param->ctx, "modifier_map");} break; case 121: /* Line 1806 of yacc.c */ -#line 585 "parser.y" +#line 583 "parser.y" { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "indicator"); } break; case 122: /* Line 1806 of yacc.c */ -#line 587 "parser.y" +#line 585 "parser.y" { (yyval.sval) = XKB_ATOM_NONE; } break; case 123: /* Line 1806 of yacc.c */ -#line 589 "parser.y" +#line 587 "parser.y" { (yyval.sval) = XKB_ATOM_NONE; } break; case 124: /* Line 1806 of yacc.c */ -#line 591 "parser.y" +#line 589 "parser.y" { (yyval.sval) = XKB_ATOM_NONE; } break; case 125: /* Line 1806 of yacc.c */ -#line 593 "parser.y" +#line 591 "parser.y" { (yyval.sval) = XKB_ATOM_NONE; } break; case 126: /* Line 1806 of yacc.c */ -#line 596 "parser.y" +#line 594 "parser.y" { (yyval.merge) = (yyvsp[(1) - (1)].merge); } break; case 127: /* Line 1806 of yacc.c */ -#line 597 "parser.y" +#line 595 "parser.y" { (yyval.merge) = MERGE_DEFAULT; } break; case 128: /* Line 1806 of yacc.c */ -#line 600 "parser.y" +#line 598 "parser.y" { (yyval.merge) = MERGE_DEFAULT; } break; case 129: /* Line 1806 of yacc.c */ -#line 601 "parser.y" +#line 599 "parser.y" { (yyval.merge) = MERGE_AUGMENT; } break; case 130: /* Line 1806 of yacc.c */ -#line 602 "parser.y" +#line 600 "parser.y" { (yyval.merge) = MERGE_OVERRIDE; } break; case 131: /* Line 1806 of yacc.c */ -#line 603 "parser.y" +#line 601 "parser.y" { (yyval.merge) = MERGE_REPLACE; } break; case 132: /* Line 1806 of yacc.c */ -#line 605 "parser.y" +#line 603 "parser.y" { /* * This used to be MERGE_ALT_FORM. This functionality was @@ -2943,134 +2941,136 @@ yyreduce: case 133: /* Line 1806 of yacc.c */ -#line 614 "parser.y" +#line 612 "parser.y" { (yyval.expr) = (yyvsp[(1) - (1)].expr); } break; case 134: /* Line 1806 of yacc.c */ -#line 615 "parser.y" +#line 613 "parser.y" { (yyval.expr) = NULL; } break; case 135: /* Line 1806 of yacc.c */ -#line 619 "parser.y" - { (yyval.expr) = (ExprDef *)AppendStmt(&(yyvsp[(1) - (3)].expr)->common, &(yyvsp[(3) - (3)].expr)->common); } +#line 617 "parser.y" + { (yyval.expr) = (ExprDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (3)].expr), + (ParseCommon *) (yyvsp[(3) - (3)].expr)); } break; case 136: /* Line 1806 of yacc.c */ -#line 621 "parser.y" +#line 620 "parser.y" { (yyval.expr) = (yyvsp[(1) - (1)].expr); } break; case 137: /* Line 1806 of yacc.c */ -#line 625 "parser.y" +#line 624 "parser.y" { (yyval.expr) = ExprCreateBinary(EXPR_DIVIDE, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; case 138: /* Line 1806 of yacc.c */ -#line 627 "parser.y" +#line 626 "parser.y" { (yyval.expr) = ExprCreateBinary(EXPR_ADD, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; case 139: /* Line 1806 of yacc.c */ -#line 629 "parser.y" +#line 628 "parser.y" { (yyval.expr) = ExprCreateBinary(EXPR_SUBTRACT, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; case 140: /* Line 1806 of yacc.c */ -#line 631 "parser.y" +#line 630 "parser.y" { (yyval.expr) = ExprCreateBinary(EXPR_MULTIPLY, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; case 141: /* Line 1806 of yacc.c */ -#line 633 "parser.y" +#line 632 "parser.y" { (yyval.expr) = ExprCreateBinary(EXPR_ASSIGN, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } break; case 142: /* Line 1806 of yacc.c */ -#line 635 "parser.y" +#line 634 "parser.y" { (yyval.expr) = (yyvsp[(1) - (1)].expr); } break; case 143: /* Line 1806 of yacc.c */ -#line 639 "parser.y" +#line 638 "parser.y" { (yyval.expr) = ExprCreateUnary(EXPR_NEGATE, (yyvsp[(2) - (2)].expr)->expr.value_type, (yyvsp[(2) - (2)].expr)); } break; case 144: /* Line 1806 of yacc.c */ -#line 641 "parser.y" +#line 640 "parser.y" { (yyval.expr) = ExprCreateUnary(EXPR_UNARY_PLUS, (yyvsp[(2) - (2)].expr)->expr.value_type, (yyvsp[(2) - (2)].expr)); } break; case 145: /* Line 1806 of yacc.c */ -#line 643 "parser.y" +#line 642 "parser.y" { (yyval.expr) = ExprCreateUnary(EXPR_NOT, EXPR_TYPE_BOOLEAN, (yyvsp[(2) - (2)].expr)); } break; case 146: /* Line 1806 of yacc.c */ -#line 645 "parser.y" +#line 644 "parser.y" { (yyval.expr) = ExprCreateUnary(EXPR_INVERT, (yyvsp[(2) - (2)].expr)->expr.value_type, (yyvsp[(2) - (2)].expr)); } break; case 147: /* Line 1806 of yacc.c */ -#line 647 "parser.y" +#line 646 "parser.y" { (yyval.expr) = (yyvsp[(1) - (1)].expr); } break; case 148: /* Line 1806 of yacc.c */ -#line 649 "parser.y" +#line 648 "parser.y" { (yyval.expr) = ExprCreateAction((yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].expr)); } break; case 149: /* Line 1806 of yacc.c */ -#line 651 "parser.y" +#line 650 "parser.y" { (yyval.expr) = (yyvsp[(1) - (1)].expr); } break; case 150: /* Line 1806 of yacc.c */ -#line 653 "parser.y" +#line 652 "parser.y" { (yyval.expr) = (yyvsp[(2) - (3)].expr); } break; case 151: /* Line 1806 of yacc.c */ -#line 657 "parser.y" - { (yyval.expr) = (ExprDef *)AppendStmt(&(yyvsp[(1) - (3)].expr)->common, &(yyvsp[(3) - (3)].expr)->common); } +#line 656 "parser.y" + { (yyval.expr) = (ExprDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (3)].expr), + (ParseCommon *) (yyvsp[(3) - (3)].expr)); } break; case 152: @@ -3215,14 +3215,20 @@ yyreduce: /* Line 1806 of yacc.c */ #line 712 "parser.y" { - if ((yyvsp[(1) - (1)].ival) < 10) { /* XKB_KEY_0 .. XKB_KEY_9 */ - (yyval.keysym) = XKB_KEY_0 + (yyvsp[(1) - (1)].ival); + if ((yyvsp[(1) - (1)].ival) < 0) { + parser_warn(param, "unrecognized keysym"); + (yyval.keysym) = XKB_KEY_NoSymbol; + } + else if ((yyvsp[(1) - (1)].ival) < 10) { /* XKB_KEY_0 .. XKB_KEY_9 */ + (yyval.keysym) = XKB_KEY_0 + (xkb_keysym_t) (yyvsp[(1) - (1)].ival); } else { char buf[17]; snprintf(buf, sizeof(buf), "0x%x", (yyvsp[(1) - (1)].ival)); - if (!resolve_keysym(buf, &(yyval.keysym))) + if (!resolve_keysym(buf, &(yyval.keysym))) { parser_warn(param, "unrecognized keysym"); + (yyval.keysym) = XKB_KEY_NoSymbol; + } } } break; @@ -3230,98 +3236,98 @@ yyreduce: case 172: /* Line 1806 of yacc.c */ -#line 725 "parser.y" +#line 731 "parser.y" { (yyval.ival) = -(yyvsp[(2) - (2)].ival); } break; case 173: /* Line 1806 of yacc.c */ -#line 726 "parser.y" +#line 732 "parser.y" { (yyval.ival) = (yyvsp[(1) - (1)].ival); } break; case 174: /* Line 1806 of yacc.c */ -#line 729 "parser.y" +#line 735 "parser.y" { (yyval.ival) = (yyvsp[(1) - (1)].num); } break; case 175: /* Line 1806 of yacc.c */ -#line 730 "parser.y" +#line 736 "parser.y" { (yyval.ival) = (yyvsp[(1) - (1)].num); } break; case 176: /* Line 1806 of yacc.c */ -#line 733 "parser.y" +#line 739 "parser.y" { (yyval.ival) = 0; } break; case 177: /* Line 1806 of yacc.c */ -#line 736 "parser.y" +#line 742 "parser.y" { (yyval.ival) = (yyvsp[(1) - (1)].num); } break; case 178: /* Line 1806 of yacc.c */ -#line 739 "parser.y" +#line 745 "parser.y" { (yyval.num) = (yyvsp[(1) - (1)].num); } break; case 179: /* Line 1806 of yacc.c */ -#line 742 "parser.y" +#line 748 "parser.y" { (yyval.sval) = xkb_atom_steal(param->ctx, (yyvsp[(1) - (1)].str)); } break; case 180: /* Line 1806 of yacc.c */ -#line 743 "parser.y" +#line 749 "parser.y" { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "default"); } break; case 181: /* Line 1806 of yacc.c */ -#line 746 "parser.y" +#line 752 "parser.y" { (yyval.sval) = xkb_atom_steal(param->ctx, (yyvsp[(1) - (1)].str)); } break; case 182: /* Line 1806 of yacc.c */ -#line 749 "parser.y" +#line 755 "parser.y" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; case 183: /* Line 1806 of yacc.c */ -#line 750 "parser.y" +#line 756 "parser.y" { (yyval.str) = NULL; } break; case 184: /* Line 1806 of yacc.c */ -#line 753 "parser.y" +#line 759 "parser.y" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; /* Line 1806 of yacc.c */ -#line 3325 "src/xkbcomp/parser.c" +#line 3331 "src/xkbcomp/parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -3552,13 +3558,11 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 756 "parser.y" +#line 762 "parser.y" -#undef scanner - XkbFile * -parse(struct xkb_context *ctx, void *scanner, const char *map) +parse(struct xkb_context *ctx, struct scanner *scanner, const char *map) { int ret; XkbFile *first = NULL; @@ -3604,5 +3608,3 @@ parse(struct xkb_context *ctx, void *scanner, const char *map) return first; } -#define scanner param->scanner - diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser.h b/src/3rdparty/xkbcommon/src/xkbcomp/parser.h index f85a2bad85..ee9b4468b5 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/parser.h +++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser.h @@ -175,7 +175,7 @@ typedef union YYSTYPE { /* Line 2068 of yacc.c */ -#line 167 "parser.y" +#line 161 "parser.y" int ival; int64_t num; diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/rules.c b/src/3rdparty/xkbcommon/src/xkbcomp/rules.c index de82d96119..61799e7059 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/rules.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/rules.c @@ -52,84 +52,6 @@ #include "include.h" #include "scanner-utils.h" -/* - * The rules file - * ============== - * The purpose of this file is to map between configuration values that - * are easy for a user to specify and understand, and the configuration - * values xkbcomp uses and understands. - * xkbcomp uses the xkb_component_names struct, which maps directly to - * include statements of the appropriate sections, called for short - * KcCGST (see keycodes.c, types.c, compat.c, symbols.c; geometry.c was - * removed). These are not really intuitive or straight-forward for - * the uninitiated. - * Instead, the user passes in a xkb_rule_names struct, which consists - * of the name of a rules file (in Linux this is usually "evdev"), a - * keyboard model (e.g. "pc105"), a set of layouts (which will end up - * in different groups, e.g. "us,fr"), variants (used to alter/augment - * the respective layout, e.g. "intl,dvorak"), and a set of options - * (used to tweak some general behavior of the keyboard, e.g. - * "ctrl:nocaps,compose:menu" to make the Caps Lock key act like Ctrl - * and the Menu key like Compose). We call these RMLVO. - * - * Format of the file - * ------------------ - * The file consists of rule sets, each consisting of rules (one per - * line), which match the MLVO values on the left hand side, and, if - * the values match to the values the user passed in, results in the - * values on the right hand side being added to the resulting KcCGST. - * Since some values are related and repeated often, it is possible - * to group them together and refer to them by a group name in the - * rules. - * Along with matching values by simple string equality, and for - * membership in a group defined previously, rules may also contain - * "wildcard" values - "*" - which always match. These usually appear - * near the end. - * - * Grammer - * ------- - * (It might be helpful to look at a file like rules/evdev along with - * this grammer. Comments, whitespace, etc. are not shown.) - * - * File ::= { "!" (Group | RuleSet) } - * - * Group ::= GroupName "=" { GroupElement } "\n" - * GroupName ::= "$" - * GroupElement ::= - * - * RuleSet ::= Mapping { Rule } - * - * Mapping ::= { Mlvo } "=" { Kccgst } "\n" - * Mlvo ::= "model" | "option" | ("layout" | "variant") [ Index ] - * Index ::= "[" 1..XKB_NUM_GROUPS "]" - * Kccgst ::= "keycodes" | "symbols" | "types" | "compat" | "geometry" - * - * Rule ::= { MlvoValue } "=" { KccgstValue } "\n" - * MlvoValue ::= "*" | GroupName | - * KccgstValue ::= - * - * Notes: - * - The order of values in a Rule must be the same as the Mapping it - * follows. The mapping line determines the meaning of the values in - * the rules which follow in the RuleSet. - * - If a Rule is matched, %-expansion is performed on the KccgstValue, - * as follows: - * %m, %l, %v: - * The model, layout or variant, if only one was given (e.g. - * %l for "us,il" is invalid). - * %l[1], %v[1]: - * Layout or variant for the specified group Index, if more than - * one was given (e.g. %l[1] for "us" is invalid). - * %+m, %+l, %+v, %+l[1], %+v[1] - * As above, but prefixed with '+'. Similarly, '|', '-', '_' may be - * used instead of '+'. - * %(m), %(l), %(l[1]), %(v), %(v[1]): - * As above, but prefixed by '(' and suffixed by ')'. - * In case the expansion is invalid, as described above, it is - * skipped (the rest of the string is still processed); this includes - * the prefix and suffix (that's why you shouldn't use e.g. "(%v[1])"). - */ - /* Scanner / Lexer */ /* Values returned with some tokens, like yylval. */ @@ -137,14 +59,6 @@ union lvalue { struct sval string; }; -/* - * Holds the location in the file of the last processed token, - * like yylloc. - */ -struct location { - int line, column; -}; - enum rules_token { TOK_END_OF_FILE = 0, TOK_END_OF_LINE, @@ -156,14 +70,6 @@ enum rules_token { TOK_ERROR }; -/* C99 is stupid. Just use the 1 variant when there are no args. */ -#define scanner_error1(scanner, loc, msg) \ - log_warn((scanner)->ctx, "rules/%s:%d:%d: %s\n", \ - (scanner)->file_name, (loc)->line, (loc)->column, msg) -#define scanner_error(scanner, loc, fmt, ...) \ - log_warn((scanner)->ctx, "rules/%s:%d:%d: " fmt "\n", \ - (scanner)->file_name, (loc)->line, (loc)->column, __VA_ARGS__) - static inline bool is_ident(char ch) { @@ -171,7 +77,7 @@ is_ident(char ch) } static enum rules_token -lex(struct scanner *s, union lvalue *val, struct location *loc) +lex(struct scanner *s, union lvalue *val) { skip_more_whitespace_and_comments: /* Skip spaces. */ @@ -191,8 +97,7 @@ skip_more_whitespace_and_comments: /* Escaped line continuation. */ if (chr(s, '\\')) { if (!eol(s)) { - scanner_error1(s, loc, - "illegal new line escape; must appear at end of line"); + scanner_err(s, "illegal new line escape; must appear at end of line"); return TOK_ERROR; } next(s); @@ -203,8 +108,8 @@ skip_more_whitespace_and_comments: if (eof(s)) return TOK_END_OF_FILE; /* New token. */ - loc->line = s->line; - loc->column = s->column; + s->token_line = s->line; + s->token_column = s->column; /* Operators and punctuation. */ if (chr(s, '!')) return TOK_BANG; @@ -220,8 +125,7 @@ skip_more_whitespace_and_comments: val->string.len++; } if (val->string.len == 0) { - scanner_error1(s, loc, - "unexpected character after \'$\'; expected name"); + scanner_err(s, "unexpected character after \'$\'; expected name"); return TOK_ERROR; } return TOK_GROUP_NAME; @@ -238,7 +142,7 @@ skip_more_whitespace_and_comments: return TOK_IDENTIFIER; } - scanner_error1(s, loc, "unrecognized token"); + scanner_err(s, "unrecognized token"); return TOK_ERROR; } @@ -330,7 +234,6 @@ struct matcher { struct xkb_context *ctx; /* Input.*/ struct rule_names rmlvo; - struct location loc; union lvalue val; struct scanner scanner; darray(struct group) groups; @@ -410,10 +313,8 @@ matcher_free(struct matcher *m) free(m); } -#define matcher_error1(matcher, msg) \ - scanner_error1(&(matcher)->scanner, &(matcher)->loc, msg) -#define matcher_error(matcher, fmt, ...) \ - scanner_error(&(matcher)->scanner, &(matcher)->loc, fmt, __VA_ARGS__) +#define matcher_err(matcher, fmt, ...) \ + scanner_err(&(matcher)->scanner, fmt, ## __VA_ARGS__) static void matcher_group_start_new(struct matcher *m, struct sval name) @@ -474,19 +375,15 @@ matcher_mapping_set_mlvo(struct matcher *m, struct sval ident) /* Not found. */ if (mlvo >= _MLVO_NUM_ENTRIES) { - matcher_error(m, - "invalid mapping: %.*s is not a valid value here; " - "ignoring rule set", - ident.len, ident.start); + matcher_err(m, "invalid mapping: %.*s is not a valid value here; ignoring rule set", + ident.len, ident.start); m->mapping.skip = true; return; } - if (m->mapping.defined_mlvo_mask & (1 << mlvo)) { - matcher_error(m, - "invalid mapping: %.*s appears twice on the same line; " - "ignoring rule set", - mlvo_sval.len, mlvo_sval.start); + if (m->mapping.defined_mlvo_mask & (1u << mlvo)) { + matcher_err(m, "invalid mapping: %.*s appears twice on the same line; ignoring rule set", + mlvo_sval.len, mlvo_sval.start); m->mapping.skip = true; return; } @@ -497,10 +394,8 @@ matcher_mapping_set_mlvo(struct matcher *m, struct sval ident) int consumed = extract_layout_index(ident.start + mlvo_sval.len, ident.len - mlvo_sval.len, &idx); if ((int) (ident.len - mlvo_sval.len) != consumed) { - matcher_error(m, - "invalid mapping:\" %.*s\" may only be followed by a valid group index; " - "ignoring rule set", - mlvo_sval.len, mlvo_sval.start); + matcher_err(m, "invalid mapping: \"%.*s\" may only be followed by a valid group index; ignoring rule set", + mlvo_sval.len, mlvo_sval.start); m->mapping.skip = true; return; } @@ -512,17 +407,15 @@ matcher_mapping_set_mlvo(struct matcher *m, struct sval ident) m->mapping.variant_idx = idx; } else { - matcher_error(m, - "invalid mapping: \"%.*s\" cannot be followed by a group index; " - "ignoring rule set", - mlvo_sval.len, mlvo_sval.start); + matcher_err(m, "invalid mapping: \"%.*s\" cannot be followed by a group index; ignoring rule set", + mlvo_sval.len, mlvo_sval.start); m->mapping.skip = true; return; } } m->mapping.mlvo_at_pos[m->mapping.num_mlvo] = mlvo; - m->mapping.defined_mlvo_mask |= 1 << mlvo; + m->mapping.defined_mlvo_mask |= 1u << mlvo; m->mapping.num_mlvo++; } @@ -541,25 +434,21 @@ matcher_mapping_set_kccgst(struct matcher *m, struct sval ident) /* Not found. */ if (kccgst >= _KCCGST_NUM_ENTRIES) { - matcher_error(m, - "invalid mapping: %.*s is not a valid value here; " - "ignoring rule set", - ident.len, ident.start); + matcher_err(m, "invalid mapping: %.*s is not a valid value here; ignoring rule set", + ident.len, ident.start); m->mapping.skip = true; return; } - if (m->mapping.defined_kccgst_mask & (1 << kccgst)) { - matcher_error(m, - "invalid mapping: %.*s appears twice on the same line; " - "ignoring rule set", - kccgst_sval.len, kccgst_sval.start); + if (m->mapping.defined_kccgst_mask & (1u << kccgst)) { + matcher_err(m, "invalid mapping: %.*s appears twice on the same line; ignoring rule set", + kccgst_sval.len, kccgst_sval.start); m->mapping.skip = true; return; } m->mapping.kccgst_at_pos[m->mapping.num_kccgst] = kccgst; - m->mapping.defined_kccgst_mask |= 1 << kccgst; + m->mapping.defined_kccgst_mask |= 1u << kccgst; m->mapping.num_kccgst++; } @@ -567,16 +456,12 @@ static void matcher_mapping_verify(struct matcher *m) { if (m->mapping.num_mlvo == 0) { - matcher_error1(m, - "invalid mapping: must have at least one value on the left hand side; " - "ignoring rule set"); + matcher_err(m, "invalid mapping: must have at least one value on the left hand side; ignoring rule set"); goto skip; } if (m->mapping.num_kccgst == 0) { - matcher_error1(m, - "invalid mapping: must have at least one value on the right hand side; " - "ignoring rule set"); + matcher_err(m, "invalid mapping: must have at least one value on the right hand side; ignoring rule set"); goto skip; } @@ -585,7 +470,7 @@ matcher_mapping_verify(struct matcher *m) * See the "Notes" section in the overview above. */ - if (m->mapping.defined_mlvo_mask & (1 << MLVO_LAYOUT)) { + if (m->mapping.defined_mlvo_mask & (1u << MLVO_LAYOUT)) { if (m->mapping.layout_idx == XKB_LAYOUT_INVALID) { if (darray_size(m->rmlvo.layouts) > 1) goto skip; @@ -597,7 +482,7 @@ matcher_mapping_verify(struct matcher *m) } } - if (m->mapping.defined_mlvo_mask & (1 << MLVO_VARIANT)) { + if (m->mapping.defined_mlvo_mask & (1u << MLVO_VARIANT)) { if (m->mapping.variant_idx == XKB_LAYOUT_INVALID) { if (darray_size(m->rmlvo.variants) > 1) goto skip; @@ -627,9 +512,7 @@ matcher_rule_set_mlvo_common(struct matcher *m, struct sval ident, enum mlvo_match_type match_type) { if (m->rule.num_mlvo_values + 1 > m->mapping.num_mlvo) { - matcher_error1(m, - "invalid rule: has more values than the mapping line; " - "ignoring rule"); + matcher_err(m, "invalid rule: has more values than the mapping line; ignoring rule"); m->rule.skip = true; return; } @@ -661,9 +544,7 @@ static void matcher_rule_set_kccgst(struct matcher *m, struct sval ident) { if (m->rule.num_kccgst_values + 1 > m->mapping.num_kccgst) { - matcher_error1(m, - "invalid rule: has more values than the mapping line; " - "ignoring rule"); + matcher_err(m, "invalid rule: has more values than the mapping line; ignoring rule"); m->rule.skip = true; return; } @@ -720,20 +601,10 @@ static bool append_expanded_kccgst_value(struct matcher *m, darray_char *to, struct sval value) { - const size_t original_size = darray_size(*to); const char *s = value.start; - - /* - * Appending bar to foo -> foo (not an error if this happens) - * Appending +bar to foo -> foo+bar - * Appending bar to +foo -> bar+foo - * Appending +bar to +foo -> +foo+bar - */ - if (!darray_empty(*to) && s[0] != '+' && s[0] != '|') { - if (darray_item(*to, 0) == '+' || darray_item(*to, 0) == '|') - darray_prepend_items_nullterminate(*to, value.start, value.len); - return true; - } + darray_char expanded = darray_new(); + char ch; + bool expanded_plus, to_plus; /* * Some ugly hand-lexing here, but going through the scanner is more @@ -743,12 +614,12 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to, enum rules_mlvo mlv; xkb_layout_index_t idx; char pfx, sfx; - struct sval expanded; + struct sval expanded_value; /* Check if that's a start of an expansion. */ if (s[i] != '%') { /* Just a normal character. */ - darray_append_items_nullterminate(*to, &s[i++], 1); + darray_appends_nullterminate(expanded, &s[i++], 1); continue; } if (++i >= value.len) goto error; @@ -777,9 +648,7 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to, int consumed; if (mlv != MLVO_LAYOUT && mlv != MLVO_VARIANT) { - matcher_error1(m, - "invalid index in %%-expansion; " - "may only index layout or variant"); + matcher_err(m, "invalid index in %%-expansion; may only index layout or variant"); goto error; } @@ -795,46 +664,65 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to, } /* Get the expanded value. */ - expanded.len = 0; + expanded_value.len = 0; if (mlv == MLVO_LAYOUT) { if (idx != XKB_LAYOUT_INVALID && idx < darray_size(m->rmlvo.layouts) && darray_size(m->rmlvo.layouts) > 1) - expanded = darray_item(m->rmlvo.layouts, idx); + expanded_value = darray_item(m->rmlvo.layouts, idx); else if (idx == XKB_LAYOUT_INVALID && darray_size(m->rmlvo.layouts) == 1) - expanded = darray_item(m->rmlvo.layouts, 0); + expanded_value = darray_item(m->rmlvo.layouts, 0); } else if (mlv == MLVO_VARIANT) { if (idx != XKB_LAYOUT_INVALID && idx < darray_size(m->rmlvo.variants) && darray_size(m->rmlvo.variants) > 1) - expanded = darray_item(m->rmlvo.variants, idx); + expanded_value = darray_item(m->rmlvo.variants, idx); else if (idx == XKB_LAYOUT_INVALID && darray_size(m->rmlvo.variants) == 1) - expanded = darray_item(m->rmlvo.variants, 0); + expanded_value = darray_item(m->rmlvo.variants, 0); } else if (mlv == MLVO_MODEL) { - expanded = m->rmlvo.model; + expanded_value = m->rmlvo.model; } /* If we didn't get one, skip silently. */ - if (expanded.len <= 0) + if (expanded_value.len <= 0) continue; if (pfx != 0) - darray_append_items_nullterminate(*to, &pfx, 1); - darray_append_items_nullterminate(*to, expanded.start, expanded.len); + darray_appends_nullterminate(expanded, &pfx, 1); + darray_appends_nullterminate(expanded, + expanded_value.start, expanded_value.len); if (sfx != 0) - darray_append_items_nullterminate(*to, &sfx, 1); + darray_appends_nullterminate(expanded, &sfx, 1); } + /* + * Appending bar to foo -> foo (not an error if this happens) + * Appending +bar to foo -> foo+bar + * Appending bar to +foo -> bar+foo + * Appending +bar to +foo -> +foo+bar + */ + + ch = (darray_empty(expanded) ? '\0' : darray_item(expanded, 0)); + expanded_plus = (ch == '+' || ch == '|'); + ch = (darray_empty(*to) ? '\0' : darray_item(*to, 0)); + to_plus = (ch == '+' || ch == '|'); + + if (expanded_plus || darray_empty(*to)) + darray_appends_nullterminate(*to, expanded.item, expanded.size); + else if (to_plus) + darray_prepends_nullterminate(*to, expanded.item, expanded.size); + + darray_free(expanded); return true; error: - matcher_error1(m, "invalid %%-expansion in value; not used"); - darray_resize(*to, original_size); + darray_free(expanded); + matcher_err(m, "invalid %%-expansion in value; not used"); return false; } @@ -843,9 +731,7 @@ matcher_rule_verify(struct matcher *m) { if (m->rule.num_mlvo_values != m->mapping.num_mlvo || m->rule.num_kccgst_values != m->mapping.num_kccgst) { - matcher_error1(m, - "invalid rule: must have same number of values as mapping line;" - "ignoring rule"); + matcher_err(m, "invalid rule: must have same number of values as mapping line; ignoring rule"); m->rule.skip = true; } } @@ -907,7 +793,7 @@ matcher_rule_apply_if_matches(struct matcher *m) static enum rules_token gettok(struct matcher *m) { - return lex(&m->scanner, &m->val, &m->loc); + return lex(&m->scanner, &m->val); } static bool @@ -1068,7 +954,7 @@ finish: return true; state_error: - matcher_error1(m, "unexpected token"); + matcher_err(m, "unexpected token"); error: return false; } @@ -1091,12 +977,13 @@ xkb_components_from_rules(struct xkb_context *ctx, ret = map_file(file, &string, &size); if (!ret) { - log_err(ctx, "Couldn't read rules file: %s\n", strerror(errno)); + log_err(ctx, "Couldn't read rules file \"%s\": %s\n", + path, strerror(errno)); goto err_file; } matcher = matcher_new(ctx, rmlvo); - ret = matcher_match(matcher, string, size, rmlvo->rules, out); + ret = matcher_match(matcher, string, size, path, out); if (!ret) log_err(ctx, "No components returned from XKB rules \"%s\"\n", path); matcher_free(matcher); diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h b/src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h deleted file mode 100644 index 7e21b00662..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef XKBCOMP_SCANNER_UTILS_H -#define XKBCOMP_SCANNER_UTILS_H - -/* Point to some substring in the file; used to avoid copying. */ -struct sval { - const char *start; - unsigned int len; -}; -typedef darray(struct sval) darray_sval; - -static inline bool -svaleq(struct sval s1, struct sval s2) -{ - return s1.len == s2.len && strncmp(s1.start, s2.start, s1.len) == 0; -} - -static inline bool -svaleq_prefix(struct sval s1, struct sval s2) -{ - return s1.len <= s2.len && strncmp(s1.start, s2.start, s1.len) == 0; -} - -struct scanner { - const char *s; - size_t pos; - size_t len; - char buf[1024]; - size_t buf_pos; - int line, column; - /* The line/column of the start of the current token. */ - int token_line, token_column; - const char *file_name; - struct xkb_context *ctx; -}; - -static inline void -scanner_init(struct scanner *s, struct xkb_context *ctx, - const char *string, size_t len, const char *file_name) -{ - s->s = string; - s->len = len; - s->pos = 0; - s->line = s->column = 1; - s->token_line = s->token_column = 1; - s->file_name = file_name; - s->ctx = ctx; -} - -static inline char -peek(struct scanner *s) -{ - return s->pos < s->len ? s->s[s->pos] : '\0'; -} - -static inline bool -eof(struct scanner *s) -{ - return s->pos >= s->len; -} - -static inline bool -eol(struct scanner *s) -{ - return peek(s) == '\n'; -} - -static inline char -next(struct scanner *s) -{ - if (eof(s)) - return '\0'; - if (eol(s)) { - s->line++; - s->column = 1; - } - else { - s->column++; - } - return s->s[s->pos++]; -} - -static inline bool -chr(struct scanner *s, char ch) -{ - if (peek(s) != ch) - return false; - s->pos++; s->column++; - return true; -} - -static inline bool -str(struct scanner *s, const char *string, size_t len) -{ - if (s->len - s->pos < len) - return false; - if (strncasecmp(s->s + s->pos, string, len) != 0) - return false; - s->pos += len; s->column += len; - return true; -} - -#define lit(s, literal) str(s, literal, sizeof(literal) - 1) - -static inline bool -buf_append(struct scanner *s, char ch) -{ - if (s->buf_pos + 1 >= sizeof(s->buf)) - return false; - s->buf[s->buf_pos++] = ch; - return true; -} - -static inline bool -oct(struct scanner *s, uint8_t *out) -{ - int i; - for (i = 0, *out = 0; peek(s) >= '0' && peek(s) <= '7' && i < 3; i++) - *out = *out * 8 + next(s) - '0'; - return i > 0; -} - -#endif diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c b/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c index 48df488547..9f200bbec4 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c @@ -23,27 +23,6 @@ #include "xkbcomp-priv.h" #include "parser-priv.h" -#include "scanner-utils.h" - -static void -scanner_log(enum xkb_log_level level, struct scanner *s, const char *msg) -{ - xkb_log(s->ctx, level, 0, "%s:%d:%d: %s\n", s->file_name, - s->token_line, s->token_column, msg); -} - -int -scanner_error(struct scanner *s, const char *msg) -{ - scanner_log(XKB_LOG_LEVEL_ERROR, s, msg); - return ERROR_TOK; -} - -void -scanner_warn(struct scanner *s, const char *msg) -{ - scanner_log(XKB_LOG_LEVEL_WARNING, s, msg); -} static bool number(struct scanner *s, int64_t *out, int *out_tok) @@ -123,11 +102,13 @@ skip_more_whitespace_and_comments: buf_append(s, next(s)); } } - if (!buf_append(s, '\0') || !chr(s, '\"')) - return scanner_error(s, "unterminated string literal"); + if (!buf_append(s, '\0') || !chr(s, '\"')) { + scanner_err(s, "unterminated string literal"); + return ERROR_TOK; + } yylval->str = strdup(s->buf); if (!yylval->str) - return scanner_error(s, "scanner out of memory"); + return ERROR_TOK; return STRING; } @@ -135,8 +116,10 @@ skip_more_whitespace_and_comments: if (chr(s, '<')) { while (is_graph(peek(s)) && peek(s) != '>') buf_append(s, next(s)); - if (!buf_append(s, '\0') || !chr(s, '>')) - return scanner_error(s, "unterminated key name literal"); + if (!buf_append(s, '\0') || !chr(s, '>')) { + scanner_err(s, "unterminated key name literal"); + return ERROR_TOK; + } /* Empty key name literals are allowed. */ yylval->sval = xkb_atom_intern(s->ctx, s->buf, s->buf_pos - 1); return KEYNAME; @@ -165,27 +148,32 @@ skip_more_whitespace_and_comments: s->buf_pos = 0; while (is_alnum(peek(s)) || peek(s) == '_') buf_append(s, next(s)); - if (!buf_append(s, '\0')) - return scanner_error(s, "identifier too long"); + if (!buf_append(s, '\0')) { + scanner_err(s, "identifier too long"); + return ERROR_TOK; + } /* Keyword. */ - tok = keyword_to_token(s->buf); + tok = keyword_to_token(s->buf, s->buf_pos - 1); if (tok != -1) return tok; yylval->str = strdup(s->buf); if (!yylval->str) - return scanner_error(s, "scanner out of memory"); + return ERROR_TOK; return IDENT; } /* Number literal (hexadecimal / decimal / float). */ if (number(s, &yylval->num, &tok)) { - if (tok == ERROR_TOK) - return scanner_error(s, "malformed number literal"); + if (tok == ERROR_TOK) { + scanner_err(s, "malformed number literal"); + return ERROR_TOK; + } return tok; } - return scanner_error(s, "unrecognized token"); + scanner_err(s, "unrecognized token"); + return ERROR_TOK; } XkbFile * diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c b/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c index 56cce431da..bd7f73d4f1 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c @@ -125,12 +125,11 @@ ClearGroupInfo(GroupInfo *groupi) static void CopyGroupInfo(GroupInfo *to, const GroupInfo *from) { - xkb_level_index_t j; to->defined = from->defined; to->type = from->type; darray_init(to->levels); darray_copy(to->levels, from->levels); - for (j = 0; j < darray_size(to->levels); j++) + for (xkb_level_index_t j = 0; j < darray_size(to->levels); j++) if (darray_item(from->levels, j).num_syms > 1) darray_item(to->levels, j).u.syms = memdup(darray_item(from->levels, j).u.syms, @@ -480,7 +479,6 @@ static void MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from, enum merge_mode merge) { - unsigned int i; KeyInfo *keyi; ModMapEntry *mm; xkb_atom_t *group_name; @@ -498,7 +496,7 @@ MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from, group_names_in_both = MIN(darray_size(into->group_names), darray_size(from->group_names)); - for (i = 0; i < group_names_in_both; i++) { + for (xkb_layout_index_t i = 0; i < group_names_in_both; i++) { if (!darray_item(from->group_names, i)) continue; @@ -511,16 +509,28 @@ MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from, darray_foreach_from(group_name, from->group_names, group_names_in_both) darray_append(into->group_names, *group_name); - darray_foreach(keyi, from->keys) { - keyi->merge = (merge == MERGE_DEFAULT ? keyi->merge : merge); - if (!AddKeySymbols(into, keyi, false)) - into->errorCount++; + if (darray_empty(into->keys)) { + into->keys = from->keys; + darray_init(from->keys); + } + else { + darray_foreach(keyi, from->keys) { + keyi->merge = (merge == MERGE_DEFAULT ? keyi->merge : merge); + if (!AddKeySymbols(into, keyi, false)) + into->errorCount++; + } } - darray_foreach(mm, from->modmaps) { - mm->merge = (merge == MERGE_DEFAULT ? mm->merge : merge); - if (!AddModMapEntry(into, mm)) - into->errorCount++; + if (darray_empty(into->modmaps)) { + into->modmaps = from->modmaps; + darray_init(from->modmaps); + } + else { + darray_foreach(mm, from->modmaps) { + mm->merge = (merge == MERGE_DEFAULT ? mm->merge : merge); + if (!AddModMapEntry(into, mm)) + into->errorCount++; + } } } @@ -633,8 +643,6 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, xkb_layout_index_t ndx; GroupInfo *groupi; xkb_level_index_t nLevels; - xkb_level_index_t i; - int j; if (!GetGroupIndex(info, keyi, arrayNdx, SYMBOLS, &ndx)) return false; @@ -669,7 +677,7 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, groupi->defined |= GROUP_FIELD_SYMS; - for (i = 0; i < nLevels; i++) { + for (xkb_level_index_t i = 0; i < nLevels; i++) { unsigned int sym_index; struct xkb_level *leveli = &darray_item(groupi->levels, i); @@ -678,7 +686,7 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, if (leveli->num_syms > 1) leveli->u.syms = calloc(leveli->num_syms, sizeof(*leveli->u.syms)); - for (j = 0; j < leveli->num_syms; j++) { + for (unsigned j = 0; j < leveli->num_syms; j++) { xkb_keysym_t keysym = darray_item(value->keysym_list.syms, sym_index + j); @@ -701,7 +709,6 @@ static bool AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, ExprDef *value) { - unsigned int i; xkb_layout_index_t ndx; GroupInfo *groupi; unsigned int nActs; @@ -742,7 +749,7 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, groupi->defined |= GROUP_FIELD_ACTS; act = value->unary.child; - for (i = 0; i < nActs; i++) { + for (unsigned i = 0; i < nActs; i++) { union xkb_action *toAct = &darray_item(groupi->levels, i).action; if (!HandleActionDef(act, info->keymap, toAct, info->actions)) @@ -772,19 +779,20 @@ static bool SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, ExprDef *arrayNdx, ExprDef *value) { - bool ok = true; struct xkb_context *ctx = info->keymap->ctx; if (istreq(field, "type")) { xkb_layout_index_t ndx; xkb_atom_t val; - if (!ExprResolveString(ctx, value, &val)) - log_vrb(ctx, 1, + if (!ExprResolveString(ctx, value, &val)) { + log_err(ctx, "The type field of a key symbol map must be a string; " "Ignoring illegal type definition\n"); + return false; + } - if (arrayNdx == NULL) { + if (!arrayNdx) { keyi->default_type = val; keyi->defined |= KEY_FIELD_DEFAULT_TYPE; } @@ -803,32 +811,33 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, darray_item(keyi->groups, ndx).defined |= GROUP_FIELD_TYPE; } } - else if (istreq(field, "symbols")) + else if (istreq(field, "symbols")) { return AddSymbolsToKey(info, keyi, arrayNdx, value); - else if (istreq(field, "actions")) + } + else if (istreq(field, "actions")) { return AddActionsToKey(info, keyi, arrayNdx, value); + } else if (istreq(field, "vmods") || istreq(field, "virtualmods") || istreq(field, "virtualmodifiers")) { xkb_mod_mask_t mask; - ok = ExprResolveModMask(info->keymap, value, MOD_VIRT, &mask); - if (ok) { - keyi->vmodmap = mask; - keyi->defined |= KEY_FIELD_VMODMAP; - } - else { - log_err(info->keymap->ctx, + if (!ExprResolveModMask(info->keymap, value, MOD_VIRT, &mask)) { + log_err(ctx, "Expected a virtual modifier mask, found %s; " "Ignoring virtual modifiers definition for key %s\n", expr_op_type_to_string(value->expr.op), KeyInfoText(info, keyi)); + return false; } + + keyi->vmodmap = mask; + keyi->defined |= KEY_FIELD_VMODMAP; } else if (istreq(field, "locking") || istreq(field, "lock") || istreq(field, "locks")) { - log_err(info->keymap->ctx, + log_vrb(ctx, 1, "Key behaviors not supported; " "Ignoring locking specification for key %s\n", KeyInfoText(info, keyi)); @@ -836,14 +845,14 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, else if (istreq(field, "radiogroup") || istreq(field, "permanentradiogroup") || istreq(field, "allownone")) { - log_err(info->keymap->ctx, + log_vrb(ctx, 1, "Radio groups not supported; " "Ignoring radio group specification for key %s\n", KeyInfoText(info, keyi)); } else if (istreq_prefix("overlay", field) || istreq_prefix("permanentoverlay", field)) { - log_err(info->keymap->ctx, + log_vrb(ctx, 1, "Overlays not supported; " "Ignoring overlay specification for key %s\n", KeyInfoText(info, keyi)); @@ -853,14 +862,14 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, istreq(field, "repeat")) { unsigned int val; - ok = ExprResolveEnum(ctx, value, &val, repeatEntries); - if (!ok) { - log_err(info->keymap->ctx, + if (!ExprResolveEnum(ctx, value, &val, repeatEntries)) { + log_err(ctx, "Illegal repeat setting for %s; " "Non-boolean repeat setting ignored\n", KeyInfoText(info, keyi)); return false; } + keyi->repeat = val; keyi->defined |= KEY_FIELD_REPEAT; } @@ -869,18 +878,14 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, bool set; if (!ExprResolveBoolean(ctx, value, &set)) { - log_err(info->keymap->ctx, + log_err(ctx, "Illegal groupsWrap setting for %s; " "Non-boolean value ignored\n", KeyInfoText(info, keyi)); return false; } - if (set) - keyi->out_of_range_group_action = RANGE_WRAP; - else - keyi->out_of_range_group_action = RANGE_SATURATE; - + keyi->out_of_range_group_action = (set ? RANGE_WRAP : RANGE_SATURATE); keyi->defined |= KEY_FIELD_GROUPINFO; } else if (istreq(field, "groupsclamp") || @@ -888,18 +893,14 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, bool set; if (!ExprResolveBoolean(ctx, value, &set)) { - log_err(info->keymap->ctx, + log_err(ctx, "Illegal groupsClamp setting for %s; " "Non-boolean value ignored\n", KeyInfoText(info, keyi)); return false; } - if (set) - keyi->out_of_range_group_action = RANGE_SATURATE; - else - keyi->out_of_range_group_action = RANGE_WRAP; - + keyi->out_of_range_group_action = (set ? RANGE_SATURATE : RANGE_WRAP); keyi->defined |= KEY_FIELD_GROUPINFO; } else if (istreq(field, "groupsredirect") || @@ -907,7 +908,7 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, xkb_layout_index_t grp; if (!ExprResolveGroup(ctx, value, &grp)) { - log_err(info->keymap->ctx, + log_err(ctx, "Illegal group index for redirect of key %s; " "Definition with non-integer group ignored\n", KeyInfoText(info, keyi)); @@ -919,17 +920,17 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, keyi->defined |= KEY_FIELD_GROUPINFO; } else { - log_err(info->keymap->ctx, + log_err(ctx, "Unknown field %s in a symbol interpretation; " "Definition ignored\n", field); - ok = false; + return false; } - return ok; + return true; } -static int +static bool SetGroupName(SymbolsInfo *info, ExprDef *arrayNdx, ExprDef *value) { xkb_layout_index_t group, group_to_use; @@ -979,16 +980,16 @@ SetGroupName(SymbolsInfo *info, ExprDef *arrayNdx, ExprDef *value) return true; } -static int +static bool HandleGlobalVar(SymbolsInfo *info, VarDef *stmt) { const char *elem, *field; ExprDef *arrayNdx; bool ret; - if (ExprResolveLhs(info->keymap->ctx, stmt->name, &elem, &field, - &arrayNdx) == 0) - return 0; /* internal error, already reported */ + if (!ExprResolveLhs(info->keymap->ctx, stmt->name, &elem, &field, &arrayNdx)) + return false; + if (elem && istreq(elem, "key")) { ret = SetSymbolsField(info, &info->default_key, field, arrayNdx, stmt->value); @@ -1098,16 +1099,15 @@ SetExplicitGroup(SymbolsInfo *info, KeyInfo *keyi) return true; } -static int +static bool HandleSymbolsDef(SymbolsInfo *info, SymbolsDef *stmt) { KeyInfo keyi; - xkb_layout_index_t i; keyi = info->default_key; darray_init(keyi.groups); darray_copy(keyi.groups, info->default_key.groups); - for (i = 0; i < darray_size(keyi.groups); i++) + for (xkb_layout_index_t i = 0; i < darray_size(keyi.groups); i++) CopyGroupInfo(&darray_item(keyi.groups, i), &darray_item(info->default_key.groups, i)); keyi.merge = stmt->merge; @@ -1134,7 +1134,6 @@ HandleSymbolsDef(SymbolsInfo *info, SymbolsDef *stmt) static bool HandleModMapDef(SymbolsInfo *info, ModMapDef *def) { - ExprDef *key; ModMapEntry tmp; xkb_mod_index_t ndx; bool ok; @@ -1153,7 +1152,7 @@ HandleModMapDef(SymbolsInfo *info, ModMapDef *def) tmp.modifier = ndx; tmp.merge = def->merge; - for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next) { + for (ExprDef *key = def->keys; key; key = (ExprDef *) key->common.next) { xkb_keysym_t sym; if (key->expr.op == EXPR_VALUE && @@ -1198,7 +1197,7 @@ HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge) ok = HandleGlobalVar(info, (VarDef *) stmt); break; case STMT_VMOD: - ok = HandleVModDef(info->keymap, (VModDef *) stmt); + ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge); break; case STMT_MODMAP: ok = HandleModMapDef(info, (ModMapDef *) stmt); @@ -1518,7 +1517,7 @@ CopyModMapDef(SymbolsInfo *info, ModMapEntry *entry) } } - key->modmap |= (1 << entry->modifier); + key->modmap |= (1u << entry->modifier); return true; } diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/types.c b/src/3rdparty/xkbcommon/src/xkbcomp/types.c index 5b7ccbb4db..7708da3882 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/types.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/types.c @@ -30,111 +30,6 @@ #include "expr.h" #include "include.h" -/* - * The xkb_types section - * ===================== - * This section is the second to be processesed, after xkb_keycodes. - * However, it is completely independent and could have been the first - * to be processed (it does not refer to specific keys as specified in - * the xkb_keycodes section). - * - * This section defines key types, which, given a key and a keyboard - * state (i.e. modifier state and group), determine the shift level to - * be used in translating the key to keysyms. These types are assigned - * to each group in each key, in the xkb_symbols section. - * - * Key types are called this way because, in a way, they really describe - * the "type" of the key (or more correctly, a specific group of the - * key). For example, an ordinary keymap will provide a type called - * "KEYPAD", which consists of two levels, with the second level being - * chosen according to the state of the Num Lock (or Shift) modifiers. - * Another example is a type called "ONE_LEVEL", which is usually - * assigned to keys such as Escape; these have just one level and are - * not affected by the modifier state. Yet more common examples are - * "TWO_LEVEL" (with Shift choosing the second level), "ALPHABETIC" - * (where Caps Lock may also choose the second level), etc. - * - * Type definitions - * ---------------- - * Statements of the form: - * type "FOUR_LEVEL" { ... } - * - * The above would create a new type named "FOUR_LEVEL". - * The body of the definition may include statements of the following - * forms: - * - * - level_name statements (mandatory for each level in the type): - * level_name[Level1] = "Base"; - * - * Gives each level in this type a descriptive name. It isn't used - * for any thing. - * Note: A level may be specified as Level[1-8] or just a number (can - * be more than 8). - * - * - modifiers statement (mandatory, should be specified only once): - * modifiers = Shift+Lock+LevelThree; - * - * A mask of real and virtual modifiers. These are the only modifiers - * being considered when matching the modifier state against the type. - * The other modifiers, whether active or not, are masked out in the - * calculation. - * - * - map entry statements (should have at least as many mappings as there - * are levels in the type): - * map[Shift+LevelThree] = Level4; - * - * If the active modifiers, masked with the type's modifiers (as stated - * above), match (i.e. equal) the modifiers inside the map[] statement, - * then the level in the right hand side is chosen. For example, in the - * above, if in the current keyboard state the Shift and LevelThree - * modifiers are active, while the Lock modifier is not, then the - * keysym(s) in the 4th level of the group will be returned to the - * user. - * - * - preserve statements: - * map[Shift+Lock+LevelThree] = Level5; - * preserve[Shift+Lock+LevelThree] = Lock; - * - * When a map entry matches the active modifiers and the level it - * specified is chosen, then these modifiers are said to be "consumed"; - * for example, in a simple US keymap where the "g" key is assigned an - * ordinary ALPHABETIC key type, if the Lock (Caps Lock) modifier is - * active and the key is pressed, then a "G" keysym is produced (as - * opposed to lower-case "g"). This is because the type definition has - * a map entry like the following: - * map[Lock] = Level2; - * And as such the Lock modifier is consumed. This information is - * relevant for applications which further process the modifiers, - * since by then the consumed modifiers have already "done their part" - * and should be masked out. - * - * However, sometimes even if a modifier is actually used to choose - * the shift level (as Lock above), it should *not* be reported as - * consumed, for various reasons. In this case, a preserve[] statement - * can be used to augment the map entry. The modifiers inside the square - * brackets should match one of the map[] statements in the type. The - * right hand side should consists of modifiers from the left hand - * side; these modifiers are then "preserved" and not reported as - * consumed. - * - * Virtual modifier statements - * --------------------------- - * Statements of the form: - * virtual_modifiers LControl; - * - * Can appear in the xkb_types, xkb_compat, xkb_symbols sections. - * TODO - * - * Effect on keymap - * ---------------- - * After all of the xkb_types sections have been compiled, the following - * members of struct xkb_keymap are finalized: - * struct xkb_key_type *types; - * unsigned int num_types; - * char *types_section_name; - * TODO: virtual modifiers. - */ - enum type_field { TYPE_FIELD_MASK = (1 << 0), TYPE_FIELD_MAP = (1 << 1), @@ -287,10 +182,16 @@ MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from, from->name = NULL; } - darray_foreach(type, from->types) { - type->merge = (merge == MERGE_DEFAULT ? type->merge : merge); - if (!AddKeyType(into, type, false)) - into->errorCount++; + if (darray_empty(into->types)) { + into->types = from->types; + darray_init(from->types); + } + else { + darray_foreach(type, from->types) { + type->merge = (merge == MERGE_DEFAULT ? type->merge : merge); + if (!AddKeyType(into, type, false)) + into->errorCount++; + } } } @@ -738,7 +639,7 @@ HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge) ok = true; break; case STMT_VMOD: - ok = HandleVModDef(info->keymap, (VModDef *) stmt); + ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge); break; default: log_err(info->keymap->ctx, diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c index 206e1624e6..86e7bec786 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c +++ b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c @@ -30,27 +30,64 @@ #include "vmod.h" bool -HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt) +HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt, + enum merge_mode merge) { xkb_mod_index_t i; - const struct xkb_mod *mod; + struct xkb_mod *mod; + xkb_mod_mask_t mapping; struct xkb_mod new; - if (stmt->value) - log_err(keymap->ctx, - "Support for setting a value in a virtual_modifiers statement has been removed; " - "Value ignored\n"); + merge = (merge == MERGE_DEFAULT ? stmt->merge : merge); + + if (stmt->value) { + /* + * This is a statement such as 'virtualModifiers NumLock = Mod1'; + * it sets the vmod-to-real-mod[s] mapping directly instead of going + * through modifier_map or some such. + */ + if (!ExprResolveModMask(keymap, stmt->value, MOD_REAL, &mapping)) { + log_err(keymap->ctx, + "Declaration of %s ignored\n", + xkb_atom_text(keymap->ctx, stmt->name)); + return false; + } + } + else { + mapping = 0; + } darray_enumerate(i, mod, keymap->mods) { if (mod->name == stmt->name) { - if (mod->type == MOD_VIRT) + if (mod->type != MOD_VIRT) { + log_err(keymap->ctx, + "Can't add a virtual modifier named \"%s\"; " + "there is already a non-virtual modifier with this name! Ignored\n", + xkb_atom_text(keymap->ctx, mod->name)); + return false; + } + + if (mod->mapping == mapping) return true; - log_err(keymap->ctx, - "Can't add a virtual modifier named \"%s\"; " - "there is already a non-virtual modifier with this name! Ignored\n", - xkb_atom_text(keymap->ctx, mod->name)); - return false; + if (mod->mapping != 0) { + xkb_mod_mask_t use, ignore; + + use = (merge == MERGE_OVERRIDE ? mapping : mod->mapping); + ignore = (merge == MERGE_OVERRIDE ? mod->mapping : mapping); + + log_warn(keymap->ctx, + "Virtual modifier %s defined multiple times; " + "Using %s, ignoring %s\n", + xkb_atom_text(keymap->ctx, stmt->name), + ModMaskText(keymap, use), + ModMaskText(keymap, ignore)); + + mapping = use; + } + + mod->mapping = mapping; + return true; } } @@ -62,7 +99,7 @@ HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt) } new.name = stmt->name; - new.mapping = 0; + new.mapping = mapping; new.type = MOD_VIRT; darray_append(keymap->mods, new); return true; diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h index 991550735f..1ba59f73cd 100644 --- a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h +++ b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h @@ -28,6 +28,7 @@ #define XKBCOMP_VMOD_H bool -HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt); +HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt, + enum merge_mode merge); #endif diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h index f96e4c806f..299732fdc3 100644 --- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h +++ b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h @@ -91,4 +91,8 @@ #define xkb_state_get_map(state) xkb_state_get_keymap(state) +/* Not needed anymore, since there's NO_FLAGS. */ +#define XKB_MAP_COMPILE_PLACEHOLDER XKB_KEYMAP_COMPILE_NO_FLAGS +#define XKB_MAP_COMPILE_NO_FLAGS XKB_KEYMAP_COMPILE_NO_FLAGS + #endif diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h index 4ec9b649c7..d9e2a4f11a 100644 --- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h +++ b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h @@ -27,6 +27,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** * @file * libxkbcommon-x11 API - Additional X11 support for xkbcommon. @@ -163,4 +167,8 @@ xkb_x11_state_new_from_device(struct xkb_keymap *keymap, /** @} */ +#ifdef __cplusplus +} /* extern "C" */ #endif + +#endif /* _XKBCOMMON_X11_H */ diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h index cc9262ff89..36251db443 100644 --- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h +++ b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h @@ -305,26 +305,60 @@ typedef uint32_t xkb_led_mask_t; /** * Names to compile a keymap with, also known as RMLVO. * - * These names together are the primary identifier for a keymap. - * If any of the members is NULL or an empty string (""), a default value is - * used. It is recommended to use the system default by passing NULL for - * unspecified values, instead of providing your own defaults. + * The names are the common configuration values by which a user picks + * a keymap. + * + * If the entire struct is NULL, then each field is taken to be NULL. + * You should prefer passing NULL instead of choosing your own defaults. */ struct xkb_rule_names { - /** The rules file to use. The rules file describes how to interpret - * the values of the model, layout, variant and options fields. */ + /** + * The rules file to use. The rules file describes how to interpret + * the values of the model, layout, variant and options fields. + * + * If NULL or the empty string "", a default value is used. + * If the XKB_DEFAULT_RULES environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ const char *rules; - /** The keyboard model by which to interpret keycodes and LEDs. */ + /** + * The keyboard model by which to interpret keycodes and LEDs. + * + * If NULL or the empty string "", a default value is used. + * If the XKB_DEFAULT_MODEL environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ const char *model; - /** A comma separated list of layouts (languages) to include in the - * keymap. */ + /** + * A comma separated list of layouts (languages) to include in the + * keymap. + * + * If NULL or the empty string "", a default value is used. + * If the XKB_DEFAULT_LAYOUT environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ const char *layout; - /** A comma separated list of variants, one per layout, which may - * modify or augment the respective layout in various ways. */ + /** + * A comma separated list of variants, one per layout, which may + * modify or augment the respective layout in various ways. + * + * If NULL or the empty string "", and a default value is also used + * for the layout, a default value is used. Otherwise no variant is + * used. + * If the XKB_DEFAULT_VARIANT environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ const char *variant; - /** A comma separated list of options, through which the user specifies - * non-layout related preferences, like which key combinations are used - * for switching layouts, or which key is the Compose key. */ + /** + * A comma separated list of options, through which the user specifies + * non-layout related preferences, like which key combinations are used + * for switching layouts, or which key is the Compose key. + * + * If NULL, a default value is used. If the empty string "", no + * options are used. + * If the XKB_DEFAULT_OPTIONS environment variable is set, it is used + * as the default. Otherwise the system default is used. + */ const char *options; }; @@ -399,6 +433,11 @@ xkb_keysym_from_name(const char *name, enum xkb_keysym_flags flags); * @returns The number of bytes written to the buffer (including the * terminating byte). If the keysym does not have a Unicode * representation, returns 0. If the buffer is too small, returns -1. + * + * Prefer not to use this function on keysyms obtained from an + * xkb_state. In this case, use xkb_state_key_get_utf8() instead. + * + * @sa xkb_state_key_get_utf8() */ int xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size); @@ -409,6 +448,11 @@ xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size); * @returns The Unicode/UTF-32 representation of keysym, which is also * compatible with UCS-4. If the keysym does not have a Unicode * representation, returns 0. + * + * Prefer not to use this function on keysyms obtained from an + * xkb_state. In this case, use xkb_state_key_get_utf32() instead. + * + * @sa xkb_state_key_get_utf32() */ uint32_t xkb_keysym_to_utf32(xkb_keysym_t keysym); @@ -681,9 +725,7 @@ xkb_context_set_log_fn(struct xkb_context *context, /** Flags for keymap compilation. */ enum xkb_keymap_compile_flags { /** Do not apply any flags. */ - XKB_MAP_COMPILE_NO_FLAGS = 0, - /** Apparently you can't have empty enums. What a drag. */ - XKB_MAP_COMPILE_PLACEHOLDER = 0 + XKB_KEYMAP_COMPILE_NO_FLAGS = 0 }; /** @@ -692,13 +734,8 @@ enum xkb_keymap_compile_flags { * The primary keymap entry point: creates a new XKB keymap from a set of * RMLVO (Rules + Model + Layouts + Variants + Options) names. * - * You should almost certainly be using this and nothing else to create - * keymaps. - * * @param context The context in which to create the keymap. - * @param names The RMLVO names to use. In xkbcommon versions prior - * to 0.2.1, this field must be non-NULL. In later - * versions, passing NULL will use the default keymap. + * @param names The RMLVO names to use. See xkb_rule_names. * @param flags Optional flags for the keymap, or 0. * * @returns A keymap compiled according to the RMLVO names, or NULL if @@ -1159,6 +1196,13 @@ enum xkb_state_component { * is pressed twice, it should be released twice; etc. Otherwise (e.g. due * to missed input events), situations like "stuck modifiers" may occur. * + * This function is often used in conjunction with the function + * xkb_state_key_get_syms() (or xkb_state_key_get_one_sym()), for example, + * when handling a key event. In this case, you should prefer to get the + * keysyms *before* updating the key, such that the keysyms reported for + * the key event are not affected by the event itself. This is the + * conventional behavior. + * * @returns A mask of state components that have changed as a result of * the update. If nothing in the state has changed, returns 0. * @@ -1234,6 +1278,44 @@ int xkb_state_key_get_syms(struct xkb_state *state, xkb_keycode_t key, const xkb_keysym_t **syms_out); +/** + * Get the Unicode/UTF-8 string obtained from pressing a particular key + * in a given keyboard state. + * + * @param[in] state The keyboard state object. + * @param[in] key The keycode of the key. + * @param[out] buffer A buffer to write the string into. + * @param[in] size Size of the buffer. + * + * @warning If the buffer passed is too small, the string is truncated + * (though still NUL-terminated). + * + * @returns The number of bytes required for the string, excluding the + * NUL byte. If there is nothing to write, returns 0. + * + * You may check if truncation has occurred by comparing the return value + * with the size of @p buffer, similarly to the snprintf(3) function. + * You may safely pass NULL and 0 to @p buffer and @p size to find the + * required size (without the NUL-byte). + * + * @memberof xkb_state + */ +int +xkb_state_key_get_utf8(struct xkb_state *state, xkb_keycode_t key, + char *buffer, size_t size); + +/** + * Get the Unicode/UTF-32 codepoint obtained from pressing a particular + * key in a a given keyboard state. + * + * @returns The UTF-32 representation for the key, if it consists of only + * a single codepoint. Otherwise, returns 0. + * + * @memberof xkb_state + */ +uint32_t +xkb_state_key_get_utf32(struct xkb_state *state, xkb_keycode_t key); + /** * Get the single keysym obtained from pressing a particular key in a * given keyboard state. @@ -1485,6 +1567,7 @@ xkb_state_mod_indices_are_active(struct xkb_state *state, * index is not valid in the keymap, returns -1. * * @sa xkb_state_mod_mask_remove_consumed() + * @sa xkb_state_key_get_consumed_mods() * @memberof xkb_state */ int @@ -1504,6 +1587,17 @@ xkb_mod_mask_t xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t key, xkb_mod_mask_t mask); +/** + * Get the mask of modifiers consumed by translating a given key. + * + * @returns a mask of the consumed modifiers. + * + * @sa xkb_state_mod_index_is_consumed() + * @memberof xkb_state + */ +xkb_mod_mask_t +xkb_state_key_get_consumed_mods(struct xkb_state *state, xkb_keycode_t key); + /** * Test whether a layout is active in a given keyboard state by name. * diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index aefd9655ed..1acd466aeb 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -48,10 +48,7 @@ #include #ifndef QT_NO_XKB -// note: extern won't be needed from libxkbcommon 0.4.1 and above -extern "C" { #include -} #endif #include -- cgit v1.2.3