[PATCH] xkb: Check and load precompiled .xkm during startup if available

Peter Hutterer peter.hutterer at who-t.net
Mon Mar 15 17:12:14 PDT 2010


On Tue, Mar 16, 2010 at 04:45:51AM +0600, Mikhail Gusarov wrote:
> New 'precompiled' subdir is added to xkb data dir, allowing to pre-compile
> keymaps to be loaded when server starts and hence avoid running xkbcomp, saving
> a bit of time.

Good idea. Do you have any numbers on how much time this actually saves? 
IIRC we only run xkbcomp once at the moment and then re-used the cached
values. Is skipping this one run beneficial?

What happens if xkeyboard-config is updated after an xkm has been
precompiled? Do the users need to recompile? This is my main worry, it'll
make triaging of nonworking keyboard layouts quite tricky.

Cheers,
  Peter

> 
> Signed-off-by: Mikhail Gusarov <dottedmag at dottedmag.net>
> ---
>  xkb/ddxLoad.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++------
>  1 files changed, 47 insertions(+), 6 deletions(-)
> 
> diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
> index 4ccddda..939835f 100644
> --- a/xkb/ddxLoad.c
> +++ b/xkb/ddxLoad.c
> @@ -174,6 +174,35 @@ OutputDirectory(
>      }
>  }
>  
> +/*
> + * Returns True if precompiled keymap is found and conveys keymap name in
> + * keymapName variable.
> + *
> + * Returns False if no precompiled keymap is found or keymapName buffer is too
> + * small.
> + */
> +static Bool
> +XkbDDXGetPrecompiledKeymap(XkbComponentNamesPtr names,
> +                           char *keymapName,
> +                           int keymapNameLen)
> +{
> +    if (!XkbBaseDirectory)
> +        return FALSE;
> +
> +    int ret = snprintf(keymapName, keymapNameLen,
> +                       "%s/precompiled/%s-%s-%s-%s-%s.xkm",
> +                       XkbBaseDirectory,
> +                       names->keycodes ? names->keycodes : "def",
> +                       names->types ? names->types : "def",
> +                       names->compat ? names->compat : "def",
> +                       names->symbols ? names->symbols : "def",
> +                       names->geometry ? names->geometry : "def");
> +    if (ret == keymapNameLen)
> +        return FALSE;
> +
> +    return access(keymapName, R_OK) == 0;
> +}
> +
>  static Bool
>  XkbDDXCompileKeymapByNames(	XkbDescPtr		xkb,
>  				XkbComponentNamesPtr	names,
> @@ -336,6 +365,7 @@ XkbDDXLoadKeymapByNames(	DeviceIntPtr		keybd,
>  XkbDescPtr      xkb;
>  FILE	*	file;
>  char		fileName[PATH_MAX];
> +Bool		unlinkFile;
>  unsigned	missing;
>  
>      *xkbRtrn = NULL;
> @@ -349,12 +379,22 @@ unsigned	missing;
>                     keybd->name ? keybd->name : "(unnamed keyboard)");
>          return 0;
>      }
> -    else if (!XkbDDXCompileKeymapByNames(xkb,names,want,need,
> -                                         nameRtrn,nameRtrnLen)){
> -	LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
> -	return 0;
> +
> +    if (XkbDDXGetPrecompiledKeymap(names, nameRtrn, nameRtrnLen)) {
> +        unlinkFile = FALSE;
> +        strncpy(fileName, nameRtrn, PATH_MAX);
> +        file = fopen(nameRtrn, "rb");
> +    } else {
> +        unlinkFile = TRUE;
> +
> +        if (!XkbDDXCompileKeymapByNames(xkb, names, want, need,
> +                                        nameRtrn, nameRtrnLen)) {
> +            LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
> +            return 0;
> +        }
> +        file= XkbDDXOpenConfigFile(nameRtrn,fileName,PATH_MAX);
>      }
> -    file= XkbDDXOpenConfigFile(nameRtrn,fileName,PATH_MAX);
> +
>      if (file==NULL) {
>  	LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",fileName);
>  	return 0;
> @@ -370,7 +410,8 @@ unsigned	missing;
>  	DebugF("Loaded XKB keymap %s, defined=0x%x\n",fileName,(*xkbRtrn)->defined);
>      }
>      fclose(file);
> -    (void) unlink (fileName);
> +    if (unlinkFile)
> +        unlink(fileName);
>      return (need|want)&(~missing);
>  }
>  
> -- 
> 1.6.3.3


More information about the xorg-devel mailing list