diff options
author | marha <marha@users.sourceforge.net> | 2011-07-15 11:25:17 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-07-15 11:25:17 +0200 |
commit | 2ce12f084113a0097fa1a0d67e2f8fe1ab70092b (patch) | |
tree | 7001b0332aba46855f1d01d7ef8ed80d134453a9 /xorg-server/xkb | |
parent | d03a5f20114203fd00e0004659fd2617f4c03a32 (diff) | |
download | vcxsrv-2ce12f084113a0097fa1a0d67e2f8fe1ab70092b.tar.gz vcxsrv-2ce12f084113a0097fa1a0d67e2f8fe1ab70092b.tar.bz2 vcxsrv-2ce12f084113a0097fa1a0d67e2f8fe1ab70092b.zip |
xserver libX11 mesa git update 15 July
Diffstat (limited to 'xorg-server/xkb')
-rw-r--r-- | xorg-server/xkb/xkb.c | 19 | ||||
-rw-r--r-- | xorg-server/xkb/xkmread.c | 31 |
2 files changed, 46 insertions, 4 deletions
diff --git a/xorg-server/xkb/xkb.c b/xorg-server/xkb/xkb.c index 86231a895..9c66955f4 100644 --- a/xorg-server/xkb/xkb.c +++ b/xorg-server/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/xorg-server/xkb/xkmread.c b/xorg-server/xkb/xkmread.c index e8b97dcda..a5c1ecfff 100644 --- a/xorg-server/xkb/xkmread.c +++ b/xorg-server/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; |