From 2e009f69c701c53123654785ff5cf0a0c67c22b2 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 4 Jun 2012 16:15:10 +0100 Subject: [PATCH] Avoid duplicating keysyms for merge if possible If we can merge cleanly (i.e. use the entirety of one entry rather than having to go level by level), then just reuse the existing symbols array and skip the entire merge process. Signed-off-by: Daniel Stone --- src/xkbcomp/symbols.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/xkbcomp/symbols.c b/src/xkbcomp/symbols.c index 9a3e73f..5e243ec 100644 --- a/src/xkbcomp/symbols.c +++ b/src/xkbcomp/symbols.c @@ -366,11 +366,18 @@ ResizeKeyGroup(KeyInfo * key, unsigned int group, unsigned int numLevels, return true; } +enum key_group_selector { + NONE = 0, + FROM = (1 << 0), + TO = (1 << 1), +}; + static bool MergeKeyGroups(SymbolsInfo * info, KeyInfo * into, KeyInfo * from, unsigned group) { xkb_keysym_t *resultSyms = NULL; + enum key_group_selector using = NONE; union xkb_action *resultActs; unsigned int resultWidth; unsigned int resultSize = 0; @@ -476,20 +483,34 @@ MergeKeyGroups(SymbolsInfo * info, if (fromSize == 0) { resultSize += toSize; + using |= TO; } else if (toSize == 0 || clobber) { resultSize += fromSize; + using |= FROM; } else { resultSize += toSize; + using |= TO; } } if (resultSize == 0) goto out; + if (using == FROM) + { + resultSyms = from->syms[group]; + goto out; + } + else if (using == TO) + { + resultSyms = into->syms[group]; + goto out; + } + resultSyms = uTypedCalloc(resultSize, xkb_keysym_t); if (!resultSyms) { @@ -500,7 +521,7 @@ MergeKeyGroups(SymbolsInfo * info, for (i = 0; i < resultWidth; i++) { - enum { NONE, FROM, TO } use; + enum key_group_selector use = NONE; unsigned int fromSize = 0; unsigned int toSize = 0; @@ -557,9 +578,11 @@ out: if (resultActs != from->acts[group]) free(from->acts[group]); into->numLevels[group] = resultWidth; - free(into->syms[group]); + if (resultSyms != into->syms[group]) + free(into->syms[group]); into->syms[group] = resultSyms; - free(from->syms[group]); + if (resultSyms != from->syms[group]) + free(from->syms[group]); from->syms[group] = NULL; from->sizeSyms[group] = 0; into->sizeSyms[group] = resultSize; @@ -569,7 +592,8 @@ out: from->symsMapNumEntries[group] = NULL; into->acts[group] = resultActs; from->acts[group] = NULL; - into->symsDefined |= (1 << group); + if (into->syms[group]) + into->symsDefined |= (1 << group); from->symsDefined &= ~(1 << group); into->actsDefined |= (1 << group); from->actsDefined &= ~(1 << group);