From: Daniel Stone Date: Sat, 25 Apr 2009 08:13:52 +0000 (+1000) Subject: Add XkbcCanonicaliseComponents X-Git-Tag: xkbcommon-0.2.0~888 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=85b7f47d8a544dab204214de9c248f03e78261fe;p=platform%2Fupstream%2Flibxkbcommon.git Add XkbcCanonicaliseComponents Canonicalises two sets of components (new and old), e.g.: new: +bar old: foo result: foo+bar This is required as part of the spec, so clients can reuse part of the device's old keymap. Signed-off-by: Daniel Stone --- diff --git a/include/X11/extensions/XKBcommon.h b/include/X11/extensions/XKBcommon.h index 090c22b..1057895 100644 --- a/include/X11/extensions/XKBcommon.h +++ b/include/X11/extensions/XKBcommon.h @@ -144,6 +144,24 @@ extern XkbComponentListPtr XkbcListComponents(XkbComponentNamesPtr ptrns, int *maxMatch); /* + * Canonicalises component names by prepending the relevant component from + * 'old' to the one in 'names' when the latter has a leading '+' or '|', and + * by replacing a '%' with the relevant component, e.g.: + * + * names old output + * ------------------------------------------ + * +bar foo foo+bar + * |quux baz baz|quux + * foo+%|baz bar foo+bar|baz + * + * If a component in names needs to be modified, the existing value will be + * free()d, and a new one allocated with malloc(). + */ +extern void +XkbcCanonicaliseComponents(XkbComponentNamesPtr names, + const XkbComponentNamesPtr old); + +/* * Converts a keysym to a string; will return unknown Unicode codepoints * as "Ua1b2", and other unknown keysyms as "0xabcd1234". * diff --git a/src/xkb.c b/src/xkb.c index b0b0de6..7ebe856 100644 --- a/src/xkb.c +++ b/src/xkb.c @@ -31,6 +31,72 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "X11/extensions/XKBcommon.h" #include "XKBcommonint.h" +static char * +XkbcCanonicaliseComponent(char *name, const char *old) +{ + char *tmp; + int i; + + if (!name) + return NULL; + + /* Treachery. */ + if (old && strchr(old, '%')) + return NULL; + + if (name[0] == '+' || name[0] == '|') { + if (old) { + tmp = malloc(strlen(name) + strlen(old) + 1); + if (!tmp) + return NULL; + sprintf(tmp, "%s%s", old, name); + free(name); + name = tmp; + } + else { + memmove(name, &name[1], strlen(&name[1]) + 1); + } + } + + for (i = 0; name[i]; i++) { + if (name[i] == '%') { + if (old) { + tmp = malloc(strlen(name) + strlen(old)); + if (!tmp) + return NULL; + strncpy(tmp, name, i); + strcat(tmp + i, old); + strcat(tmp + i + strlen(old), &name[i + 1]); + free(name); + name = tmp; + i--; + } + else { + memmove(&name[i - 1], &name[i + 1], strlen(&name[i + 1]) + 1); + i -= 2; + } + } + } + + return name; +} + +void +XkbcCanonicaliseComponents(XkbComponentNamesPtr names, + const XkbComponentNamesPtr old) +{ + names->keycodes = XkbcCanonicaliseComponent(names->keycodes, + old ? old->keycodes : NULL); + names->compat = XkbcCanonicaliseComponent(names->compat, + old ? old->compat : NULL); + names->geometry = XkbcCanonicaliseComponent(names->geometry, + old ? old->geometry : NULL); + names->symbols = XkbcCanonicaliseComponent(names->symbols, + old ? old->symbols : NULL); + names->types = XkbcCanonicaliseComponent(names->types, + old ? old->types : NULL); +} + Bool XkbcComputeEffectiveMap(XkbcDescPtr xkb, XkbKeyTypePtr type, unsigned char *map_rtrn)