summaryrefslogtreecommitdiff
path: root/xkb
diff options
context:
space:
mode:
Diffstat (limited to 'xkb')
-rw-r--r--xkb/ddxLoad.c86
1 files changed, 66 insertions, 20 deletions
diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index 551f20a13..33247cf66 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 *