diff options
author | Dan Nicholson <dbn.lists@gmail.com> | 2009-02-19 06:45:05 -0800 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2009-02-20 09:42:27 +1000 |
commit | 225853d51d1fb610261ab0c295b1b5a96ce177d5 (patch) | |
tree | 5c596b8dcc9e97bb8f934162074e325b1d66c293 /xkb/xkbInit.c | |
parent | 64e595d12e05c4df56b0230cc57924b9beb274d3 (diff) |
xkb: Use cached XKB keymap when rules haven't changed
Rather than compiling a new keymap every time InitKeyboardDeviceStruct
is called, cache the previous keymap and reuse it if the rules have not
changed.
Signed-off-by: Dan Nicholson <dbn.lists@gmail.com>
Acked-by: Daniel Stone <daniel@fooishbar.org>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'xkb/xkbInit.c')
-rw-r--r-- | xkb/xkbInit.c | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c index e9b9d65c2..1f5f8dc49 100644 --- a/xkb/xkbInit.c +++ b/xkb/xkbInit.c @@ -105,6 +105,8 @@ static char * XkbLayoutUsed= NULL; static char * XkbVariantUsed= NULL; static char * XkbOptionsUsed= NULL; +static XkbDescPtr xkb_cached_map = NULL; + static Bool XkbWantRulesProp= XKB_DFLT_RULES_PROP; /***====================================================================***/ @@ -255,8 +257,27 @@ XkbDeleteRulesDflts(void) XkbVariantDflt = NULL; _XkbFree(XkbOptionsDflt); XkbOptionsDflt = NULL; + + XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, True); + xkb_cached_map = NULL; +} + +#define DIFFERS(a, b) (strcmp((a) ? (a) : "", (b) ? (b) : "") != 0) + +static Bool +XkbCompareUsedRMLVO(XkbRMLVOSet *rmlvo) +{ + if (DIFFERS(rmlvo->rules, XkbRulesUsed) || + DIFFERS(rmlvo->model, XkbModelUsed) || + DIFFERS(rmlvo->layout, XkbLayoutUsed) || + DIFFERS(rmlvo->variant, XkbVariantUsed) || + DIFFERS(rmlvo->options, XkbOptionsUsed)) + return FALSE; + return TRUE; } +#undef DIFFERS + /***====================================================================***/ #include "xkbDflts.h" @@ -479,11 +500,34 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet *rmlvo, } dev->key->xkbInfo = xkbi; - xkb = XkbCompileKeymap(dev, rmlvo); + if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) { + XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, True); + xkb_cached_map = NULL; + } + + if (xkb_cached_map) + LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n"); + else { + xkb_cached_map = XkbCompileKeymap(dev, rmlvo); + if (!xkb_cached_map) { + ErrorF("XKB: Failed to compile keymap\n"); + goto unwind_info; + } + } + + xkb = XkbAllocKeyboard(); if (!xkb) { - ErrorF("XKB: Failed to compile keymap\n"); + ErrorF("XKB: Failed to allocate keyboard description\n"); goto unwind_info; } + + if (!XkbCopyKeymap(xkb, xkb_cached_map)) { + ErrorF("XKB: Failed to copy keymap\n"); + goto unwind_desc; + } + xkb->defined = xkb_cached_map->defined; + xkb->flags = xkb_cached_map->flags; + xkb->device_spec = xkb_cached_map->device_spec; xkbi->desc = xkb; if (xkb->min_key_code == 0) |