From d039622a659b40d014f146fcd2ff2353cd5b1bc7 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Thu, 22 Mar 2012 17:39:12 +0000 Subject: [PATCH] Rename keymap allocation API Signed-off-by: Daniel Stone --- include/xkbcommon/xkbcommon.h | 79 +++++++++++++++++++++++++++++++++++-------- src/alloc.c | 5 ++- src/state.c | 5 +++ src/xkbcomp/keymap.c | 2 +- src/xkbcomp/xkbcomp.c | 66 +++++++++++++++++++++++++----------- test/filecomp.c | 21 ++++++------ test/filecomp.sh | 7 +--- test/named.xkb | 15 -------- test/namescomp.c | 18 +++++----- test/rulescomp.c | 6 ++-- test/state.c | 4 +-- 11 files changed, 145 insertions(+), 83 deletions(-) delete mode 100644 test/named.xkb diff --git a/include/xkbcommon/xkbcommon.h b/include/xkbcommon/xkbcommon.h index fe72a74..18441c0 100644 --- a/include/xkbcommon/xkbcommon.h +++ b/include/xkbcommon/xkbcommon.h @@ -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. diff --git a/src/alloc.c b/src/alloc.c index c623eb0..8dd4b5f 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -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; } diff --git a/src/state.c b/src/state.c index e5dce5c..116f513 100644 --- a/src/state.c +++ b/src/state.c @@ -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); } diff --git a/src/xkbcomp/keymap.c b/src/xkbcomp/keymap.c index d3c99ce..897ff41 100644 --- a/src/xkbcomp/keymap.c +++ b/src/xkbcomp/keymap.c @@ -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; } diff --git a/src/xkbcomp/xkbcomp.c b/src/xkbcomp/xkbcomp.c index 8ab30d4..19ac4b8 100644 --- a/src/xkbcomp/xkbcomp.c +++ b/src/xkbcomp/xkbcomp.c @@ -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(); } diff --git a/test/filecomp.c b/test/filecomp.c index 27691a8..facc02f 100644 --- a/test/filecomp.c +++ b/test/filecomp.c @@ -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; } diff --git a/test/filecomp.sh b/test/filecomp.sh index 1abfeb0..ac2dbec 100755 --- a/test/filecomp.sh +++ b/test/filecomp.sh @@ -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 index f51fbbb..0000000 --- a/test/named.xkb +++ /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)" }; -}; diff --git a/test/namescomp.c b/test/namescomp.c index e397fbc..b98ac7a 100644 --- a/test/namescomp.c +++ b/test/namescomp.c @@ -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; } diff --git a/test/rulescomp.c b/test/rulescomp.c index 2532202..fa0890a 100644 --- a/test/rulescomp.c +++ b/test/rulescomp.c @@ -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; } diff --git a/test/state.c b/test/state.c index eea5b59..c320440 100644 --- a/test/state.c +++ b/test/state.c @@ -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; } -- 2.7.4