Rename keymap allocation API
authorDaniel Stone <daniel@fooishbar.org>
Thu, 22 Mar 2012 17:39:12 +0000 (17:39 +0000)
committerDaniel Stone <daniel@fooishbar.org>
Thu, 22 Mar 2012 17:39:12 +0000 (17:39 +0000)
Signed-off-by: Daniel Stone <daniel@fooishbar.org>
include/xkbcommon/xkbcommon.h
src/alloc.c
src/state.c
src/xkbcomp/keymap.c
src/xkbcomp/xkbcomp.c
test/filecomp.c
test/filecomp.sh
test/named.xkb [deleted file]
test/namescomp.c
test/rulescomp.c
test/state.c

index fe72a74..18441c0 100644 (file)
@@ -358,6 +358,7 @@ struct xkb_controls {
 
 /* Common keyboard description structure */
 struct xkb_desc {
+    unsigned int        refcnt;
     unsigned int        defined;
     unsigned short      flags;
     unsigned short      device_spec;
@@ -518,21 +519,6 @@ struct xkb_state {
 
 _XFUNCPROTOBEGIN
 
-_X_EXPORT extern struct xkb_desc *
-xkb_compile_keymap_from_rules(const struct xkb_rule_names *rules);
-
-_X_EXPORT extern struct xkb_desc *
-xkb_compile_keymap_from_components(const struct xkb_component_names * ktcsg);
-
-_X_EXPORT extern struct xkb_desc *
-xkb_compile_keymap_from_file(FILE *inputFile, const char *mapName);
-
-_X_EXPORT extern struct xkb_desc *
-xkb_compile_keymap_from_string(const char *string, const char *mapName);
-
-_X_EXPORT extern void
-xkb_free_keymap(struct xkb_desc *xkb);
-
 /*
  * Canonicalises component names by prepending the relevant component from
  * 'old' to the one in 'names' when the latter has a leading '+' or '|', and
@@ -570,6 +556,69 @@ xkb_key_get_syms(struct xkb_state *state, xkb_keycode_t key,
                  xkb_keysym_t **syms_out);
 
 /**
+ * @defgroup map Keymap management
+ * These utility functions allow you to create and deallocate XKB keymaps.
+ *
+ * @{
+ */
+
+/**
+ * The primary keymap entry point: creates a new XKB keymap from a set of
+ * RMLVO (Rules + Model + Layout + Variant + Option) names.
+ *
+ * You should almost certainly be using this and nothing else to create
+ * keymaps.
+ */
+_X_EXPORT extern struct xkb_desc *
+xkb_map_new_from_names(const struct xkb_rule_names *names);
+
+/**
+ * Deprecated entrypoint for legacy users who need to be able to compile
+ * XKB keymaps by KcCGST (Keycodes + Compat + Geometry + Symbols + Types)
+ * names.
+ *
+ * You should not use this unless you are the X server.  This entrypoint
+ * may well disappear in future releases.  Please, please, don't use it.
+ *
+ * Geometry will be ignored since xkbcommon does not support it in any way.
+ */
+_X_EXPORT extern struct xkb_desc *
+xkb_map_new_from_kccgst(const struct xkb_component_names *kccgst);
+
+enum xkb_keymap_format {
+    /** The current/classic XKB text format, as generated by xkbcomp -xkb. */
+    XKB_KEYMAP_FORMAT_TEXT_V1 = 1,
+};
+
+/**
+ * Creates an XKB keymap from a full text XKB keymap passed into the
+ * file descriptor.
+ */
+_X_EXPORT extern struct xkb_desc *
+xkb_map_new_from_fd(int fd, enum xkb_keymap_format format);
+
+/**
+ * Creates an XKB keymap from a full text XKB keymap serialised into one
+ * enormous string.
+ */
+_X_EXPORT extern struct xkb_desc *
+xkb_map_new_from_string(const char *string, enum xkb_keymap_format format);
+
+/**
+ * Takes a new reference on a keymap.
+ */
+_X_EXPORT extern void
+xkb_map_ref(struct xkb_desc *xkb);
+
+/**
+ * Releases a reference on a keymap.
+ */
+_X_EXPORT extern void
+xkb_map_unref(struct xkb_desc *xkb);
+
+/** @} */
+
+/**
  * @defgroup components XKB state components
  * Allows enumeration of state components such as modifiers and groups within
  * the current keymap.
index c623eb0..8dd4b5f 100644 (file)
@@ -266,8 +266,11 @@ XkbcAllocKeyboard(void)
     struct xkb_desc *xkb;
 
     xkb = _XkbTypedCalloc(1, struct xkb_desc);
-    if (xkb)
+    if (xkb) {
         xkb->device_spec = XkbUseCoreKbd;
+        xkb->refcnt = 1;
+    }
+
     return xkb;
 }
 
index e5dce5c..116f513 100644 (file)
@@ -422,6 +422,7 @@ struct xkb_state *
 xkb_state_new(struct xkb_desc *xkb)
 {
     struct xkb_state *ret;
+
     if (!xkb)
         return NULL;
 
@@ -431,6 +432,8 @@ xkb_state_new(struct xkb_desc *xkb)
 
     ret->refcnt = 1;
     ret->xkb = xkb;
+    xkb_map_ref(xkb);
+
     return ret;
 }
 
@@ -441,6 +444,8 @@ xkb_state_unref(struct xkb_state *state)
     assert(state->refcnt >= 0);
     if (state->refcnt == 0)
         return;
+
+    xkb_map_unref(state->xkb);
     free(state);
 }
 
index d3c99ce..897ff41 100644 (file)
@@ -199,6 +199,6 @@ CompileKeymap(XkbFile *file, unsigned merge)
 err:
     ACTION("Failed to compile keymap\n");
     if (xkb)
-        xkb_free_keymap(xkb);
+        xkb_map_unref(xkb);
     return NULL;
 }
index 8ab30d4..19ac4b8 100644 (file)
@@ -113,7 +113,7 @@ unwind_file:
 }
 
 struct xkb_desc *
-xkb_compile_keymap_from_rules(const struct xkb_rule_names *rmlvo)
+xkb_map_new_from_names(const struct xkb_rule_names *rmlvo)
 {
     XkbRF_VarDefsRec defs;
     struct xkb_component_names * names;
@@ -136,7 +136,7 @@ xkb_compile_keymap_from_rules(const struct xkb_rule_names *rmlvo)
         return NULL;
     }
 
-    xkb = xkb_compile_keymap_from_components(names);
+    xkb = xkb_map_new_from_kccgst(names);
 
     free(names->keymap);
     free(names->keycodes);
@@ -183,13 +183,13 @@ XkbChooseMap(XkbFile *file, const char *name)
 }
 
 static struct xkb_desc *
-compile_keymap(XkbFile *file, const char *mapName)
+compile_keymap(XkbFile *file)
 {
     XkbFile *mapToUse;
     struct xkb_desc * xkb = NULL;
 
     /* Find map to use */
-    mapToUse = XkbChooseMap(file, mapName);
+    mapToUse = XkbChooseMap(file, NULL);
     if (!mapToUse)
         goto err;
 
@@ -211,52 +211,58 @@ err:
     FreeXKBFile(file);
     free(scanFile);
     XkbFreeIncludePath();
+    XkbcFreeAllAtoms();
     return xkb;
 }
 
 struct xkb_desc *
-xkb_compile_keymap_from_components(const struct xkb_component_names * ktcsg)
+xkb_map_new_from_kccgst(const struct xkb_component_names *kccgst)
 {
     XkbFile *file;
 
-    if (!ktcsg) {
+    if (!kccgst) {
         ERROR("no components specified\n");
         return NULL;
     }
 
-    if (ISEMPTY(ktcsg->keycodes)) {
+    if (ISEMPTY(kccgst->keycodes)) {
         ERROR("keycodes required to generate XKB keymap\n");
         return NULL;
     }
 
-    if (ISEMPTY(ktcsg->compat)) {
+    if (ISEMPTY(kccgst->compat)) {
         ERROR("compat map required to generate XKB keymap\n");
         return NULL;
     }
 
-    if (ISEMPTY(ktcsg->types)) {
+    if (ISEMPTY(kccgst->types)) {
         ERROR("types required to generate XKB keymap\n");
         return NULL;
     }
 
-    if (ISEMPTY(ktcsg->symbols)) {
+    if (ISEMPTY(kccgst->symbols)) {
         ERROR("symbols required to generate XKB keymap\n");
         return NULL;
     }
 
-    if (!(file = XkbKeymapFileFromComponents(ktcsg))) {
+    if (!(file = XkbKeymapFileFromComponents(kccgst))) {
         ERROR("failed to generate parsed XKB file from components\n");
         return NULL;
     }
 
-    return compile_keymap(file, NULL);
+    return compile_keymap(file);
 }
 
 struct xkb_desc *
-xkb_compile_keymap_from_string(const char *string, const char *mapName)
+xkb_map_new_from_string(const char *string, enum xkb_keymap_format format)
 {
     XkbFile *file;
 
+    if (format != XKB_KEYMAP_FORMAT_TEXT_V1) {
+        ERROR("unsupported keymap format %d\n", format);
+        return NULL;
+    }
+
     if (!string) {
         ERROR("no string specified to generate XKB keymap\n");
         return NULL;
@@ -268,31 +274,51 @@ xkb_compile_keymap_from_string(const char *string, const char *mapName)
         return NULL;
     }
 
-    return compile_keymap(file, mapName);
+    return compile_keymap(file);
 }
 
 struct xkb_desc *
-xkb_compile_keymap_from_file(FILE *inputFile, const char *mapName)
+xkb_map_new_from_fd(int fd, enum xkb_keymap_format format)
 {
     XkbFile *file;
+    FILE *fptr;
 
-    if (!inputFile) {
+    if (format != XKB_KEYMAP_FORMAT_TEXT_V1) {
+        ERROR("unsupported keymap format %d\n", format);
+        return NULL;
+    }
+
+    if (fd < 0) {
         ERROR("no file specified to generate XKB keymap\n");
        return NULL;
     }
 
+    fptr = fdopen(fd, "r");
+    if (!fptr) {
+        ERROR("couldn't associate fd with file pointer\n");
+        return NULL;
+    }
+
     setScanState("input", 1);
-    if (!XKBParseFile(inputFile, &file) || !file) {
+    if (!XKBParseFile(fptr, &file) || !file) {
         ERROR("failed to parse input xkb file\n");
        return NULL;
     }
 
-    return compile_keymap(file, mapName);
+    return compile_keymap(file);
+}
+
+void
+xkb_map_ref(struct xkb_desc *xkb)
+{
+    xkb->refcnt++;
 }
 
 void
-xkb_free_keymap(struct xkb_desc *xkb)
+xkb_map_unref(struct xkb_desc *xkb)
 {
+    if (--xkb->refcnt > 0)
+        return;
+
     XkbcFreeKeyboard(xkb);
-    XkbcFreeAllAtoms();
 }
index 27691a8..facc02f 100644 (file)
@@ -37,15 +37,15 @@ static char buffer[8192];
 
 int main(int argc, char *argv[])
 {
-    char *path, *name;
-    FILE *file;
+    char *path;
+    int fd;
     struct xkb_desc * xkb;
     int i, len, from_string = 0;
 
     /* Require xkb file */
     if (argc < 2) {
         fprintf(stderr, "Not enough arguments\n");
-        fprintf(stderr, "Usage: %s [-s] XKBFILE [NAME]\n",
+        fprintf(stderr, "Usage: %s [-s] XKBFILE\n",
                 argv[0]);
         exit(1);
     }
@@ -57,30 +57,29 @@ int main(int argc, char *argv[])
     }
 
     path = argv[i];
-    name = (argc > i + 1) ? argv[i + 1] : NULL;
 
-    file = fopen(path, "r");
-    if (!file) {
+    fd = open(path, O_RDONLY);
+    if (fd < 0) {
         fprintf(stderr, "Failed to open file \"%s\": %s\n", path,
                 strerror(errno));
         exit(1);
     }
 
     if (from_string) {
-       len = fread(buffer, 1, sizeof buffer, file);
+       len = read(fd, buffer, sizeof(buffer));
        buffer[len] = '\0';
-       xkb = xkb_compile_keymap_from_string(buffer, name);
+       xkb = xkb_map_new_from_string(buffer, XKB_KEYMAP_FORMAT_TEXT_V1);
     } else {
-       xkb = xkb_compile_keymap_from_file(file, name);
+       xkb = xkb_map_new_from_fd(fd, XKB_KEYMAP_FORMAT_TEXT_V1);
     }
-    fclose(file);
+    close(fd);
 
     if (!xkb) {
         fprintf(stderr, "Failed to compile keymap\n");
         exit(1);
     }
 
-    xkb_free_keymap(xkb);
+    xkb_map_unref(xkb);
 
     return 0;
 }
index 1abfeb0..ac2dbec 100755 (executable)
@@ -24,12 +24,7 @@ failcompile()
 rm -f "$log"
 
 compile $srcdir/basic.xkb
-compile $srcdir/named.xkb
-compile $srcdir/named.xkb de
-compile $srcdir/named.xkb us
+# XXX check we actually get qwertz here ...
 compile $srcdir/default.xkb
 compile $srcdir/comprehensive-plus-geom.xkb
-
-failcompile $srcdir/basic.xkb foo
-failcompile $srcdir/named.xkb foo
 failcompile $srcdir/bad.xkb
diff --git a/test/named.xkb b/test/named.xkb
deleted file mode 100644 (file)
index f51fbbb..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-default xkb_keymap "us" {
-    xkb_keycodes  { include "xfree86+aliases(qwerty)" };
-    xkb_types     { include "complete" };
-    xkb_compat    { include "complete" };
-    xkb_symbols   { include "pc+us" };
-    xkb_geometry  { include "pc(pc105)" };
-};
-
-xkb_keymap "de" {
-    xkb_keycodes  { include "xfree86+aliases(qwertz)" };
-    xkb_types     { include "complete" };
-    xkb_compat    { include "complete" };
-    xkb_symbols   { include "pc+de" };
-    xkb_geometry  { include "pc(pc105)" };
-};
index e397fbc..b98ac7a 100644 (file)
@@ -33,8 +33,8 @@ authorization from the authors.
 
 int main(int argc, char *argv[])
 {
-    struct xkb_component_names ktcsg;
-    struct xkb_desc * xkb;
+    struct xkb_component_names kccgst;
+    struct xkb_desc *xkb;
 
     /* Require Kc + T + C + S */
     if (argc < 5) {
@@ -44,20 +44,20 @@ int main(int argc, char *argv[])
         exit(1);
     }
 
-    ktcsg.keymap = NULL;
-    ktcsg.keycodes = argv[1];
-    ktcsg.types = argv[2];
-    ktcsg.compat = argv[3];
-    ktcsg.symbols = argv[4];
+    kccgst.keymap = NULL;
+    kccgst.keycodes = argv[1];
+    kccgst.types = argv[2];
+    kccgst.compat = argv[3];
+    kccgst.symbols = argv[4];
 
-    xkb = xkb_compile_keymap_from_components(&ktcsg);
+    xkb = xkb_map_new_from_kccgst(&kccgst);
 
     if (!xkb) {
         fprintf(stderr, "Failed to compile keymap\n");
         exit(1);
     }
 
-    xkb_free_keymap(xkb);
+    xkb_map_unref(xkb);
 
     return 0;
 }
index 2532202..fa0890a 100644 (file)
@@ -34,7 +34,7 @@ authorization from the authors.
 int main(int argc, char *argv[])
 {
     struct xkb_rule_names rmlvo;
-    struct xkb_desc * xkb;
+    struct xkb_desc *xkb;
 
     /* Require rmlvo */
     if (argc < 6) {
@@ -50,14 +50,14 @@ int main(int argc, char *argv[])
     rmlvo.variant = argv[4];
     rmlvo.options = argv[5];
 
-    xkb = xkb_compile_keymap_from_rules(&rmlvo);
+    xkb = xkb_map_new_from_names(&rmlvo);
 
     if (!xkb) {
         fprintf(stderr, "Failed to compile keymap\n");
         exit(1);
     }
 
-    xkb_free_keymap(xkb);
+    xkb_map_unref(xkb);
 
     return 0;
 }
index eea5b59..c320440 100644 (file)
@@ -104,7 +104,7 @@ main(int argc, char *argv[])
     rmlvo.variant = NULL;
     rmlvo.options = NULL;
 
-    xkb = xkb_compile_keymap_from_rules(&rmlvo);
+    xkb = xkb_map_new_from_names(&rmlvo);
 
     if (!xkb) {
         fprintf(stderr, "Failed to compile keymap\n");
@@ -164,7 +164,7 @@ main(int argc, char *argv[])
     assert(num_syms == 1 && syms[0] == XK_q);
 
     xkb_state_unref(state);
-    xkb_free_keymap(xkb);
+    xkb_map_unref(xkb);
 
     return 0;
 }