summaryrefslogtreecommitdiff
path: root/xkb
diff options
context:
space:
mode:
authorDan Nicholson <dbn.lists@gmail.com>2009-02-19 06:45:05 -0800
committerPeter Hutterer <peter.hutterer@who-t.net>2009-02-20 09:42:27 +1000
commit225853d51d1fb610261ab0c295b1b5a96ce177d5 (patch)
tree5c596b8dcc9e97bb8f934162074e325b1d66c293 /xkb
parent64e595d12e05c4df56b0230cc57924b9beb274d3 (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')
-rw-r--r--xkb/xkbInit.c48
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)