libxkbcommon: Changes to 'upstream-unstable'
.autom4te.cfg | 3
.gitignore | 1
Makefile.am | 76
NEWS | 86
README | 47
configure.ac | 45
doc/Doxyfile.in | 142
makekeys.py | 44
src/atom.c | 137
src/atom.h | 7
src/context-priv.c | 171
src/context.c | 179
src/context.h | 62
src/keymap-priv.c | 121
src/keymap.c | 83
src/keymap.h | 25
src/keysym-utf.c | 13
src/keysym.c | 56
src/keysym.h | 6
src/ks_tables.h |11765 +++++++++++++++++++++--------------
src/state.c | 20
src/text.c | 8
src/utils.h | 75
src/x11/keymap.c | 1146 +++
src/x11/state.c | 71
src/x11/util.c | 215
src/x11/x11-priv.h | 44
src/xkbcomp/action.c | 91
src/xkbcomp/ast-build.c | 318
src/xkbcomp/ast-build.h | 58
src/xkbcomp/ast.h | 124
src/xkbcomp/compat.c | 61
src/xkbcomp/expr.c | 170
src/xkbcomp/include.c | 36
src/xkbcomp/keycodes.c | 29
src/xkbcomp/keymap-dump.c | 19
src/xkbcomp/keymap.c | 30
src/xkbcomp/keywords.c | 2
src/xkbcomp/keywords.gperf | 2
src/xkbcomp/parser-priv.h | 7
src/xkbcomp/parser.y | 191
src/xkbcomp/rules.c | 123
src/xkbcomp/scanner-utils.h | 11
src/xkbcomp/scanner.c | 68
src/xkbcomp/symbols.c | 122
src/xkbcomp/types.c | 13
src/xkbcomp/xkbcomp-priv.h | 3
test/.gitignore | 5
test/atom.c | 181
test/common.c | 154
test/context.c | 9
test/data/keycodes/empty | 4
test/data/keycodes/evdev-xkbcommon | 1
test/data/keymaps/divide-by-zero.xkb | 6
test/data/keymaps/quartz.xkb | 1139 +++
test/data/rules/base | 13
test/data/rules/evdev | 15
test/data/rules/groups | 5
test/data/symbols/altwin | 8
test/data/symbols/ch | 225
test/data/symbols/compose | 35
test/data/symbols/cz | 184
test/data/symbols/de | 78
test/data/symbols/empty | 4
test/data/symbols/inet | 2
test/data/symbols/level3 | 4
test/data/symbols/level5 | 4
test/data/symbols/ru | 21
test/data/symbols/us | 61
test/data/sync.sh | 4
test/filecomp.c | 1
test/interactive-evdev.c | 114
test/interactive-x11.c | 367 +
test/keyseq.c | 55
test/keysym.c | 13
test/rulescomp.c | 10
test/state.c | 114
test/stringcomp.c | 7
test/test.h | 11
test/x11.c | 78
xkbcommon-x11-uninstalled.pc.in | 10
xkbcommon-x11.pc.in | 12
xkbcommon/xkbcommon-keysyms.h | 8
xkbcommon/xkbcommon-names.h | 1
xkbcommon/xkbcommon-x11.h | 166
xkbcommon/xkbcommon.h | 147
86 files changed, 13287 insertions(+), 6115 deletions(-)
New commits:
commit be16858c927b0d3023dd20fc35fa0919711a72c7
Author: Ran Benita <ran234@gmail.com>
Date: Sun Feb 2 12:13:26 2014 +0200
Bump version to 0.4.0
Signed-off-by: Ran Benita <ran234@gmail.com>
diff --git a/configure.ac b/configure.ac
index 2466021..ff03b76 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@ dnl Process this file with autoconf to create configure.
# Initialize Autoconf
AC_PREREQ([2.62])
-AC_INIT([libxkbcommon], [0.3.2],
+AC_INIT([libxkbcommon], [0.4.0],
[https://bugs.freedesktop.org/enter_bug.cgi?product=libxkbcommon],
[libxkbcommon], [http://xkbcommon.org])
AC_CONFIG_SRCDIR([Makefile.am])
commit a15b4a55350173292b39748ed859299ba2761f1f
Author: Ran Benita <ran234@gmail.com>
Date: Sun Feb 2 12:08:43 2014 +0200
Update README
- Remove outdated information about API/ABI stability. If we ever break
API or ABI, we'll do a major release. But currently everything is
stable.
- Remove outdated warnings about internal symbols. You simply cannot
access them...
- Briefly mention xkbcommon-x11 existence.
- Update git and bug URLs.
- Add myself as maintainer :)
Signed-off-by: Ran Benita <ran234@gmail.com>
diff --git a/README b/README
index fa8e94c..6b99c46 100644
--- a/README
+++ b/README
@@ -25,27 +25,17 @@ API
While xkbcommon's API is somewhat derived from the classic XKB API as found
in <X11/extensions/XKB.h> and friends, it has been substantially reworked to
-expose fewer internal details to clients. The only supported API is available
-in <xkbcommon/xkbcommon.h>. Any definition not in this header (including
-accessing internal structures through the old macros previously available)
-should be regarded as an implementation detail and is liable to change at any
-time.
+expose fewer internal details to clients. The supported API is available
+in the <xkbcommon/xkbcommon-*.h> files. Additional support is provided for
+X11 (XCB) clients, in the xkbcommon-x11 library, <xkbcommon/xkbcommon-x11.h>.
-During its early development, xkbcommon does not promise API or ABI stability.
-Regardless, we will attempt to not break ABI during a minor release series,
-so applications written against 0.1.0 should be completely compatible with
-0.1.3, but not necessarily with 0.2.0. However, new symbols may be introduced
-in any release. Thus, anyone packaging xkbcommon should make sure any package
-depending on it depends on a release greater than or equal to the version it
-was built against (or earlier, if it doesn't use any newly-introduced
-symbols), but less than the next major release.
-
-xkbcommon 1.x will offer full API and ABI stability for its lifetime, with a
-soname of libxkbcommon.so.1. Any ABI breaks will wait until xkbcommon 2.0,
-which will be libxkbcommon.so.2.
-
-The xkbcomp command-line tool has also been removed, although this will
-likely reappear in a later release.
+The xkbcommon API and ABI are stable. We will attempt to not break ABI during
+a minor release series, so applications written against 0.1.0 should be
+completely compatible with 0.5.3, but not necessarily with 1.0.0. However, new
+symbols may be introduced in any release. Thus, anyone packaging xkbcommon
+should make sure any package depending on it depends on a release greater than
+or equal to the version it was built against (or earlier, if it doesn't use
+any newly-introduced symbols), but less than the next major release.
Relation to X11
@@ -101,19 +91,24 @@ Development
An extremely rudimentary homepage can be found at:
http://xkbcommon.org
-xkbcommon is maintained in git at freedesktop.org:
- git://anongit.freedesktop.org/git/libxkbcommon
+xkbcommon is maintained in git at github.com:
+ https://github.com/xkbcommon/libxkbcommon
Patches are always welcome, and may be sent to either xorg-devel@lists.x.org,
-or wayland-devel@lists.freedesktop.org. Bugs are tracked in Bugzilla at:
- http://bugs.freedesktop.org
+or wayland-devel@lists.freedesktop.org.
+
+Bugs are tracked in Bugzilla at:
+ https://bugs.freedesktop.org/describecomponents.cgi?product=libxkbcommon
+Or in github at:
+ https://github.com/xkbcommon/libxkbcommon/issues
-The maintainer is Daniel Stone, who can be reached at:
+The maintainers are Daniel Stone and Ran Benita, who can be reached at:
<daniel@fooishbar.org>
+ <ran234@gmail.com>
Credits
=======
Many thanks are due to Dan Nicholson for his heroic work in getting xkbcommon
-off the ground initially, as well as to Ran Benita for subsequent development.
+off the ground initially.
commit 87e0e47462f54545ee97ada8d156f1f16cc51bd0
Author: Ran Benita <ran234@gmail.com>
Date: Sun Feb 2 12:05:35 2014 +0200
Update NEWS
Signed-off-by: Ran Benita <ran234@gmail.com>
diff --git a/NEWS b/NEWS
index 93aae00..450b753 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,32 @@
-libxkbcommon 0.3.2
+libxkbcommon 0.4.0
==================
-- Added XKB_KEY_XF86AudioMicMute keysym, to match xproto 7.0.24.
+- Add a new add-on library, xkbcommon-x11, to support creating keymaps
+ with the XKB X11 protocol, by querying the X server directly.
+ See the xkbcommon/xkbcommon-x11.h header file for more details.
+ This library requires libxcb-xkb >= 1.10, and is enabled by default.
+ It can be disabled with the --disable-x11 configure switch.
+ Distributions are encouraged to split the necessary files for this
+ library (libxkbcommon-x11.so, xkbcommon-x11.pc, xkbcommon/xkbcommon-x11.h)
+ to a separate package, such that the main package does not depend on
+ X11 libraries.
+
+- Fix the keysym <-> name lookup table to not require huge amounts of
+ relocations.
+
+- Fix a bug in the keysym <-> name lookup, whereby lookup might fail in
+ some rare cases.
+
+- Reduce memory usage during keymap compilation.
+
+- New API:
+ New keysyms from xproto 7.0.25 (German T3 layout keysyms).
+ XKB_MOD_NAME_NUM for the usual NumLock modifier.
+ xkb_x11_* types and functions, XKB_X11_* constants.
+
+
+libxkbcommon 0.3.2
+==================
- Log messages from the library now look like "xkbcommon: ERROR" by
default, instead of xkbcomp-like "Error: ".
@@ -14,6 +39,7 @@ libxkbcommon 0.3.2
- Support byacc for generating the parser, in addition to Bison.
- New API:
+ XKB_KEY_XF86AudioMicMute keysym from xproto 7.0.24.
XKB_KEYSYM_NO_FLAGS
XKB_CONTEXT_NO_FLAGS
XKB_MAP_COMPILE_NO_FLAGS
commit 70717c5686f0f916bb9a23cbdfc79c8ff1f727da
Author: Ran Benita <ran234@gmail.com>
Date: Sun Feb 2 11:13:28 2014 +0200
build: add configure summary
Signed-off-by: Ran Benita <ran234@gmail.com>
diff --git a/configure.ac b/configure.ac
index 9f5afa0..2466021 100644
--- a/configure.ac
+++ b/configure.ac
@@ -163,3 +163,22 @@ AC_CONFIG_FILES([
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}
+])
commit 2f93c78894ba180cc5ba602bf1b03961173db7b8
Author: Ran Benita <ran234@gmail.com>
Date: Tue Jul 30 15:06:40 2013 +0300
x11: add a couple of tests
Add two tests:
./test/interactive-x11
which is like test/interactive-evdev, but should behave exactly like your
X keyboard and react to state and keymap changes - in other words, just
like typing in xterm. Press ESC to exit.
./test/x11
which currently should only print out the same keymap as
xkbcomp $DISPLAY out.xkb
(modulo some whitespace and some constructs we do not support.)
Signed-off-by: Ran Benita <ran234@gmail.com>
diff --git a/Makefile.am b/Makefile.am
index 5fc982b..c4d3352 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -201,6 +201,21 @@ check_PROGRAMS += \
endif BUILD_LINUX_TESTS
+if ENABLE_X11
+TESTS += \
+ test/x11
+TESTS_X11_LDADD = $(TESTS_LDADD) $(XCB_XKB_LIBS) libxkbcommon-x11.la
+TESTS_X11_CFLAGS = $(XCB_XKB_CFLAGS)
+
+test_x11_LDADD = $(TESTS_X11_LDADD)
+test_x11_CFLAGS = $(TESTS_X11_CFLAGS)
+test_interactive_x11_LDADD = $(TESTS_X11_LDADD)
+test_interactive_x11_CFLAGS = $(TESTS_X11_CFLAGS)
+
+check_PROGRAMS += \
+ test/interactive-x11
+endif ENABLE_X11
+
EXTRA_DIST += \
test/data
diff --git a/test/.gitignore b/test/.gitignore
index eacfcc7..e4b7758 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -15,3 +15,5 @@ rmlvo-to-kccgst
print-compiled-keymap
bench-key-proc
atom
+x11
+interactive-x11
diff --git a/test/interactive-x11.c b/test/interactive-x11.c
new file mode 100644
index 0000000..843b4d2
--- /dev/null
+++ b/test/interactive-x11.c
@@ -0,0 +1,367 @@
+/*
+ * Copyright © 2013 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 <locale.h>
+
+#include "xkbcommon/xkbcommon-x11.h"
+#include "test.h"
+
+#include <xcb/xkb.h>
+
+/*
+ * Note: This program only handles the core keyboard device for now.
+ * It should be straigtforward to change struct keyboard to a list of
+ * keyboards with device IDs, as in test/interactive-evdev.c. This would
+ * require:
+ *
+ * - Initially listing the keyboard devices.
+ * - Listening to device changes.
+ * - Matching events to their devices.
+ *
+ * XKB itself knows about xinput1 devices, and most requests and events are
+ * device-specific.
+ *
+ * In order to list the devices and react to changes, you need xinput1/2.
+ * You also need xinput for the key press/release event, since the core
+ * protocol key press event does not carry a device ID to match on.
+ */
+
+struct keyboard {
+ xcb_connection_t *conn;
+ uint8_t first_xkb_event;
+ struct xkb_context *ctx;
+
+ struct xkb_keymap *keymap;
+ struct xkb_state *state;
+ int32_t device_id;
+};
+
+static bool terminate;
+
+static int
+select_xkb_events_for_device(xcb_connection_t *conn, int32_t device_id)
+{
+ static const xcb_xkb_map_part_t required_map_parts =
+ (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_event_type_t required_events =
+ (XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY |
+ XCB_XKB_EVENT_TYPE_MAP_NOTIFY |
+ XCB_XKB_EVENT_TYPE_STATE_NOTIFY);
+
+ xcb_void_cookie_t cookie =
+ xcb_xkb_select_events_checked(conn,
+ device_id,
+ required_events,
+ 0,
+ required_events,
+ required_map_parts,
+ required_map_parts,
+ 0);
+
+ xcb_generic_error_t *error = xcb_request_check(conn, cookie);
+ if (error) {
+ free(error);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+update_keymap(struct keyboard *kbd)
+{
+ struct xkb_keymap *new_keymap;
+ struct xkb_state *new_state;
+
+ new_keymap = xkb_x11_keymap_new_from_device(kbd->ctx, kbd->conn,
+ kbd->device_id, 0);
+ if (!new_keymap)
+ goto err_out;
+
+ new_state = xkb_x11_state_new_from_device(new_keymap, kbd->conn,
+ kbd->device_id);
+ if (!new_state)
+ goto err_keymap;
+
+ if (kbd->keymap)
+ printf("Keymap updated!\n");
+
+ xkb_state_unref(kbd->state);
+ xkb_keymap_unref(kbd->keymap);
+ kbd->keymap = new_keymap;
+ kbd->state = new_state;
+ return 0;
+
+err_keymap:
+ xkb_keymap_unref(new_keymap);
+err_out:
+ return -1;
+}
+
+static int
+init_kbd(struct keyboard *kbd, xcb_connection_t *conn, uint8_t first_xkb_event,
+ int32_t device_id, struct xkb_context *ctx)
+{
+ int ret;
+
+ kbd->conn = conn;
+ kbd->first_xkb_event = first_xkb_event;
+ kbd->ctx = ctx;
+ kbd->keymap = NULL;
+ kbd->state = NULL;
+ kbd->device_id = device_id;
+
+ ret = update_keymap(kbd);
+ if (ret)
+ goto err_out;
+
+ ret = select_xkb_events_for_device(conn, device_id);
+ if (ret)
+ goto err_state;
+
+ return 0;
+
+err_state:
+ xkb_state_unref(kbd->state);
+ xkb_keymap_unref(kbd->keymap);
+err_out:
+ return -1;
+}
+
+static void
+deinit_kbd(struct keyboard *kbd)
+{
+ xkb_state_unref(kbd->state);
+ xkb_keymap_unref(kbd->keymap);
+}
+
+static void
+process_xkb_event(xcb_generic_event_t *gevent, struct keyboard *kbd)
+{
+ union xkb_event {
+ struct {
+ uint8_t response_type;
+ uint8_t xkbType;
+ uint16_t sequence;
+ xcb_timestamp_t time;
+ uint8_t deviceID;
+ } any;
+ xcb_xkb_new_keyboard_notify_event_t new_keyboard_notify;
+ xcb_xkb_map_notify_event_t map_notify;
+ xcb_xkb_state_notify_event_t state_notify;
+ } *event = (union xkb_event *) gevent;
+
+ if (event->any.deviceID != kbd->device_id)
+ return;
+
+ /*
+ * XkbNewKkdNotify and XkbMapNotify together capture all sorts of keymap
+ * updates (e.g. xmodmap, xkbcomp, setxkbmap), with minimal redundent
+ * recompilations.
+ */
+ switch (event->any.xkbType) {
+ case XCB_XKB_NEW_KEYBOARD_NOTIFY:
+ if (event->new_keyboard_notify.changed & XCB_XKB_NKN_DETAIL_KEYCODES)
+ update_keymap(kbd);
+ break;
+
+ case XCB_XKB_MAP_NOTIFY:
+ update_keymap(kbd);
+ break;
+
+ case XCB_XKB_STATE_NOTIFY:
+ xkb_state_update_mask(kbd->state,
+ event->state_notify.baseMods,
+ event->state_notify.latchedMods,
+ event->state_notify.lockedMods,
+ event->state_notify.baseGroup,
+ event->state_notify.latchedGroup,
+ event->state_notify.lockedGroup);
+ break;
+ }
+}
+
+static void
+process_event(xcb_generic_event_t *gevent, struct keyboard *kbd)
+{
+ switch (gevent->response_type) {
+ case XCB_KEY_PRESS: {
+ xcb_key_press_event_t *event = (xcb_key_press_event_t *) gevent;
+ xkb_keycode_t keycode = event->detail;
+
+ test_print_keycode_state(kbd->state, keycode);
+
+ /* Exit on ESC. */
+ if (keycode == 9)
+ terminate = true;
+ break;
+ }
+ default:
+ if (gevent->response_type == kbd->first_xkb_event)
+ process_xkb_event(gevent, kbd);
+ break;
+ }
+}
+
+static int
+loop(xcb_connection_t *conn, struct keyboard *kbd)
+{
+ while (!terminate) {
+ xcb_generic_event_t *event;
+
+ switch (xcb_connection_has_error(conn)) {
+ case 0:
+ break;
+ case XCB_CONN_ERROR:
+ fprintf(stderr,
+ "Closed connection to X server: connection error\n");
+ return -1;
+ case XCB_CONN_CLOSED_EXT_NOTSUPPORTED:
+ fprintf(stderr,
+ "Closed connection to X server: extension not supported\n");
+ return -1;
+ default:
+ fprintf(stderr,
+ "Closed connection to X server: error code %d\n",
+ xcb_connection_has_error(conn));
+ return -1;
+ }
+
+ event = xcb_wait_for_event(conn);
+ process_event(event, kbd);
+ free(event);
+ }
+
+ return 0;
+}
+
+static int
+create_capture_window(xcb_connection_t *conn)
+{
+ xcb_generic_error_t *error;
+ xcb_void_cookie_t cookie;
+ xcb_screen_t *screen =
+ xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
+ xcb_window_t window = xcb_generate_id(conn);
+ uint32_t values[2] = {
+ screen->white_pixel,
+ XCB_EVENT_MASK_KEY_PRESS,
+ };
+
+ cookie = xcb_create_window_checked(conn, XCB_COPY_FROM_PARENT,
+ window, screen->root,
+ 10, 10, 100, 100, 1,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ screen->root_visual,
+ XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK,
+ values);
+ if ((error = xcb_request_check(conn, cookie)) != NULL) {
+ free(error);
+ return -1;
+ }
+
+ cookie = xcb_map_window_checked(conn, window);
+ if ((error = xcb_request_check(conn, cookie)) != NULL) {
+ free(error);
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ret;
+ xcb_connection_t *conn;
+ uint8_t first_xkb_event;
+ int32_t core_kbd_device_id;
+ struct xkb_context *ctx;
+ struct keyboard core_kbd;
+
+ setlocale(LC_ALL, "");
+
+ 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, &first_xkb_event, NULL);
+ if (!ret) {
+ fprintf(stderr, "Couldn't setup XKB extension\n");
+ goto err_conn;
+ }
+
+ ctx = test_get_context(0);
+ if (!ctx) {
+ ret = -1;
+ fprintf(stderr, "Couldn't create xkb context\n");
+ goto err_conn;
+ }
+
+ core_kbd_device_id = xkb_x11_get_core_keyboard_device_id(conn);
+ if (core_kbd_device_id == -1) {
+ ret = -1;
+ fprintf(stderr, "Couldn't find core keyboard device\n");
+ goto err_ctx;
+ }
+
+ ret = init_kbd(&core_kbd, conn, first_xkb_event, core_kbd_device_id, ctx);
+ if (ret) {
+ fprintf(stderr, "Couldn't initialize core keyboard device\n");
+ goto err_ctx;
+ }
+
+ ret = create_capture_window(conn);
+ if (ret) {
+ fprintf(stderr, "Couldn't create a capture window\n");
+ goto err_core_kbd;
+ }
+
+ system("stty -echo");
+ ret = loop(conn, &core_kbd);
+ system("stty echo");
+
+err_core_kbd:
+ deinit_kbd(&core_kbd);
+err_ctx:
+ xkb_context_unref(ctx);
+err_conn:
+ xcb_disconnect(conn);
+err_out:
+ exit(ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
diff --git a/test/test.h b/test/test.h
index ec0b16d..d0104ce 100644
--- a/test/test.h
+++ b/test/test.h
@@ -30,6 +30,9 @@
#include "xkbcommon/xkbcommon.h"
#include "utils.h"
+/* Automake test exit code to signify SKIP (à la PASS, FAIL, etc). */
+#define SKIP_TEST 77
+
/* The offset between KEY_* numbering, and keycodes in the XKB evdev
* dataset. */
#define EVDEV_OFFSET 8
diff --git a/test/x11.c b/test/x11.c
new file mode 100644
index 0000000..f16dded
--- /dev/null
+++ b/test/x11.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2013 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 "test.h"
+#include "xkbcommon/xkbcommon-x11.h"
+
+int
+main(void)
+{
+ struct xkb_context *ctx = test_get_context(0);
+ xcb_connection_t *conn;
+ int ret;
+ int32_t device_id;
+ struct xkb_keymap *keymap;
+ struct xkb_state *state;
+ char *dump;
+
+ /*
+ * The next two steps depend on a running X server with XKB support.
+ * If it fails, it's not necessarily an actual problem with the code.
+ * So we don't want a FAIL here.
+ */
+ conn = xcb_connect(NULL, NULL);
+ if (!conn || xcb_connection_has_error(conn))
+ return SKIP_TEST;
+
+ 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)
+ return SKIP_TEST;
+
+ device_id = xkb_x11_get_core_keyboard_device_id(conn);
+ assert(device_id != -1);
+
+ keymap = xkb_x11_keymap_new_from_device(ctx, conn, device_id,
+ XKB_MAP_COMPILE_NO_FLAGS);
+ assert(keymap);
+
+ state = xkb_x11_state_new_from_device(keymap, conn, device_id);
+ assert(state);
+
+ dump = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_USE_ORIGINAL_FORMAT);
+ assert(dump);
+ fputs(dump, stdout);
+
+ /* TODO: Write some X11-specific tests. */
+
+ free(dump);
+ xkb_state_unref(state);
+ xkb_keymap_unref(keymap);
+ xcb_disconnect(conn);
+ xkb_context_unref(ctx);
+
+ return 0;
+}
commit eb34825560edf570d883d3e52a8fe657c17b3d9c
Author: Ran Benita <ran234@gmail.com>
Date: Sat Jul 20 23:21:44 2013 +0300
x11: add XKB protocol keymap and state creation support
These are function to create an xkb_keymap directly from XKB requests
to the X server. This opens up the possibility for X clients to use
xcb + xcb-xkb + xkbcommon as a proper replacement for Xlib + xkbfile for
keyboard support.
The X11 support must be enabled with --enable-x11 for now.
The functions are in xkbcommon/xkbcommon-x11.h. It depends on a recent
libxcb with xkb enabled. The functions are in a new libxkbcommon-x11.so,
with a new pkg-config file, etc. so that the packages may be split, and
libxkbcommon.so itself remains dependency-free.
Why not just use the RMLVO that the server puts in the _XKB_RULES_NAMES
property? This does not account for custom keymaps, on-the-fly keymap
modifications, remote clients, etc., so is not a proper solution in
practice. Also, some servers don't even set it. Now, the client just
needs to recreate the keymap in response to a change in the server's
keymap (as Xlib clients do with XRefreshKeyboardMapping() and friends).
Signed-off-by: Ran Benita <ran234@gmail.com>
diff --git a/Makefile.am b/Makefile.am
index 3168b55..5fc982b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -78,6 +78,33 @@ libxkbcommon_la_SOURCES = \
src/utils.c \
src/utils.h
+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_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
diff --git a/configure.ac b/configure.ac
index b8e242e..9f5afa0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -143,10 +143,23 @@ if ! test "x$DEFAULT_XKB_OPTIONS" = x; then
[Default XKB options])
fi
+AC_ARG_ENABLE([x11],
+ [AS_HELP_STRING([--disable-x11],
+ [Disable support for creating keymaps with the X11 protocol (default: enabled)])],
+ [], [enable_x11=yes])
+if test "x$enable_x11" == xyes; then
+ 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.])])
+fi
+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
diff --git a/src/utils.h b/src/utils.h
index 04fb9c5..81d1cc9 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -158,6 +158,22 @@ is_graph(char ch)
return ch >= '!' && ch <= '~';
}
+/*
+ * Return the bit position of the most significant bit.
+ * Note: this is 1-based! It's more useful this way, and returns 0 when
+ * mask is all 0s.
+ */
+static inline int
+msb_pos(uint32_t mask)
+{
+ int pos = 0;
+ while (mask) {
+ pos++;
+ mask >>= 1;
+ }
+ return pos;
+}
+
bool
map_file(FILE *file, const char **string_out, size_t *size_out);
diff --git a/src/x11/keymap.c b/src/x11/keymap.c
new file mode 100644
index 0000000..968f187
--- /dev/null
+++ b/src/x11/keymap.c
@@ -0,0 +1,1146 @@
+/*
+ * Copyright © 2013 Ran Benita
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "x11-priv.h"
+
+/*
+ * References for the lonesome traveler:
+ * Xkb protocol specification:
+ * http://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:
+ * /usr/include/xcb/xkb.h
+ * The old kbproto header files:
+ * /usr/include/X11/extensions/XKB{,proto,str}.h
+ * Xlib XKB source code:
+ * <libX11>/src/xkb/XKBGetMap.c (and friends)
+ * X server XKB protocol handling:
+ * <xserver>/xkb/xkb.c
+ * Man pages:
+ * XkbGetMap(3), XkbGetCompatMap(3), etc.
+ */
+
+/* Constants from /usr/include/X11/extensions/XKB.h */
+/* XkbNumModifiers. */
+#define NUM_REAL_MODS 8
+/* XkbNumVirtualMods. */
+#define NUM_VMODS 16
+/* XkbNoModifier. */
Reply to: