summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stone <daniel@fooishbar.org>2012-03-27 16:59:01 +0100
committerDaniel Stone <daniel@fooishbar.org>2012-03-27 16:59:01 +0100
commit3e9dd7512c16dd752830d9fd56d9f4cba76ee7d3 (patch)
treea96f8de74a8e07260a291ab2ec2052487b3e5c8f
parentf0cb4ee2191b097cb44370a37259b39e54f23e00 (diff)
downloadxorg-lib-libxkbcommon-3e9dd7512c16dd752830d9fd56d9f4cba76ee7d3.tar.gz
Add new context API
Signed-off-by: Daniel Stone <daniel@fooishbar.org>
-rw-r--r--Makefile.am1
-rw-r--r--configure.ac3
-rw-r--r--include/xkbcommon/xkbcommon.h74
-rw-r--r--src/context.c198
-rw-r--r--test/.gitignore1
-rw-r--r--test/Makefile.am2
-rw-r--r--test/context.c47
-rwxr-xr-xtest/context.sh13
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