[PATCH v2] xkb: Use cached XKB keymap when rules haven't changed
Dan Nicholson
dbn.lists at gmail.com
Tue Feb 17 22:46:05 PST 2009
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 at gmail.com>
---
The RMLVO comparison takes into account empty string vs. NULL. Should
it do that? I can't tell from a cursory glance through xkb/maprule.c
whether that's important or not.
xkb/xkbInit.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index e9b9d65..1698cf0 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,28 @@ XkbDeleteRulesDflts(void)
XkbVariantDflt = NULL;
_XkbFree(XkbOptionsDflt);
XkbOptionsDflt = NULL;
+
+ XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, True);
+ xkb_cached_map = NULL;
+}
+
+#define DIFFERS(a,b) \
+ (((a) && !(b)) || (!(a) && (b)) || ((a) && (b) && strcmp((a), (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 +501,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)
--
1.5.6.6
More information about the xorg-devel
mailing list