Update Native Libraries (#1)
* Update libxkbcommon * Squash bugs * Update xkbcommon to latest master * Update parser definitions * Bug fixes
This commit is contained in:
parent
7c1bfbc9d6
commit
afe1e33f3e
|
@ -35,13 +35,13 @@ LOCAL_SRC_FILES := \
|
|||
xkbcommon/src/utf8.c \
|
||||
xkbcommon/src/utils.c
|
||||
LOCAL_CFLAGS := \
|
||||
-std=c99 -Wall -Werror -Wno-unused-parameter -Wno-missing-field-initializers \
|
||||
-std=c99 -Wall -Werror -Wno-unused-parameter -Wno-missing-field-initializers -Wimplicit-function-declaration \
|
||||
-D_GNU_SOURCE \
|
||||
-DXLOCALEDIR=\"/data/data/com.termux/files/usr/share/X11/locale\" \
|
||||
-DDEFAULT_XKB_LAYOUT=\"us\" \
|
||||
-DDEFAULT_XKB_MODEL=\"pc105\" \
|
||||
-DDEFAULT_XKB_RULES=\"evdev\" \
|
||||
-DDFLT_XKB_CONFIG_ROOT=\"/data/data/com.termux/files/usr/share/X11/xkb\"
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/xkbcommon $(LOCAL_PATH)/xkbcommon/src
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/xkbcommon $(LOCAL_PATH)/xkbcommon/src $(LOCAL_PATH)/xkbcommon/include
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/xkbcommon/
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
begin-language: "Autoconf-without-aclocal-m4"
|
||||
args: --cache=build-aux
|
||||
end-language: "Autoconf-without-aclocal-m4"
|
|
@ -0,0 +1,14 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
max_line_length = 80
|
||||
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
|
@ -1,12 +0,0 @@
|
|||
language: c
|
||||
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install xutils-dev
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
# libxcb too old -- should enable when possible.
|
||||
script: ./autogen.sh --disable-x11 && make && make check
|
|
@ -20,7 +20,7 @@ BEGINNING OF SOFTWARE COPYRIGHT/LICENSE STATEMENTS:
|
|||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Copyright © 2009-2012 Daniel Stone
|
||||
Copyright © 2009-2012, 2016 Daniel Stone
|
||||
Copyright © 2012 Ran Benita <ran234@gmail.com>
|
||||
Copyright © 2010, 2012 Intel Corporation
|
||||
Copyright © 2008, 2009 Dan Nicholson
|
|
@ -1,309 +0,0 @@
|
|||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = xkbcommon.pc
|
||||
|
||||
EXTRA_DIST = \
|
||||
makekeys.py \
|
||||
src/xkbcomp/keywords.gperf \
|
||||
test/data \
|
||||
README.md \
|
||||
doc/quick-guide.md \
|
||||
doc/compat.md \
|
||||
doc/keymap-format-text-v1.txt \
|
||||
doc/rules-format.txt \
|
||||
doc/doxygen-extra.css \
|
||||
xkbcommon.map \
|
||||
xkbcommon-x11.map \
|
||||
PACKAGING
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-DDFLT_XKB_CONFIG_ROOT='"$(XKBCONFIGROOT)"' \
|
||||
-DXLOCALEDIR='"$(XLOCALEDIR)"' \
|
||||
-I$(top_srcdir)/src \
|
||||
-I$(top_srcdir)/src/xkbcomp \
|
||||
-I$(top_builddir)/src/xkbcomp \
|
||||
-include $(top_builddir)/src/config.h
|
||||
|
||||
AM_CFLAGS = $(BASE_CFLAGS)
|
||||
|
||||
AM_LDFLAGS = -no-undefined
|
||||
if HAVE_NO_UNDEFINED
|
||||
AM_LDFLAGS += -Wl,--no-undefined
|
||||
endif
|
||||
|
||||
AM_YFLAGS = -d -p _xkbcommon_
|
||||
|
||||
xkbcommonincludedir = $(includedir)/xkbcommon
|
||||
xkbcommoninclude_HEADERS = \
|
||||
xkbcommon/xkbcommon.h \
|
||||
xkbcommon/xkbcommon-compat.h \
|
||||
xkbcommon/xkbcommon-compose.h \
|
||||
xkbcommon/xkbcommon-keysyms.h \
|
||||
xkbcommon/xkbcommon-names.h
|
||||
|
||||
lib_LTLIBRARIES = libxkbcommon.la
|
||||
libxkbcommon_la_SOURCES = \
|
||||
src/compose/parser.c \
|
||||
src/compose/parser.h \
|
||||
src/compose/paths.c \
|
||||
src/compose/paths.h \
|
||||
src/compose/state.c \
|
||||
src/compose/table.c \
|
||||
src/compose/table.h \
|
||||
src/xkbcomp/action.c \
|
||||
src/xkbcomp/action.h \
|
||||
src/xkbcomp/ast.h \
|
||||
src/xkbcomp/ast-build.c \
|
||||
src/xkbcomp/ast-build.h \
|
||||
src/xkbcomp/compat.c \
|
||||
src/xkbcomp/expr.c \
|
||||
src/xkbcomp/expr.h \
|
||||
src/xkbcomp/include.c \
|
||||
src/xkbcomp/include.h \
|
||||
src/xkbcomp/keycodes.c \
|
||||
src/xkbcomp/keymap.c \
|
||||
src/xkbcomp/keymap-dump.c \
|
||||
src/xkbcomp/keywords.c \
|
||||
src/xkbcomp/parser.y \
|
||||
src/xkbcomp/parser-priv.h \
|
||||
src/xkbcomp/rules.c \
|
||||
src/xkbcomp/rules.h \
|
||||
src/xkbcomp/scanner.c \
|
||||
src/xkbcomp/symbols.c \
|
||||
src/xkbcomp/types.c \
|
||||
src/xkbcomp/vmod.c \
|
||||
src/xkbcomp/vmod.h \
|
||||
src/xkbcomp/xkbcomp.c \
|
||||
src/xkbcomp/xkbcomp-priv.h \
|
||||
src/atom.c \
|
||||
src/atom.h \
|
||||
src/context.c \
|
||||
src/context.h \
|
||||
src/context-priv.c \
|
||||
src/darray.h \
|
||||
src/keysym.c \
|
||||
src/keysym.h \
|
||||
src/keysym-utf.c \
|
||||
src/ks_tables.h \
|
||||
src/keymap.c \
|
||||
src/keymap.h \
|
||||
src/keymap-priv.c \
|
||||
src/scanner-utils.h \
|
||||
src/state.c \
|
||||
src/text.c \
|
||||
src/text.h \
|
||||
src/utf8.c \
|
||||
src/utf8.h \
|
||||
src/utils.c \
|
||||
src/utils.h
|
||||
libxkbcommon_la_LDFLAGS = -Wl,--version-script=${srcdir}/xkbcommon.map
|
||||
|
||||
if ENABLE_X11
|
||||
pkgconfig_DATA += xkbcommon-x11.pc
|
||||
|
||||
xkbcommon_x11includedir = $(xkbcommonincludedir)
|
||||
xkbcommon_x11include_HEADERS = \
|
||||
xkbcommon/xkbcommon-x11.h
|
||||
|
||||
lib_LTLIBRARIES += libxkbcommon-x11.la
|
||||
|
||||
libxkbcommon_x11_la_CFLAGS = $(AM_CFLAGS) $(XCB_XKB_CFLAGS)
|
||||
libxkbcommon_x11_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/x11
|
||||
libxkbcommon_x11_la_LIBADD = libxkbcommon.la $(XCB_XKB_LIBS)
|
||||
libxkbcommon_x11_la_LDFLAGS = -Wl,--version-script=${srcdir}/xkbcommon-x11.map
|
||||
|
||||
libxkbcommon_x11_la_SOURCES = \
|
||||
src/x11/keymap.c \
|
||||
src/x11/state.c \
|
||||
src/x11/util.c \
|
||||
src/x11/x11-priv.h \
|
||||
src/context.h \
|
||||
src/context-priv.c \
|
||||
src/keymap.h \
|
||||
src/keymap-priv.c \
|
||||
src/atom.h \
|
||||
src/atom.c
|
||||
endif ENABLE_X11
|
||||
|
||||
BUILT_SOURCES = \
|
||||
src/xkbcomp/parser.c \
|
||||
src/xkbcomp/parser.h
|
||||
CLEANFILES = $(BUILT_SOURCES)
|
||||
|
||||
src/xkbcomp/parser.c: $(top_builddir)/src/$(am__dirstamp) $(top_builddir)/src/xkbcomp/$(am__dirstamp)
|
||||
src/xkbcomp/parser.h: $(top_builddir)/src/$(am__dirstamp) $(top_builddir)/src/xkbcomp/$(am__dirstamp)
|
||||
|
||||
##
|
||||
# Documentation
|
||||
##
|
||||
|
||||
if ENABLE_DOCS
|
||||
if HAVE_DOXYGEN
|
||||
doc: doc/stamp-doxygen
|
||||
clean-doc: clean-doxygen
|
||||
all-local:: doc
|
||||
clean-local:: clean-doc
|
||||
|
||||
doc/stamp-doxygen: $(top_srcdir)/xkbcommon/*.h
|
||||
$(AM_V_GEN)$(DOXYGEN) doc/Doxyfile
|
||||
touch $@
|
||||
|
||||
clean-doxygen:
|
||||
rm -rf doc/html doc/stamp-doxygen
|
||||
|
||||
install-data-local:: doc
|
||||
$(MKDIR_P) $(DESTDIR)$(htmldir)
|
||||
$(INSTALL_DATA) doc/html/* $(DESTDIR)$(htmldir)
|
||||
|
||||
uninstall-local::
|
||||
rm -rf $(DESTDIR)$(htmldir)
|
||||
endif HAVE_DOXYGEN
|
||||
endif ENABLE_DOCS
|
||||
|
||||
##
|
||||
# Tests
|
||||
##
|
||||
|
||||
# Some tests need to use unexported symbols, so we link them against
|
||||
# a private copy of libxkbcommon with all symbols exposed.
|
||||
check_LTLIBRARIES = libtest.la
|
||||
libtest_la_SOURCES = \
|
||||
$(libxkbcommon_la_SOURCES) \
|
||||
test/common.c \
|
||||
test/test.h \
|
||||
test/evdev-scancodes.h
|
||||
|
||||
AM_TESTS_ENVIRONMENT = \
|
||||
XKB_LOG_LEVEL=debug; export XKB_LOG_LEVEL; \
|
||||
XKB_LOG_VERBOSITY=10; export XKB_LOG_VERBOSITY; \
|
||||
$(XORG_MALLOC_DEBUG_ENV)
|
||||
|
||||
TESTS = \
|
||||
test/keysym \
|
||||
test/filecomp \
|
||||
test/context \
|
||||
test/rules-file \
|
||||
test/stringcomp \
|
||||
test/buffercomp \
|
||||
test/log \
|
||||
test/atom \
|
||||
test/utf8 \
|
||||
test/state \
|
||||
test/keyseq \
|
||||
test/rulescomp \
|
||||
test/compose
|
||||
check_PROGRAMS = \
|
||||
test/rmlvo-to-kccgst \
|
||||
test/print-compiled-keymap
|
||||
|
||||
TESTS_LDADD = libtest.la
|
||||
|
||||
test_keysym_LDADD = $(TESTS_LDADD)
|
||||
test_filecomp_LDADD = $(TESTS_LDADD)
|
||||
test_context_LDADD = $(TESTS_LDADD)
|
||||
test_rules_file_CFLAGS = $(AM_CFLAGS) -Wno-declaration-after-statement
|
||||
test_rules_file_LDADD = $(TESTS_LDADD)
|
||||
test_stringcomp_LDADD = $(TESTS_LDADD)
|
||||
test_buffercomp_LDADD = $(TESTS_LDADD)
|
||||
test_log_LDADD = $(TESTS_LDADD)
|
||||
test_atom_LDADD = $(TESTS_LDADD)
|
||||
test_utf8_LDADD = $(TESTS_LDADD)
|
||||
test_state_LDADD = $(TESTS_LDADD)
|
||||
test_keyseq_LDADD = $(TESTS_LDADD)
|
||||
test_rulescomp_LDADD = $(TESTS_LDADD)
|
||||
test_rmlvo_to_kccgst_LDADD = $(TESTS_LDADD)
|
||||
test_print_compiled_keymap_LDADD = $(TESTS_LDADD)
|
||||
test_compose_LDADD = $(TESTS_LDADD) $(RT_LIBS)
|
||||
|
||||
if BUILD_LINUX_TESTS
|
||||
check_PROGRAMS += \
|
||||
test/interactive-evdev
|
||||
|
||||
test_interactive_evdev_LDADD = $(TESTS_LDADD)
|
||||
endif BUILD_LINUX_TESTS
|
||||
|
||||
if ENABLE_X11
|
||||
TESTS += \
|
||||
test/x11 \
|
||||
test/x11comp
|
||||
check_PROGRAMS += \
|
||||
test/interactive-x11
|
||||
|
||||
TESTS_X11_LDADD = $(XCB_XKB_LIBS) $(TESTS_LDADD) libxkbcommon-x11.la
|
||||
TESTS_X11_CFLAGS = $(XCB_XKB_CFLAGS)
|
||||
|
||||
test_x11_LDADD = $(TESTS_X11_LDADD)
|
||||
test_x11_CFLAGS = $(TESTS_X11_CFLAGS)
|
||||
test_x11comp_LDADD = $(TESTS_X11_LDADD)
|
||||
test_x11comp_CFLAGS = $(TESTS_X11_CFLAGS)
|
||||
test_interactive_x11_LDADD = $(TESTS_X11_LDADD)
|
||||
test_interactive_x11_CFLAGS = $(TESTS_X11_CFLAGS)
|
||||
endif ENABLE_X11
|
||||
|
||||
check_PROGRAMS += $(TESTS)
|
||||
|
||||
##
|
||||
# Benchmarks
|
||||
##
|
||||
|
||||
BENCH_LDADD = $(TESTS_LDADD) $(RT_LIBS)
|
||||
|
||||
check_PROGRAMS += \
|
||||
bench/key-proc \
|
||||
bench/rules \
|
||||
bench/rulescomp \
|
||||
bench/compose
|
||||
bench_key_proc_LDADD = $(BENCH_LDADD)
|
||||
bench_rules_LDADD = $(BENCH_LDADD)
|
||||
bench_rulescomp_LDADD = $(BENCH_LDADD)
|
||||
bench_compose_LDADD = $(BENCH_LDADD)
|
||||
|
||||
##
|
||||
# Custom targets
|
||||
##
|
||||
|
||||
# This sed script strips out lines that start with '#define _' which
|
||||
# removes #define _OSF_Keysyms and such. The XK_Ydiaeresis case is to
|
||||
# handle a duplicate definition in HPkeysyms.h which kicks in if it's
|
||||
# not already defined.
|
||||
X11_INCLUDEDIR = /usr/include/X11
|
||||
KEYSYMDEFS = \
|
||||
$(X11_INCLUDEDIR)/keysymdef.h \
|
||||
$(X11_INCLUDEDIR)/XF86keysym.h \
|
||||
$(X11_INCLUDEDIR)/Sunkeysym.h \
|
||||
$(X11_INCLUDEDIR)/DECkeysym.h \
|
||||
$(X11_INCLUDEDIR)/HPkeysym.h
|
||||
update-keysyms:
|
||||
echo -en '#ifndef _XKBCOMMON_KEYSYMS_H\n#define _XKBCOMMON_KEYSYMS_H\n\n' > $(top_srcdir)/xkbcommon/xkbcommon-keysyms.h
|
||||
echo -en '/* This file is autogenerated from Makefile.am; please do not commit directly. */\n\n' >> $(top_srcdir)/xkbcommon/xkbcommon-keysyms.h
|
||||
echo -en '#define XKB_KEY_NoSymbol 0x000000 /* Special KeySym */\n\n' >> $(top_srcdir)/xkbcommon/xkbcommon-keysyms.h
|
||||
sed -e '/XK_Ydiaeresis\s*0x100000ee/d' \
|
||||
-e '/#define _/d' \
|
||||
-e 's/#define\s*\(\w*\)XK_/#define XKB_KEY_\1/' \
|
||||
-e '/\(#ifdef\|#ifndef\|#endif\)/d' $(KEYSYMDEFS) >> $(top_srcdir)/xkbcommon/xkbcommon-keysyms.h
|
||||
echo -en '\n\n#endif\n' >> $(top_srcdir)/xkbcommon/xkbcommon-keysyms.h
|
||||
LC_CTYPE=C python $(top_srcdir)/makekeys.py $(top_srcdir)/xkbcommon/xkbcommon-keysyms.h > $(top_srcdir)/src/ks_tables.h
|
||||
|
||||
# Run this if you add/remove a new keyword to the xkbcomp scanner,
|
||||
# or just want to regenerate the gperf file.
|
||||
update-keywords:
|
||||
$(AM_V_GEN)gperf < $(top_srcdir)/src/xkbcomp/keywords.gperf > $(top_srcdir)/src/xkbcomp/keywords.c
|
||||
|
||||
##
|
||||
# Android stuff
|
||||
##
|
||||
|
||||
Android_build.mk: Makefile $(BUILT_SOURCES)
|
||||
androgenizer \
|
||||
-:PROJECT libxkbcommon \
|
||||
-:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
|
||||
\
|
||||
-:STATIC libxkbcommon \
|
||||
-:TAGS eng debug \
|
||||
-:SOURCES $(filter-out %.l %.y,$(libxkbcommon_la_SOURCES)) $(BUILT_SOURCES) \
|
||||
-:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(AM_CPPFLAGS) $(AM_CFLAGS) \
|
||||
-:LDFLAGS $(AM_LDFLAGS) \
|
||||
\
|
||||
-:PASSTHROUGH 'libxkbcommon-clean: clean-libxkbcommon' \
|
||||
> $@
|
|
@ -1,3 +1,550 @@
|
|||
libxkbcommon 1.3.0 - 2021-05-01
|
||||
==================
|
||||
|
||||
- Change `xkbcli list` to output YAML, instead of the previous ad-hoc format.
|
||||
|
||||
This allows to more easily process the information in a programmetic way, for
|
||||
example
|
||||
|
||||
xkbcli list | yq -r ".layouts[].layout"
|
||||
|
||||
Contributed by Peter Hutterer.
|
||||
|
||||
- Optimize a certain part of keymap compilation (atom interning).
|
||||
|
||||
- Fix segmentation fault in case-insensitive `xkb_keysym_from_name` for certain
|
||||
values like the empty string.
|
||||
|
||||
Contributed by Isaac Freund.
|
||||
|
||||
- Support building libxkbcommon as a meson subproject.
|
||||
|
||||
Contributed by Adrian Perez de Castro.
|
||||
|
||||
- Add `ftruncate` fallback for `posix_fallocate` in `xkbcli interactive-wayland`
|
||||
for FreeBSD.
|
||||
|
||||
Contributed by Evgeniy Khramtsov.
|
||||
|
||||
- Properly export library symbols in MSVC.
|
||||
|
||||
Contributed by Adrian Perez de Castro.
|
||||
|
||||
libxkbcommon 1.2.1 - 2021-04-07
|
||||
==================
|
||||
|
||||
- Fix `xkb_x11_keymap_new_from_device()` failing when the keymap contains key
|
||||
types with missing level names, like the one used by the `numpad:mac` option
|
||||
in xkeyboard-config. Regressed in 1.2.0.
|
||||
|
||||
libxkbcommon 1.2.0 - 2021-04-03
|
||||
==================
|
||||
|
||||
- `xkb_x11_keymap_new_from_device()` is much faster. It now performs only 2
|
||||
roundtrips to the X server, instead of dozens (in first-time calls).
|
||||
|
||||
Contributed by Uli Schlachter.
|
||||
|
||||
- Case-sensitive `xkb_keysym_from_name()` is much faster.
|
||||
|
||||
- Keysym names of the form `0x12AB` and `U12AB` are parsed more strictly.
|
||||
Previously the hexadecimal part was parsed with `strtoul()`, now only up
|
||||
to 8 hexadecimal digits (0-9A-Fa-f) are allowed.
|
||||
|
||||
- Compose files now have a size limit (65535 internal nodes). Further sequences
|
||||
are discared and a warning is issued.
|
||||
|
||||
- Compose table loading (`xkb_compose_table_new_from_locale()` and similar) is
|
||||
much faster.
|
||||
|
||||
- Use `poll()` instead of `epoll()` for `xlbcli interactive-evdev`, making it
|
||||
portable to FreeBSD which provides evdev but not epoll. On FreeBSD, remember
|
||||
to install the `evdev-proto` package to get the evdev headers.
|
||||
|
||||
- The build now requires a C11 compiler (uses anonymous structs/unions).
|
||||
|
||||
libxkbcommon 1.1.0 - 2021-02-27
|
||||
==================
|
||||
|
||||
- Publish the `xkb-format-text-v1.md` file in the HTML documentation. This file
|
||||
existed for a long time but only in the Git repository.
|
||||
Link: https://xkbcommon.org/doc/current/md_doc_keymap_format_text_v1.html
|
||||
|
||||
- Add partial documentation for xkb_symbols to xkb-format-text-v1.md.
|
||||
|
||||
Contributed by Simon Zeni.
|
||||
|
||||
- Update keysym definitions to latest xorgproto. In particular, this adds many
|
||||
special keysyms corresponding to Linux evdev keycodes.
|
||||
|
||||
Contributed by Peter Hutterer <@who-t.net>.
|
||||
|
||||
- New API:
|
||||
Too many XKB_KEY_* definitions to list here.
|
||||
|
||||
libxkbcommon 1.0.3 - 2020-11-23
|
||||
==================
|
||||
|
||||
- Fix (hopefully) a segfault in xkb_x11_keymap_new_from_device() in some
|
||||
unclear situation (bug introduced in 1.0.2).
|
||||
|
||||
- Fix keymaps created with xkb_x11_keymap_new_from_device() don't have level
|
||||
names (bug introduced in 0.8.0).
|
||||
|
||||
libxkbcommon 1.0.2 - 2020-11-20
|
||||
==================
|
||||
|
||||
- Fix a bug where a keysym that cannot be resolved in a keymap gets compiled to
|
||||
a garbage keysym. Now it is set to XKB_KEY_NoSymbol instead.
|
||||
|
||||
- Improve the speed of xkb_x11_keymap_new_from_device() on repeated calls in the
|
||||
same xkb_context().
|
||||
|
||||
|
||||
libxkbcommon 1.0.1 - 2020-09-11
|
||||
==================
|
||||
|
||||
- Fix the tool-option-parsing test failing.
|
||||
|
||||
- Remove requirement for pytest in the tool-option-parsing test.
|
||||
|
||||
- Make the table output of `xkbcli how-to-type` aligned.
|
||||
|
||||
- Some portability and test isolation fixes.
|
||||
|
||||
libxkbcommon 1.0.0 - 2020-09-05
|
||||
==================
|
||||
|
||||
Note: this release is API and ABI compatible with previous releases -- the
|
||||
major version bump is only an indication of stability.
|
||||
|
||||
- Add libxkbregistry as configure-time optional library. libxkbregistry is a C
|
||||
library that lists available XKB models, layouts and variants for a given
|
||||
ruleset. This is a separate library (libxkbregistry.so, pkgconfig file
|
||||
xkbregistry.pc) and aimed at tools that provide a listing of available
|
||||
keyboard layouts to the user. See the Documentation for details on the API.
|
||||
|
||||
Contributed by Peter Hutterer <@who-t.net>.
|
||||
|
||||
- Better support custom user configuration:
|
||||
|
||||
* Allow including XKB files from other paths.
|
||||
|
||||
Previously, a 'symbols/us' file in path A would shadow the same file in
|
||||
path B. This is suboptimal, we rarely need to hide the system files - we
|
||||
care mostly about *extending* them. By continuing to check other lookup
|
||||
paths, we make it possible for a XDG_CONFIG_HOME/xkb/symbols/us file to
|
||||
have sections including those from /usr/share/X11/xkb/symbols/us.
|
||||
|
||||
Note that this is not possible for rules files, which need to be manually
|
||||
controlled to get the right bits resolved.
|
||||
|
||||
* Add /etc/xkb as extra lookup path for system data files.
|
||||
|
||||
This completes the usual triplet of configuration locations available for
|
||||
most processes:
|
||||
- vendor-provided data files in /usr/share/X11/xkb
|
||||
- system-specific data files in /etc/xkb
|
||||
- user-specific data files in $XDG_CONFIG_HOME/xkb
|
||||
|
||||
The default lookup order user, system, vendor, just like everything else
|
||||
that uses these conventions.
|
||||
|
||||
For include directives in rules files, the '%E' resolves to that path.
|
||||
|
||||
* Add a new section to the documentation for custom user configuration.
|
||||
|
||||
Contributed by Peter Hutterer <@who-t.net>.
|
||||
|
||||
- Add an `xkbcli` command-line utility.
|
||||
|
||||
This tool offers various subcommands for introspection and debugging.
|
||||
Currently the available subcommands are:
|
||||
|
||||
list
|
||||
List available rules, models, layouts, variants and options
|
||||
|
||||
interactive-wayland
|
||||
Interactive debugger for XKB keymaps for Wayland
|
||||
|
||||
interactive-x11
|
||||
Interactive debugger for XKB keymaps for X11
|
||||
|
||||
interactive-evdev
|
||||
Interactive debugger for XKB keymaps for evdev (Linux)
|
||||
|
||||
compile-keymap
|
||||
Compile an XKB keymap
|
||||
|
||||
how-to-type
|
||||
See separate entry below.
|
||||
|
||||
See the manpages for usage information.
|
||||
|
||||
Contributed by Peter Hutterer <@who-t.net>.
|
||||
|
||||
- Add `xkb_utf32_to_keysym()` to translate a Unicode codepoint to a keysym.
|
||||
When a special keysym (`XKB_KEY_` constant) for the codepoint exists, it is
|
||||
returned, otherwise the direct encoding is used, if permissible.
|
||||
|
||||
Contributed by Jaroslaw Kubik <@froglogic.com>.
|
||||
|
||||
- Add `xkb_keymap_key_get_mods_for_level()` which retrieves sets of modifiers
|
||||
which produce a given shift level in a given key+layout.
|
||||
|
||||
Contributed by Jaroslaw Kubik <@froglogic.com>.
|
||||
|
||||
- Add `xkbcli how-to-type` command, which, using `xkb_utf32_to_keysym()`
|
||||
and `xkb_keymap_key_get_mods_for_level()` and other APIs, prints out all
|
||||
the ways to produce a given keysym.
|
||||
|
||||
For example, how to type `?` (codepoint 63) in a us,de keymap?
|
||||
|
||||
$ xkbcli how-to-type --layout us,de 63 | column -ts $'\t'
|
||||
keysym: question (0x3f)
|
||||
KEYCODE KEY NAME LAYOUT# LAYOUT NAME LEVEL# MODIFIERS
|
||||
20 AE11 2 German 2 [ Shift ]
|
||||
20 AE11 2 German 2 [ Shift Lock ]
|
||||
61 AB10 1 English (US) 2 [ Shift ]
|
||||
|
||||
- Add a new section to the documentation describing the format of the XKB
|
||||
rules file.
|
||||
|
||||
- Search for Compose in $XDG_CONFIG_HOME/XCompose (fallback to
|
||||
~/.config/XCompose) before trying $HOME/.XCompose.
|
||||
|
||||
Note that libX11 still only searches in $HOME/.XCompose.
|
||||
|
||||
Contributed by Emmanuel Gil Peyrot <@linkmauve.fr>.
|
||||
|
||||
- Bump meson requirement to >= 0.49.0.
|
||||
|
||||
- Fix build with byacc.
|
||||
|
||||
- Fix building X11 tests on PE targets.
|
||||
|
||||
Contributed by Jon Turney <@dronecode.org.uk>
|
||||
|
||||
- The tests no longer rely on bash, only Python (which is already used by
|
||||
meson).
|
||||
|
||||
- New API:
|
||||
xkb_utf32_to_keysym
|
||||
xkb_keymap_key_get_mods_for_level
|
||||
XKB_KEY_XF86FullScreen
|
||||
|
||||
|
||||
libxkbcommon 0.10.0 - 2020-01-18
|
||||
===================
|
||||
|
||||
- (security) Fix quadratic complexity in the XKB file parser. See commit
|
||||
message 7c42945e04a2107827a057245298dedc0475cc88 for details.
|
||||
|
||||
- Add $XDG_CONFIG_HOME/xkb to the default search path. If $XDG_CONFIG_HOME
|
||||
is not set, $HOME/.config/xkb is used. If $HOME is not set, the path is not
|
||||
added.
|
||||
|
||||
The XDG path is looked up before the existing default search path $HOME/.xkb.
|
||||
|
||||
Contributed by Peter Hutterer <@who-t.net>.
|
||||
|
||||
- Add support for include statements in XKB rules files.
|
||||
|
||||
This is a step towards making local XKB customizations more tenable and
|
||||
convenient, without modifying system files.
|
||||
|
||||
You can now include other rules files like this:
|
||||
|
||||
! include %S/evdev
|
||||
|
||||
Two directives are supported, %H to $HOME and %S for the system-installed
|
||||
rules directory (usually /usr/share/X11/xkb/rules).
|
||||
|
||||
See commit message ca033a29d2ca910fd17b1ae287cb420205bdddc8 and
|
||||
doc/rules-format.txt in the xkbcommon source code for more information.
|
||||
|
||||
Contributed by Peter Hutterer <@who-t.net>.
|
||||
|
||||
- Downgrade "Symbol added to modifier map for multiple modifiers" log to a
|
||||
warning.
|
||||
|
||||
This error message was too annoying to be shown by default. When working on
|
||||
keymaps, set `XKB_LOG_LEVEL=debug XKB_LOG_VERBOSITY=10` to see all possible
|
||||
messages.
|
||||
|
||||
- Support building on Windows using the meson MSVC backend.
|
||||
|
||||
Contributed by Adrian Perez de Castro <@igalia.com>.
|
||||
|
||||
- Fix bug where the merge mode only applied to the first vmod in a
|
||||
`virtual_modifiers` statement. Given
|
||||
|
||||
augment virtual_modifiers NumLock,Alt,LevelThree
|
||||
|
||||
Previously it was incorrectly treated as
|
||||
|
||||
augment virtual_modifiers NumLock;
|
||||
virtual_modifiers Alt;
|
||||
virtual_modifiers LevelThree;
|
||||
|
||||
Now it is treated as
|
||||
|
||||
augment virtual_modifiers NumLock;
|
||||
augment virtual_modifiers Alt;
|
||||
augment virtual_modifiers LevelThree;
|
||||
|
||||
- Reject interpret modifier predicate with more than one value. Given
|
||||
|
||||
interpret ISO_Level3_Shift+AnyOf(all,extraneous) { ... };
|
||||
|
||||
Previously, extraneous (and further) was ignored. Now it's rejected.
|
||||
|
||||
- Correctly handle capitalization of the ssharp keysym.
|
||||
|
||||
- Speed up and improve the internal `xkeyboard-config` tool. This tool
|
||||
compiles all layout/variant combinations in the xkeyboard-config dataset
|
||||
and reports any issues it finds.
|
||||
|
||||
Contributed by Peter Hutterer <@who-t.net>.
|
||||
|
||||
- Speed up "atoms" (string interning). This code goes back at least to X11R1
|
||||
(released 1987).
|
||||
|
||||
|
||||
libxkbcommon 0.9.1 - 2019-10-19
|
||||
==================
|
||||
|
||||
- Fix context creation failing when run in privileged processes as defined by
|
||||
`secure_getenv(3)`, e.g. GDM.
|
||||
|
||||
|
||||
libxkbcommon 0.9.0 - 2019-10-19
|
||||
==================
|
||||
|
||||
- Move ~/.xkb to before XKB_CONFIG_ROOT (the system XKB path, usually
|
||||
/usr/share/X11/xkb) in the default include path. This enables the user
|
||||
to have full control of the keymap definitions, instead of only augmenting
|
||||
them.
|
||||
|
||||
- Remove the Autotools build system. Use the meson build system instead.
|
||||
|
||||
- Fix invalid names used for levels above 8 when dumping keymaps. Previously,
|
||||
e.g. "Level20" was dumped, but only up to "Level8" is accepted by the
|
||||
parser. Now "20" is dumped.
|
||||
|
||||
- Change level references to always be dumped as e.g. "5" instead of "Level5".
|
||||
|
||||
Change group references to always be dumped capitalized e.g. "Group3" instead
|
||||
of "group3". Previously it was inconsistent.
|
||||
|
||||
These changes affect the output of xkb_keymap_get_as_string().
|
||||
|
||||
- Fix several build issues on macOS/Darwin, Solaris, NetBSD, cross compilation.
|
||||
|
||||
- Port the interactive-wayland test program to the stable version of xdg-shell.
|
||||
|
||||
|
||||
libxkbcommon 0.8.4 - 2019-02-22
|
||||
==================
|
||||
|
||||
- Fix build of xkbcommon-x11 static library with meson.
|
||||
|
||||
- Fix building using meson from the tarball generated by autotools.
|
||||
|
||||
|
||||
libxkbcommon 0.8.3 - 2019-02-08
|
||||
==================
|
||||
|
||||
- Fix build of static libraries with meson.
|
||||
(Future note: xkbcommon-x11 was *not* fixed in this release.)
|
||||
|
||||
- New API:
|
||||
XKB_KEY_XF86MonBrightnessCycle
|
||||
XKB_KEY_XF86RotationLockToggle
|
||||
|
||||
|
||||
libxkbcommon 0.8.2 - 2018-08-05
|
||||
==================
|
||||
|
||||
- Fix various problems found with fuzzing (see commit messages for
|
||||
more details):
|
||||
|
||||
- Fix a few NULL-dereferences, out-of-bounds access and undefined behavior
|
||||
in the XKB text format parser.
|
||||
|
||||
|
||||
libxkbcommon 0.8.1 - 2018-08-03
|
||||
==================
|
||||
|
||||
- Fix various problems found in the meson build (see commit messages for more
|
||||
details):
|
||||
|
||||
- Fix compilation on Darwin.
|
||||
|
||||
- Fix compilation of the x11 tests and demos when XCB is installed in a
|
||||
non-standard location.
|
||||
|
||||
- Fix xkbcommon-x11.pc missing the Requires specification.
|
||||
|
||||
- Fix various problems found with fuzzing and Coverity (see commit messages for
|
||||
more details):
|
||||
|
||||
- Fix stack overflow in the XKB text format parser when evaluating boolean
|
||||
negation.
|
||||
|
||||
- Fix NULL-dereferences in the XKB text format parser when some unsupported
|
||||
tokens appear (the tokens are still parsed for backward compatibility).
|
||||
|
||||
- Fix NULL-dereference in the XKB text format parser when parsing an
|
||||
xkb_geometry section.
|
||||
|
||||
- Fix an infinite loop in the Compose text format parser on some inputs.
|
||||
|
||||
- Fix an invalid free() when using multiple keysyms.
|
||||
|
||||
- Replace the Unicode characters for the leftanglebracket and rightanglebracket
|
||||
keysyms from the deprecated LEFT/RIGHT-POINTING ANGLE BRACKET to
|
||||
MATHEMATICAL LEFT/RIGHT ANGLE BRACKET.
|
||||
|
||||
- Reject out-of-range Unicode codepoints in xkb_keysym_to_utf8 and
|
||||
xkb_keysym_to_utf32.
|
||||
|
||||
|
||||
libxkbcommon 0.8.0 - 2017-12-15
|
||||
==================
|
||||
|
||||
- Added xkb_keysym_to_{upper,lower} to perform case-conversion directly on
|
||||
keysyms. This is useful in some odd cases, but working with the Unicode
|
||||
representations should be preferred when possible.
|
||||
|
||||
- Added Unicode conversion rules for the signifblank and permille keysyms.
|
||||
|
||||
- Fixed a bug in the parsing of XKB key type definitions where the number
|
||||
of levels were determined by the number of level *names*. Keymaps which
|
||||
omit level names were hence miscompiled.
|
||||
|
||||
This regressed in version 0.4.3. Keymaps from xkeyboard-config were not
|
||||
affected since they don't omit level names.
|
||||
|
||||
- New API:
|
||||
xkb_keysym_to_upper()
|
||||
xkb_keysym_to_lower()
|
||||
|
||||
|
||||
libxkbcommon 0.7.2 - 2017-08-04
|
||||
==================
|
||||
|
||||
- Added a Meson build system as an alternative to existing autotools build
|
||||
system.
|
||||
|
||||
The intent is to remove the autotools build in one of the next releases.
|
||||
Please try to convert to it and report any problems.
|
||||
|
||||
See http://mesonbuild.com/Quick-guide.html for basic usage, the
|
||||
meson_options.txt for the project-specific configuration options,
|
||||
and the PACKAGING file for more details.
|
||||
|
||||
There are some noteworthy differences compared to the autotools build:
|
||||
|
||||
- Feature auto-detection is not performed. By default, all features are
|
||||
enabled (currently: docs, x11, wayland). The build fails if any of
|
||||
the required dependencies are not available. To disable a feature,
|
||||
pass -Denable-<feature>=false to meson.
|
||||
|
||||
- The libraries are either installed as shared or static, as specified
|
||||
by the -Ddefault_library=shared/static option. With autotools, both
|
||||
versions are installed by default.
|
||||
|
||||
- xorg-util-macros is not used.
|
||||
|
||||
- A parser generator (bison/byacc) is always required - there is no
|
||||
fallback to pre-generated output bundled in the tarball, as there is
|
||||
in autotools.
|
||||
|
||||
- Removed Android.mk support.
|
||||
|
||||
- Removed the *-uninstalled.pc pkgconfig files.
|
||||
|
||||
- Ported the interactive-wayland demo program to v6 of the xdg-shell
|
||||
protocol.
|
||||
|
||||
- Added new keysym definitions from xproto.
|
||||
|
||||
- New API:
|
||||
XKB_KEY_XF86Keyboard
|
||||
XKB_KEY_XF86WWAN
|
||||
XKB_KEY_XF86RFKill
|
||||
XKB_KEY_XF86AudioPreset
|
||||
|
||||
|
||||
libxkbcommon 0.7.1 - 2017-01-18
|
||||
==================
|
||||
|
||||
- Fixed various reported problems when the current locale is tr_TR.UTF-8.
|
||||
|
||||
The function xkb_keysym_from_name() used to perform case-insensitive
|
||||
string comparisons in a locale-dependent way, but required it to to
|
||||
work as in the C/ASCII locale (the so called "Turkish i problem").
|
||||
|
||||
The function is now no longer affected by the current locale.
|
||||
|
||||
- Fixed compilation in NetBSD.
|
||||
|
||||
|
||||
libxkbcommon 0.7.0 - 2016-11-11
|
||||
==================
|
||||
|
||||
- Added support for different "modes" of calculating consumed modifiers.
|
||||
The existing mode, based on the XKB standard, has proven to be
|
||||
unintuitive in various shortcut implementations.
|
||||
|
||||
A new mode, based on the calculation used by the GTK toolkit, is added.
|
||||
This mode is less eager to declare a modifier as consumed.
|
||||
|
||||
- Added a new interactive demo program using the Wayland protocol.
|
||||
See the PACKAGING file for the new (optional) test dependencies.
|
||||
|
||||
- Fixed a compilation error on GNU Hurd.
|
||||
|
||||
- New API:
|
||||
enum xkb_consumed_mode
|
||||
XKB_CONSUMED_MODE_XKB
|
||||
XKB_CONSUMED_MODE_GTK
|
||||
xkb_state_key_get_consumed_mods2
|
||||
xkb_state_mod_index_is_consumed2
|
||||
|
||||
|
||||
libxkbcommon 0.6.1 - 2016-04-08
|
||||
==================
|
||||
|
||||
- Added LICENSE to distributed files in tarball releases.
|
||||
|
||||
- Minor typo fix in xkb_keymap_get_as_string() documentation.
|
||||
|
||||
|
||||
libxkbcommon 0.6.0 - 2016-03-16
|
||||
==================
|
||||
|
||||
- If the XKB_CONFIG_ROOT environment variable is set, it is used as the XKB
|
||||
configuration root instead of the path determined at build time.
|
||||
|
||||
- Tests and benchmarks now build correctly on OSX.
|
||||
|
||||
- An XKB keymap provides a name for each key it defines. Traditionally,
|
||||
these names are limited to at most 4 characters, and are thus somewhat
|
||||
obscure, but might still be useful (xkbcommon lifts the 4 character limit).
|
||||
|
||||
The new functions xkb_keymap_key_get_name() and xkb_keymap_key_by_name()
|
||||
can be used to get the name of a key or find a key by name. Note that
|
||||
a key may have aliases.
|
||||
|
||||
- Documentation improvements.
|
||||
|
||||
- New API:
|
||||
xkb_keymap_key_by_name()
|
||||
xkb_keymap_key_get_name()
|
||||
|
||||
|
||||
libxkbcommon 0.5.0 - 2014-10-18
|
||||
==================
|
||||
|
||||
|
@ -42,6 +589,7 @@ libxkbcommon 0.5.0 - 2014-10-18
|
|||
XKB_COMPOSE_*
|
||||
xkb_compose_*
|
||||
|
||||
|
||||
libxkbcommon 0.4.3 - 2014-08-19
|
||||
==================
|
||||
|
||||
|
@ -65,6 +613,7 @@ libxkbcommon 0.4.3 - 2014-08-19
|
|||
- Fixed memory leaks after parse errors in the XKB yacc parser.
|
||||
The fix required changes which are currently incompatible with byacc.
|
||||
|
||||
|
||||
libxkbcommon 0.4.2 - 2014-05-15
|
||||
==================
|
||||
|
||||
|
@ -87,6 +636,7 @@ libxkbcommon 0.4.2 - 2014-05-15
|
|||
Note: it seems impossible to trigger in the current code since the input
|
||||
size cannot exceed the required size.
|
||||
|
||||
|
||||
libxkbcommon 0.4.1 - 2014-03-27
|
||||
==================
|
||||
|
||||
|
@ -104,7 +654,7 @@ libxkbcommon 0.4.1 - 2014-03-27
|
|||
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://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier
|
||||
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=75892
|
||||
|
||||
|
@ -130,6 +680,7 @@ libxkbcommon 0.4.1 - 2014-03-27
|
|||
|
||||
- Bug fixes.
|
||||
|
||||
|
||||
libxkbcommon 0.4.0 - 2014-02-02
|
||||
==================
|
||||
|
||||
|
@ -166,7 +717,7 @@ libxkbcommon 0.3.2 - 2013-11-22
|
|||
- Apply capitalization transformation on keysyms in
|
||||
xkb_keysym_get_one_sym(), to match the behavior specified in the XKB
|
||||
specification:
|
||||
http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier
|
||||
https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier
|
||||
|
||||
- Support byacc for generating the parser, in addition to Bison.
|
||||
|
||||
|
|
|
@ -1,26 +1,30 @@
|
|||
libxkbcommon consists of two shared libraries, libxkbcommon (the main
|
||||
library) and libxkbcommon-x11 (an addon library for XCB clients).
|
||||
libxkbcommon consists of three shared libraries, libxkbcommon (the main
|
||||
library), libxkbcommon-x11 (an addon library for XCB clients) and libxkbregistry
|
||||
(a library to list available RMLVO options).
|
||||
|
||||
The files for libxkbcommon-x11 are:
|
||||
libxkbcommon-x11.a libxkbcommon.so* xkbcommon/xkbcommon-x11.h
|
||||
libxkbcommon-x11.a libxkbcommon-x11.so* xkbcommon/xkbcommon-x11.h
|
||||
xkbcommon-x11.map xkbcommon-x11.pc
|
||||
|
||||
libxkbcommon-x11 can be disabled with --disable-x11 (see
|
||||
`./configure --help` for other options/variables).
|
||||
libxkbcommon-x11 can be disabled with -Denable-x11=false (see
|
||||
`meson configure build` for other options/variables).
|
||||
|
||||
The files for libxkbregistry are:
|
||||
libxkbregistry.a libxkbregistry.so* xkbcommon/xkbregistry.h
|
||||
xkbregistry.map xkbregistry.pc
|
||||
|
||||
libxkbregistry can be disabled with -Denable-xkbregistry=false (see
|
||||
`meson configure build` for other options/variables).
|
||||
|
||||
Dependencies for libxkbcommon:
|
||||
- C compiler, autoconf, automake, pkg-config, libc, etc.
|
||||
- C compiler, meson, pkg-config, libc.
|
||||
|
||||
- (build optional) xorg-util-macros.
|
||||
Output included in tarball.
|
||||
|
||||
- (build optional) bison (preferred) or byacc>=20141006.
|
||||
Output included in tarball.
|
||||
- (build) bison (preferred), win_bison or byacc>=20141006.
|
||||
byacc must be configured with --enable-btyacc.
|
||||
|
||||
- (build optional, runtime) xkeyboard-config.
|
||||
- (build optional, runtime required) xkeyboard-config.
|
||||
During build, for automatically detecting the value of
|
||||
--with-xkb-config-root instead of guessing (/usr/share/X11/xkb).
|
||||
-Dxkb-config-root instead of guessing (/usr/share/X11/xkb).
|
||||
During runtime, not strictly needed, but most users of the library
|
||||
would need it.
|
||||
|
||||
|
@ -30,10 +34,14 @@ Dependencies for libxkbcommon:
|
|||
|
||||
- (build optional) doxygen.
|
||||
For generating the HTML documentation.
|
||||
To disable, use -Denable-docs=false.
|
||||
|
||||
- (build optional) gperf.
|
||||
Output included in git and tarball. To regenerate, use
|
||||
`make update-keywords`.
|
||||
`./scripts/update-keywords`.
|
||||
|
||||
Dependencies for xkbcli:
|
||||
- libxkbcommon.
|
||||
|
||||
Dependencies for libxkbcommon-x11:
|
||||
- libxkbcommon.
|
||||
|
@ -44,7 +52,25 @@ Dependencies for libxkbcommon-x11 tests:
|
|||
- xkbcomp, Xvfb.
|
||||
If they are not available, the relevant tests are skipped.
|
||||
|
||||
Dependencies for libxkbregistry:
|
||||
- libxkbregistry is a sublibrary of libxkbcommon and cannot be built without
|
||||
building libxbkcommon. The files produced are otherwise independent.
|
||||
|
||||
- libxml2
|
||||
|
||||
- (build optional, runtime requirement) xkeyboard-config
|
||||
During build, for automatically detecting the value of
|
||||
-Dxkb-config-root instead of guessing (/usr/share/X11/xkb).
|
||||
|
||||
Dependencies for Wayland tests:
|
||||
- wayland-client>=1.2.0, wayland-scanner, wayland-protocols>=1.0.
|
||||
To disable, use -Denable-wayland=false.
|
||||
|
||||
Unless libxcb is always available as part of the system, it is preferred
|
||||
that libxkbcommon and libxkbcommon-x11 be split into separate packages,
|
||||
such that the main library does not depend on libxcb. This avoids a
|
||||
transitive dependency of Wayland clients on X libraries.
|
||||
|
||||
It is perferred that libxkbregistry be split into a separate packages as most
|
||||
clients that require libxkbcommon do not require libxkbregistry and clients
|
||||
requiring libxkbregistry may not need libxkbcommon.
|
||||
|
|
|
@ -3,19 +3,35 @@
|
|||
libxkbcommon is a keyboard keymap compiler and support library which
|
||||
processes a reduced subset of keymaps as defined by the XKB (X Keyboard
|
||||
Extension) specification. It also contains a module for handling Compose
|
||||
and dead keys.
|
||||
and dead keys and a separate library for listing available keyboard layouts.
|
||||
|
||||
## Quick Guide
|
||||
|
||||
See [Quick Guide](doc/quick-guide.md).
|
||||
|
||||
## Building
|
||||
|
||||
libxkbcommon is built with [Meson](http://mesonbuild.com/):
|
||||
|
||||
meson setup build
|
||||
ninja -C build
|
||||
|
||||
To build for use with Wayland, you can disable X11 support while still
|
||||
using the X11 keyboard configuration resource files thusly:
|
||||
|
||||
meson setup build \
|
||||
-Denable-x11=false \
|
||||
-Dxkb-config-root=/usr/share/X11/xkb \
|
||||
-Dx-locale-root=/usr/share/X11/locale
|
||||
ninja -C build
|
||||
|
||||
## API
|
||||
|
||||
While libxkbcommon'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.
|
||||
|
||||
See the [API Documentation](http://xkbcommon.org/doc/current/modules.html).
|
||||
See the [API Documentation](https://xkbcommon.org/doc/current/modules.html).
|
||||
|
||||
## Dataset
|
||||
|
||||
|
@ -23,7 +39,7 @@ libxkbcommon does not distribute a keymap dataset itself, other than for
|
|||
testing purposes. The most common dataset is xkeyboard-config, which is 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
|
||||
https://www.freedesktop.org/wiki/Software/XKeyboardConfig
|
||||
|
||||
The dataset for Compose is distributed in libX11, as part of the X locale
|
||||
data.
|
||||
|
@ -35,23 +51,21 @@ See [Compatibility](doc/compat.md) notes.
|
|||
## Development
|
||||
|
||||
An extremely rudimentary homepage can be found at
|
||||
http://xkbcommon.org
|
||||
https://xkbcommon.org
|
||||
|
||||
xkbcommon is maintained in git at
|
||||
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>
|
||||
or through github.
|
||||
or in a [GitHub](https://github.com/xkbcommon/libxkbcommon) pull request.
|
||||
|
||||
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
|
||||
Bug reports (and usage questions) are also welcome, and may be filed at
|
||||
[GitHub](https://github.com/xkbcommon/libxkbcommon/issues).
|
||||
|
||||
The maintainers are
|
||||
- Daniel Stone <daniel@fooishbar.org>
|
||||
- Ran Benita <ran234@gmail.com>
|
||||
- Ran Benita <ran@unusedvar.com>
|
||||
|
||||
## Credits
|
||||
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
srcdir=`dirname "$0"`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
ORIGDIR=`pwd`
|
||||
cd "$srcdir"
|
||||
|
||||
autoreconf --verbose --install --force --warnings=all
|
||||
cd "$ORIGDIR"
|
||||
|
||||
if test -z "$NOCONFIGURE"; then
|
||||
exec "$srcdir/configure" "$@"
|
||||
fi
|
|
@ -1,4 +0,0 @@
|
|||
key-proc
|
||||
rules
|
||||
rulescomp
|
||||
compose
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright © 2021 Ran Benita <ran@unusedvar.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "atom.h"
|
||||
#include "bench.h"
|
||||
#include "darray.h"
|
||||
|
||||
#define BENCHMARK_ITERATIONS 100
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
FILE *file;
|
||||
char wordbuf[1024];
|
||||
darray(char *) words;
|
||||
char **worditer;
|
||||
struct atom_table *table;
|
||||
xkb_atom_t atom;
|
||||
const char *text;
|
||||
struct bench bench;
|
||||
char *elapsed;
|
||||
|
||||
darray_init(words);
|
||||
file = fopen("/usr/share/dict/words", "rb");
|
||||
if (file == NULL) {
|
||||
perror("/usr/share/dict/words");
|
||||
return -1;
|
||||
}
|
||||
while (fgets(wordbuf, sizeof(wordbuf), file)) {
|
||||
size_t len = strlen(wordbuf);
|
||||
if (len > 0 && wordbuf[len - 1] == '\n')
|
||||
wordbuf[len - 1] = '\0';
|
||||
darray_append(words, strdup(wordbuf));
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
bench_start(&bench);
|
||||
for (int i = 0; i < BENCHMARK_ITERATIONS; i++) {
|
||||
table = atom_table_new();
|
||||
assert(table);
|
||||
|
||||
darray_foreach(worditer, words) {
|
||||
atom = atom_intern(table, *worditer, strlen(*worditer) - 1, true);
|
||||
assert(atom != XKB_ATOM_NONE);
|
||||
|
||||
text = atom_text(table, atom);
|
||||
assert(text != NULL);
|
||||
}
|
||||
|
||||
atom_table_free(table);
|
||||
}
|
||||
bench_stop(&bench);
|
||||
|
||||
elapsed = bench_elapsed_str(&bench);
|
||||
fprintf(stderr, "%d iterations in %ss\n",
|
||||
BENCHMARK_ITERATIONS, elapsed);
|
||||
free(elapsed);
|
||||
|
||||
darray_foreach(worditer, words) {
|
||||
free(*worditer);
|
||||
}
|
||||
darray_free(words);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright © 2015 Kazunobu Kuriyama <kazunobu.kuriyama@nifty.com>
|
||||
* Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bench.h"
|
||||
#include "../src/utils.h"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct timeval {
|
||||
long tv_sec, tv_usec;
|
||||
};
|
||||
|
||||
static int
|
||||
gettimeofday(struct timeval *tv, void *unused)
|
||||
{
|
||||
static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
|
||||
|
||||
SYSTEMTIME system_time;
|
||||
FILETIME file_time;
|
||||
uint64_t t;
|
||||
|
||||
GetSystemTime(&system_time);
|
||||
SystemTimeToFileTime(&system_time, &file_time);
|
||||
t = (uint64_t) file_time.dwLowDateTime;
|
||||
t += ((uint64_t) file_time.dwHighDateTime) << 32;
|
||||
|
||||
tv->tv_sec = (long) ((t - EPOCH) / 10000000L);
|
||||
tv->tv_usec = (long) (system_time.wMilliseconds * 1000);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
bench_start(struct bench *bench)
|
||||
{
|
||||
struct timeval val;
|
||||
(void) gettimeofday(&val, NULL);
|
||||
bench->start = (struct bench_time) {
|
||||
.seconds = val.tv_sec,
|
||||
.microseconds = val.tv_usec,
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
bench_stop(struct bench *bench)
|
||||
{
|
||||
struct timeval val;
|
||||
(void) gettimeofday(&val, NULL);
|
||||
bench->stop = (struct bench_time) {
|
||||
.seconds = val.tv_sec,
|
||||
.microseconds = val.tv_usec,
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
bench_elapsed(const struct bench *bench, struct bench_time *result)
|
||||
{
|
||||
result->seconds = bench->stop.seconds - bench->start.seconds;
|
||||
result->microseconds = bench->stop.microseconds - bench->start.microseconds;
|
||||
if (result->microseconds < 0) {
|
||||
result->microseconds += 1000000;
|
||||
result->seconds--;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
bench_elapsed_str(const struct bench *bench)
|
||||
{
|
||||
struct bench_time elapsed;
|
||||
char *buf;
|
||||
int ret;
|
||||
|
||||
bench_elapsed(bench, &elapsed);
|
||||
ret = asprintf(&buf, "%ld.%06ld", elapsed.seconds, elapsed.microseconds);
|
||||
assert(ret >= 0);
|
||||
|
||||
return buf;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright © 2015 Kazunobu Kuriyama <kazunobu.kuriyama@nifty.com>
|
||||
* Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIBXKBCOMMON_BENCH_H
|
||||
#define LIBXKBCOMMON_BENCH_H
|
||||
|
||||
struct bench_time {
|
||||
long seconds;
|
||||
long microseconds;
|
||||
};
|
||||
|
||||
struct bench {
|
||||
struct bench_time start;
|
||||
struct bench_time stop;
|
||||
};
|
||||
|
||||
void
|
||||
bench_start(struct bench *bench);
|
||||
void
|
||||
bench_stop(struct bench *bench);
|
||||
|
||||
void
|
||||
bench_elapsed(const struct bench *bench, struct bench_time *result);
|
||||
/* The caller is responsibile to free() the returned string. */
|
||||
char *
|
||||
bench_elapsed_str(const struct bench *bench);
|
||||
|
||||
#endif /* LIBXKBCOMMON_BENCH_H */
|
|
@ -21,11 +21,14 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "xkbcommon/xkbcommon-compose.h"
|
||||
|
||||
#include "../test/test.h"
|
||||
#include "bench.h"
|
||||
|
||||
#define BENCHMARK_ITERATIONS 1000
|
||||
|
||||
|
@ -33,21 +36,28 @@ int
|
|||
main(void)
|
||||
{
|
||||
struct xkb_context *ctx;
|
||||
struct timespec start, stop, elapsed;
|
||||
char *path;
|
||||
FILE *file;
|
||||
struct xkb_compose_table *table;
|
||||
struct bench bench;
|
||||
char *elapsed;
|
||||
|
||||
ctx = test_get_context(CONTEXT_NO_FLAG);
|
||||
assert(ctx);
|
||||
|
||||
path = test_get_path("compose/en_US.UTF-8/Compose");
|
||||
file = fopen(path, "r");
|
||||
path = test_get_path("locale/en_US.UTF-8/Compose");
|
||||
file = fopen(path, "rb");
|
||||
if (file == NULL) {
|
||||
perror(path);
|
||||
free(path);
|
||||
xkb_context_unref(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_CRITICAL);
|
||||
xkb_context_set_log_verbosity(ctx, 0);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
bench_start(&bench);
|
||||
for (int i = 0; i < BENCHMARK_ITERATIONS; i++) {
|
||||
rewind(file);
|
||||
table = xkb_compose_table_new_from_file(ctx, file, "",
|
||||
|
@ -56,20 +66,15 @@ main(void)
|
|||
assert(table);
|
||||
xkb_compose_table_unref(table);
|
||||
}
|
||||
clock_gettime(CLOCK_MONOTONIC, &stop);
|
||||
bench_stop(&bench);
|
||||
|
||||
fclose(file);
|
||||
free(path);
|
||||
|
||||
elapsed.tv_sec = stop.tv_sec - start.tv_sec;
|
||||
elapsed.tv_nsec = stop.tv_nsec - start.tv_nsec;
|
||||
if (elapsed.tv_nsec < 0) {
|
||||
elapsed.tv_nsec += 1000000000;
|
||||
elapsed.tv_sec--;
|
||||
}
|
||||
|
||||
fprintf(stderr, "compiled %d compose tables in %ld.%09lds\n",
|
||||
BENCHMARK_ITERATIONS, elapsed.tv_sec, elapsed.tv_nsec);
|
||||
elapsed = bench_elapsed_str(&bench);
|
||||
fprintf(stderr, "compiled %d compose tables in %ss\n",
|
||||
BENCHMARK_ITERATIONS, elapsed);
|
||||
free(elapsed);
|
||||
|
||||
xkb_context_unref(ctx);
|
||||
return 0;
|
||||
|
|
|
@ -21,15 +21,18 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "../test/test.h"
|
||||
#include "bench.h"
|
||||
|
||||
#define BENCHMARK_ITERATIONS 20000000
|
||||
|
||||
static void
|
||||
bench(struct xkb_state *state)
|
||||
bench_key_proc(struct xkb_state *state)
|
||||
{
|
||||
int8_t keys[256] = { 0 };
|
||||
xkb_keycode_t keycode;
|
||||
|
@ -56,7 +59,8 @@ main(void)
|
|||
struct xkb_context *ctx;
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_state *state;
|
||||
struct timespec start, stop, elapsed;
|
||||
struct bench bench;
|
||||
char *elapsed;
|
||||
|
||||
ctx = test_get_context(0);
|
||||
assert(ctx);
|
||||
|
@ -71,21 +75,16 @@ main(void)
|
|||
xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_CRITICAL);
|
||||
xkb_context_set_log_verbosity(ctx, 0);
|
||||
|
||||
srand(time(NULL));
|
||||
srand((unsigned) time(NULL));
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
bench(state);
|
||||
clock_gettime(CLOCK_MONOTONIC, &stop);
|
||||
bench_start(&bench);
|
||||
bench_key_proc(state);
|
||||
bench_stop(&bench);
|
||||
|
||||
elapsed.tv_sec = stop.tv_sec - start.tv_sec;
|
||||
elapsed.tv_nsec = stop.tv_nsec - start.tv_nsec;
|
||||
if (elapsed.tv_nsec < 0) {
|
||||
elapsed.tv_nsec += 1000000000;
|
||||
elapsed.tv_sec--;
|
||||
}
|
||||
|
||||
fprintf(stderr, "ran %d iterations in %ld.%09lds\n",
|
||||
BENCHMARK_ITERATIONS, elapsed.tv_sec, elapsed.tv_nsec);
|
||||
elapsed = bench_elapsed_str(&bench);
|
||||
fprintf(stderr, "ran %d iterations in %ss\n",
|
||||
BENCHMARK_ITERATIONS, elapsed);
|
||||
free(elapsed);
|
||||
|
||||
xkb_state_unref(state);
|
||||
xkb_keymap_unref(keymap);
|
||||
|
|
|
@ -21,11 +21,14 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "../test/test.h"
|
||||
#include "xkbcomp-priv.h"
|
||||
#include "rules.h"
|
||||
#include "xkbcomp/xkbcomp-priv.h"
|
||||
#include "xkbcomp/rules.h"
|
||||
#include "bench.h"
|
||||
|
||||
#define BENCHMARK_ITERATIONS 20000
|
||||
|
||||
|
@ -33,12 +36,12 @@ int
|
|||
main(int argc, char *argv[])
|
||||
{
|
||||
struct xkb_context *ctx;
|
||||
struct timespec start, stop, elapsed;
|
||||
int i;
|
||||
struct xkb_rule_names rmlvo = {
|
||||
"evdev", "pc105", "us,il", ",", "ctrl:nocaps,grp:menu_toggle",
|
||||
};
|
||||
struct xkb_component_names kccgst;
|
||||
struct bench bench;
|
||||
char *elapsed;
|
||||
|
||||
ctx = test_get_context(0);
|
||||
assert(ctx);
|
||||
|
@ -46,25 +49,22 @@ main(int argc, char *argv[])
|
|||
xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_CRITICAL);
|
||||
xkb_context_set_log_verbosity(ctx, 0);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
bench_start(&bench);
|
||||
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
|
||||
struct xkb_component_names kccgst;
|
||||
|
||||
assert(xkb_components_from_rules(ctx, &rmlvo, &kccgst));
|
||||
free(kccgst.keycodes);
|
||||
free(kccgst.types);
|
||||
free(kccgst.compat);
|
||||
free(kccgst.symbols);
|
||||
}
|
||||
clock_gettime(CLOCK_MONOTONIC, &stop);
|
||||
bench_stop(&bench);
|
||||
|
||||
elapsed.tv_sec = stop.tv_sec - start.tv_sec;
|
||||
elapsed.tv_nsec = stop.tv_nsec - start.tv_nsec;
|
||||
if (elapsed.tv_nsec < 0) {
|
||||
elapsed.tv_nsec += 1000000000;
|
||||
elapsed.tv_sec--;
|
||||
}
|
||||
|
||||
fprintf(stderr, "processed %d rule files in %ld.%09lds\n",
|
||||
BENCHMARK_ITERATIONS, elapsed.tv_sec, elapsed.tv_nsec);
|
||||
elapsed = bench_elapsed_str(&bench);
|
||||
fprintf(stderr, "processed %d rule files in %ss\n",
|
||||
BENCHMARK_ITERATIONS, elapsed);
|
||||
free(elapsed);
|
||||
|
||||
xkb_context_unref(ctx);
|
||||
return 0;
|
||||
|
|
|
@ -21,18 +21,22 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "../test/test.h"
|
||||
#include "bench.h"
|
||||
|
||||
#define BENCHMARK_ITERATIONS 2500
|
||||
#define BENCHMARK_ITERATIONS 1000
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct xkb_context *ctx;
|
||||
struct xkb_keymap *keymap;
|
||||
struct timespec start, stop, elapsed;
|
||||
struct bench bench;
|
||||
char *elapsed;
|
||||
int i;
|
||||
|
||||
ctx = test_get_context(0);
|
||||
|
@ -41,23 +45,18 @@ main(int argc, char *argv[])
|
|||
xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_CRITICAL);
|
||||
xkb_context_set_log_verbosity(ctx, 0);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
bench_start(&bench);
|
||||
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
|
||||
keymap = test_compile_rules(ctx, "evdev", "evdev", "us", "", "");
|
||||
assert(keymap);
|
||||
xkb_keymap_unref(keymap);
|
||||
}
|
||||
clock_gettime(CLOCK_MONOTONIC, &stop);
|
||||
bench_stop(&bench);
|
||||
|
||||
elapsed.tv_sec = stop.tv_sec - start.tv_sec;
|
||||
elapsed.tv_nsec = stop.tv_nsec - start.tv_nsec;
|
||||
if (elapsed.tv_nsec < 0) {
|
||||
elapsed.tv_nsec += 1000000000;
|
||||
elapsed.tv_sec--;
|
||||
}
|
||||
|
||||
fprintf(stderr, "compiled %d keymaps in %ld.%09lds\n",
|
||||
BENCHMARK_ITERATIONS, elapsed.tv_sec, elapsed.tv_nsec);
|
||||
elapsed = bench_elapsed_str(&bench);
|
||||
fprintf(stderr, "compiled %d keymaps in %ss\n",
|
||||
BENCHMARK_ITERATIONS, elapsed);
|
||||
free(elapsed);
|
||||
|
||||
xkb_context_unref(ctx);
|
||||
return 0;
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright © 2020 Ran Benita <ran@unusedvar.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <xcb/xkb.h>
|
||||
|
||||
#include "xkbcommon/xkbcommon.h"
|
||||
#include "xkbcommon/xkbcommon-x11.h"
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
#define BENCHMARK_ITERATIONS 2500
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
int ret;
|
||||
xcb_connection_t *conn;
|
||||
int32_t device_id;
|
||||
struct xkb_context *ctx;
|
||||
struct bench bench;
|
||||
char *elapsed;
|
||||
|
||||
conn = xcb_connect(NULL, NULL);
|
||||
if (!conn || xcb_connection_has_error(conn)) {
|
||||
fprintf(stderr, "Couldn't connect to X server: error code %d\n",
|
||||
conn ? xcb_connection_has_error(conn) : -1);
|
||||
ret = -1;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
ret = xkb_x11_setup_xkb_extension(conn,
|
||||
XKB_X11_MIN_MAJOR_XKB_VERSION,
|
||||
XKB_X11_MIN_MINOR_XKB_VERSION,
|
||||
XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (!ret) {
|
||||
fprintf(stderr, "Couldn't setup XKB extension\n");
|
||||
goto err_conn;
|
||||
}
|
||||
|
||||
device_id = xkb_x11_get_core_keyboard_device_id(conn);
|
||||
if (device_id == -1) {
|
||||
ret = -1;
|
||||
fprintf(stderr, "Couldn't find core keyboard device\n");
|
||||
goto err_conn;
|
||||
}
|
||||
|
||||
ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (!ctx) {
|
||||
ret = -1;
|
||||
fprintf(stderr, "Couldn't create xkb context\n");
|
||||
goto err_conn;
|
||||
}
|
||||
|
||||
bench_start(&bench);
|
||||
for (int i = 0; i < BENCHMARK_ITERATIONS; i++) {
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_state *state;
|
||||
|
||||
keymap = xkb_x11_keymap_new_from_device(ctx, conn, device_id,
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
assert(keymap);
|
||||
|
||||
state = xkb_x11_state_new_from_device(keymap, conn, device_id);
|
||||
assert(state);
|
||||
|
||||
xkb_state_unref(state);
|
||||
xkb_keymap_unref(keymap);
|
||||
}
|
||||
bench_stop(&bench);
|
||||
ret = 0;
|
||||
|
||||
elapsed = bench_elapsed_str(&bench);
|
||||
fprintf(stderr, "retrieved %d keymaps from X in %ss\n",
|
||||
BENCHMARK_ITERATIONS, elapsed);
|
||||
free(elapsed);
|
||||
|
||||
xkb_context_unref(ctx);
|
||||
err_conn:
|
||||
xcb_disconnect(conn);
|
||||
err_out:
|
||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
|
@ -1,347 +0,0 @@
|
|||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand '-c -o'.
|
||||
|
||||
scriptversion=2012-10-14.11; # UTC
|
||||
|
||||
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
# We need space, tab and new line, in precisely that order. Quoting is
|
||||
# there to prevent tools from complaining about whitespace usage.
|
||||
IFS=" "" $nl"
|
||||
|
||||
file_conv=
|
||||
|
||||
# func_file_conv build_file lazy
|
||||
# Convert a $build file to $host form and store it in $file
|
||||
# Currently only supports Windows hosts. If the determined conversion
|
||||
# type is listed in (the comma separated) LAZY, no conversion will
|
||||
# take place.
|
||||
func_file_conv ()
|
||||
{
|
||||
file=$1
|
||||
case $file in
|
||||
/ | /[!/]*) # absolute file, and not a UNC file
|
||||
if test -z "$file_conv"; then
|
||||
# lazily determine how to convert abs files
|
||||
case `uname -s` in
|
||||
MINGW*)
|
||||
file_conv=mingw
|
||||
;;
|
||||
CYGWIN*)
|
||||
file_conv=cygwin
|
||||
;;
|
||||
*)
|
||||
file_conv=wine
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
case $file_conv/,$2, in
|
||||
*,$file_conv,*)
|
||||
;;
|
||||
mingw/*)
|
||||
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||
;;
|
||||
cygwin/*)
|
||||
file=`cygpath -m "$file" || echo "$file"`
|
||||
;;
|
||||
wine/*)
|
||||
file=`winepath -w "$file" || echo "$file"`
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# func_cl_dashL linkdir
|
||||
# Make cl look for libraries in LINKDIR
|
||||
func_cl_dashL ()
|
||||
{
|
||||
func_file_conv "$1"
|
||||
if test -z "$lib_path"; then
|
||||
lib_path=$file
|
||||
else
|
||||
lib_path="$lib_path;$file"
|
||||
fi
|
||||
linker_opts="$linker_opts -LIBPATH:$file"
|
||||
}
|
||||
|
||||
# func_cl_dashl library
|
||||
# Do a library search-path lookup for cl
|
||||
func_cl_dashl ()
|
||||
{
|
||||
lib=$1
|
||||
found=no
|
||||
save_IFS=$IFS
|
||||
IFS=';'
|
||||
for dir in $lib_path $LIB
|
||||
do
|
||||
IFS=$save_IFS
|
||||
if $shared && test -f "$dir/$lib.dll.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.dll.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/$lib.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/lib$lib.a"; then
|
||||
found=yes
|
||||
lib=$dir/lib$lib.a
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS=$save_IFS
|
||||
|
||||
if test "$found" != yes; then
|
||||
lib=$lib.lib
|
||||
fi
|
||||
}
|
||||
|
||||
# func_cl_wrapper cl arg...
|
||||
# Adjust compile command to suit cl
|
||||
func_cl_wrapper ()
|
||||
{
|
||||
# Assume a capable shell
|
||||
lib_path=
|
||||
shared=:
|
||||
linker_opts=
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.[oO][bB][jJ])
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fo"$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fe"$file"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-I)
|
||||
eat=1
|
||||
func_file_conv "$2" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-I*)
|
||||
func_file_conv "${1#-I}" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-l)
|
||||
eat=1
|
||||
func_cl_dashl "$2"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-l*)
|
||||
func_cl_dashl "${1#-l}"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-L)
|
||||
eat=1
|
||||
func_cl_dashL "$2"
|
||||
;;
|
||||
-L*)
|
||||
func_cl_dashL "${1#-L}"
|
||||
;;
|
||||
-static)
|
||||
shared=false
|
||||
;;
|
||||
-Wl,*)
|
||||
arg=${1#-Wl,}
|
||||
save_ifs="$IFS"; IFS=','
|
||||
for flag in $arg; do
|
||||
IFS="$save_ifs"
|
||||
linker_opts="$linker_opts $flag"
|
||||
done
|
||||
IFS="$save_ifs"
|
||||
;;
|
||||
-Xlinker)
|
||||
eat=1
|
||||
linker_opts="$linker_opts $2"
|
||||
;;
|
||||
-*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
|
||||
func_file_conv "$1"
|
||||
set x "$@" -Tp"$file"
|
||||
shift
|
||||
;;
|
||||
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
|
||||
func_file_conv "$1" mingw
|
||||
set x "$@" "$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
if test -n "$linker_opts"; then
|
||||
linker_opts="-link$linker_opts"
|
||||
fi
|
||||
exec "$@" $linker_opts
|
||||
exit 1
|
||||
}
|
||||
|
||||
eat=
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Wrapper for compilers which do not understand '-c -o'.
|
||||
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||
arguments, and rename the output as expected.
|
||||
|
||||
If you are trying to build a whole package this is not the
|
||||
right script to run: please start by reading the file 'INSTALL'.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "compile $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
|
||||
func_cl_wrapper "$@" # Doesn't return...
|
||||
;;
|
||||
esac
|
||||
|
||||
ofile=
|
||||
cfile=
|
||||
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
# So we strip '-o arg' only if arg is an object.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.obj)
|
||||
ofile=$2
|
||||
;;
|
||||
*)
|
||||
set x "$@" -o "$2"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*.c)
|
||||
cfile=$1
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$ofile" || test -z "$cfile"; then
|
||||
# If no '-o' option was seen then we might have been invoked from a
|
||||
# pattern rule where we don't need one. That is ok -- this is a
|
||||
# normal compilation that the losing compiler can handle. If no
|
||||
# '.c' file was seen then we are probably linking. That is also
|
||||
# ok.
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
# Name of file we expect compiler to create.
|
||||
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||
|
||||
# Create the lock directory.
|
||||
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
|
||||
# that we are using for the .o file. Also, base the name on the expected
|
||||
# object file name, since that is what matters with a parallel build.
|
||||
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||
while true; do
|
||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# FIXME: race condition here if user kills between mkdir and trap.
|
||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||
|
||||
# Run the compile.
|
||||
"$@"
|
||||
ret=$?
|
||||
|
||||
if test -f "$cofile"; then
|
||||
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||
elif test -f "${cofile}bj"; then
|
||||
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||
fi
|
||||
|
||||
rmdir "$lockdir"
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,791 +0,0 @@
|
|||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2013-05-30.07; # UTC
|
||||
|
||||
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||
as side-effects.
|
||||
|
||||
Environment variables:
|
||||
depmode Dependency tracking mode.
|
||||
source Source file read by 'PROGRAMS ARGS'.
|
||||
object Object file output by 'PROGRAMS ARGS'.
|
||||
DEPDIR directory where to store dependencies.
|
||||
depfile Dependency file to output.
|
||||
tmpdepfile Temporary file to use when outputting dependencies.
|
||||
libtool Whether libtool is used (yes/no).
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "depcomp $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
# Get the directory component of the given path, and save it in the
|
||||
# global variables '$dir'. Note that this directory component will
|
||||
# be either empty or ending with a '/' character. This is deliberate.
|
||||
set_dir_from ()
|
||||
{
|
||||
case $1 in
|
||||
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
|
||||
*) dir=;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Get the suffix-stripped basename of the given path, and save it the
|
||||
# global variable '$base'.
|
||||
set_base_from ()
|
||||
{
|
||||
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
|
||||
}
|
||||
|
||||
# If no dependency file was actually created by the compiler invocation,
|
||||
# we still have to create a dummy depfile, to avoid errors with the
|
||||
# Makefile "include basename.Plo" scheme.
|
||||
make_dummy_depfile ()
|
||||
{
|
||||
echo "#dummy" > "$depfile"
|
||||
}
|
||||
|
||||
# Factor out some common post-processing of the generated depfile.
|
||||
# Requires the auxiliary global variable '$tmpdepfile' to be set.
|
||||
aix_post_process_depfile ()
|
||||
{
|
||||
# If the compiler actually managed to produce a dependency file,
|
||||
# post-process it.
|
||||
if test -f "$tmpdepfile"; then
|
||||
# Each line is of the form 'foo.o: dependency.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# $object: dependency.h
|
||||
# and one to simply output
|
||||
# dependency.h:
|
||||
# which is needed to avoid the deleted-header problem.
|
||||
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
|
||||
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
|
||||
} > "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
}
|
||||
|
||||
# A tabulation character.
|
||||
tab=' '
|
||||
# A newline character.
|
||||
nl='
|
||||
'
|
||||
# Character ranges might be problematic outside the C locale.
|
||||
# These definitions help.
|
||||
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
lower=abcdefghijklmnopqrstuvwxyz
|
||||
digits=0123456789
|
||||
alpha=${upper}${lower}
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||
depfile=${depfile-`echo "$object" |
|
||||
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||
|
||||
rm -f "$tmpdepfile"
|
||||
|
||||
# Avoid interferences from the environment.
|
||||
gccflag= dashmflag=
|
||||
|
||||
# Some modes work just like other modes, but use different flags. We
|
||||
# parameterize here, but still list the modes in the big case below,
|
||||
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||
# here, because this file can only contain one case statement.
|
||||
if test "$depmode" = hp; then
|
||||
# HP compiler uses -M and no extra arg.
|
||||
gccflag=-M
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
if test "$depmode" = dashXmstdout; then
|
||||
# This is just like dashmstdout with a different argument.
|
||||
dashmflag=-xM
|
||||
depmode=dashmstdout
|
||||
fi
|
||||
|
||||
cygpath_u="cygpath -u -f -"
|
||||
if test "$depmode" = msvcmsys; then
|
||||
# This is just like msvisualcpp but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u='sed s,\\\\,/,g'
|
||||
depmode=msvisualcpp
|
||||
fi
|
||||
|
||||
if test "$depmode" = msvc7msys; then
|
||||
# This is just like msvc7 but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u='sed s,\\\\,/,g'
|
||||
depmode=msvc7
|
||||
fi
|
||||
|
||||
if test "$depmode" = xlc; then
|
||||
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
|
||||
gccflag=-qmakedep=gcc,-MF
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||
## the command line argument order; so add the flags where they
|
||||
## appear in depend2.am. Note that the slowdown incurred here
|
||||
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||
*) set fnord "$@" "$arg" ;;
|
||||
esac
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
done
|
||||
"$@"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
mv "$tmpdepfile" "$depfile"
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
|
||||
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
|
||||
## (see the conditional assignment to $gccflag above).
|
||||
## There are various ways to get dependency output from gcc. Here's
|
||||
## why we pick this rather obscure method:
|
||||
## - Don't want to use -MD because we'd like the dependencies to end
|
||||
## up in a subdir. Having to rename by hand is ugly.
|
||||
## (We might end up doing this anyway to support other compilers.)
|
||||
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||
## -MM, not -M (despite what the docs say). Also, it might not be
|
||||
## supported by the other compilers which use the 'gcc' depmode.
|
||||
## - Using -M directly means running the compiler twice (even worse
|
||||
## than renaming).
|
||||
if test -z "$gccflag"; then
|
||||
gccflag=-MD,
|
||||
fi
|
||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
# The second -e expression handles DOS-style file names with drive
|
||||
# letters.
|
||||
sed -e 's/^[^:]*: / /' \
|
||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||
## This next piece of magic avoids the "deleted header file" problem.
|
||||
## The problem is that when a header file which appears in a .P file
|
||||
## is deleted, the dependency causes make to die (because there is
|
||||
## typically no way to rebuild the header). We avoid this by adding
|
||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||
## this for us directly.
|
||||
## Some versions of gcc put a space before the ':'. On the theory
|
||||
## that the space means something, we add a space to the output as
|
||||
## well. hp depmode also adds that space, but also prefixes the VPATH
|
||||
## to the object. Take care to not repeat it in the output.
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sgi)
|
||||
if test "$libtool" = yes; then
|
||||
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||
else
|
||||
"$@" -MDupdate "$tmpdepfile"
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
|
||||
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||
echo "$object : \\" > "$depfile"
|
||||
# Clip off the initial element (the dependent). Don't try to be
|
||||
# clever and replace this with sed code, as IRIX sed won't handle
|
||||
# lines with more than a fixed number of characters (4096 in
|
||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||
# the IRIX cc adds comments like '#:fec' to the end of the
|
||||
# dependency line.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
|
||||
| tr "$nl" ' ' >> "$depfile"
|
||||
echo >> "$depfile"
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> "$depfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
xlc)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
aix)
|
||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||
# in a .u file. In older versions, this file always lives in the
|
||||
# current directory. Also, the AIX compiler puts '$object:' at the
|
||||
# start of each line; $object doesn't have directory information.
|
||||
# Version 6 uses the directory in both cases.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$base.u
|
||||
tmpdepfile3=$dir.libs/$base.u
|
||||
"$@" -Wc,-M
|
||||
else
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$dir$base.u
|
||||
tmpdepfile3=$dir$base.u
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
aix_post_process_depfile
|
||||
;;
|
||||
|
||||
tcc)
|
||||
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
|
||||
# FIXME: That version still under development at the moment of writing.
|
||||
# Make that this statement remains true also for stable, released
|
||||
# versions.
|
||||
# It will wrap lines (doesn't matter whether long or short) with a
|
||||
# trailing '\', as in:
|
||||
#
|
||||
# foo.o : \
|
||||
# foo.c \
|
||||
# foo.h \
|
||||
#
|
||||
# It will put a trailing '\' even on the last line, and will use leading
|
||||
# spaces rather than leading tabs (at least since its commit 0394caf7
|
||||
# "Emit spaces for -MD").
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
|
||||
# We have to change lines of the first kind to '$object: \'.
|
||||
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
|
||||
# And for each line of the second kind, we have to emit a 'dep.h:'
|
||||
# dummy dependency, to avoid the deleted-header problem.
|
||||
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
## The order of this option in the case statement is important, since the
|
||||
## shell code in configure will try each of these formats in the order
|
||||
## listed in this file. A plain '-MD' option would be understood by many
|
||||
## compilers, so we must ensure this comes after the gcc and icc options.
|
||||
pgcc)
|
||||
# Portland's C compiler understands '-MD'.
|
||||
# Will always output deps to 'file.d' where file is the root name of the
|
||||
# source file under compilation, even if file resides in a subdirectory.
|
||||
# The object file name does not affect the name of the '.d' file.
|
||||
# pgcc 10.2 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using '\' :
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
set_dir_from "$object"
|
||||
# Use the source, not the object, to determine the base name, since
|
||||
# that's sadly what pgcc will do too.
|
||||
set_base_from "$source"
|
||||
tmpdepfile=$base.d
|
||||
|
||||
# For projects that build the same source file twice into different object
|
||||
# files, the pgcc approach of using the *source* file root name can cause
|
||||
# problems in parallel builds. Use a locking strategy to avoid stomping on
|
||||
# the same $tmpdepfile.
|
||||
lockdir=$base.d-lock
|
||||
trap "
|
||||
echo '$0: caught signal, cleaning up...' >&2
|
||||
rmdir '$lockdir'
|
||||
exit 1
|
||||
" 1 2 13 15
|
||||
numtries=100
|
||||
i=$numtries
|
||||
while test $i -gt 0; do
|
||||
# mkdir is a portable test-and-set.
|
||||
if mkdir "$lockdir" 2>/dev/null; then
|
||||
# This process acquired the lock.
|
||||
"$@" -MD
|
||||
stat=$?
|
||||
# Release the lock.
|
||||
rmdir "$lockdir"
|
||||
break
|
||||
else
|
||||
# If the lock is being held by a different process, wait
|
||||
# until the winning process is done or we timeout.
|
||||
while test -d "$lockdir" && test $i -gt 0; do
|
||||
sleep 1
|
||||
i=`expr $i - 1`
|
||||
done
|
||||
fi
|
||||
i=`expr $i - 1`
|
||||
done
|
||||
trap - 1 2 13 15
|
||||
if test $i -le 0; then
|
||||
echo "$0: failed to acquire lock after $numtries attempts" >&2
|
||||
echo "$0: check lockdir '$lockdir'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each line is of the form `foo.o: dependent.h',
|
||||
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp2)
|
||||
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||
# compilers, which have integrated preprocessors. The correct option
|
||||
# to use with these is +Maked; it writes dependencies to a file named
|
||||
# 'foo.d', which lands next to the object file, wherever that
|
||||
# happens to be.
|
||||
# Much of this is similar to the tru64 case; see comments there.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir.libs/$base.d
|
||||
"$@" -Wc,+Maked
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
"$@" +Maked
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add 'dependent.h:' lines.
|
||||
sed -ne '2,${
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
s/$/:/
|
||||
p
|
||||
}' "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||
;;
|
||||
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in 'foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# Libtool generates 2 separate objects for the 2 libraries. These
|
||||
# two compilations output dependencies in $dir.libs/$base.o.d and
|
||||
# in $dir$base.o.d. We have to check for both files, because
|
||||
# one of the two compilations can be disabled. We should prefer
|
||||
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||
# the former would cause a distcleancheck panic.
|
||||
tmpdepfile1=$dir$base.o.d # libtool 1.5
|
||||
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
|
||||
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
tmpdepfile3=$dir$base.d
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
# Same post-processing that is required for AIX mode.
|
||||
aix_post_process_depfile
|
||||
;;
|
||||
|
||||
msvc7)
|
||||
if test "$libtool" = yes; then
|
||||
showIncludes=-Wc,-showIncludes
|
||||
else
|
||||
showIncludes=-showIncludes
|
||||
fi
|
||||
"$@" $showIncludes > "$tmpdepfile"
|
||||
stat=$?
|
||||
grep -v '^Note: including file: ' "$tmpdepfile"
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
# The first sed program below extracts the file names and escapes
|
||||
# backslashes for cygpath. The second sed program outputs the file
|
||||
# name when reading, but also accumulates all include files in the
|
||||
# hold buffer in order to output them again at the end. This only
|
||||
# works with sed implementations that can handle large buffers.
|
||||
sed < "$tmpdepfile" -n '
|
||||
/^Note: including file: *\(.*\)/ {
|
||||
s//\1/
|
||||
s/\\/\\\\/g
|
||||
p
|
||||
}' | $cygpath_u | sort -u | sed -n '
|
||||
s/ /\\ /g
|
||||
s/\(.*\)/'"$tab"'\1 \\/p
|
||||
s/.\(.*\) \\/\1:/
|
||||
H
|
||||
$ {
|
||||
s/.*/'"$tab"'/
|
||||
G
|
||||
p
|
||||
}' >> "$depfile"
|
||||
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvc7msys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
#nosideeffect)
|
||||
# This comment above is used by automake to tell side-effect
|
||||
# dependency tracking mechanisms from slower ones.
|
||||
|
||||
dashmstdout)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove '-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
# Require at least two characters before searching for ':'
|
||||
# in the target name. This is to cope with DOS-style filenames:
|
||||
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
|
||||
"$@" $dashmflag |
|
||||
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this sed invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
dashXmstdout)
|
||||
# This case only exists to satisfy depend.m4. It is never actually
|
||||
# run, as this mode is specially recognized in the preamble.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
makedepend)
|
||||
"$@" || exit $?
|
||||
# Remove any Libtool call
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
# X makedepend
|
||||
shift
|
||||
cleared=no eat=no
|
||||
for arg
|
||||
do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
if test $eat = yes; then
|
||||
eat=no
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
# Strip any option that makedepend may not understand. Remove
|
||||
# the object too, otherwise makedepend will parse it as a source file.
|
||||
-arch)
|
||||
eat=yes ;;
|
||||
-*|$object)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
esac
|
||||
done
|
||||
obj_suffix=`echo "$object" | sed 's/^.*\././'`
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
rm -f "$depfile"
|
||||
# makedepend may prepend the VPATH from the source file name to the object.
|
||||
# No need to regex-escape $object, excess matching of '.' is harmless.
|
||||
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process the last invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed '1,2d' "$tmpdepfile" \
|
||||
| tr ' ' "$nl" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||
;;
|
||||
|
||||
cpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove '-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
"$@" -E \
|
||||
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
| sed '$ s: \\$::' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
cat < "$tmpdepfile" >> "$depfile"
|
||||
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvisualcpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E 2>/dev/null |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
|
||||
echo "$tab" >> "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvcmsys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
none)
|
||||
exec "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown depmode $depmode" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
|
@ -1,527 +0,0 @@
|
|||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2011-11-20.07; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# 'make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
nl='
|
||||
'
|
||||
IFS=" "" $nl"
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit=${DOITPROG-}
|
||||
if test -z "$doit"; then
|
||||
doit_exec=exec
|
||||
else
|
||||
doit_exec=$doit
|
||||
fi
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_glob='?'
|
||||
initialize_posix_glob='
|
||||
test "$posix_glob" != "?" || {
|
||||
if (set -f) 2>/dev/null; then
|
||||
posix_glob=
|
||||
else
|
||||
posix_glob=:
|
||||
fi
|
||||
}
|
||||
'
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
no_target_directory=
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *' '* | *'
|
||||
'* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t) dst_arg=$2
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-T) no_target_directory=true;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call 'install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
do_exit='(exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
trap "ret=130; $do_exit" 2
|
||||
trap "ret=141; $do_exit" 13
|
||||
trap "ret=143; $do_exit" 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $src in
|
||||
-* | [=\(\)!]) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
dst=$dst_arg
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test -n "$no_target_directory"; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dst=$dstdir/`basename "$src"`
|
||||
dstdir_status=0
|
||||
else
|
||||
# Prefer dirname, but fall back on a substitute if dirname fails.
|
||||
dstdir=`
|
||||
(dirname "$dst") 2>/dev/null ||
|
||||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$dst" : 'X\(//\)[^/]' \| \
|
||||
X"$dst" : 'X\(//\)$' \| \
|
||||
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
echo X"$dst" |
|
||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)[^/].*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\).*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
s/.*/./; q'
|
||||
`
|
||||
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
if (umask $mkdir_umask &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/d" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
[-=\(\)!]*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
eval "$initialize_posix_glob"
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
$posix_glob set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
$posix_glob set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test X"$d" = X && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
|
||||
eval "$initialize_posix_glob" &&
|
||||
$posix_glob set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
$posix_glob set +f &&
|
||||
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
File diff suppressed because it is too large
Load Diff
|
@ -1,215 +0,0 @@
|
|||
#! /bin/sh
|
||||
# Common wrapper for a few potentially missing GNU programs.
|
||||
|
||||
scriptversion=2013-10-28.13; # UTC
|
||||
|
||||
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo 1>&2 "Try '$0 --help' for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
|
||||
--is-lightweight)
|
||||
# Used by our autoconf macros to check whether the available missing
|
||||
# script is modern enough.
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--run)
|
||||
# Back-compat with the calling convention used by older automake.
|
||||
shift
|
||||
;;
|
||||
|
||||
-h|--h|--he|--hel|--help)
|
||||
echo "\
|
||||
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||
|
||||
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
|
||||
to PROGRAM being missing or too old.
|
||||
|
||||
Options:
|
||||
-h, --help display this help and exit
|
||||
-v, --version output version information and exit
|
||||
|
||||
Supported PROGRAM values:
|
||||
aclocal autoconf autoheader autom4te automake makeinfo
|
||||
bison yacc flex lex help2man
|
||||
|
||||
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
|
||||
'g' are ignored when checking the name.
|
||||
|
||||
Send bug reports to <bug-automake@gnu.org>."
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||
echo "missing $scriptversion (GNU Automake)"
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-*)
|
||||
echo 1>&2 "$0: unknown '$1' option"
|
||||
echo 1>&2 "Try '$0 --help' for more information"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# Run the given program, remember its exit status.
|
||||
"$@"; st=$?
|
||||
|
||||
# If it succeeded, we are done.
|
||||
test $st -eq 0 && exit 0
|
||||
|
||||
# Also exit now if we it failed (or wasn't found), and '--version' was
|
||||
# passed; such an option is passed most likely to detect whether the
|
||||
# program is present and works.
|
||||
case $2 in --version|--help) exit $st;; esac
|
||||
|
||||
# Exit code 63 means version mismatch. This often happens when the user
|
||||
# tries to use an ancient version of a tool on a file that requires a
|
||||
# minimum version.
|
||||
if test $st -eq 63; then
|
||||
msg="probably too old"
|
||||
elif test $st -eq 127; then
|
||||
# Program was missing.
|
||||
msg="missing on your system"
|
||||
else
|
||||
# Program was found and executed, but failed. Give up.
|
||||
exit $st
|
||||
fi
|
||||
|
||||
perl_URL=http://www.perl.org/
|
||||
flex_URL=http://flex.sourceforge.net/
|
||||
gnu_software_URL=http://www.gnu.org/software
|
||||
|
||||
program_details ()
|
||||
{
|
||||
case $1 in
|
||||
aclocal|automake)
|
||||
echo "The '$1' program is part of the GNU Automake package:"
|
||||
echo "<$gnu_software_URL/automake>"
|
||||
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/autoconf>"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
autoconf|autom4te|autoheader)
|
||||
echo "The '$1' program is part of the GNU Autoconf package:"
|
||||
echo "<$gnu_software_URL/autoconf/>"
|
||||
echo "It also requires GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice ()
|
||||
{
|
||||
# Normalize program name to check for.
|
||||
normalized_program=`echo "$1" | sed '
|
||||
s/^gnu-//; t
|
||||
s/^gnu//; t
|
||||
s/^g//; t'`
|
||||
|
||||
printf '%s\n' "'$1' is $msg."
|
||||
|
||||
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
|
||||
case $normalized_program in
|
||||
autoconf*)
|
||||
echo "You should only need it if you modified 'configure.ac',"
|
||||
echo "or m4 files included by it."
|
||||
program_details 'autoconf'
|
||||
;;
|
||||
autoheader*)
|
||||
echo "You should only need it if you modified 'acconfig.h' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'autoheader'
|
||||
;;
|
||||
automake*)
|
||||
echo "You should only need it if you modified 'Makefile.am' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'automake'
|
||||
;;
|
||||
aclocal*)
|
||||
echo "You should only need it if you modified 'acinclude.m4' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'aclocal'
|
||||
;;
|
||||
autom4te*)
|
||||
echo "You might have modified some maintainer files that require"
|
||||
echo "the 'autom4te' program to be rebuilt."
|
||||
program_details 'autom4te'
|
||||
;;
|
||||
bison*|yacc*)
|
||||
echo "You should only need it if you modified a '.y' file."
|
||||
echo "You may want to install the GNU Bison package:"
|
||||
echo "<$gnu_software_URL/bison/>"
|
||||
;;
|
||||
lex*|flex*)
|
||||
echo "You should only need it if you modified a '.l' file."
|
||||
echo "You may want to install the Fast Lexical Analyzer package:"
|
||||
echo "<$flex_URL>"
|
||||
;;
|
||||
help2man*)
|
||||
echo "You should only need it if you modified a dependency" \
|
||||
"of a man page."
|
||||
echo "You may want to install the GNU Help2man package:"
|
||||
echo "<$gnu_software_URL/help2man/>"
|
||||
;;
|
||||
makeinfo*)
|
||||
echo "You should only need it if you modified a '.texi' file, or"
|
||||
echo "any other file indirectly affecting the aspect of the manual."
|
||||
echo "You might want to install the Texinfo package:"
|
||||
echo "<$gnu_software_URL/texinfo/>"
|
||||
echo "The spurious makeinfo call might also be the consequence of"
|
||||
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
|
||||
echo "want to install GNU make:"
|
||||
echo "<$gnu_software_URL/make/>"
|
||||
;;
|
||||
*)
|
||||
echo "You might have modified some files without having the proper"
|
||||
echo "tools for further handling them. Check the 'README' file, it"
|
||||
echo "often tells you about the needed prerequisites for installing"
|
||||
echo "this package. You may also peek at any GNU archive site, in"
|
||||
echo "case some other package contains this missing '$1' program."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice "$1" | sed -e '1s/^/WARNING: /' \
|
||||
-e '2,$s/^/ /' >&2
|
||||
|
||||
# Propagate the correct exit status (expected to be 127 for a program
|
||||
# not found, 63 for a program that failed due to version mismatch).
|
||||
exit $st
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,606 +0,0 @@
|
|||
# This file was generated by Autom4te Thu Apr 10 10:06:43 UTC 2014.
|
||||
# It contains the lists of macros which have been traced.
|
||||
# It can be safely removed.
|
||||
|
||||
@request = (
|
||||
bless( [
|
||||
'0',
|
||||
1,
|
||||
[
|
||||
'/usr/share/autoconf'
|
||||
],
|
||||
[
|
||||
'/usr/share/autoconf/autoconf/autoconf.m4f',
|
||||
'-',
|
||||
'/usr/share/aclocal-1.14/internal/ac-config-macro-dirs.m4',
|
||||
'/usr/share/aclocal/argz.m4',
|
||||
'/usr/share/aclocal/libtool.m4',
|
||||
'/usr/share/aclocal/ltdl.m4',
|
||||
'/usr/share/aclocal/ltoptions.m4',
|
||||
'/usr/share/aclocal/ltsugar.m4',
|
||||
'/usr/share/aclocal/ltversion.m4',
|
||||
'/usr/share/aclocal/lt~obsolete.m4',
|
||||
'/usr/share/aclocal/pkg.m4',
|
||||
'/usr/share/aclocal/xorg-macros.m4',
|
||||
'/usr/share/aclocal-1.14/amversion.m4',
|
||||
'/usr/share/aclocal-1.14/auxdir.m4',
|
||||
'/usr/share/aclocal-1.14/cond.m4',
|
||||
'/usr/share/aclocal-1.14/depend.m4',
|
||||
'/usr/share/aclocal-1.14/depout.m4',
|
||||
'/usr/share/aclocal-1.14/init.m4',
|
||||
'/usr/share/aclocal-1.14/install-sh.m4',
|
||||
'/usr/share/aclocal-1.14/lead-dot.m4',
|
||||
'/usr/share/aclocal-1.14/maintainer.m4',
|
||||
'/usr/share/aclocal-1.14/make.m4',
|
||||
'/usr/share/aclocal-1.14/missing.m4',
|
||||
'/usr/share/aclocal-1.14/options.m4',
|
||||
'/usr/share/aclocal-1.14/prog-cc-c-o.m4',
|
||||
'/usr/share/aclocal-1.14/runlog.m4',
|
||||
'/usr/share/aclocal-1.14/sanity.m4',
|
||||
'/usr/share/aclocal-1.14/silent.m4',
|
||||
'/usr/share/aclocal-1.14/strip.m4',
|
||||
'/usr/share/aclocal-1.14/substnot.m4',
|
||||
'/usr/share/aclocal-1.14/tar.m4',
|
||||
'm4/ax_gcc_builtin.m4',
|
||||
'configure.ac'
|
||||
],
|
||||
{
|
||||
'PKG_CHECK_MODULES' => 1,
|
||||
'AC_LTDL_DLLIB' => 1,
|
||||
'_AM_PROG_TAR' => 1,
|
||||
'AC_LTDL_OBJDIR' => 1,
|
||||
'XORG_DEFAULT_OPTIONS' => 1,
|
||||
'_LT_AC_LANG_F77_CONFIG' => 1,
|
||||
'AM_PROG_LIBTOOL' => 1,
|
||||
'_LT_PREPARE_SED_QUOTE_VARS' => 1,
|
||||
'_AC_PROG_LIBTOOL' => 1,
|
||||
'AM_PROG_NM' => 1,
|
||||
'XORG_INSTALL' => 1,
|
||||
'AM_MAINTAINER_MODE' => 1,
|
||||
'AC_PROG_NM' => 1,
|
||||
'XORG_TESTSET_CFLAG' => 1,
|
||||
'AC_WITH_LTDL' => 1,
|
||||
'AC_LIBTOOL_LANG_C_CONFIG' => 1,
|
||||
'AM_ENABLE_STATIC' => 1,
|
||||
'AX_GCC_BUILTIN' => 1,
|
||||
'XORG_ENABLE_DEVEL_DOCS' => 1,
|
||||
'_LT_AC_TRY_DLOPEN_SELF' => 1,
|
||||
'AC_LIBTOOL_GCJ' => 1,
|
||||
'AC_PROG_EGREP' => 1,
|
||||
'_LT_AC_LANG_F77' => 1,
|
||||
'_LT_AC_PROG_CXXCPP' => 1,
|
||||
'_LT_LINKER_OPTION' => 1,
|
||||
'gl_FUNC_ARGZ' => 1,
|
||||
'AM_PROG_CC_C_O' => 1,
|
||||
'_LT_PATH_TOOL_PREFIX' => 1,
|
||||
'LT_LANG' => 1,
|
||||
'LT_AC_PROG_RC' => 1,
|
||||
'_LT_AC_PROG_ECHO_BACKSLASH' => 1,
|
||||
'_LT_AC_LANG_GCJ_CONFIG' => 1,
|
||||
'_LT_COMPILER_BOILERPLATE' => 1,
|
||||
'gl_PREREQ_ARGZ' => 1,
|
||||
'XORG_MANPAGE_SECTIONS' => 1,
|
||||
'XORG_WITH_PS2PDF' => 1,
|
||||
'AM_DEP_TRACK' => 1,
|
||||
'PKG_CHECK_EXISTS' => 1,
|
||||
'AC_LIBTOOL_FC' => 1,
|
||||
'LTDL_CONVENIENCE' => 1,
|
||||
'_AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
|
||||
'AC_CHECK_LIBM' => 1,
|
||||
'XORG_CWARNFLAGS' => 1,
|
||||
'XORG_LINT_LIBRARY' => 1,
|
||||
'_m4_warn' => 1,
|
||||
'_PKG_SHORT_ERRORS_SUPPORTED' => 1,
|
||||
'AC_LIBTOOL_PROG_COMPILER_PIC' => 1,
|
||||
'AM_DISABLE_SHARED' => 1,
|
||||
'_AM_MANGLE_OPTION' => 1,
|
||||
'_LT_AC_CHECK_DLFCN' => 1,
|
||||
'AC_LIBTOOL_PICMODE' => 1,
|
||||
'AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH' => 1,
|
||||
'AC_LTDL_SYSSEARCHPATH' => 1,
|
||||
'AC_PATH_MAGIC' => 1,
|
||||
'AC_LIBTOOL_WIN32_DLL' => 1,
|
||||
'_LT_AC_LANG_RC_CONFIG' => 1,
|
||||
'_LT_AC_SYS_COMPILER' => 1,
|
||||
'AC_LTDL_SYMBOL_USCORE' => 1,
|
||||
'_LT_AC_TAGVAR' => 1,
|
||||
'_LT_PROG_ECHO_BACKSLASH' => 1,
|
||||
'LT_FUNC_DLSYM_USCORE' => 1,
|
||||
'XORG_PROG_RAWCPP' => 1,
|
||||
'_AM_AUTOCONF_VERSION' => 1,
|
||||
'AM_ENABLE_SHARED' => 1,
|
||||
'XORG_COMPILER_FLAGS' => 1,
|
||||
'AC_DISABLE_FAST_INSTALL' => 1,
|
||||
'XORG_CHECK_LINKER_FLAGS' => 1,
|
||||
'AC_DEPLIBS_CHECK_METHOD' => 1,
|
||||
'AM_DISABLE_STATIC' => 1,
|
||||
'AM_MISSING_HAS_RUN' => 1,
|
||||
'AC_LTDL_ENABLE_INSTALL' => 1,
|
||||
'_LT_AC_TAGCONFIG' => 1,
|
||||
'AC_PROG_LD_GNU' => 1,
|
||||
'include' => 1,
|
||||
'LT_SYS_MODULE_EXT' => 1,
|
||||
'AM_PROG_LD' => 1,
|
||||
'LT_AC_PROG_SED' => 1,
|
||||
'AC_LIB_LTDL' => 1,
|
||||
'AM_RUN_LOG' => 1,
|
||||
'LT_INIT' => 1,
|
||||
'_LT_AC_LANG_CXX' => 1,
|
||||
'AC_LIBTOOL_CXX' => 1,
|
||||
'AC_DEFUN_ONCE' => 1,
|
||||
'AC_LIBTOOL_DLOPEN_SELF' => 1,
|
||||
'LT_PROG_GCJ' => 1,
|
||||
'LT_SYS_MODULE_PATH' => 1,
|
||||
'AC_LIBTOOL_RC' => 1,
|
||||
'_LT_CC_BASENAME' => 1,
|
||||
'AM_AUTOMAKE_VERSION' => 1,
|
||||
'_LT_AC_SHELL_INIT' => 1,
|
||||
'_AM_DEPENDENCIES' => 1,
|
||||
'AC_LIBTOOL_SYS_LIB_STRIP' => 1,
|
||||
'_AM_SET_OPTION' => 1,
|
||||
'_AM_SUBST_NOTMAKE' => 1,
|
||||
'LT_PATH_NM' => 1,
|
||||
'XORG_CHECK_MALLOC_ZERO' => 1,
|
||||
'AC_LIBLTDL_CONVENIENCE' => 1,
|
||||
'LT_CONFIG_LTDL_DIR' => 1,
|
||||
'AC_DEFUN' => 1,
|
||||
'AM_PROG_INSTALL_STRIP' => 1,
|
||||
'_LT_AC_LOCK' => 1,
|
||||
'XORG_ENABLE_DOCS' => 1,
|
||||
'XORG_ENABLE_SPECS' => 1,
|
||||
'AC_LIBTOOL_COMPILER_OPTION' => 1,
|
||||
'm4_pattern_forbid' => 1,
|
||||
'_LTDL_SETUP' => 1,
|
||||
'AM_SUBST_NOTMAKE' => 1,
|
||||
'AC_LIBTOOL_DLOPEN' => 1,
|
||||
'AC_DISABLE_STATIC' => 1,
|
||||
'LT_PROG_RC' => 1,
|
||||
'_LT_AC_SYS_LIBPATH_AIX' => 1,
|
||||
'AC_ENABLE_FAST_INSTALL' => 1,
|
||||
'AC_PROG_LIBTOOL' => 1,
|
||||
'XORG_WITH_XMLTO' => 1,
|
||||
'_LT_LINKER_BOILERPLATE' => 1,
|
||||
'LTSUGAR_VERSION' => 1,
|
||||
'_LT_PROG_F77' => 1,
|
||||
'AC_CONFIG_MACRO_DIR' => 1,
|
||||
'LTVERSION_VERSION' => 1,
|
||||
'XORG_LD_WRAP' => 1,
|
||||
'LT_WITH_LTDL' => 1,
|
||||
'AC_LIBTOOL_SYS_DYNAMIC_LINKER' => 1,
|
||||
'XORG_MEMORY_CHECK_FLAGS' => 1,
|
||||
'LT_SUPPORTED_TAG' => 1,
|
||||
'LT_AC_PROG_EGREP' => 1,
|
||||
'AC_LTDL_DLSYM_USCORE' => 1,
|
||||
'_AM_PROG_CC_C_O' => 1,
|
||||
'_LT_PROG_LTMAIN' => 1,
|
||||
'XORG_CHECK_SGML_DOCTOOLS' => 1,
|
||||
'_AM_IF_OPTION' => 1,
|
||||
'AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
|
||||
'_AM_CONFIG_MACRO_DIRS' => 1,
|
||||
'AC_LIBTOOL_LANG_CXX_CONFIG' => 1,
|
||||
'_LT_PROG_CXX' => 1,
|
||||
'AC_LTDL_SHLIBPATH' => 1,
|
||||
'AC_LIBTOOL_CONFIG' => 1,
|
||||
'XORG_WITH_DOXYGEN' => 1,
|
||||
'LT_SYS_DLOPEN_DEPLIBS' => 1,
|
||||
'AC_CONFIG_MACRO_DIR_TRACE' => 1,
|
||||
'AC_LIBTOOL_SYS_MAX_CMD_LEN' => 1,
|
||||
'AC_LIBTOOL_POSTDEP_PREDEP' => 1,
|
||||
'm4_pattern_allow' => 1,
|
||||
'LTDL_INSTALLABLE' => 1,
|
||||
'AC_LTDL_SHLIBEXT' => 1,
|
||||
'_LT_AC_LANG_CXX_CONFIG' => 1,
|
||||
'AU_DEFUN' => 1,
|
||||
'AC_LIBTOOL_OBJDIR' => 1,
|
||||
'AM_SET_CURRENT_AUTOMAKE_VERSION' => 1,
|
||||
'AC_LIBTOOL_SETUP' => 1,
|
||||
'AC_LIBTOOL_F77' => 1,
|
||||
'AC_ENABLE_SHARED' => 1,
|
||||
'AC_LIBTOOL_PROG_COMPILER_NO_RTTI' => 1,
|
||||
'AM_SILENT_RULES' => 1,
|
||||
'_LT_AC_LANG_C_CONFIG' => 1,
|
||||
'AC_DISABLE_SHARED' => 1,
|
||||
'AC_LIBLTDL_INSTALLABLE' => 1,
|
||||
'AC_PROG_LD' => 1,
|
||||
'XORG_ENABLE_INTEGRATION_TESTS' => 1,
|
||||
'PKG_PROG_PKG_CONFIG' => 1,
|
||||
'XORG_WITH_GROFF' => 1,
|
||||
'_LT_COMPILER_OPTION' => 1,
|
||||
'LT_SYS_DLSEARCH_PATH' => 1,
|
||||
'AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE' => 1,
|
||||
'XORG_RELEASE_VERSION' => 1,
|
||||
'AM_INIT_AUTOMAKE' => 1,
|
||||
'LT_SYS_SYMBOL_USCORE' => 1,
|
||||
'AC_LIBTOOL_SYS_OLD_ARCHIVE' => 1,
|
||||
'XORG_CHECK_LINUXDOC' => 1,
|
||||
'XORG_STRICT_OPTION' => 1,
|
||||
'XORG_WITH_FOP' => 1,
|
||||
'XORG_WITH_LINT' => 1,
|
||||
'XORG_WITH_PERL' => 1,
|
||||
'AC_PROG_LD_RELOAD_FLAG' => 1,
|
||||
'AM_SANITY_CHECK' => 1,
|
||||
'AM_SET_LEADING_DOT' => 1,
|
||||
'_LT_LIBOBJ' => 1,
|
||||
'XORG_COMPILER_BRAND' => 1,
|
||||
'LT_PROG_GO' => 1,
|
||||
'_LT_AC_FILE_LTDLL_C' => 1,
|
||||
'LT_SYS_DLOPEN_SELF' => 1,
|
||||
'LT_LIB_DLLOAD' => 1,
|
||||
'AC_LIBTOOL_LINKER_OPTION' => 1,
|
||||
'XORG_WITH_ASCIIDOC' => 1,
|
||||
'AM_MISSING_PROG' => 1,
|
||||
'_LT_AC_LANG_GCJ' => 1,
|
||||
'_AC_AM_CONFIG_HEADER_HOOK' => 1,
|
||||
'AC_LTDL_PREOPEN' => 1,
|
||||
'AM_AUX_DIR_EXPAND' => 1,
|
||||
'XORG_WITH_GLIB' => 1,
|
||||
'AM_CONDITIONAL' => 1,
|
||||
'_LT_WITH_SYSROOT' => 1,
|
||||
'AC_ENABLE_STATIC' => 1,
|
||||
'XORG_CHECK_DOCBOOK' => 1,
|
||||
'LTOBSOLETE_VERSION' => 1,
|
||||
'LT_OUTPUT' => 1,
|
||||
'XORG_CHANGELOG' => 1,
|
||||
'LT_LIB_M' => 1,
|
||||
'AC_LIBTOOL_PROG_CC_C_O' => 1,
|
||||
'AM_SET_DEPDIR' => 1,
|
||||
'AC_LIBTOOL_LANG_RC_CONFIG' => 1,
|
||||
'AC_LIBTOOL_LANG_F77_CONFIG' => 1,
|
||||
'm4_include' => 1,
|
||||
'LT_PATH_LD' => 1,
|
||||
'_LT_PROG_FC' => 1,
|
||||
'_LT_REQUIRED_DARWIN_CHECKS' => 1,
|
||||
'AC_LIBTOOL_SYS_HARD_LINK_LOCKS' => 1,
|
||||
'AC_LTDL_SYS_DLOPEN_DEPLIBS' => 1,
|
||||
'XORG_WITH_XSLTPROC' => 1,
|
||||
'LTDL_INIT' => 1,
|
||||
'AC_PATH_TOOL_PREFIX' => 1,
|
||||
'AM_PROG_INSTALL_SH' => 1,
|
||||
'AC_LIBTOOL_LANG_GCJ_CONFIG' => 1,
|
||||
'_AM_SET_OPTIONS' => 1,
|
||||
'AC_LIBTOOL_PROG_LD_SHLIBS' => 1,
|
||||
'LT_AC_PROG_GCJ' => 1,
|
||||
'LTOPTIONS_VERSION' => 1,
|
||||
'AM_MAKE_INCLUDE' => 1,
|
||||
'LT_CMD_MAX_LEN' => 1,
|
||||
'XORG_ENABLE_UNIT_TESTS' => 1
|
||||
}
|
||||
], 'Autom4te::Request' ),
|
||||
bless( [
|
||||
'1',
|
||||
1,
|
||||
[
|
||||
'/usr/share/autoconf'
|
||||
],
|
||||
[
|
||||
'/usr/share/autoconf/autoconf/autoconf.m4f',
|
||||
'aclocal.m4',
|
||||
'configure.ac'
|
||||
],
|
||||
{
|
||||
'LT_SUPPORTED_TAG' => 1,
|
||||
'AC_SUBST_TRACE' => 1,
|
||||
'_LT_AC_TAGCONFIG' => 1,
|
||||
'AM_NLS' => 1,
|
||||
'AM_MAINTAINER_MODE' => 1,
|
||||
'AM_PROG_F77_C_O' => 1,
|
||||
'AC_LIBSOURCE' => 1,
|
||||
'AC_FC_PP_SRCEXT' => 1,
|
||||
'AC_CONFIG_HEADERS' => 1,
|
||||
'AM_PROG_CXX_C_O' => 1,
|
||||
'AC_CONFIG_SUBDIRS' => 1,
|
||||
'AM_PROG_MOC' => 1,
|
||||
'AH_OUTPUT' => 1,
|
||||
'AM_PROG_CC_C_O' => 1,
|
||||
'AM_PROG_MKDIR_P' => 1,
|
||||
'AC_FC_FREEFORM' => 1,
|
||||
'AC_INIT' => 1,
|
||||
'LT_INIT' => 1,
|
||||
'AC_SUBST' => 1,
|
||||
'AM_CONDITIONAL' => 1,
|
||||
'AM_POT_TOOLS' => 1,
|
||||
'AM_XGETTEXT_OPTION' => 1,
|
||||
'include' => 1,
|
||||
'AC_CONFIG_LIBOBJ_DIR' => 1,
|
||||
'LT_CONFIG_LTDL_DIR' => 1,
|
||||
'AM_MAKEFILE_INCLUDE' => 1,
|
||||
'AC_FC_PP_DEFINE' => 1,
|
||||
'AC_CANONICAL_BUILD' => 1,
|
||||
'AM_SILENT_RULES' => 1,
|
||||
'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
|
||||
'm4_include' => 1,
|
||||
'AC_DEFINE_TRACE_LITERAL' => 1,
|
||||
'AM_GNU_GETTEXT' => 1,
|
||||
'AC_CANONICAL_SYSTEM' => 1,
|
||||
'AC_REQUIRE_AUX_FILE' => 1,
|
||||
'AC_FC_SRCEXT' => 1,
|
||||
'_AM_SUBST_NOTMAKE' => 1,
|
||||
'_AM_COND_ENDIF' => 1,
|
||||
'AM_EXTRA_RECURSIVE_TARGETS' => 1,
|
||||
'm4_sinclude' => 1,
|
||||
'AC_CONFIG_AUX_DIR' => 1,
|
||||
'm4_pattern_allow' => 1,
|
||||
'AM_AUTOMAKE_VERSION' => 1,
|
||||
'AC_CONFIG_FILES' => 1,
|
||||
'sinclude' => 1,
|
||||
'AM_ENABLE_MULTILIB' => 1,
|
||||
'AC_CANONICAL_HOST' => 1,
|
||||
'_AM_MAKEFILE_INCLUDE' => 1,
|
||||
'AC_PROG_LIBTOOL' => 1,
|
||||
'AC_CONFIG_LINKS' => 1,
|
||||
'_m4_warn' => 1,
|
||||
'AC_CANONICAL_TARGET' => 1,
|
||||
'AM_PROG_AR' => 1,
|
||||
'AM_INIT_AUTOMAKE' => 1,
|
||||
'AM_PATH_GUILE' => 1,
|
||||
'_AM_COND_ELSE' => 1,
|
||||
'AM_PROG_FC_C_O' => 1,
|
||||
'_AM_COND_IF' => 1,
|
||||
'm4_pattern_forbid' => 1
|
||||
}
|
||||
], 'Autom4te::Request' ),
|
||||
bless( [
|
||||
'2',
|
||||
1,
|
||||
[
|
||||
'/usr/share/autoconf'
|
||||
],
|
||||
[
|
||||
'/usr/share/autoconf/autoconf/autoconf.m4f',
|
||||
'-',
|
||||
'/usr/share/aclocal-1.14/internal/ac-config-macro-dirs.m4',
|
||||
'/usr/share/aclocal/argz.m4',
|
||||
'/usr/share/aclocal/ltdl.m4',
|
||||
'/usr/share/aclocal/pkg.m4',
|
||||
'/usr/share/aclocal/xorg-macros.m4',
|
||||
'/usr/share/aclocal-1.14/amversion.m4',
|
||||
'/usr/share/aclocal-1.14/auxdir.m4',
|
||||
'/usr/share/aclocal-1.14/cond.m4',
|
||||
'/usr/share/aclocal-1.14/depend.m4',
|
||||
'/usr/share/aclocal-1.14/depout.m4',
|
||||
'/usr/share/aclocal-1.14/init.m4',
|
||||
'/usr/share/aclocal-1.14/install-sh.m4',
|
||||
'/usr/share/aclocal-1.14/lead-dot.m4',
|
||||
'/usr/share/aclocal-1.14/maintainer.m4',
|
||||
'/usr/share/aclocal-1.14/make.m4',
|
||||
'/usr/share/aclocal-1.14/missing.m4',
|
||||
'/usr/share/aclocal-1.14/options.m4',
|
||||
'/usr/share/aclocal-1.14/prog-cc-c-o.m4',
|
||||
'/usr/share/aclocal-1.14/runlog.m4',
|
||||
'/usr/share/aclocal-1.14/sanity.m4',
|
||||
'/usr/share/aclocal-1.14/silent.m4',
|
||||
'/usr/share/aclocal-1.14/strip.m4',
|
||||
'/usr/share/aclocal-1.14/substnot.m4',
|
||||
'/usr/share/aclocal-1.14/tar.m4',
|
||||
'm4/ax_gcc_builtin.m4',
|
||||
'm4/libtool.m4',
|
||||
'm4/ltoptions.m4',
|
||||
'm4/ltsugar.m4',
|
||||
'm4/ltversion.m4',
|
||||
'm4/lt~obsolete.m4',
|
||||
'configure.ac'
|
||||
],
|
||||
{
|
||||
'XORG_CHECK_SGML_DOCTOOLS' => 1,
|
||||
'_AM_IF_OPTION' => 1,
|
||||
'AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
|
||||
'_AM_CONFIG_MACRO_DIRS' => 1,
|
||||
'AC_LIBTOOL_LANG_CXX_CONFIG' => 1,
|
||||
'AC_LTDL_SHLIBPATH' => 1,
|
||||
'_LT_PROG_CXX' => 1,
|
||||
'XORG_WITH_DOXYGEN' => 1,
|
||||
'AC_LIBTOOL_CONFIG' => 1,
|
||||
'LTVERSION_VERSION' => 1,
|
||||
'XORG_LD_WRAP' => 1,
|
||||
'LT_WITH_LTDL' => 1,
|
||||
'AC_LIBTOOL_SYS_DYNAMIC_LINKER' => 1,
|
||||
'AC_LTDL_DLSYM_USCORE' => 1,
|
||||
'LT_AC_PROG_EGREP' => 1,
|
||||
'_AM_PROG_CC_C_O' => 1,
|
||||
'_LT_PROG_LTMAIN' => 1,
|
||||
'XORG_MEMORY_CHECK_FLAGS' => 1,
|
||||
'LT_SUPPORTED_TAG' => 1,
|
||||
'XORG_ENABLE_INTEGRATION_TESTS' => 1,
|
||||
'AC_PROG_LD' => 1,
|
||||
'PKG_PROG_PKG_CONFIG' => 1,
|
||||
'XORG_WITH_GROFF' => 1,
|
||||
'LT_SYS_SYMBOL_USCORE' => 1,
|
||||
'AM_INIT_AUTOMAKE' => 1,
|
||||
'XORG_CHECK_LINUXDOC' => 1,
|
||||
'AC_LIBTOOL_SYS_OLD_ARCHIVE' => 1,
|
||||
'LT_SYS_DLSEARCH_PATH' => 1,
|
||||
'_LT_COMPILER_OPTION' => 1,
|
||||
'AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE' => 1,
|
||||
'XORG_RELEASE_VERSION' => 1,
|
||||
'XORG_WITH_LINT' => 1,
|
||||
'XORG_STRICT_OPTION' => 1,
|
||||
'XORG_WITH_FOP' => 1,
|
||||
'AM_SANITY_CHECK' => 1,
|
||||
'AC_PROG_LD_RELOAD_FLAG' => 1,
|
||||
'XORG_WITH_PERL' => 1,
|
||||
'LTDL_INSTALLABLE' => 1,
|
||||
'AC_LTDL_SHLIBEXT' => 1,
|
||||
'm4_pattern_allow' => 1,
|
||||
'AC_CONFIG_MACRO_DIR_TRACE' => 1,
|
||||
'LT_SYS_DLOPEN_DEPLIBS' => 1,
|
||||
'AC_LIBTOOL_SYS_MAX_CMD_LEN' => 1,
|
||||
'AC_LIBTOOL_POSTDEP_PREDEP' => 1,
|
||||
'AM_SET_CURRENT_AUTOMAKE_VERSION' => 1,
|
||||
'AU_DEFUN' => 1,
|
||||
'AC_LIBTOOL_OBJDIR' => 1,
|
||||
'_LT_AC_LANG_CXX_CONFIG' => 1,
|
||||
'AM_SILENT_RULES' => 1,
|
||||
'AC_LIBTOOL_SETUP' => 1,
|
||||
'AC_ENABLE_SHARED' => 1,
|
||||
'AC_LIBTOOL_F77' => 1,
|
||||
'AC_LIBTOOL_PROG_COMPILER_NO_RTTI' => 1,
|
||||
'AC_LIBLTDL_INSTALLABLE' => 1,
|
||||
'AC_DISABLE_SHARED' => 1,
|
||||
'_LT_AC_LANG_C_CONFIG' => 1,
|
||||
'XORG_WITH_GLIB' => 1,
|
||||
'AM_AUX_DIR_EXPAND' => 1,
|
||||
'_LT_WITH_SYSROOT' => 1,
|
||||
'AM_CONDITIONAL' => 1,
|
||||
'AC_ENABLE_STATIC' => 1,
|
||||
'LT_OUTPUT' => 1,
|
||||
'XORG_CHANGELOG' => 1,
|
||||
'XORG_CHECK_DOCBOOK' => 1,
|
||||
'LTOBSOLETE_VERSION' => 1,
|
||||
'AM_SET_LEADING_DOT' => 1,
|
||||
'XORG_COMPILER_BRAND' => 1,
|
||||
'_LT_LIBOBJ' => 1,
|
||||
'LT_LIB_DLLOAD' => 1,
|
||||
'LT_SYS_DLOPEN_SELF' => 1,
|
||||
'AC_LIBTOOL_LINKER_OPTION' => 1,
|
||||
'_LT_AC_FILE_LTDLL_C' => 1,
|
||||
'LT_PROG_GO' => 1,
|
||||
'AC_LTDL_PREOPEN' => 1,
|
||||
'XORG_WITH_ASCIIDOC' => 1,
|
||||
'AM_MISSING_PROG' => 1,
|
||||
'_LT_AC_LANG_GCJ' => 1,
|
||||
'_AC_AM_CONFIG_HEADER_HOOK' => 1,
|
||||
'AM_PROG_INSTALL_SH' => 1,
|
||||
'AC_LIBTOOL_LANG_GCJ_CONFIG' => 1,
|
||||
'XORG_WITH_XSLTPROC' => 1,
|
||||
'LTDL_INIT' => 1,
|
||||
'AC_PATH_TOOL_PREFIX' => 1,
|
||||
'AC_LIBTOOL_PROG_LD_SHLIBS' => 1,
|
||||
'_AM_SET_OPTIONS' => 1,
|
||||
'LT_AC_PROG_GCJ' => 1,
|
||||
'LTOPTIONS_VERSION' => 1,
|
||||
'AM_MAKE_INCLUDE' => 1,
|
||||
'XORG_ENABLE_UNIT_TESTS' => 1,
|
||||
'LT_CMD_MAX_LEN' => 1,
|
||||
'AM_SET_DEPDIR' => 1,
|
||||
'LT_LIB_M' => 1,
|
||||
'AC_LIBTOOL_PROG_CC_C_O' => 1,
|
||||
'AC_LIBTOOL_LANG_RC_CONFIG' => 1,
|
||||
'm4_include' => 1,
|
||||
'AC_LIBTOOL_LANG_F77_CONFIG' => 1,
|
||||
'AC_LIBTOOL_SYS_HARD_LINK_LOCKS' => 1,
|
||||
'AC_LTDL_SYS_DLOPEN_DEPLIBS' => 1,
|
||||
'LT_PATH_LD' => 1,
|
||||
'_LT_REQUIRED_DARWIN_CHECKS' => 1,
|
||||
'_LT_PROG_FC' => 1,
|
||||
'AC_LIBTOOL_GCJ' => 1,
|
||||
'_LT_AC_TRY_DLOPEN_SELF' => 1,
|
||||
'AM_ENABLE_STATIC' => 1,
|
||||
'XORG_ENABLE_DEVEL_DOCS' => 1,
|
||||
'AX_GCC_BUILTIN' => 1,
|
||||
'_LT_LINKER_OPTION' => 1,
|
||||
'AC_PROG_EGREP' => 1,
|
||||
'_LT_AC_LANG_F77' => 1,
|
||||
'_LT_AC_PROG_CXXCPP' => 1,
|
||||
'gl_FUNC_ARGZ' => 1,
|
||||
'LT_LANG' => 1,
|
||||
'_LT_PATH_TOOL_PREFIX' => 1,
|
||||
'AM_PROG_CC_C_O' => 1,
|
||||
'AC_LTDL_DLLIB' => 1,
|
||||
'_AM_PROG_TAR' => 1,
|
||||
'AC_LTDL_OBJDIR' => 1,
|
||||
'PKG_CHECK_MODULES' => 1,
|
||||
'_LT_AC_LANG_F77_CONFIG' => 1,
|
||||
'XORG_DEFAULT_OPTIONS' => 1,
|
||||
'AM_PROG_LIBTOOL' => 1,
|
||||
'AM_MAINTAINER_MODE' => 1,
|
||||
'AC_PROG_NM' => 1,
|
||||
'XORG_TESTSET_CFLAG' => 1,
|
||||
'_LT_PREPARE_SED_QUOTE_VARS' => 1,
|
||||
'AM_PROG_NM' => 1,
|
||||
'_AC_PROG_LIBTOOL' => 1,
|
||||
'XORG_INSTALL' => 1,
|
||||
'AC_LIBTOOL_LANG_C_CONFIG' => 1,
|
||||
'AC_WITH_LTDL' => 1,
|
||||
'AC_CHECK_LIBM' => 1,
|
||||
'_AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
|
||||
'AC_LIBTOOL_PROG_COMPILER_PIC' => 1,
|
||||
'_PKG_SHORT_ERRORS_SUPPORTED' => 1,
|
||||
'XORG_CWARNFLAGS' => 1,
|
||||
'XORG_LINT_LIBRARY' => 1,
|
||||
'_m4_warn' => 1,
|
||||
'_AM_MANGLE_OPTION' => 1,
|
||||
'AM_DISABLE_SHARED' => 1,
|
||||
'AC_LIBTOOL_WIN32_DLL' => 1,
|
||||
'AC_PATH_MAGIC' => 1,
|
||||
'AC_LTDL_SYSSEARCHPATH' => 1,
|
||||
'AC_LIBTOOL_PICMODE' => 1,
|
||||
'_LT_AC_CHECK_DLFCN' => 1,
|
||||
'AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH' => 1,
|
||||
'_LT_AC_LANG_GCJ_CONFIG' => 1,
|
||||
'gl_PREREQ_ARGZ' => 1,
|
||||
'XORG_MANPAGE_SECTIONS' => 1,
|
||||
'_LT_COMPILER_BOILERPLATE' => 1,
|
||||
'LT_AC_PROG_RC' => 1,
|
||||
'_LT_AC_PROG_ECHO_BACKSLASH' => 1,
|
||||
'AM_DEP_TRACK' => 1,
|
||||
'XORG_WITH_PS2PDF' => 1,
|
||||
'LTDL_CONVENIENCE' => 1,
|
||||
'PKG_CHECK_EXISTS' => 1,
|
||||
'AC_LIBTOOL_FC' => 1,
|
||||
'LT_SYS_MODULE_EXT' => 1,
|
||||
'AM_PROG_LD' => 1,
|
||||
'AC_PROG_LD_GNU' => 1,
|
||||
'include' => 1,
|
||||
'LT_AC_PROG_SED' => 1,
|
||||
'AC_LIB_LTDL' => 1,
|
||||
'AM_RUN_LOG' => 1,
|
||||
'LT_INIT' => 1,
|
||||
'LT_SYS_MODULE_PATH' => 1,
|
||||
'LT_PROG_GCJ' => 1,
|
||||
'AC_LIBTOOL_DLOPEN_SELF' => 1,
|
||||
'AC_DEFUN_ONCE' => 1,
|
||||
'AC_LIBTOOL_RC' => 1,
|
||||
'_LT_AC_LANG_CXX' => 1,
|
||||
'AC_LIBTOOL_CXX' => 1,
|
||||
'_LT_AC_TAGVAR' => 1,
|
||||
'AC_LTDL_SYMBOL_USCORE' => 1,
|
||||
'_LT_PROG_ECHO_BACKSLASH' => 1,
|
||||
'LT_FUNC_DLSYM_USCORE' => 1,
|
||||
'_LT_AC_SYS_COMPILER' => 1,
|
||||
'_LT_AC_LANG_RC_CONFIG' => 1,
|
||||
'XORG_PROG_RAWCPP' => 1,
|
||||
'AM_ENABLE_SHARED' => 1,
|
||||
'_AM_AUTOCONF_VERSION' => 1,
|
||||
'AM_DISABLE_STATIC' => 1,
|
||||
'AC_DEPLIBS_CHECK_METHOD' => 1,
|
||||
'AM_MISSING_HAS_RUN' => 1,
|
||||
'_LT_AC_TAGCONFIG' => 1,
|
||||
'AC_LTDL_ENABLE_INSTALL' => 1,
|
||||
'AC_DISABLE_FAST_INSTALL' => 1,
|
||||
'XORG_COMPILER_FLAGS' => 1,
|
||||
'XORG_CHECK_LINKER_FLAGS' => 1,
|
||||
'XORG_ENABLE_SPECS' => 1,
|
||||
'm4_pattern_forbid' => 1,
|
||||
'AC_LIBTOOL_COMPILER_OPTION' => 1,
|
||||
'_LT_AC_LOCK' => 1,
|
||||
'XORG_ENABLE_DOCS' => 1,
|
||||
'LT_PROG_RC' => 1,
|
||||
'_LT_AC_SYS_LIBPATH_AIX' => 1,
|
||||
'AM_SUBST_NOTMAKE' => 1,
|
||||
'_LTDL_SETUP' => 1,
|
||||
'AC_DISABLE_STATIC' => 1,
|
||||
'AC_LIBTOOL_DLOPEN' => 1,
|
||||
'AC_PROG_LIBTOOL' => 1,
|
||||
'AC_ENABLE_FAST_INSTALL' => 1,
|
||||
'AC_CONFIG_MACRO_DIR' => 1,
|
||||
'_LT_PROG_F77' => 1,
|
||||
'XORG_WITH_XMLTO' => 1,
|
||||
'LTSUGAR_VERSION' => 1,
|
||||
'_LT_LINKER_BOILERPLATE' => 1,
|
||||
'AM_AUTOMAKE_VERSION' => 1,
|
||||
'_LT_CC_BASENAME' => 1,
|
||||
'_AM_SUBST_NOTMAKE' => 1,
|
||||
'LT_PATH_NM' => 1,
|
||||
'_LT_AC_SHELL_INIT' => 1,
|
||||
'_AM_DEPENDENCIES' => 1,
|
||||
'AC_LIBTOOL_SYS_LIB_STRIP' => 1,
|
||||
'_AM_SET_OPTION' => 1,
|
||||
'AM_PROG_INSTALL_STRIP' => 1,
|
||||
'AC_DEFUN' => 1,
|
||||
'XORG_CHECK_MALLOC_ZERO' => 1,
|
||||
'AC_LIBLTDL_CONVENIENCE' => 1,
|
||||
'LT_CONFIG_LTDL_DIR' => 1
|
||||
}
|
||||
], 'Autom4te::Request' )
|
||||
);
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
#! /bin/sh
|
||||
# test-driver - basic testsuite driver script.
|
||||
|
||||
scriptversion=2013-07-13.22; # UTC
|
||||
|
||||
# Copyright (C) 2011-2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
# Make unconditional expansion of undefined variables an error. This
|
||||
# helps a lot in preventing typo-related bugs.
|
||||
set -u
|
||||
|
||||
usage_error ()
|
||||
{
|
||||
echo "$0: $*" >&2
|
||||
print_usage >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
print_usage ()
|
||||
{
|
||||
cat <<END
|
||||
Usage:
|
||||
test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
|
||||
[--expect-failure={yes|no}] [--color-tests={yes|no}]
|
||||
[--enable-hard-errors={yes|no}] [--]
|
||||
TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
|
||||
The '--test-name', '--log-file' and '--trs-file' options are mandatory.
|
||||
END
|
||||
}
|
||||
|
||||
test_name= # Used for reporting.
|
||||
log_file= # Where to save the output of the test script.
|
||||
trs_file= # Where to save the metadata of the test run.
|
||||
expect_failure=no
|
||||
color_tests=no
|
||||
enable_hard_errors=yes
|
||||
while test $# -gt 0; do
|
||||
case $1 in
|
||||
--help) print_usage; exit $?;;
|
||||
--version) echo "test-driver $scriptversion"; exit $?;;
|
||||
--test-name) test_name=$2; shift;;
|
||||
--log-file) log_file=$2; shift;;
|
||||
--trs-file) trs_file=$2; shift;;
|
||||
--color-tests) color_tests=$2; shift;;
|
||||
--expect-failure) expect_failure=$2; shift;;
|
||||
--enable-hard-errors) enable_hard_errors=$2; shift;;
|
||||
--) shift; break;;
|
||||
-*) usage_error "invalid option: '$1'";;
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
missing_opts=
|
||||
test x"$test_name" = x && missing_opts="$missing_opts --test-name"
|
||||
test x"$log_file" = x && missing_opts="$missing_opts --log-file"
|
||||
test x"$trs_file" = x && missing_opts="$missing_opts --trs-file"
|
||||
if test x"$missing_opts" != x; then
|
||||
usage_error "the following mandatory options are missing:$missing_opts"
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
usage_error "missing argument"
|
||||
fi
|
||||
|
||||
if test $color_tests = yes; then
|
||||
# Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
|
||||
red='[0;31m' # Red.
|
||||
grn='[0;32m' # Green.
|
||||
lgn='[1;32m' # Light green.
|
||||
blu='[1;34m' # Blue.
|
||||
mgn='[0;35m' # Magenta.
|
||||
std='[m' # No color.
|
||||
else
|
||||
red= grn= lgn= blu= mgn= std=
|
||||
fi
|
||||
|
||||
do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
|
||||
trap "st=129; $do_exit" 1
|
||||
trap "st=130; $do_exit" 2
|
||||
trap "st=141; $do_exit" 13
|
||||
trap "st=143; $do_exit" 15
|
||||
|
||||
# Test script is run here.
|
||||
"$@" >$log_file 2>&1
|
||||
estatus=$?
|
||||
if test $enable_hard_errors = no && test $estatus -eq 99; then
|
||||
estatus=1
|
||||
fi
|
||||
|
||||
case $estatus:$expect_failure in
|
||||
0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
|
||||
0:*) col=$grn res=PASS recheck=no gcopy=no;;
|
||||
77:*) col=$blu res=SKIP recheck=no gcopy=yes;;
|
||||
99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;;
|
||||
*:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;;
|
||||
*:*) col=$red res=FAIL recheck=yes gcopy=yes;;
|
||||
esac
|
||||
|
||||
# Report outcome to console.
|
||||
echo "${col}${res}${std}: $test_name"
|
||||
|
||||
# Register the test result, and other relevant metadata.
|
||||
echo ":test-result: $res" > $trs_file
|
||||
echo ":global-test-result: $res" >> $trs_file
|
||||
echo ":recheck: $recheck" >> $trs_file
|
||||
echo ":copy-in-global-log: $gcopy" >> $trs_file
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
File diff suppressed because it is too large
Load Diff
|
@ -1,832 +0,0 @@
|
|||
m4trace:aclocal.m4:3199: -1- m4_include([m4/ax_gcc_builtin.m4])
|
||||
m4trace:aclocal.m4:3200: -1- m4_include([m4/libtool.m4])
|
||||
m4trace:aclocal.m4:3201: -1- m4_include([m4/ltoptions.m4])
|
||||
m4trace:aclocal.m4:3202: -1- m4_include([m4/ltsugar.m4])
|
||||
m4trace:aclocal.m4:3203: -1- m4_include([m4/ltversion.m4])
|
||||
m4trace:aclocal.m4:3204: -1- m4_include([m4/lt~obsolete.m4])
|
||||
m4trace:configure.ac:25: -1- AC_INIT([libxkbcommon], [0.5.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=libxkbcommon], [libxkbcommon], [http://xkbcommon.org])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_forbid([^_?A[CHUM]_])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_forbid([_AC_])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS'])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^AS_FLAGS$])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_forbid([^_?m4_])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_forbid([^dnl$])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_forbid([^_?AS_])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([SHELL])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([SHELL])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^SHELL$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([PATH_SEPARATOR])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([PATH_SEPARATOR])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^PATH_SEPARATOR$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([PACKAGE_NAME], [m4_ifdef([AC_PACKAGE_NAME], ['AC_PACKAGE_NAME'])])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([PACKAGE_NAME])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^PACKAGE_NAME$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([PACKAGE_TARNAME], [m4_ifdef([AC_PACKAGE_TARNAME], ['AC_PACKAGE_TARNAME'])])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([PACKAGE_TARNAME])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^PACKAGE_TARNAME$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([PACKAGE_VERSION], [m4_ifdef([AC_PACKAGE_VERSION], ['AC_PACKAGE_VERSION'])])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([PACKAGE_VERSION])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^PACKAGE_VERSION$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([PACKAGE_STRING], [m4_ifdef([AC_PACKAGE_STRING], ['AC_PACKAGE_STRING'])])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([PACKAGE_STRING])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^PACKAGE_STRING$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([PACKAGE_BUGREPORT], [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([PACKAGE_BUGREPORT])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([PACKAGE_URL], [m4_ifdef([AC_PACKAGE_URL], ['AC_PACKAGE_URL'])])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([PACKAGE_URL])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^PACKAGE_URL$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([exec_prefix], [NONE])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([exec_prefix])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^exec_prefix$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([prefix], [NONE])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([prefix])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^prefix$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([program_transform_name], [s,x,x,])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([program_transform_name])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^program_transform_name$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([bindir], ['${exec_prefix}/bin'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([bindir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^bindir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([sbindir], ['${exec_prefix}/sbin'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([sbindir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^sbindir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([libexecdir], ['${exec_prefix}/libexec'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([libexecdir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^libexecdir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([datarootdir], ['${prefix}/share'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([datarootdir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^datarootdir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([datadir], ['${datarootdir}'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([datadir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^datadir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([sysconfdir], ['${prefix}/etc'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([sysconfdir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^sysconfdir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([sharedstatedir], ['${prefix}/com'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([sharedstatedir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^sharedstatedir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([localstatedir], ['${prefix}/var'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([localstatedir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^localstatedir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([includedir], ['${prefix}/include'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([includedir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^includedir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([oldincludedir], ['/usr/include'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([oldincludedir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^oldincludedir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME],
|
||||
['${datarootdir}/doc/${PACKAGE_TARNAME}'],
|
||||
['${datarootdir}/doc/${PACKAGE}'])])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([docdir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^docdir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([infodir], ['${datarootdir}/info'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([infodir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^infodir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([htmldir], ['${docdir}'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([htmldir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^htmldir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([dvidir], ['${docdir}'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([dvidir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^dvidir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([pdfdir], ['${docdir}'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([pdfdir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^pdfdir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([psdir], ['${docdir}'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([psdir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^psdir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([libdir], ['${exec_prefix}/lib'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([libdir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^libdir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([localedir], ['${datarootdir}/locale'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([localedir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^localedir$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([mandir], ['${datarootdir}/man'])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([mandir])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^mandir$])
|
||||
m4trace:configure.ac:25: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_NAME])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^PACKAGE_NAME$])
|
||||
m4trace:configure.ac:25: -1- AH_OUTPUT([PACKAGE_NAME], [/* Define to the full name of this package. */
|
||||
@%:@undef PACKAGE_NAME])
|
||||
m4trace:configure.ac:25: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_TARNAME])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^PACKAGE_TARNAME$])
|
||||
m4trace:configure.ac:25: -1- AH_OUTPUT([PACKAGE_TARNAME], [/* Define to the one symbol short name of this package. */
|
||||
@%:@undef PACKAGE_TARNAME])
|
||||
m4trace:configure.ac:25: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^PACKAGE_VERSION$])
|
||||
m4trace:configure.ac:25: -1- AH_OUTPUT([PACKAGE_VERSION], [/* Define to the version of this package. */
|
||||
@%:@undef PACKAGE_VERSION])
|
||||
m4trace:configure.ac:25: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_STRING])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^PACKAGE_STRING$])
|
||||
m4trace:configure.ac:25: -1- AH_OUTPUT([PACKAGE_STRING], [/* Define to the full name and version of this package. */
|
||||
@%:@undef PACKAGE_STRING])
|
||||
m4trace:configure.ac:25: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_BUGREPORT])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$])
|
||||
m4trace:configure.ac:25: -1- AH_OUTPUT([PACKAGE_BUGREPORT], [/* Define to the address where bug reports for this package should be sent. */
|
||||
@%:@undef PACKAGE_BUGREPORT])
|
||||
m4trace:configure.ac:25: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_URL])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^PACKAGE_URL$])
|
||||
m4trace:configure.ac:25: -1- AH_OUTPUT([PACKAGE_URL], [/* Define to the home page for this package. */
|
||||
@%:@undef PACKAGE_URL])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([DEFS])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([DEFS])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^DEFS$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([ECHO_C])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([ECHO_C])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^ECHO_C$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([ECHO_N])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([ECHO_N])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^ECHO_N$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([ECHO_T])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([ECHO_T])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^ECHO_T$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([LIBS])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([LIBS])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^LIBS$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([build_alias])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([build_alias])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^build_alias$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([host_alias])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([host_alias])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^host_alias$])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST([target_alias])
|
||||
m4trace:configure.ac:25: -1- AC_SUBST_TRACE([target_alias])
|
||||
m4trace:configure.ac:25: -1- m4_pattern_allow([^target_alias$])
|
||||
m4trace:configure.ac:29: -1- AC_CONFIG_HEADERS([src/config.h])
|
||||
m4trace:configure.ac:31: -1- AC_CONFIG_AUX_DIR([build-aux])
|
||||
m4trace:configure.ac:34: -1- AM_INIT_AUTOMAKE([foreign dist-xz no-dist-gzip subdir-objects color-tests parallel-tests check-news])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^AM_[A-Z]+FLAGS$])
|
||||
m4trace:configure.ac:34: -1- AM_AUTOMAKE_VERSION([1.14.1])
|
||||
m4trace:configure.ac:34: -1- AC_REQUIRE_AUX_FILE([install-sh])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([INSTALL_PROGRAM])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([INSTALL_PROGRAM])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^INSTALL_PROGRAM$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([INSTALL_SCRIPT])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([INSTALL_SCRIPT])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^INSTALL_SCRIPT$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([INSTALL_DATA])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([INSTALL_DATA])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^INSTALL_DATA$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([am__isrc], [' -I$(srcdir)'])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([am__isrc])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^am__isrc$])
|
||||
m4trace:configure.ac:34: -1- _AM_SUBST_NOTMAKE([am__isrc])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([CYGPATH_W])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([CYGPATH_W])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^CYGPATH_W$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([PACKAGE])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^PACKAGE$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([VERSION])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^VERSION$])
|
||||
m4trace:configure.ac:34: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^PACKAGE$])
|
||||
m4trace:configure.ac:34: -1- AH_OUTPUT([PACKAGE], [/* Name of package */
|
||||
@%:@undef PACKAGE])
|
||||
m4trace:configure.ac:34: -1- AC_DEFINE_TRACE_LITERAL([VERSION])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^VERSION$])
|
||||
m4trace:configure.ac:34: -1- AH_OUTPUT([VERSION], [/* Version number of package */
|
||||
@%:@undef VERSION])
|
||||
m4trace:configure.ac:34: -1- AC_REQUIRE_AUX_FILE([missing])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([ACLOCAL])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([ACLOCAL])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^ACLOCAL$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([AUTOCONF])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([AUTOCONF])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^AUTOCONF$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([AUTOMAKE])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([AUTOMAKE])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^AUTOMAKE$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([AUTOHEADER])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([AUTOHEADER])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^AUTOHEADER$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([MAKEINFO])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([MAKEINFO])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^MAKEINFO$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([install_sh])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([install_sh])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^install_sh$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([STRIP])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([STRIP])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^STRIP$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([INSTALL_STRIP_PROGRAM])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([INSTALL_STRIP_PROGRAM])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^INSTALL_STRIP_PROGRAM$])
|
||||
m4trace:configure.ac:34: -1- AC_REQUIRE_AUX_FILE([install-sh])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([MKDIR_P])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([MKDIR_P])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^MKDIR_P$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([mkdir_p])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^mkdir_p$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([AWK])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([AWK])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^AWK$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([SET_MAKE])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([SET_MAKE])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^SET_MAKE$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([am__leading_dot])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([am__leading_dot])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^am__leading_dot$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([AMTAR], ['$${TAR-tar}'])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([AMTAR])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^AMTAR$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([am__tar])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([am__tar])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^am__tar$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([am__untar])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([am__untar])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^am__untar$])
|
||||
m4trace:configure.ac:34: -1- AM_SILENT_RULES
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([AM_V])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([AM_V])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^AM_V$])
|
||||
m4trace:configure.ac:34: -1- _AM_SUBST_NOTMAKE([AM_V])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([AM_DEFAULT_V])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([AM_DEFAULT_V])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^AM_DEFAULT_V$])
|
||||
m4trace:configure.ac:34: -1- _AM_SUBST_NOTMAKE([AM_DEFAULT_V])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([AM_DEFAULT_VERBOSITY])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([AM_DEFAULT_VERBOSITY])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^AM_DEFAULT_VERBOSITY$])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST([AM_BACKSLASH])
|
||||
m4trace:configure.ac:34: -1- AC_SUBST_TRACE([AM_BACKSLASH])
|
||||
m4trace:configure.ac:34: -1- m4_pattern_allow([^AM_BACKSLASH$])
|
||||
m4trace:configure.ac:34: -1- _AM_SUBST_NOTMAKE([AM_BACKSLASH])
|
||||
m4trace:configure.ac:35: -1- AM_MAINTAINER_MODE([enable])
|
||||
m4trace:configure.ac:35: -1- AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
|
||||
m4trace:configure.ac:35: -1- AC_SUBST([MAINTAINER_MODE_TRUE])
|
||||
m4trace:configure.ac:35: -1- AC_SUBST_TRACE([MAINTAINER_MODE_TRUE])
|
||||
m4trace:configure.ac:35: -1- m4_pattern_allow([^MAINTAINER_MODE_TRUE$])
|
||||
m4trace:configure.ac:35: -1- AC_SUBST([MAINTAINER_MODE_FALSE])
|
||||
m4trace:configure.ac:35: -1- AC_SUBST_TRACE([MAINTAINER_MODE_FALSE])
|
||||
m4trace:configure.ac:35: -1- m4_pattern_allow([^MAINTAINER_MODE_FALSE$])
|
||||
m4trace:configure.ac:35: -1- _AM_SUBST_NOTMAKE([MAINTAINER_MODE_TRUE])
|
||||
m4trace:configure.ac:35: -1- _AM_SUBST_NOTMAKE([MAINTAINER_MODE_FALSE])
|
||||
m4trace:configure.ac:35: -1- AC_SUBST([MAINT])
|
||||
m4trace:configure.ac:35: -1- AC_SUBST_TRACE([MAINT])
|
||||
m4trace:configure.ac:35: -1- m4_pattern_allow([^MAINT$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([CC])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([CC])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^CC$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([CFLAGS])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([CFLAGS])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^CFLAGS$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([LDFLAGS])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([LDFLAGS])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^LDFLAGS$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([LIBS])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([LIBS])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^LIBS$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([CPPFLAGS])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([CPPFLAGS])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^CPPFLAGS$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([CC])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([CC])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^CC$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([CC])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([CC])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^CC$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([CC])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([CC])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^CC$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([CC])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([CC])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^CC$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([ac_ct_CC])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([ac_ct_CC])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^ac_ct_CC$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([EXEEXT], [$ac_cv_exeext])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([EXEEXT])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^EXEEXT$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([OBJEXT], [$ac_cv_objext])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([OBJEXT])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^OBJEXT$])
|
||||
m4trace:configure.ac:38: -1- AC_REQUIRE_AUX_FILE([compile])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([DEPDIR])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^DEPDIR$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([am__include])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([am__include])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^am__include$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([am__quote])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([am__quote])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^am__quote$])
|
||||
m4trace:configure.ac:38: -1- AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([AMDEP_TRUE])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([AMDEP_TRUE])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^AMDEP_TRUE$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([AMDEP_FALSE])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([AMDEP_FALSE])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^AMDEP_FALSE$])
|
||||
m4trace:configure.ac:38: -1- _AM_SUBST_NOTMAKE([AMDEP_TRUE])
|
||||
m4trace:configure.ac:38: -1- _AM_SUBST_NOTMAKE([AMDEP_FALSE])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([AMDEPBACKSLASH])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([AMDEPBACKSLASH])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^AMDEPBACKSLASH$])
|
||||
m4trace:configure.ac:38: -1- _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([am__nodep])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([am__nodep])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^am__nodep$])
|
||||
m4trace:configure.ac:38: -1- _AM_SUBST_NOTMAKE([am__nodep])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([CCDEPMODE], [depmode=$am_cv_CC_dependencies_compiler_type])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([CCDEPMODE])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^CCDEPMODE$])
|
||||
m4trace:configure.ac:38: -1- AM_CONDITIONAL([am__fastdepCC], [
|
||||
test "x$enable_dependency_tracking" != xno \
|
||||
&& test "$am_cv_CC_dependencies_compiler_type" = gcc3])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([am__fastdepCC_TRUE])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([am__fastdepCC_TRUE])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^am__fastdepCC_TRUE$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([am__fastdepCC_FALSE])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([am__fastdepCC_FALSE])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^am__fastdepCC_FALSE$])
|
||||
m4trace:configure.ac:38: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_TRUE])
|
||||
m4trace:configure.ac:38: -1- _AM_SUBST_NOTMAKE([am__fastdepCC_FALSE])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([CPP])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([CPP])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^CPP$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([CPPFLAGS])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([CPPFLAGS])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^CPPFLAGS$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([CPP])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([CPP])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^CPP$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([GREP])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([GREP])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^GREP$])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST([EGREP])
|
||||
m4trace:configure.ac:38: -1- AC_SUBST_TRACE([EGREP])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^EGREP$])
|
||||
m4trace:configure.ac:38: -1- AC_DEFINE_TRACE_LITERAL([STDC_HEADERS])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^STDC_HEADERS$])
|
||||
m4trace:configure.ac:38: -1- AH_OUTPUT([STDC_HEADERS], [/* Define to 1 if you have the ANSI C header files. */
|
||||
@%:@undef STDC_HEADERS])
|
||||
m4trace:configure.ac:38: -1- AH_OUTPUT([HAVE_SYS_TYPES_H], [/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
@%:@undef HAVE_SYS_TYPES_H])
|
||||
m4trace:configure.ac:38: -1- AH_OUTPUT([HAVE_SYS_STAT_H], [/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
@%:@undef HAVE_SYS_STAT_H])
|
||||
m4trace:configure.ac:38: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
@%:@undef HAVE_STDLIB_H])
|
||||
m4trace:configure.ac:38: -1- AH_OUTPUT([HAVE_STRING_H], [/* Define to 1 if you have the <string.h> header file. */
|
||||
@%:@undef HAVE_STRING_H])
|
||||
m4trace:configure.ac:38: -1- AH_OUTPUT([HAVE_MEMORY_H], [/* Define to 1 if you have the <memory.h> header file. */
|
||||
@%:@undef HAVE_MEMORY_H])
|
||||
m4trace:configure.ac:38: -1- AH_OUTPUT([HAVE_STRINGS_H], [/* Define to 1 if you have the <strings.h> header file. */
|
||||
@%:@undef HAVE_STRINGS_H])
|
||||
m4trace:configure.ac:38: -1- AH_OUTPUT([HAVE_INTTYPES_H], [/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
@%:@undef HAVE_INTTYPES_H])
|
||||
m4trace:configure.ac:38: -1- AH_OUTPUT([HAVE_STDINT_H], [/* Define to 1 if you have the <stdint.h> header file. */
|
||||
@%:@undef HAVE_STDINT_H])
|
||||
m4trace:configure.ac:38: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the <unistd.h> header file. */
|
||||
@%:@undef HAVE_UNISTD_H])
|
||||
m4trace:configure.ac:38: -1- AC_DEFINE_TRACE_LITERAL([_POSIX_SOURCE])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^_POSIX_SOURCE$])
|
||||
m4trace:configure.ac:38: -1- AH_OUTPUT([_POSIX_SOURCE], [/* Define to 1 if you need to in order for `stat\' and other things to work. */
|
||||
@%:@undef _POSIX_SOURCE])
|
||||
m4trace:configure.ac:38: -1- AC_DEFINE_TRACE_LITERAL([_POSIX_1_SOURCE])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^_POSIX_1_SOURCE$])
|
||||
m4trace:configure.ac:38: -1- AH_OUTPUT([_POSIX_1_SOURCE], [/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
@%:@undef _POSIX_1_SOURCE])
|
||||
m4trace:configure.ac:38: -1- AC_DEFINE_TRACE_LITERAL([_MINIX])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^_MINIX$])
|
||||
m4trace:configure.ac:38: -1- AH_OUTPUT([_MINIX], [/* Define to 1 if on MINIX. */
|
||||
@%:@undef _MINIX])
|
||||
m4trace:configure.ac:38: -1- AH_OUTPUT([USE_SYSTEM_EXTENSIONS], [/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
])
|
||||
m4trace:configure.ac:38: -1- AC_DEFINE_TRACE_LITERAL([__EXTENSIONS__])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^__EXTENSIONS__$])
|
||||
m4trace:configure.ac:38: -1- AC_DEFINE_TRACE_LITERAL([_ALL_SOURCE])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^_ALL_SOURCE$])
|
||||
m4trace:configure.ac:38: -1- AC_DEFINE_TRACE_LITERAL([_GNU_SOURCE])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^_GNU_SOURCE$])
|
||||
m4trace:configure.ac:38: -1- AC_DEFINE_TRACE_LITERAL([_POSIX_PTHREAD_SEMANTICS])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^_POSIX_PTHREAD_SEMANTICS$])
|
||||
m4trace:configure.ac:38: -1- AC_DEFINE_TRACE_LITERAL([_TANDEM_SOURCE])
|
||||
m4trace:configure.ac:38: -1- m4_pattern_allow([^_TANDEM_SOURCE$])
|
||||
m4trace:configure.ac:41: -1- LT_INIT
|
||||
m4trace:configure.ac:41: -1- m4_pattern_forbid([^_?LT_[A-Z_]+$])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])
|
||||
m4trace:configure.ac:41: -1- AC_REQUIRE_AUX_FILE([ltmain.sh])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([LIBTOOL])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([LIBTOOL])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^LIBTOOL$])
|
||||
m4trace:configure.ac:41: -1- AC_CANONICAL_HOST
|
||||
m4trace:configure.ac:41: -1- AC_CANONICAL_BUILD
|
||||
m4trace:configure.ac:41: -1- AC_REQUIRE_AUX_FILE([config.sub])
|
||||
m4trace:configure.ac:41: -1- AC_REQUIRE_AUX_FILE([config.guess])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([build], [$ac_cv_build])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([build])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^build$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([build_cpu], [$[1]])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([build_cpu])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^build_cpu$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([build_vendor], [$[2]])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([build_vendor])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^build_vendor$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([build_os])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([build_os])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^build_os$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([host], [$ac_cv_host])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([host])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^host$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([host_cpu], [$[1]])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([host_cpu])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^host_cpu$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([host_vendor], [$[2]])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([host_vendor])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^host_vendor$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([host_os])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([host_os])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^host_os$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([SED])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([SED])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^SED$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([FGREP])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([FGREP])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^FGREP$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([GREP])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([GREP])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^GREP$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([LD])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([LD])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^LD$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([DUMPBIN])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([DUMPBIN])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^DUMPBIN$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([ac_ct_DUMPBIN])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([ac_ct_DUMPBIN])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^ac_ct_DUMPBIN$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([DUMPBIN])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([DUMPBIN])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^DUMPBIN$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([NM])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([NM])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^NM$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([LN_S], [$as_ln_s])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([LN_S])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^LN_S$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([OBJDUMP])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([OBJDUMP])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^OBJDUMP$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([OBJDUMP])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([OBJDUMP])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^OBJDUMP$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([DLLTOOL])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([DLLTOOL])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^DLLTOOL$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([DLLTOOL])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([DLLTOOL])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^DLLTOOL$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([AR])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([AR])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^AR$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([ac_ct_AR])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([ac_ct_AR])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^ac_ct_AR$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([STRIP])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([STRIP])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^STRIP$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([RANLIB])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([RANLIB])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^RANLIB$])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([LT_OBJDIR])
|
||||
m4trace:configure.ac:41: -1- AC_DEFINE_TRACE_LITERAL([LT_OBJDIR])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^LT_OBJDIR$])
|
||||
m4trace:configure.ac:41: -1- AH_OUTPUT([LT_OBJDIR], [/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
@%:@undef LT_OBJDIR])
|
||||
m4trace:configure.ac:41: -1- LT_SUPPORTED_TAG([CC])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([MANIFEST_TOOL])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([MANIFEST_TOOL])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^MANIFEST_TOOL$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([DSYMUTIL])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([DSYMUTIL])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^DSYMUTIL$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([NMEDIT])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([NMEDIT])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^NMEDIT$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([LIPO])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([LIPO])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^LIPO$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([OTOOL])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([OTOOL])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^OTOOL$])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST([OTOOL64])
|
||||
m4trace:configure.ac:41: -1- AC_SUBST_TRACE([OTOOL64])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^OTOOL64$])
|
||||
m4trace:configure.ac:41: -1- AH_OUTPUT([HAVE_DLFCN_H], [/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
@%:@undef HAVE_DLFCN_H])
|
||||
m4trace:configure.ac:41: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DLFCN_H])
|
||||
m4trace:configure.ac:41: -1- m4_pattern_allow([^HAVE_DLFCN_H$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([BASE_CFLAGS])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([BASE_CFLAGS])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^BASE_CFLAGS$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([CWARNFLAGS])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([CWARNFLAGS])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^CWARNFLAGS$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([STRICT_CFLAGS])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([STRICT_CFLAGS])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^STRICT_CFLAGS$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([BASE_CFLAGS])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([BASE_CFLAGS])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^BASE_CFLAGS$])
|
||||
m4trace:configure.ac:47: -2- AC_SUBST([CWARNFLAGS])
|
||||
m4trace:configure.ac:47: -2- AC_SUBST_TRACE([CWARNFLAGS])
|
||||
m4trace:configure.ac:47: -2- m4_pattern_allow([^CWARNFLAGS$])
|
||||
m4trace:configure.ac:47: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION_MAJOR])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^PACKAGE_VERSION_MAJOR$])
|
||||
m4trace:configure.ac:47: -1- AH_OUTPUT([PACKAGE_VERSION_MAJOR], [/* Major version of this package */
|
||||
@%:@undef PACKAGE_VERSION_MAJOR])
|
||||
m4trace:configure.ac:47: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION_MINOR])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^PACKAGE_VERSION_MINOR$])
|
||||
m4trace:configure.ac:47: -1- AH_OUTPUT([PACKAGE_VERSION_MINOR], [/* Minor version of this package */
|
||||
@%:@undef PACKAGE_VERSION_MINOR])
|
||||
m4trace:configure.ac:47: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION_PATCHLEVEL])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^PACKAGE_VERSION_PATCHLEVEL$])
|
||||
m4trace:configure.ac:47: -1- AH_OUTPUT([PACKAGE_VERSION_PATCHLEVEL], [/* Patch version of this package */
|
||||
@%:@undef PACKAGE_VERSION_PATCHLEVEL])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([CHANGELOG_CMD])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([CHANGELOG_CMD])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^CHANGELOG_CMD$])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_forbid([^_?PKG_[A-Z_]+$])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([PKG_CONFIG])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([PKG_CONFIG])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^PKG_CONFIG$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([PKG_CONFIG_PATH])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([PKG_CONFIG_PATH])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^PKG_CONFIG_PATH$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([PKG_CONFIG_LIBDIR])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([PKG_CONFIG_LIBDIR])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^PKG_CONFIG_LIBDIR$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([PKG_CONFIG])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([PKG_CONFIG])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^PKG_CONFIG$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([INSTALL_CMD])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([INSTALL_CMD])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^INSTALL_CMD$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([APP_MAN_SUFFIX])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([APP_MAN_SUFFIX])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^APP_MAN_SUFFIX$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([LIB_MAN_SUFFIX])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([LIB_MAN_SUFFIX])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^LIB_MAN_SUFFIX$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([FILE_MAN_SUFFIX])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([FILE_MAN_SUFFIX])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^FILE_MAN_SUFFIX$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([MISC_MAN_SUFFIX])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([MISC_MAN_SUFFIX])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^MISC_MAN_SUFFIX$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([DRIVER_MAN_SUFFIX])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([DRIVER_MAN_SUFFIX])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^DRIVER_MAN_SUFFIX$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([ADMIN_MAN_SUFFIX])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([ADMIN_MAN_SUFFIX])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^ADMIN_MAN_SUFFIX$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([APP_MAN_DIR])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([APP_MAN_DIR])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^APP_MAN_DIR$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([LIB_MAN_DIR])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([LIB_MAN_DIR])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^LIB_MAN_DIR$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([FILE_MAN_DIR])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([FILE_MAN_DIR])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^FILE_MAN_DIR$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([MISC_MAN_DIR])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([MISC_MAN_DIR])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^MISC_MAN_DIR$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([DRIVER_MAN_DIR])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([DRIVER_MAN_DIR])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^DRIVER_MAN_DIR$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([ADMIN_MAN_DIR])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([ADMIN_MAN_DIR])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^ADMIN_MAN_DIR$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([XORG_MAN_PAGE])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([XORG_MAN_PAGE])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^XORG_MAN_PAGE$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([MAN_SUBSTS])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([MAN_SUBSTS])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^MAN_SUBSTS$])
|
||||
m4trace:configure.ac:47: -1- AM_SILENT_RULES([yes])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([AM_V])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([AM_V])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^AM_V$])
|
||||
m4trace:configure.ac:47: -1- _AM_SUBST_NOTMAKE([AM_V])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([AM_DEFAULT_V])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([AM_DEFAULT_V])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^AM_DEFAULT_V$])
|
||||
m4trace:configure.ac:47: -1- _AM_SUBST_NOTMAKE([AM_DEFAULT_V])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([AM_DEFAULT_VERBOSITY])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([AM_DEFAULT_VERBOSITY])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^AM_DEFAULT_VERBOSITY$])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST([AM_BACKSLASH])
|
||||
m4trace:configure.ac:47: -1- AC_SUBST_TRACE([AM_BACKSLASH])
|
||||
m4trace:configure.ac:47: -1- m4_pattern_allow([^AM_BACKSLASH$])
|
||||
m4trace:configure.ac:47: -1- _AM_SUBST_NOTMAKE([AM_BACKSLASH])
|
||||
m4trace:configure.ac:48: -1- AC_SUBST([XORG_MALLOC_DEBUG_ENV])
|
||||
m4trace:configure.ac:48: -1- AC_SUBST_TRACE([XORG_MALLOC_DEBUG_ENV])
|
||||
m4trace:configure.ac:48: -1- m4_pattern_allow([^XORG_MALLOC_DEBUG_ENV$])
|
||||
m4trace:configure.ac:48: -1- AC_SUBST([XORG_MALLOC_DEBUG_ENV], [$malloc_debug_env])
|
||||
m4trace:configure.ac:48: -1- AC_SUBST_TRACE([XORG_MALLOC_DEBUG_ENV])
|
||||
m4trace:configure.ac:48: -1- m4_pattern_allow([^XORG_MALLOC_DEBUG_ENV$])
|
||||
m4trace:configure.ac:49: -1- AM_CONDITIONAL([ENABLE_DOCS], [test x$build_docs = xyes])
|
||||
m4trace:configure.ac:49: -1- AC_SUBST([ENABLE_DOCS_TRUE])
|
||||
m4trace:configure.ac:49: -1- AC_SUBST_TRACE([ENABLE_DOCS_TRUE])
|
||||
m4trace:configure.ac:49: -1- m4_pattern_allow([^ENABLE_DOCS_TRUE$])
|
||||
m4trace:configure.ac:49: -1- AC_SUBST([ENABLE_DOCS_FALSE])
|
||||
m4trace:configure.ac:49: -1- AC_SUBST_TRACE([ENABLE_DOCS_FALSE])
|
||||
m4trace:configure.ac:49: -1- m4_pattern_allow([^ENABLE_DOCS_FALSE$])
|
||||
m4trace:configure.ac:49: -1- _AM_SUBST_NOTMAKE([ENABLE_DOCS_TRUE])
|
||||
m4trace:configure.ac:49: -1- _AM_SUBST_NOTMAKE([ENABLE_DOCS_FALSE])
|
||||
m4trace:configure.ac:50: -1- AC_SUBST([DOXYGEN])
|
||||
m4trace:configure.ac:50: -1- AC_SUBST_TRACE([DOXYGEN])
|
||||
m4trace:configure.ac:50: -1- m4_pattern_allow([^DOXYGEN$])
|
||||
m4trace:configure.ac:50: -1- AC_SUBST([DOXYGEN])
|
||||
m4trace:configure.ac:50: -1- AC_SUBST_TRACE([DOXYGEN])
|
||||
m4trace:configure.ac:50: -1- m4_pattern_allow([^DOXYGEN$])
|
||||
m4trace:configure.ac:50: -1- AC_SUBST([DOXYGEN])
|
||||
m4trace:configure.ac:50: -1- AC_SUBST_TRACE([DOXYGEN])
|
||||
m4trace:configure.ac:50: -1- m4_pattern_allow([^DOXYGEN$])
|
||||
m4trace:configure.ac:50: -1- AM_CONDITIONAL([HAVE_DOXYGEN], [test "$have_doxygen" = yes])
|
||||
m4trace:configure.ac:50: -1- AC_SUBST([HAVE_DOXYGEN_TRUE])
|
||||
m4trace:configure.ac:50: -1- AC_SUBST_TRACE([HAVE_DOXYGEN_TRUE])
|
||||
m4trace:configure.ac:50: -1- m4_pattern_allow([^HAVE_DOXYGEN_TRUE$])
|
||||
m4trace:configure.ac:50: -1- AC_SUBST([HAVE_DOXYGEN_FALSE])
|
||||
m4trace:configure.ac:50: -1- AC_SUBST_TRACE([HAVE_DOXYGEN_FALSE])
|
||||
m4trace:configure.ac:50: -1- m4_pattern_allow([^HAVE_DOXYGEN_FALSE$])
|
||||
m4trace:configure.ac:50: -1- _AM_SUBST_NOTMAKE([HAVE_DOXYGEN_TRUE])
|
||||
m4trace:configure.ac:50: -1- _AM_SUBST_NOTMAKE([HAVE_DOXYGEN_FALSE])
|
||||
m4trace:configure.ac:53: -1- AM_PROG_CC_C_O
|
||||
m4trace:configure.ac:56: -1- AH_OUTPUT([inline], [/* Define to `__inline__\' or `__inline\' if that\'s what the C compiler
|
||||
calls it, or to nothing if \'inline\' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif])
|
||||
m4trace:configure.ac:60: -1- m4_pattern_forbid([^_?PKG_[A-Z_]+$])
|
||||
m4trace:configure.ac:60: -1- m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
|
||||
m4trace:configure.ac:60: -1- m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
|
||||
m4trace:configure.ac:60: -1- AC_SUBST([PKG_CONFIG])
|
||||
m4trace:configure.ac:60: -1- AC_SUBST_TRACE([PKG_CONFIG])
|
||||
m4trace:configure.ac:60: -1- m4_pattern_allow([^PKG_CONFIG$])
|
||||
m4trace:configure.ac:60: -1- AC_SUBST([PKG_CONFIG_PATH])
|
||||
m4trace:configure.ac:60: -1- AC_SUBST_TRACE([PKG_CONFIG_PATH])
|
||||
m4trace:configure.ac:60: -1- m4_pattern_allow([^PKG_CONFIG_PATH$])
|
||||
m4trace:configure.ac:60: -1- AC_SUBST([PKG_CONFIG_LIBDIR])
|
||||
m4trace:configure.ac:60: -1- AC_SUBST_TRACE([PKG_CONFIG_LIBDIR])
|
||||
m4trace:configure.ac:60: -1- m4_pattern_allow([^PKG_CONFIG_LIBDIR$])
|
||||
m4trace:configure.ac:60: -1- AC_SUBST([PKG_CONFIG])
|
||||
m4trace:configure.ac:60: -1- AC_SUBST_TRACE([PKG_CONFIG])
|
||||
m4trace:configure.ac:60: -1- m4_pattern_allow([^PKG_CONFIG$])
|
||||
m4trace:configure.ac:64: -1- AC_SUBST([YACC])
|
||||
m4trace:configure.ac:64: -1- AC_SUBST_TRACE([YACC])
|
||||
m4trace:configure.ac:64: -1- m4_pattern_allow([^YACC$])
|
||||
m4trace:configure.ac:64: -1- AC_SUBST([YACC])
|
||||
m4trace:configure.ac:64: -1- AC_SUBST_TRACE([YACC])
|
||||
m4trace:configure.ac:64: -1- m4_pattern_allow([^YACC$])
|
||||
m4trace:configure.ac:64: -1- AC_SUBST([YFLAGS])
|
||||
m4trace:configure.ac:64: -1- AC_SUBST_TRACE([YFLAGS])
|
||||
m4trace:configure.ac:64: -1- m4_pattern_allow([^YFLAGS$])
|
||||
m4trace:configure.ac:65: -1- AC_SUBST([YACC_INST])
|
||||
m4trace:configure.ac:65: -1- AC_SUBST_TRACE([YACC_INST])
|
||||
m4trace:configure.ac:65: -1- m4_pattern_allow([^YACC_INST$])
|
||||
m4trace:configure.ac:71: -1- AH_OUTPUT([HAVE_STRCASECMP], [/* Define to 1 if you have the `strcasecmp\' function. */
|
||||
@%:@undef HAVE_STRCASECMP])
|
||||
m4trace:configure.ac:71: -1- AH_OUTPUT([HAVE_STRNCASECMP], [/* Define to 1 if you have the `strncasecmp\' function. */
|
||||
@%:@undef HAVE_STRNCASECMP])
|
||||
m4trace:configure.ac:77: -1- AH_OUTPUT([HAVE_EACCESS], [/* Define to 1 if you have the `eaccess\' function. */
|
||||
@%:@undef HAVE_EACCESS])
|
||||
m4trace:configure.ac:77: -1- AH_OUTPUT([HAVE_EUIDACCESS], [/* Define to 1 if you have the `euidaccess\' function. */
|
||||
@%:@undef HAVE_EUIDACCESS])
|
||||
m4trace:configure.ac:77: -1- AH_OUTPUT([HAVE_MMAP], [/* Define to 1 if you have the `mmap\' function. */
|
||||
@%:@undef HAVE_MMAP])
|
||||
m4trace:configure.ac:79: -1- AH_OUTPUT([HAVE_SECURE_GETENV], [/* Define to 1 if you have the `secure_getenv\' function. */
|
||||
@%:@undef HAVE_SECURE_GETENV])
|
||||
m4trace:configure.ac:79: -1- AH_OUTPUT([HAVE___SECURE_GETENV], [/* Define to 1 if you have the `__secure_getenv\' function. */
|
||||
@%:@undef HAVE___SECURE_GETENV])
|
||||
m4trace:configure.ac:85: -1- AC_DEFINE_TRACE_LITERAL([HAVE___BUILTIN_EXPECT])
|
||||
m4trace:configure.ac:85: -1- m4_pattern_allow([^HAVE___BUILTIN_EXPECT$])
|
||||
m4trace:configure.ac:85: -1- AH_OUTPUT([HAVE___BUILTIN_EXPECT], [/* Define to 1 if the system has the `__builtin_expect\' built-in function */
|
||||
@%:@undef HAVE___BUILTIN_EXPECT])
|
||||
m4trace:configure.ac:89: -1- AM_CONDITIONAL([BUILD_LINUX_TESTS], [test "x$ac_cv_header_linux_input_h" = xyes])
|
||||
m4trace:configure.ac:89: -1- AC_SUBST([BUILD_LINUX_TESTS_TRUE])
|
||||
m4trace:configure.ac:89: -1- AC_SUBST_TRACE([BUILD_LINUX_TESTS_TRUE])
|
||||
m4trace:configure.ac:89: -1- m4_pattern_allow([^BUILD_LINUX_TESTS_TRUE$])
|
||||
m4trace:configure.ac:89: -1- AC_SUBST([BUILD_LINUX_TESTS_FALSE])
|
||||
m4trace:configure.ac:89: -1- AC_SUBST_TRACE([BUILD_LINUX_TESTS_FALSE])
|
||||
m4trace:configure.ac:89: -1- m4_pattern_allow([^BUILD_LINUX_TESTS_FALSE$])
|
||||
m4trace:configure.ac:89: -1- _AM_SUBST_NOTMAKE([BUILD_LINUX_TESTS_TRUE])
|
||||
m4trace:configure.ac:89: -1- _AM_SUBST_NOTMAKE([BUILD_LINUX_TESTS_FALSE])
|
||||
m4trace:configure.ac:104: -1- AM_CONDITIONAL([HAVE_NO_UNDEFINED], [test "x$have_no_undefined" = xyes])
|
||||
m4trace:configure.ac:104: -1- AC_SUBST([HAVE_NO_UNDEFINED_TRUE])
|
||||
m4trace:configure.ac:104: -1- AC_SUBST_TRACE([HAVE_NO_UNDEFINED_TRUE])
|
||||
m4trace:configure.ac:104: -1- m4_pattern_allow([^HAVE_NO_UNDEFINED_TRUE$])
|
||||
m4trace:configure.ac:104: -1- AC_SUBST([HAVE_NO_UNDEFINED_FALSE])
|
||||
m4trace:configure.ac:104: -1- AC_SUBST_TRACE([HAVE_NO_UNDEFINED_FALSE])
|
||||
m4trace:configure.ac:104: -1- m4_pattern_allow([^HAVE_NO_UNDEFINED_FALSE$])
|
||||
m4trace:configure.ac:104: -1- _AM_SUBST_NOTMAKE([HAVE_NO_UNDEFINED_TRUE])
|
||||
m4trace:configure.ac:104: -1- _AM_SUBST_NOTMAKE([HAVE_NO_UNDEFINED_FALSE])
|
||||
m4trace:configure.ac:106: -1- AC_SUBST([RT_LIBS], ["-lrt"])
|
||||
m4trace:configure.ac:106: -1- AC_SUBST_TRACE([RT_LIBS])
|
||||
m4trace:configure.ac:106: -1- m4_pattern_allow([^RT_LIBS$])
|
||||
m4trace:configure.ac:106: -1- AC_SUBST([RT_LIBS], [""])
|
||||
m4trace:configure.ac:106: -1- AC_SUBST_TRACE([RT_LIBS])
|
||||
m4trace:configure.ac:106: -1- m4_pattern_allow([^RT_LIBS$])
|
||||
m4trace:configure.ac:121: -1- AC_SUBST([XKBCONFIGROOT])
|
||||
m4trace:configure.ac:121: -1- AC_SUBST_TRACE([XKBCONFIGROOT])
|
||||
m4trace:configure.ac:121: -1- m4_pattern_allow([^XKBCONFIGROOT$])
|
||||
m4trace:configure.ac:129: -1- AC_SUBST([XLOCALEDIR])
|
||||
m4trace:configure.ac:129: -1- AC_SUBST_TRACE([XLOCALEDIR])
|
||||
m4trace:configure.ac:129: -1- m4_pattern_allow([^XLOCALEDIR$])
|
||||
m4trace:configure.ac:136: -1- AC_DEFINE_TRACE_LITERAL([DEFAULT_XKB_RULES])
|
||||
m4trace:configure.ac:136: -1- m4_pattern_allow([^DEFAULT_XKB_RULES$])
|
||||
m4trace:configure.ac:136: -1- AH_OUTPUT([DEFAULT_XKB_RULES], [/* Default XKB ruleset */
|
||||
@%:@undef DEFAULT_XKB_RULES])
|
||||
m4trace:configure.ac:144: -1- AC_DEFINE_TRACE_LITERAL([DEFAULT_XKB_MODEL])
|
||||
m4trace:configure.ac:144: -1- m4_pattern_allow([^DEFAULT_XKB_MODEL$])
|
||||
m4trace:configure.ac:144: -1- AH_OUTPUT([DEFAULT_XKB_MODEL], [/* Default XKB model */
|
||||
@%:@undef DEFAULT_XKB_MODEL])
|
||||
m4trace:configure.ac:152: -1- AC_DEFINE_TRACE_LITERAL([DEFAULT_XKB_LAYOUT])
|
||||
m4trace:configure.ac:152: -1- m4_pattern_allow([^DEFAULT_XKB_LAYOUT$])
|
||||
m4trace:configure.ac:152: -1- AH_OUTPUT([DEFAULT_XKB_LAYOUT], [/* Default XKB layout */
|
||||
@%:@undef DEFAULT_XKB_LAYOUT])
|
||||
m4trace:configure.ac:160: -1- AC_DEFINE_TRACE_LITERAL([DEFAULT_XKB_VARIANT])
|
||||
m4trace:configure.ac:160: -1- m4_pattern_allow([^DEFAULT_XKB_VARIANT$])
|
||||
m4trace:configure.ac:160: -1- AH_OUTPUT([DEFAULT_XKB_VARIANT], [/* Default XKB variant */
|
||||
@%:@undef DEFAULT_XKB_VARIANT])
|
||||
m4trace:configure.ac:170: -1- AC_DEFINE_TRACE_LITERAL([DEFAULT_XKB_OPTIONS])
|
||||
m4trace:configure.ac:170: -1- m4_pattern_allow([^DEFAULT_XKB_OPTIONS$])
|
||||
m4trace:configure.ac:170: -1- AH_OUTPUT([DEFAULT_XKB_OPTIONS], [/* Default XKB options */
|
||||
@%:@undef DEFAULT_XKB_OPTIONS])
|
||||
m4trace:configure.ac:179: -1- AC_SUBST([XCB_XKB_CFLAGS])
|
||||
m4trace:configure.ac:179: -1- AC_SUBST_TRACE([XCB_XKB_CFLAGS])
|
||||
m4trace:configure.ac:179: -1- m4_pattern_allow([^XCB_XKB_CFLAGS$])
|
||||
m4trace:configure.ac:179: -1- AC_SUBST([XCB_XKB_LIBS])
|
||||
m4trace:configure.ac:179: -1- AC_SUBST_TRACE([XCB_XKB_LIBS])
|
||||
m4trace:configure.ac:179: -1- m4_pattern_allow([^XCB_XKB_LIBS$])
|
||||
m4trace:configure.ac:184: -1- AM_CONDITIONAL([ENABLE_X11], [test "x$enable_x11" = xyes])
|
||||
m4trace:configure.ac:184: -1- AC_SUBST([ENABLE_X11_TRUE])
|
||||
m4trace:configure.ac:184: -1- AC_SUBST_TRACE([ENABLE_X11_TRUE])
|
||||
m4trace:configure.ac:184: -1- m4_pattern_allow([^ENABLE_X11_TRUE$])
|
||||
m4trace:configure.ac:184: -1- AC_SUBST([ENABLE_X11_FALSE])
|
||||
m4trace:configure.ac:184: -1- AC_SUBST_TRACE([ENABLE_X11_FALSE])
|
||||
m4trace:configure.ac:184: -1- m4_pattern_allow([^ENABLE_X11_FALSE$])
|
||||
m4trace:configure.ac:184: -1- _AM_SUBST_NOTMAKE([ENABLE_X11_TRUE])
|
||||
m4trace:configure.ac:184: -1- _AM_SUBST_NOTMAKE([ENABLE_X11_FALSE])
|
||||
m4trace:configure.ac:186: -1- AC_CONFIG_FILES([
|
||||
Makefile
|
||||
xkbcommon-uninstalled.pc
|
||||
xkbcommon.pc
|
||||
xkbcommon-x11.pc
|
||||
xkbcommon-x11-uninstalled.pc
|
||||
doc/Doxyfile
|
||||
])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([LIB@&t@OBJS])
|
||||
m4trace:configure.ac:194: -1- m4_pattern_allow([^LIB@&t@OBJS$])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([LTLIBOBJS])
|
||||
m4trace:configure.ac:194: -1- m4_pattern_allow([^LTLIBOBJS$])
|
||||
m4trace:configure.ac:194: -1- AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST([am__EXEEXT_TRUE])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([am__EXEEXT_TRUE])
|
||||
m4trace:configure.ac:194: -1- m4_pattern_allow([^am__EXEEXT_TRUE$])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST([am__EXEEXT_FALSE])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([am__EXEEXT_FALSE])
|
||||
m4trace:configure.ac:194: -1- m4_pattern_allow([^am__EXEEXT_FALSE$])
|
||||
m4trace:configure.ac:194: -1- _AM_SUBST_NOTMAKE([am__EXEEXT_TRUE])
|
||||
m4trace:configure.ac:194: -1- _AM_SUBST_NOTMAKE([am__EXEEXT_FALSE])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([top_builddir])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([top_build_prefix])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([srcdir])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([abs_srcdir])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([top_srcdir])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([abs_top_srcdir])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([builddir])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([abs_builddir])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([abs_top_builddir])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([INSTALL])
|
||||
m4trace:configure.ac:194: -1- AC_SUBST_TRACE([MKDIR_P])
|
||||
m4trace:configure.ac:194: -1- AC_REQUIRE_AUX_FILE([ltmain.sh])
|
File diff suppressed because it is too large
Load Diff
|
@ -1,247 +0,0 @@
|
|||
#! /bin/sh
|
||||
# ylwrap - wrapper for lex/yacc invocations.
|
||||
|
||||
scriptversion=2013-01-12.17; # UTC
|
||||
|
||||
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
get_dirname ()
|
||||
{
|
||||
case $1 in
|
||||
*/*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';;
|
||||
# Otherwise, we want the empty string (not ".").
|
||||
esac
|
||||
}
|
||||
|
||||
# guard FILE
|
||||
# ----------
|
||||
# The CPP macro used to guard inclusion of FILE.
|
||||
guard ()
|
||||
{
|
||||
printf '%s\n' "$1" \
|
||||
| sed \
|
||||
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
|
||||
-e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g' \
|
||||
-e 's/__*/_/g'
|
||||
}
|
||||
|
||||
# quote_for_sed [STRING]
|
||||
# ----------------------
|
||||
# Return STRING (or stdin) quoted to be used as a sed pattern.
|
||||
quote_for_sed ()
|
||||
{
|
||||
case $# in
|
||||
0) cat;;
|
||||
1) printf '%s\n' "$1";;
|
||||
esac \
|
||||
| sed -e 's|[][\\.*]|\\&|g'
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
'')
|
||||
echo "$0: No files given. Try '$0 --help' for more information." 1>&2
|
||||
exit 1
|
||||
;;
|
||||
--basedir)
|
||||
basedir=$2
|
||||
shift 2
|
||||
;;
|
||||
-h|--h*)
|
||||
cat <<\EOF
|
||||
Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]...
|
||||
|
||||
Wrapper for lex/yacc invocations, renaming files as desired.
|
||||
|
||||
INPUT is the input file
|
||||
OUTPUT is one file PROG generates
|
||||
DESIRED is the file we actually want instead of OUTPUT
|
||||
PROGRAM is program to run
|
||||
ARGS are passed to PROG
|
||||
|
||||
Any number of OUTPUT,DESIRED pairs may be used.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v|--v*)
|
||||
echo "ylwrap $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# The input.
|
||||
input=$1
|
||||
shift
|
||||
# We'll later need for a correct munging of "#line" directives.
|
||||
input_sub_rx=`get_dirname "$input" | quote_for_sed`
|
||||
case $input in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
# Absolute path; do nothing.
|
||||
;;
|
||||
*)
|
||||
# Relative path. Make it absolute.
|
||||
input=`pwd`/$input
|
||||
;;
|
||||
esac
|
||||
input_rx=`get_dirname "$input" | quote_for_sed`
|
||||
|
||||
# Since DOS filename conventions don't allow two dots,
|
||||
# the DOS version of Bison writes out y_tab.c instead of y.tab.c
|
||||
# and y_tab.h instead of y.tab.h. Test to see if this is the case.
|
||||
y_tab_nodot=false
|
||||
if test -f y_tab.c || test -f y_tab.h; then
|
||||
y_tab_nodot=true
|
||||
fi
|
||||
|
||||
# The parser itself, the first file, is the destination of the .y.c
|
||||
# rule in the Makefile.
|
||||
parser=$1
|
||||
|
||||
# A sed program to s/FROM/TO/g for all the FROM/TO so that, for
|
||||
# instance, we rename #include "y.tab.h" into #include "parse.h"
|
||||
# during the conversion from y.tab.c to parse.c.
|
||||
sed_fix_filenames=
|
||||
|
||||
# Also rename header guards, as Bison 2.7 for instance uses its header
|
||||
# guard in its implementation file.
|
||||
sed_fix_header_guards=
|
||||
|
||||
while test $# -ne 0; do
|
||||
if test x"$1" = x"--"; then
|
||||
shift
|
||||
break
|
||||
fi
|
||||
from=$1
|
||||
# Handle y_tab.c and y_tab.h output by DOS
|
||||
if $y_tab_nodot; then
|
||||
case $from in
|
||||
"y.tab.c") from=y_tab.c;;
|
||||
"y.tab.h") from=y_tab.h;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
to=$1
|
||||
shift
|
||||
sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;"
|
||||
sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;"
|
||||
done
|
||||
|
||||
# The program to run.
|
||||
prog=$1
|
||||
shift
|
||||
# Make any relative path in $prog absolute.
|
||||
case $prog in
|
||||
[\\/]* | ?:[\\/]*) ;;
|
||||
*[\\/]*) prog=`pwd`/$prog ;;
|
||||
esac
|
||||
|
||||
dirname=ylwrap$$
|
||||
do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
trap "ret=130; $do_exit" 2
|
||||
trap "ret=141; $do_exit" 13
|
||||
trap "ret=143; $do_exit" 15
|
||||
mkdir $dirname || exit 1
|
||||
|
||||
cd $dirname
|
||||
|
||||
case $# in
|
||||
0) "$prog" "$input" ;;
|
||||
*) "$prog" "$@" "$input" ;;
|
||||
esac
|
||||
ret=$?
|
||||
|
||||
if test $ret -eq 0; then
|
||||
for from in *
|
||||
do
|
||||
to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"`
|
||||
if test -f "$from"; then
|
||||
# If $2 is an absolute path name, then just use that,
|
||||
# otherwise prepend '../'.
|
||||
case $to in
|
||||
[\\/]* | ?:[\\/]*) target=$to;;
|
||||
*) target=../$to;;
|
||||
esac
|
||||
|
||||
# Do not overwrite unchanged header files to avoid useless
|
||||
# recompilations. Always update the parser itself: it is the
|
||||
# destination of the .y.c rule in the Makefile. Divert the
|
||||
# output of all other files to a temporary file so we can
|
||||
# compare them to existing versions.
|
||||
if test $from != $parser; then
|
||||
realtarget=$target
|
||||
target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'`
|
||||
fi
|
||||
|
||||
# Munge "#line" or "#" directives. Don't let the resulting
|
||||
# debug information point at an absolute srcdir. Use the real
|
||||
# output file name, not yy.lex.c for instance. Adjust the
|
||||
# include guards too.
|
||||
sed -e "/^#/!b" \
|
||||
-e "s|$input_rx|$input_sub_rx|" \
|
||||
-e "$sed_fix_filenames" \
|
||||
-e "$sed_fix_header_guards" \
|
||||
"$from" >"$target" || ret=$?
|
||||
|
||||
# Check whether files must be updated.
|
||||
if test "$from" != "$parser"; then
|
||||
if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then
|
||||
echo "$to is unchanged"
|
||||
rm -f "$target"
|
||||
else
|
||||
echo "updating $to"
|
||||
mv -f "$target" "$realtarget"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# A missing file is only an error for the parser. This is a
|
||||
# blatant hack to let us support using "yacc -d". If -d is not
|
||||
# specified, don't fail when the header file is "missing".
|
||||
if test "$from" = "$parser"; then
|
||||
ret=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Remove the directory.
|
||||
cd ..
|
||||
rm -rf $dirname
|
||||
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
|
@ -1,214 +0,0 @@
|
|||
dnl Copyright © 2008 Dan Nicholson
|
||||
dnl
|
||||
dnl Permission to use, copy, modify, distribute, and sell this software and its
|
||||
dnl documentation for any purpose is hereby granted without fee, provided that
|
||||
dnl the above copyright notice appear in all copies and that both that
|
||||
dnl copyright notice and this permission notice appear in supporting
|
||||
dnl documentation, and that the name of Keith Packard not be used in
|
||||
dnl advertising or publicity pertaining to distribution of the software without
|
||||
dnl specific, written prior permission. Keith Packard makes no
|
||||
dnl representations about the suitability of this software for any purpose. It
|
||||
dnl is provided "as is" without express or implied warranty.
|
||||
dnl
|
||||
dnl DAN NICHOLSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
dnl INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
dnl EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
dnl CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
dnl DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
dnl TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
dnl PERFORMANCE OF THIS SOFTWARE.
|
||||
dnl
|
||||
dnl Process this file with autoconf to create configure.
|
||||
|
||||
# Initialize Autoconf
|
||||
AC_PREREQ([2.62])
|
||||
AC_INIT([libxkbcommon], [0.5.0],
|
||||
[https://bugs.freedesktop.org/enter_bug.cgi?product=libxkbcommon],
|
||||
[libxkbcommon], [http://xkbcommon.org])
|
||||
AC_CONFIG_SRCDIR([Makefile.am])
|
||||
AC_CONFIG_HEADERS([src/config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
|
||||
# Initialize Automake
|
||||
AM_INIT_AUTOMAKE([foreign dist-xz no-dist-gzip subdir-objects color-tests parallel-tests check-news])
|
||||
AM_MAINTAINER_MODE([enable])
|
||||
|
||||
# Get _GNU_SOURCE and friends
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
# Initialize libtool
|
||||
LT_INIT
|
||||
|
||||
# Add xorg-macros stuff
|
||||
m4_ifndef([XORG_MACROS_VERSION],
|
||||
[m4_fatal([must install xorg-macros 1.16 or later before running autoconf/autogen])])
|
||||
XORG_MACROS_VERSION(1.16)
|
||||
XORG_DEFAULT_OPTIONS
|
||||
XORG_MEMORY_CHECK_FLAGS
|
||||
XORG_ENABLE_DOCS
|
||||
XORG_WITH_DOXYGEN
|
||||
|
||||
# Needed in older Automakes for subdir-objects
|
||||
AM_PROG_CC_C_O
|
||||
|
||||
# Check for compiler features
|
||||
AC_C_INLINE
|
||||
|
||||
# Check for programs
|
||||
AC_PROG_MKDIR_P
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
# Note: we use some yacc extensions, which work with either GNU bison
|
||||
# (preferred) or byacc. Other yacc's may or may not work.
|
||||
AC_PROG_YACC
|
||||
AC_PATH_PROG([YACC_INST], [$YACC])
|
||||
AS_IF([test ! -f "src/xkbcomp/parser.c" -a "x$YACC_INST" = x], [
|
||||
AC_MSG_ERROR([yacc not found - unable to compile src/xkbcomp/parser.y])
|
||||
])
|
||||
|
||||
# Checks for library functions.
|
||||
AC_CHECK_FUNCS([strcasecmp strncasecmp])
|
||||
AS_IF([test "x$ac_cv_func_strcasecmp" = xno -o \
|
||||
"x$ac_cv_func_strncasecmp" = xno], [
|
||||
AC_MSG_ERROR([C library does not support strcasecmp/strncasecmp])
|
||||
])
|
||||
|
||||
AC_CHECK_FUNCS([eaccess euidaccess mmap])
|
||||
|
||||
AC_CHECK_FUNCS([secure_getenv __secure_getenv])
|
||||
AS_IF([test "x$ac_cv_func_secure_getenv" = xno -a \
|
||||
"x$ac_cv_func___secure_getenv" = xno], [
|
||||
AC_MSG_WARN([C library does not support secure_getenv, using getenv instead])
|
||||
])
|
||||
|
||||
AX_GCC_BUILTIN(__builtin_expect)
|
||||
|
||||
# Some tests use Linux-specific headers
|
||||
AC_CHECK_HEADER([linux/input.h])
|
||||
AM_CONDITIONAL(BUILD_LINUX_TESTS, [test "x$ac_cv_header_linux_input_h" = xyes])
|
||||
|
||||
XORG_TESTSET_CFLAG([BASE_CFLAGS], [-fvisibility=hidden])
|
||||
XORG_TESTSET_CFLAG([BASE_CFLAGS], [-Wextra -Wno-unused-parameter -Wno-missing-field-initializers])
|
||||
XORG_TESTSET_CFLAG([BASE_CFLAGS], [-Wdocumentation])
|
||||
|
||||
# OpenBSD does not have DT_NEEDED entries for libc by design
|
||||
# so when these flags are passed to ld via libtool the checks will fail
|
||||
case "$host_os" in
|
||||
openbsd*)
|
||||
;;
|
||||
*)
|
||||
XORG_CHECK_LINKER_FLAGS([-Wl,--no-undefined], [have_no_undefined=yes]) ;;
|
||||
esac
|
||||
|
||||
AM_CONDITIONAL([HAVE_NO_UNDEFINED], [test "x$have_no_undefined" = xyes])
|
||||
|
||||
AC_CHECK_LIB(rt, clock_gettime,
|
||||
[AC_SUBST(RT_LIBS, "-lrt")],
|
||||
[AC_SUBST(RT_LIBS, "")],
|
||||
[-lrt])
|
||||
|
||||
# Define a configuration option for the XKB config root
|
||||
xkb_base=`$PKG_CONFIG --variable=xkb_base xkeyboard-config`
|
||||
AS_IF([test "x$xkb_base" = x], [
|
||||
xkb_base="$datadir/X11/xkb"
|
||||
])
|
||||
AC_ARG_WITH([xkb_config_root],
|
||||
[AS_HELP_STRING([--with-xkb-config-root=<path>],
|
||||
[Set default XKB config root (default: xkeyboard-config install path)])],
|
||||
[XKBCONFIGROOT="$withval"],
|
||||
[XKBCONFIGROOT="$xkb_base"])
|
||||
AC_SUBST([XKBCONFIGROOT])
|
||||
|
||||
# Define a configuration option for the X locale directory for compose
|
||||
AC_ARG_WITH([x_locale_root],
|
||||
[AS_HELP_STRING([--with-x-locale-root=<path>],
|
||||
[Set X locale root (default: $datadir/X11/locale)])],
|
||||
[XLOCALEDIR="$withval"],
|
||||
[XLOCALEDIR="$datadir/X11/locale"])
|
||||
AC_SUBST([XLOCALEDIR])
|
||||
|
||||
AC_ARG_WITH([default_rules],
|
||||
[AS_HELP_STRING([--with-default-rules=<path>],
|
||||
[Default XKB ruleset (default: evdev)])],
|
||||
[DEFAULT_XKB_RULES="$withval"],
|
||||
[DEFAULT_XKB_RULES="evdev"])
|
||||
AC_DEFINE_UNQUOTED([DEFAULT_XKB_RULES], ["$DEFAULT_XKB_RULES"],
|
||||
[Default XKB ruleset])
|
||||
|
||||
AC_ARG_WITH([default_model],
|
||||
[AS_HELP_STRING([--with-default-model=<path>],
|
||||
[Default XKB model (default: pc105)])],
|
||||
[DEFAULT_XKB_MODEL="$withval"],
|
||||
[DEFAULT_XKB_MODEL="pc105"])
|
||||
AC_DEFINE_UNQUOTED([DEFAULT_XKB_MODEL], ["$DEFAULT_XKB_MODEL"],
|
||||
[Default XKB model])
|
||||
|
||||
AC_ARG_WITH([default_layout],
|
||||
[AS_HELP_STRING([--with-default-layout=<path>],
|
||||
[Default XKB layout (default: us)])],
|
||||
[DEFAULT_XKB_LAYOUT="$withval"],
|
||||
[DEFAULT_XKB_LAYOUT="us"])
|
||||
AC_DEFINE_UNQUOTED([DEFAULT_XKB_LAYOUT], ["$DEFAULT_XKB_LAYOUT"],
|
||||
[Default XKB layout])
|
||||
|
||||
AC_ARG_WITH([default_variant],
|
||||
[AS_HELP_STRING([--with-default-variant=<path>],
|
||||
[Default XKB variant (default: (none))])],
|
||||
[DEFAULT_XKB_VARIANT="$withval"],
|
||||
[DEFAULT_XKB_VARIANT=])
|
||||
AS_IF([test "x$DEFAULT_XKB_VARIANT" != x], [
|
||||
AC_DEFINE_UNQUOTED([DEFAULT_XKB_VARIANT], ["$DEFAULT_XKB_VARIANT"],
|
||||
[Default XKB variant])
|
||||
])
|
||||
|
||||
AC_ARG_WITH([default_options],
|
||||
[AS_HELP_STRING([--with-default-options=<path>],
|
||||
[Default XKB options (default: (none))])],
|
||||
[DEFAULT_XKB_OPTIONS="$withval"],
|
||||
[DEFAULT_XKB_OPTIONS=])
|
||||
AS_IF([test "x$DEFAULT_XKB_OPTIONS" != x], [
|
||||
AC_DEFINE_UNQUOTED([DEFAULT_XKB_OPTIONS], ["$DEFAULT_XKB_OPTIONS"],
|
||||
[Default XKB options])
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE([x11],
|
||||
[AS_HELP_STRING([--disable-x11],
|
||||
[Disable support for creating keymaps with the X11 protocol (default: enabled)])],
|
||||
[], [enable_x11=yes])
|
||||
AS_IF([test "x$enable_x11" = xyes], [
|
||||
PKG_CHECK_MODULES([XCB_XKB], [xcb xcb-xkb >= 1.10], [],
|
||||
[AC_MSG_ERROR([xkbcommon-x11 requires xcb-xkb >= 1.10 which was not found. \
|
||||
You can disable X11 support with --disable-x11.])])
|
||||
], [enable_x11=no])
|
||||
AM_CONDITIONAL([ENABLE_X11], [test "x$enable_x11" = xyes])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
xkbcommon-uninstalled.pc
|
||||
xkbcommon.pc
|
||||
xkbcommon-x11.pc
|
||||
xkbcommon-x11-uninstalled.pc
|
||||
doc/Doxyfile
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
AC_MSG_RESULT([
|
||||
$PACKAGE_NAME $VERSION
|
||||
|
||||
libxkbcommon: yes
|
||||
libxkbcommon-x11: ${enable_x11}
|
||||
documentation: ${build_docs}
|
||||
|
||||
default XKB rules: ${DEFAULT_XKB_RULES}
|
||||
default XKB model: ${DEFAULT_XKB_MODEL}
|
||||
default XKB layout: ${DEFAULT_XKB_LAYOUT}
|
||||
default XKB variant: ${DEFAULT_XKB_VARIANT}
|
||||
default XKB options: ${DEFAULT_XKB_OPTIONS}
|
||||
|
||||
prefix: ${prefix}
|
||||
includedir: ${includedir}
|
||||
lib dir: ${libdir}
|
||||
XKB config root: ${XKBCONFIGROOT}
|
||||
X11 locale root: ${XLOCALEDIR}
|
||||
])
|
|
@ -1,3 +0,0 @@
|
|||
Doxyfile
|
||||
html/
|
||||
stamp-doxygen
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
# Compatibility
|
||||
|
||||
Relative to the XKB 1.1 specification implemented in current X servers,
|
||||
Relative to the XKB 1.0 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
|
||||
|
@ -42,8 +42,8 @@ Notable additions:
|
|||
- extended number of modifiers (planned)
|
||||
- extended number of groups (planned)
|
||||
- multiple keysyms per level
|
||||
+ this requires incompatible dataset changes, such that X11 would
|
||||
not be able to parse these
|
||||
+ such levels are ignored by x11/xkbcomp.
|
||||
- key names (e.g. `<AE11>`) can be longer than 4 characters.
|
||||
|
||||
## Compose support
|
||||
|
||||
|
@ -51,5 +51,6 @@ Relative to the standard implementation in libX11 (described in the
|
|||
Compose(5) man-page), some features are not supported:
|
||||
|
||||
- the (! MODIFIER) syntax
|
||||
+ parsed correctly but ignored.
|
||||
- using modifier keysyms in Compose sequences
|
||||
- several interactions with Braille keysyms
|
||||
|
|
|
@ -0,0 +1,472 @@
|
|||
# The XKB keymap text format, V1
|
||||
|
||||
This document describes the `XKB_KEYMAP_FORMAT_TEXT_V1` keymap format,
|
||||
as implemented by libxkbcommon.
|
||||
|
||||
NOTE: This document is ever incomplete. Some additional resources are:
|
||||
|
||||
- [Ivan Pascal's XKB documentation](https://web.archive.org/web/20190724015820/http://pascal.tsu.ru/en/xkb/)
|
||||
- [An Unreliable Guide to XKB Configuration](https://www.charvolant.org/doug/xkb/html/index.html)
|
||||
- [ArchWiki XKB page](https://wiki.archlinux.org/index.php/X_keyboard_extension)
|
||||
|
||||
A keymap consists of a single top-level `xkb_keymap` block, underwhich
|
||||
are nested the following sections.
|
||||
|
||||
|
||||
## 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:
|
||||
|
||||
<TLDE> = 49;
|
||||
<AE01> = 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
|
||||
`<WXYZ>` is always used to refer to a key by name.
|
||||
|
||||
[The naming convention `<AE01>` just denotes the position of the key
|
||||
in the main alphanumeric section of a standard QWERTY 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
|
||||
|
||||
correspond to the ones above. 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 <MENU> = <COMP>;
|
||||
|
||||
Allows to refer to a previously defined key (here `<COMP>`) by another
|
||||
name (here `<MENU>`). Conflicts are handled similarly to keycode
|
||||
statements.
|
||||
|
||||
### 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 (AKA indicator) with the given
|
||||
index. The LED may be referred by this name later in the compat
|
||||
section and by the user.
|
||||
|
||||
|
||||
## The `xkb_types` section
|
||||
|
||||
This section is the second to be processed, 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
|
||||
|
||||
level_name[Level1] = "Base";
|
||||
|
||||
Mandatory for each level in the type.
|
||||
|
||||
Gives each level in this type a descriptive name. It isn't used
|
||||
for anything.
|
||||
|
||||
Note: A level may be specified as Level[1-8] or just a number (can
|
||||
be more than 8).
|
||||
|
||||
#### `modifiers` statement
|
||||
|
||||
modifiers = Shift+Lock+LevelThree;
|
||||
|
||||
Mandatory, should be specified only once.
|
||||
|
||||
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
|
||||
|
||||
map[Shift+LevelThree] = Level4;
|
||||
|
||||
Should have at least as many mappings as there are levels in the type.
|
||||
|
||||
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 key type is used for keysym translation, its modifiers are said
|
||||
to be "consumed". For example, in a simple US keymap, the "g" "g" key
|
||||
is assigned an ordinary `ALPHABETIC` key type, whose modifiers are
|
||||
Shift and Lock; then for the "g" key, these two modifiers are consumed
|
||||
by the translation. 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 had already affected the key
|
||||
translation through the type, 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 (if
|
||||
there is no matching map entry, one mapping to Level1 is implicitly
|
||||
added). The right hand side should consists of modifiers from the
|
||||
type's modifiers; these modifiers are then "preserved" and not
|
||||
reported as consumed.
|
||||
|
||||
|
||||
## 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 below) allows the keymap author to
|
||||
perform, among other things, the following things 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 fails. 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 modifiers 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 using `AnyOfOrNone` while
|
||||
specifying all modifiers. Leaving out just the matching condition is
|
||||
equivalent to using `Exactly`.
|
||||
|
||||
An interpret may also include `useModMapMods = level1;` - see below.
|
||||
|
||||
If a level fulfils the conditions of several interprets, 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 statement 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.
|
||||
|
||||
#### `virtualModifier` 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 (AKA
|
||||
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` statement
|
||||
|
||||
modifiers = ScrollLock;
|
||||
|
||||
If the given modifiers are in the required state (see below), the
|
||||
LED is lit.
|
||||
|
||||
#### `whichModState` statement
|
||||
|
||||
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 modifier 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` statement
|
||||
|
||||
groups = All - group1;
|
||||
|
||||
If the given groups are in the required state (see below), the LED is
|
||||
lit.
|
||||
|
||||
#### `whichGroupState` statement
|
||||
|
||||
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.
|
||||
|
||||
|
||||
## The `xkb_symbols` section
|
||||
|
||||
NOTE: The documentation of this section is incomplete.
|
||||
|
||||
This section is the fourth to be processed, after `xkb_keycodes`, `xkb_types`
|
||||
and `xkb_compat`.
|
||||
|
||||
Statements of the form:
|
||||
|
||||
xkb_symbols "basic" {
|
||||
...
|
||||
}
|
||||
|
||||
Declare a symbols map named `basic`. Statements inside the curly braces only
|
||||
affect the symbols map.
|
||||
|
||||
A map can have various flags applied to it above the statement, separated by
|
||||
whitespace:
|
||||
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "basic" {
|
||||
...
|
||||
}
|
||||
|
||||
The possible flags are:
|
||||
|
||||
* `partial` - Indicates that the map doesn't cover a complete keyboard.
|
||||
* `default` - Marks the symbol map as the default map in the file when no
|
||||
explicit map is specified. If no map is marked as a default, the first map
|
||||
in the file is the default.
|
||||
* `hidden` - Variant that can only be used internally
|
||||
* `alphanumeric_keys` - Indicates that the map contains alphanumeric keys
|
||||
* `modifier_keys` - Indicates that the map contains modifier keys
|
||||
* `keypad_keys` - Indicates that the map contains keypad keys
|
||||
* `function_keys` - Indicates that the map contains function keys
|
||||
* `alternate_group` - Indicates that the map contains keys for an alternate
|
||||
group
|
||||
|
||||
If no `*_keys` flags are supplied, then the map is assumed to cover a complete
|
||||
keyboard.
|
||||
|
||||
At present, except for `default`, none of the flags affect key processing in
|
||||
libxkbcommon, and only serve as metadata.
|
||||
|
||||
### Name statements
|
||||
|
||||
Statements of the form:
|
||||
|
||||
name[Group1] = "US/ASCII";
|
||||
groupName[1] = "US/ASCII";
|
||||
|
||||
Gives the name "US/ASCII" to the first group of symbols. Other groups can be
|
||||
named using a different group index (ex: `Group2`), and with a different name.
|
||||
A group must be named.
|
||||
|
||||
`group` and `groupName` mean the same thing, and the `Group` in `Group1` is
|
||||
optional.
|
||||
|
||||
### Include statements
|
||||
|
||||
Statements of the form:
|
||||
|
||||
include "nokia_vndr/rx-51(nordic_base)
|
||||
|
||||
Will include data from another `xkb_symbols` section, possibly located in
|
||||
another file. Here it would include the `xkb_symbols` section called
|
||||
`nordic_base`, from the file `rx-51` located in the `nokia_vndr` folder, itself
|
||||
located in an XKB include path.
|
||||
|
||||
### Key statement
|
||||
|
||||
Statements of the form:
|
||||
|
||||
key <AD01> { [ q, Q ] };
|
||||
|
||||
Describes the mapping of a keycode `<AD01>` to a given group of symbols. The
|
||||
possible keycodes are the keycodes defined in the `xkb_keycodes` section.
|
||||
|
||||
Symbols are named using the symbolic names from the
|
||||
`xkbcommon/xkbcommon-keysyms.h` file. A group of symbols is enclosed in brackets
|
||||
and separated by commas. Each element of the symbol arrays corresponds to a
|
||||
different modifier level. In this example, the symbol (keysym) `XKB_KEY_q` for
|
||||
level 1 and `XKB_KEY_Q` for level 2.
|
||||
|
||||
#### Groups
|
||||
|
||||
Each group represents a list of symbols mapped to a keycode:
|
||||
|
||||
name[Group1]= "US/ASCII";
|
||||
name[Group2]= "Russian";
|
||||
...
|
||||
key <AD01> { [ q, Q ],
|
||||
[ Cyrillic_shorti, Cyrillic_SHORTI ] };
|
||||
|
||||
A long-form syntax can also be used:
|
||||
|
||||
key <AD01> {
|
||||
symbols[Group1]= [ q, Q ],
|
||||
symbols[Group2]= [ Cyrillic_shorti, Cyrillic_SHORTI ]
|
||||
};
|
||||
|
||||
Groups can also be omitted, but the brackets must be present. The following
|
||||
statement only defines the Group3 of a mapping:
|
||||
|
||||
key <AD01> { [], [], [ q, Q ] };
|
||||
|
||||
## Virtual modifier statements
|
||||
|
||||
Statements of the form:
|
||||
|
||||
virtual_modifiers LControl;
|
||||
|
||||
Can appear in the `xkb_types`, `xkb_compat`, `xkb_symbols` sections.
|
||||
|
||||
TODO
|
|
@ -1,359 +0,0 @@
|
|||
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:
|
||||
|
||||
<TLDE> = 49;
|
||||
<AE01> = 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 <WXYZ> is
|
||||
always used to refer to a key by name.
|
||||
|
||||
[The naming convention <AE01> 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
|
||||
|
||||
correspond to the ones above. 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 <MENU> = <COMP>;
|
||||
|
||||
Allows to refer to a previously defined key (here <COMP>) by another
|
||||
name (here <MENU>). Conflicts are handled similarly to keycode
|
||||
statements.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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 anything.
|
||||
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.
|
||||
|
||||
|
||||
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 below) allows the keymap author to perform,
|
||||
among other things, the following things 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 fails. 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 modifiers 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 using AnyOfOrNone while
|
||||
specifying all modifiers. Leaving out just the matching condition
|
||||
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 statement 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 statement:
|
||||
|
||||
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.
|
||||
|
||||
|
||||
The xkb_symbols section
|
||||
=======================
|
||||
|
||||
This section is the fourth to be processed, after xkb_keycodes,
|
||||
xkb_types and xkb_compat.
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
Virtual modifier statements
|
||||
===========================
|
||||
|
||||
Statements of the form:
|
||||
virtual_modifiers LControl;
|
||||
|
||||
Can appear in the xkb_types, xkb_compat, xkb_symbols sections.
|
||||
TODO
|
|
@ -16,9 +16,11 @@ the library. We will employ a few use-cases to lead the examples:
|
|||
The snippets are not complete, and some support code is omitted. You
|
||||
can find complete and more complex examples in the source directory:
|
||||
|
||||
1. test/interactive-evdev.c contains an interactive evdev client.
|
||||
1. tools/interactive-evdev.c contains an interactive evdev client.
|
||||
|
||||
2. test/interactive-x11.c contains an interactive X11 client.
|
||||
2. tools/interactive-x11.c contains an interactive X11 client.
|
||||
|
||||
3. tools/interactive-wayland.c contains an interactive Wayland client.
|
||||
|
||||
Also, the library contains many more functions for examining and using
|
||||
the library context, the keymap and the keyboard state. See the
|
||||
|
@ -27,22 +29,21 @@ xkbcommon/ for more details.
|
|||
|
||||
## Code
|
||||
|
||||
Before we can do anything interesting, we need a library context. So
|
||||
let's create one:
|
||||
Before we can do anything interesting, we need a library context:
|
||||
|
||||
~~~{.c}
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
struct xkb_context ctx;
|
||||
struct xkb_context *ctx;
|
||||
|
||||
ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (!ctx) <error>
|
||||
~~~
|
||||
|
||||
The xkb_context contains the keymap include paths, the log level and
|
||||
The `xkb_context` contains the keymap include paths, the log level and
|
||||
functions, and other general customizable administrativia.
|
||||
|
||||
Next we need to create a keymap, xkb_keymap. This is an immutable object
|
||||
Next we need to create a keymap, `xkb_keymap`. This is an immutable object
|
||||
which contains all of the information about the keys, layouts, etc. There
|
||||
are different ways to do this.
|
||||
|
||||
|
@ -50,8 +51,8 @@ If we are an evdev client, we have nothing to go by, so we need to ask
|
|||
the user for his/her keymap preferences (for example, an Icelandic
|
||||
keyboard with a Dvorak layout). The configuration format is commonly
|
||||
called RMLVO (Rules+Model+Layout+Variant+Options), the same format used
|
||||
by the X server. With it, we can fill a struct called xkb_rule_names;
|
||||
passing NULL chooses the system's default.
|
||||
by the X server. With it, we can fill a struct called `xkb_rule_names`;
|
||||
passing `NULL` chooses the system's default.
|
||||
|
||||
~~~{.c}
|
||||
struct xkb_keymap *keymap;
|
||||
|
@ -75,6 +76,7 @@ with a keymap. In this case, we can create the keymap object like this:
|
|||
~~~{.c}
|
||||
/* From the wl_keyboard::keymap event. */
|
||||
const char *keymap_string = <...>;
|
||||
struct xkb_keymap *keymap;
|
||||
|
||||
keymap = xkb_keymap_new_from_string(ctx, keymap_string,
|
||||
XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||
|
@ -101,7 +103,7 @@ we will use the core keyboard device:
|
|||
~~~
|
||||
|
||||
Now that we have the keymap, we are ready to handle the keyboard devices.
|
||||
For each device, we create an xkb_state, which remembers things like which
|
||||
For each device, we create an `xkb_state`, which remembers things like which
|
||||
keyboard modifiers and LEDs are active:
|
||||
|
||||
~~~{.c}
|
||||
|
@ -118,7 +120,7 @@ For X11/XCB clients, this is better:
|
|||
if (!state) <error>
|
||||
~~~
|
||||
|
||||
When we have an xkb_state for a device, we can start handling key events
|
||||
When we have an `xkb_state` for a device, we can start handling key events
|
||||
from it. Given a keycode for a key, we can get its keysym:
|
||||
|
||||
~~~{.c}
|
||||
|
@ -165,7 +167,7 @@ We can also get a UTF-8 string representation for this key:
|
|||
xkb_state_key_get_utf8(state, keycode, buffer, size);
|
||||
~~~
|
||||
|
||||
Of course, we also need to keep the xkb_state up-to-date with the
|
||||
Of course, we also need to keep the `xkb_state` up-to-date with the
|
||||
keyboard device, if we want to get the correct keysyms in the future.
|
||||
|
||||
If we are an evdev client, we must let the library know whether a key
|
||||
|
@ -183,7 +185,7 @@ is pressed or released at any given time:
|
|||
The `changed` return value tells us exactly which parts of the state
|
||||
have changed.
|
||||
|
||||
If is is a key-repeat event, we can ask the keymap what to do with it:
|
||||
If it is a key-repeat event, we can ask the keymap what to do with it:
|
||||
|
||||
~~~{.c}
|
||||
if (<key repeat> && !xkb_keymap_key_repeats(keymap, keycode))
|
||||
|
@ -205,7 +207,7 @@ information usually comes in a form of some "state changed" event):
|
|||
event->locked_layout);
|
||||
~~~
|
||||
|
||||
Now that we have an always-up-to-date xkb_state, we can examine it.
|
||||
Now that we have an always-up-to-date `xkb_state`, we can examine it.
|
||||
For example, we can check whether the Control modifier is active, or
|
||||
whether the Num Lock LED is active:
|
||||
|
||||
|
@ -218,8 +220,7 @@ whether the Num Lock LED is active:
|
|||
<The Num Lock LED is active>
|
||||
~~~
|
||||
|
||||
And that's it! When we're finished, we should free the objects we've
|
||||
created:
|
||||
And that's it! Eventually, we should free the objects we've created:
|
||||
|
||||
~~~{.c}
|
||||
xkb_state_unref(state);
|
||||
|
|
|
@ -38,9 +38,12 @@ near the end.
|
|||
Grammar
|
||||
-------
|
||||
(It might be helpful to look at a file like rules/evdev along with
|
||||
this grammer. Comments, whitespace, etc. are not shown.)
|
||||
this grammar. Comments, whitespace, etc. are not shown.)
|
||||
|
||||
File ::= { "!" (Group | RuleSet) }
|
||||
```
|
||||
File ::= { "!" (Include | Group | RuleSet) }
|
||||
|
||||
Include ::= "include" <ident>
|
||||
|
||||
Group ::= GroupName "=" { GroupElement } "\n"
|
||||
GroupName ::= "$"<ident>
|
||||
|
@ -56,9 +59,27 @@ Kccgst ::= "keycodes" | "symbols" | "types" | "compat" | "geometry"
|
|||
Rule ::= { MlvoValue } "=" { KccgstValue } "\n"
|
||||
MlvoValue ::= "*" | GroupName | <ident>
|
||||
KccgstValue ::= <ident>
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Include processes the rules in the file path specified in the ident,
|
||||
in order. %-expansion is performed, as follows:
|
||||
|
||||
```
|
||||
%%:
|
||||
A literal %.
|
||||
|
||||
%H:
|
||||
The value of the HOME environment variable.
|
||||
|
||||
%E:
|
||||
The extra lookup path for system-wide XKB data (usually /etc/xkb/rules).
|
||||
|
||||
%S:
|
||||
The system-installed rules directory (usually /usr/share/X11/xkb/rules).
|
||||
```
|
||||
|
||||
- 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.
|
||||
|
@ -66,6 +87,7 @@ Notes:
|
|||
- 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).
|
||||
|
@ -80,6 +102,7 @@ Notes:
|
|||
|
||||
%(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
|
|
@ -0,0 +1,232 @@
|
|||
# User-configuration
|
||||
|
||||
This page describes how to add a custom layout or option so that it will be
|
||||
parsed by libxkbcommon.
|
||||
|
||||
**The below requires libxkbcommon as keymap compiler and does not work in X**.
|
||||
|
||||
## Data locations
|
||||
|
||||
libxkbcommon searches the following paths for XKB configuration files:
|
||||
- `$XDG_CONFIG_HOME/xkb/`, or `$HOME/.config/xkb/` if the `$XDG_CONFIG_HOME`
|
||||
environment variable is not defined
|
||||
- `$HOME/.xkb/`
|
||||
- `$XKB_CONFIG_EXTRA_PATH` if set, otherswise `<sysconfdir>/xkb` (on most
|
||||
distributions this is `/etc/xkb`)
|
||||
- `$XKB_CONFIG_ROOT` if set, otherwise `<datadir>/X11/xkb/` (path defined by the
|
||||
`xkeyboard-config` package, on most distributions this is
|
||||
`/usr/share/X11/xkb`)
|
||||
|
||||
A keymap created with `xkb_keymap_new_from_names()` will look up those paths in
|
||||
order until the required data is found.
|
||||
|
||||
**Note: Where libxkbcommon runs in a privileged context, only the system
|
||||
(datadir) path is available.**
|
||||
|
||||
Each directory should have one or more of the following subdirectories:
|
||||
- `compat`
|
||||
- `geometry` (libxkbcommon ignores this directory)
|
||||
- `keycodes`
|
||||
- `rules`
|
||||
- `symbols`
|
||||
- `types`
|
||||
|
||||
The majority of user-specific configuration involve modifying key symbols and
|
||||
this is what this document focuses on. For use-cases where a user may need to
|
||||
add new key types or compat entries the general approach remains the same. A
|
||||
detailed description for how to add those types or compat entries is out of
|
||||
scope for this document.
|
||||
|
||||
You should never need to add user-specific keycodes. Where a keycode is missing,
|
||||
the addition should be filed in the upstream xkeyboard-config project.
|
||||
|
||||
## RMLVO vs KcCGST
|
||||
|
||||
Due to how XKB is configured, there is no such thing as a "layout" in XKB
|
||||
itself, or, indeed, any of the rules, models, variant, options (RMLVO) decribed
|
||||
in `struct xkb_rule_names`. RMLVO names are merely lookup keys in the
|
||||
rules file provided by xkeyboard-config to map to the correct keycode, compat,
|
||||
geometry (ignored by libxkbcommon), symbols and types (KcCGST). The KcCGST data
|
||||
is the one used by XKB and libxbkcommon to map keys to actual symbols.
|
||||
|
||||
For example, a common RMLVO configuration is layout "us", variant "dvorak" and
|
||||
option "terminate:ctrl_alt_bksp". Using the default rules file and model
|
||||
this maps into the following KcCGST components:
|
||||
|
||||
```
|
||||
xkb_keymap {
|
||||
xkb_keycodes { include "evdev+aliases(qwerty)" };
|
||||
xkb_types { include "complete" };
|
||||
xkb_compat { include "complete" };
|
||||
xkb_symbols { include "pc+us(dvorak)+inet(evdev)+terminate(ctrl_alt_bksp)" };
|
||||
xkb_geometry { include "pc(pc105)" };
|
||||
};
|
||||
```
|
||||
|
||||
A detailed explanation of how rules files convert RMLVO to KcCGST is out of
|
||||
scope for this document. See [the rules file](md_doc_rules-format.html) page
|
||||
instead.
|
||||
|
||||
|
||||
## Adding a layout
|
||||
|
||||
Adding a layout requires that the user adds **symbols** in the correct location.
|
||||
|
||||
The default rules files (usually `evdev`) have a catch-all to map a layout, say
|
||||
"foo", and a variant, say "bar", into the "bar" section in the file
|
||||
`$xkb_base_dir/symbols/foo`.
|
||||
This is sufficient to define a new keyboard layout. The example below defines
|
||||
the keyboard layout "banana" with an optional variant "orange"
|
||||
|
||||
```
|
||||
$ cat $XDG_CONFIG_HOME/xkb/symbols/banana
|
||||
// Like a US layout but swap the top row so numbers are on Shift
|
||||
default partial alphanumeric_keys
|
||||
xkb_symbols "basic" {
|
||||
include "us(basic)"
|
||||
name[Group1]= "Banana (US)";
|
||||
|
||||
key <AE01> { [ exclam, 1] };
|
||||
key <AE02> { [ at, 2] };
|
||||
key <AE03> { [ numbersign, 3] };
|
||||
key <AE04> { [ dollar, 4] };
|
||||
key <AE05> { [ percent, 5] };
|
||||
key <AE06> { [ asciicircum, 6] };
|
||||
key <AE07> { [ ampersand, 7] };
|
||||
key <AE08> { [ asterisk, 8] };
|
||||
key <AE09> { [ parenleft, 9] };
|
||||
key <AE10> { [ parenright, 0] };
|
||||
key <AE11> { [ underscore, minus] };
|
||||
key <AE12> { [ plus, equal] };
|
||||
};
|
||||
|
||||
// Same as banana but map the euro sign to the 5 key
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "orange" {
|
||||
include "banana(basic)"
|
||||
name[Group1] = "Banana (Eurosign on 5)";
|
||||
include "eurosign(5)"
|
||||
};
|
||||
```
|
||||
|
||||
The `default` section is loaded when no variant is given. The first example
|
||||
sections uses ``include`` to populate with a symbols list defined elsewhere
|
||||
(here: section `basic` from the file `symbols/us`, aka. the default US keyboard
|
||||
layout) and overrides parts of these
|
||||
symbols. The effect of this section is to swap the numbers and symbols in the
|
||||
top-most row (compared to the US layout) but otherwise use the US layout.
|
||||
|
||||
The "orange" variant uses the "banana" symbols and includes a different section
|
||||
to define the eurosign. It does not specificially override any symbols.
|
||||
|
||||
The exact details of how `xkb_symbols` work is out of scope for this document.
|
||||
|
||||
## Adding an option
|
||||
|
||||
For technical reasons, options do **not** have a catch-all to map option names
|
||||
to files and sections and must be specifically mapped by the user. This requires
|
||||
a custom rules file. As the `evdev` ruleset is hardcoded in many clients, the
|
||||
custom rules file must usually be named `evdev`.
|
||||
|
||||
```
|
||||
$ cat $XDG_CONFIG_HOME/xkb/rules/evdev
|
||||
! option = symbols
|
||||
custom:foo = +custom(bar)
|
||||
custom:baz = +other(baz)
|
||||
|
||||
! include %S/evdev
|
||||
```
|
||||
|
||||
This rules file maps the RMLVO option "custom:foo" to the "bar" section in the
|
||||
`symbols/custom` file and the "custom:baz" option to the "baz" section in the
|
||||
`symbols/other` file. Note how the RMLVO option name may be different to the
|
||||
file or section name.
|
||||
|
||||
The `include` statement includes the system-provided `evdev` ruleset. This
|
||||
allows users to only override those options they need.
|
||||
|
||||
The files themselves are similar to the layout examples in the previous section:
|
||||
|
||||
```
|
||||
$ cat $XDG_CONFIG_HOME/xkb/symbols/custom
|
||||
// map the Tilde key to nothing on the first shift level
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "bar" {
|
||||
key <TLDE> { [ VoidSymbol ] };
|
||||
};
|
||||
|
||||
$ cat $XDG_CONFIG_HOME/xkb/symbols/other
|
||||
// map first key in bottom row (Z in the US layout) to k/K
|
||||
partial alphanumeric_keys
|
||||
xkb_symbols "baz" {
|
||||
key <AB01> { [ k, K ] };
|
||||
};
|
||||
```
|
||||
|
||||
With these in place, a user may select any layout/variant together with
|
||||
the "custom:foo" and/or "custom:baz" options.
|
||||
|
||||
## Discoverable layouts
|
||||
|
||||
**The below requires libxkbregistry as XKB lookup tool and does not work where
|
||||
clients parse the XML file directly**.
|
||||
|
||||
The above sections apply only to the data files and require that the user knows
|
||||
about the existence of the new entries. To make custom entries discoverable by
|
||||
the configuration tools (e.g. the GNOME Control Center), the new entries must
|
||||
also be added to the XML file that is parsed by libxkbregistry. In most cases,
|
||||
this is the `evdev.xml` file in the rules directory. The example below shows the
|
||||
XML file that would add the custom layout and custom options as outlined above
|
||||
to the XKB registry:
|
||||
|
||||
```
|
||||
$ cat $XDG_CONFIG_HOME/xkb/rules/evdev.xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xkbConfigRegistry SYSTEM "xkb.dtd">
|
||||
<xkbConfigRegistry version="1.1">
|
||||
<layoutList>
|
||||
<layout>
|
||||
<configItem>
|
||||
<name>banana</name>
|
||||
<shortDescription>ban</shortDescription>
|
||||
<description>Banana</description>
|
||||
</configItem>
|
||||
<variantList>
|
||||
<variant>
|
||||
<configItem>
|
||||
<name>orange</name>
|
||||
<shortDescription>or</shortDescription>
|
||||
<description>Orange (Banana)</description>
|
||||
</configItem>
|
||||
</variant>
|
||||
</variantList>
|
||||
</layout>
|
||||
</layoutList>
|
||||
<optionList>
|
||||
<group allowMultipleSelection="true">
|
||||
<configItem>
|
||||
<name>custom</name>
|
||||
<description>Custom options</description>
|
||||
</configItem>
|
||||
<option>
|
||||
<configItem>
|
||||
<name>custom:foo</name>
|
||||
<description>Map Tilde to nothing</description>
|
||||
</configItem>
|
||||
</option>
|
||||
<option>
|
||||
<configItem>
|
||||
<name>custom:baz</name>
|
||||
<description>Map Z to K</description>
|
||||
</configItem>
|
||||
</option>
|
||||
</group>
|
||||
</optionList>
|
||||
</xkbConfigRegistry>
|
||||
```
|
||||
|
||||
The default behavior of libxkbregistry ensures that the new layout and options
|
||||
are added to the system-provided layouts and options.
|
||||
|
||||
For details on the XML format, see DTD in `<datadir>/X11/xkb/rules/xkb.dtd`
|
||||
and the system-provided XML files in `<datadir>/X11/xkb/rulies/xkb.dtd`.
|
|
@ -0,0 +1,8 @@
|
|||
"Ctrl"
|
||||
"Lock"
|
||||
"Caps"
|
||||
"Shift"
|
||||
"Alt"
|
||||
"Meta"
|
||||
"None"
|
||||
"acute"
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* A target program for fuzzing the Compose text format.
|
||||
*
|
||||
* Currently, just parses an input file, and hopefully doesn't crash or hang.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "xkbcommon/xkbcommon.h"
|
||||
#include "xkbcommon/xkbcommon-compose.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct xkb_context *ctx;
|
||||
FILE *file;
|
||||
struct xkb_compose_table *table;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s <file>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ctx = xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES | XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
|
||||
assert(ctx);
|
||||
|
||||
#ifdef __AFL_HAVE_MANUAL_CONTROL
|
||||
__AFL_INIT();
|
||||
|
||||
while (__AFL_LOOP(1000))
|
||||
#endif
|
||||
{
|
||||
file = fopen(argv[1], "rb");
|
||||
assert(file);
|
||||
table = xkb_compose_table_new_from_file(ctx, file,
|
||||
"en_US.UTF-8",
|
||||
XKB_COMPOSE_FORMAT_TEXT_V1,
|
||||
XKB_COMPOSE_COMPILE_NO_FLAGS);
|
||||
xkb_compose_table_unref(table);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
puts(table ? "OK" : "FAIL");
|
||||
xkb_context_unref(ctx);
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
<dead_tilde> <space> : "~" asciitilde # X
|
||||
Meta <Multi_key> !Alt ~Shift <apostrophe> <apostrophe> : "\"\'\x43\123abc" acute # Y
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
keymap|compose)
|
||||
;;
|
||||
*)
|
||||
echo "usage: $0 keymap|compose" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
export CC=afl-clang-fast
|
||||
export AFL_HARDEN=1
|
||||
test -d fuzz/build || meson setup -Db_lto=true fuzz/build
|
||||
ninja -C fuzz/build
|
||||
afl-fuzz -i fuzz/$1/testcases -x fuzz/$1/dict -o fuzz/$1/findings -t 200 -m 10 -- ./fuzz/build/fuzz-$1 @@
|
|
@ -0,0 +1,120 @@
|
|||
"Control"
|
||||
"Group1"
|
||||
"Group5"
|
||||
"Lock"
|
||||
"Mod1"
|
||||
"Mod9"
|
||||
"Shift"
|
||||
"U1"
|
||||
"0x1"
|
||||
"Up"
|
||||
"accel"
|
||||
"action"
|
||||
"actions"
|
||||
"affect"
|
||||
"alias"
|
||||
"all"
|
||||
"allowexplicit"
|
||||
"allownone"
|
||||
"alphanumeric_keys"
|
||||
"alternate"
|
||||
"alternate_group"
|
||||
"any"
|
||||
"augment"
|
||||
"both"
|
||||
"button"
|
||||
"clearLocks"
|
||||
"clearmods"
|
||||
"controls"
|
||||
"count"
|
||||
"ctrls"
|
||||
"data"
|
||||
"default"
|
||||
"dev"
|
||||
"device"
|
||||
"dfltbtn"
|
||||
"driveskbd"
|
||||
"false"
|
||||
"foo"
|
||||
"function_keys"
|
||||
"genKeyEvent"
|
||||
"group"
|
||||
"groupname"
|
||||
"groups"
|
||||
"groupsclamp"
|
||||
"groupsredirect"
|
||||
"groupswrap"
|
||||
"hidden"
|
||||
"include"
|
||||
"increment"
|
||||
"index"
|
||||
"indicator"
|
||||
"indicatordriveskbd"
|
||||
"interpret"
|
||||
"kc"
|
||||
"key"
|
||||
"keycode"
|
||||
"keypad_keys"
|
||||
"keys"
|
||||
"latchToLock"
|
||||
"leddriveskbd"
|
||||
"levelname"
|
||||
"lock"
|
||||
"locking"
|
||||
"logo"
|
||||
"map"
|
||||
"mod_map"
|
||||
"modifier_keys"
|
||||
"modifier_map"
|
||||
"modifiers"
|
||||
"modmap"
|
||||
"modmapmods"
|
||||
"mods"
|
||||
"name"
|
||||
"neither"
|
||||
"no"
|
||||
"none"
|
||||
"nosymbol"
|
||||
"off"
|
||||
"on"
|
||||
"outline"
|
||||
"overlay"
|
||||
"override"
|
||||
"partial"
|
||||
"preserve"
|
||||
"radiogroup"
|
||||
"repeat"
|
||||
"replace"
|
||||
"report"
|
||||
"row"
|
||||
"same"
|
||||
"sameServer"
|
||||
"screen"
|
||||
"section"
|
||||
"shape"
|
||||
"solid"
|
||||
"symbols"
|
||||
"text"
|
||||
"true"
|
||||
"type"
|
||||
"unlock"
|
||||
"usemodmap"
|
||||
"value"
|
||||
"virtual"
|
||||
"virtual_modifiers"
|
||||
"virtualmod"
|
||||
"vmods"
|
||||
"voidsymbol"
|
||||
"whichgroupstate"
|
||||
"whichmodstate"
|
||||
"x"
|
||||
"xkb_compat"
|
||||
"xkb_geometry"
|
||||
"xkb_keycodes"
|
||||
"xkb_keymap"
|
||||
"xkb_layout"
|
||||
"xkb_semantics"
|
||||
"xkb_symbols"
|
||||
"xkb_types"
|
||||
"y"
|
||||
"yes"
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* A target program for fuzzing the XKB keymap text format.
|
||||
*
|
||||
* Currently, just parses an input file, and hopefully doesn't crash or hang.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "xkbcommon/xkbcommon.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct xkb_context *ctx;
|
||||
FILE *file;
|
||||
struct xkb_keymap *keymap;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s <file>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ctx = xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES | XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
|
||||
assert(ctx);
|
||||
|
||||
#ifdef __AFL_HAVE_MANUAL_CONTROL
|
||||
__AFL_INIT();
|
||||
|
||||
while (__AFL_LOOP(1000))
|
||||
#endif
|
||||
{
|
||||
file = fopen(argv[1], "rb");
|
||||
assert(file);
|
||||
keymap = xkb_keymap_new_from_file(ctx, file,
|
||||
XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
xkb_keymap_unref(keymap);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
puts(keymap ? "OK" : "FAIL");
|
||||
xkb_context_unref(ctx);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
xkb_keymap{
|
||||
xkb_keycodes"0"{
|
||||
minimum=0;
|
||||
maximum=500;
|
||||
<a>=0;
|
||||
indicator 1="X";
|
||||
alias<X>=<Y>;
|
||||
};
|
||||
xkb_types"X"{
|
||||
virtual_modifiers NumLock;
|
||||
type"X"{
|
||||
modifiers=Shift;
|
||||
map[Shift]=Level2;
|
||||
level_name[Level1]="X";
|
||||
preserve[Shift]=Shift;
|
||||
};
|
||||
};
|
||||
partial xkb_compat{
|
||||
virtual_modifiers Alt;
|
||||
interpret.useModMapMods=AnyLevel;
|
||||
interpret.repeat=False;
|
||||
interpret.locking=False;
|
||||
interpret ISO_Level2_Latch+Exactly(Shift){
|
||||
repeat=True;
|
||||
virtualModifier=NumLock;
|
||||
useModMapMods=level1;
|
||||
action=LatchMods(modifiers=Shift,clearLocks,latchToLock);
|
||||
action=MovePtr(x=+0,y=-0);
|
||||
action=SwitchScreen(screen=00,!same);
|
||||
action=Private(type=0x80,data[0]=0x00);
|
||||
};
|
||||
indicator"X"{whichModState=locked;modifiers=Lock;};
|
||||
};
|
||||
xkb_symbols{
|
||||
name[group1]="X";
|
||||
key<Y>{type[group2]="X",symbols[Group1]=[0,exclam],symbols[Group2]=[0xff,U00],symbols[Group3]=[z]};
|
||||
modifier_map Control{<a>};
|
||||
};
|
||||
default xkb_geometry"X"{
|
||||
description="X";
|
||||
width=470;
|
||||
shape.cornerRadius=1;
|
||||
shape"NORM"{cornerRadius=0,{[0.0,0]},{[0,0],[0,0.0]}};
|
||||
solid"X"{shape="X";top=00;left=00;color="X";};
|
||||
indicator.onColor="X";
|
||||
indicator.top=00.0;
|
||||
indicator.shape="X";
|
||||
indicator"X"{left=0;};
|
||||
text.top=00;
|
||||
text.color="X";
|
||||
text"X"{left=0;text="X";};
|
||||
section.left=00;
|
||||
row.left=0;
|
||||
key.shape="X";
|
||||
key.gap=1;
|
||||
section"X"{top=22;row{top=1;keys{{<X>,color="X"},{<X>,00.0},<X>,<X>,<X>};};};
|
||||
alias<AC00>=<CAPS>;
|
||||
};
|
||||
};
|
|
@ -55,13 +55,13 @@ extern "C" {
|
|||
* Here are some example sequences, in the libX11 Compose file format:
|
||||
*
|
||||
* <dead_acute> <a> : "á" aacute # LATIN SMALL LETTER A WITH ACUTE
|
||||
* <Multi_key> <A> <T> : "@" at # COMMERCIAL AT
|
||||
* <Multi_key> <A> <T> : "@" at # COMMERCIAL AT
|
||||
*
|
||||
* When the user presses a key which produces the \<dead_acute> keysym,
|
||||
* When the user presses a key which produces the `<dead_acute>` keysym,
|
||||
* nothing initially happens (thus the key is dubbed a "dead-key"). But
|
||||
* when the user enters <a>, "á" is "composed", in place of "a". If
|
||||
* when the user enters `<a>`, "á" is "composed", in place of "a". If
|
||||
* instead the user had entered a keysym which does not follow
|
||||
* \<dead_acute\> in any compose sequence, the sequence is said to be
|
||||
* `<dead_acute>` in any compose sequence, the sequence is said to be
|
||||
* "cancelled".
|
||||
*
|
||||
* Compose files define many such sequences. For a description of the
|
||||
|
@ -73,7 +73,7 @@ extern "C" {
|
|||
* result string (using xkb_keysym_to_utf8()).
|
||||
*
|
||||
* This library provides low-level support for Compose file parsing and
|
||||
* processing. Higher-level APIs (such as libX11's Xutf8LookupString(3))
|
||||
* processing. Higher-level APIs (such as libX11's `Xutf8LookupString`(3))
|
||||
* may be built upon it, or it can be used directly.
|
||||
*
|
||||
* @endparblock
|
||||
|
@ -90,7 +90,7 @@ extern "C" {
|
|||
* 2. An equal sequence overrides an existing one.
|
||||
* 3. A shorter sequence does not override a longer one.
|
||||
*
|
||||
* Sequences of length 1 are allowed, although they are not common.
|
||||
* Sequences of length 1 are allowed.
|
||||
*
|
||||
* @endparblock
|
||||
*/
|
||||
|
@ -100,15 +100,15 @@ extern "C" {
|
|||
* @parblock
|
||||
*
|
||||
* What should happen when a sequence is cancelled? For example, consider
|
||||
* there are only the above sequences, and the input kesysms are
|
||||
* \<dead_acute\> \<b\>. There are a few approaches:
|
||||
* there are only the above sequences, and the input keysyms are
|
||||
* `<dead_acute> <b>`. There are a few approaches:
|
||||
*
|
||||
* 1. Swallow the cancelling keysym; that is, no keysym is produced.
|
||||
* This is the approach taken by libX11.
|
||||
* 2. Let the cancelling keysym through; that is, \<b\> is produced.
|
||||
* 3. Replay the entire sequence; that is, \<dead_acute\> \<b\> is produced.
|
||||
* 2. Let the cancelling keysym through; that is, `<b>` is produced.
|
||||
* 3. Replay the entire sequence; that is, `<dead_acute> <b>` is produced.
|
||||
* This is the approach taken by Microsoft Windows (approximately;
|
||||
* instead of \<dead_acute\>, the underlying key is used. This is
|
||||
* instead of `<dead_acute>`, the underlying key is used. This is
|
||||
* difficult to simulate with XKB keymaps).
|
||||
*
|
||||
* You can program whichever approach best fits users' expectations.
|
||||
|
@ -158,9 +158,10 @@ enum xkb_compose_format {
|
|||
* - Compose files are written for a locale, and the locale is used when
|
||||
* searching for the appropriate file to use.
|
||||
* - Compose files may reference the locale internally, with directives
|
||||
* such as %L.
|
||||
* such as \%L.
|
||||
*
|
||||
* As such, functions like xkb_compose_table_new_from_locale() require
|
||||
* a @p locale parameter. This will usually be the current locale (see
|
||||
* a `locale` parameter. This will usually be the current locale (see
|
||||
* locale(7) for more details). You may also want to allow the user to
|
||||
* explicitly configure it, so he can use the Compose file of a given
|
||||
* locale, but not use that locale for other things.
|
||||
|
@ -172,19 +173,20 @@ enum xkb_compose_format {
|
|||
* @endcode
|
||||
*
|
||||
* This will only give useful results if the program had previously set
|
||||
* the current locale using setlocale(3), with LC_CTYPE or LC_ALL and a
|
||||
* non-NULL argument.
|
||||
* the current locale using setlocale(3), with `LC_CTYPE` or `LC_ALL`
|
||||
* and a non-NULL argument.
|
||||
*
|
||||
* If you prefer not to use the locale system of the C runtime library,
|
||||
* you may nevertheless obtain the user's locale directly using
|
||||
* environment variables, as described in locale(7). For example,
|
||||
* @code
|
||||
* const char *locale;
|
||||
* locale = getenv("LC_ALL");
|
||||
* if (!locale)
|
||||
* if (!locale || !*locale)
|
||||
* locale = getenv("LC_CTYPE");
|
||||
* if (!locale)
|
||||
* if (!locale || !*locale)
|
||||
* locale = getenv("LANG");
|
||||
* if (!locale)
|
||||
* if (!locale || !*locale)
|
||||
* locale = "C";
|
||||
* @endcode
|
||||
*
|
||||
|
@ -200,12 +202,28 @@ enum xkb_compose_format {
|
|||
* The locale is used for searching the file-system for an appropriate
|
||||
* Compose file. The search order is described in Compose(5). It is
|
||||
* affected by the following environment variables:
|
||||
* XCOMPOSEFILE, HOME, XLOCALEDIR.
|
||||
*
|
||||
* 1. `XCOMPOSEFILE` - see Compose(5).
|
||||
* 2. `XDG_CONFIG_HOME` - before `$HOME/.XCompose` is checked,
|
||||
* `$XDG_CONFIG_HOME/XCompose` is checked (with a fall back to
|
||||
* `$HOME/.config/XCompose` if `XDG_CONFIG_HOME` is not defined).
|
||||
* This is a libxkbcommon extension to the search procedure in
|
||||
* Compose(5) (since libxkbcommon 1.0.0). Note that other
|
||||
* implementations, such as libX11, might not find a Compose file in
|
||||
* this path.
|
||||
* 3. `HOME` - see Compose(5).
|
||||
* 4. `XLOCALEDIR` - if set, used as the base directory for the system's
|
||||
* X locale files, e.g. `/usr/share/X11/locale`, instead of the
|
||||
* preconfigured directory.
|
||||
*
|
||||
* @param context
|
||||
* The library context in which to create the compose table.
|
||||
* @param locale
|
||||
* The current locale. See @ref compose-locale.
|
||||
* \n
|
||||
* The value is copied, so it is safe to pass the result of getenv(3)
|
||||
* (or similar) without fear of it being invalidated by a subsequent
|
||||
* setenv(3) (or similar).
|
||||
* @param flags
|
||||
* Optional flags for the compose table, or 0.
|
||||
*
|
||||
|
@ -362,15 +380,15 @@ enum xkb_compose_feed_result {
|
|||
* Feed one keysym to the Compose sequence state machine.
|
||||
*
|
||||
* This function can advance into a compose sequence, cancel a sequence,
|
||||
* start a new sequence, or do nothing in particular . The resulting
|
||||
* start a new sequence, or do nothing in particular. The resulting
|
||||
* status may be observed with xkb_compose_state_get_status().
|
||||
*
|
||||
* Some keysyms, such as keysysm for modifier keys, are ignored - they
|
||||
* Some keysyms, such as keysyms for modifier keys, are ignored - they
|
||||
* have no effect on the status or otherwise.
|
||||
*
|
||||
* The following is a description of the possible status transitions, in
|
||||
* the format CURRENT STATUS => NEXT STATUS, given a non-ignored input
|
||||
* keysym @p keysym:
|
||||
* keysym `keysym`:
|
||||
*
|
||||
@verbatim
|
||||
NOTHING or CANCELLED or COMPOSED =>
|
||||
|
@ -389,8 +407,8 @@ enum xkb_compose_feed_result {
|
|||
*
|
||||
* The current Compose formats do not support multiple-keysyms.
|
||||
* Therefore, if you are using a function such as xkb_state_key_get_syms()
|
||||
* and it returns more than one keysym, consider feeding
|
||||
* @p XKB_KEY_NoSymbol instead.
|
||||
* and it returns more than one keysym, consider feeding XKB_KEY_NoSymbol
|
||||
* instead.
|
||||
*
|
||||
* @param state
|
||||
* The compose state object.
|
||||
|
@ -446,12 +464,11 @@ xkb_compose_state_get_status(struct xkb_compose_state *state);
|
|||
* @returns
|
||||
* The number of bytes required for the string, excluding the NUL byte.
|
||||
* If the sequence is not complete, or does not have a viable result
|
||||
* string, returns 0, and sets @p buffer to the empty string (if
|
||||
* possible).
|
||||
* string, returns 0, and sets `buffer` to the empty string (if possible).
|
||||
* @returns
|
||||
* 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
|
||||
* with the size of `buffer`, similarly to the `snprintf`(3) function.
|
||||
* You may safely pass NULL and 0 to `buffer` and `size` to find the
|
||||
* required size (without the NUL-byte).
|
||||
*
|
||||
* @memberof xkb_compose_state
|
File diff suppressed because it is too large
Load Diff
|
@ -54,7 +54,7 @@ extern "C" {
|
|||
* can be used as a replacement for Xlib's keyboard handling.
|
||||
*
|
||||
* Following is an example workflow using xkbcommon-x11. A complete
|
||||
* example may be found in the test/interactive-x11.c file in the
|
||||
* example may be found in the tools/interactive-x11.c file in the
|
||||
* xkbcommon source repository. On startup:
|
||||
*
|
||||
* 1. Connect to the X server using xcb_connect().
|
||||
|
@ -64,10 +64,9 @@ extern "C" {
|
|||
*
|
||||
* The XKB extension supports using separate keymaps and states for
|
||||
* different keyboard devices. The devices are identified by an integer
|
||||
* device ID and are managed by another X11 extension, XInput (or its
|
||||
* successor, XInput2). The original X11 protocol only had one keyboard
|
||||
* device, called the "core keyboard", which is still supported as a
|
||||
* "virtual device".
|
||||
* device ID and are managed by another X11 extension, XInput. The
|
||||
* original X11 protocol only had one keyboard device, called the "core
|
||||
* keyboard", which is still supported as a "virtual device".
|
||||
*
|
||||
* 3. We will use the core keyboard as an example. To get its device ID,
|
||||
* use either the xcb_xkb_get_device_info() request directly, or the
|
||||
|
@ -79,7 +78,7 @@ extern "C" {
|
|||
*
|
||||
* @note At this point, you may consider setting various XKB controls and
|
||||
* XKB per-client flags. For example, enabling detectable autorepeat: \n
|
||||
* http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Detectable_Autorepeat
|
||||
* https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Detectable_Autorepeat
|
||||
*
|
||||
* Next, you need to react to state changes (e.g. a modifier was pressed,
|
||||
* the layout was changed) and to keymap changes (e.g. a tool like xkbcomp,
|
||||
|
@ -96,7 +95,7 @@ extern "C" {
|
|||
* @note It is also possible to use the KeyPress/KeyRelease @p state
|
||||
* field to find the effective modifier and layout state, instead of
|
||||
* using XkbStateNotify: \n
|
||||
* http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Computing_A_State_Field_from_an_XKB_State
|
||||
* https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Computing_A_State_Field_from_an_XKB_State
|
||||
* \n However, XkbStateNotify is more accurate.
|
||||
*
|
||||
* @note There is no need to call xkb_state_update_key(); the state is
|
||||
|
@ -197,8 +196,9 @@ xkb_x11_get_core_keyboard_device_id(xcb_connection_t *connection);
|
|||
* @param connection
|
||||
* An XCB connection to the X server.
|
||||
* @param device_id
|
||||
* An XInput 1 device ID (in the range 0-255) with input class KEY.
|
||||
* Passing values outside of this range is an error.
|
||||
* An XInput device ID (in the range 0-127) with input class KEY.
|
||||
* Passing values outside of this range is an error (the XKB protocol
|
||||
* predates the XInput2 protocol, which first allowed IDs > 127).
|
||||
* @param flags
|
||||
* Optional flags for the keymap, or 0.
|
||||
*
|
|
@ -152,6 +152,10 @@ struct xkb_state;
|
|||
* underlying input system. For example, with an X11-compatible keymap
|
||||
* and Linux evdev scan codes (see linux/input.h), a fixed offset is used:
|
||||
*
|
||||
* The keymap defines a canonical name for each key, plus possible aliases.
|
||||
* Historically, the XKB protocol restricts these names to at most 4 (ASCII)
|
||||
* characters, but this library does not share this limit.
|
||||
*
|
||||
* @code
|
||||
* xkb_keycode_t keycode_A = KEY_A + 8;
|
||||
* @endcode
|
||||
|
@ -173,7 +177,7 @@ typedef uint32_t xkb_keycode_t;
|
|||
* somewhat more general, in that they can also represent some "function",
|
||||
* such as "Left" or "Right" for the arrow keys. For more information,
|
||||
* see:
|
||||
* http://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html#keysym_encoding
|
||||
* https://www.x.org/releases/current/doc/xproto/x11protocol.html#keysym_encoding
|
||||
*
|
||||
* Specifically named keysyms can be found in the
|
||||
* xkbcommon/xkbcommon-keysyms.h header file. Their name does not include
|
||||
|
@ -204,6 +208,15 @@ typedef uint32_t xkb_keysym_t;
|
|||
* Therefore, it is not safe to use the name as a unique identifier for a
|
||||
* layout. Layout names are case-sensitive.
|
||||
*
|
||||
* Layout names are specified in the layout's definition, for example
|
||||
* "English (US)". These are different from the (conventionally) short names
|
||||
* which are used to locate the layout, for example "us" or "us(intl)". These
|
||||
* names are not present in a compiled keymap.
|
||||
*
|
||||
* If the user selects layouts from a list generated from the XKB registry
|
||||
* (using libxkbregistry or directly), and this metadata is needed later on, it
|
||||
* is recommended to store it along with the keymap.
|
||||
*
|
||||
* Layouts are also called "groups" by XKB.
|
||||
*
|
||||
* @sa xkb_keymap_num_layouts() xkb_keymap_num_layouts_for_key()
|
||||
|
@ -342,6 +355,9 @@ struct xkb_rule_names {
|
|||
* A comma separated list of variants, one per layout, which may
|
||||
* modify or augment the respective layout in various ways.
|
||||
*
|
||||
* Generally, should either be empty or have the same number of values
|
||||
* as the number of layouts. You may use empty values as in "intl,,neo".
|
||||
*
|
||||
* 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.
|
||||
|
@ -381,7 +397,7 @@ struct xkb_rule_names {
|
|||
* Similarly, the UTF-8/UTF-32 string produced is capitalized.
|
||||
*
|
||||
* This is described in:
|
||||
* http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier
|
||||
* https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier
|
||||
*
|
||||
* - Control transformation. If the Control modifier is active and
|
||||
* was not consumed by the translation process, the string produced
|
||||
|
@ -389,7 +405,7 @@ struct xkb_rule_names {
|
|||
* applicable). Keysyms are not affected.
|
||||
*
|
||||
* This is described in:
|
||||
* http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier
|
||||
* https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier
|
||||
*
|
||||
* Each relevant function discusses which transformations it performs.
|
||||
*
|
||||
|
@ -445,6 +461,9 @@ enum xkb_keysym_flags {
|
|||
* fails, only then to try with this flag, while possibly warning the user
|
||||
* he had misspelled the name, and might get wrong results.
|
||||
*
|
||||
* Case folding is done according to the C locale; the current locale is not
|
||||
* consulted.
|
||||
*
|
||||
* @returns The keysym. If the name is invalid, returns XKB_KEY_NoSymbol.
|
||||
*
|
||||
* @sa xkb_keysym_t
|
||||
|
@ -486,6 +505,49 @@ xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size);
|
|||
uint32_t
|
||||
xkb_keysym_to_utf32(xkb_keysym_t keysym);
|
||||
|
||||
/**
|
||||
* Get the keysym corresponding to a Unicode/UTF-32 codepoint.
|
||||
*
|
||||
* @returns The keysym corresponding to the specified Unicode
|
||||
* codepoint, or XKB_KEY_NoSymbol if there is none.
|
||||
*
|
||||
* This function is the inverse of @ref xkb_keysym_to_utf32. In cases
|
||||
* where a single codepoint corresponds to multiple keysyms, returns
|
||||
* the keysym with the lowest value.
|
||||
*
|
||||
* Unicode codepoints which do not have a special (legacy) keysym
|
||||
* encoding use a direct encoding scheme. These keysyms don't usually
|
||||
* have an associated keysym constant (XKB_KEY_*).
|
||||
*
|
||||
* For noncharacter Unicode codepoints and codepoints outside of the
|
||||
* defined Unicode planes this function returns XKB_KEY_NoSymbol.
|
||||
*
|
||||
* @sa xkb_keysym_to_utf32()
|
||||
* @since 1.0.0
|
||||
*/
|
||||
xkb_keysym_t
|
||||
xkb_utf32_to_keysym(uint32_t ucs);
|
||||
|
||||
/**
|
||||
* Convert a keysym to its uppercase form.
|
||||
*
|
||||
* If there is no such form, the keysym is returned unchanged.
|
||||
*
|
||||
* The conversion rules may be incomplete; prefer to work with the Unicode
|
||||
* representation instead, when possible.
|
||||
*/
|
||||
xkb_keysym_t
|
||||
xkb_keysym_to_upper(xkb_keysym_t ks);
|
||||
|
||||
/**
|
||||
* Convert a keysym to its lowercase form.
|
||||
*
|
||||
* The conversion rules may be incomplete; prefer to work with the Unicode
|
||||
* representation instead, when possible.
|
||||
*/
|
||||
xkb_keysym_t
|
||||
xkb_keysym_to_lower(xkb_keysym_t ks);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -498,6 +560,18 @@ xkb_keysym_to_utf32(xkb_keysym_t keysym);
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page envvars Environment Variables
|
||||
*
|
||||
* The user may set some environment variables which affect the library:
|
||||
*
|
||||
* - `XKB_CONFIG_ROOT`, `XKB_CONFIG_EXTRA_PATH`, `XDG_CONFIG_DIR`, `HOME` - see @ref include-path.
|
||||
* - `XKB_LOG_LEVEL` - see xkb_context_set_log_level().
|
||||
* - `XKB_LOG_VERBOSITY` - see xkb_context_set_log_verbosity().
|
||||
* - `XKB_DEFAULT_RULES`, `XKB_DEFAULT_MODEL`, `XKB_DEFAULT_LAYOUT`,
|
||||
* `XKB_DEFAULT_VARIANT`, `XKB_DEFAULT_OPTIONS` - see xkb_rule_names.
|
||||
*/
|
||||
|
||||
/** Flags for context creation. */
|
||||
enum xkb_context_flags {
|
||||
/** Do not apply any context flags. */
|
||||
|
@ -518,10 +592,6 @@ enum xkb_context_flags {
|
|||
*
|
||||
* @returns A new context, or NULL on failure.
|
||||
*
|
||||
* The user may set some environment variables to affect default values in
|
||||
* the context. See e.g. xkb_context_set_log_level() and
|
||||
* xkb_context_set_log_verbosity().
|
||||
*
|
||||
* @memberof xkb_context
|
||||
*/
|
||||
struct xkb_context *
|
||||
|
@ -580,7 +650,17 @@ xkb_context_get_user_data(struct xkb_context *context);
|
|||
*
|
||||
* The include paths are the file-system paths that are searched when an
|
||||
* include statement is encountered during keymap compilation.
|
||||
* In most cases, the default include paths are sufficient.
|
||||
*
|
||||
* The default include paths are, in that lookup order:
|
||||
* - The path `$XDG_CONFIG_HOME/xkb`, with the usual `XDG_CONFIG_HOME`
|
||||
* fallback to `$HOME/.config/` if unset.
|
||||
* - The path `$HOME/.xkb`, where $HOME is the value of the environment
|
||||
* variable `HOME`.
|
||||
* - The `XKB_CONFIG_EXTRA_PATH` environment variable, if defined, otherwise the
|
||||
* system configuration directory, defined at library configuration time
|
||||
* (usually `/etc/xkb`).
|
||||
* - The `XKB_CONFIG_ROOT` environment variable, if defined, otherwise
|
||||
* the system XKB root, defined at library configuration time.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
@ -875,7 +955,7 @@ xkb_keymap_unref(struct xkb_keymap *keymap);
|
|||
*
|
||||
* @returns The keymap as a NUL-terminated string, or NULL if unsuccessful.
|
||||
*
|
||||
* The returned string may be fed back into xkb_map_new_from_string() to get
|
||||
* The returned string may be fed back into xkb_keymap_new_from_string() to get
|
||||
* the exact same keymap (possibly in another process, etc.).
|
||||
*
|
||||
* The returned string is dynamically allocated and should be freed by the
|
||||
|
@ -940,6 +1020,37 @@ void
|
|||
xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter,
|
||||
void *data);
|
||||
|
||||
/**
|
||||
* Find the name of the key with the given keycode.
|
||||
*
|
||||
* This function always returns the canonical name of the key (see
|
||||
* description in xkb_keycode_t).
|
||||
*
|
||||
* @returns The key name. If no key with this keycode exists,
|
||||
* returns NULL.
|
||||
*
|
||||
* @sa xkb_keycode_t
|
||||
* @memberof xkb_keymap
|
||||
* @since 0.6.0
|
||||
*/
|
||||
const char *
|
||||
xkb_keymap_key_get_name(struct xkb_keymap *keymap, xkb_keycode_t key);
|
||||
|
||||
/**
|
||||
* Find the keycode of the key with the given name.
|
||||
*
|
||||
* The name can be either a canonical name or an alias.
|
||||
*
|
||||
* @returns The keycode. If no key with this name exists,
|
||||
* returns XKB_KEYCODE_INVALID.
|
||||
*
|
||||
* @sa xkb_keycode_t
|
||||
* @memberof xkb_keymap
|
||||
* @since 0.6.0
|
||||
*/
|
||||
xkb_keycode_t
|
||||
xkb_keymap_key_by_name(struct xkb_keymap *keymap, const char *name);
|
||||
|
||||
/**
|
||||
* Get the number of modifiers in the keymap.
|
||||
*
|
||||
|
@ -988,6 +1099,7 @@ xkb_keymap_num_layouts(struct xkb_keymap *keymap);
|
|||
* a name, returns NULL.
|
||||
*
|
||||
* @sa xkb_layout_index_t
|
||||
* For notes on layout names.
|
||||
* @memberof xkb_keymap
|
||||
*/
|
||||
const char *
|
||||
|
@ -1000,6 +1112,8 @@ xkb_keymap_layout_get_name(struct xkb_keymap *keymap, xkb_layout_index_t idx);
|
|||
* XKB_LAYOUT_INVALID. If more than one layout in the keymap has this name,
|
||||
* returns the lowest index among them.
|
||||
*
|
||||
* @sa xkb_layout_index_t
|
||||
* For notes on layout names.
|
||||
* @memberof xkb_keymap
|
||||
*/
|
||||
xkb_layout_index_t
|
||||
|
@ -1067,6 +1181,49 @@ xkb_level_index_t
|
|||
xkb_keymap_num_levels_for_key(struct xkb_keymap *keymap, xkb_keycode_t key,
|
||||
xkb_layout_index_t layout);
|
||||
|
||||
/**
|
||||
* Retrieves every possible modifier mask that produces the specified
|
||||
* shift level for a specific key and layout.
|
||||
*
|
||||
* This API is useful for inverse key transformation; i.e. finding out
|
||||
* which modifiers need to be active in order to be able to type the
|
||||
* keysym(s) corresponding to the specific key code, layout and level.
|
||||
*
|
||||
* @warning It returns only up to masks_size modifier masks. If the
|
||||
* buffer passed is too small, some of the possible modifier combinations
|
||||
* will not be returned.
|
||||
*
|
||||
* @param[in] keymap The keymap.
|
||||
* @param[in] key The keycode of the key.
|
||||
* @param[in] layout The layout for which to get modifiers.
|
||||
* @param[in] level The shift level in the layout for which to get the
|
||||
* modifiers. This should be smaller than:
|
||||
* @code xkb_keymap_num_levels_for_key(keymap, key) @endcode
|
||||
* @param[out] masks_out A buffer in which the requested masks should be
|
||||
* stored.
|
||||
* @param[out] masks_size The size of the buffer pointed to by masks_out.
|
||||
*
|
||||
* If @c layout is out of range for this key (that is, larger or equal to
|
||||
* the value returned by xkb_keymap_num_layouts_for_key()), it is brought
|
||||
* back into range in a manner consistent with xkb_state_key_get_layout().
|
||||
*
|
||||
* @returns The number of modifier masks stored in the masks_out array.
|
||||
* If the key is not in the keymap or if the specified shift level cannot
|
||||
* be reached it returns 0 and does not modify the masks_out buffer.
|
||||
*
|
||||
* @sa xkb_level_index_t
|
||||
* @sa xkb_mod_mask_t
|
||||
* @memberof xkb_keymap
|
||||
* @since 1.0.0
|
||||
*/
|
||||
size_t
|
||||
xkb_keymap_key_get_mods_for_level(struct xkb_keymap *keymap,
|
||||
xkb_keycode_t key,
|
||||
xkb_layout_index_t layout,
|
||||
xkb_level_index_t level,
|
||||
xkb_mod_mask_t *masks_out,
|
||||
size_t masks_size);
|
||||
|
||||
/**
|
||||
* Get the keysyms obtained from pressing a key in a given layout and
|
||||
* shift level.
|
||||
|
@ -1079,7 +1236,7 @@ xkb_keymap_num_levels_for_key(struct xkb_keymap *keymap, xkb_keycode_t key,
|
|||
* @param[in] key The keycode of the key.
|
||||
* @param[in] layout The layout for which to get the keysyms.
|
||||
* @param[in] level The shift level in the layout for which to get the
|
||||
* keysyms. This must be smaller than:
|
||||
* keysyms. This should be smaller than:
|
||||
* @code xkb_keymap_num_levels_for_key(keymap, key) @endcode
|
||||
* @param[out] syms_out An immutable array of keysyms corresponding to the
|
||||
* key in the given layout and shift level.
|
||||
|
@ -1200,7 +1357,7 @@ enum xkb_state_component {
|
|||
XKB_STATE_MODS_LOCKED = (1 << 2),
|
||||
/** Effective modifiers, i.e. currently active and affect key
|
||||
* processing (derived from the other state components).
|
||||
* Use this unless you explictly care how the state came about. */
|
||||
* Use this unless you explicitly care how the state came about. */
|
||||
XKB_STATE_MODS_EFFECTIVE = (1 << 3),
|
||||
/** Depressed layout, i.e. a key is physically holding it. */
|
||||
XKB_STATE_LAYOUT_DEPRESSED = (1 << 4),
|
||||
|
@ -1212,7 +1369,7 @@ enum xkb_state_component {
|
|||
XKB_STATE_LAYOUT_LOCKED = (1 << 6),
|
||||
/** Effective layout, i.e. currently active and affects key processing
|
||||
* (derived from the other state components).
|
||||
* Use this unless you explictly care how the state came about. */
|
||||
* Use this unless you explicitly care how the state came about. */
|
||||
XKB_STATE_LAYOUT_EFFECTIVE = (1 << 7),
|
||||
/** LEDs (derived from the other state components). */
|
||||
XKB_STATE_LEDS = (1 << 8)
|
||||
|
@ -1223,10 +1380,10 @@ enum xkb_state_component {
|
|||
* released.
|
||||
*
|
||||
* This entry point is intended for programs which track the keyboard state
|
||||
* explictly (like an evdev client). If the state is serialized to you by
|
||||
* explicitly (like an evdev client). If the state is serialized to you by
|
||||
* a master process (like a Wayland compositor) using functions like
|
||||
* xkb_state_serialize_mods(), you should use xkb_state_update_mask() instead.
|
||||
* The two functins should not generally be used together.
|
||||
* The two functions should not generally be used together.
|
||||
*
|
||||
* A series of calls to this function should be consistent; that is, a call
|
||||
* with XKB_KEY_DOWN for a key should be matched by an XKB_KEY_UP; if a key
|
||||
|
@ -1601,7 +1758,7 @@ xkb_state_mod_indices_are_active(struct xkb_state *state,
|
|||
* Effectively, this means that consumed modifiers (Shift in this example)
|
||||
* are masked out as well, before doing the comparison.
|
||||
*
|
||||
* In summary, this is how the matching would be performed:
|
||||
* In summary, this is approximately how the matching would be performed:
|
||||
* @code
|
||||
* (keysym == shortcut_keysym) &&
|
||||
* ((state_mods & ~consumed_mods & significant_mods) == shortcut_mods)
|
||||
|
@ -1617,16 +1774,100 @@ xkb_state_mod_indices_are_active(struct xkb_state *state,
|
|||
* @endparblock
|
||||
*/
|
||||
|
||||
/**
|
||||
* Consumed modifiers mode.
|
||||
*
|
||||
* There are several possible methods for deciding which modifiers are
|
||||
* consumed and which are not, each applicable for different systems or
|
||||
* situations. The mode selects the method to use.
|
||||
*
|
||||
* Keep in mind that in all methods, the keymap may decide to "preserve"
|
||||
* a modifier, meaning it is not reported as consumed even if it would
|
||||
* have otherwise.
|
||||
*/
|
||||
enum xkb_consumed_mode {
|
||||
/**
|
||||
* This is the mode defined in the XKB specification and used by libX11.
|
||||
*
|
||||
* A modifier is consumed if and only if it *may affect* key translation.
|
||||
*
|
||||
* For example, if `Control+Alt+<Backspace>` produces some assigned keysym,
|
||||
* then when pressing just `<Backspace>`, `Control` and `Alt` are consumed,
|
||||
* even though they are not active, since if they *were* active they would
|
||||
* have affected key translation.
|
||||
*/
|
||||
XKB_CONSUMED_MODE_XKB,
|
||||
/**
|
||||
* This is the mode used by the GTK+ toolkit.
|
||||
*
|
||||
* The mode consists of the following two independent heuristics:
|
||||
*
|
||||
* - The currently active set of modifiers, excluding modifiers which do
|
||||
* not affect the key (as described for @ref XKB_CONSUMED_MODE_XKB), are
|
||||
* considered consumed, if the keysyms produced when all of them are
|
||||
* active are different from the keysyms produced when no modifiers are
|
||||
* active.
|
||||
*
|
||||
* - A single modifier is considered consumed if the keysyms produced for
|
||||
* the key when it is the only active modifier are different from the
|
||||
* keysyms produced when no modifiers are active.
|
||||
*/
|
||||
XKB_CONSUMED_MODE_GTK
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the mask of modifiers consumed by translating a given key.
|
||||
*
|
||||
* @param state The keyboard state.
|
||||
* @param key The keycode of the key.
|
||||
* @param mode The consumed modifiers mode to use; see enum description.
|
||||
*
|
||||
* @returns a mask of the consumed modifiers.
|
||||
*
|
||||
* @memberof xkb_state
|
||||
* @since 0.7.0
|
||||
*/
|
||||
xkb_mod_mask_t
|
||||
xkb_state_key_get_consumed_mods2(struct xkb_state *state, xkb_keycode_t key,
|
||||
enum xkb_consumed_mode mode);
|
||||
|
||||
/**
|
||||
* Same as xkb_state_key_get_consumed_mods2() with mode XKB_CONSUMED_MODE_XKB.
|
||||
*
|
||||
* @memberof xkb_state
|
||||
* @since 0.4.1
|
||||
*/
|
||||
xkb_mod_mask_t
|
||||
xkb_state_key_get_consumed_mods(struct xkb_state *state, xkb_keycode_t key);
|
||||
|
||||
/**
|
||||
* Test whether a modifier is consumed by keyboard state translation for
|
||||
* a key.
|
||||
*
|
||||
* @param state The keyboard state.
|
||||
* @param key The keycode of the key.
|
||||
* @param idx The index of the modifier to check.
|
||||
* @param mode The consumed modifiers mode to use; see enum description.
|
||||
*
|
||||
* @returns 1 if the modifier is consumed, 0 if it is not. If the modifier
|
||||
* 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
|
||||
* @since 0.7.0
|
||||
*/
|
||||
int
|
||||
xkb_state_mod_index_is_consumed2(struct xkb_state *state,
|
||||
xkb_keycode_t key,
|
||||
xkb_mod_index_t idx,
|
||||
enum xkb_consumed_mode mode);
|
||||
|
||||
/**
|
||||
* Same as xkb_state_mod_index_is_consumed2() with mode XKB_CONSUMED_MOD_XKB.
|
||||
*
|
||||
* @memberof xkb_state
|
||||
* @since 0.4.1
|
||||
*/
|
||||
int
|
||||
xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t key,
|
||||
|
@ -1635,6 +1876,8 @@ xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t key,
|
|||
/**
|
||||
* Remove consumed modifiers from a modifier mask for a key.
|
||||
*
|
||||
* @deprecated Use xkb_state_key_get_consumed_mods2() instead.
|
||||
*
|
||||
* Takes the given modifier mask, and removes all modifiers which are
|
||||
* consumed for that particular key (as in xkb_state_mod_index_is_consumed()).
|
||||
*
|
||||
|
@ -1645,18 +1888,6 @@ 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
|
||||
* @since 0.4.1
|
||||
*/
|
||||
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.
|
||||
*
|
|
@ -0,0 +1,782 @@
|
|||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* 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 _XKBREGISTRY_H_
|
||||
#define _XKBREGISTRY_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Query for available RMLVO
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup registry Query for available RMLVO
|
||||
*
|
||||
* The libxkbregistry API to query for available rules, models, layouts,
|
||||
* variants and options (RMLVO). libxkbregistry is a separate library to
|
||||
* libxkbcommon.
|
||||
*
|
||||
* This library is the replacement for clients currently parsing evdev.xml
|
||||
* directly. The library is intended to provide easy access to the set of
|
||||
* **possible** MLVO configurations for a given ruleset. It is not a library to
|
||||
* apply these configurations, merely to enumerate them. The intended users of
|
||||
* this library are the configuration UIs that allow a user to select their
|
||||
* keyboard layout of choice.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @struct rxkb_context
|
||||
*
|
||||
* Opaque top level library context object.
|
||||
*
|
||||
* The context contains general library state, like include paths and parsed
|
||||
* data. Objects are created in a specific context, and multiple contexts
|
||||
* may coexist simultaneously. Objects from different contexts are
|
||||
* completely separated and do not share any memory or state.
|
||||
*/
|
||||
struct rxkb_context;
|
||||
|
||||
/**
|
||||
* @struct rxkb_model
|
||||
*
|
||||
* Opaque struct representing an XKB model.
|
||||
*/
|
||||
struct rxkb_model;
|
||||
|
||||
/**
|
||||
* @struct rxkb_layout
|
||||
*
|
||||
* Opaque struct representing an XKB layout, including an optional variant.
|
||||
* Where the variant is NULL, the layout is the base layout.
|
||||
*
|
||||
* For example, "us" is the base layout, "us(intl)" is the "intl" variant of the
|
||||
* layout "us".
|
||||
*/
|
||||
struct rxkb_layout;
|
||||
|
||||
/**
|
||||
* @struct rxkb_option_group
|
||||
*
|
||||
* Opaque struct representing an option group. Option groups divide the
|
||||
* individual options into logical groups. Their main purpose is to indicate
|
||||
* whether some options are mutually exclusive or not.
|
||||
*/
|
||||
struct rxkb_option_group;
|
||||
|
||||
/**
|
||||
* @struct rxkb_option
|
||||
*
|
||||
* Opaque struct representing an XKB option. Options are grouped inside an @ref
|
||||
* rxkb_option_group.
|
||||
*/
|
||||
struct rxkb_option;
|
||||
|
||||
/**
|
||||
*
|
||||
* @struct rxkb_iso639_code
|
||||
*
|
||||
* Opaque struct representing an ISO 639-3 code (e.g. "eng", "fra"). There
|
||||
* is no guarantee that two identical ISO codes share the same struct. You
|
||||
* must not rely on the pointer value of this struct.
|
||||
*
|
||||
* See https://iso639-3.sil.org/code_tables/639/data for a list of codes.
|
||||
*/
|
||||
struct rxkb_iso639_code;
|
||||
|
||||
/**
|
||||
*
|
||||
* @struct rxkb_iso3166_code
|
||||
*
|
||||
* Opaque struct representing an ISO 3166 Alpha 2 code (e.g. "US", "FR").
|
||||
* There is no guarantee that two identical ISO codes share the same struct.
|
||||
* You must not rely on the pointer value of this struct.
|
||||
*
|
||||
* See https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes for a list
|
||||
* of codes.
|
||||
*/
|
||||
struct rxkb_iso3166_code;
|
||||
|
||||
/**
|
||||
* Describes the popularity of an item. Historically, some highly specialized or
|
||||
* experimental definitions are excluded from the default list and shipped in
|
||||
* separate files. If these extra definitions are loaded (see @ref
|
||||
* RXKB_CONTEXT_LOAD_EXOTIC_RULES), the popularity of the item is set
|
||||
* accordingly.
|
||||
*
|
||||
* If the exotic items are not loaded, all items will have the standard
|
||||
* popularity.
|
||||
*/
|
||||
enum rxkb_popularity {
|
||||
RXKB_POPULARITY_STANDARD = 1,
|
||||
RXKB_POPULARITY_EXOTIC,
|
||||
};
|
||||
|
||||
/**
|
||||
* Flags for context creation.
|
||||
*/
|
||||
enum rxkb_context_flags {
|
||||
RXKB_CONTEXT_NO_FLAGS = 0,
|
||||
/**
|
||||
* Skip the default include paths. This requires the caller to call
|
||||
* rxkb_context_include_path_append() or
|
||||
* rxkb_context_include_path_append_default().
|
||||
*/
|
||||
RXKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0),
|
||||
/**
|
||||
* Load the extra items that are considered too exotic for the default list.
|
||||
*
|
||||
* For historical reasons, xkeyboard-config ships those exotic rules in a
|
||||
* separate file (e.g. `evdev.extras.xml`). Where the exotic rules are
|
||||
* requested, libxkbregistry will look for and load `$ruleset.extras.xml`
|
||||
* in the include paths, see rxkb_context_include_path_append() for details
|
||||
* on the lookup behavior.
|
||||
*/
|
||||
RXKB_CONTEXT_LOAD_EXOTIC_RULES = (1 << 1),
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new xkb registry context.
|
||||
*
|
||||
* The context has an initial refcount of 1. Use rxkb_context_unref() to release
|
||||
* memory associated with this context.
|
||||
*
|
||||
* Creating a context does not parse the files yet, use
|
||||
* rxkb_context_parse().
|
||||
*
|
||||
* @param flags Flags affecting context behavior
|
||||
* @return A new xkb registry context or NULL on failure
|
||||
*/
|
||||
struct rxkb_context *
|
||||
rxkb_context_new(enum rxkb_context_flags flags);
|
||||
|
||||
/** Specifies a logging level. */
|
||||
enum rxkb_log_level {
|
||||
RXKB_LOG_LEVEL_CRITICAL = 10, /**< Log critical internal errors only. */
|
||||
RXKB_LOG_LEVEL_ERROR = 20, /**< Log all errors. */
|
||||
RXKB_LOG_LEVEL_WARNING = 30, /**< Log warnings and errors. */
|
||||
RXKB_LOG_LEVEL_INFO = 40, /**< Log information, warnings, and errors. */
|
||||
RXKB_LOG_LEVEL_DEBUG = 50 /**< Log everything. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the current logging level.
|
||||
*
|
||||
* @param ctx The context in which to set the logging level.
|
||||
* @param level The logging level to use. Only messages from this level
|
||||
* and below will be logged.
|
||||
*
|
||||
* The default level is RXKB_LOG_LEVEL_ERROR. The environment variable
|
||||
* RXKB_LOG_LEVEL, if set at the time the context was created, overrides the
|
||||
* default value. It may be specified as a level number or name.
|
||||
*/
|
||||
void
|
||||
rxkb_context_set_log_level(struct rxkb_context *ctx,
|
||||
enum rxkb_log_level level);
|
||||
|
||||
/**
|
||||
* Get the current logging level.
|
||||
*/
|
||||
enum rxkb_log_level
|
||||
rxkb_context_get_log_level(struct rxkb_context *ctx);
|
||||
|
||||
/**
|
||||
* Set a custom function to handle logging messages.
|
||||
*
|
||||
* @param ctx The context in which to use the set logging function.
|
||||
* @param log_fn The function that will be called for logging messages.
|
||||
* Passing NULL restores the default function, which logs to stderr.
|
||||
*
|
||||
* By default, log messages from this library are printed to stderr. This
|
||||
* function allows you to replace the default behavior with a custom
|
||||
* handler. The handler is only called with messages which match the
|
||||
* current logging level and verbosity settings for the context.
|
||||
* level is the logging level of the message. @a format and @a args are
|
||||
* the same as in the vprintf(3) function.
|
||||
*
|
||||
* You may use rxkb_context_set_user_data() on the context, and then call
|
||||
* rxkb_context_get_user_data() from within the logging function to provide
|
||||
* it with additional private context.
|
||||
*/
|
||||
void
|
||||
rxkb_context_set_log_fn(struct rxkb_context *ctx,
|
||||
void (*log_fn)(struct rxkb_context *ctx,
|
||||
enum rxkb_log_level level,
|
||||
const char *format, va_list args));
|
||||
|
||||
|
||||
/**
|
||||
* Parse the given ruleset. This can only be called once per context and once
|
||||
* parsed the data in the context is considered constant and will never
|
||||
* change.
|
||||
*
|
||||
* This function parses all files with the given ruleset name. See
|
||||
* rxkb_context_include_path_append() for details.
|
||||
*
|
||||
* If this function returns false, libxkbregistry failed to parse the xml files.
|
||||
* This is usually caused by invalid files on the host and should be debugged by
|
||||
* the host's administrator using external tools. Callers should reduce the
|
||||
* include paths to known good paths and/or fall back to a default RMLVO set.
|
||||
*
|
||||
* If this function returns false, the context should be be considered dead and
|
||||
* must be released with rxkb_context_unref().
|
||||
*
|
||||
* @param ctx The xkb registry context
|
||||
* @param ruleset The ruleset to parse, e.g. "evdev"
|
||||
* @return true on success or false on failure
|
||||
*/
|
||||
bool
|
||||
rxkb_context_parse(struct rxkb_context *ctx, const char *ruleset);
|
||||
|
||||
/**
|
||||
* Parse the default ruleset as configured at build time. See
|
||||
* rxkb_context_parse() for details.
|
||||
*/
|
||||
bool
|
||||
rxkb_context_parse_default_ruleset(struct rxkb_context *ctx);
|
||||
|
||||
/**
|
||||
* Increases the refcount of this object by one and returns the object.
|
||||
*
|
||||
* @param ctx The xkb registry context
|
||||
* @return The passed in object
|
||||
*/
|
||||
struct rxkb_context*
|
||||
rxkb_context_ref(struct rxkb_context *ctx);
|
||||
|
||||
/**
|
||||
* Decreases the refcount of this object by one. Where the refcount of an
|
||||
* object hits zero, associated resources will be freed.
|
||||
*
|
||||
* @param ctx The xkb registry context
|
||||
* @return always NULL
|
||||
*/
|
||||
struct rxkb_context*
|
||||
rxkb_context_unref(struct rxkb_context *ctx);
|
||||
|
||||
/**
|
||||
* Assign user-specific data. libxkbregistry will not look at or modify the
|
||||
* data, it will merely return the same pointer in
|
||||
* rxkb_context_get_user_data().
|
||||
*
|
||||
* @param ctx The xkb registry context
|
||||
* @param user_data User-specific data pointer
|
||||
*/
|
||||
void
|
||||
rxkb_context_set_user_data(struct rxkb_context *ctx, void *user_data);
|
||||
|
||||
/**
|
||||
* Return the pointer passed into rxkb_context_get_user_data().
|
||||
*
|
||||
* @param ctx The xkb registry context
|
||||
* @return User-specific data pointer
|
||||
*/
|
||||
void *
|
||||
rxkb_context_get_user_data(struct rxkb_context *ctx);
|
||||
|
||||
/**
|
||||
* Append a new entry to the context's include path.
|
||||
*
|
||||
* The include path handling is optimized for the most common use-case: a set of
|
||||
* system files that provide a complete set of MLVO and some
|
||||
* custom MLVO provided by a user **in addition** to the system set.
|
||||
*
|
||||
* The include paths should be given so that the least complete path is
|
||||
* specified first and the most complete path is appended last. For example:
|
||||
*
|
||||
* @code
|
||||
* ctx = rxkb_context_new(RXKB_CONTEXT_NO_DEFAULT_INCLUDES);
|
||||
* rxkb_context_include_path_append(ctx, "/home/user/.config/xkb");
|
||||
* rxkb_context_include_path_append(ctx, "/usr/share/X11/xkb");
|
||||
* rxkb_context_parse(ctx, "evdev");
|
||||
* @endcode
|
||||
*
|
||||
* The above example reflects the default behavior unless @ref
|
||||
* RXKB_CONTEXT_NO_DEFAULT_INCLUDES is provided.
|
||||
*
|
||||
* Loading of the files is in **reverse order**, i.e. the last path appended is
|
||||
* loaded first - in this case the ``/usr/share/X11/xkb`` path.
|
||||
* Any models, layouts, variants and options defined in the "evdev" ruleset
|
||||
* are loaded into the context. Then, any RMLVO found in the "evdev" ruleset of
|
||||
* the user's path (``/home/user/.config/xkb`` in this example) are **appended**
|
||||
* to the existing set.
|
||||
*
|
||||
* Note that data from previously loaded include paths is never overwritten,
|
||||
* only appended to. It is not not possible to change the system-provided data,
|
||||
* only to append new models, layouts, variants and options to it.
|
||||
*
|
||||
* In other words, to define a new variant of the "us" layout called "banana",
|
||||
* the following XML is sufficient.
|
||||
*
|
||||
* @verbatim
|
||||
* <xkbConfigRegistry version="1.1">
|
||||
* <layoutList>
|
||||
* <layout>
|
||||
* <configItem>
|
||||
* <name>us</name>
|
||||
* </configItem>
|
||||
* <variantList>
|
||||
* <variant>
|
||||
* <configItem>
|
||||
* <name>banana</name>
|
||||
* <description>English (Banana)</description>
|
||||
* </configItem>
|
||||
* </variant>
|
||||
* </layout>
|
||||
* </layoutList>
|
||||
* </xkbConfigRegistry>
|
||||
* @endverbatim
|
||||
*
|
||||
* The list of models, options and all other layouts (including "us" and its
|
||||
* variants) is taken from the system files. The resulting list of layouts will
|
||||
* thus have a "us" keyboard layout with the variant "banana" and all other
|
||||
* system-provided variants (dvorak, colemak, intl, etc.)
|
||||
*
|
||||
* This function must be called before rxkb_context_parse() or
|
||||
* rxkb_context_parse_default_ruleset().
|
||||
*
|
||||
* @returns true on success, or false if the include path could not be added
|
||||
* or is inaccessible.
|
||||
*/
|
||||
bool
|
||||
rxkb_context_include_path_append(struct rxkb_context *ctx, const char *path);
|
||||
|
||||
/**
|
||||
* Append the default include paths to the context's include path.
|
||||
* See rxkb_context_include_path_append() for details about the merge order.
|
||||
*
|
||||
* This function must be called before rxkb_context_parse() or
|
||||
* rxkb_context_parse_default_ruleset().
|
||||
*
|
||||
* @returns true on success, or false if the include path could not be added
|
||||
* or is inaccessible.
|
||||
*/
|
||||
bool
|
||||
rxkb_context_include_path_append_default(struct rxkb_context *ctx);
|
||||
|
||||
/**
|
||||
* Return the first model for this context. Use this to start iterating over
|
||||
* the models, followed by calls to rxkb_model_next(). Models are not sorted.
|
||||
*
|
||||
* The refcount of the returned model is not increased. Use rxkb_model_ref() if
|
||||
* you need to keep this struct outside the immediate scope.
|
||||
*
|
||||
* @return The first model in the model list.
|
||||
*/
|
||||
struct rxkb_model *
|
||||
rxkb_model_first(struct rxkb_context *ctx);
|
||||
|
||||
/**
|
||||
* Return the next model for this context. Returns NULL when no more models
|
||||
* are available.
|
||||
*
|
||||
* The refcount of the returned model is not increased. Use rxkb_model_ref() if
|
||||
* you need to keep this struct outside the immediate scope.
|
||||
*
|
||||
* @return the next model or NULL at the end of the list
|
||||
*/
|
||||
struct rxkb_model *
|
||||
rxkb_model_next(struct rxkb_model *m);
|
||||
|
||||
/**
|
||||
* Increase the refcount of the argument by one.
|
||||
*
|
||||
* @returns The argument passed in to this function.
|
||||
*/
|
||||
struct rxkb_model *
|
||||
rxkb_model_ref(struct rxkb_model *m);
|
||||
|
||||
/**
|
||||
* Decrease the refcount of the argument by one. When the refcount hits zero,
|
||||
* all memory associated with this struct is freed.
|
||||
*
|
||||
* @returns always NULL
|
||||
*/
|
||||
struct rxkb_model *
|
||||
rxkb_model_unref(struct rxkb_model *m);
|
||||
|
||||
/**
|
||||
* Return the name of this model. This is the value for M in RMLVO, to be used
|
||||
* with libxkbcommon.
|
||||
*/
|
||||
const char *
|
||||
rxkb_model_get_name(struct rxkb_model *m);
|
||||
|
||||
/**
|
||||
* Return a human-readable description of this model. This function may return
|
||||
* NULL.
|
||||
*/
|
||||
const char *
|
||||
rxkb_model_get_description(struct rxkb_model *m);
|
||||
|
||||
/**
|
||||
* Return the vendor name for this model. This function may return NULL.
|
||||
*/
|
||||
const char *
|
||||
rxkb_model_get_vendor(struct rxkb_model *m);
|
||||
|
||||
/**
|
||||
* Return the popularity for this model.
|
||||
*/
|
||||
enum rxkb_popularity
|
||||
rxkb_model_get_popularity(struct rxkb_model *m);
|
||||
|
||||
/**
|
||||
* Return the first layout for this context. Use this to start iterating over
|
||||
* the layouts, followed by calls to rxkb_layout_next(). Layouts are not sorted.
|
||||
*
|
||||
* The refcount of the returned layout is not increased. Use rxkb_layout_ref() if
|
||||
* you need to keep this struct outside the immediate scope.
|
||||
*
|
||||
* @return The first layout in the layout list.
|
||||
*/
|
||||
struct rxkb_layout *
|
||||
rxkb_layout_first(struct rxkb_context *ctx);
|
||||
|
||||
/**
|
||||
* Return the next layout for this context. Returns NULL when no more layouts
|
||||
* are available.
|
||||
*
|
||||
* The refcount of the returned layout is not increased. Use rxkb_layout_ref()
|
||||
* if you need to keep this struct outside the immediate scope.
|
||||
*
|
||||
* @return the next layout or NULL at the end of the list
|
||||
*/
|
||||
struct rxkb_layout *
|
||||
rxkb_layout_next(struct rxkb_layout *l);
|
||||
|
||||
/**
|
||||
* Increase the refcount of the argument by one.
|
||||
*
|
||||
* @returns The argument passed in to this function.
|
||||
*/
|
||||
struct rxkb_layout *
|
||||
rxkb_layout_ref(struct rxkb_layout *l);
|
||||
|
||||
/**
|
||||
* Decrease the refcount of the argument by one. When the refcount hits zero,
|
||||
* all memory associated with this struct is freed.
|
||||
*
|
||||
* @returns always NULL
|
||||
*/
|
||||
struct rxkb_layout *
|
||||
rxkb_layout_unref(struct rxkb_layout *l);
|
||||
|
||||
/**
|
||||
* Return the name of this layout. This is the value for L in RMLVO, to be used
|
||||
* with libxkbcommon.
|
||||
*/
|
||||
const char *
|
||||
rxkb_layout_get_name(struct rxkb_layout *l);
|
||||
|
||||
/**
|
||||
* Return the variant of this layout. This is the value for V in RMLVO, to be
|
||||
* used with libxkbcommon.
|
||||
*
|
||||
* A variant does not stand on its own, it always depends on the base layout.
|
||||
* e.g. there may be multiple variants called "intl" but there is only one
|
||||
* "us(intl)".
|
||||
*
|
||||
* Where the variant is NULL, the layout is the base layout (e.g. "us").
|
||||
*/
|
||||
const char *
|
||||
rxkb_layout_get_variant(struct rxkb_layout *l);
|
||||
|
||||
/**
|
||||
* Return a short (one-word) description of this layout. This function may
|
||||
* return NULL.
|
||||
*/
|
||||
const char *
|
||||
rxkb_layout_get_brief(struct rxkb_layout *l);
|
||||
|
||||
/**
|
||||
* Return a human-readable description of this layout. This function may return
|
||||
* NULL.
|
||||
*/
|
||||
const char *
|
||||
rxkb_layout_get_description(struct rxkb_layout *l);
|
||||
|
||||
/**
|
||||
* Return the popularity for this layout.
|
||||
*/
|
||||
enum rxkb_popularity
|
||||
rxkb_layout_get_popularity(struct rxkb_layout *l);
|
||||
|
||||
/**
|
||||
* Return the first option group for this context. Use this to start iterating
|
||||
* over the option groups, followed by calls to rxkb_option_group_next().
|
||||
* Option groups are not sorted.
|
||||
*
|
||||
* The refcount of the returned option group is not increased. Use
|
||||
* rxkb_option_group_ref() if you need to keep this struct outside the immediate
|
||||
* scope.
|
||||
*
|
||||
* @return The first option group in the option group list.
|
||||
*/
|
||||
struct rxkb_option_group *
|
||||
rxkb_option_group_first(struct rxkb_context *ctx);
|
||||
|
||||
/**
|
||||
* Return the next option group for this context. Returns NULL when no more
|
||||
* option groups are available.
|
||||
*
|
||||
* The refcount of the returned option group is not increased. Use
|
||||
* rxkb_option_group_ref() if you need to keep this struct outside the immediate
|
||||
* scope.
|
||||
*
|
||||
* @return the next option group or NULL at the end of the list
|
||||
*/
|
||||
struct rxkb_option_group *
|
||||
rxkb_option_group_next(struct rxkb_option_group *g);
|
||||
|
||||
/**
|
||||
* Increase the refcount of the argument by one.
|
||||
*
|
||||
* @returns The argument passed in to this function.
|
||||
*/
|
||||
struct rxkb_option_group *
|
||||
rxkb_option_group_ref(struct rxkb_option_group *g);
|
||||
|
||||
/**
|
||||
* Decrease the refcount of the argument by one. When the refcount hits zero,
|
||||
* all memory associated with this struct is freed.
|
||||
*
|
||||
* @returns always NULL
|
||||
*/
|
||||
struct rxkb_option_group *
|
||||
rxkb_option_group_unref(struct rxkb_option_group *g);
|
||||
|
||||
/**
|
||||
* Return the name of this option group. This is **not** the value for O in
|
||||
* RMLVO, the name can be used for internal sorting in the caller. This function
|
||||
* may return NULL.
|
||||
*/
|
||||
const char *
|
||||
rxkb_option_group_get_name(struct rxkb_option_group *m);
|
||||
|
||||
/**
|
||||
* Return a human-readable description of this option group. This function may
|
||||
* return NULL.
|
||||
*/
|
||||
const char *
|
||||
rxkb_option_group_get_description(struct rxkb_option_group *m);
|
||||
|
||||
/**
|
||||
* @return true if multiple options within this option group can be selected
|
||||
* simultaneously, false if all options within this option group
|
||||
* are mutually exclusive.
|
||||
*/
|
||||
bool
|
||||
rxkb_option_group_allows_multiple(struct rxkb_option_group *g);
|
||||
|
||||
/**
|
||||
* Return the popularity for this option group.
|
||||
*/
|
||||
enum rxkb_popularity
|
||||
rxkb_option_group_get_popularity(struct rxkb_option_group *g);
|
||||
|
||||
/**
|
||||
* Return the first option for this option group. Use this to start iterating
|
||||
* over the options, followed by calls to rxkb_option_next(). Options are not
|
||||
* sorted.
|
||||
*
|
||||
* The refcount of the returned option is not increased. Use rxkb_option_ref()
|
||||
* if you need to keep this struct outside the immediate scope.
|
||||
*
|
||||
* @return The first option in the option list.
|
||||
*/
|
||||
struct rxkb_option *
|
||||
rxkb_option_first(struct rxkb_option_group *group);
|
||||
|
||||
/**
|
||||
* Return the next option for this option group. Returns NULL when no more
|
||||
* options are available.
|
||||
*
|
||||
* The refcount of the returned options is not increased. Use rxkb_option_ref()
|
||||
* if you need to keep this struct outside the immediate scope.
|
||||
*
|
||||
* @returns The next option or NULL at the end of the list
|
||||
*/
|
||||
struct rxkb_option *
|
||||
rxkb_option_next(struct rxkb_option *o);
|
||||
|
||||
/**
|
||||
* Increase the refcount of the argument by one.
|
||||
*
|
||||
* @returns The argument passed in to this function.
|
||||
*/
|
||||
struct rxkb_option *
|
||||
rxkb_option_ref(struct rxkb_option *o);
|
||||
|
||||
/**
|
||||
* Decrease the refcount of the argument by one. When the refcount hits zero,
|
||||
* all memory associated with this struct is freed.
|
||||
*
|
||||
* @returns always NULL
|
||||
*/
|
||||
struct rxkb_option *
|
||||
rxkb_option_unref(struct rxkb_option *o);
|
||||
|
||||
/**
|
||||
* Return the name of this option. This is the value for O in RMLVO, to be used
|
||||
* with libxkbcommon.
|
||||
*/
|
||||
const char *
|
||||
rxkb_option_get_name(struct rxkb_option *o);
|
||||
|
||||
/**
|
||||
* Return a short (one-word) description of this option. This function may
|
||||
* return NULL.
|
||||
*/
|
||||
const char *
|
||||
rxkb_option_get_brief(struct rxkb_option *o);
|
||||
|
||||
/**
|
||||
* Return a human-readable description of this option. This function may return
|
||||
* NULL.
|
||||
*/
|
||||
const char *
|
||||
rxkb_option_get_description(struct rxkb_option *o);
|
||||
|
||||
/**
|
||||
* Return the popularity for this option.
|
||||
*/
|
||||
enum rxkb_popularity
|
||||
rxkb_option_get_popularity(struct rxkb_option *o);
|
||||
|
||||
/**
|
||||
* Increase the refcount of the argument by one.
|
||||
*
|
||||
* @returns The argument passed in to this function.
|
||||
*/
|
||||
struct rxkb_iso639_code *
|
||||
rxkb_iso639_code_ref(struct rxkb_iso639_code *iso639);
|
||||
|
||||
/**
|
||||
* Decrease the refcount of the argument by one. When the refcount hits zero,
|
||||
* all memory associated with this struct is freed.
|
||||
*
|
||||
* @returns always NULL
|
||||
*/
|
||||
struct rxkb_iso639_code *
|
||||
rxkb_iso639_code_unref(struct rxkb_iso639_code *iso639);
|
||||
|
||||
/**
|
||||
* Return the ISO 639-3 code for this code (e.g. "eng", "fra").
|
||||
*/
|
||||
const char *
|
||||
rxkb_iso639_code_get_code(struct rxkb_iso639_code *iso639);
|
||||
|
||||
/**
|
||||
* Return the first ISO 639 for this layout. Use this to start iterating over
|
||||
* the codes, followed by calls to rxkb_iso639_code_next(). Codes are not
|
||||
* sorted.
|
||||
*
|
||||
* The refcount of the returned code is not increased. Use rxkb_iso639_code_ref()
|
||||
* if you need to keep this struct outside the immediate scope.
|
||||
*
|
||||
* @return The first code in the code list.
|
||||
*/
|
||||
struct rxkb_iso639_code *
|
||||
rxkb_layout_get_iso639_first(struct rxkb_layout *layout);
|
||||
|
||||
/**
|
||||
* Return the next code in the list. Returns NULL when no more codes
|
||||
* are available.
|
||||
*
|
||||
* The refcount of the returned codes is not increased. Use
|
||||
* rxkb_iso639_code_ref() if you need to keep this struct outside the immediate
|
||||
* scope.
|
||||
*
|
||||
* @returns The next code or NULL at the end of the list
|
||||
*/
|
||||
struct rxkb_iso639_code *
|
||||
rxkb_iso639_code_next(struct rxkb_iso639_code *iso639);
|
||||
|
||||
/**
|
||||
* Increase the refcount of the argument by one.
|
||||
*
|
||||
* @returns The argument passed in to this function.
|
||||
*/
|
||||
struct rxkb_iso3166_code *
|
||||
rxkb_iso3166_code_ref(struct rxkb_iso3166_code *iso3166);
|
||||
|
||||
/**
|
||||
* Decrease the refcount of the argument by one. When the refcount hits zero,
|
||||
* all memory associated with this struct is freed.
|
||||
*
|
||||
* @returns always NULL
|
||||
*/
|
||||
struct rxkb_iso3166_code *
|
||||
rxkb_iso3166_code_unref(struct rxkb_iso3166_code *iso3166);
|
||||
|
||||
/**
|
||||
* Return the ISO 3166 Alpha 2 code for this code (e.g. "US", "FR").
|
||||
*/
|
||||
const char *
|
||||
rxkb_iso3166_code_get_code(struct rxkb_iso3166_code *iso3166);
|
||||
|
||||
/**
|
||||
* Return the first ISO 3166 for this layout. Use this to start iterating over
|
||||
* the codes, followed by calls to rxkb_iso3166_code_next(). Codes are not
|
||||
* sorted.
|
||||
*
|
||||
* The refcount of the returned code is not increased. Use
|
||||
* rxkb_iso3166_code_ref() if you need to keep this struct outside the immediate
|
||||
* scope.
|
||||
*
|
||||
* @return The first code in the code list.
|
||||
*/
|
||||
struct rxkb_iso3166_code *
|
||||
rxkb_layout_get_iso3166_first(struct rxkb_layout *layout);
|
||||
|
||||
/**
|
||||
* Return the next code in the list. Returns NULL when no more codes
|
||||
* are available.
|
||||
*
|
||||
* The refcount of the returned codes is not increased. Use
|
||||
* rxkb_iso3166_code_ref() if you need to keep this struct outside the immediate
|
||||
* scope.
|
||||
*
|
||||
* @returns The next code or NULL at the end of the list
|
||||
*/
|
||||
struct rxkb_iso3166_code *
|
||||
rxkb_iso3166_code_next(struct rxkb_iso3166_code *iso3166);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* _XKBREGISTRY_H_ */
|
|
@ -1,168 +0,0 @@
|
|||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_gcc_builtin.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_GCC_BUILTIN(BUILTIN)
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro checks if the compiler supports one of GCC's built-in
|
||||
# functions; many other compilers also provide those same built-ins.
|
||||
#
|
||||
# The BUILTIN parameter is the name of the built-in function.
|
||||
#
|
||||
# If BUILTIN is supported define HAVE_<BUILTIN>. Keep in mind that since
|
||||
# builtins usually start with two underscores they will be copied over
|
||||
# into the HAVE_<BUILTIN> definition (e.g. HAVE___BUILTIN_EXPECT for
|
||||
# __builtin_expect()).
|
||||
#
|
||||
# The macro caches its result in the ax_cv_have_<BUILTIN> variable (e.g.
|
||||
# ax_cv_have___builtin_expect).
|
||||
#
|
||||
# The macro currently supports the following built-in functions:
|
||||
#
|
||||
# __builtin_assume_aligned
|
||||
# __builtin_bswap32
|
||||
# __builtin_bswap64
|
||||
# __builtin_choose_expr
|
||||
# __builtin___clear_cache
|
||||
# __builtin_clrsb
|
||||
# __builtin_clrsbl
|
||||
# __builtin_clrsbll
|
||||
# __builtin_clz
|
||||
# __builtin_clzl
|
||||
# __builtin_clzll
|
||||
# __builtin_complex
|
||||
# __builtin_constant_p
|
||||
# __builtin_ctz
|
||||
# __builtin_ctzl
|
||||
# __builtin_ctzll
|
||||
# __builtin_expect
|
||||
# __builtin_ffs
|
||||
# __builtin_ffsl
|
||||
# __builtin_ffsll
|
||||
# __builtin_fpclassify
|
||||
# __builtin_huge_val
|
||||
# __builtin_huge_valf
|
||||
# __builtin_huge_vall
|
||||
# __builtin_inf
|
||||
# __builtin_infd128
|
||||
# __builtin_infd32
|
||||
# __builtin_infd64
|
||||
# __builtin_inff
|
||||
# __builtin_infl
|
||||
# __builtin_isinf_sign
|
||||
# __builtin_nan
|
||||
# __builtin_nand128
|
||||
# __builtin_nand32
|
||||
# __builtin_nand64
|
||||
# __builtin_nanf
|
||||
# __builtin_nanl
|
||||
# __builtin_nans
|
||||
# __builtin_nansf
|
||||
# __builtin_nansl
|
||||
# __builtin_object_size
|
||||
# __builtin_parity
|
||||
# __builtin_parityl
|
||||
# __builtin_parityll
|
||||
# __builtin_popcount
|
||||
# __builtin_popcountl
|
||||
# __builtin_popcountll
|
||||
# __builtin_powi
|
||||
# __builtin_powif
|
||||
# __builtin_powil
|
||||
# __builtin_prefetch
|
||||
# __builtin_trap
|
||||
# __builtin_types_compatible_p
|
||||
# __builtin_unreachable
|
||||
#
|
||||
# Unsuppored built-ins will be tested with an empty parameter set and the
|
||||
# result of the check might be wrong or meaningless so use with care.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 2
|
||||
|
||||
AC_DEFUN([AX_GCC_BUILTIN], [
|
||||
AS_VAR_PUSHDEF([ac_var], [ax_cv_have_$1])
|
||||
|
||||
AC_CACHE_CHECK([for $1], [ac_var], [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [
|
||||
m4_case([$1],
|
||||
[__builtin_assume_aligned], [$1("", 0)],
|
||||
[__builtin_bswap32], [$1(0)],
|
||||
[__builtin_bswap64], [$1(0)],
|
||||
[__builtin_choose_expr], [$1(0, 0, 0)],
|
||||
[__builtin___clear_cache], [$1("", "")],
|
||||
[__builtin_clrsb], [$1(0)],
|
||||
[__builtin_clrsbl], [$1(0)],
|
||||
[__builtin_clrsbll], [$1(0)],
|
||||
[__builtin_clz], [$1(0)],
|
||||
[__builtin_clzl], [$1(0)],
|
||||
[__builtin_clzll], [$1(0)],
|
||||
[__builtin_complex], [$1(0.0, 0.0)],
|
||||
[__builtin_constant_p], [$1(0)],
|
||||
[__builtin_ctz], [$1(0)],
|
||||
[__builtin_ctzl], [$1(0)],
|
||||
[__builtin_ctzll], [$1(0)],
|
||||
[__builtin_expect], [$1(0, 0)],
|
||||
[__builtin_ffs], [$1(0)],
|
||||
[__builtin_ffsl], [$1(0)],
|
||||
[__builtin_ffsll], [$1(0)],
|
||||
[__builtin_fpclassify], [$1(0, 1, 2, 3, 4, 0.0)],
|
||||
[__builtin_huge_val], [$1()],
|
||||
[__builtin_huge_valf], [$1()],
|
||||
[__builtin_huge_vall], [$1()],
|
||||
[__builtin_inf], [$1()],
|
||||
[__builtin_infd128], [$1()],
|
||||
[__builtin_infd32], [$1()],
|
||||
[__builtin_infd64], [$1()],
|
||||
[__builtin_inff], [$1()],
|
||||
[__builtin_infl], [$1()],
|
||||
[__builtin_isinf_sign], [$1(0.0)],
|
||||
[__builtin_nan], [$1("")],
|
||||
[__builtin_nand128], [$1("")],
|
||||
[__builtin_nand32], [$1("")],
|
||||
[__builtin_nand64], [$1("")],
|
||||
[__builtin_nanf], [$1("")],
|
||||
[__builtin_nanl], [$1("")],
|
||||
[__builtin_nans], [$1("")],
|
||||
[__builtin_nansf], [$1("")],
|
||||
[__builtin_nansl], [$1("")],
|
||||
[__builtin_object_size], [$1("", 0)],
|
||||
[__builtin_parity], [$1(0)],
|
||||
[__builtin_parityl], [$1(0)],
|
||||
[__builtin_parityll], [$1(0)],
|
||||
[__builtin_popcount], [$1(0)],
|
||||
[__builtin_popcountl], [$1(0)],
|
||||
[__builtin_popcountll], [$1(0)],
|
||||
[__builtin_powi], [$1(0, 0)],
|
||||
[__builtin_powif], [$1(0, 0)],
|
||||
[__builtin_powil], [$1(0, 0)],
|
||||
[__builtin_prefetch], [$1("")],
|
||||
[__builtin_trap], [$1()],
|
||||
[__builtin_types_compatible_p], [$1(int, int)],
|
||||
[__builtin_unreachable], [$1()],
|
||||
[m4_warn([syntax], [Unsupported built-in $1, the test may fail])
|
||||
$1()]
|
||||
)
|
||||
])],
|
||||
[AS_VAR_SET([ac_var], [yes])],
|
||||
[AS_VAR_SET([ac_var], [no])])
|
||||
])
|
||||
|
||||
AS_IF([test yes = AS_VAR_GET([ac_var])],
|
||||
[AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$1), 1,
|
||||
[Define to 1 if the system has the `$1' built-in function])], [])
|
||||
|
||||
AS_VAR_POPDEF([ac_var])
|
||||
])
|
|
@ -0,0 +1,830 @@
|
|||
project(
|
||||
'libxkbcommon',
|
||||
'c',
|
||||
version: '1.3.0',
|
||||
default_options: [
|
||||
'c_std=c11',
|
||||
'warning_level=2',
|
||||
'b_lundef=true',
|
||||
],
|
||||
meson_version : '>= 0.49.0',
|
||||
)
|
||||
pkgconfig = import('pkgconfig')
|
||||
cc = meson.get_compiler('c')
|
||||
|
||||
dir_libexec = get_option('prefix')/get_option('libexecdir')/'xkbcommon'
|
||||
|
||||
# Compiler flags.
|
||||
cflags = [
|
||||
'-fno-strict-aliasing',
|
||||
'-fsanitize-undefined-trap-on-error',
|
||||
'-Wno-unused-parameter',
|
||||
'-Wno-missing-field-initializers',
|
||||
'-Wpointer-arith',
|
||||
'-Wmissing-declarations',
|
||||
'-Wformat=2',
|
||||
'-Wstrict-prototypes',
|
||||
'-Wmissing-prototypes',
|
||||
'-Wnested-externs',
|
||||
'-Wbad-function-cast',
|
||||
'-Wshadow',
|
||||
'-Wlogical-op',
|
||||
'-Wdate-time',
|
||||
'-Wwrite-strings',
|
||||
'-Wno-documentation-deprecated-sync',
|
||||
]
|
||||
add_project_arguments(cc.get_supported_arguments(cflags), language: 'c')
|
||||
|
||||
|
||||
# The XKB config root.
|
||||
XKBCONFIGROOT = get_option('xkb-config-root')
|
||||
if XKBCONFIGROOT == ''
|
||||
xkeyboard_config_dep = dependency('xkeyboard-config', required: false)
|
||||
if xkeyboard_config_dep.found()
|
||||
XKBCONFIGROOT = xkeyboard_config_dep.get_pkgconfig_variable('xkb_base')
|
||||
else
|
||||
XKBCONFIGROOT = get_option('prefix')/get_option('datadir')/'X11'/'xkb'
|
||||
endif
|
||||
endif
|
||||
|
||||
XKBCONFIGEXTRAPATH = get_option('xkb-config-extra-path')
|
||||
if XKBCONFIGEXTRAPATH == ''
|
||||
XKBCONFIGEXTRAPATH = get_option('prefix')/get_option('sysconfdir')/'xkb'
|
||||
endif
|
||||
|
||||
# The X locale directory for compose.
|
||||
XLOCALEDIR = get_option('x-locale-root')
|
||||
if XLOCALEDIR == ''
|
||||
XLOCALEDIR = get_option('prefix')/get_option('datadir')/'X11'/'locale'
|
||||
endif
|
||||
|
||||
|
||||
# config.h.
|
||||
configh_data = configuration_data()
|
||||
configh_data.set('EXIT_INVALID_USAGE', '2')
|
||||
configh_data.set_quoted('LIBXKBCOMMON_VERSION', meson.project_version())
|
||||
configh_data.set_quoted('LIBXKBCOMMON_TOOL_PATH', dir_libexec)
|
||||
# Like AC_USE_SYSTEM_EXTENSIONS, what #define to use to get extensions
|
||||
# beyond the base POSIX function set.
|
||||
if host_machine.system() == 'sunos'
|
||||
system_extensions = '__EXTENSIONS__'
|
||||
else
|
||||
system_extensions = '_GNU_SOURCE'
|
||||
endif
|
||||
configh_data.set(system_extensions, 1)
|
||||
system_ext_define = '#define ' + system_extensions
|
||||
configh_data.set_quoted('DFLT_XKB_CONFIG_ROOT', XKBCONFIGROOT)
|
||||
configh_data.set_quoted('DFLT_XKB_CONFIG_EXTRA_PATH', XKBCONFIGEXTRAPATH)
|
||||
configh_data.set_quoted('XLOCALEDIR', XLOCALEDIR)
|
||||
configh_data.set_quoted('DEFAULT_XKB_RULES', get_option('default-rules'))
|
||||
configh_data.set_quoted('DEFAULT_XKB_MODEL', get_option('default-model'))
|
||||
configh_data.set_quoted('DEFAULT_XKB_LAYOUT', get_option('default-layout'))
|
||||
if get_option('default-variant') != ''
|
||||
configh_data.set_quoted('DEFAULT_XKB_VARIANT', get_option('default-variant'))
|
||||
else
|
||||
configh_data.set('DEFAULT_XKB_VARIANT', 'NULL')
|
||||
endif
|
||||
if get_option('default-options') != ''
|
||||
configh_data.set_quoted('DEFAULT_XKB_OPTIONS', get_option('default-options'))
|
||||
else
|
||||
configh_data.set('DEFAULT_XKB_OPTIONS', 'NULL')
|
||||
endif
|
||||
if cc.has_header('unistd.h')
|
||||
configh_data.set('HAVE_UNISTD_H', 1)
|
||||
endif
|
||||
if cc.links('int main(){if(__builtin_expect(1<0,0)){}}', name: '__builtin_expect')
|
||||
configh_data.set('HAVE___BUILTIN_EXPECT', 1)
|
||||
endif
|
||||
if cc.has_header_symbol('unistd.h', 'eaccess', prefix: system_ext_define)
|
||||
configh_data.set('HAVE_EACCESS', 1)
|
||||
endif
|
||||
if cc.has_header_symbol('unistd.h', 'euidaccess', prefix: system_ext_define)
|
||||
configh_data.set('HAVE_EUIDACCESS', 1)
|
||||
endif
|
||||
if cc.has_header_symbol('sys/mman.h', 'mmap')
|
||||
configh_data.set('HAVE_MMAP', 1)
|
||||
endif
|
||||
if cc.has_header_symbol('stdlib.h', 'mkostemp', prefix: system_ext_define)
|
||||
configh_data.set('HAVE_MKOSTEMP', 1)
|
||||
endif
|
||||
if cc.has_header_symbol('fcntl.h', 'posix_fallocate', prefix: system_ext_define)
|
||||
configh_data.set('HAVE_POSIX_FALLOCATE', 1)
|
||||
endif
|
||||
if cc.has_header_symbol('string.h', 'strndup', prefix: system_ext_define)
|
||||
configh_data.set('HAVE_STRNDUP', 1)
|
||||
endif
|
||||
if cc.has_header_symbol('stdio.h', 'asprintf', prefix: system_ext_define)
|
||||
configh_data.set('HAVE_ASPRINTF', 1)
|
||||
elif cc.has_header_symbol('stdio.h', 'vasprintf', prefix: system_ext_define)
|
||||
configh_data.set('HAVE_VASPRINTF', 1)
|
||||
endif
|
||||
if cc.has_header_symbol('stdlib.h', 'secure_getenv', prefix: system_ext_define)
|
||||
configh_data.set('HAVE_SECURE_GETENV', 1)
|
||||
elif cc.has_header_symbol('stdlib.h', '__secure_getenv', prefix: system_ext_define)
|
||||
configh_data.set('HAVE___SECURE_GETENV', 1)
|
||||
else
|
||||
message('C library does not support secure_getenv, using getenv instead')
|
||||
endif
|
||||
have_getopt_long = cc.has_header_symbol('getopt.h', 'getopt_long',
|
||||
prefix: '#define _GNU_SOURCE')
|
||||
if not cc.has_header_symbol('limits.h', 'PATH_MAX', prefix: system_ext_define)
|
||||
if host_machine.system() == 'windows'
|
||||
# see https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#maximum-path-length-limitation
|
||||
configh_data.set('PATH_MAX', 260)
|
||||
else
|
||||
configh_data.set('PATH_MAX', 4096)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Silence some security & deprecation warnings on MSVC
|
||||
# for some unix/C functions we use.
|
||||
# https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-3-c4996?view=vs-2019
|
||||
configh_data.set('_CRT_SECURE_NO_WARNINGS', 1)
|
||||
configh_data.set('_CRT_NONSTDC_NO_WARNINGS', 1)
|
||||
configh_data.set('_CRT_NONSTDC_NO_DEPRECATE', 1)
|
||||
# Reduce unnecessary includes on MSVC.
|
||||
configh_data.set('WIN32_LEAN_AND_MEAN', 1)
|
||||
|
||||
# Supports -Wl,--version-script?
|
||||
have_version_script = cc.links(
|
||||
'int main(){}',
|
||||
args: '-Wl,--version-script=' + meson.source_root()/'xkbcommon.map',
|
||||
name: '-Wl,--version-script',
|
||||
)
|
||||
|
||||
map_to_def = find_program('scripts/map-to-def')
|
||||
|
||||
# libxkbcommon.
|
||||
# Note: we use some yacc extensions, which work with either GNU bison
|
||||
# (preferred) or byacc (with backtracking enabled).
|
||||
bison = find_program('bison', 'win_bison', required: false)
|
||||
if bison.found()
|
||||
yacc_gen = generator(
|
||||
bison,
|
||||
output: ['@BASENAME@.c', '@BASENAME@.h'],
|
||||
arguments: ['--defines=@OUTPUT1@', '-o', '@OUTPUT0@', '-p', '_xkbcommon_', '@INPUT@'],
|
||||
)
|
||||
else
|
||||
byacc = find_program('byacc', required: false)
|
||||
if byacc.found()
|
||||
yacc_gen = generator(
|
||||
byacc,
|
||||
output: ['@BASENAME@.c', '@BASENAME@.h'],
|
||||
arguments: ['-H', '@OUTPUT1@', '-o', '@OUTPUT0@', '-p', '_xkbcommon_', '@INPUT@'],
|
||||
)
|
||||
else
|
||||
error('Could not find a compatible YACC program (bison or byacc)')
|
||||
endif
|
||||
endif
|
||||
libxkbcommon_sources = [
|
||||
'src/compose/parser.c',
|
||||
'src/compose/parser.h',
|
||||
'src/compose/paths.c',
|
||||
'src/compose/paths.h',
|
||||
'src/compose/state.c',
|
||||
'src/compose/table.c',
|
||||
'src/compose/table.h',
|
||||
'src/xkbcomp/action.c',
|
||||
'src/xkbcomp/action.h',
|
||||
'src/xkbcomp/ast.h',
|
||||
'src/xkbcomp/ast-build.c',
|
||||
'src/xkbcomp/ast-build.h',
|
||||
'src/xkbcomp/compat.c',
|
||||
'src/xkbcomp/expr.c',
|
||||
'src/xkbcomp/expr.h',
|
||||
'src/xkbcomp/include.c',
|
||||
'src/xkbcomp/include.h',
|
||||
'src/xkbcomp/keycodes.c',
|
||||
'src/xkbcomp/keymap.c',
|
||||
'src/xkbcomp/keymap-dump.c',
|
||||
'src/xkbcomp/keywords.c',
|
||||
yacc_gen.process('src/xkbcomp/parser.y'),
|
||||
'src/xkbcomp/parser-priv.h',
|
||||
'src/xkbcomp/rules.c',
|
||||
'src/xkbcomp/rules.h',
|
||||
'src/xkbcomp/scanner.c',
|
||||
'src/xkbcomp/symbols.c',
|
||||
'src/xkbcomp/types.c',
|
||||
'src/xkbcomp/vmod.c',
|
||||
'src/xkbcomp/vmod.h',
|
||||
'src/xkbcomp/xkbcomp.c',
|
||||
'src/xkbcomp/xkbcomp-priv.h',
|
||||
'src/atom.c',
|
||||
'src/atom.h',
|
||||
'src/context.c',
|
||||
'src/context.h',
|
||||
'src/context-priv.c',
|
||||
'src/darray.h',
|
||||
'src/keysym.c',
|
||||
'src/keysym.h',
|
||||
'src/keysym-utf.c',
|
||||
'src/ks_tables.h',
|
||||
'src/keymap.c',
|
||||
'src/keymap.h',
|
||||
'src/keymap-priv.c',
|
||||
'src/scanner-utils.h',
|
||||
'src/state.c',
|
||||
'src/text.c',
|
||||
'src/text.h',
|
||||
'src/utf8.c',
|
||||
'src/utf8.h',
|
||||
'src/utils.c',
|
||||
'src/utils.h',
|
||||
]
|
||||
libxkbcommon_link_args = []
|
||||
libxkbcommon_link_deps = []
|
||||
if have_version_script
|
||||
libxkbcommon_link_args += '-Wl,--version-script=' + meson.source_root()/'xkbcommon.map'
|
||||
libxkbcommon_link_deps += 'xkbcommon.map'
|
||||
elif cc.get_argument_syntax() == 'msvc'
|
||||
libxkbcommon_def = custom_target('xkbcommon.def',
|
||||
command: [map_to_def, '@INPUT@', '@OUTPUT@'],
|
||||
input: 'xkbcommon.map',
|
||||
output: 'kxbcommon.def',
|
||||
)
|
||||
libxkbcommon_link_deps += libxkbcommon_def
|
||||
libxkbcommon_link_args += '/DEF:' + libxkbcommon_def.full_path()
|
||||
endif
|
||||
libxkbcommon = library(
|
||||
'xkbcommon',
|
||||
'include/xkbcommon/xkbcommon.h',
|
||||
libxkbcommon_sources,
|
||||
link_args: libxkbcommon_link_args,
|
||||
link_depends: libxkbcommon_link_deps,
|
||||
gnu_symbol_visibility: 'hidden',
|
||||
version: '0.0.0',
|
||||
install: true,
|
||||
include_directories: include_directories('src', 'include'),
|
||||
)
|
||||
install_headers(
|
||||
'include/xkbcommon/xkbcommon.h',
|
||||
'include/xkbcommon/xkbcommon-compat.h',
|
||||
'include/xkbcommon/xkbcommon-compose.h',
|
||||
'include/xkbcommon/xkbcommon-keysyms.h',
|
||||
'include/xkbcommon/xkbcommon-names.h',
|
||||
subdir: 'xkbcommon',
|
||||
)
|
||||
|
||||
dep_libxkbcommon = declare_dependency(
|
||||
link_with: libxkbcommon,
|
||||
include_directories: include_directories('include'),
|
||||
)
|
||||
pkgconfig.generate(
|
||||
libxkbcommon,
|
||||
name: 'xkbcommon',
|
||||
filebase: 'xkbcommon',
|
||||
version: meson.project_version(),
|
||||
description: 'XKB API common to servers and clients',
|
||||
)
|
||||
|
||||
|
||||
# libxkbcommon-x11.
|
||||
if get_option('enable-x11')
|
||||
xcb_dep = dependency('xcb', version: '>=1.10', required: false)
|
||||
xcb_xkb_dep = dependency('xcb-xkb', version: '>=1.10', required: false)
|
||||
if not xcb_dep.found() or not xcb_xkb_dep.found()
|
||||
error('''X11 support requires xcb-xkb >= 1.10 which was not found.
|
||||
You can disable X11 support with -Denable-x11=false.''')
|
||||
endif
|
||||
|
||||
libxkbcommon_x11_sources = [
|
||||
'src/x11/keymap.c',
|
||||
'src/x11/state.c',
|
||||
'src/x11/util.c',
|
||||
'src/x11/x11-priv.h',
|
||||
'src/context.h',
|
||||
'src/context-priv.c',
|
||||
'src/keymap.h',
|
||||
'src/keymap-priv.c',
|
||||
'src/atom.h',
|
||||
'src/atom.c',
|
||||
]
|
||||
libxkbcommon_x11_link_args = []
|
||||
libxkbcommon_x11_link_deps = []
|
||||
if have_version_script
|
||||
libxkbcommon_x11_link_args += '-Wl,--version-script=' + meson.source_root()/'xkbcommon-x11.map'
|
||||
libxkbcommon_x11_link_deps += 'xkbcommon-x11.map'
|
||||
elif cc.get_argument_syntax() == 'msvc'
|
||||
libxkbcommon_x11_def = custom_target('xkbcommon-x11.def',
|
||||
command: [map_to_def, '@INPUT@', '@OUTPUT@'],
|
||||
input: 'xkbcommon-x11.map',
|
||||
output: 'xkbcommon-x11.def',
|
||||
)
|
||||
libxkbcommon_x11_link_deps += libxkbcommon_x11_def
|
||||
libxkbcommon_x11_link_args += '/DEF:' + libxkbcommon_x11_def.full_path()
|
||||
endif
|
||||
libxkbcommon_x11 = library(
|
||||
'xkbcommon-x11',
|
||||
'include/xkbcommon/xkbcommon-x11.h',
|
||||
libxkbcommon_x11_sources,
|
||||
link_args: libxkbcommon_x11_link_args,
|
||||
link_depends: libxkbcommon_x11_link_deps,
|
||||
gnu_symbol_visibility: 'hidden',
|
||||
version: '0.0.0',
|
||||
install: true,
|
||||
include_directories: include_directories('src', 'include'),
|
||||
link_with: libxkbcommon,
|
||||
dependencies: [
|
||||
xcb_dep,
|
||||
xcb_xkb_dep,
|
||||
],
|
||||
)
|
||||
install_headers(
|
||||
'include/xkbcommon/xkbcommon-x11.h',
|
||||
subdir: 'xkbcommon',
|
||||
)
|
||||
dep_libxkbcommon_x11 = declare_dependency(
|
||||
link_with: libxkbcommon_x11,
|
||||
include_directories: include_directories('include'),
|
||||
)
|
||||
pkgconfig.generate(
|
||||
libxkbcommon_x11,
|
||||
name: 'xkbcommon-x11',
|
||||
filebase: 'xkbcommon-x11',
|
||||
version: meson.project_version(),
|
||||
description: 'XKB API common to servers and clients - X11 support',
|
||||
requires: ['xkbcommon'],
|
||||
requires_private: ['xcb>=1.10', 'xcb-xkb>=1.10'],
|
||||
)
|
||||
endif
|
||||
|
||||
# libxkbregistry
|
||||
if get_option('enable-xkbregistry')
|
||||
dep_libxml = dependency('libxml-2.0')
|
||||
deps_libxkbregistry = [dep_libxml]
|
||||
libxkbregistry_sources = [
|
||||
'src/registry.c',
|
||||
'src/utils.h',
|
||||
'src/utils.c',
|
||||
'src/util-list.h',
|
||||
'src/util-list.c',
|
||||
]
|
||||
libxkbregistry_link_args = []
|
||||
libxkbregistry_link_deps = []
|
||||
if have_version_script
|
||||
libxkbregistry_link_args += '-Wl,--version-script=' + meson.source_root()/'xkbregistry.map'
|
||||
libxkbregistry_link_deps += 'xkbregistry.map'
|
||||
elif cc.get_argument_syntax() == 'msvc'
|
||||
libxkbregistry_def = custom_target('xkbregistry.def',
|
||||
command: [map_to_def, '@INPUT@', '@OUTPUT@'],
|
||||
input: 'xkbregistry.map',
|
||||
output: 'xkbregistry.def',
|
||||
)
|
||||
libxkbregistry_link_deps += libxkbregistry_def
|
||||
libxkbregistry_link_args += '/DEF:' + libxkbregistry_def.full_path()
|
||||
endif
|
||||
libxkbregistry = library(
|
||||
'xkbregistry',
|
||||
'include/xkbcommon/xkbregistry.h',
|
||||
libxkbregistry_sources,
|
||||
link_args: libxkbregistry_link_args,
|
||||
link_depends: libxkbregistry_link_deps,
|
||||
gnu_symbol_visibility: 'hidden',
|
||||
dependencies: deps_libxkbregistry,
|
||||
version: '0.0.0',
|
||||
install: true,
|
||||
include_directories: include_directories('src', 'include'),
|
||||
)
|
||||
install_headers(
|
||||
'include/xkbcommon/xkbregistry.h',
|
||||
subdir: 'xkbcommon',
|
||||
)
|
||||
pkgconfig.generate(
|
||||
libxkbregistry,
|
||||
name: 'xkbregistry',
|
||||
filebase: 'xkbregistry',
|
||||
version: meson.project_version(),
|
||||
description: 'XKB API to query available rules, models, layouts, variants and options',
|
||||
)
|
||||
|
||||
dep_libxkbregistry = declare_dependency(
|
||||
link_with: libxkbregistry,
|
||||
include_directories: include_directories('include'),
|
||||
)
|
||||
endif
|
||||
|
||||
man_pages = []
|
||||
|
||||
# Tools
|
||||
build_tools = have_getopt_long
|
||||
if build_tools
|
||||
libxkbcommon_tools_internal = static_library(
|
||||
'tools-internal',
|
||||
'tools/tools-common.h',
|
||||
'tools/tools-common.c',
|
||||
dependencies: dep_libxkbcommon,
|
||||
)
|
||||
tools_dep = declare_dependency(
|
||||
include_directories: [include_directories('tools', 'include')],
|
||||
link_with: libxkbcommon_tools_internal,
|
||||
)
|
||||
|
||||
executable('xkbcli', 'tools/xkbcli.c',
|
||||
dependencies: tools_dep, install: true)
|
||||
install_man('tools/xkbcli.1')
|
||||
|
||||
xkbcli_compile_keymap = executable('xkbcli-compile-keymap',
|
||||
'tools/compile-keymap.c',
|
||||
dependencies: tools_dep,
|
||||
install: true,
|
||||
install_dir: dir_libexec)
|
||||
install_man('tools/xkbcli-compile-keymap.1')
|
||||
# The same tool again, but with access to some private APIs.
|
||||
executable('compile-keymap',
|
||||
'tools/compile-keymap.c',
|
||||
libxkbcommon_sources,
|
||||
dependencies: [tools_dep],
|
||||
c_args: ['-DENABLE_PRIVATE_APIS'],
|
||||
include_directories: [include_directories('src', 'include')],
|
||||
install: false)
|
||||
executable('compose',
|
||||
'tools/compose.c',
|
||||
dependencies: tools_dep,
|
||||
include_directories: [include_directories('src', 'include')],
|
||||
install: false)
|
||||
configh_data.set10('HAVE_XKBCLI_COMPILE_KEYMAP', true)
|
||||
executable('xkbcli-how-to-type',
|
||||
'tools/how-to-type.c',
|
||||
dependencies: tools_dep,
|
||||
install: true,
|
||||
install_dir: dir_libexec)
|
||||
install_man('tools/xkbcli-how-to-type.1')
|
||||
configh_data.set10('HAVE_XKBCLI_HOW_TO_TYPE', true)
|
||||
if cc.has_header('linux/input.h')
|
||||
executable('xkbcli-interactive-evdev',
|
||||
'tools/interactive-evdev.c',
|
||||
dependencies: tools_dep,
|
||||
install: true,
|
||||
install_dir: dir_libexec)
|
||||
configh_data.set10('HAVE_XKBCLI_INTERACTIVE_EVDEV', true)
|
||||
install_man('tools/xkbcli-interactive-evdev.1')
|
||||
endif
|
||||
if get_option('enable-x11')
|
||||
x11_tools_dep = declare_dependency(
|
||||
link_with: libxkbcommon_x11,
|
||||
dependencies: [
|
||||
tools_dep,
|
||||
xcb_dep,
|
||||
xcb_xkb_dep,
|
||||
],
|
||||
)
|
||||
executable('xkbcli-interactive-x11',
|
||||
'tools/interactive-x11.c',
|
||||
dependencies: x11_tools_dep,
|
||||
install: true,
|
||||
install_dir: dir_libexec)
|
||||
install_man('tools/xkbcli-interactive-x11.1')
|
||||
configh_data.set10('HAVE_XKBCLI_INTERACTIVE_X11', true)
|
||||
endif
|
||||
if get_option('enable-wayland')
|
||||
wayland_client_dep = dependency('wayland-client', version: '>=1.2.0', required: false)
|
||||
wayland_protocols_dep = dependency('wayland-protocols', version: '>=1.12', required: false)
|
||||
wayland_scanner_dep = dependency('wayland-scanner', required: false, native: true)
|
||||
if not wayland_client_dep.found() or not wayland_protocols_dep.found() or not wayland_scanner_dep.found()
|
||||
error('''The Wayland xkbcli programs require wayland-client >= 1.2.0, wayland-protocols >= 1.7 which were not found.
|
||||
You can disable the Wayland xkbcli programs with -Denable-wayland=false.''')
|
||||
endif
|
||||
|
||||
wayland_scanner = find_program(wayland_scanner_dep.get_pkgconfig_variable('wayland_scanner'))
|
||||
wayland_scanner_code_gen = generator(
|
||||
wayland_scanner,
|
||||
output: '@BASENAME@-protocol.c',
|
||||
arguments: ['code', '@INPUT@', '@OUTPUT@'],
|
||||
)
|
||||
wayland_scanner_client_header_gen = generator(
|
||||
wayland_scanner,
|
||||
output: '@BASENAME@-client-protocol.h',
|
||||
arguments: ['client-header', '@INPUT@', '@OUTPUT@'],
|
||||
)
|
||||
wayland_protocols_datadir = wayland_protocols_dep.get_pkgconfig_variable('pkgdatadir')
|
||||
xdg_shell_xml = wayland_protocols_datadir/'stable/xdg-shell/xdg-shell.xml'
|
||||
xdg_shell_sources = [
|
||||
wayland_scanner_code_gen.process(xdg_shell_xml),
|
||||
wayland_scanner_client_header_gen.process(xdg_shell_xml),
|
||||
]
|
||||
executable('xkbcli-interactive-wayland',
|
||||
'tools/interactive-wayland.c',
|
||||
xdg_shell_sources,
|
||||
dependencies: [tools_dep, wayland_client_dep],
|
||||
install: true,
|
||||
install_dir: dir_libexec)
|
||||
install_man('tools/xkbcli-interactive-wayland.1')
|
||||
configh_data.set10('HAVE_XKBCLI_INTERACTIVE_WAYLAND', true)
|
||||
endif
|
||||
|
||||
if get_option('enable-xkbregistry')
|
||||
configh_data.set10('HAVE_XKBCLI_LIST', true)
|
||||
executable('xkbcli-list',
|
||||
'tools/registry-list.c',
|
||||
dependencies: dep_libxkbregistry,
|
||||
install: true,
|
||||
install_dir: dir_libexec)
|
||||
install_man('tools/xkbcli-list.1')
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
# xkeyboard-config "verifier"
|
||||
xkct_config = configuration_data()
|
||||
xkct_config.set('MESON_BUILD_ROOT', meson.build_root())
|
||||
xkct_config.set('XKB_CONFIG_ROOT', XKBCONFIGROOT)
|
||||
configure_file(input: 'test/xkeyboard-config-test.py.in',
|
||||
output: 'xkeyboard-config-test',
|
||||
configuration: xkct_config)
|
||||
|
||||
# Tests
|
||||
test_env = environment()
|
||||
test_env.set('XKB_LOG_LEVEL', 'debug')
|
||||
test_env.set('XKB_LOG_VERBOSITY', '10')
|
||||
test_env.set('top_srcdir', meson.source_root())
|
||||
test_env.set('top_builddir', meson.build_root())
|
||||
test_env.set('HAVE_XKBCLI_INTERACTIVE_EVDEV', configh_data.get('HAVE_XKBCLI_INTERACTIVE_EVDEV', 0).to_string())
|
||||
test_env.set('HAVE_XKBCLI_INTERACTIVE_WAYLAND', configh_data.get('HAVE_XKBCLI_INTERACTIVE_WAYLAND', 0).to_string())
|
||||
test_env.set('HAVE_XKBCLI_INTERACTIVE_X11', configh_data.get('HAVE_XKBCLI_INTERACTIVE_X11', 0).to_string())
|
||||
test_env.set('HAVE_XKBCLI_LIST', configh_data.get('HAVE_XKBCLI_LIST', 0).to_string())
|
||||
|
||||
test_configh_data = configuration_data()
|
||||
test_configh_data.set_quoted('TEST_XKB_CONFIG_ROOT', meson.source_root()/'test'/'data')
|
||||
configure_file(output: 'test-config.h', configuration: test_configh_data)
|
||||
|
||||
# Some tests need to use unexported symbols, so we link them against
|
||||
# an internal copy of libxkbcommon with all symbols exposed.
|
||||
libxkbcommon_test_internal = static_library(
|
||||
'xkbcommon-test-internal',
|
||||
'test/common.c',
|
||||
'test/test.h',
|
||||
'test/evdev-scancodes.h',
|
||||
'bench/bench.c',
|
||||
'bench/bench.h',
|
||||
libxkbcommon_sources,
|
||||
include_directories: include_directories('src', 'include'),
|
||||
)
|
||||
test_dep = declare_dependency(
|
||||
include_directories: include_directories('src', 'include'),
|
||||
link_with: libxkbcommon_test_internal,
|
||||
)
|
||||
if get_option('enable-x11')
|
||||
libxkbcommon_x11_internal = static_library(
|
||||
'xkbcommon-x11-internal',
|
||||
libxkbcommon_x11_sources,
|
||||
include_directories: include_directories('src', 'include'),
|
||||
link_with: libxkbcommon_test_internal,
|
||||
dependencies: [
|
||||
xcb_dep,
|
||||
xcb_xkb_dep,
|
||||
],
|
||||
)
|
||||
x11_test_dep = declare_dependency(
|
||||
link_with: libxkbcommon_x11_internal,
|
||||
dependencies: [
|
||||
test_dep,
|
||||
xcb_dep,
|
||||
xcb_xkb_dep,
|
||||
],
|
||||
)
|
||||
endif
|
||||
test(
|
||||
'keysym',
|
||||
executable('test-keysym', 'test/keysym.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
test(
|
||||
'keymap',
|
||||
executable('test-keymap', 'test/keymap.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
test(
|
||||
'filecomp',
|
||||
executable('test-filecomp', 'test/filecomp.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
# TODO: This test currently uses some functions that don't exist on Windows.
|
||||
if cc.get_id() != 'msvc'
|
||||
test(
|
||||
'context',
|
||||
executable('test-context', 'test/context.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
endif
|
||||
test(
|
||||
'rules-file',
|
||||
executable('test-rules-file', 'test/rules-file.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
test(
|
||||
'rules-file-includes',
|
||||
executable('test-rules-file-includes', 'test/rules-file-includes.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
test(
|
||||
'stringcomp',
|
||||
executable('test-stringcomp', 'test/stringcomp.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
test(
|
||||
'buffercomp',
|
||||
executable('test-buffercomp', 'test/buffercomp.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
test(
|
||||
'log',
|
||||
executable('test-log', 'test/log.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
test(
|
||||
'atom',
|
||||
executable('test-atom', 'test/atom.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
test(
|
||||
'utf8',
|
||||
executable('test-utf8', 'test/utf8.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
test(
|
||||
'state',
|
||||
executable('test-state', 'test/state.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
test(
|
||||
'keyseq',
|
||||
executable('test-keyseq', 'test/keyseq.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
test(
|
||||
'rulescomp',
|
||||
executable('test-rulescomp', 'test/rulescomp.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
test(
|
||||
'compose',
|
||||
executable('test-compose', 'test/compose.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
test(
|
||||
'utils',
|
||||
executable('test-utils', 'test/utils.c', dependencies: test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
test(
|
||||
'symbols-leak-test',
|
||||
find_program('test/symbols-leak-test.py'),
|
||||
env: test_env,
|
||||
suite: ['python-tests'],
|
||||
)
|
||||
if get_option('enable-x11')
|
||||
test(
|
||||
'x11',
|
||||
executable('test-x11', 'test/x11.c', dependencies: x11_test_dep),
|
||||
env: test_env,
|
||||
)
|
||||
# test/x11comp is meant to be run, but it is (temporarily?) disabled.
|
||||
# See: https://github.com/xkbcommon/libxkbcommon/issues/30
|
||||
executable('test-x11comp', 'test/x11comp.c', dependencies: x11_test_dep)
|
||||
endif
|
||||
if get_option('enable-xkbregistry')
|
||||
test(
|
||||
'registry',
|
||||
executable('test-registry', 'test/registry.c',
|
||||
include_directories: include_directories('src'),
|
||||
dependencies: dep_libxkbregistry),
|
||||
env: test_env,
|
||||
)
|
||||
endif
|
||||
if build_tools
|
||||
test('tool-option-parsing',
|
||||
find_program('test/tool-option-parsing.py'),
|
||||
env: test_env,
|
||||
suite: ['python-tests'])
|
||||
|
||||
# A set of keysyms to test for. Add one or two symbols to this array
|
||||
# whenever the xorgproto gets updated to make sure we resolve them.
|
||||
keysyms_to_test = [
|
||||
'XF86Macro23',
|
||||
]
|
||||
|
||||
env = environment()
|
||||
env.set('XKB_CONFIG_ROOT', meson.source_root()/'test'/'data')
|
||||
foreach keysym: keysyms_to_test
|
||||
test('keysym-test-@0@'.format(keysym),
|
||||
find_program('test/test-keysym.py'),
|
||||
env: env,
|
||||
args: [keysym, '--tool', xkbcli_compile_keymap],
|
||||
suite: ['python-tests'])
|
||||
endforeach
|
||||
endif
|
||||
|
||||
valgrind = find_program('valgrind', required: false)
|
||||
if valgrind.found()
|
||||
add_test_setup('valgrind',
|
||||
exe_wrapper: [valgrind,
|
||||
'--leak-check=full',
|
||||
'--track-origins=yes',
|
||||
'--gen-suppressions=all',
|
||||
'--error-exitcode=99'],
|
||||
timeout_multiplier : 10)
|
||||
else
|
||||
message('valgrind not found, disabling valgrind test setup')
|
||||
endif
|
||||
|
||||
|
||||
# Fuzzing target programs.
|
||||
executable('fuzz-keymap', 'fuzz/keymap/target.c', dependencies: test_dep)
|
||||
executable('fuzz-compose', 'fuzz/compose/target.c', dependencies: test_dep)
|
||||
|
||||
|
||||
# Benchmarks.
|
||||
bench_env = environment()
|
||||
bench_env.set('top_srcdir', meson.source_root())
|
||||
benchmark(
|
||||
'key-proc',
|
||||
executable('bench-key-proc', 'bench/key-proc.c', dependencies: test_dep),
|
||||
env: bench_env,
|
||||
)
|
||||
benchmark(
|
||||
'rules',
|
||||
executable('bench-rules', 'bench/rules.c', dependencies: test_dep),
|
||||
env: bench_env,
|
||||
)
|
||||
benchmark(
|
||||
'rulescomp',
|
||||
executable('bench-rulescomp', 'bench/rulescomp.c', dependencies: test_dep),
|
||||
env: bench_env,
|
||||
)
|
||||
benchmark(
|
||||
'compose',
|
||||
executable('bench-compose', 'bench/compose.c', dependencies: test_dep),
|
||||
env: bench_env,
|
||||
)
|
||||
benchmark(
|
||||
'atom',
|
||||
executable('bench-atom', 'bench/atom.c', dependencies: test_dep),
|
||||
env: bench_env,
|
||||
)
|
||||
if get_option('enable-x11')
|
||||
benchmark(
|
||||
'x11',
|
||||
executable('bench-x11', 'bench/x11.c', dependencies: x11_test_dep),
|
||||
env: bench_env,
|
||||
)
|
||||
endif
|
||||
|
||||
|
||||
# Documentation.
|
||||
if get_option('enable-docs')
|
||||
doxygen = find_program('doxygen', required: false)
|
||||
if not doxygen.found()
|
||||
error('''Documentation requires doxygen which was not found.
|
||||
You can disable the documentation with -Denable-docs=false.''')
|
||||
endif
|
||||
doxygen_wrapper = find_program('scripts/doxygen-wrapper')
|
||||
|
||||
doxygen_input = [
|
||||
'README.md',
|
||||
'doc/doxygen-extra.css',
|
||||
'doc/quick-guide.md',
|
||||
'doc/compat.md',
|
||||
'doc/user-configuration.md',
|
||||
'doc/rules-format.md',
|
||||
'doc/keymap-format-text-v1.md',
|
||||
'include/xkbcommon/xkbcommon.h',
|
||||
'include/xkbcommon/xkbcommon-names.h',
|
||||
'include/xkbcommon/xkbcommon-x11.h',
|
||||
'include/xkbcommon/xkbcommon-compose.h',
|
||||
'include/xkbcommon/xkbregistry.h',
|
||||
]
|
||||
doxygen_data = configuration_data()
|
||||
doxygen_data.set('PACKAGE_NAME', meson.project_name())
|
||||
doxygen_data.set('PACKAGE_VERSION', meson.project_version())
|
||||
doxygen_data.set('INPUT', ' '.join(doxygen_input))
|
||||
doxygen_data.set('OUTPUT_DIRECTORY', meson.build_root())
|
||||
doxyfile = configure_file(
|
||||
input: 'doc/Doxyfile.in',
|
||||
output: 'Doxyfile',
|
||||
configuration: doxygen_data,
|
||||
)
|
||||
# TODO: Meson should provide this.
|
||||
docdir = get_option('datadir')/'doc'/meson.project_name()
|
||||
custom_target(
|
||||
'doc',
|
||||
input: [doxyfile] + doxygen_input,
|
||||
output: 'html',
|
||||
command: [doxygen_wrapper, doxygen.path(), meson.build_root()/'Doxyfile', meson.source_root()],
|
||||
install: true,
|
||||
install_dir: docdir,
|
||||
build_by_default: true,
|
||||
)
|
||||
endif
|
||||
|
||||
configure_file(output: 'config.h', configuration: configh_data)
|
||||
|
||||
|
||||
# Stable variables for projects using xkbcommon as a subproject.
|
||||
# These variables should not be renamed.
|
||||
libxkbcommon_dep = dep_libxkbcommon
|
||||
if get_option('enable-x11')
|
||||
libxkbcommon_x11_dep = dep_libxkbcommon_x11
|
||||
endif
|
||||
if get_option('enable-xkbregistry')
|
||||
libxkbregistry_dep = dep_libxkbregistry
|
||||
endif
|
|
@ -0,0 +1,69 @@
|
|||
option(
|
||||
'xkb-config-root',
|
||||
type: 'string',
|
||||
description: 'The XKB config root [default=xkeyboard-config install path]',
|
||||
)
|
||||
option(
|
||||
'xkb-config-extra-path',
|
||||
type: 'string',
|
||||
description: 'Extra lookup path for system-wide XKB data [default=$sysconfdir/xkb]',
|
||||
)
|
||||
option(
|
||||
'x-locale-root',
|
||||
type: 'string',
|
||||
description: 'The X locale root [default=$datadir/X11/locale]',
|
||||
)
|
||||
option(
|
||||
'default-rules',
|
||||
type: 'string',
|
||||
value: 'evdev',
|
||||
description: 'Default XKB ruleset',
|
||||
)
|
||||
option(
|
||||
'default-model',
|
||||
type: 'string',
|
||||
value: 'pc105',
|
||||
description: 'Default XKB model',
|
||||
)
|
||||
option(
|
||||
'default-layout',
|
||||
type: 'string',
|
||||
value: 'us',
|
||||
description: 'Default XKB layout',
|
||||
)
|
||||
option(
|
||||
'default-variant',
|
||||
type: 'string',
|
||||
value: '',
|
||||
description: 'Default XKB variant',
|
||||
)
|
||||
option(
|
||||
'default-options',
|
||||
type: 'string',
|
||||
value: '',
|
||||
description: 'Default XKB options',
|
||||
)
|
||||
option(
|
||||
'enable-x11',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Enable building the xkbcommon-x11 library',
|
||||
)
|
||||
option(
|
||||
'enable-docs',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Enable building the documentation',
|
||||
)
|
||||
option(
|
||||
'enable-wayland',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Enable support for Wayland utility programs',
|
||||
)
|
||||
option(
|
||||
'enable-xkbregistry',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Enable building libxkbregistry',
|
||||
)
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
# Run doxygen such that the working directory is the source root.
|
||||
# This is needed for various reasons (e.g. relative references in md files).
|
||||
# Do not use directly.
|
||||
DOXYGEN="$1"
|
||||
DOXYFILE="$2"
|
||||
ABS_TOP_SRCDIR="$3"
|
||||
cd "$ABS_TOP_SRCDIR" && exec "$DOXYGEN" "$DOXYFILE"
|
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/env python
|
||||
from __future__ import print_function
|
||||
import re
|
||||
import os
|
||||
|
||||
# expected format:
|
||||
# #define XF86XK_FooBar _EVDEVK(0x123) /* some optional comment */
|
||||
evdev_pattern = re.compile(r'^#define\s+XF86XK_(?P<name>\w+)\s+_EVDEVK\((?P<value>0x[0-9A-Fa-f]+)\)')
|
||||
|
||||
prefix = os.environ.get('X11_HEADERS_PREFIX', '/usr')
|
||||
HEADERS = [
|
||||
prefix + '/include/X11/keysymdef.h',
|
||||
prefix + '/include/X11/XF86keysym.h',
|
||||
prefix + '/include/X11/Sunkeysym.h',
|
||||
prefix + '/include/X11/DECkeysym.h',
|
||||
prefix + '/include/X11/HPkeysym.h',
|
||||
]
|
||||
|
||||
print('''#ifndef _XKBCOMMON_KEYSYMS_H
|
||||
#define _XKBCOMMON_KEYSYMS_H
|
||||
|
||||
/* This file is autogenerated; please do not commit directly. */
|
||||
|
||||
#define XKB_KEY_NoSymbol 0x000000 /* Special KeySym */
|
||||
''')
|
||||
for path in HEADERS:
|
||||
with open(path) as header:
|
||||
for line in header:
|
||||
if '#ifdef' in line or '#ifndef' in line or '#endif' in line:
|
||||
continue
|
||||
|
||||
# Remove #define _OSF_Keysyms and such.
|
||||
if '#define _' in line:
|
||||
continue
|
||||
|
||||
# Handle a duplicate definition in HPkeysyms.h which kicks in if
|
||||
# it's not already defined.
|
||||
if 'XK_Ydiaeresis' in line and '0x100000ee' in line:
|
||||
continue
|
||||
|
||||
# Replace the xorgproto _EVDEVK macro with the actual value
|
||||
# 0x10081000 is the base, the evdev hex code is added to that.
|
||||
# We replace to make parsing of the keys later easier.
|
||||
match = re.match(evdev_pattern, line)
|
||||
if match:
|
||||
value = 0x10081000 + int(match.group('value'), 16)
|
||||
line = re.sub(r'_EVDEVK\(0x([0-9A-Fa-f]+)\)', '{:#x}'.format(value), line)
|
||||
|
||||
line = re.sub(r'#define\s*(\w*)XK_', r'#define XKB_KEY_\1', line)
|
||||
|
||||
print(line, end='')
|
||||
print('\n\n#endif')
|
44
app/src/main/jni/libxkbcommon/xkbcommon/makekeys.py → app/src/main/jni/libxkbcommon/xkbcommon/scripts/makekeys
Normal file → Executable file
44
app/src/main/jni/libxkbcommon/xkbcommon/makekeys.py → app/src/main/jni/libxkbcommon/xkbcommon/scripts/makekeys
Normal file → Executable file
|
@ -2,10 +2,15 @@
|
|||
|
||||
import re, sys, itertools
|
||||
|
||||
import perfect_hash
|
||||
|
||||
pattern = re.compile(r'^#define\s+XKB_KEY_(?P<name>\w+)\s+(?P<value>0x[0-9a-fA-F]+)\s')
|
||||
matches = [pattern.match(line) for line in open(sys.argv[1])]
|
||||
entries = [(m.group("name"), int(m.group("value"), 16)) for m in matches if m]
|
||||
|
||||
entries_isorted = sorted(entries, key=lambda e: e[0].lower())
|
||||
entries_kssorted = sorted(entries, key=lambda e: e[1])
|
||||
|
||||
print('''
|
||||
/**
|
||||
* This file comes from libxkbcommon and was generated by makekeys.py
|
||||
|
@ -17,20 +22,53 @@ print('''
|
|||
entry_offsets = {}
|
||||
|
||||
print('''
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Woverlength-strings"
|
||||
#endif
|
||||
static const char *keysym_names =
|
||||
'''.strip())
|
||||
offs = 0
|
||||
for (name, _) in sorted(entries, key=lambda e: e[0].lower()):
|
||||
for (name, _) in entries_isorted:
|
||||
entry_offsets[name] = offs
|
||||
print(' "{name}\\0"'.format(name=name))
|
||||
offs += len(name) + 1
|
||||
print('''
|
||||
;
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
'''.strip())
|
||||
|
||||
|
||||
template = r'''
|
||||
static const uint16_t keysym_name_G[] = {
|
||||
$G
|
||||
};
|
||||
|
||||
static size_t
|
||||
keysym_name_hash_f(const char *key, const char *T)
|
||||
{
|
||||
size_t sum = 0;
|
||||
for (size_t i = 0; key[i] != '\0'; i++)
|
||||
sum += T[i % $NS] * key[i];
|
||||
return sum % $NG;
|
||||
}
|
||||
|
||||
static size_t
|
||||
keysym_name_perfect_hash(const char *key)
|
||||
{
|
||||
return (
|
||||
keysym_name_G[keysym_name_hash_f(key, "$S1")] +
|
||||
keysym_name_G[keysym_name_hash_f(key, "$S2")]
|
||||
) % $NG;
|
||||
}
|
||||
'''
|
||||
print(perfect_hash.generate_code(
|
||||
keys=[name for name, value in entries_isorted],
|
||||
template=template,
|
||||
))
|
||||
|
||||
print('''
|
||||
struct name_keysym {
|
||||
xkb_keysym_t keysym;
|
||||
|
@ -42,10 +80,10 @@ def print_entries(x):
|
|||
print(' {{ 0x{value:08x}, {offs} }}, /* {name} */'.format(offs=entry_offsets[name], value=value, name=name))
|
||||
|
||||
print('static const struct name_keysym name_to_keysym[] = {')
|
||||
print_entries(sorted(entries, key=lambda e: e[0].lower()))
|
||||
print_entries(entries_isorted)
|
||||
print('};\n')
|
||||
|
||||
# *.sort() is stable so we always get the first keysym for duplicate
|
||||
print('static const struct name_keysym keysym_to_name[] = {')
|
||||
print_entries(next(g[1]) for g in itertools.groupby(sorted(entries, key=lambda e: e[1]), key=lambda e: e[1]))
|
||||
print_entries(next(g[1]) for g in itertools.groupby(entries_kssorted, key=lambda e: e[1]))
|
||||
print('};')
|
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""A script to generate MSVC Module-Definition files from version-script
|
||||
files (which are maintained manually)."""
|
||||
|
||||
import re
|
||||
import sys
|
||||
import pathlib
|
||||
|
||||
|
||||
def symbols_from_map(path):
|
||||
return re.findall(r'^\s+(r?xkb_.*);', path.read_text('utf-8'), re.MULTILINE)
|
||||
|
||||
|
||||
if 2 > len(sys.argv) > 3:
|
||||
raise SystemExit("Usage: {} file.map [file.def]".format(sys.argv[0]))
|
||||
|
||||
|
||||
map_file = pathlib.Path(sys.argv[1])
|
||||
map_symbols = set(symbols_from_map(map_file))
|
||||
|
||||
if len(sys.argv) == 3:
|
||||
def_file = open(sys.argv[2], "w", encoding="utf-8")
|
||||
else:
|
||||
def_file = sys.stdout
|
||||
|
||||
def_file.write("LIBRARY {}\n".format(map_file.stem))
|
||||
def_file.write("EXPORTS\n")
|
||||
for symbol in sorted(map_symbols):
|
||||
def_file.write("\t{}\n".format(symbol))
|
|
@ -0,0 +1,674 @@
|
|||
# Derived from: https://github.com/ilanschnell/perfect-hash
|
||||
# Commit: 6b7dd80a525dbd4349ea2c69f04a9c96f3c2fd54
|
||||
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (c) 2019 - 2021, Ilan Schnell
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the Ilan Schnell nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL ILAN SCHNELL BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""
|
||||
Generate a minimal perfect hash function for the keys in a file,
|
||||
desired hash values may be specified within this file as well.
|
||||
A given code template is filled with parameters, such that the
|
||||
output is code which implements the hash function.
|
||||
Templates can easily be constructed for any programming language.
|
||||
|
||||
The code is based on an a program A.M. Kuchling wrote:
|
||||
http://www.amk.ca/python/code/perfect-hash
|
||||
|
||||
The algorithm the program uses is described in the paper
|
||||
'Optimal algorithms for minimal perfect hashing',
|
||||
Z. J. Czech, G. Havas and B.S. Majewski.
|
||||
http://citeseer.ist.psu.edu/122364.html
|
||||
|
||||
The algorithm works like this:
|
||||
|
||||
1. You have K keys, that you want to perfectly hash against some
|
||||
desired hash values.
|
||||
|
||||
2. Choose a number N larger than K. This is the number of
|
||||
vertices in a graph G, and also the size of the resulting table G.
|
||||
|
||||
3. Pick two random hash functions f1, f2, that return values from 0..N-1.
|
||||
|
||||
4. Now, for all keys, you draw an edge between vertices f1(key) and f2(key)
|
||||
of the graph G, and associate the desired hash value with that edge.
|
||||
|
||||
5. If G is cyclic, go back to step 2.
|
||||
|
||||
6. Assign values to each vertex such that, for each edge, you can add
|
||||
the values for the two vertices and get the desired (hash) value
|
||||
for that edge. This task is easy, because the graph is acyclic.
|
||||
This is done by picking a vertex, and assigning it a value of 0.
|
||||
Then do a depth-first search, assigning values to new vertices so that
|
||||
they sum up properly.
|
||||
|
||||
7. f1, f2, and vertex values of G now make up a perfect hash function.
|
||||
|
||||
|
||||
For simplicity, the implementation of the algorithm combines steps 5 and 6.
|
||||
That is, we check for loops in G and assign the vertex values in one procedure.
|
||||
If this procedure succeeds, G is acyclic and the vertex values are assigned.
|
||||
If the procedure fails, G is cyclic, and we go back to step 2, replacing G
|
||||
with a new graph, and thereby discarding the vertex values from the failed
|
||||
attempt.
|
||||
"""
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import sys
|
||||
import random
|
||||
import string
|
||||
import subprocess
|
||||
import shutil
|
||||
import tempfile
|
||||
from collections import defaultdict
|
||||
from os.path import join
|
||||
|
||||
if sys.version_info[0] == 2:
|
||||
from cStringIO import StringIO
|
||||
else:
|
||||
from io import StringIO
|
||||
|
||||
|
||||
__version__ = '0.4.2'
|
||||
|
||||
|
||||
verbose = False
|
||||
trials = 150
|
||||
|
||||
|
||||
class Graph(object):
|
||||
"""
|
||||
Implements a graph with 'N' vertices. First, you connect the graph with
|
||||
edges, which have a desired value associated. Then the vertex values
|
||||
are assigned, which will fail if the graph is cyclic. The vertex values
|
||||
are assigned such that the two values corresponding to an edge add up to
|
||||
the desired edge value (mod N).
|
||||
"""
|
||||
def __init__(self, N):
|
||||
self.N = N # number of vertices
|
||||
|
||||
# maps a vertex number to the list of tuples (vertex, edge value)
|
||||
# to which it is connected by edges.
|
||||
self.adjacent = defaultdict(list)
|
||||
|
||||
def connect(self, vertex1, vertex2, edge_value):
|
||||
"""
|
||||
Connect 'vertex1' and 'vertex2' with an edge, with associated
|
||||
value 'value'
|
||||
"""
|
||||
# Add vertices to each other's adjacent list
|
||||
self.adjacent[vertex1].append((vertex2, edge_value))
|
||||
self.adjacent[vertex2].append((vertex1, edge_value))
|
||||
|
||||
def assign_vertex_values(self):
|
||||
"""
|
||||
Try to assign the vertex values, such that, for each edge, you can
|
||||
add the values for the two vertices involved and get the desired
|
||||
value for that edge, i.e. the desired hash key.
|
||||
This will fail when the graph is cyclic.
|
||||
|
||||
This is done by a Depth-First Search of the graph. If the search
|
||||
finds a vertex that was visited before, there's a loop and False is
|
||||
returned immediately, i.e. the assignment is terminated.
|
||||
On success (when the graph is acyclic) True is returned.
|
||||
"""
|
||||
self.vertex_values = self.N * [-1] # -1 means unassigned
|
||||
|
||||
visited = self.N * [False]
|
||||
|
||||
# Loop over all vertices, taking unvisited ones as roots.
|
||||
for root in range(self.N):
|
||||
if visited[root]:
|
||||
continue
|
||||
|
||||
# explore tree starting at 'root'
|
||||
self.vertex_values[root] = 0 # set arbitrarily to zero
|
||||
|
||||
# Stack of vertices to visit, a list of tuples (parent, vertex)
|
||||
tovisit = [(None, root)]
|
||||
while tovisit:
|
||||
parent, vertex = tovisit.pop()
|
||||
visited[vertex] = True
|
||||
|
||||
# Loop over adjacent vertices, but skip the vertex we arrived
|
||||
# here from the first time it is encountered.
|
||||
skip = True
|
||||
for neighbor, edge_value in self.adjacent[vertex]:
|
||||
if skip and neighbor == parent:
|
||||
skip = False
|
||||
continue
|
||||
|
||||
if visited[neighbor]:
|
||||
# We visited here before, so the graph is cyclic.
|
||||
return False
|
||||
|
||||
tovisit.append((vertex, neighbor))
|
||||
|
||||
# Set new vertex's value to the desired edge value,
|
||||
# minus the value of the vertex we came here from.
|
||||
self.vertex_values[neighbor] = (
|
||||
edge_value - self.vertex_values[vertex]) % self.N
|
||||
|
||||
# check if all vertices have a valid value
|
||||
for vertex in range(self.N):
|
||||
assert self.vertex_values[vertex] >= 0
|
||||
|
||||
# We got though, so the graph is acyclic,
|
||||
# and all values are now assigned.
|
||||
return True
|
||||
|
||||
|
||||
class StrSaltHash(object):
|
||||
"""
|
||||
Random hash function generator.
|
||||
Simple byte level hashing: each byte is multiplied to another byte from
|
||||
a random string of characters, summed up, and finally modulo NG is
|
||||
taken.
|
||||
"""
|
||||
chars = string.ascii_letters + string.digits
|
||||
|
||||
def __init__(self, N):
|
||||
self.N = N
|
||||
self.salt = ''
|
||||
|
||||
def __call__(self, key):
|
||||
# XXX: xkbcommon modification: make the salt length a power of 2
|
||||
# so that the % operation in the hash is fast.
|
||||
while len(self.salt) < max(len(key), 32): # add more salt as necessary
|
||||
self.salt += random.choice(self.chars)
|
||||
|
||||
return sum(ord(self.salt[i]) * ord(c)
|
||||
for i, c in enumerate(key)) % self.N
|
||||
|
||||
template = """
|
||||
def hash_f(key, T):
|
||||
return sum(ord(T[i % $NS]) * ord(c) for i, c in enumerate(key)) % $NG
|
||||
|
||||
def perfect_hash(key):
|
||||
return (G[hash_f(key, "$S1")] +
|
||||
G[hash_f(key, "$S2")]) % $NG
|
||||
"""
|
||||
|
||||
class IntSaltHash(object):
|
||||
"""
|
||||
Random hash function generator.
|
||||
Simple byte level hashing, each byte is multiplied in sequence to a table
|
||||
containing random numbers, summed tp, and finally modulo NG is taken.
|
||||
"""
|
||||
def __init__(self, N):
|
||||
self.N = N
|
||||
self.salt = []
|
||||
|
||||
def __call__(self, key):
|
||||
while len(self.salt) < len(key): # add more salt as necessary
|
||||
self.salt.append(random.randint(1, self.N - 1))
|
||||
|
||||
return sum(self.salt[i] * ord(c)
|
||||
for i, c in enumerate(key)) % self.N
|
||||
|
||||
template = """
|
||||
S1 = [$S1]
|
||||
S2 = [$S2]
|
||||
assert len(S1) == len(S2) == $NS
|
||||
|
||||
def hash_f(key, T):
|
||||
return sum(T[i % $NS] * ord(c) for i, c in enumerate(key)) % $NG
|
||||
|
||||
def perfect_hash(key):
|
||||
return (G[hash_f(key, S1)] + G[hash_f(key, S2)]) % $NG
|
||||
"""
|
||||
|
||||
def builtin_template(Hash):
|
||||
return """\
|
||||
# =======================================================================
|
||||
# ================= Python code for perfect hash function ===============
|
||||
# =======================================================================
|
||||
|
||||
G = [$G]
|
||||
""" + Hash.template + """
|
||||
# ============================ Sanity check =============================
|
||||
|
||||
K = [$K]
|
||||
assert len(K) == $NK
|
||||
|
||||
for h, k in enumerate(K):
|
||||
assert perfect_hash(k) == h
|
||||
"""
|
||||
|
||||
|
||||
class TooManyInterationsError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def generate_hash(keys, Hash=StrSaltHash):
|
||||
"""
|
||||
Return hash functions f1 and f2, and G for a perfect minimal hash.
|
||||
Input is an iterable of 'keys', whos indicies are the desired hash values.
|
||||
'Hash' is a random hash function generator, that means Hash(N) returns a
|
||||
returns a random hash function which returns hash values from 0..N-1.
|
||||
"""
|
||||
if not isinstance(keys, (list, tuple)):
|
||||
raise TypeError("list or tuple expected")
|
||||
NK = len(keys)
|
||||
if NK != len(set(keys)):
|
||||
raise ValueError("duplicate keys")
|
||||
for key in keys:
|
||||
if not isinstance(key, str):
|
||||
raise TypeError("key a not string: %r" % key)
|
||||
if NK > 10000 and Hash == StrSaltHash:
|
||||
print("""\
|
||||
WARNING: You have %d keys.
|
||||
Using --hft=1 is likely to fail for so many keys.
|
||||
Please use --hft=2 instead.
|
||||
""" % NK)
|
||||
|
||||
# the number of vertices in the graph G
|
||||
NG = NK + 1
|
||||
if verbose:
|
||||
print('NG = %d' % NG)
|
||||
|
||||
trial = 0 # Number of trial graphs so far
|
||||
while True:
|
||||
if (trial % trials) == 0: # trials failures, increase NG slightly
|
||||
if trial > 0:
|
||||
NG = max(NG + 1, int(1.05 * NG))
|
||||
if verbose:
|
||||
sys.stdout.write('\nGenerating graphs NG = %d ' % NG)
|
||||
trial += 1
|
||||
|
||||
if NG > 100 * (NK + 1):
|
||||
raise TooManyInterationsError("%d keys" % NK)
|
||||
|
||||
if verbose:
|
||||
sys.stdout.write('.')
|
||||
sys.stdout.flush()
|
||||
|
||||
G = Graph(NG) # Create graph with NG vertices
|
||||
f1 = Hash(NG) # Create 2 random hash functions
|
||||
f2 = Hash(NG)
|
||||
|
||||
# Connect vertices given by the values of the two hash functions
|
||||
# for each key. Associate the desired hash value with each edge.
|
||||
for hashval, key in enumerate(keys):
|
||||
G.connect(f1(key), f2(key), hashval)
|
||||
|
||||
# Try to assign the vertex values. This will fail when the graph
|
||||
# is cyclic. But when the graph is acyclic it will succeed and we
|
||||
# break out, because we're done.
|
||||
if G.assign_vertex_values():
|
||||
break
|
||||
|
||||
if verbose:
|
||||
print('\nAcyclic graph found after %d trials.' % trial)
|
||||
print('NG = %d' % NG)
|
||||
|
||||
# Sanity check the result by actually verifying that all the keys
|
||||
# hash to the right value.
|
||||
for hashval, key in enumerate(keys):
|
||||
assert hashval == (
|
||||
G.vertex_values[f1(key)] + G.vertex_values[f2(key)]
|
||||
) % NG
|
||||
|
||||
if verbose:
|
||||
print('OK')
|
||||
|
||||
return f1, f2, G.vertex_values
|
||||
|
||||
|
||||
class Format(object):
|
||||
|
||||
def __init__(self, width=76, indent=4, delimiter=', '):
|
||||
self.width = width
|
||||
self.indent = indent
|
||||
self.delimiter = delimiter
|
||||
|
||||
def print_format(self):
|
||||
print("Format options:")
|
||||
for name in 'width', 'indent', 'delimiter':
|
||||
print(' %s: %r' % (name, getattr(self, name)))
|
||||
|
||||
def __call__(self, data, quote=False):
|
||||
if not isinstance(data, (list, tuple)):
|
||||
return str(data)
|
||||
|
||||
lendel = len(self.delimiter)
|
||||
aux = StringIO()
|
||||
pos = 20
|
||||
for i, elt in enumerate(data):
|
||||
last = bool(i == len(data) - 1)
|
||||
|
||||
s = ('"%s"' if quote else '%s') % elt
|
||||
|
||||
if pos + len(s) + lendel > self.width:
|
||||
aux.write('\n' + (self.indent * ' '))
|
||||
pos = self.indent
|
||||
|
||||
aux.write(s)
|
||||
pos += len(s)
|
||||
if not last:
|
||||
aux.write(self.delimiter)
|
||||
pos += lendel
|
||||
|
||||
return '\n'.join(l.rstrip() for l in aux.getvalue().split('\n'))
|
||||
|
||||
|
||||
def generate_code(keys, Hash=StrSaltHash, template=None, options=None):
|
||||
"""
|
||||
Takes a list of key value pairs and inserts the generated parameter
|
||||
lists into the 'template' string. 'Hash' is the random hash function
|
||||
generator, and the optional keywords are formating options.
|
||||
The return value is the substituted code template.
|
||||
"""
|
||||
f1, f2, G = generate_hash(keys, Hash)
|
||||
|
||||
assert f1.N == f2.N == len(G)
|
||||
try:
|
||||
salt_len = len(f1.salt)
|
||||
assert salt_len == len(f2.salt)
|
||||
except TypeError:
|
||||
salt_len = None
|
||||
|
||||
if template is None:
|
||||
template = builtin_template(Hash)
|
||||
|
||||
if options is None:
|
||||
fmt = Format()
|
||||
else:
|
||||
fmt = Format(width=options.width, indent=options.indent,
|
||||
delimiter=options.delimiter)
|
||||
|
||||
if verbose:
|
||||
fmt.print_format()
|
||||
|
||||
return string.Template(template).substitute(
|
||||
NS = salt_len,
|
||||
S1 = fmt(f1.salt),
|
||||
S2 = fmt(f2.salt),
|
||||
NG = len(G),
|
||||
G = fmt(G),
|
||||
NK = len(keys),
|
||||
K = fmt(list(keys), quote=True))
|
||||
|
||||
|
||||
def read_table(filename, options):
|
||||
"""
|
||||
Reads keys and desired hash value pairs from a file. If no column
|
||||
for the hash value is specified, a sequence of hash values is generated,
|
||||
from 0 to N-1, where N is the number of rows found in the file.
|
||||
"""
|
||||
if verbose:
|
||||
print("Reading table from file `%s' to extract keys." % filename)
|
||||
try:
|
||||
fi = open(filename)
|
||||
except IOError:
|
||||
sys.exit("Error: Could not open `%s' for reading." % filename)
|
||||
|
||||
keys = []
|
||||
|
||||
if verbose:
|
||||
print("Reader options:")
|
||||
for name in 'comment', 'splitby', 'keycol':
|
||||
print(' %s: %r' % (name, getattr(options, name)))
|
||||
|
||||
for n, line in enumerate(fi):
|
||||
line = line.strip()
|
||||
if not line or line.startswith(options.comment):
|
||||
continue
|
||||
|
||||
if line.count(options.comment): # strip content after comment
|
||||
line = line.split(options.comment)[0].strip()
|
||||
|
||||
row = [col.strip() for col in line.split(options.splitby)]
|
||||
|
||||
try:
|
||||
key = row[options.keycol - 1]
|
||||
except IndexError:
|
||||
sys.exit("%s:%d: Error: Cannot read key, not enough columns." %
|
||||
(filename, n + 1))
|
||||
|
||||
keys.append(key)
|
||||
|
||||
fi.close()
|
||||
|
||||
if not keys:
|
||||
exit("Error: no keys found in file `%s'." % filename)
|
||||
|
||||
return keys
|
||||
|
||||
|
||||
def read_template(filename):
|
||||
if verbose:
|
||||
print("Reading template from file `%s'" % filename)
|
||||
try:
|
||||
with open(filename, 'r') as fi:
|
||||
return fi.read()
|
||||
except IOError:
|
||||
sys.exit("Error: Could not open `%s' for reading." % filename)
|
||||
|
||||
|
||||
def run_code(code):
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
path = join(tmpdir, 't.py')
|
||||
with open(path, 'w') as fo:
|
||||
fo.write(code)
|
||||
try:
|
||||
subprocess.check_call([sys.executable, path])
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise AssertionError(e)
|
||||
finally:
|
||||
shutil.rmtree(tmpdir)
|
||||
|
||||
|
||||
def main():
|
||||
from optparse import OptionParser
|
||||
|
||||
usage = "usage: %prog [options] KEYS_FILE [TMPL_FILE]"
|
||||
|
||||
description = """\
|
||||
Generates code for perfect hash functions from
|
||||
a file with keywords and a code template.
|
||||
If no template file is provided, a small built-in Python template
|
||||
is processed and the output code is written to stdout.
|
||||
"""
|
||||
|
||||
parser = OptionParser(usage = usage,
|
||||
description = description,
|
||||
prog = sys.argv[0],
|
||||
version = "%prog: " + __version__)
|
||||
|
||||
parser.add_option("--delimiter",
|
||||
action = "store",
|
||||
default = ", ",
|
||||
help = "Delimiter for list items used in output, "
|
||||
"the default delimiter is '%default'",
|
||||
metavar = "STR")
|
||||
|
||||
parser.add_option("--indent",
|
||||
action = "store",
|
||||
default = 4,
|
||||
type = "int",
|
||||
help = "Make INT spaces at the beginning of a "
|
||||
"new line when generated list is wrapped. "
|
||||
"Default is %default",
|
||||
metavar = "INT")
|
||||
|
||||
parser.add_option("--width",
|
||||
action = "store",
|
||||
default = 76,
|
||||
type = "int",
|
||||
help = "Maximal width of generated list when "
|
||||
"wrapped. Default width is %default",
|
||||
metavar = "INT")
|
||||
|
||||
parser.add_option("--comment",
|
||||
action = "store",
|
||||
default = "#",
|
||||
help = "STR is the character, or sequence of "
|
||||
"characters, which marks the beginning "
|
||||
"of a comment (which runs till "
|
||||
"the end of the line), in the input "
|
||||
"KEYS_FILE. "
|
||||
"Default is '%default'",
|
||||
metavar = "STR")
|
||||
|
||||
parser.add_option("--splitby",
|
||||
action = "store",
|
||||
default = ",",
|
||||
help = "STR is the character by which the columns "
|
||||
"in the input KEYS_FILE are split. "
|
||||
"Default is '%default'",
|
||||
metavar = "STR")
|
||||
|
||||
parser.add_option("--keycol",
|
||||
action = "store",
|
||||
default = 1,
|
||||
type = "int",
|
||||
help = "Specifies the column INT in the input "
|
||||
"KEYS_FILE which contains the keys. "
|
||||
"Default is %default, i.e. the first column.",
|
||||
metavar = "INT")
|
||||
|
||||
parser.add_option("--trials",
|
||||
action = "store",
|
||||
default = 5,
|
||||
type = "int",
|
||||
help = "Specifies the number of trials before "
|
||||
"NG is increased. A small INT will give "
|
||||
"compute faster, but the array G will be "
|
||||
"large. A large INT will take longer to "
|
||||
"compute but G will be smaller. "
|
||||
"Default is %default",
|
||||
metavar = "INT")
|
||||
|
||||
parser.add_option("--hft",
|
||||
action = "store",
|
||||
default = 1,
|
||||
type = "int",
|
||||
help = "Hash function type INT. Possible values "
|
||||
"are 1 (StrSaltHash) and 2 (IntSaltHash). "
|
||||
"The default is %default",
|
||||
metavar = "INT")
|
||||
|
||||
parser.add_option("-e", "--execute",
|
||||
action = "store_true",
|
||||
help = "Execute the generated code within "
|
||||
"the Python interpreter.")
|
||||
|
||||
parser.add_option("-o", "--output",
|
||||
action = "store",
|
||||
help = "Specify output FILE explicitly. "
|
||||
"`-o std' means standard output. "
|
||||
"`-o no' means no output. "
|
||||
"By default, the file name is obtained "
|
||||
"from the name of the template file by "
|
||||
"substituting `tmpl' to `code'.",
|
||||
metavar = "FILE")
|
||||
|
||||
parser.add_option("-v", "--verbose",
|
||||
action = "store_true",
|
||||
help = "verbosity")
|
||||
|
||||
options, args = parser.parse_args()
|
||||
|
||||
if options.trials <= 0:
|
||||
parser.error("trials before increasing N has to be larger than zero")
|
||||
|
||||
global trials
|
||||
trials = options.trials
|
||||
|
||||
global verbose
|
||||
verbose = options.verbose
|
||||
|
||||
if len(args) not in (1, 2):
|
||||
parser.error("incorrect number of arguments")
|
||||
|
||||
if len(args) == 2 and not args[1].count('tmpl'):
|
||||
parser.error("template filename does not contain 'tmpl'")
|
||||
|
||||
if options.hft == 1:
|
||||
Hash = StrSaltHash
|
||||
elif options.hft == 2:
|
||||
Hash = IntSaltHash
|
||||
else:
|
||||
parser.error("Hash function %s not implemented." % options.hft)
|
||||
|
||||
# --------------------- end parsing and checking --------------
|
||||
|
||||
keys_file = args[0]
|
||||
|
||||
if verbose:
|
||||
print("keys_file = %r" % keys_file)
|
||||
|
||||
keys = read_table(keys_file, options)
|
||||
|
||||
if verbose:
|
||||
print("Number os keys: %d" % len(keys))
|
||||
|
||||
tmpl_file = args[1] if len(args) == 2 else None
|
||||
|
||||
if verbose:
|
||||
print("tmpl_file = %r" % tmpl_file)
|
||||
|
||||
template = read_template(tmpl_file) if tmpl_file else None
|
||||
|
||||
if options.output:
|
||||
outname = options.output
|
||||
else:
|
||||
if tmpl_file:
|
||||
if 'tmpl' not in tmpl_file:
|
||||
sys.exit("Hmm, template filename does not contain 'tmpl'")
|
||||
outname = tmpl_file.replace('tmpl', 'code')
|
||||
else:
|
||||
outname = 'std'
|
||||
|
||||
if verbose:
|
||||
print("outname = %r\n" % outname)
|
||||
|
||||
if outname == 'std':
|
||||
outstream = sys.stdout
|
||||
elif outname == 'no':
|
||||
outstream = None
|
||||
else:
|
||||
try:
|
||||
outstream = open(outname, 'w')
|
||||
except IOError:
|
||||
sys.exit("Error: Could not open `%s' for writing." % outname)
|
||||
|
||||
code = generate_code(keys, Hash, template, options)
|
||||
|
||||
if options.execute or template == builtin_template(Hash):
|
||||
if verbose:
|
||||
print('Executing code...\n')
|
||||
run_code(code)
|
||||
|
||||
if outstream:
|
||||
outstream.write(code)
|
||||
if not outname == 'std':
|
||||
outstream.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
# Run this to regenerate xkbcommon-keysyms.h from the X11 headers
|
||||
# defining the keysyms and update the name <-> keysym mapping.
|
||||
export LC_CTYPE=C
|
||||
scripts/makeheader > include/xkbcommon/xkbcommon-keysyms.h
|
||||
scripts/makekeys include/xkbcommon/xkbcommon-keysyms.h > src/ks_tables.h
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
# Run this if you add/remove a new keyword to the xkbcomp scanner,
|
||||
# or just want to regenerate the gperf file.
|
||||
gperf < src/xkbcomp/keywords.gperf > src/xkbcomp/keywords.c
|
|
@ -70,33 +70,53 @@
|
|||
*
|
||||
********************************************************/
|
||||
|
||||
#include "utils.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "atom.h"
|
||||
#include "darray.h"
|
||||
#include "utils.h"
|
||||
|
||||
struct atom_node {
|
||||
xkb_atom_t left, right;
|
||||
xkb_atom_t atom;
|
||||
unsigned int fingerprint;
|
||||
char *string;
|
||||
};
|
||||
/* FNV-1a (http://www.isthe.com/chongo/tech/comp/fnv/). */
|
||||
static inline uint32_t
|
||||
hash_buf(const char *string, size_t len)
|
||||
{
|
||||
uint32_t hash = 2166136261u;
|
||||
for (size_t i = 0; i < (len + 1) / 2; i++) {
|
||||
hash ^= (uint8_t) string[i];
|
||||
hash *= 0x01000193;
|
||||
hash ^= (uint8_t) string[len - 1 - i];
|
||||
hash *= 0x01000193;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/*
|
||||
* The atom table is an insert-only linear probing hash table
|
||||
* mapping strings to atoms. Another array maps the atoms to
|
||||
* strings. The atom value is the position in the strings array.
|
||||
*/
|
||||
struct atom_table {
|
||||
xkb_atom_t root;
|
||||
darray(struct atom_node) table;
|
||||
xkb_atom_t *index;
|
||||
size_t index_size;
|
||||
darray(char *) strings;
|
||||
};
|
||||
|
||||
struct atom_table *
|
||||
atom_table_new(void)
|
||||
{
|
||||
struct atom_table *table;
|
||||
|
||||
table = calloc(1, sizeof(*table));
|
||||
struct atom_table *table = calloc(1, sizeof(*table));
|
||||
if (!table)
|
||||
return NULL;
|
||||
|
||||
darray_init(table->table);
|
||||
/* The original throw-away root is here, at the illegal atom 0. */
|
||||
darray_resize0(table->table, 1);
|
||||
darray_init(table->strings);
|
||||
darray_append(table->strings, NULL);
|
||||
table->index_size = 4;
|
||||
table->index = calloc(table->index_size, sizeof(*table->index));
|
||||
|
||||
return table;
|
||||
}
|
||||
|
@ -104,122 +124,70 @@ atom_table_new(void)
|
|||
void
|
||||
atom_table_free(struct atom_table *table)
|
||||
{
|
||||
struct atom_node *node;
|
||||
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
darray_foreach(node, table->table)
|
||||
free(node->string);
|
||||
darray_free(table->table);
|
||||
char **string;
|
||||
darray_foreach(string, table->strings)
|
||||
free(*string);
|
||||
darray_free(table->strings);
|
||||
free(table->index);
|
||||
free(table);
|
||||
}
|
||||
|
||||
const char *
|
||||
atom_text(struct atom_table *table, xkb_atom_t atom)
|
||||
{
|
||||
if (atom == XKB_ATOM_NONE || atom >= darray_size(table->table))
|
||||
return NULL;
|
||||
|
||||
return darray_item(table->table, atom).string;
|
||||
}
|
||||
|
||||
static bool
|
||||
find_atom_pointer(struct atom_table *table, const char *string, size_t len,
|
||||
xkb_atom_t **atomp_out, unsigned int *fingerprint_out)
|
||||
{
|
||||
xkb_atom_t *atomp = &table->root;
|
||||
unsigned int fingerprint = 0;
|
||||
bool found = false;
|
||||
|
||||
for (size_t i = 0; i < (len + 1) / 2; i++) {
|
||||
fingerprint = fingerprint * 27 + string[i];
|
||||
fingerprint = fingerprint * 27 + string[len - 1 - i];
|
||||
}
|
||||
|
||||
while (*atomp != XKB_ATOM_NONE) {
|
||||
struct atom_node *node = &darray_item(table->table, *atomp);
|
||||
|
||||
if (fingerprint < node->fingerprint) {
|
||||
atomp = &node->left;
|
||||
}
|
||||
else if (fingerprint > node->fingerprint) {
|
||||
atomp = &node->right;
|
||||
}
|
||||
else {
|
||||
/* Now start testing the strings. */
|
||||
const int cmp = strncmp(string, node->string, len);
|
||||
if (cmp < 0 || (cmp == 0 && len < strlen(node->string))) {
|
||||
atomp = &node->left;
|
||||
}
|
||||
else if (cmp > 0) {
|
||||
atomp = &node->right;
|
||||
}
|
||||
else {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fingerprint_out)
|
||||
*fingerprint_out = fingerprint;
|
||||
if (atomp_out)
|
||||
*atomp_out = atomp;
|
||||
return found;
|
||||
assert(atom < darray_size(table->strings));
|
||||
return darray_item(table->strings, atom);
|
||||
}
|
||||
|
||||
xkb_atom_t
|
||||
atom_lookup(struct atom_table *table, const char *string, size_t len)
|
||||
atom_intern(struct atom_table *table, const char *string, size_t len, bool add)
|
||||
{
|
||||
xkb_atom_t *atomp;
|
||||
if (darray_size(table->strings) > 0.80 * table->index_size) {
|
||||
table->index_size *= 2;
|
||||
table->index = realloc(table->index, table->index_size * sizeof(*table->index));
|
||||
memset(table->index, 0, table->index_size * sizeof(*table->index));
|
||||
for (size_t j = 1; j < darray_size(table->strings); j++) {
|
||||
const char *s = darray_item(table->strings, j);
|
||||
uint32_t hash = hash_buf(s, strlen(s));
|
||||
for (size_t i = 0; i < table->index_size; i++) {
|
||||
size_t index_pos = (hash + i) & (table->index_size - 1);
|
||||
if (index_pos == 0)
|
||||
continue;
|
||||
|
||||
if (!string)
|
||||
return XKB_ATOM_NONE;
|
||||
xkb_atom_t atom = table->index[index_pos];
|
||||
if (atom == XKB_ATOM_NONE) {
|
||||
table->index[index_pos] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!find_atom_pointer(table, string, len, &atomp, NULL))
|
||||
return XKB_ATOM_NONE;
|
||||
uint32_t hash = hash_buf(string, len);
|
||||
for (size_t i = 0; i < table->index_size; i++) {
|
||||
size_t index_pos = (hash + i) & (table->index_size - 1);
|
||||
if (index_pos == 0)
|
||||
continue;
|
||||
|
||||
return *atomp;
|
||||
}
|
||||
|
||||
/*
|
||||
* If steal is true, we do not strdup @string; therefore it must be
|
||||
* dynamically allocated, NUL-terminated, not be free'd by the caller
|
||||
* and not be used afterwards. Use to avoid some redundant allocations.
|
||||
*/
|
||||
xkb_atom_t
|
||||
atom_intern(struct atom_table *table, const char *string, size_t len,
|
||||
bool steal)
|
||||
{
|
||||
xkb_atom_t *atomp;
|
||||
struct atom_node node;
|
||||
unsigned int fingerprint;
|
||||
|
||||
if (!string)
|
||||
return XKB_ATOM_NONE;
|
||||
|
||||
if (find_atom_pointer(table, string, len, &atomp, &fingerprint)) {
|
||||
if (steal)
|
||||
free(UNCONSTIFY(string));
|
||||
return *atomp;
|
||||
}
|
||||
|
||||
if (steal) {
|
||||
node.string = UNCONSTIFY(string);
|
||||
}
|
||||
else {
|
||||
node.string = strndup(string, len);
|
||||
if (!node.string)
|
||||
return XKB_ATOM_NONE;
|
||||
}
|
||||
|
||||
node.left = node.right = XKB_ATOM_NONE;
|
||||
node.fingerprint = fingerprint;
|
||||
node.atom = darray_size(table->table);
|
||||
/* Do this before the append, as it may realloc and change the offsets. */
|
||||
*atomp = node.atom;
|
||||
darray_append(table->table, node);
|
||||
|
||||
return node.atom;
|
||||
xkb_atom_t existing_atom = table->index[index_pos];
|
||||
if (existing_atom == XKB_ATOM_NONE) {
|
||||
if (add) {
|
||||
xkb_atom_t new_atom = darray_size(table->strings);
|
||||
darray_append(table->strings, strndup(string, len));
|
||||
table->index[index_pos] = new_atom;
|
||||
return new_atom;
|
||||
} else {
|
||||
return XKB_ATOM_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
const char *existing_value = darray_item(table->strings, existing_atom);
|
||||
if (strncmp(existing_value, string, len) == 0 && existing_value[len] == '\0')
|
||||
return existing_atom;
|
||||
}
|
||||
|
||||
assert(!"couldn't find an empty slot during probing");
|
||||
}
|
||||
|
|
|
@ -37,11 +37,7 @@ void
|
|||
atom_table_free(struct atom_table *table);
|
||||
|
||||
xkb_atom_t
|
||||
atom_lookup(struct atom_table *table, const char *string, size_t len);
|
||||
|
||||
xkb_atom_t
|
||||
atom_intern(struct atom_table *table, const char *string, size_t len,
|
||||
bool steal);
|
||||
atom_intern(struct atom_table *table, const char *string, size_t len, bool add);
|
||||
|
||||
const char *
|
||||
atom_text(struct atom_table *table, xkb_atom_t atom);
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#define _GNU_SOURCE_ 1
|
||||
|
||||
#define DFLT_XKB_CONFIG_EXTRA_PATH "/data/data/com.termux/files/home/.termux.wayland/xkb/config"
|
||||
|
||||
#define DEFAULT_XKB_VARIANT "NULL"
|
||||
|
||||
#define DEFAULT_XKB_OPTIONS "NULL"
|
|
@ -52,6 +52,8 @@ OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
******************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
@ -64,45 +66,6 @@ OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#define MAX_LHS_LEN 10
|
||||
#define MAX_INCLUDE_DEPTH 5
|
||||
|
||||
#define KEYSYM_FROM_NAME_CACHE_SIZE 8
|
||||
|
||||
/*
|
||||
* xkb_keysym_from_name() is fairly slow, because for internal reasons
|
||||
* it must use strcasecmp().
|
||||
* A small cache reduces about 20% from the compilation time of
|
||||
* en_US.UTF-8/Compose.
|
||||
*/
|
||||
struct keysym_from_name_cache {
|
||||
struct {
|
||||
char name[64];
|
||||
unsigned len;
|
||||
xkb_keysym_t keysym;
|
||||
} cache[KEYSYM_FROM_NAME_CACHE_SIZE];
|
||||
unsigned next;
|
||||
};
|
||||
|
||||
static xkb_keysym_t
|
||||
cached_keysym_from_name(struct keysym_from_name_cache *cache,
|
||||
const char *name, size_t len)
|
||||
{
|
||||
xkb_keysym_t keysym;
|
||||
|
||||
if (len >= sizeof(cache->cache[0].name))
|
||||
return XKB_KEY_NoSymbol;
|
||||
|
||||
for (unsigned i = 0; i < KEYSYM_FROM_NAME_CACHE_SIZE; i++)
|
||||
if (cache->cache[i].len == len &&
|
||||
memcmp(cache->cache[i].name, name, len) == 0)
|
||||
return cache->cache[i].keysym;
|
||||
|
||||
keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
|
||||
strcpy(cache->cache[cache->next].name, name);
|
||||
cache->cache[cache->next].len = len;
|
||||
cache->cache[cache->next].keysym = keysym;
|
||||
cache->next = (cache->next + 1) % KEYSYM_FROM_NAME_CACHE_SIZE;
|
||||
return keysym;
|
||||
}
|
||||
|
||||
/*
|
||||
* Grammar adapted from libX11/modules/im/ximcp/imLcPrs.c.
|
||||
* See also the XCompose(5) manpage.
|
||||
|
@ -113,8 +76,9 @@ cached_keysym_from_name(struct keysym_from_name_cache *cache,
|
|||
* COMMENT ::= "#" {<any character except null or newline>}
|
||||
* LHS ::= EVENT { EVENT }
|
||||
* EVENT ::= [MODIFIER_LIST] "<" keysym ">"
|
||||
* MODIFIER_LIST ::= ("!" {MODIFIER} ) | "None"
|
||||
* MODIFIER ::= ["~"] modifier_name
|
||||
* MODIFIER_LIST ::= (["!"] {MODIFIER} ) | "None"
|
||||
* MODIFIER ::= ["~"] MODIFIER_NAME
|
||||
* MODIFIER_NAME ::= ("Ctrl"|"Lock"|"Caps"|"Shift"|"Alt"|"Meta")
|
||||
* RHS ::= ( STRING | keysym | STRING keysym )
|
||||
* STRING ::= '"' { CHAR } '"'
|
||||
* CHAR ::= GRAPHIC_CHAR | ESCAPED_CHAR
|
||||
|
@ -182,7 +146,7 @@ skip_more_whitespace_and_comments:
|
|||
|
||||
/* LHS Keysym. */
|
||||
if (chr(s, '<')) {
|
||||
while (peek(s) != '>' && !eol(s))
|
||||
while (peek(s) != '>' && !eol(s) && !eof(s))
|
||||
buf_append(s, next(s));
|
||||
if (!chr(s, '>')) {
|
||||
scanner_err(s, "unterminated keysym literal");
|
||||
|
@ -354,108 +318,123 @@ struct production {
|
|||
unsigned int len;
|
||||
xkb_keysym_t keysym;
|
||||
char string[256];
|
||||
/* At least one of these is true. */
|
||||
bool has_keysym;
|
||||
bool has_string;
|
||||
|
||||
xkb_mod_mask_t mods;
|
||||
/* The matching is as follows: (active_mods & modmask) == mods. */
|
||||
xkb_mod_mask_t modmask;
|
||||
xkb_mod_mask_t mods;
|
||||
};
|
||||
|
||||
static uint32_t
|
||||
add_node(struct xkb_compose_table *table, xkb_keysym_t keysym)
|
||||
{
|
||||
struct compose_node new = {
|
||||
.keysym = keysym,
|
||||
.next = 0,
|
||||
.is_leaf = true,
|
||||
};
|
||||
darray_append(table->nodes, new);
|
||||
return darray_size(table->nodes) - 1;
|
||||
}
|
||||
|
||||
static void
|
||||
add_production(struct xkb_compose_table *table, struct scanner *s,
|
||||
const struct production *production)
|
||||
{
|
||||
unsigned lhs_pos;
|
||||
uint32_t curr;
|
||||
struct compose_node *node;
|
||||
unsigned lhs_pos = 0;
|
||||
uint16_t curr = darray_size(table->nodes) == 1 ? 0 : 1;
|
||||
uint16_t *pptr = NULL;
|
||||
struct compose_node *node = NULL;
|
||||
|
||||
curr = 0;
|
||||
node = &darray_item(table->nodes, curr);
|
||||
/* Warn before potentially going over the limit, discard silently after. */
|
||||
if (darray_size(table->nodes) + production->len + MAX_LHS_LEN > MAX_COMPOSE_NODES)
|
||||
scanner_warn(s, "too many sequences for one Compose file; will ignore further lines");
|
||||
if (darray_size(table->nodes) + production->len >= MAX_COMPOSE_NODES)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Insert the sequence to the trie, creating new nodes as needed.
|
||||
* Insert the sequence to the ternary search tree, creating new nodes as
|
||||
* needed.
|
||||
*
|
||||
* TODO: This can be sped up a bit by first trying the path that the
|
||||
* previous production took, and only then doing the linear search
|
||||
* through the trie levels. This will work because sequences in the
|
||||
* Compose files are often clustered by a common prefix; especially
|
||||
* in the 1st and 2nd keysyms, which is where the largest variation
|
||||
* (thus, longest search) is.
|
||||
* TODO: We insert in the order given, this means some inputs can create
|
||||
* long O(n) chains, which results in total O(n^2) parsing time. We should
|
||||
* ensure the tree is reasonably balanced somehow.
|
||||
*/
|
||||
for (lhs_pos = 0; lhs_pos < production->len; lhs_pos++) {
|
||||
while (production->lhs[lhs_pos] != node->keysym) {
|
||||
if (node->next == 0) {
|
||||
uint32_t next = add_node(table, production->lhs[lhs_pos]);
|
||||
/* Refetch since add_node could have realloc()ed. */
|
||||
node = &darray_item(table->nodes, curr);
|
||||
node->next = next;
|
||||
}
|
||||
while (true) {
|
||||
const xkb_keysym_t keysym = production->lhs[lhs_pos];
|
||||
const bool last = lhs_pos + 1 == production->len;
|
||||
|
||||
curr = node->next;
|
||||
node = &darray_item(table->nodes, curr);
|
||||
if (curr == 0) {
|
||||
/*
|
||||
* Create a new node and update the parent pointer to it.
|
||||
* Update the pointer first because the append invalidates it.
|
||||
*/
|
||||
struct compose_node new = {
|
||||
.keysym = keysym,
|
||||
.lokid = 0,
|
||||
.hikid = 0,
|
||||
.internal = {
|
||||
.eqkid = 0,
|
||||
.is_leaf = false,
|
||||
},
|
||||
};
|
||||
curr = darray_size(table->nodes);
|
||||
if (pptr != NULL) {
|
||||
*pptr = curr;
|
||||
pptr = NULL;
|
||||
}
|
||||
darray_append(table->nodes, new);
|
||||
}
|
||||
|
||||
if (lhs_pos + 1 == production->len)
|
||||
break;
|
||||
|
||||
if (node->is_leaf) {
|
||||
if (node->u.leaf.utf8 != 0 ||
|
||||
node->u.leaf.keysym != XKB_KEY_NoSymbol) {
|
||||
scanner_warn(s, "a sequence already exists which is a prefix of this sequence; overriding");
|
||||
node->u.leaf.utf8 = 0;
|
||||
node->u.leaf.keysym = XKB_KEY_NoSymbol;
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t successor = add_node(table, production->lhs[lhs_pos + 1]);
|
||||
/* Refetch since add_node could have realloc()ed. */
|
||||
node = &darray_item(table->nodes, curr);
|
||||
node->is_leaf = false;
|
||||
node->u.successor = successor;
|
||||
}
|
||||
}
|
||||
|
||||
curr = node->u.successor;
|
||||
node = &darray_item(table->nodes, curr);
|
||||
}
|
||||
|
||||
if (!node->is_leaf) {
|
||||
scanner_warn(s, "this compose sequence is a prefix of another; skipping line");
|
||||
return;
|
||||
}
|
||||
|
||||
if (node->u.leaf.utf8 != 0 || node->u.leaf.keysym != XKB_KEY_NoSymbol) {
|
||||
if (streq(&darray_item(table->utf8, node->u.leaf.utf8),
|
||||
production->string) &&
|
||||
node->u.leaf.keysym == production->keysym) {
|
||||
scanner_warn(s, "this compose sequence is a duplicate of another; skipping line");
|
||||
if (keysym < node->keysym) {
|
||||
pptr = &node->lokid;
|
||||
curr = node->lokid;
|
||||
} else if (keysym > node->keysym) {
|
||||
pptr = &node->hikid;
|
||||
curr = node->hikid;
|
||||
} else if (!last) {
|
||||
if (node->is_leaf) {
|
||||
scanner_warn(s, "a sequence already exists which is a prefix of this sequence; overriding");
|
||||
node->internal.eqkid = node->lokid = node->hikid = 0;
|
||||
node->internal.is_leaf = false;
|
||||
}
|
||||
lhs_pos++;
|
||||
pptr = &node->internal.eqkid;
|
||||
curr = node->internal.eqkid;
|
||||
} else {
|
||||
if (node->is_leaf) {
|
||||
bool same_string =
|
||||
(node->leaf.utf8 == 0 && !production->has_string) ||
|
||||
(
|
||||
node->leaf.utf8 != 0 && production->has_string &&
|
||||
streq(&darray_item(table->utf8, node->leaf.utf8),
|
||||
production->string)
|
||||
);
|
||||
bool same_keysym =
|
||||
(node->leaf.keysym == XKB_KEY_NoSymbol && !production->has_keysym) ||
|
||||
(
|
||||
node->leaf.keysym != XKB_KEY_NoSymbol && production->has_keysym &&
|
||||
node->leaf.keysym == production->keysym
|
||||
);
|
||||
if (same_string && same_keysym) {
|
||||
scanner_warn(s, "this compose sequence is a duplicate of another; skipping line");
|
||||
return;
|
||||
} else {
|
||||
scanner_warn(s, "this compose sequence already exists; overriding");
|
||||
}
|
||||
} else if (node->internal.eqkid != 0) {
|
||||
scanner_warn(s, "this compose sequence is a prefix of another; skipping line");
|
||||
return;
|
||||
}
|
||||
node->is_leaf = true;
|
||||
if (production->has_string) {
|
||||
node->leaf.utf8 = darray_size(table->utf8);
|
||||
darray_append_items(table->utf8, production->string,
|
||||
strlen(production->string) + 1);
|
||||
}
|
||||
if (production->has_keysym) {
|
||||
node->leaf.keysym = production->keysym;
|
||||
}
|
||||
return;
|
||||
}
|
||||
scanner_warn(s, "this compose sequence already exists; overriding");
|
||||
}
|
||||
|
||||
if (production->has_string) {
|
||||
node->u.leaf.utf8 = darray_size(table->utf8);
|
||||
darray_append_items(table->utf8, production->string,
|
||||
strlen(production->string) + 1);
|
||||
}
|
||||
if (production->has_keysym) {
|
||||
node->u.leaf.keysym = production->keysym;
|
||||
}
|
||||
}
|
||||
|
||||
/* Should match resolve_modifier(). */
|
||||
#define ALL_MODS_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3))
|
||||
|
||||
static xkb_mod_index_t
|
||||
resolve_modifier(const char *name)
|
||||
{
|
||||
|
@ -488,7 +467,7 @@ do_include(struct xkb_compose_table *table, struct scanner *s,
|
|||
{
|
||||
FILE *file;
|
||||
bool ok;
|
||||
const char *string;
|
||||
char *string;
|
||||
size_t size;
|
||||
struct scanner new_s;
|
||||
|
||||
|
@ -498,7 +477,7 @@ do_include(struct xkb_compose_table *table, struct scanner *s,
|
|||
return false;
|
||||
}
|
||||
|
||||
file = fopen(path, "r");
|
||||
file = fopen(path, "rb");
|
||||
if (!file) {
|
||||
scanner_err(s, "failed to open included Compose file \"%s\": %s",
|
||||
path, strerror(errno));
|
||||
|
@ -531,7 +510,6 @@ parse(struct xkb_compose_table *table, struct scanner *s,
|
|||
{
|
||||
enum rules_token tok;
|
||||
union lvalue val;
|
||||
struct keysym_from_name_cache *cache = s->priv;
|
||||
xkb_keysym_t keysym;
|
||||
struct production production;
|
||||
enum { MAX_ERRORS = 10 };
|
||||
|
@ -587,15 +565,16 @@ lhs_tok:
|
|||
}
|
||||
goto rhs;
|
||||
case TOK_IDENT:
|
||||
if (!streq(val.string.str, "None")) {
|
||||
scanner_err(s, "unrecognized identifier \"%s\"", val.string.str);
|
||||
goto error;
|
||||
if (streq(val.string.str, "None")) {
|
||||
production.mods = 0;
|
||||
production.modmask = ALL_MODS_MASK;
|
||||
goto lhs_keysym;
|
||||
}
|
||||
production.mods = 0;
|
||||
/* XXX Should only include the mods in resolve_mods(). */
|
||||
production.modmask = 0xff;
|
||||
goto lhs_keysym;
|
||||
goto lhs_mod_list_tok;
|
||||
case TOK_TILDE:
|
||||
goto lhs_mod_list_tok;
|
||||
case TOK_BANG:
|
||||
production.modmask = ALL_MODS_MASK;
|
||||
goto lhs_mod_list;
|
||||
default:
|
||||
goto lhs_keysym_tok;
|
||||
|
@ -606,7 +585,7 @@ lhs_keysym:
|
|||
lhs_keysym_tok:
|
||||
switch (tok) {
|
||||
case TOK_LHS_KEYSYM:
|
||||
keysym = cached_keysym_from_name(cache, val.string.str, val.string.len);
|
||||
keysym = xkb_keysym_from_name(val.string.str, XKB_KEYSYM_NO_FLAGS);
|
||||
if (keysym == XKB_KEY_NoSymbol) {
|
||||
scanner_err(s, "unrecognized keysym \"%s\" on left-hand side",
|
||||
val.string.str);
|
||||
|
@ -625,21 +604,22 @@ lhs_keysym_tok:
|
|||
goto unexpected;
|
||||
}
|
||||
|
||||
lhs_mod_list: {
|
||||
lhs_mod_list:
|
||||
tok = lex(s, &val);
|
||||
lhs_mod_list_tok: {
|
||||
bool tilde = false;
|
||||
xkb_mod_index_t mod;
|
||||
|
||||
tok = lex(s, &val);
|
||||
if (tok != TOK_TILDE && tok != TOK_IDENT)
|
||||
goto lhs_keysym_tok;
|
||||
|
||||
if (tok == TOK_TILDE) {
|
||||
tilde = true;
|
||||
tok = lex(s, &val);
|
||||
}
|
||||
|
||||
if (tok != TOK_IDENT) {
|
||||
if (tilde || production.modmask == 0)
|
||||
goto unexpected;
|
||||
goto lhs_keysym_tok;
|
||||
}
|
||||
if (tok != TOK_IDENT)
|
||||
goto unexpected;
|
||||
|
||||
mod = resolve_modifier(val.string.str);
|
||||
if (mod == XKB_MOD_INVALID) {
|
||||
|
@ -676,7 +656,7 @@ rhs:
|
|||
production.has_string = true;
|
||||
goto rhs;
|
||||
case TOK_IDENT:
|
||||
keysym = cached_keysym_from_name(cache, val.string.str, val.string.len);
|
||||
keysym = xkb_keysym_from_name(val.string.str, XKB_KEYSYM_NO_FLAGS);
|
||||
if (keysym == XKB_KEY_NoSymbol) {
|
||||
scanner_err(s, "unrecognized keysym \"%s\" on right-hand side",
|
||||
val.string.str);
|
||||
|
@ -688,6 +668,7 @@ rhs:
|
|||
}
|
||||
production.keysym = keysym;
|
||||
production.has_keysym = true;
|
||||
/* fallthrough */
|
||||
case TOK_END_OF_LINE:
|
||||
if (!production.has_string && !production.has_keysym) {
|
||||
scanner_warn(s, "right-hand side must have at least one of string or keysym; skipping line");
|
||||
|
@ -728,9 +709,7 @@ parse_string(struct xkb_compose_table *table, const char *string, size_t len,
|
|||
const char *file_name)
|
||||
{
|
||||
struct scanner s;
|
||||
struct keysym_from_name_cache cache;
|
||||
memset(&cache, 0, sizeof(cache));
|
||||
scanner_init(&s, table->ctx, string, len, file_name, &cache);
|
||||
scanner_init(&s, table->ctx, string, len, file_name, NULL);
|
||||
if (!parse(table, &s, 0))
|
||||
return false;
|
||||
/* Maybe the allocator can use the excess space. */
|
||||
|
@ -743,7 +722,7 @@ bool
|
|||
parse_file(struct xkb_compose_table *table, FILE *file, const char *file_name)
|
||||
{
|
||||
bool ok;
|
||||
const char *string;
|
||||
char *string;
|
||||
size_t size;
|
||||
|
||||
ok = map_file(file, &string, &size);
|
||||
|
|
|
@ -21,8 +21,11 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "paths.h"
|
||||
#include "utils.h"
|
||||
|
||||
enum resolve_name_direction {
|
||||
LEFT_TO_RIGHT,
|
||||
|
@ -52,8 +55,9 @@ resolve_name(const char *filename, enum resolve_name_direction direction,
|
|||
const char *xlocaledir;
|
||||
char path[512];
|
||||
FILE *file;
|
||||
const char *string, *end;
|
||||
char *string;
|
||||
size_t string_size;
|
||||
const char *end;
|
||||
const char *s, *left, *right;
|
||||
char *match;
|
||||
size_t left_len, right_len, name_len;
|
||||
|
@ -64,7 +68,7 @@ resolve_name(const char *filename, enum resolve_name_direction direction,
|
|||
if (ret < 0 || (size_t) ret >= sizeof(path))
|
||||
return false;
|
||||
|
||||
file = fopen(path, "r");
|
||||
file = fopen(path, "rb");
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
|
@ -139,35 +143,44 @@ resolve_locale(const char *locale)
|
|||
return alias ? alias : strdup(locale);
|
||||
}
|
||||
|
||||
const char *
|
||||
char *
|
||||
get_xcomposefile_path(void)
|
||||
{
|
||||
return secure_getenv("XCOMPOSEFILE");
|
||||
return strdup_safe(secure_getenv("XCOMPOSEFILE"));
|
||||
}
|
||||
|
||||
char *
|
||||
get_xdg_xcompose_file_path(void)
|
||||
{
|
||||
const char *xdg_config_home;
|
||||
const char *home;
|
||||
|
||||
xdg_config_home = secure_getenv("XDG_CONFIG_HOME");
|
||||
if (!xdg_config_home || xdg_config_home[0] != '/') {
|
||||
home = secure_getenv("HOME");
|
||||
if (!home)
|
||||
return NULL;
|
||||
return asprintf_safe("%s/.config/XCompose", home);
|
||||
}
|
||||
|
||||
return asprintf_safe("%s/XCompose", xdg_config_home);
|
||||
}
|
||||
|
||||
char *
|
||||
get_home_xcompose_file_path(void)
|
||||
{
|
||||
int ret;
|
||||
const char *home;
|
||||
char *path;
|
||||
|
||||
home = secure_getenv("HOME");
|
||||
if (!home)
|
||||
return NULL;
|
||||
|
||||
ret = asprintf(&path, "%s/.XCompose", home);
|
||||
if (ret <0)
|
||||
return NULL;
|
||||
|
||||
return path;
|
||||
return asprintf_safe("%s/.XCompose", home);
|
||||
}
|
||||
|
||||
char *
|
||||
get_locale_compose_file_path(const char *locale)
|
||||
{
|
||||
int ret;
|
||||
const char *xlocaledir;
|
||||
char *resolved;
|
||||
char *path;
|
||||
|
||||
|
@ -193,11 +206,9 @@ get_locale_compose_file_path(const char *locale)
|
|||
path = resolved;
|
||||
}
|
||||
else {
|
||||
xlocaledir = get_xlocaledir_path();
|
||||
ret = asprintf(&path, "%s/%s", xlocaledir, resolved);
|
||||
const char *xlocaledir = get_xlocaledir_path();
|
||||
path = asprintf_safe("%s/%s", xlocaledir, resolved);
|
||||
free(resolved);
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return path;
|
||||
|
|
|
@ -30,9 +30,12 @@ resolve_locale(const char *locale);
|
|||
const char *
|
||||
get_xlocaledir_path(void);
|
||||
|
||||
const char *
|
||||
char *
|
||||
get_xcomposefile_path(void);
|
||||
|
||||
char *
|
||||
get_xdg_xcompose_file_path(void);
|
||||
|
||||
char *
|
||||
get_home_xcompose_file_path(void);
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "table.h"
|
||||
#include "utils.h"
|
||||
#include "keysym.h"
|
||||
|
@ -39,8 +41,8 @@ struct xkb_compose_state {
|
|||
* This is also sufficient for inferring the current status; see
|
||||
* xkb_compose_state_get_status().
|
||||
*/
|
||||
uint32_t prev_context;
|
||||
uint32_t context;
|
||||
uint16_t prev_context;
|
||||
uint16_t context;
|
||||
};
|
||||
|
||||
XKB_EXPORT struct xkb_compose_state *
|
||||
|
@ -89,7 +91,7 @@ xkb_compose_state_get_compose_table(struct xkb_compose_state *state)
|
|||
XKB_EXPORT enum xkb_compose_feed_result
|
||||
xkb_compose_state_feed(struct xkb_compose_state *state, xkb_keysym_t keysym)
|
||||
{
|
||||
uint32_t context;
|
||||
uint16_t context;
|
||||
const struct compose_node *node;
|
||||
|
||||
/*
|
||||
|
@ -107,17 +109,20 @@ xkb_compose_state_feed(struct xkb_compose_state *state, xkb_keysym_t keysym)
|
|||
|
||||
node = &darray_item(state->table->nodes, state->context);
|
||||
|
||||
context = (node->is_leaf ? 0 : node->u.successor);
|
||||
node = &darray_item(state->table->nodes, context);
|
||||
|
||||
while (node->keysym != keysym && node->next != 0) {
|
||||
context = node->next;
|
||||
node = &darray_item(state->table->nodes, context);
|
||||
}
|
||||
|
||||
if (node->keysym != keysym)
|
||||
context = (node->is_leaf ? 1 : node->internal.eqkid);
|
||||
if (context == 1 && darray_size(state->table->nodes) == 1)
|
||||
context = 0;
|
||||
|
||||
while (context != 0) {
|
||||
node = &darray_item(state->table->nodes, context);
|
||||
if (keysym < node->keysym)
|
||||
context = node->lokid;
|
||||
else if (keysym > node->keysym)
|
||||
context = node->hikid;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
state->prev_context = state->context;
|
||||
state->context = context;
|
||||
return XKB_COMPOSE_FEED_ACCEPTED;
|
||||
|
@ -162,11 +167,11 @@ xkb_compose_state_get_utf8(struct xkb_compose_state *state,
|
|||
|
||||
/* If there's no string specified, but only a keysym, try to do the
|
||||
* most helpful thing. */
|
||||
if (node->u.leaf.utf8 == 0 && node->u.leaf.keysym != XKB_KEY_NoSymbol) {
|
||||
if (node->leaf.utf8 == 0 && node->leaf.keysym != XKB_KEY_NoSymbol) {
|
||||
char name[64];
|
||||
int ret;
|
||||
|
||||
ret = xkb_keysym_to_utf8(node->u.leaf.keysym, name, sizeof(name));
|
||||
ret = xkb_keysym_to_utf8(node->leaf.keysym, name, sizeof(name));
|
||||
if (ret < 0 || ret == 0) {
|
||||
/* ret < 0 is impossible.
|
||||
* ret == 0 means the keysym has no string representation. */
|
||||
|
@ -177,7 +182,7 @@ xkb_compose_state_get_utf8(struct xkb_compose_state *state,
|
|||
}
|
||||
|
||||
return snprintf(buffer, size, "%s",
|
||||
&darray_item(state->table->utf8, node->u.leaf.utf8));
|
||||
&darray_item(state->table->utf8, node->leaf.utf8));
|
||||
|
||||
fail:
|
||||
if (size > 0)
|
||||
|
@ -192,5 +197,5 @@ xkb_compose_state_get_one_sym(struct xkb_compose_state *state)
|
|||
&darray_item(state->table->nodes, state->context);
|
||||
if (!node->is_leaf)
|
||||
return XKB_KEY_NoSymbol;
|
||||
return node->u.leaf.keysym;
|
||||
return node->leaf.keysym;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2013 Ran Benita <ran234@gmail.com>
|
||||
* Copyright © 2013,2021 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -21,6 +21,8 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "table.h"
|
||||
#include "parser.h"
|
||||
|
@ -34,7 +36,7 @@ xkb_compose_table_new(struct xkb_context *ctx,
|
|||
{
|
||||
char *resolved_locale;
|
||||
struct xkb_compose_table *table;
|
||||
struct compose_node root;
|
||||
struct compose_node dummy;
|
||||
|
||||
resolved_locale = resolve_locale(locale);
|
||||
if (!resolved_locale)
|
||||
|
@ -56,12 +58,11 @@ xkb_compose_table_new(struct xkb_context *ctx,
|
|||
darray_init(table->nodes);
|
||||
darray_init(table->utf8);
|
||||
|
||||
root.keysym = XKB_KEY_NoSymbol;
|
||||
root.next = 0;
|
||||
root.is_leaf = true;
|
||||
root.u.leaf.utf8 = 0;
|
||||
root.u.leaf.keysym = XKB_KEY_NoSymbol;
|
||||
darray_append(table->nodes, root);
|
||||
dummy.keysym = XKB_KEY_NoSymbol;
|
||||
dummy.leaf.is_leaf = true;
|
||||
dummy.leaf.utf8 = 0;
|
||||
dummy.leaf.keysym = XKB_KEY_NoSymbol;
|
||||
darray_append(table->nodes, dummy);
|
||||
|
||||
darray_append(table->utf8, '\0');
|
||||
|
||||
|
@ -159,8 +160,7 @@ xkb_compose_table_new_from_locale(struct xkb_context *ctx,
|
|||
enum xkb_compose_compile_flags flags)
|
||||
{
|
||||
struct xkb_compose_table *table;
|
||||
char *path = NULL;
|
||||
const char *cpath;
|
||||
char *path;
|
||||
FILE *file;
|
||||
bool ok;
|
||||
|
||||
|
@ -174,39 +174,48 @@ xkb_compose_table_new_from_locale(struct xkb_context *ctx,
|
|||
if (!table)
|
||||
return NULL;
|
||||
|
||||
cpath = get_xcomposefile_path();
|
||||
if (cpath) {
|
||||
file = fopen(cpath, "r");
|
||||
if (file)
|
||||
goto found_path;
|
||||
}
|
||||
|
||||
cpath = path = get_home_xcompose_file_path();
|
||||
path = get_xcomposefile_path();
|
||||
if (path) {
|
||||
file = fopen(path, "r");
|
||||
file = fopen(path, "rb");
|
||||
if (file)
|
||||
goto found_path;
|
||||
}
|
||||
free(path);
|
||||
path = NULL;
|
||||
|
||||
cpath = path = get_locale_compose_file_path(table->locale);
|
||||
path = get_xdg_xcompose_file_path();
|
||||
if (path) {
|
||||
file = fopen(path, "r");
|
||||
file = fopen(path, "rb");
|
||||
if (file)
|
||||
goto found_path;
|
||||
}
|
||||
free(path);
|
||||
path = NULL;
|
||||
|
||||
log_err(ctx, "couldn't find a Compose file for locale \"%s\"\n", locale);
|
||||
path = get_home_xcompose_file_path();
|
||||
if (path) {
|
||||
file = fopen(path, "rb");
|
||||
if (file)
|
||||
goto found_path;
|
||||
}
|
||||
free(path);
|
||||
|
||||
path = get_locale_compose_file_path(table->locale);
|
||||
if (path) {
|
||||
file = fopen(path, "rb");
|
||||
if (file)
|
||||
goto found_path;
|
||||
}
|
||||
free(path);
|
||||
|
||||
log_err(ctx, "couldn't find a Compose file for locale \"%s\" (mapped to \"%s\")\n",
|
||||
locale, table->locale);
|
||||
xkb_compose_table_unref(table);
|
||||
return NULL;
|
||||
|
||||
found_path:
|
||||
ok = parse_file(table, file, cpath);
|
||||
ok = parse_file(table, file, path);
|
||||
fclose(file);
|
||||
if (!ok) {
|
||||
free(path);
|
||||
xkb_compose_table_unref(table);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2013 Ran Benita <ran234@gmail.com>
|
||||
* Copyright © 2013,2021 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -29,36 +29,43 @@
|
|||
#include "context.h"
|
||||
|
||||
/*
|
||||
* The compose table data structure is a simple trie. An example will
|
||||
* help. Given these sequences:
|
||||
* The compose table data structure is a ternary search tree.
|
||||
*
|
||||
* <A> <B> : "first" dead_a
|
||||
* <A> <C> <D> : "second" dead_b
|
||||
* <E> <F> : "third" dead_c
|
||||
* Reference: https://www.drdobbs.com/database/ternary-search-trees/184410528
|
||||
* Visualization: https://www.cs.usfca.edu/~galles/visualization/TST.html
|
||||
*
|
||||
* the trie would look like:
|
||||
* Short example. Given these sequences:
|
||||
*
|
||||
* <B> <C> : "first" dead_a
|
||||
* <B> <D> <E> : "second" dead_b
|
||||
* <A> <F> : "third" dead_c
|
||||
*
|
||||
* the tree would look like:
|
||||
*
|
||||
* -------- [<B>]---------
|
||||
* | | #
|
||||
* v V
|
||||
* -- [<A>] -- [<C>] --------
|
||||
* # | # | |
|
||||
* v # -- [<D>] --
|
||||
* -- [<F>] -- # | #
|
||||
* # | # v
|
||||
* # -- [<E>] --
|
||||
* # | #
|
||||
* #
|
||||
*
|
||||
* [root] ---> [<A>] -----------------> [<E>] -#
|
||||
* | | |
|
||||
* # v v
|
||||
* [<B>] ---> [<C>] -# [<F>] -#
|
||||
* | | -
|
||||
* # v #
|
||||
* [<D>] -#
|
||||
* |
|
||||
* #
|
||||
* where:
|
||||
* - [root] is a special empty root node.
|
||||
* - [<X>] is a node for a sequence keysym <X>.
|
||||
* - right arrows are `next` pointers.
|
||||
* - down arrows are `successor` pointers.
|
||||
* - right arrows are `hikid` pointers.
|
||||
* - left arrows are `lokid` pointers.
|
||||
* - down arrows are `eqkid` pointers.
|
||||
* - # is a nil pointer.
|
||||
*
|
||||
* The nodes are all kept in a contiguous array. Pointers are represented
|
||||
* as integer offsets into this array. A nil pointer is represented as 0
|
||||
* (which, helpfully, is the offset of the empty root node).
|
||||
* (which, helpfully, is the offset of an empty dummy node).
|
||||
*
|
||||
* Nodes without a successor are leaf nodes. Since a sequence cannot be a
|
||||
* Nodes without an eqkid are leaf nodes. Since a sequence cannot be a
|
||||
* prefix of another, these are exactly the nodes which terminate the
|
||||
* sequences (in a bijective manner).
|
||||
*
|
||||
|
@ -68,21 +75,35 @@
|
|||
* \0 is so offset 0 points to an empty string).
|
||||
*/
|
||||
|
||||
/* Fits in uint16_t, also a good idea to have some limit. */
|
||||
#define MAX_COMPOSE_NODES 65535
|
||||
|
||||
struct compose_node {
|
||||
xkb_keysym_t keysym;
|
||||
/* Offset into xkb_compose_table::nodes. */
|
||||
unsigned int next:31;
|
||||
bool is_leaf:1;
|
||||
|
||||
/* Offset into xkb_compose_table::nodes or 0. */
|
||||
uint16_t lokid;
|
||||
/* Offset into xkb_compose_table::nodes or 0. */
|
||||
uint16_t hikid;
|
||||
|
||||
union {
|
||||
/* Offset into xkb_compose_table::nodes. */
|
||||
uint32_t successor;
|
||||
struct {
|
||||
uint32_t _pad:31;
|
||||
bool is_leaf:1;
|
||||
};
|
||||
struct {
|
||||
uint32_t _pad:31;
|
||||
bool is_leaf:1;
|
||||
/* Offset into xkb_compose_table::nodes or 0. */
|
||||
uint16_t eqkid;
|
||||
} internal;
|
||||
struct {
|
||||
/* Offset into xkb_compose_table::utf8. */
|
||||
uint32_t utf8;
|
||||
uint32_t utf8:31;
|
||||
bool is_leaf:1;
|
||||
xkb_keysym_t keysym;
|
||||
} leaf;
|
||||
} u;
|
||||
};
|
||||
};
|
||||
|
||||
struct xkb_compose_table {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#define _GNU_SOURCE_ 1
|
||||
|
||||
#define DFLT_XKB_CONFIG_EXTRA_PATH "/data/data/com.termux/files/home/.termux.wayland/xkb/config"
|
||||
|
||||
#define DEFAULT_XKB_VARIANT "NULL"
|
||||
|
||||
#define DEFAULT_XKB_OPTIONS "NULL"
|
|
@ -24,10 +24,11 @@
|
|||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "xkbcommon/xkbcommon.h"
|
||||
#include "utils.h"
|
||||
|
@ -52,19 +53,13 @@ xkb_context_failed_include_path_get(struct xkb_context *ctx,
|
|||
xkb_atom_t
|
||||
xkb_atom_lookup(struct xkb_context *ctx, const char *string)
|
||||
{
|
||||
return atom_lookup(ctx->atom_table, string, strlen(string));
|
||||
return atom_intern(ctx->atom_table, string, strlen(string), false);
|
||||
}
|
||||
|
||||
xkb_atom_t
|
||||
xkb_atom_intern(struct xkb_context *ctx, const char *string, size_t len)
|
||||
{
|
||||
return atom_intern(ctx->atom_table, string, len, false);
|
||||
}
|
||||
|
||||
xkb_atom_t
|
||||
xkb_atom_steal(struct xkb_context *ctx, char *string)
|
||||
{
|
||||
return atom_intern(ctx->atom_table, string, strlen(string), true);
|
||||
return atom_intern(ctx->atom_table, string, len, true);
|
||||
}
|
||||
|
||||
const char *
|
||||
|
@ -104,14 +99,6 @@ xkb_context_get_buffer(struct xkb_context *ctx, size_t size)
|
|||
return rtrn;
|
||||
}
|
||||
|
||||
#ifndef DEFAULT_XKB_VARIANT
|
||||
#define DEFAULT_XKB_VARIANT NULL
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_XKB_OPTIONS
|
||||
#define DEFAULT_XKB_OPTIONS NULL
|
||||
#endif
|
||||
|
||||
static const char *
|
||||
xkb_context_get_default_rules(struct xkb_context *ctx)
|
||||
{
|
||||
|
|
|
@ -24,10 +24,20 @@
|
|||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#ifdef _MSC_VER
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
# ifndef S_ISDIR
|
||||
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
# endif
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "xkbcommon/xkbcommon.h"
|
||||
#include "utils.h"
|
||||
|
@ -40,7 +50,7 @@ XKB_EXPORT int
|
|||
xkb_context_include_path_append(struct xkb_context *ctx, const char *path)
|
||||
{
|
||||
struct stat stat_buf;
|
||||
int err;
|
||||
int err = ENOMEM;
|
||||
char *tmp;
|
||||
|
||||
tmp = strdup(path);
|
||||
|
@ -48,48 +58,85 @@ xkb_context_include_path_append(struct xkb_context *ctx, const char *path)
|
|||
goto err;
|
||||
|
||||
err = stat(path, &stat_buf);
|
||||
if (err != 0)
|
||||
if (err != 0) {
|
||||
err = errno;
|
||||
goto err;
|
||||
if (!S_ISDIR(stat_buf.st_mode))
|
||||
}
|
||||
if (!S_ISDIR(stat_buf.st_mode)) {
|
||||
err = ENOTDIR;
|
||||
goto err;
|
||||
}
|
||||
|
||||
#if defined(HAVE_EACCESS)
|
||||
if (eaccess(path, R_OK | X_OK) != 0)
|
||||
if (!check_eaccess(path, R_OK | X_OK)) {
|
||||
err = EACCES;
|
||||
goto err;
|
||||
#elif defined(HAVE_EUIDACCESS)
|
||||
if (euidaccess(path, R_OK | X_OK) != 0)
|
||||
goto err;
|
||||
#endif
|
||||
}
|
||||
|
||||
darray_append(ctx->includes, tmp);
|
||||
log_dbg(ctx, "Include path added: %s\n", tmp);
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
darray_append(ctx->failed_includes, tmp);
|
||||
log_dbg(ctx, "Include path failed: %s (%s)\n", tmp, strerror(err));
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
xkb_context_include_path_get_extra_path(struct xkb_context *ctx)
|
||||
{
|
||||
const char *extra = secure_getenv("XKB_CONFIG_EXTRA_PATH");
|
||||
return extra ? extra : DFLT_XKB_CONFIG_EXTRA_PATH;
|
||||
}
|
||||
|
||||
const char *
|
||||
xkb_context_include_path_get_system_path(struct xkb_context *ctx)
|
||||
{
|
||||
const char *root = secure_getenv("XKB_CONFIG_ROOT");
|
||||
return root ? root : DFLT_XKB_CONFIG_ROOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the default include directories to the context.
|
||||
*/
|
||||
XKB_EXPORT int
|
||||
xkb_context_include_path_append_default(struct xkb_context *ctx)
|
||||
{
|
||||
const char *home;
|
||||
const char *home, *xdg, *root, *extra;
|
||||
char *user_path;
|
||||
int err;
|
||||
int ret = 0;
|
||||
|
||||
ret |= xkb_context_include_path_append(ctx, DFLT_XKB_CONFIG_ROOT);
|
||||
|
||||
home = secure_getenv("HOME");
|
||||
if (!home)
|
||||
return ret;
|
||||
err = asprintf(&user_path, "%s/.xkb", home);
|
||||
if (err <= 0)
|
||||
return ret;
|
||||
ret |= xkb_context_include_path_append(ctx, user_path);
|
||||
free(user_path);
|
||||
|
||||
xdg = secure_getenv("XDG_CONFIG_HOME");
|
||||
if (xdg != NULL) {
|
||||
user_path = asprintf_safe("%s/xkb", xdg);
|
||||
if (user_path) {
|
||||
ret |= xkb_context_include_path_append(ctx, user_path);
|
||||
free(user_path);
|
||||
}
|
||||
} else if (home != NULL) {
|
||||
/* XDG_CONFIG_HOME fallback is $HOME/.config/ */
|
||||
user_path = asprintf_safe("%s/.config/xkb", home);
|
||||
if (user_path) {
|
||||
ret |= xkb_context_include_path_append(ctx, user_path);
|
||||
free(user_path);
|
||||
}
|
||||
}
|
||||
|
||||
if (home != NULL) {
|
||||
user_path = asprintf_safe("%s/.xkb", home);
|
||||
if (user_path) {
|
||||
ret |= xkb_context_include_path_append(ctx, user_path);
|
||||
free(user_path);
|
||||
}
|
||||
}
|
||||
|
||||
extra = xkb_context_include_path_get_extra_path(ctx);
|
||||
ret |= xkb_context_include_path_append(ctx, extra);
|
||||
root = xkb_context_include_path_get_system_path(ctx);
|
||||
ret |= xkb_context_include_path_append(ctx, root);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -163,6 +210,7 @@ xkb_context_unref(struct xkb_context *ctx)
|
|||
if (!ctx || --ctx->refcnt > 0)
|
||||
return;
|
||||
|
||||
free(ctx->x11_atom_cache);
|
||||
xkb_context_include_path_clear(ctx);
|
||||
atom_table_free(ctx->atom_table);
|
||||
free(ctx);
|
||||
|
@ -276,6 +324,8 @@ xkb_context_new(enum xkb_context_flags flags)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ctx->x11_atom_cache = NULL;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,9 @@ struct xkb_context {
|
|||
|
||||
struct atom_table *atom_table;
|
||||
|
||||
/* Used and allocated by xkbcommon-x11, free()d with the context. */
|
||||
void *x11_atom_cache;
|
||||
|
||||
/* Buffer for the *Text() functions. */
|
||||
char text_buffer[2048];
|
||||
size_t text_next;
|
||||
|
@ -59,6 +62,12 @@ const char *
|
|||
xkb_context_failed_include_path_get(struct xkb_context *ctx,
|
||||
unsigned int idx);
|
||||
|
||||
const char *
|
||||
xkb_context_include_path_get_extra_path(struct xkb_context *ctx);
|
||||
|
||||
const char *
|
||||
xkb_context_include_path_get_system_path(struct xkb_context *ctx);
|
||||
|
||||
/*
|
||||
* Returns XKB_ATOM_NONE if @string was not previously interned,
|
||||
* otherwise returns the atom.
|
||||
|
@ -101,14 +110,16 @@ xkb_context_sanitize_rule_names(struct xkb_context *ctx,
|
|||
* format is supplied without arguments. Not supplying it would still
|
||||
* result in an error, though.
|
||||
*/
|
||||
|
||||
|
||||
#define log_dbg(ctx, ...) \
|
||||
xkb_log((ctx), XKB_LOG_LEVEL_DEBUG, 0, __VA_ARGS__)
|
||||
#define log_info(ctx, ...) \
|
||||
xkb_log((ctx), XKB_LOG_LEVEL_INFO, 0, __VA_ARGS__)
|
||||
#define log_warn(ctx, ...) \
|
||||
xkb_log((ctx), XKB_LOG_LEVEL_WARNING, 0, __VA_ARGS__)
|
||||
xkb_log((ctx), XKB_LOG_LEVEL_WARNING, 0, __VA_ARGS__)
|
||||
#define log_err(ctx, ...) \
|
||||
xkb_log((ctx), XKB_LOG_LEVEL_ERROR, 0, __VA_ARGS__)
|
||||
xkb_log((ctx), XKB_LOG_LEVEL_ERROR, 0, __VA_ARGS__)
|
||||
#define log_wsgo(ctx, ...) \
|
||||
xkb_log((ctx), XKB_LOG_LEVEL_CRITICAL, 0, __VA_ARGS__)
|
||||
#define log_vrb(ctx, vrb, ...) \
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#ifndef CCAN_DARRAY_H
|
||||
#define CCAN_DARRAY_H
|
||||
|
||||
/* Originally taken from: http://ccodearchive.net/info/darray.html
|
||||
/* Originally taken from: https://ccodearchive.net/info/darray.html
|
||||
* But modified for libxkbcommon. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -104,12 +104,16 @@ typedef darray (unsigned long) darray_ulong;
|
|||
#define darray_from_items(arr, items, count) do { \
|
||||
unsigned __count = (count); \
|
||||
darray_resize(arr, __count); \
|
||||
memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
|
||||
if (__count != 0) \
|
||||
memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
|
||||
} while (0)
|
||||
|
||||
#define darray_copy(arr_to, arr_from) \
|
||||
darray_from_items((arr_to), (arr_from).item, (arr_from).size)
|
||||
|
||||
#define darray_concat(arr_to, arr_from) \
|
||||
darray_append_items((arr_to), (arr_from).item, (arr_from).size)
|
||||
|
||||
/*** String buffer ***/
|
||||
|
||||
#define darray_append_string(arr, str) do { \
|
||||
|
@ -202,4 +206,7 @@ darray_next_alloc(unsigned alloc, unsigned need, unsigned itemSize)
|
|||
(idx) < (arr).size; \
|
||||
(idx)++, (val)++)
|
||||
|
||||
#define darray_foreach_reverse(i, arr) \
|
||||
for ((i) = &(arr).item[(arr).size - 1]; (arr).size > 0 && (i) >= &(arr).item[0]; (i)--)
|
||||
|
||||
#endif /* CCAN_DARRAY_H */
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "keymap.h"
|
||||
|
||||
static void
|
||||
|
@ -118,7 +120,8 @@ XkbEscapeMapName(char *name)
|
|||
return;
|
||||
|
||||
while (*name) {
|
||||
if (!(legal[*name / 8] & (1 << (*name % 8))))
|
||||
unsigned char c = *name;
|
||||
if (!(legal[c / 8] & (1 << (c % 8))))
|
||||
*name = '_';
|
||||
name++;
|
||||
}
|
||||
|
@ -137,3 +140,13 @@ XkbModNameToIndex(const struct xkb_mod_set *mods, xkb_atom_t name,
|
|||
|
||||
return XKB_MOD_INVALID;
|
||||
}
|
||||
|
||||
bool
|
||||
XkbLevelsSameSyms(const struct xkb_level *a, const struct xkb_level *b)
|
||||
{
|
||||
if (a->num_syms != b->num_syms)
|
||||
return false;
|
||||
if (a->num_syms <= 1)
|
||||
return a->u.sym == b->u.sym;
|
||||
return memcmp(a->u.syms, b->u.syms, sizeof(*a->u.syms) * a->num_syms) == 0;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
*
|
||||
* ********************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "keymap.h"
|
||||
#include "text.h"
|
||||
|
||||
|
@ -407,6 +409,66 @@ xkb_keymap_led_get_index(struct xkb_keymap *keymap, const char *name)
|
|||
return XKB_LED_INVALID;
|
||||
}
|
||||
|
||||
XKB_EXPORT size_t
|
||||
xkb_keymap_key_get_mods_for_level(struct xkb_keymap *keymap,
|
||||
xkb_keycode_t kc,
|
||||
xkb_layout_index_t layout,
|
||||
xkb_level_index_t level,
|
||||
xkb_mod_mask_t *masks_out,
|
||||
size_t masks_size)
|
||||
{
|
||||
const struct xkb_key *key = XkbKey(keymap, kc);
|
||||
if (!key)
|
||||
return 0;
|
||||
|
||||
layout = XkbWrapGroupIntoRange(layout, key->num_groups,
|
||||
key->out_of_range_group_action,
|
||||
key->out_of_range_group_number);
|
||||
if (layout == XKB_LAYOUT_INVALID)
|
||||
return 0;
|
||||
|
||||
if (level >= XkbKeyNumLevels(key, layout))
|
||||
return 0;
|
||||
|
||||
const struct xkb_key_type *type = key->groups[layout].type;
|
||||
|
||||
size_t count = 0;
|
||||
|
||||
/*
|
||||
* If the active set of modifiers doesn't match any explicit entry of
|
||||
* the key type, the resulting level is 0 (i.e. Level 1).
|
||||
* So, if we are asked to find the modifiers for level==0, we can offer
|
||||
* an ~infinite supply, which is not very workable.
|
||||
* What we do instead, is special case the empty set of modifiers for
|
||||
* this purpose. If the empty set isn't explicit mapped to a level, we
|
||||
* take it to map to Level 1.
|
||||
* This is almost always what we want. If applicable, given it priority
|
||||
* over other ways to generate the level.
|
||||
*/
|
||||
if (level == 0) {
|
||||
bool empty_mapped = false;
|
||||
for (unsigned i = 0; i < type->num_entries && count < masks_size; i++)
|
||||
if (entry_is_active(&type->entries[i]) &&
|
||||
type->entries[i].mods.mask == 0) {
|
||||
empty_mapped = true;
|
||||
break;
|
||||
}
|
||||
if (!empty_mapped && count < masks_size) {
|
||||
masks_out[count++] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now search explicit mappings. */
|
||||
for (unsigned i = 0; i < type->num_entries && count < masks_size; i++) {
|
||||
if (entry_is_active(&type->entries[i]) &&
|
||||
type->entries[i].level == level) {
|
||||
masks_out[count++] = type->entries[i].mods.mask;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* As below, but takes an explicit layout/level rather than state.
|
||||
*/
|
||||
|
@ -470,6 +532,40 @@ xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter,
|
|||
iter(keymap, key->keycode, data);
|
||||
}
|
||||
|
||||
XKB_EXPORT const char *
|
||||
xkb_keymap_key_get_name(struct xkb_keymap *keymap, xkb_keycode_t kc)
|
||||
{
|
||||
const struct xkb_key *key = XkbKey(keymap, kc);
|
||||
|
||||
if (!key)
|
||||
return NULL;
|
||||
|
||||
return xkb_atom_text(keymap->ctx, key->name);
|
||||
}
|
||||
|
||||
XKB_EXPORT xkb_keycode_t
|
||||
xkb_keymap_key_by_name(struct xkb_keymap *keymap, const char *name)
|
||||
{
|
||||
struct xkb_key *key;
|
||||
xkb_atom_t atom;
|
||||
|
||||
atom = xkb_atom_lookup(keymap->ctx, name);
|
||||
if (atom) {
|
||||
xkb_atom_t ratom = XkbResolveKeyAlias(keymap, atom);
|
||||
if (ratom)
|
||||
atom = ratom;
|
||||
}
|
||||
if (!atom)
|
||||
return XKB_KEYCODE_INVALID;
|
||||
|
||||
xkb_keys_foreach(key, keymap) {
|
||||
if (key->name == atom)
|
||||
return key->keycode;
|
||||
}
|
||||
|
||||
return XKB_KEYCODE_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple boolean specifying whether or not the key should repeat.
|
||||
*/
|
||||
|
|
|
@ -253,6 +253,7 @@ struct xkb_key_type {
|
|||
xkb_atom_t name;
|
||||
struct xkb_mods mods;
|
||||
xkb_level_index_t num_levels;
|
||||
unsigned int num_level_names;
|
||||
xkb_atom_t *level_names;
|
||||
unsigned int num_entries;
|
||||
struct xkb_key_type_entry *entries;
|
||||
|
@ -324,7 +325,7 @@ struct xkb_group {
|
|||
bool explicit_type;
|
||||
/* Points to a type in keymap->types. */
|
||||
const struct xkb_key_type *type;
|
||||
/* Use XkbKeyGroupWidth for the number of levels. */
|
||||
/* Use XkbKeyNumLevels for the number of levels. */
|
||||
struct xkb_level *levels;
|
||||
};
|
||||
|
||||
|
@ -437,6 +438,17 @@ XkbKeyNumLevels(const struct xkb_key *key, xkb_layout_index_t layout)
|
|||
return key->groups[layout].type->num_levels;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the virtual modifiers are not bound to anything, the entry
|
||||
* is not active and should be skipped. xserver does this with
|
||||
* cached entry->active field.
|
||||
*/
|
||||
static inline bool
|
||||
entry_is_active(const struct xkb_key_type_entry *entry)
|
||||
{
|
||||
return entry->mods.mods == 0 || entry->mods.mask != 0;
|
||||
}
|
||||
|
||||
struct xkb_keymap *
|
||||
xkb_keymap_new(struct xkb_context *ctx,
|
||||
enum xkb_keymap_format format,
|
||||
|
@ -455,6 +467,9 @@ xkb_mod_index_t
|
|||
XkbModNameToIndex(const struct xkb_mod_set *mods, xkb_atom_t name,
|
||||
enum mod_type type);
|
||||
|
||||
bool
|
||||
XkbLevelsSameSyms(const struct xkb_level *a, const struct xkb_level *b);
|
||||
|
||||
xkb_layout_index_t
|
||||
XkbWrapGroupIntoRange(int32_t group,
|
||||
xkb_layout_index_t num_groups,
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "xkbcommon/xkbcommon.h"
|
||||
#include "utils.h"
|
||||
#include "utf8.h"
|
||||
|
@ -521,7 +523,7 @@ static const struct codepair keysymtab[] = {
|
|||
{ 0x0aa8, 0x200a }, /* hairspace HAIR SPACE */
|
||||
{ 0x0aa9, 0x2014 }, /* emdash — EM DASH */
|
||||
{ 0x0aaa, 0x2013 }, /* endash – EN DASH */
|
||||
/* 0x0aac signifblank ? ??? */
|
||||
{ 0x0aac, 0x2423 }, /* signifblank ␣ OPEN BOX */
|
||||
{ 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */
|
||||
{ 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */
|
||||
{ 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */
|
||||
|
@ -534,9 +536,9 @@ static const struct codepair keysymtab[] = {
|
|||
{ 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */
|
||||
{ 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */
|
||||
{ 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */
|
||||
{ 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */
|
||||
{ 0x0abc, 0x27e8 }, /* leftanglebracket ⟨ MATHEMATICAL LEFT ANGLE BRACKET */
|
||||
{ 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */
|
||||
{ 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */
|
||||
{ 0x0abe, 0x27e9 }, /* rightanglebracket ⟩ MATHEMATICAL RIGHT ANGLE BRACKET */
|
||||
/* 0x0abf marker ? ??? */
|
||||
{ 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */
|
||||
{ 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */
|
||||
|
@ -554,6 +556,7 @@ static const struct codepair keysymtab[] = {
|
|||
{ 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */
|
||||
{ 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */
|
||||
{ 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */
|
||||
{ 0x0ad5, 0x2030 }, /* permille ‰ PER MILLE SIGN */
|
||||
{ 0x0ad6, 0x2032 }, /* minutes ′ PRIME */
|
||||
{ 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */
|
||||
{ 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */
|
||||
|
@ -611,8 +614,8 @@ static const struct codepair keysymtab[] = {
|
|||
{ 0x0bd6, 0x222a }, /* downshoe ∪ UNION */
|
||||
{ 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */
|
||||
{ 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */
|
||||
{ 0x0bdc, 0x22a2 }, /* lefttack ⊢ RIGHT TACK */
|
||||
{ 0x0bfc, 0x22a3 }, /* righttack ⊣ LEFT TACK */
|
||||
{ 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */
|
||||
{ 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */
|
||||
{ 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */
|
||||
{ 0x0ce0, 0x05d0 }, /* hebrew_aleph א HEBREW LETTER ALEF */
|
||||
{ 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */
|
||||
|
@ -807,7 +810,7 @@ static const struct codepair keysymtab[] = {
|
|||
{ 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */
|
||||
{ 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */
|
||||
{ 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */
|
||||
/* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */
|
||||
{ 0x0ef3, 0x3181 }, /* Hangul_KkogjiDalrinIeung ㆁ HANGUL LETTER YESIEUNG */
|
||||
{ 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
|
||||
{ 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
|
||||
{ 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */
|
||||
|
@ -880,14 +883,49 @@ xkb_keysym_to_utf32(xkb_keysym_t keysym)
|
|||
keysym == XKB_KEY_KP_Enter || keysym == XKB_KEY_KP_Equal)
|
||||
return keysym & 0x7f;
|
||||
|
||||
/* also check for directly encoded 24-bit UCS characters */
|
||||
if ((keysym & 0xff000000) == 0x01000000)
|
||||
return keysym & 0x00ffffff;
|
||||
/* also check for directly encoded Unicode codepoints */
|
||||
/*
|
||||
* In theory, this is supposed to start from 0x100100, such that the ASCII
|
||||
* range, which is already covered by 0x00-0xff, can't be encoded in two
|
||||
* ways. However, changing this after a couple of decades probably won't
|
||||
* go well, so it stays as it is.
|
||||
*/
|
||||
if (0x01000000 <= keysym && keysym <= 0x0110ffff)
|
||||
return keysym - 0x01000000;
|
||||
|
||||
/* search main table */
|
||||
return bin_search(keysymtab, ARRAY_SIZE(keysymtab) - 1, keysym);
|
||||
}
|
||||
|
||||
XKB_EXPORT xkb_keysym_t
|
||||
xkb_utf32_to_keysym(uint32_t ucs)
|
||||
{
|
||||
/* first check for Latin-1 characters (1:1 mapping) */
|
||||
if ((ucs >= 0x0020 && ucs <= 0x007e) ||
|
||||
(ucs >= 0x00a0 && ucs <= 0x00ff))
|
||||
return ucs;
|
||||
|
||||
/* special keysyms */
|
||||
if ((ucs >= (XKB_KEY_BackSpace & 0x7f) && ucs <= (XKB_KEY_Clear & 0x7f)) ||
|
||||
ucs == (XKB_KEY_Return & 0x7f) || ucs == (XKB_KEY_Escape & 0x7f))
|
||||
return ucs | 0xff00;
|
||||
if (ucs == (XKB_KEY_Delete & 0x7f))
|
||||
return XKB_KEY_Delete;
|
||||
|
||||
/* Unicode non-symbols and code points outside Unicode planes */
|
||||
if ((ucs >= 0xfdd0 && ucs <= 0xfdef) ||
|
||||
ucs > 0x10ffff || (ucs & 0xfffe) == 0xfffe)
|
||||
return XKB_KEY_NoSymbol;
|
||||
|
||||
/* search main table */
|
||||
for (size_t i = 0; i < ARRAY_SIZE(keysymtab); i++)
|
||||
if (keysymtab[i].ucs == ucs)
|
||||
return keysymtab[i].keysym;
|
||||
|
||||
/* Use direct encoding if everything else fails */
|
||||
return ucs | 0x01000000;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
*
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "xkbcommon/xkbcommon.h"
|
||||
#include "utils.h"
|
||||
|
@ -59,42 +61,25 @@ get_name(const struct name_keysym *entry)
|
|||
return keysym_names + entry->offset;
|
||||
}
|
||||
|
||||
static int
|
||||
compare_by_keysym(const void *a, const void *b)
|
||||
{
|
||||
const xkb_keysym_t *key = a;
|
||||
const struct name_keysym *entry = b;
|
||||
if (*key < entry->keysym)
|
||||
return -1;
|
||||
if (*key > entry->keysym)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
compare_by_name(const void *a, const void *b)
|
||||
{
|
||||
const char *key = a;
|
||||
const struct name_keysym *entry = b;
|
||||
return strcasecmp(key, get_name(entry));
|
||||
}
|
||||
|
||||
XKB_EXPORT int
|
||||
xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
|
||||
{
|
||||
const struct name_keysym *entry;
|
||||
|
||||
if ((ks & ((unsigned long) ~0x1fffffff)) != 0) {
|
||||
snprintf(buffer, size, "Invalid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
entry = bsearch(&ks, keysym_to_name,
|
||||
ARRAY_SIZE(keysym_to_name),
|
||||
sizeof(*keysym_to_name),
|
||||
compare_by_keysym);
|
||||
if (entry)
|
||||
return snprintf(buffer, size, "%s", get_name(entry));
|
||||
int32_t lo = 0, hi = ARRAY_SIZE(keysym_to_name) - 1;
|
||||
while (hi >= lo) {
|
||||
int32_t mid = (lo + hi) / 2;
|
||||
if (ks > keysym_to_name[mid].keysym) {
|
||||
lo = mid + 1;
|
||||
} else if (ks < keysym_to_name[mid].keysym) {
|
||||
hi = mid - 1;
|
||||
} else {
|
||||
return snprintf(buffer, size, "%s", get_name(&keysym_to_name[mid]));
|
||||
}
|
||||
}
|
||||
|
||||
/* Unnamed Unicode codepoint. */
|
||||
if (ks >= 0x01000100 && ks <= 0x0110ffff) {
|
||||
|
@ -107,108 +92,135 @@ xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
|
|||
}
|
||||
|
||||
/*
|
||||
* Find the correct keysym if one case-insensitive match is given.
|
||||
*
|
||||
* The name_to_keysym table is sorted by strcasecmp(). So bsearch() may return
|
||||
* _any_ of all possible case-insensitive duplicates. This function searches the
|
||||
* returned entry @entry, all previous and all next entries that match by
|
||||
* case-insensitive comparison and returns the exact match to @name. If @icase
|
||||
* is true, then this returns the best case-insensitive match instead of a
|
||||
* correct match.
|
||||
* The "best" case-insensitive match is the lower-case keysym which we find with
|
||||
* the help of xkb_keysym_is_lower().
|
||||
* The only keysyms that only differ by letter-case are keysyms that are
|
||||
* available as lower-case and upper-case variant (like KEY_a and KEY_A). So
|
||||
* returning the first lower-case match is enough in this case.
|
||||
* Parse the numeric part of a 0xXXXX and UXXXX keysym.
|
||||
* Not using strtoul -- it's slower and accepts a bunch of stuff
|
||||
* we don't want to allow, like signs, spaces, even locale stuff.
|
||||
*/
|
||||
static const struct name_keysym *
|
||||
find_sym(const struct name_keysym *entry, const char *name, bool icase)
|
||||
static bool
|
||||
parse_keysym_hex(const char *s, uint32_t *out)
|
||||
{
|
||||
const struct name_keysym *iter, *last;
|
||||
size_t len = ARRAY_SIZE(name_to_keysym);
|
||||
|
||||
if (!entry)
|
||||
return NULL;
|
||||
|
||||
if (!icase && strcmp(get_name(entry), name) == 0)
|
||||
return entry;
|
||||
if (icase && xkb_keysym_is_lower(entry->keysym))
|
||||
return entry;
|
||||
|
||||
for (iter = entry - 1; iter >= name_to_keysym; --iter) {
|
||||
if (!icase && strcmp(get_name(iter), name) == 0)
|
||||
return iter;
|
||||
if (strcasecmp(get_name(iter), get_name(entry)) != 0)
|
||||
break;
|
||||
if (icase && xkb_keysym_is_lower(iter->keysym))
|
||||
return iter;
|
||||
uint32_t result = 0;
|
||||
int i;
|
||||
for (i = 0; i < 8 && s[i] != '\0'; i++) {
|
||||
result <<= 4;
|
||||
if ('0' <= s[i] && s[i] <= '9')
|
||||
result += s[i] - '0';
|
||||
else if ('a' <= s[i] && s[i] <= 'f')
|
||||
result += 10 + s[i] - 'a';
|
||||
else if ('A' <= s[i] && s[i] <= 'F')
|
||||
result += 10 + s[i] - 'A';
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
last = name_to_keysym + len;
|
||||
for (iter = entry + 1; iter < last; ++iter) {
|
||||
if (!icase && strcmp(get_name(iter), name) == 0)
|
||||
return iter;
|
||||
if (strcasecmp(get_name(iter), get_name(entry)) != 0)
|
||||
break;
|
||||
if (icase && xkb_keysym_is_lower(iter->keysym))
|
||||
return iter;
|
||||
}
|
||||
|
||||
if (icase)
|
||||
return entry;
|
||||
return NULL;
|
||||
*out = result;
|
||||
return s[i] == '\0' && i > 0;
|
||||
}
|
||||
|
||||
XKB_EXPORT xkb_keysym_t
|
||||
xkb_keysym_from_name(const char *s, enum xkb_keysym_flags flags)
|
||||
xkb_keysym_from_name(const char *name, enum xkb_keysym_flags flags)
|
||||
{
|
||||
const struct name_keysym *entry;
|
||||
const struct name_keysym *entry = NULL;
|
||||
char *tmp;
|
||||
xkb_keysym_t val;
|
||||
uint32_t val;
|
||||
bool icase = (flags & XKB_KEYSYM_CASE_INSENSITIVE);
|
||||
|
||||
if (flags & ~XKB_KEYSYM_CASE_INSENSITIVE)
|
||||
return XKB_KEY_NoSymbol;
|
||||
|
||||
entry = bsearch(s, name_to_keysym,
|
||||
ARRAY_SIZE(name_to_keysym),
|
||||
sizeof(*name_to_keysym),
|
||||
compare_by_name);
|
||||
entry = find_sym(entry, s, icase);
|
||||
if (entry)
|
||||
return entry->keysym;
|
||||
/*
|
||||
* We need to !icase case to be fast, for e.g. Compose file parsing.
|
||||
* So do it in a fast path.
|
||||
*/
|
||||
if (!icase) {
|
||||
size_t pos = keysym_name_perfect_hash(name);
|
||||
if (pos < ARRAY_SIZE(name_to_keysym)) {
|
||||
const char *s = get_name(&name_to_keysym[pos]);
|
||||
if (strcmp(name, s) == 0)
|
||||
return name_to_keysym[pos].keysym;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Find the correct keysym for case-insensitive match.
|
||||
*
|
||||
* The name_to_keysym table is sorted by istrcmp(). So the binary
|
||||
* search may return _any_ of all possible case-insensitive duplicates. This
|
||||
* code searches the entry, all previous and all next entries that match by
|
||||
* case-insensitive comparison and returns the "best" case-insensitive
|
||||
* match.
|
||||
*
|
||||
* The "best" case-insensitive match is the lower-case keysym which we find
|
||||
* with the help of xkb_keysym_is_lower(). The only keysyms that only differ
|
||||
* by letter-case are keysyms that are available as lower-case and
|
||||
* upper-case variant (like KEY_a and KEY_A). So returning the first
|
||||
* lower-case match is enough in this case.
|
||||
*/
|
||||
else {
|
||||
int32_t lo = 0, hi = ARRAY_SIZE(name_to_keysym) - 1;
|
||||
while (hi >= lo) {
|
||||
int32_t mid = (lo + hi) / 2;
|
||||
int cmp = istrcmp(name, get_name(&name_to_keysym[mid]));
|
||||
if (cmp > 0) {
|
||||
lo = mid + 1;
|
||||
} else if (cmp < 0) {
|
||||
hi = mid - 1;
|
||||
} else {
|
||||
entry = &name_to_keysym[mid];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry) {
|
||||
const struct name_keysym *iter, *last;
|
||||
|
||||
if (*s == 'U' || (icase && *s == 'u')) {
|
||||
val = strtoul(&s[1], &tmp, 16);
|
||||
if (tmp && *tmp != '\0')
|
||||
if (icase && xkb_keysym_is_lower(entry->keysym))
|
||||
return entry->keysym;
|
||||
|
||||
for (iter = entry - 1; iter >= name_to_keysym; --iter) {
|
||||
if (istrcmp(get_name(iter), get_name(entry)) != 0)
|
||||
break;
|
||||
if (xkb_keysym_is_lower(iter->keysym))
|
||||
return iter->keysym;
|
||||
}
|
||||
|
||||
last = name_to_keysym + ARRAY_SIZE(name_to_keysym);
|
||||
for (iter = entry + 1; iter < last; ++iter) {
|
||||
if (istrcmp(get_name(iter), get_name(entry)) != 0)
|
||||
break;
|
||||
if (xkb_keysym_is_lower(iter->keysym))
|
||||
return iter->keysym;
|
||||
}
|
||||
|
||||
return entry->keysym;
|
||||
}
|
||||
}
|
||||
|
||||
if (*name == 'U' || (icase && *name == 'u')) {
|
||||
if (!parse_keysym_hex(&name[1], &val))
|
||||
return XKB_KEY_NoSymbol;
|
||||
|
||||
if (val < 0x20 || (val > 0x7e && val < 0xa0))
|
||||
return XKB_KEY_NoSymbol;
|
||||
if (val < 0x100)
|
||||
return val;
|
||||
return (xkb_keysym_t) val;
|
||||
if (val > 0x10ffff)
|
||||
return XKB_KEY_NoSymbol;
|
||||
return val | 0x01000000;
|
||||
return (xkb_keysym_t) val | 0x01000000;
|
||||
}
|
||||
else if (s[0] == '0' && (s[1] == 'x' || (icase && s[1] == 'X'))) {
|
||||
val = strtoul(&s[2], &tmp, 16);
|
||||
if (tmp && *tmp != '\0')
|
||||
else if (name[0] == '0' && (name[1] == 'x' || (icase && name[1] == 'X'))) {
|
||||
if (!parse_keysym_hex(&name[2], &val))
|
||||
return XKB_KEY_NoSymbol;
|
||||
|
||||
return val;
|
||||
return (xkb_keysym_t) val;
|
||||
}
|
||||
|
||||
/* Stupid inconsistency between the headers and XKeysymDB: the former has
|
||||
* no separating underscore, while some XF86* syms in the latter did.
|
||||
* As a last ditch effort, try without. */
|
||||
if (strncmp(s, "XF86_", 5) == 0 ||
|
||||
(icase && strncasecmp(s, "XF86_", 5) == 0)) {
|
||||
if (strncmp(name, "XF86_", 5) == 0 ||
|
||||
(icase && istrncmp(name, "XF86_", 5) == 0)) {
|
||||
xkb_keysym_t ret;
|
||||
tmp = strdup(s);
|
||||
tmp = strdup(name);
|
||||
if (!tmp)
|
||||
return XKB_KEY_NoSymbol;
|
||||
memmove(&tmp[4], &tmp[5], strlen(s) - 5 + 1);
|
||||
memmove(&tmp[4], &tmp[5], strlen(name) - 5 + 1);
|
||||
ret = xkb_keysym_from_name(tmp, flags);
|
||||
free(tmp);
|
||||
return ret;
|
||||
|
@ -264,7 +276,7 @@ xkb_keysym_is_upper(xkb_keysym_t ks)
|
|||
return (ks == upper ? true : false);
|
||||
}
|
||||
|
||||
xkb_keysym_t
|
||||
XKB_EXPORT xkb_keysym_t
|
||||
xkb_keysym_to_lower(xkb_keysym_t ks)
|
||||
{
|
||||
xkb_keysym_t lower, upper;
|
||||
|
@ -274,7 +286,7 @@ xkb_keysym_to_lower(xkb_keysym_t ks)
|
|||
return lower;
|
||||
}
|
||||
|
||||
xkb_keysym_t
|
||||
XKB_EXPORT xkb_keysym_t
|
||||
xkb_keysym_to_upper(xkb_keysym_t ks)
|
||||
{
|
||||
xkb_keysym_t lower, upper;
|
||||
|
@ -478,6 +490,8 @@ UCSConvertCase(uint32_t code, xkb_keysym_t *lower, xkb_keysym_t *upper)
|
|||
*upper = 0x0178;
|
||||
else if (code == 0x00b5) /* micro sign */
|
||||
*upper = 0x039c;
|
||||
else if (code == 0x00df) /* ssharp */
|
||||
*upper = 0x1e9e;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -607,6 +621,8 @@ UCSConvertCase(uint32_t code, xkb_keysym_t *lower, xkb_keysym_t *upper)
|
|||
}
|
||||
else if (code == 0x1e9b)
|
||||
*upper = 0x1e60;
|
||||
else if (code == 0x1e9e)
|
||||
*lower = 0x00df; /* ssharp */
|
||||
}
|
||||
|
||||
/* Greek Extended, U+1F00 to U+1FFF */
|
||||
|
|
|
@ -62,10 +62,4 @@ xkb_keysym_is_keypad(xkb_keysym_t keysym);
|
|||
bool
|
||||
xkb_keysym_is_modifier(xkb_keysym_t keysym);
|
||||
|
||||
xkb_keysym_t
|
||||
xkb_keysym_to_upper(xkb_keysym_t ks);
|
||||
|
||||
xkb_keysym_t
|
||||
xkb_keysym_to_lower(xkb_keysym_t ks);
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -49,9 +49,9 @@ struct scanner {
|
|||
size_t len;
|
||||
char buf[1024];
|
||||
size_t buf_pos;
|
||||
unsigned line, column;
|
||||
size_t line, column;
|
||||
/* The line/column of the start of the current token. */
|
||||
unsigned token_line, token_column;
|
||||
size_t token_line, token_column;
|
||||
const char *file_name;
|
||||
struct xkb_context *ctx;
|
||||
void *priv;
|
||||
|
@ -59,7 +59,7 @@ struct scanner {
|
|||
|
||||
#define scanner_log(scanner, level, fmt, ...) \
|
||||
xkb_log((scanner)->ctx, (level), 0, \
|
||||
"%s:%u:%u: " fmt "\n", \
|
||||
"%s:%zu:%zu: " fmt "\n", \
|
||||
(scanner)->file_name, \
|
||||
(scanner)->token_line, (scanner)->token_column, ##__VA_ARGS__)
|
||||
|
||||
|
|
|
@ -59,6 +59,8 @@
|
|||
* - messages (very unlikely)
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "keymap.h"
|
||||
#include "keysym.h"
|
||||
#include "utf8.h"
|
||||
|
@ -116,27 +118,23 @@ struct xkb_state {
|
|||
struct xkb_keymap *keymap;
|
||||
};
|
||||
|
||||
static const struct xkb_key_type_entry *
|
||||
get_entry_for_mods(const struct xkb_key_type *type, xkb_mod_mask_t mods)
|
||||
{
|
||||
for (unsigned i = 0; i < type->num_entries; i++)
|
||||
if (entry_is_active(&type->entries[i]) &&
|
||||
type->entries[i].mods.mask == mods)
|
||||
return &type->entries[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct xkb_key_type_entry *
|
||||
get_entry_for_key_state(struct xkb_state *state, const struct xkb_key *key,
|
||||
xkb_layout_index_t group)
|
||||
{
|
||||
const struct xkb_key_type *type = key->groups[group].type;
|
||||
xkb_mod_mask_t active_mods = state->components.mods & type->mods.mask;
|
||||
|
||||
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
|
||||
* entry->active field).
|
||||
*/
|
||||
if (type->entries[i].mods.mods != 0 && type->entries[i].mods.mask == 0)
|
||||
continue;
|
||||
|
||||
if (type->entries[i].mods.mask == active_mods)
|
||||
return &type->entries[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return get_entry_for_mods(type, active_mods);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,21 +213,21 @@ xkb_state_key_get_layout(struct xkb_state *state, xkb_keycode_t kc)
|
|||
key->out_of_range_group_number);
|
||||
}
|
||||
|
||||
static const union xkb_action fake = { .type = ACTION_TYPE_NONE };
|
||||
|
||||
static const union xkb_action *
|
||||
xkb_key_get_action(struct xkb_state *state, const struct xkb_key *key)
|
||||
{
|
||||
static const union xkb_action dummy = { .type = ACTION_TYPE_NONE };
|
||||
|
||||
xkb_layout_index_t layout;
|
||||
xkb_level_index_t level;
|
||||
|
||||
layout = xkb_state_key_get_layout(state, key->keycode);
|
||||
if (layout == XKB_LAYOUT_INVALID)
|
||||
return &fake;
|
||||
return &dummy;
|
||||
|
||||
level = xkb_state_key_get_level(state, key->keycode, layout);
|
||||
if (level == XKB_LEVEL_INVALID)
|
||||
return &fake;
|
||||
return &dummy;
|
||||
|
||||
return &key->groups[layout].levels[level].action;
|
||||
}
|
||||
|
@ -257,33 +255,20 @@ xkb_filter_new(struct xkb_state *state)
|
|||
|
||||
/***====================================================================***/
|
||||
|
||||
static bool
|
||||
xkb_filter_group_set_func(struct xkb_state *state,
|
||||
struct xkb_filter *filter,
|
||||
const struct xkb_key *key,
|
||||
enum xkb_key_direction direction)
|
||||
{
|
||||
if (key != filter->key) {
|
||||
filter->action.group.flags &= ~ACTION_LOCK_CLEAR;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (direction == XKB_KEY_DOWN) {
|
||||
filter->refcnt++;
|
||||
return false;
|
||||
}
|
||||
else if (--filter->refcnt > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
state->components.base_group = filter->priv;
|
||||
|
||||
if (filter->action.group.flags & ACTION_LOCK_CLEAR)
|
||||
state->components.locked_group = 0;
|
||||
|
||||
filter->func = NULL;
|
||||
return true;
|
||||
}
|
||||
enum xkb_filter_result {
|
||||
/*
|
||||
* The event is consumed by the filters.
|
||||
*
|
||||
* An event is always processed by all filters, but any filter can
|
||||
* prevent it from being processed further by consuming it.
|
||||
*/
|
||||
XKB_FILTER_CONSUME,
|
||||
/*
|
||||
* The event may continue to be processed as far as this filter is
|
||||
* concerned.
|
||||
*/
|
||||
XKB_FILTER_CONTINUE,
|
||||
};
|
||||
|
||||
static void
|
||||
xkb_filter_group_set_new(struct xkb_state *state, struct xkb_filter *filter)
|
||||
|
@ -296,23 +281,31 @@ xkb_filter_group_set_new(struct xkb_state *state, struct xkb_filter *filter)
|
|||
}
|
||||
|
||||
static bool
|
||||
xkb_filter_group_lock_func(struct xkb_state *state,
|
||||
struct xkb_filter *filter,
|
||||
const struct xkb_key *key,
|
||||
enum xkb_key_direction direction)
|
||||
xkb_filter_group_set_func(struct xkb_state *state,
|
||||
struct xkb_filter *filter,
|
||||
const struct xkb_key *key,
|
||||
enum xkb_key_direction direction)
|
||||
{
|
||||
if (key != filter->key)
|
||||
return true;
|
||||
if (key != filter->key) {
|
||||
filter->action.group.flags &= ~ACTION_LOCK_CLEAR;
|
||||
return XKB_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
if (direction == XKB_KEY_DOWN) {
|
||||
filter->refcnt++;
|
||||
return false;
|
||||
return XKB_FILTER_CONSUME;
|
||||
}
|
||||
if (--filter->refcnt > 0)
|
||||
return false;
|
||||
else if (--filter->refcnt > 0) {
|
||||
return XKB_FILTER_CONSUME;
|
||||
}
|
||||
|
||||
state->components.base_group = filter->priv;
|
||||
|
||||
if (filter->action.group.flags & ACTION_LOCK_CLEAR)
|
||||
state->components.locked_group = 0;
|
||||
|
||||
filter->func = NULL;
|
||||
return true;
|
||||
return XKB_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -325,30 +318,23 @@ xkb_filter_group_lock_new(struct xkb_state *state, struct xkb_filter *filter)
|
|||
}
|
||||
|
||||
static bool
|
||||
xkb_filter_mod_set_func(struct xkb_state *state,
|
||||
struct xkb_filter *filter,
|
||||
const struct xkb_key *key,
|
||||
enum xkb_key_direction direction)
|
||||
xkb_filter_group_lock_func(struct xkb_state *state,
|
||||
struct xkb_filter *filter,
|
||||
const struct xkb_key *key,
|
||||
enum xkb_key_direction direction)
|
||||
{
|
||||
if (key != filter->key) {
|
||||
filter->action.mods.flags &= ~ACTION_LOCK_CLEAR;
|
||||
return true;
|
||||
}
|
||||
if (key != filter->key)
|
||||
return XKB_FILTER_CONTINUE;
|
||||
|
||||
if (direction == XKB_KEY_DOWN) {
|
||||
filter->refcnt++;
|
||||
return false;
|
||||
return XKB_FILTER_CONSUME;
|
||||
}
|
||||
else if (--filter->refcnt > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
state->clear_mods = filter->action.mods.mods.mask;
|
||||
if (filter->action.mods.flags & ACTION_LOCK_CLEAR)
|
||||
state->components.locked_mods &= ~filter->action.mods.mods.mask;
|
||||
if (--filter->refcnt > 0)
|
||||
return XKB_FILTER_CONSUME;
|
||||
|
||||
filter->func = NULL;
|
||||
return true;
|
||||
return XKB_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -358,27 +344,30 @@ xkb_filter_mod_set_new(struct xkb_state *state, struct xkb_filter *filter)
|
|||
}
|
||||
|
||||
static bool
|
||||
xkb_filter_mod_lock_func(struct xkb_state *state,
|
||||
struct xkb_filter *filter,
|
||||
const struct xkb_key *key,
|
||||
enum xkb_key_direction direction)
|
||||
xkb_filter_mod_set_func(struct xkb_state *state,
|
||||
struct xkb_filter *filter,
|
||||
const struct xkb_key *key,
|
||||
enum xkb_key_direction direction)
|
||||
{
|
||||
if (key != filter->key)
|
||||
return true;
|
||||
if (key != filter->key) {
|
||||
filter->action.mods.flags &= ~ACTION_LOCK_CLEAR;
|
||||
return XKB_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
if (direction == XKB_KEY_DOWN) {
|
||||
filter->refcnt++;
|
||||
return false;
|
||||
return XKB_FILTER_CONSUME;
|
||||
}
|
||||
else if (--filter->refcnt > 0) {
|
||||
return XKB_FILTER_CONSUME;
|
||||
}
|
||||
if (--filter->refcnt > 0)
|
||||
return false;
|
||||
|
||||
state->clear_mods |= filter->action.mods.mods.mask;
|
||||
if (!(filter->action.mods.flags & ACTION_LOCK_NO_UNLOCK))
|
||||
state->components.locked_mods &= ~filter->priv;
|
||||
state->clear_mods = filter->action.mods.mods.mask;
|
||||
if (filter->action.mods.flags & ACTION_LOCK_CLEAR)
|
||||
state->components.locked_mods &= ~filter->action.mods.mods.mask;
|
||||
|
||||
filter->func = NULL;
|
||||
return true;
|
||||
return XKB_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -391,6 +380,30 @@ xkb_filter_mod_lock_new(struct xkb_state *state, struct xkb_filter *filter)
|
|||
state->components.locked_mods |= filter->action.mods.mods.mask;
|
||||
}
|
||||
|
||||
static bool
|
||||
xkb_filter_mod_lock_func(struct xkb_state *state,
|
||||
struct xkb_filter *filter,
|
||||
const struct xkb_key *key,
|
||||
enum xkb_key_direction direction)
|
||||
{
|
||||
if (key != filter->key)
|
||||
return XKB_FILTER_CONTINUE;
|
||||
|
||||
if (direction == XKB_KEY_DOWN) {
|
||||
filter->refcnt++;
|
||||
return XKB_FILTER_CONSUME;
|
||||
}
|
||||
if (--filter->refcnt > 0)
|
||||
return XKB_FILTER_CONSUME;
|
||||
|
||||
state->clear_mods |= filter->action.mods.mods.mask;
|
||||
if (!(filter->action.mods.flags & ACTION_LOCK_NO_UNLOCK))
|
||||
state->components.locked_mods &= ~filter->priv;
|
||||
|
||||
filter->func = NULL;
|
||||
return XKB_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
enum xkb_key_latch_state {
|
||||
NO_LATCH,
|
||||
LATCH_KEY_DOWN,
|
||||
|
@ -414,6 +427,13 @@ xkb_action_breaks_latch(const union xkb_action *action)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xkb_filter_mod_latch_new(struct xkb_state *state, struct xkb_filter *filter)
|
||||
{
|
||||
filter->priv = LATCH_KEY_DOWN;
|
||||
state->set_mods = filter->action.mods.mods.mask;
|
||||
}
|
||||
|
||||
static bool
|
||||
xkb_filter_mod_latch_func(struct xkb_state *state,
|
||||
struct xkb_filter *filter,
|
||||
|
@ -445,14 +465,14 @@ xkb_filter_mod_latch_func(struct xkb_state *state,
|
|||
filter->key = key;
|
||||
state->components.latched_mods &= ~filter->action.mods.mods.mask;
|
||||
/* XXX beep beep! */
|
||||
return false;
|
||||
return XKB_FILTER_CONSUME;
|
||||
}
|
||||
else if (xkb_action_breaks_latch(action)) {
|
||||
/* XXX: This may be totally broken, we might need to break the
|
||||
* latch in the next run after this press? */
|
||||
state->components.latched_mods &= ~filter->action.mods.mods.mask;
|
||||
filter->func = NULL;
|
||||
return true;
|
||||
return XKB_FILTER_CONTINUE;
|
||||
}
|
||||
}
|
||||
else if (direction == XKB_KEY_UP && key == filter->key) {
|
||||
|
@ -492,14 +512,7 @@ xkb_filter_mod_latch_func(struct xkb_state *state,
|
|||
|
||||
filter->priv = latch;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
xkb_filter_mod_latch_new(struct xkb_state *state, struct xkb_filter *filter)
|
||||
{
|
||||
filter->priv = LATCH_KEY_DOWN;
|
||||
state->set_mods = filter->action.mods.mods.mask;
|
||||
return XKB_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
|
@ -531,17 +544,19 @@ xkb_filter_apply_all(struct xkb_state *state,
|
|||
{
|
||||
struct xkb_filter *filter;
|
||||
const union xkb_action *action;
|
||||
bool send = true;
|
||||
bool consumed;
|
||||
|
||||
/* First run through all the currently active filters and see if any of
|
||||
* them have claimed this event. */
|
||||
* them have consumed this event. */
|
||||
consumed = false;
|
||||
darray_foreach(filter, state->filters) {
|
||||
if (!filter->func)
|
||||
continue;
|
||||
send = filter->func(state, filter, key, direction) && send;
|
||||
}
|
||||
|
||||
if (!send || direction == XKB_KEY_UP)
|
||||
if (filter->func(state, filter, key, direction) == XKB_FILTER_CONSUME)
|
||||
consumed = true;
|
||||
}
|
||||
if (consumed || direction == XKB_KEY_UP)
|
||||
return;
|
||||
|
||||
action = xkb_key_get_action(state, key);
|
||||
|
@ -560,9 +575,6 @@ xkb_filter_apply_all(struct xkb_state *state,
|
|||
return;
|
||||
|
||||
filter = xkb_filter_new(state);
|
||||
if (!filter)
|
||||
return; /* WSGO */
|
||||
|
||||
filter->key = key;
|
||||
filter->func = filter_action_funcs[action->type].func;
|
||||
filter->action = *action;
|
||||
|
@ -855,7 +867,7 @@ err:
|
|||
}
|
||||
|
||||
/*
|
||||
* http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier
|
||||
* https://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)
|
||||
|
@ -869,7 +881,7 @@ should_do_caps_transformation(struct xkb_state *state, xkb_keycode_t kc)
|
|||
}
|
||||
|
||||
/*
|
||||
* http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier
|
||||
* https://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)
|
||||
|
@ -1133,7 +1145,7 @@ xkb_state_mod_index_is_active(struct xkb_state *state,
|
|||
* Helper function for xkb_state_mod_indices_are_active and
|
||||
* xkb_state_mod_names_are_active.
|
||||
*/
|
||||
static int
|
||||
static bool
|
||||
match_mod_masks(struct xkb_state *state,
|
||||
enum xkb_state_component type,
|
||||
enum xkb_state_match match,
|
||||
|
@ -1142,14 +1154,12 @@ match_mod_masks(struct xkb_state *state,
|
|||
xkb_mod_mask_t active = xkb_state_serialize_mods(state, type);
|
||||
|
||||
if (!(match & XKB_STATE_MATCH_NON_EXCLUSIVE) && (active & ~wanted))
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
if (match & XKB_STATE_MATCH_ANY)
|
||||
return !!(active & wanted);
|
||||
else
|
||||
return (active & wanted) == wanted;
|
||||
return active & wanted;
|
||||
|
||||
return 0;
|
||||
return (active & wanted) == wanted;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1163,14 +1173,13 @@ xkb_state_mod_indices_are_active(struct xkb_state *state,
|
|||
...)
|
||||
{
|
||||
va_list ap;
|
||||
xkb_mod_index_t idx = 0;
|
||||
xkb_mod_mask_t wanted = 0;
|
||||
int ret = 0;
|
||||
xkb_mod_index_t num_mods = xkb_keymap_num_mods(state->keymap);
|
||||
|
||||
va_start(ap, match);
|
||||
while (1) {
|
||||
idx = va_arg(ap, xkb_mod_index_t);
|
||||
xkb_mod_index_t idx = va_arg(ap, xkb_mod_index_t);
|
||||
if (idx == XKB_MOD_INVALID)
|
||||
break;
|
||||
if (idx >= num_mods) {
|
||||
|
@ -1214,12 +1223,12 @@ xkb_state_mod_names_are_active(struct xkb_state *state,
|
|||
...)
|
||||
{
|
||||
va_list ap;
|
||||
xkb_mod_index_t idx = 0;
|
||||
xkb_mod_mask_t wanted = 0;
|
||||
int ret = 0;
|
||||
|
||||
va_start(ap, match);
|
||||
while (1) {
|
||||
xkb_mod_index_t idx;
|
||||
const char *str = va_arg(ap, const char *);
|
||||
if (str == NULL)
|
||||
break;
|
||||
|
@ -1307,13 +1316,20 @@ xkb_state_led_name_is_active(struct xkb_state *state, const char *name)
|
|||
return xkb_state_led_index_is_active(state, idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* See:
|
||||
* - XkbTranslateKeyCode(3), mod_rtrn return value, from libX11.
|
||||
* - MyEnhancedXkbTranslateKeyCode(), a modification of the above, from GTK+.
|
||||
*/
|
||||
static xkb_mod_mask_t
|
||||
key_get_consumed(struct xkb_state *state, const struct xkb_key *key)
|
||||
key_get_consumed(struct xkb_state *state, const struct xkb_key *key,
|
||||
enum xkb_consumed_mode mode)
|
||||
{
|
||||
const struct xkb_key_type *type;
|
||||
const struct xkb_key_type_entry *entry;
|
||||
xkb_mod_mask_t preserve;
|
||||
const struct xkb_key_type_entry *matching_entry;
|
||||
xkb_mod_mask_t preserve = 0;
|
||||
xkb_layout_index_t group;
|
||||
xkb_mod_mask_t consumed = 0;
|
||||
|
||||
group = xkb_state_key_get_layout(state, key->keycode);
|
||||
if (group == XKB_LAYOUT_INVALID)
|
||||
|
@ -1321,47 +1337,64 @@ key_get_consumed(struct xkb_state *state, const struct xkb_key *key)
|
|||
|
||||
type = key->groups[group].type;
|
||||
|
||||
entry = get_entry_for_key_state(state, key, group);
|
||||
if (entry)
|
||||
preserve = entry->preserve.mask;
|
||||
else
|
||||
preserve = 0;
|
||||
matching_entry = get_entry_for_key_state(state, key, group);
|
||||
if (matching_entry)
|
||||
preserve = matching_entry->preserve.mask;
|
||||
|
||||
return type->mods.mask & ~preserve;
|
||||
switch (mode) {
|
||||
case XKB_CONSUMED_MODE_XKB:
|
||||
consumed = type->mods.mask;
|
||||
break;
|
||||
|
||||
case XKB_CONSUMED_MODE_GTK: {
|
||||
const struct xkb_key_type_entry *no_mods_entry;
|
||||
xkb_level_index_t no_mods_leveli;
|
||||
const struct xkb_level *no_mods_level, *level;
|
||||
|
||||
no_mods_entry = get_entry_for_mods(type, 0);
|
||||
no_mods_leveli = no_mods_entry ? no_mods_entry->level : 0;
|
||||
no_mods_level = &key->groups[group].levels[no_mods_leveli];
|
||||
|
||||
for (unsigned i = 0; i < type->num_entries; i++) {
|
||||
const struct xkb_key_type_entry *entry = &type->entries[i];
|
||||
if (!entry_is_active(entry))
|
||||
continue;
|
||||
|
||||
level = &key->groups[group].levels[entry->level];
|
||||
if (XkbLevelsSameSyms(level, no_mods_level))
|
||||
continue;
|
||||
|
||||
if (entry == matching_entry || one_bit_set(entry->mods.mask))
|
||||
consumed |= entry->mods.mask & ~entry->preserve.mask;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed & ~preserve;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see if a modifier is used up by our translation of a
|
||||
* keycode to keysyms, taking note of the current modifier state and
|
||||
* the appropriate key type's preserve information, if any. This allows
|
||||
* the user to mask out the modifier in later processing of the
|
||||
* modifiers, e.g. when implementing hot keys or accelerators.
|
||||
*
|
||||
* See also, for example:
|
||||
* - XkbTranslateKeyCode(3), mod_rtrn return value, from libX11.
|
||||
* - gdk_keymap_translate_keyboard_state, consumed_modifiers return value,
|
||||
* from gtk+.
|
||||
*/
|
||||
XKB_EXPORT int
|
||||
xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t kc,
|
||||
xkb_mod_index_t idx)
|
||||
xkb_state_mod_index_is_consumed2(struct xkb_state *state, xkb_keycode_t kc,
|
||||
xkb_mod_index_t idx,
|
||||
enum xkb_consumed_mode mode)
|
||||
{
|
||||
const struct xkb_key *key = XkbKey(state->keymap, kc);
|
||||
|
||||
if (!key || idx >= xkb_keymap_num_mods(state->keymap))
|
||||
return -1;
|
||||
|
||||
return !!((1u << idx) & key_get_consumed(state, key));
|
||||
return !!((1u << idx) & key_get_consumed(state, key, mode));
|
||||
}
|
||||
|
||||
XKB_EXPORT int
|
||||
xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t kc,
|
||||
xkb_mod_index_t idx)
|
||||
{
|
||||
return xkb_state_mod_index_is_consumed2(state, kc, idx,
|
||||
XKB_CONSUMED_MODE_XKB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates which modifiers should be consumed during key processing,
|
||||
* and returns the mask with all these modifiers removed. e.g. if
|
||||
* given a state of Alt and Shift active for a two-level alphabetic
|
||||
* key containing plus and equal on the first and second level
|
||||
* respectively, will return a mask of only Alt, as Shift has been
|
||||
* consumed by the type handling.
|
||||
*/
|
||||
XKB_EXPORT xkb_mod_mask_t
|
||||
xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t kc,
|
||||
xkb_mod_mask_t mask)
|
||||
|
@ -1371,16 +1404,34 @@ xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t kc,
|
|||
if (!key)
|
||||
return 0;
|
||||
|
||||
return mask & ~key_get_consumed(state, key);
|
||||
return mask & ~key_get_consumed(state, key, XKB_CONSUMED_MODE_XKB);
|
||||
}
|
||||
|
||||
XKB_EXPORT xkb_mod_mask_t
|
||||
xkb_state_key_get_consumed_mods2(struct xkb_state *state, xkb_keycode_t kc,
|
||||
enum xkb_consumed_mode mode)
|
||||
{
|
||||
const struct xkb_key *key;
|
||||
|
||||
switch (mode) {
|
||||
case XKB_CONSUMED_MODE_XKB:
|
||||
case XKB_CONSUMED_MODE_GTK:
|
||||
break;
|
||||
default:
|
||||
log_err_func(state->keymap->ctx,
|
||||
"unrecognized consumed modifiers mode: %d\n", mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
key = XkbKey(state->keymap, kc);
|
||||
if (!key)
|
||||
return 0;
|
||||
|
||||
return key_get_consumed(state, key, mode);
|
||||
}
|
||||
|
||||
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);
|
||||
return xkb_state_key_get_consumed_mods2(state, kc, XKB_CONSUMED_MODE_XKB);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
*
|
||||
********************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "keymap.h"
|
||||
#include "text.h"
|
||||
|
||||
|
@ -204,6 +206,7 @@ const LookupEntry symInterpretMatchMaskNames[] = {
|
|||
{ "AnyOf", MATCH_ANY },
|
||||
{ "AllOf", MATCH_ALL },
|
||||
{ "Exactly", MATCH_EXACTLY },
|
||||
{ NULL, 0 },
|
||||
};
|
||||
|
||||
const char *
|
||||
|
@ -254,7 +257,7 @@ const char *
|
|||
ModMaskText(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
xkb_mod_mask_t mask)
|
||||
{
|
||||
char buf[1024];
|
||||
char buf[1024] = {0};
|
||||
size_t pos = 0;
|
||||
xkb_mod_index_t i;
|
||||
const struct xkb_mod *mod;
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
* Author: Rob Bradford <rob@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <inttypes.h>
|
||||
|
@ -49,17 +51,13 @@ utf32_to_utf8(uint32_t unichar, char *buffer)
|
|||
length = 3;
|
||||
head = 0xe0;
|
||||
}
|
||||
else if (unichar <= 0x1fffff) {
|
||||
else if (unichar <= 0x10ffff) {
|
||||
length = 4;
|
||||
head = 0xf0;
|
||||
}
|
||||
else if (unichar <= 0x3ffffff) {
|
||||
length = 5;
|
||||
head = 0xf8;
|
||||
}
|
||||
else {
|
||||
length = 6;
|
||||
head = 0xfc;
|
||||
buffer[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (count = length - 1, shift = 0; count > 0; count--, shift += 6)
|
||||
|
@ -80,7 +78,7 @@ is_valid_utf8(const char *ss, size_t len)
|
|||
|
||||
/* 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
|
||||
* https://www.unicode.org/versions/Unicode6.2.0/ch03.pdf#G7404
|
||||
* We can optimize if needed. */
|
||||
while (i < len)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright © 2008-2011 Kristian Høgsberg
|
||||
* Copyright © 2011 Intel Corporation
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "util-list.h"
|
||||
|
||||
void
|
||||
list_init(struct list *list)
|
||||
{
|
||||
list->prev = list;
|
||||
list->next = list;
|
||||
}
|
||||
|
||||
void
|
||||
list_insert(struct list *list, struct list *elm)
|
||||
{
|
||||
assert((list->next != NULL && list->prev != NULL) ||
|
||||
!"list->next|prev is NULL, possibly missing list_init()");
|
||||
assert(((elm->next == NULL && elm->prev == NULL) || list_empty(elm)) ||
|
||||
!"elm->next|prev is not NULL, list node used twice?");
|
||||
|
||||
elm->prev = list;
|
||||
elm->next = list->next;
|
||||
list->next = elm;
|
||||
elm->next->prev = elm;
|
||||
}
|
||||
|
||||
void
|
||||
list_append(struct list *list, struct list *elm)
|
||||
{
|
||||
assert((list->next != NULL && list->prev != NULL) ||
|
||||
!"list->next|prev is NULL, possibly missing list_init()");
|
||||
assert(((elm->next == NULL && elm->prev == NULL) || list_empty(elm)) ||
|
||||
!"elm->next|prev is not NULL, list node used twice?");
|
||||
|
||||
elm->next = list;
|
||||
elm->prev = list->prev;
|
||||
list->prev = elm;
|
||||
elm->prev->next = elm;
|
||||
}
|
||||
|
||||
void
|
||||
list_remove(struct list *elm)
|
||||
{
|
||||
assert((elm->next != NULL && elm->prev != NULL) ||
|
||||
!"list->next|prev is NULL, possibly missing list_init()");
|
||||
|
||||
elm->prev->next = elm->next;
|
||||
elm->next->prev = elm->prev;
|
||||
elm->next = NULL;
|
||||
elm->prev = NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
list_empty(const struct list *list)
|
||||
{
|
||||
assert((list->next != NULL && list->prev != NULL) ||
|
||||
!"list->next|prev is NULL, possibly missing list_init()");
|
||||
|
||||
return list->next == list;
|
||||
}
|
||||
|
||||
bool
|
||||
list_is_last(const struct list *list, const struct list *elm)
|
||||
{
|
||||
return elm->next == list;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright © 2008-2011 Kristian Høgsberg
|
||||
* Copyright © 2011 Intel Corporation
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/*
|
||||
* This list data structure is a verbatim copy from wayland-util.h from the
|
||||
* Wayland project; except that wl_ prefix has been removed.
|
||||
*/
|
||||
|
||||
struct list {
|
||||
struct list *prev;
|
||||
struct list *next;
|
||||
};
|
||||
|
||||
void list_init(struct list *list);
|
||||
void list_insert(struct list *list, struct list *elm);
|
||||
void list_append(struct list *list, struct list *elm);
|
||||
void list_remove(struct list *elm);
|
||||
bool list_empty(const struct list *list);
|
||||
bool list_is_last(const struct list *list, const struct list *elm);
|
||||
|
||||
#define container_of(ptr, type, member) \
|
||||
(__typeof__(type) *)((char *)(ptr) - \
|
||||
offsetof(__typeof__(type), member))
|
||||
|
||||
#define list_first_entry(head, pos, member) \
|
||||
container_of((head)->next, __typeof__(*pos), member)
|
||||
|
||||
#define list_last_entry(head, pos, member) \
|
||||
container_of((head)->prev, __typeof__(*pos), member)
|
||||
|
||||
#define list_for_each(pos, head, member) \
|
||||
for (pos = 0, pos = list_first_entry(head, pos, member); \
|
||||
&pos->member != (head); \
|
||||
pos = list_first_entry(&pos->member, pos, member))
|
||||
|
||||
#define list_for_each_safe(pos, tmp, head, member) \
|
||||
for (pos = 0, tmp = 0, \
|
||||
pos = list_first_entry(head, pos, member), \
|
||||
tmp = list_first_entry(&pos->member, tmp, member); \
|
||||
&pos->member != (head); \
|
||||
pos = tmp, \
|
||||
tmp = list_first_entry(&pos->member, tmp, member))
|
|
@ -21,6 +21,8 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
|
@ -32,13 +34,16 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
bool
|
||||
map_file(FILE *file, const char **string_out, size_t *size_out)
|
||||
map_file(FILE *file, char **string_out, size_t *size_out)
|
||||
{
|
||||
struct stat stat_buf;
|
||||
const int fd = fileno(file);
|
||||
int fd;
|
||||
char *string;
|
||||
|
||||
/* Make sure to keep the errno on failure! */
|
||||
fd = fileno(file);
|
||||
if (fd < 0)
|
||||
return false;
|
||||
|
||||
if (fstat(fd, &stat_buf) != 0)
|
||||
return false;
|
||||
|
@ -53,15 +58,15 @@ map_file(FILE *file, const char **string_out, size_t *size_out)
|
|||
}
|
||||
|
||||
void
|
||||
unmap_file(const char *str, size_t size)
|
||||
unmap_file(char *str, size_t size)
|
||||
{
|
||||
munmap(UNCONSTIFY(str), size);
|
||||
munmap(str, size);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool
|
||||
map_file(FILE *file, const char **string_out, size_t *size_out)
|
||||
map_file(FILE *file, char **string_out, size_t *size_out)
|
||||
{
|
||||
long ret;
|
||||
size_t ret_s;
|
||||
|
@ -99,9 +104,107 @@ map_file(FILE *file, const char **string_out, size_t *size_out)
|
|||
}
|
||||
|
||||
void
|
||||
unmap_file(const char *str, size_t size)
|
||||
unmap_file(char *str, size_t size)
|
||||
{
|
||||
free(UNCONSTIFY(str));
|
||||
free(str);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ASCII lower-case map.
|
||||
static const unsigned char lower_map[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
|
||||
59, 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
|
||||
108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
|
||||
91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
|
||||
108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
|
||||
123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137,
|
||||
138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152,
|
||||
153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
|
||||
168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182,
|
||||
183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
|
||||
198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,
|
||||
213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
|
||||
228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
|
||||
243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
|
||||
};
|
||||
|
||||
// ASCII tolower (to avoid locale issues).
|
||||
char
|
||||
to_lower(char c)
|
||||
{
|
||||
return (char) lower_map[(unsigned char) c];
|
||||
}
|
||||
|
||||
// ASCII strcasecmp (to avoid locale issues).
|
||||
int
|
||||
istrcmp(const char *a, const char *b)
|
||||
{
|
||||
for (size_t i = 0; ; i++) {
|
||||
if (to_lower(a[i]) != to_lower(b[i]))
|
||||
return (int) to_lower(a[i]) - (int) to_lower(b[i]);
|
||||
if (!a[i])
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ASCII strncasecmp (to avoid locale issues).
|
||||
int
|
||||
istrncmp(const char *a, const char *b, size_t n)
|
||||
{
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (to_lower(a[i]) != to_lower(b[i]))
|
||||
return (int) to_lower(a[i]) - (int) to_lower(b[i]);
|
||||
if (!a[i])
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !(defined(HAVE_ASPRINTF) && HAVE_ASPRINTF)
|
||||
int
|
||||
asprintf(char **strp, const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
ret = vasprintf(strp, fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
# if !(defined(HAVE_VASPRINTF) && HAVE_VASPRINTF)
|
||||
int
|
||||
vasprintf(char **strp, const char *fmt, va_list ap)
|
||||
{
|
||||
int ret;
|
||||
char *buf;
|
||||
va_list ap_copy;
|
||||
|
||||
/*
|
||||
* The value of the va_list parameter is undefined after the call to
|
||||
* vsnprintf() returns: pass a copy to make sure "ap" remains valid.
|
||||
*/
|
||||
va_copy(ap_copy, ap);
|
||||
ret = vsnprintf(NULL, 0, fmt, ap_copy);
|
||||
va_end(ap_copy);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!(buf = malloc(ret + 1)))
|
||||
return -1;
|
||||
|
||||
if ((ret = vsnprintf(buf, ret + 1, fmt, ap)) < 0) {
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*strp = buf;
|
||||
return ret;
|
||||
}
|
||||
# endif /* !HAVE_VASPRINTF */
|
||||
#endif /* !HAVE_ASPRINTF */
|
||||
|
|
|
@ -26,30 +26,58 @@
|
|||
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#else
|
||||
/* Required on Windows where unistd.h doesn't exist */
|
||||
#define R_OK 4 /* Test for read permission. */
|
||||
#define W_OK 2 /* Test for write permission. */
|
||||
#define X_OK 1 /* Test for execute permission. */
|
||||
#define F_OK 0 /* Test for existence. */
|
||||
#endif
|
||||
|
||||
#include "darray.h"
|
||||
|
||||
/*
|
||||
* We sometimes malloc strings and then expose them as const char*'s. This
|
||||
* macro is used when we free these strings in order to avoid -Wcast-qual
|
||||
* errors.
|
||||
*/
|
||||
#define UNCONSTIFY(const_ptr) ((void *) (uintptr_t) (const_ptr))
|
||||
|
||||
#define STATIC_ASSERT(expr, message) do { \
|
||||
switch (0) { case 0: case (expr): ; } \
|
||||
} while (0)
|
||||
|
||||
#define ARRAY_SIZE(arr) ((sizeof(arr) / sizeof(*(arr))))
|
||||
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
/* Round up @a so it's divisible by @b. */
|
||||
#define ROUNDUP(a, b) (((a) + (b) - 1) / (b) * (b))
|
||||
|
||||
char
|
||||
to_lower(char c);
|
||||
|
||||
int
|
||||
istrcmp(const char *a, const char *b);
|
||||
|
||||
int
|
||||
istrncmp(const char *a, const char *b, size_t n);
|
||||
|
||||
static inline bool
|
||||
streq(const char *s1, const char *s2)
|
||||
{
|
||||
assert(s1 && s2);
|
||||
return strcmp(s1, s2) == 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
streq_null(const char *s1, const char *s2)
|
||||
{
|
||||
if (s1 == NULL || s2 == NULL)
|
||||
return s1 == s2;
|
||||
return streq(s1, s2);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
streq_not_null(const char *s1, const char *s2)
|
||||
{
|
||||
|
@ -61,13 +89,13 @@ streq_not_null(const char *s1, const char *s2)
|
|||
static inline bool
|
||||
istreq(const char *s1, const char *s2)
|
||||
{
|
||||
return strcasecmp(s1, s2) == 0;
|
||||
return istrcmp(s1, s2) == 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
istreq_prefix(const char *s1, const char *s2)
|
||||
{
|
||||
return strncasecmp(s1, s2, strlen(s1)) == 0;
|
||||
return istrncmp(s1, s2, strlen(s1)) == 0;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
|
@ -108,18 +136,22 @@ memdup(const void *mem, size_t nmemb, size_t size)
|
|||
memcpy(p, mem, nmemb * size);
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline int
|
||||
min(int misc, int other)
|
||||
#ifndef ANDROID
|
||||
#if !(defined(HAVE_STRNDUP) && HAVE_STRNDUP)
|
||||
static inline char *
|
||||
strndup(const char *s, size_t n)
|
||||
{
|
||||
return (misc < other) ? misc : other;
|
||||
}
|
||||
|
||||
static inline int
|
||||
max(int misc, int other)
|
||||
{
|
||||
return (misc > other) ? misc : other;
|
||||
size_t slen = strlen(s);
|
||||
size_t len = MIN(slen, n);
|
||||
char *p = malloc(len + 1);
|
||||
if (!p)
|
||||
return NULL;
|
||||
memcpy(p, s, len);
|
||||
p[len] = '\0';
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ctype.h is locale-dependent and has other oddities. */
|
||||
static inline bool
|
||||
|
@ -178,21 +210,31 @@ msb_pos(uint32_t mask)
|
|||
return pos;
|
||||
}
|
||||
|
||||
static inline int
|
||||
one_bit_set(uint32_t x)
|
||||
{
|
||||
return x && (x & (x - 1)) == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
map_file(FILE *file, const char **string_out, size_t *size_out);
|
||||
map_file(FILE *file, char **string_out, size_t *size_out);
|
||||
|
||||
void
|
||||
unmap_file(const char *str, size_t size);
|
||||
unmap_file(char *string, size_t size);
|
||||
|
||||
#define ARRAY_SIZE(arr) ((sizeof(arr) / sizeof(*(arr))))
|
||||
static inline bool
|
||||
check_eaccess(const char *path, int mode)
|
||||
{
|
||||
#if defined(HAVE_EACCESS)
|
||||
if (eaccess(path, mode) != 0)
|
||||
return false;
|
||||
#elif defined(HAVE_EUIDACCESS)
|
||||
if (euidaccess(path, mode) != 0)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define MIN3(a, b, c) MIN(MIN((a), (b)), (c))
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MAX3(a, b, c) MAX(MAX((a), (b)), (c))
|
||||
|
||||
/* Round up @a so it's divisible by @b. */
|
||||
#define ROUNDUP(a, b) (((a) + (b) - 1) / (b) * (b))
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(HAVE_SECURE_GETENV)
|
||||
# define secure_getenv secure_getenv
|
||||
|
@ -251,4 +293,58 @@ unmap_file(const char *str, size_t size);
|
|||
#define ATTR_PACKED
|
||||
#endif
|
||||
|
||||
#if !(defined(HAVE_ASPRINTF) && HAVE_ASPRINTF)
|
||||
int asprintf(char **strp, const char *fmt, ...) ATTR_PRINTF(2, 3);
|
||||
# if !(defined(HAVE_VASPRINTF) && HAVE_VASPRINTF)
|
||||
# include <stdarg.h>
|
||||
int vasprintf(char **strp, const char *fmt, va_list ap);
|
||||
# endif /* !HAVE_VASPRINTF */
|
||||
#endif /* !HAVE_ASPRINTF */
|
||||
|
||||
static inline bool
|
||||
ATTR_PRINTF(3, 4)
|
||||
snprintf_safe(char *buf, size_t sz, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int rc;
|
||||
|
||||
va_start(ap, format);
|
||||
rc = vsnprintf(buf, sz, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return rc >= 0 && (size_t)rc < sz;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
ATTR_PRINTF(1, 0)
|
||||
vasprintf_safe(const char *fmt, va_list args)
|
||||
{
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
len = vasprintf(&str, fmt, args);
|
||||
|
||||
if (len == -1)
|
||||
return NULL;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* A version of asprintf that returns the allocated string or NULL on error.
|
||||
*/
|
||||
static inline char *
|
||||
ATTR_PRINTF(1, 2)
|
||||
asprintf_safe(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *str;
|
||||
|
||||
va_start(args, fmt);
|
||||
str = vasprintf_safe(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
#endif /* UTILS_H */
|
||||
|
|
|
@ -21,12 +21,14 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "x11-priv.h"
|
||||
|
||||
/*
|
||||
* References for the lonesome traveler:
|
||||
* Xkb protocol specification:
|
||||
* http://www.x.org/releases/current/doc/kbproto/xkbproto.html
|
||||
* https://www.x.org/releases/current/doc/kbproto/xkbproto.html
|
||||
* The XCB xkb XML protocol file:
|
||||
* /user/share/xcb/xkb.xml
|
||||
* The XCB xkb header file:
|
||||
|
@ -86,6 +88,33 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
static const xcb_xkb_map_part_t get_map_required_components =
|
||||
(XCB_XKB_MAP_PART_KEY_TYPES |
|
||||
XCB_XKB_MAP_PART_KEY_SYMS |
|
||||
XCB_XKB_MAP_PART_MODIFIER_MAP |
|
||||
XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS |
|
||||
XCB_XKB_MAP_PART_KEY_ACTIONS |
|
||||
XCB_XKB_MAP_PART_VIRTUAL_MODS |
|
||||
XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP);
|
||||
|
||||
static const xcb_xkb_name_detail_t get_names_wanted =
|
||||
(XCB_XKB_NAME_DETAIL_KEYCODES |
|
||||
XCB_XKB_NAME_DETAIL_SYMBOLS |
|
||||
XCB_XKB_NAME_DETAIL_TYPES |
|
||||
XCB_XKB_NAME_DETAIL_COMPAT |
|
||||
XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES |
|
||||
XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES |
|
||||
XCB_XKB_NAME_DETAIL_INDICATOR_NAMES |
|
||||
XCB_XKB_NAME_DETAIL_KEY_NAMES |
|
||||
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 get_names_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);
|
||||
|
||||
|
||||
static xkb_mod_mask_t
|
||||
translate_mods(uint8_t rmods, uint16_t vmods_low, uint16_t vmods_high)
|
||||
|
@ -218,8 +247,8 @@ translate_action(union xkb_action *action, const xcb_xkb_action_t *wire)
|
|||
case XCB_XKB_SA_TYPE_MOVE_PTR:
|
||||
action->type = ACTION_TYPE_PTR_MOVE;
|
||||
|
||||
action->ptr.x = (wire->moveptr.xLow | (wire->moveptr.xHigh << 8));
|
||||
action->ptr.y = (wire->moveptr.yLow | (wire->moveptr.yHigh << 8));
|
||||
action->ptr.x = (int16_t) (wire->moveptr.xLow | ((uint16_t) wire->moveptr.xHigh << 8));
|
||||
action->ptr.y = (int16_t) (wire->moveptr.yLow | ((uint16_t) wire->moveptr.yHigh << 8));
|
||||
|
||||
if (!(wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_NO_ACCELERATION))
|
||||
action->ptr.flags |= ACTION_ACCEL;
|
||||
|
@ -443,18 +472,19 @@ get_sym_maps(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
|||
|
||||
FAIL_UNLESS((unsigned) syms_length == wire_sym_map->width * key->num_groups);
|
||||
|
||||
for (int j = 0; j < syms_length; j++) {
|
||||
xcb_keysym_t wire_keysym = *syms_iter;
|
||||
const xkb_layout_index_t group = j / wire_sym_map->width;
|
||||
const xkb_level_index_t level = j % wire_sym_map->width;
|
||||
for (xkb_layout_index_t group = 0; group < key->num_groups; group++) {
|
||||
for (xkb_level_index_t level = 0; level < wire_sym_map->width; level++) {
|
||||
xcb_keysym_t wire_keysym = *syms_iter;
|
||||
|
||||
if (level < key->groups[group].type->num_levels &&
|
||||
wire_keysym != XKB_KEY_NoSymbol) {
|
||||
key->groups[group].levels[level].num_syms = 1;
|
||||
key->groups[group].levels[level].u.sym = wire_keysym;
|
||||
assert(key->groups[group].type != NULL);
|
||||
if (level < key->groups[group].type->num_levels &&
|
||||
wire_keysym != XKB_KEY_NoSymbol) {
|
||||
key->groups[group].levels[level].num_syms = 1;
|
||||
key->groups[group].levels[level].u.sym = wire_keysym;
|
||||
}
|
||||
|
||||
syms_iter++;
|
||||
}
|
||||
|
||||
syms_iter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,21 +519,23 @@ get_actions(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
|||
uint8_t wire_count = *acts_count_iter;
|
||||
struct xkb_key *key = &keymap->keys[reply->firstKeyAction + i];
|
||||
|
||||
FAIL_UNLESS((unsigned) syms_length == wire_sym_map->width * key->num_groups);
|
||||
FAIL_UNLESS(wire_count == 0 || wire_count == syms_length);
|
||||
|
||||
for (int j = 0; j < wire_count; j++) {
|
||||
xcb_xkb_action_t *wire_action = acts_iter.data;
|
||||
const xkb_layout_index_t group = j / wire_sym_map->width;
|
||||
const xkb_level_index_t level = j % wire_sym_map->width;
|
||||
if (wire_count != 0) {
|
||||
for (xkb_layout_index_t group = 0; group < key->num_groups; group++) {
|
||||
for (xkb_level_index_t level = 0; level < wire_sym_map->width; level++) {
|
||||
xcb_xkb_action_t *wire_action = acts_iter.data;
|
||||
|
||||
if (level < key->groups[group].type->num_levels) {
|
||||
union xkb_action *action =
|
||||
&key->groups[group].levels[level].action;
|
||||
if (level < key->groups[group].type->num_levels) {
|
||||
union xkb_action *action = &key->groups[group].levels[level].action;
|
||||
|
||||
translate_action(action, wire_action);
|
||||
translate_action(action, wire_action);
|
||||
}
|
||||
|
||||
xcb_xkb_action_next(&acts_iter);
|
||||
}
|
||||
}
|
||||
|
||||
xcb_xkb_action_next(&acts_iter);
|
||||
}
|
||||
|
||||
acts_count_iter++;
|
||||
|
@ -640,26 +672,15 @@ fail:
|
|||
}
|
||||
|
||||
static bool
|
||||
get_map(struct xkb_keymap *keymap, xcb_connection_t *conn, uint16_t device_id)
|
||||
get_map(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
||||
xcb_xkb_get_map_cookie_t cookie)
|
||||
{
|
||||
static const xcb_xkb_map_part_t required_components =
|
||||
(XCB_XKB_MAP_PART_KEY_TYPES |
|
||||
XCB_XKB_MAP_PART_KEY_SYMS |
|
||||
XCB_XKB_MAP_PART_MODIFIER_MAP |
|
||||
XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS |
|
||||
XCB_XKB_MAP_PART_KEY_ACTIONS |
|
||||
XCB_XKB_MAP_PART_VIRTUAL_MODS |
|
||||
XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP);
|
||||
|
||||
xcb_xkb_get_map_cookie_t cookie =
|
||||
xcb_xkb_get_map(conn, device_id, required_components,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
xcb_xkb_get_map_reply_t *reply = xcb_xkb_get_map_reply(conn, cookie, NULL);
|
||||
xcb_xkb_get_map_map_t map;
|
||||
|
||||
FAIL_IF_BAD_REPLY(reply, "XkbGetMap");
|
||||
|
||||
if ((reply->present & required_components) != required_components)
|
||||
if ((reply->present & get_map_required_components) != get_map_required_components)
|
||||
goto fail;
|
||||
|
||||
xcb_xkb_get_map_map_unpack(xcb_xkb_get_map_map(reply),
|
||||
|
@ -744,10 +765,8 @@ get_indicators(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
|||
|
||||
static bool
|
||||
get_indicator_map(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
||||
uint16_t device_id)
|
||||
xcb_xkb_get_indicator_map_cookie_t cookie)
|
||||
{
|
||||
xcb_xkb_get_indicator_map_cookie_t cookie =
|
||||
xcb_xkb_get_indicator_map(conn, device_id, ALL_INDICATORS_MASK);
|
||||
xcb_xkb_get_indicator_map_reply_t *reply =
|
||||
xcb_xkb_get_indicator_map_reply(conn, cookie, NULL);
|
||||
|
||||
|
@ -826,10 +845,8 @@ fail:
|
|||
|
||||
static bool
|
||||
get_compat_map(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
||||
uint16_t device_id)
|
||||
xcb_xkb_get_compat_map_cookie_t cookie)
|
||||
{
|
||||
xcb_xkb_get_compat_map_cookie_t cookie =
|
||||
xcb_xkb_get_compat_map(conn, device_id, 0, true, 0, 0);
|
||||
xcb_xkb_get_compat_map_reply_t *reply =
|
||||
xcb_xkb_get_compat_map_reply(conn, cookie, NULL);
|
||||
|
||||
|
@ -847,7 +864,7 @@ fail:
|
|||
}
|
||||
|
||||
static bool
|
||||
get_type_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
||||
get_type_names(struct xkb_keymap *keymap, struct x11_atom_interner *interner,
|
||||
xcb_xkb_get_names_reply_t *reply,
|
||||
xcb_xkb_get_names_value_list_t *list)
|
||||
{
|
||||
|
@ -875,14 +892,13 @@ get_type_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
|||
|
||||
ALLOC_OR_FAIL(type->level_names, type->num_levels);
|
||||
|
||||
if (!adopt_atom(keymap->ctx, conn, wire_type_name, &type->name))
|
||||
goto fail;
|
||||
|
||||
if (!adopt_atoms(keymap->ctx, conn,
|
||||
kt_level_names_iter, type->level_names,
|
||||
wire_num_levels))
|
||||
goto fail;
|
||||
x11_atom_interner_adopt_atom(interner, wire_type_name, &type->name);
|
||||
for (size_t j = 0; j < wire_num_levels; j++) {
|
||||
x11_atom_interner_adopt_atom(interner, kt_level_names_iter[j],
|
||||
&type->level_names[j]);
|
||||
}
|
||||
|
||||
type->num_level_names = type->num_levels;
|
||||
kt_level_names_iter += wire_num_levels;
|
||||
key_type_names_iter++;
|
||||
n_levels_per_type_iter++;
|
||||
|
@ -895,7 +911,8 @@ fail:
|
|||
}
|
||||
|
||||
static bool
|
||||
get_indicator_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
||||
get_indicator_names(struct xkb_keymap *keymap,
|
||||
struct x11_atom_interner *interner,
|
||||
xcb_xkb_get_names_reply_t *reply,
|
||||
xcb_xkb_get_names_value_list_t *list)
|
||||
{
|
||||
|
@ -908,8 +925,7 @@ get_indicator_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
|||
xcb_atom_t wire = *iter;
|
||||
struct xkb_led *led = &keymap->leds[i];
|
||||
|
||||
if (!adopt_atom(keymap->ctx, conn, wire, &led->name))
|
||||
return false;
|
||||
x11_atom_interner_adopt_atom(interner, wire, &led->name);
|
||||
|
||||
iter++;
|
||||
}
|
||||
|
@ -922,7 +938,7 @@ fail:
|
|||
}
|
||||
|
||||
static bool
|
||||
get_vmod_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
||||
get_vmod_names(struct xkb_keymap *keymap, struct x11_atom_interner *interner,
|
||||
xcb_xkb_get_names_reply_t *reply,
|
||||
xcb_xkb_get_names_value_list_t *list)
|
||||
{
|
||||
|
@ -941,8 +957,7 @@ get_vmod_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
|||
xcb_atom_t wire = *iter;
|
||||
struct xkb_mod *mod = &keymap->mods.mods[NUM_REAL_MODS + i];
|
||||
|
||||
if (!adopt_atom(keymap->ctx, conn, wire, &mod->name))
|
||||
return false;
|
||||
x11_atom_interner_adopt_atom(interner, wire, &mod->name);
|
||||
|
||||
iter++;
|
||||
}
|
||||
|
@ -952,7 +967,7 @@ get_vmod_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
|||
}
|
||||
|
||||
static bool
|
||||
get_group_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
||||
get_group_names(struct xkb_keymap *keymap, struct x11_atom_interner *interner,
|
||||
xcb_xkb_get_names_reply_t *reply,
|
||||
xcb_xkb_get_names_value_list_t *list)
|
||||
{
|
||||
|
@ -962,9 +977,10 @@ get_group_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
|||
keymap->num_group_names = msb_pos(reply->groupNames);
|
||||
ALLOC_OR_FAIL(keymap->group_names, keymap->num_group_names);
|
||||
|
||||
if (!adopt_atoms(keymap->ctx, conn,
|
||||
iter, keymap->group_names, length))
|
||||
goto fail;
|
||||
for (int i = 0; i < length; i++) {
|
||||
x11_atom_interner_adopt_atom(interner, iter[i],
|
||||
&keymap->group_names[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -1045,36 +1061,17 @@ fail:
|
|||
}
|
||||
|
||||
static bool
|
||||
get_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
||||
uint16_t device_id)
|
||||
get_names(struct xkb_keymap *keymap, struct x11_atom_interner *interner,
|
||||
xcb_xkb_get_names_cookie_t cookie)
|
||||
{
|
||||
static const xcb_xkb_name_detail_t wanted =
|
||||
(XCB_XKB_NAME_DETAIL_KEYCODES |
|
||||
XCB_XKB_NAME_DETAIL_SYMBOLS |
|
||||
XCB_XKB_NAME_DETAIL_TYPES |
|
||||
XCB_XKB_NAME_DETAIL_COMPAT |
|
||||
XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES |
|
||||
XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES |
|
||||
XCB_XKB_NAME_DETAIL_INDICATOR_NAMES |
|
||||
XCB_XKB_NAME_DETAIL_KEY_NAMES |
|
||||
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, wanted);
|
||||
xcb_connection_t *conn = interner->conn;
|
||||
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");
|
||||
|
||||
FAIL_UNLESS((reply->which & required) == required);
|
||||
FAIL_UNLESS((reply->which & get_names_required) == get_names_required);
|
||||
|
||||
xcb_xkb_get_names_value_list_unpack(xcb_xkb_get_names_value_list(reply),
|
||||
reply->nTypes,
|
||||
|
@ -1087,23 +1084,22 @@ get_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
|||
reply->which,
|
||||
&list);
|
||||
|
||||
if (!get_atom_name(conn, list.keycodesName, &keymap->keycodes_section_name) ||
|
||||
!get_atom_name(conn, list.symbolsName, &keymap->symbols_section_name) ||
|
||||
!get_atom_name(conn, list.typesName, &keymap->types_section_name) ||
|
||||
!get_atom_name(conn, list.compatName, &keymap->compat_section_name) ||
|
||||
!get_type_names(keymap, conn, reply, &list) ||
|
||||
!get_indicator_names(keymap, conn, reply, &list) ||
|
||||
!get_vmod_names(keymap, conn, reply, &list) ||
|
||||
!get_group_names(keymap, conn, reply, &list) ||
|
||||
x11_atom_interner_get_escaped_atom_name(interner, list.keycodesName,
|
||||
&keymap->keycodes_section_name);
|
||||
x11_atom_interner_get_escaped_atom_name(interner, list.symbolsName,
|
||||
&keymap->symbols_section_name);
|
||||
x11_atom_interner_get_escaped_atom_name(interner, list.typesName,
|
||||
&keymap->types_section_name);
|
||||
x11_atom_interner_get_escaped_atom_name(interner, list.compatName,
|
||||
&keymap->compat_section_name);
|
||||
if (!get_type_names(keymap, interner, reply, &list) ||
|
||||
!get_indicator_names(keymap, interner, reply, &list) ||
|
||||
!get_vmod_names(keymap, interner, reply, &list) ||
|
||||
!get_group_names(keymap, interner, reply, &list) ||
|
||||
!get_key_names(keymap, conn, reply, &list) ||
|
||||
!get_aliases(keymap, conn, reply, &list))
|
||||
goto fail;
|
||||
|
||||
XkbEscapeMapName(keymap->keycodes_section_name);
|
||||
XkbEscapeMapName(keymap->symbols_section_name);
|
||||
XkbEscapeMapName(keymap->types_section_name);
|
||||
XkbEscapeMapName(keymap->compat_section_name);
|
||||
|
||||
free(reply);
|
||||
return true;
|
||||
|
||||
|
@ -1114,10 +1110,8 @@ fail:
|
|||
|
||||
static bool
|
||||
get_controls(struct xkb_keymap *keymap, xcb_connection_t *conn,
|
||||
uint16_t device_id)
|
||||
xcb_xkb_get_controls_cookie_t cookie)
|
||||
{
|
||||
xcb_xkb_get_controls_cookie_t cookie =
|
||||
xcb_xkb_get_controls(conn, device_id);
|
||||
xcb_xkb_get_controls_reply_t *reply =
|
||||
xcb_xkb_get_controls_reply(conn, cookie, NULL);
|
||||
|
||||
|
@ -1154,7 +1148,7 @@ xkb_x11_keymap_new_from_device(struct xkb_context *ctx,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (device_id < 0 || device_id > 255) {
|
||||
if (device_id < 0 || device_id > 127) {
|
||||
log_err_func(ctx, "illegal device ID: %d\n", device_id);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1163,11 +1157,31 @@ xkb_x11_keymap_new_from_device(struct xkb_context *ctx,
|
|||
if (!keymap)
|
||||
return NULL;
|
||||
|
||||
if (!get_map(keymap, conn, device_id) ||
|
||||
!get_indicator_map(keymap, conn, device_id) ||
|
||||
!get_compat_map(keymap, conn, device_id) ||
|
||||
!get_names(keymap, conn, device_id) ||
|
||||
!get_controls(keymap, conn, device_id)) {
|
||||
struct x11_atom_interner interner;
|
||||
x11_atom_interner_init(&interner, ctx, conn);
|
||||
|
||||
xcb_xkb_get_map_cookie_t get_map_cookie =
|
||||
xcb_xkb_get_map(conn, device_id, get_map_required_components,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
xcb_xkb_get_indicator_map_cookie_t indicator_map_cookie =
|
||||
xcb_xkb_get_indicator_map(conn, device_id, ALL_INDICATORS_MASK);
|
||||
xcb_xkb_get_compat_map_cookie_t compat_map_cookie =
|
||||
xcb_xkb_get_compat_map(conn, device_id, 0, true, 0, 0);
|
||||
xcb_xkb_get_names_cookie_t get_names_cookie =
|
||||
xcb_xkb_get_names(conn, device_id, get_names_wanted);
|
||||
xcb_xkb_get_controls_cookie_t get_controls_cookie =
|
||||
xcb_xkb_get_controls(conn, device_id);
|
||||
|
||||
bool had_error = false;
|
||||
had_error |= !get_map(keymap, conn, get_map_cookie);
|
||||
had_error |= !get_indicator_map(keymap, conn, indicator_map_cookie);
|
||||
had_error |= !get_compat_map(keymap, conn, compat_map_cookie);
|
||||
had_error |= !get_names(keymap, &interner, get_names_cookie);
|
||||
had_error |= !get_controls(keymap, conn, get_controls_cookie);
|
||||
|
||||
x11_atom_interner_round_trip(&interner);
|
||||
had_error |= interner.had_error;
|
||||
if (had_error) {
|
||||
xkb_keymap_unref(keymap);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "x11-priv.h"
|
||||
|
||||
static bool
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue