aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/xkb
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2014-03-21 19:36:05 +0100
committermarha <marha@users.sourceforge.net>2014-03-21 19:36:05 +0100
commit41fea4472dec859ddec76bdfa7108ebec71de1e3 (patch)
tree385ccec6dc105acc75169122d4e0714046cfbbd5 /xorg-server/xkb
parentcd8b0d0de3fcb53f6d3ece8ce26d97aaab2c0914 (diff)
downloadvcxsrv-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')
-rw-r--r--xorg-server/xkb/ddxLoad.c244
-rw-r--r--xorg-server/xkb/xkb.c16
-rw-r--r--xorg-server/xkb/xkbInit.c42
-rw-r--r--xorg-server/xkb/xkbUtils.c37
4 files changed, 255 insertions, 84 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);
}
diff --git a/xorg-server/xkb/xkb.c b/xorg-server/xkb/xkb.c
index 31bb8d3c5..dc570f0e5 100644
--- a/xorg-server/xkb/xkb.c
+++ b/xorg-server/xkb/xkb.c
@@ -5950,25 +5950,13 @@ ProcXkbGetKbdByName(ClientPtr client)
if (rep.loaded) {
XkbDescPtr old_xkb;
xkbNewKeyboardNotify nkn;
- int i, nG, nTG;
old_xkb = xkb;
xkb = new;
dev->key->xkbInfo->desc = xkb;
new = old_xkb; /* so it'll get freed automatically */
- *xkb->ctrls = *old_xkb->ctrls;
- for (nG = nTG = 0, i = xkb->min_key_code; i <= xkb->max_key_code; i++) {
- nG = XkbKeyNumGroups(xkb, i);
- if (nG >= XkbNumKbdGroups) {
- nTG = XkbNumKbdGroups;
- break;
- }
- if (nG > nTG) {
- nTG = nG;
- }
- }
- xkb->ctrls->num_groups = nTG;
+ XkbCopyControls(xkb, old_xkb);
nkn.deviceID = nkn.oldDeviceID = dev->id;
nkn.minKeyCode = new->min_key_code;
@@ -5991,7 +5979,7 @@ ProcXkbGetKbdByName(ClientPtr client)
continue;
if (tmpd != dev)
- XkbCopyDeviceKeymap(tmpd, dev);
+ XkbDeviceApplyKeymap(tmpd, xkb);
if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
old_sli = tmpd->kbdfeed->xkb_sli;
diff --git a/xorg-server/xkb/xkbInit.c b/xorg-server/xkb/xkbInit.c
index 33420b6b6..06ec46e81 100644
--- a/xorg-server/xkb/xkbInit.c
+++ b/xorg-server/xkb/xkbInit.c
@@ -505,9 +505,10 @@ XkbInitControls(DeviceIntPtr pXDev, XkbSrvInfoPtr xkbi)
return Success;
}
-_X_EXPORT Bool
-InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
- BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+static Bool
+InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
+ const char *keymap, int keymap_length,
+ BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
{
int i;
unsigned int check;
@@ -521,8 +522,9 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
BUG_RETURN_VAL(dev == NULL, FALSE);
BUG_RETURN_VAL(dev->key != NULL, FALSE);
BUG_RETURN_VAL(dev->kbdfeed != NULL, FALSE);
+ BUG_RETURN_VAL(rmlvo && keymap, FALSE);
- if (!rmlvo) {
+ if (!rmlvo && !keymap) {
rmlvo = &rmlvo_dflts;
XkbGetRulesDflts(rmlvo);
}
@@ -550,7 +552,7 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
}
dev->key->xkbInfo = xkbi;
- if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) {
+ if (xkb_cached_map && (keymap || (rmlvo && !XkbCompareUsedRMLVO(rmlvo)))) {
XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
xkb_cached_map = NULL;
}
@@ -558,7 +560,11 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
if (xkb_cached_map)
LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
else {
- xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
+ if (rmlvo)
+ xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
+ else
+ xkb_cached_map = XkbCompileKeymapFromString(dev, keymap, keymap_length);
+
if (!xkb_cached_map) {
ErrorF("XKB: Failed to compile keymap\n");
goto unwind_info;
@@ -627,8 +633,10 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
dev->kbdfeed->CtrlProc(dev, &dev->kbdfeed->ctrl);
- XkbSetRulesDflts(rmlvo);
- XkbSetRulesUsed(rmlvo);
+ if (rmlvo) {
+ XkbSetRulesDflts(rmlvo);
+ XkbSetRulesUsed(rmlvo);
+ }
XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
return TRUE;
@@ -647,6 +655,24 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
return FALSE;
}
+_X_EXPORT Bool
+InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
+ BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+{
+ return InitKeyboardDeviceStructInternal(dev, rmlvo,
+ NULL, 0, bell_func, ctrl_func);
+}
+
+_X_EXPORT Bool
+InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
+ const char *keymap, int keymap_length,
+ BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+{
+ return InitKeyboardDeviceStructInternal(dev, NULL,
+ keymap, keymap_length,
+ bell_func, ctrl_func);
+}
+
/***====================================================================***/
/*
diff --git a/xorg-server/xkb/xkbUtils.c b/xorg-server/xkb/xkbUtils.c
index 6c6af60f0..6cf6e79df 100644
--- a/xorg-server/xkb/xkbUtils.c
+++ b/xorg-server/xkb/xkbUtils.c
@@ -1999,28 +1999,28 @@ XkbCopyKeymap(XkbDescPtr dst, XkbDescPtr src)
}
Bool
-XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src)
+XkbDeviceApplyKeymap(DeviceIntPtr dst, XkbDescPtr desc)
{
xkbNewKeyboardNotify nkn;
Bool ret;
- if (!dst->key || !src->key)
+ if (!dst->key || !desc)
return FALSE;
memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
nkn.oldMinKeyCode = dst->key->xkbInfo->desc->min_key_code;
nkn.oldMaxKeyCode = dst->key->xkbInfo->desc->max_key_code;
nkn.deviceID = dst->id;
- nkn.oldDeviceID = dst->id; /* maybe src->id? */
- nkn.minKeyCode = src->key->xkbInfo->desc->min_key_code;
- nkn.maxKeyCode = src->key->xkbInfo->desc->max_key_code;
+ nkn.oldDeviceID = dst->id;
+ nkn.minKeyCode = desc->min_key_code;
+ nkn.maxKeyCode = desc->max_key_code;
nkn.requestMajor = XkbReqCode;
nkn.requestMinor = X_kbSetMap; /* Near enough's good enough. */
nkn.changed = XkbNKN_KeycodesMask;
- if (src->key->xkbInfo->desc->geom)
+ if (desc->geom)
nkn.changed |= XkbNKN_GeometryMask;
- ret = XkbCopyKeymap(dst->key->xkbInfo->desc, src->key->xkbInfo->desc);
+ ret = XkbCopyKeymap(dst->key->xkbInfo->desc, desc);
if (ret)
XkbSendNewKeyboardNotify(dst, &nkn);
@@ -2090,3 +2090,26 @@ XkbMergeLockedPtrBtns(DeviceIntPtr master)
xkbi->lockedPtrButtons |= d->key->xkbInfo->lockedPtrButtons;
}
}
+
+void
+XkbCopyControls(XkbDescPtr dst, XkbDescPtr src)
+{
+ int i, nG, nTG;
+
+ if (!dst || !src)
+ return;
+
+ *dst->ctrls = *src->ctrls;
+
+ for (nG = nTG = 0, i = dst->min_key_code; i <= dst->max_key_code; i++) {
+ nG = XkbKeyNumGroups(dst, i);
+ if (nG >= XkbNumKbdGroups) {
+ nTG = XkbNumKbdGroups;
+ break;
+ }
+ if (nG > nTG) {
+ nTG = nG;
+ }
+ }
+ dst->ctrls->num_groups = nTG;
+}