[PATCH v2] xkb: Use cached XKB keymap when rules haven't changed

Peter Hutterer peter.hutterer at who-t.net
Wed Feb 18 21:33:09 PST 2009


On Tue, Feb 17, 2009 at 10:46:05PM -0800, Dan Nicholson wrote:
> 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.


15:25 < whot> daniels: is the NULL != "" thing an issue? it not, I'll push,
the patch works
15:26 < daniels> NULL and "" should be treated identically

Other than that, ACK from me.

Cheers,
  Peter

> 
>  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