diff options
author | marha <marha@users.sourceforge.net> | 2014-03-21 19:36:05 +0100 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2014-03-21 19:36:05 +0100 |
commit | 41fea4472dec859ddec76bdfa7108ebec71de1e3 (patch) | |
tree | 385ccec6dc105acc75169122d4e0714046cfbbd5 /xorg-server/xkb/ddxLoad.c | |
parent | cd8b0d0de3fcb53f6d3ece8ce26d97aaab2c0914 (diff) | |
download | vcxsrv-41fea4472dec859ddec76bdfa7108ebec71de1e3.tar.gz vcxsrv-41fea4472dec859ddec76bdfa7108ebec71de1e3.tar.bz2 vcxsrv-41fea4472dec859ddec76bdfa7108ebec71de1e3.zip |
xserver fontconfig libX11 libXext libxcb mesa git update 21 Mar 2014
xserver commit 4fb31e4824d46edc80bb49b4065152899faa5ac6
libxcb commit cb686b576739deea00180c54697c8b62b8419ae0
libX11 commit 8be4610939b833587954957f5963eb4191b43d19
libXext commit 11aad96bd689d54156064d2e81213dc827a689d1
fontconfig commit 5478192f379d784b421329e4bf72cc780818e467
mesa commit 8d8d0cb09eb8735a04fc36cc4d0e2dc9f9d460eb
Diffstat (limited to 'xorg-server/xkb/ddxLoad.c')
-rw-r--r-- | xorg-server/xkb/ddxLoad.c | 244 |
1 files changed, 189 insertions, 55 deletions
diff --git a/xorg-server/xkb/ddxLoad.c b/xorg-server/xkb/ddxLoad.c index f458e3bde..1dc0e4eee 100644 --- a/xorg-server/xkb/ddxLoad.c +++ b/xorg-server/xkb/ddxLoad.c @@ -68,6 +68,9 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #define PATHSEPARATOR "/" #endif +static unsigned +LoadXKM(unsigned want, unsigned need, const char *keymap, XkbDescPtr *xkbRtrn); + static void OutputDirectory(char *outdir, size_t size) { @@ -90,11 +93,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 +164,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 +174,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 +185,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,14 +205,101 @@ 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; +} + +typedef struct { + const char *keymap; + size_t len; +} XkbKeymapString; + +static void +xkb_write_keymap_string_cb(FILE *out, void *userdata) +{ + XkbKeymapString *s = userdata; + fwrite(s->keymap, s->len, 1, out); +} + +static unsigned int +XkbDDXLoadKeymapFromString(DeviceIntPtr keybd, + const char *keymap, int keymap_length, + unsigned int want, + unsigned int need, + XkbDescPtr *xkbRtrn) +{ + unsigned int have; + char *map_name; + XkbKeymapString map = { + .keymap = keymap, + .len = keymap_length + }; + + *xkbRtrn = NULL; + + map_name = RunXkbComp(xkb_write_keymap_string_cb, &map); + if (!map_name) { + LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n"); + return 0; + } + + have = LoadXKM(want, need, map_name, xkbRtrn); + free(map_name); + + return have; } static FILE * -XkbDDXOpenConfigFile(char *mapName, char *fileNameRtrn, int fileNameRtrnLen) +XkbDDXOpenConfigFile(const char *mapName, char *fileNameRtrn, int fileNameRtrnLen) { char buf[PATH_MAX], xkm_output_dir[PATH_MAX]; FILE *file; @@ -245,6 +334,35 @@ XkbDDXOpenConfigFile(char *mapName, char *fileNameRtrn, int fileNameRtrnLen) return file; } +static unsigned +LoadXKM(unsigned want, unsigned need, const char *keymap, XkbDescPtr *xkbRtrn) +{ + FILE *file; + char fileName[PATH_MAX]; + unsigned missing; + + file = XkbDDXOpenConfigFile(keymap, fileName, PATH_MAX); + if (file == NULL) { + LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n", + fileName); + return 0; + } + missing = XkmReadFile(file, need, want, xkbRtrn); + if (*xkbRtrn == NULL) { + LogMessage(X_ERROR, "Error loading keymap %s\n", fileName); + fclose(file); + (void) unlink(fileName); + return 0; + } + else { + DebugF("Loaded XKB keymap %s, defined=0x%x\n", fileName, + (*xkbRtrn)->defined); + } + fclose(file); + (void) unlink(fileName); + return (need | want) & (~missing); +} + unsigned XkbDDXLoadKeymapByNames(DeviceIntPtr keybd, XkbComponentNamesPtr names, @@ -253,9 +371,6 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd, XkbDescPtr *xkbRtrn, char *nameRtrn, int nameRtrnLen) { XkbDescPtr xkb; - FILE *file; - char fileName[PATH_MAX]; - unsigned missing; *xkbRtrn = NULL; if ((keybd == NULL) || (keybd->key == NULL) || @@ -275,26 +390,8 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd, LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n"); return 0; } - file = XkbDDXOpenConfigFile(nameRtrn, fileName, PATH_MAX); - if (file == NULL) { - LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n", - fileName); - return 0; - } - missing = XkmReadFile(file, need, want, xkbRtrn); - if (*xkbRtrn == NULL) { - LogMessage(X_ERROR, "Error loading keymap %s\n", fileName); - fclose(file); - (void) unlink(fileName); - return 0; - } - else { - DebugF("Loaded XKB keymap %s, defined=0x%x\n", fileName, - (*xkbRtrn)->defined); - } - fclose(file); - (void) unlink(fileName); - return (need | want) & (~missing); + + return LoadXKM(want, need, nameRtrn, xkbRtrn); } Bool @@ -390,6 +487,29 @@ XkbCompileKeymapForDevice(DeviceIntPtr dev, XkbRMLVOSet * rmlvo, int need) return xkb; } +static XkbDescPtr +KeymapOrDefaults(DeviceIntPtr dev, XkbDescPtr xkb) +{ + XkbRMLVOSet dflts; + + if (xkb) + return xkb; + + /* we didn't get what we really needed. And that will likely leave + * us with a keyboard that doesn't work. Use the defaults instead */ + LogMessage(X_ERROR, "XKB: Failed to load keymap. Loading default " + "keymap instead.\n"); + + XkbGetRulesDflts(&dflts); + + xkb = XkbCompileKeymapForDevice(dev, &dflts, 0); + + XkbFreeRMLVOSet(&dflts, FALSE); + + return xkb; +} + + XkbDescPtr XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo) { @@ -407,20 +527,34 @@ XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo) xkb = XkbCompileKeymapForDevice(dev, rmlvo, need); - if (!xkb) { - XkbRMLVOSet dflts; - - /* we didn't get what we really needed. And that will likely leave - * us with a keyboard that doesn't work. Use the defaults instead */ - LogMessage(X_ERROR, "XKB: Failed to load keymap. Loading default " - "keymap instead.\n"); + return KeymapOrDefaults(dev, xkb); +} - XkbGetRulesDflts(&dflts); +XkbDescPtr +XkbCompileKeymapFromString(DeviceIntPtr dev, + const char *keymap, int keymap_length) +{ + XkbDescPtr xkb; + unsigned int need, provided; - xkb = XkbCompileKeymapForDevice(dev, &dflts, 0); + if (!dev || !keymap) { + LogMessage(X_ERROR, "XKB: No device or keymap specified\n"); + return NULL; + } - XkbFreeRMLVOSet(&dflts, FALSE); + /* These are the components we really really need */ + need = XkmSymbolsMask | XkmCompatMapMask | XkmTypesMask | + XkmKeyNamesMask | XkmVirtualModsMask; + + provided = + XkbDDXLoadKeymapFromString(dev, keymap, keymap_length, + XkmAllIndicesMask, need, &xkb); + if ((need & provided) != need) { + if (xkb) { + XkbFreeKeyboard(xkb, 0, TRUE); + xkb = NULL; + } } - return xkb; + return KeymapOrDefaults(dev, xkb); } |