xkb: add a callback to xkbcomp

This provides a callback to write to xkbcomp's buffer once everything is
prepared.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
This commit is contained in:
Peter Hutterer 2014-03-12 16:08:15 +10:00
parent 6ebd838d80
commit 4391cf27f4

View File

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