diff options
author | Daniel Stone <daniel@fooishbar.org> | 2012-03-27 16:59:01 +0100 |
---|---|---|
committer | Daniel Stone <daniel@fooishbar.org> | 2012-03-27 16:59:01 +0100 |
commit | 3e9dd7512c16dd752830d9fd56d9f4cba76ee7d3 (patch) | |
tree | a96f8de74a8e07260a291ab2ec2052487b3e5c8f | |
parent | f0cb4ee2191b097cb44370a37259b39e54f23e00 (diff) | |
download | xorg-lib-libxkbcommon-3e9dd7512c16dd752830d9fd56d9f4cba76ee7d3.tar.gz |
Add new context API
Signed-off-by: Daniel Stone <daniel@fooishbar.org>
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | include/xkbcommon/xkbcommon.h | 74 | ||||
-rw-r--r-- | src/context.c | 198 | ||||
-rw-r--r-- | test/.gitignore | 1 | ||||
-rw-r--r-- | test/Makefile.am | 2 | ||||
-rw-r--r-- | test/context.c | 47 | ||||
-rwxr-xr-x | test/context.sh | 13 |
8 files changed, 337 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am index 2bc6a35..6f37998 100644 --- a/Makefile.am +++ b/Makefile.am @@ -63,6 +63,7 @@ libxkbcommon_la_SOURCES = \ src/xkbcomp/xkbscan.l \ src/alloc.c \ src/atom.c \ + src/context.c \ src/keysym.c \ src/malloc.c \ src/map.c \ diff --git a/configure.ac b/configure.ac index 3a4519a..d149c21 100644 --- a/configure.ac +++ b/configure.ac @@ -42,6 +42,9 @@ XORG_MACROS_VERSION(1.8) XORG_DEFAULT_OPTIONS XORG_CHECK_MALLOC_ZERO +# Get _GNU_SOURCE and friends +AC_USE_SYSTEM_EXTENSIONS + # Check for programs AC_PROG_LEX AC_PROG_YACC diff --git a/include/xkbcommon/xkbcommon.h b/include/xkbcommon/xkbcommon.h index b823890..e15dbac 100644 --- a/include/xkbcommon/xkbcommon.h +++ b/include/xkbcommon/xkbcommon.h @@ -135,7 +135,19 @@ struct xkb_component_names { }; /** - * Opaque state object, may only be created, accessed, manipulated and + * Opaque context object; may only be created, accessed, manipulated and + * destroyed through the xkb_context_*() API. + */ +struct xkb_context; + +/** + * Opaque keymap object; may only be created, accessed, manipulated and + * destroyed through the xkb_state_*() API. + */ +struct xkb_desc; + +/** + * Opaque state object; may only be created, accessed, manipulated and * destroyed through the xkb_state_*() API. */ struct xkb_state; @@ -179,6 +191,66 @@ xkb_key_get_syms(struct xkb_state *state, xkb_keycode_t key, xkb_keysym_t **syms_out); /** + * @defgroup ctx XKB contexts + * Every keymap compilation request must have an XKB context associated with + * it. The context keeps around state such as the include path. + * + * @{ + */ + +/** + * Returns a new XKB context, or NULL on failure. If successful, the caller + * holds a reference on the context, and must free it when finished with + * xkb_context_unref(). + */ +_X_EXPORT struct xkb_context * +xkb_context_new(void); + +/** + * Appends a new entry to the include path used for keymap compilation. + * Returns 1 on success, or 0 if the include path could not be added or is + * inaccessible. + */ +_X_EXPORT int +xkb_context_include_path_append(struct xkb_context *context, const char *path); + +/** + * Appends the default include paths to the context's current include path. + * Returns 1 on success, or 0 if the primary include path could not be + * added. + */ +_X_EXPORT int +xkb_context_include_path_append_default(struct xkb_context *context); + +/** + * Removes all entries from the context's include path, and inserts the + * default paths. Returns 1 on success, or 0 if the primary include path + * could not be added. + */ +_X_EXPORT int +xkb_context_include_path_reset(struct xkb_context *context); + +/** + * Removes all entries from the context's include path. + */ +_X_EXPORT void +xkb_context_include_path_clear(struct xkb_context *context); + +/** + * Takes a new reference on an XKB context. + */ +_X_EXPORT void +xkb_context_ref(struct xkb_context *context); + +/** + * Releases a reference on an XKB context, and possibly frees it. + */ +_X_EXPORT void +xkb_context_unref(struct xkb_context *context); + +/** @} */ + +/** * @defgroup map Keymap management * These utility functions allow you to create and deallocate XKB keymaps. * diff --git a/src/context.c b/src/context.c new file mode 100644 index 0000000..20f8c79 --- /dev/null +++ b/src/context.c @@ -0,0 +1,198 @@ +/* + * Copyright © 2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Daniel Stone <daniel@fooishbar.org> + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <unistd.h> + +#include "xkbcommon/xkbcommon.h" +#include "XKBcommonint.h" +#include "utils.h" + +struct xkb_context { + int refcnt; + char **include_paths; + int num_include_paths; + int size_include_paths; +}; + +/** + * Append one directory to the context's include path. + */ +int +xkb_context_include_path_append(struct xkb_context *context, const char *path) +{ + struct stat stat_buf; + int err; + + if (context->size_include_paths <= context->num_include_paths) { + int new_size; + char **new_paths; + new_size = context->size_include_paths + 2; + new_paths = uTypedRecalloc(context->include_paths, + context->size_include_paths, + new_size, + typeof(new_paths)); + if (!new_paths) + return 0; + context->include_paths = new_paths; + context->size_include_paths = new_size; + } + + err = stat(path, &stat_buf); + if (err != 0) + return 0; + if (!S_ISDIR(stat_buf.st_mode)) + return 0; + if (eaccess(path, R_OK | X_OK) != 0) + return 0; + + context->include_paths[context->num_include_paths] = strdup(path); + if (!context->include_paths[context->num_include_paths]) + return 0; + context->num_include_paths++; + + return 1; +} + +/** + * Append the default include directories to the context. + */ +int +xkb_context_include_path_append_default(struct xkb_context *context) +{ + const char *home = getenv("HOME"); + char *user_path; + int err; + + (void) xkb_context_include_path_append(context, DFLT_XKB_CONFIG_ROOT); + + home = getenv("HOME"); + if (!home) + return 1; + err = asprintf(&user_path, "%s/.xkb", home); + if (err <= 0) + return 1; + (void) xkb_context_include_path_append(context, user_path); + + return 1; +} + +/** + * Remove all entries in the context's include path. + */ +void +xkb_context_include_path_clear(struct xkb_context *context) +{ + int i; + + for (i = 0; i < context->num_include_paths; i++) { + free(context->include_paths[i]); + context->include_paths[i] = NULL; + } + context->num_include_paths = 0; +} + +/** + * xkb_context_include_path_clear() + xkb_context_include_path_append_default() + */ +int +xkb_context_include_path_reset_defaults(struct xkb_context *context) +{ + xkb_context_include_path_clear(context); + return xkb_context_include_path_append_default(context); +} + +/** + * Returns the number of entries in the context's include path. + */ +unsigned int +xkb_context_include_path_num_entries(struct xkb_context *context) +{ + return context->size_include_paths; +} + +/** + * Returns the given entry in the context's include path, or NULL if an + * invalid index is passed. + */ +const char * +xkb_context_include_path_get_entry(struct xkb_context *context, + unsigned int index) +{ + if (index >= xkb_context_include_path_num_entries(context)) + return NULL; + + return context->include_paths[index]; +} + +/** + * Take a new reference on the context. + */ +void +xkb_context_ref(struct xkb_context *context) +{ + context->refcnt++; +} + +/** + * Drop an existing reference on the context, and free it if the refcnt is + * now 0. + */ +void +xkb_context_unref(struct xkb_context *context) +{ + if (--context->refcnt > 0) + return; + + xkb_context_include_path_clear(context); + free(context); +} + +/** + * Create a new context. + */ +struct xkb_context * +xkb_context_new(void) +{ + struct xkb_context *context = calloc(1, sizeof(*context)); + + if (!context) + return NULL; + + context->refcnt = 1; + + if (!xkb_context_include_path_append_default(context)) { + xkb_context_unref(context); + return NULL; + } + + return context; +} diff --git a/test/.gitignore b/test/.gitignore index eaf2cc6..e0e6667 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -5,3 +5,4 @@ namescomp rulescomp xkey state +context diff --git a/test/Makefile.am b/test/Makefile.am index fb4e3e6..9a43e42 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,7 +4,7 @@ LDADD = $(top_builddir)/libxkbcommon.la TESTS_ENVIRONMENT = $(SHELL) -check_PROGRAMS = xkey filecomp namescomp rulescomp canonicalise state +check_PROGRAMS = xkey filecomp namescomp rulescomp canonicalise state context TESTS = $(check_PROGRAMS:=.sh) EXTRA_DIST = \ diff --git a/test/context.c b/test/context.c new file mode 100644 index 0000000..1ed965e --- /dev/null +++ b/test/context.c @@ -0,0 +1,47 @@ +/* + * Copyright © 2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Daniel Stone <daniel@fooishbar.org> + */ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <X11/keysym.h> +#include <linux/input.h> +#include "xkbcommon/xkbcommon.h" +#include "utils.h" +#include "XKBcommonint.h" + +int +main(int argc, char *argv[]) +{ + struct xkb_context *context = xkb_context_new(); + + assert(context); + + /* FIXME: Test include path stuff. */ + + xkb_context_unref(context); + + return 0; +} diff --git a/test/context.sh b/test/context.sh new file mode 100755 index 0000000..730e5a5 --- /dev/null +++ b/test/context.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +srcdir=${srcdir-.} +builddir=${builddir-.} + +name=context +prog="$builddir/$name$EXEEXT" +log="$builddir/$name.log" + +rm -f "$log" +srcdir=${srcdir-.} +builddir=${builddir-.} +$builddir/$name$EXEEXT >> $log 2>&1 |