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:
parent
6ebd838d80
commit
4391cf27f4
|
@ -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 *
|
||||
|
|
Loading…
Reference in New Issue
Block a user