summaryrefslogtreecommitdiff
path: root/xkb
diff options
context:
space:
mode:
authorDaniel Stone <daniel@fooishbar.org>2011-07-13 12:08:04 +0100
committerPeter Hutterer <peter.hutterer@who-t.net>2011-07-15 15:44:19 +1000
commit82f5521a6d91ebcd2a4400f6c221ad625edc99a1 (patch)
treee88df47cd8b6f974e2819cdd53a14eacf7c2c3be /xkb
parentc177a5bcaa170d24a784540460906cc04ac5c752 (diff)
XKB: Work around broken interps from old xkbcomp
Bugfix for broken xkbcomp: if we encounter an XFree86Private action with Any+AnyOfOrNone(All), then we skip the interp as broken. Versions of xkbcomp below 1.2.2 had a bug where they would interpret a symbol that couldn't be found in an interpret as Any. So, an XF86LogWindowTree+AnyOfOrNone(All) interp that triggered the PrWins action would make every key without an action trigger PrWins if libX11 didn't yet know about the XF86LogWindowTree keysym. None too useful. We only do this for XFree86 actions, as the current XKB dataset relies on Any+AnyOfOrNone(All) -> SetMods for Ctrl in particular. See xkbcomp commits 2a473b906943ffd807ad81960c47530ee7ae9a60 and 3caab5aa37decb7b5dc1642a0452efc3e1f5100e for more details. Signed-off-by: Daniel Stone <daniel@fooishbar.org> Acked-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'xkb')
-rw-r--r--xkb/xkb.c19
-rw-r--r--xkb/xkmread.c31
2 files changed, 46 insertions, 4 deletions
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 86231a895..9c66955f4 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -2786,6 +2786,7 @@ _XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev,
if (req->nSI>0) {
xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
XkbSymInterpretPtr sym;
+ unsigned int skipped = 0;
if ((unsigned)(req->firstSI+req->nSI)>compat->num_si) {
compat->num_si= req->firstSI+req->nSI;
compat->sym_interpret= realloc(compat->sym_interpret,
@@ -2799,11 +2800,19 @@ _XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev,
compat->num_si = req->firstSI+req->nSI;
}
sym = &compat->sym_interpret[req->firstSI];
- for (i=0;i<req->nSI;i++,wire++,sym++) {
+ for (i=0;i<req->nSI;i++,wire++) {
if (client->swapped) {
int n;
swapl(&wire->sym,n);
}
+ if (wire->sym == NoSymbol && wire->match == XkbSI_AnyOfOrNone &&
+ (wire->mods & 0xff) == 0xff &&
+ wire->act.type == XkbSA_XFree86Private) {
+ ErrorF("XKB: Skipping broken Any+AnyOfOrNone(All) -> Private "
+ "action from client\n");
+ skipped++;
+ continue;
+ }
sym->sym= wire->sym;
sym->mods= wire->mods;
sym->match= wire->match;
@@ -2811,6 +2820,14 @@ _XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev,
sym->virtual_mod= wire->virtualMod;
memcpy((char *)&sym->act,(char *)&wire->act,
SIZEOF(xkbActionWireDesc));
+ sym++;
+ }
+ if (skipped) {
+ if (req->firstSI + req->nSI < compat->num_si)
+ memmove(sym, sym + skipped,
+ (compat->num_si - req->firstSI - req->nSI) *
+ sizeof(*sym));
+ compat->num_si -= skipped;
}
data = (char *)wire;
}
diff --git a/xkb/xkmread.c b/xkb/xkmread.c
index e8b97dcda..a5c1ecfff 100644
--- a/xkb/xkmread.c
+++ b/xkb/xkmread.c
@@ -425,9 +425,9 @@ XkbAction *act;
if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_si)!=Success)
return -1;
compat= xkb->compat;
- compat->num_si= num_si;
+ compat->num_si= 0;
interp= compat->sym_interpret;
- for (i=0;i<num_si;i++,interp++) {
+ for (i=0;i<num_si;i++) {
tmp= fread(&wire,SIZEOF(xkmSymInterpretDesc),1,file);
nRead+= tmp*SIZEOF(xkmSymInterpretDesc);
interp->sym= wire.sym;
@@ -520,6 +520,29 @@ XkbAction *act;
break;
case XkbSA_XFree86Private:
+ /*
+ * Bugfix for broken xkbcomp: if we encounter an XFree86Private
+ * action with Any+AnyOfOrNone(All), then we skip the interp as
+ * broken. Versions of xkbcomp below 1.2.2 had a bug where they
+ * would interpret a symbol that couldn't be found in an interpret
+ * as Any. So, an XF86LogWindowTree+AnyOfOrNone(All) interp that
+ * triggered the PrWins action would make every key without an
+ * action trigger PrWins if libX11 didn't yet know about the
+ * XF86LogWindowTree keysym. None too useful.
+ *
+ * We only do this for XFree86 actions, as the current XKB
+ * dataset relies on Any+AnyOfOrNone(All) -> SetMods for Ctrl in
+ * particular.
+ *
+ * See xkbcomp commits 2a473b906943ffd807ad81960c47530ee7ae9a60 and
+ * 3caab5aa37decb7b5dc1642a0452efc3e1f5100e for more details.
+ */
+ if (interp->sym == NoSymbol && interp->match == XkbSI_AnyOfOrNone &&
+ (interp->mods & 0xff) == 0xff) {
+ ErrorF("XKB: Skipping broken Any+AnyOfOrNone(All) -> Private "
+ "action from compiled keymap\n");
+ continue;
+ }
/* copy the kind of action */
memcpy(act->any.data, wire.actionData, XkbAnyActionDataSize);
break ;
@@ -531,10 +554,12 @@ XkbAction *act;
/* unsupported. */
break;
}
+ interp++;
+ compat->num_si++;
}
if ((num_si>0)&&(changes)) {
changes->compat.first_si= 0;
- changes->compat.num_si= num_si;
+ changes->compat.num_si= compat->num_si;
}
if (groups) {
register unsigned bit;