From 4391cf27f40ec53d41ac7e437cde49848eb32bde Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 12 Mar 2014 16:08:15 +1000 Subject: [PATCH] xkb: add a callback to xkbcomp MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This provides a callback to write to xkbcomp's buffer once everything is prepared. Signed-off-by: Peter Hutterer Reviewed-by: Kristian Høgsberg --- xkb/ddxLoad.c | 86 +++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c index 551f20a..33247cf 100644 --- a/xkb/ddxLoad.c +++ b/xkb/ddxLoad.c @@ -90,11 +90,17 @@ OutputDirectory(char *outdir, size_t size) } } -static Bool -XkbDDXCompileKeymapByNames(XkbDescPtr xkb, - XkbComponentNamesPtr names, - unsigned want, - unsigned need, char *nameRtrn, int nameRtrnLen) +/** + * Callback invoked by XkbRunXkbComp. Write to out to talk to xkbcomp. + */ +typedef void (*xkbcomp_buffer_callback)(FILE *out, void *userdata); + +/** + * Start xkbcomp, let the callback write into xkbcomp's stdin. When done, + * return a strdup'd copy of the file name we've written to. + */ +static char * +RunXkbComp(xkbcomp_buffer_callback callback, void *userdata) { FILE *out; char *buf = NULL, keymap[PATH_MAX], xkm_output_dir[PATH_MAX]; @@ -155,7 +161,7 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb, if (!buf) { LogMessage(X_ERROR, "XKB: Could not invoke xkbcomp: not enough memory\n"); - return FALSE; + return NULL; } #ifndef WIN32 @@ -165,13 +171,9 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb, #endif if (out != NULL) { -#ifdef DEBUG - if (xkbDebugFlags) { - ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n"); - XkbWriteXKBKeymapForNames(stderr, names, xkb, want, need); - } -#endif - XkbWriteXKBKeymapForNames(out, names, xkb, want, need); + /* Now write to xkbcomp */ + (*callback)(out, userdata); + #ifndef WIN32 if (Pclose(out) == 0) #else @@ -180,14 +182,11 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb, { if (xkbDebugFlags) DebugF("[xkb] xkb executes: %s\n", buf); - if (nameRtrn) { - strlcpy(nameRtrn, keymap, nameRtrnLen); - } free(buf); #ifdef WIN32 unlink(tmpname); #endif - return TRUE; + return xnfstrdup(keymap); } else LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap); @@ -203,10 +202,57 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb, LogMessage(X_ERROR, "Could not open file %s\n", tmpname); #endif } - if (nameRtrn) - nameRtrn[0] = '\0'; free(buf); - return FALSE; + return NULL; +} + +typedef struct { + XkbDescPtr xkb; + XkbComponentNamesPtr names; + unsigned int want; + unsigned int need; +} XkbKeymapNamesCtx; + +static void +xkb_write_keymap_for_names_cb(FILE *out, void *userdata) +{ + XkbKeymapNamesCtx *ctx = userdata; +#ifdef DEBUG + if (xkbDebugFlags) { + ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n"); + XkbWriteXKBKeymapForNames(stderr, ctx->names, ctx->xkb, ctx->want, ctx->need); + } +#endif + XkbWriteXKBKeymapForNames(out, ctx->names, ctx->xkb, ctx->want, ctx->need); +} + +static Bool +XkbDDXCompileKeymapByNames(XkbDescPtr xkb, + XkbComponentNamesPtr names, + unsigned want, + unsigned need, char *nameRtrn, int nameRtrnLen) +{ + char *keymap; + Bool rc = FALSE; + XkbKeymapNamesCtx ctx = { + .xkb = xkb, + .names = names, + .want = want, + .need = need + }; + + keymap = RunXkbComp(xkb_write_keymap_for_names_cb, &ctx); + + if (keymap) { + if(nameRtrn) + strlcpy(nameRtrn, keymap, nameRtrnLen); + + free(keymap); + rc = TRUE; + } else if (nameRtrn) + *nameRtrn = '\0'; + + return rc; } static FILE * -- 2.7.4