Imported Debian patch 2:1.15.1-0ubuntu2.6
[deb_xorg-server.git] / debian / patches / 208_switch_on_release.diff
diff --git a/debian/patches/208_switch_on_release.diff b/debian/patches/208_switch_on_release.diff
new file mode 100644 (file)
index 0000000..d1f7d26
--- /dev/null
@@ -0,0 +1,110 @@
+diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
+index c473df1..0ac2c71 100644
+--- a/xkb/xkbActions.c
++++ b/xkb/xkbActions.c
+@@ -341,22 +341,83 @@ _XkbFilterLatchState(XkbSrvInfoPtr xkbi,
+ }
+ static int
+-_XkbFilterLockState(XkbSrvInfoPtr xkbi,
++xkbSwitchGroupOnRelease(void)
++{
++    /* TODO: user configuring */
++    return TRUE;
++}
++
++static void
++xkbUpdateLockedGroup(XkbSrvInfoPtr xkbi, XkbAction *pAction)
++{
++    XkbGroupAction ga = pAction->group;
++
++    if (ga.flags & XkbSA_GroupAbsolute)
++        xkbi->state.locked_group = XkbSAGroup(&ga);
++    else
++        xkbi->state.locked_group += XkbSAGroup(&ga);
++}
++
++static XkbFilterPtr _XkbNextFreeFilter(XkbSrvInfoPtr xkbi);
++
++static int
++_XkbFilterLockGroup(XkbSrvInfoPtr xkbi,
+                     XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
+ {
+-    if (pAction && (pAction->type == XkbSA_LockGroup)) {
+-        if (pAction->group.flags & XkbSA_GroupAbsolute)
+-            xkbi->state.locked_group = XkbSAGroup(&pAction->group);
+-        else
+-            xkbi->state.locked_group += XkbSAGroup(&pAction->group);
+-        return 1;
++    int sendEvent = 1;
++
++    if (!xkbSwitchGroupOnRelease()) {
++        xkbUpdateLockedGroup(xkbi, pAction);
++        return sendEvent;
+     }
++
++    /* Delay switch till button release */
++    if (filter->keycode == 0) { /* initial press */
++        filter->keycode = keycode;
++        filter->active = 1;
++        filter->filterOthers = 0;       /* for what? */
++        filter->filter = _XkbFilterLockGroup;
++
++        /* filter->priv = 0; */
++        filter->upAction = *pAction;
++
++        /* Ok, now we need to simulate the action which would go if this action didn't block it.
++           XkbSA_SetMods is the one: it is to set modifier' flag up. */
++        {
++            XkbStateRec fake_state = xkbi->state;
++            XkbAction act;
++
++            fake_state.mods = 0;
++            act = XkbGetKeyAction(xkbi, &fake_state, keycode);
++
++            /* KLUDGE: XkbSA_SetMods only? */
++            if (act.type == XkbSA_SetMods) {
++                XkbFilterPtr filter = _XkbNextFreeFilter(xkbi);
++
++                sendEvent = _XkbFilterSetState(xkbi, filter, keycode, &act);
++            }
++        }
++    }
++    else {
++        /* do nothing if some button else is pressed */
++        if (!pAction)
++            xkbUpdateLockedGroup(xkbi, &filter->upAction);
++        filter->active = 0;
++    }
++
++    return sendEvent;
++}
++
++static int
++_XkbFilterLockMods(XkbSrvInfoPtr xkbi,
++                   XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
++{
+     if (filter->keycode == 0) { /* initial press */
+         filter->keycode = keycode;
+         filter->active = 1;
+         filter->filterOthers = 0;
+         filter->priv = xkbi->state.locked_mods & pAction->mods.mask;
+-        filter->filter = _XkbFilterLockState;
++        filter->filter = _XkbFilterLockMods;
+         filter->upAction = *pAction;
+         if (!(filter->upAction.mods.flags & XkbSA_LockNoLock))
+             xkbi->state.locked_mods |= pAction->mods.mask;
+@@ -1129,9 +1190,12 @@ XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
+                 sendEvent = _XkbFilterLatchState(xkbi, filter, key, &act);
+                 break;
+             case XkbSA_LockMods:
++                filter = _XkbNextFreeFilter(xkbi);
++                sendEvent = _XkbFilterLockMods(xkbi, filter, key, &act);
++                break;
+             case XkbSA_LockGroup:
+                 filter = _XkbNextFreeFilter(xkbi);
+-                sendEvent = _XkbFilterLockState(xkbi, filter, key, &act);
++                sendEvent = _XkbFilterLockGroup(xkbi, filter, key, &act);
+                 break;
+             case XkbSA_ISOLock:
+                 filter = _XkbNextFreeFilter(xkbi);