[PATCH v2 2/5] xkb: add a callback to xkbcomp

Peter Hutterer peter.hutterer at who-t.net
Wed Mar 12 19:56:56 PDT 2014


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

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 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 *
-- 
1.8.5.3



More information about the xorg-devel mailing list