Imported Debian patch 2:1.15.1-0ubuntu2.6
[deb_xorg-server.git] / debian / patches / 208_switch_on_release.diff
CommitLineData
7217e0ca
ML
1diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
2index c473df1..0ac2c71 100644
3--- a/xkb/xkbActions.c
4+++ b/xkb/xkbActions.c
5@@ -341,22 +341,83 @@ _XkbFilterLatchState(XkbSrvInfoPtr xkbi,
6 }
7
8 static int
9-_XkbFilterLockState(XkbSrvInfoPtr xkbi,
10+xkbSwitchGroupOnRelease(void)
11+{
12+ /* TODO: user configuring */
13+ return TRUE;
14+}
15+
16+static void
17+xkbUpdateLockedGroup(XkbSrvInfoPtr xkbi, XkbAction *pAction)
18+{
19+ XkbGroupAction ga = pAction->group;
20+
21+ if (ga.flags & XkbSA_GroupAbsolute)
22+ xkbi->state.locked_group = XkbSAGroup(&ga);
23+ else
24+ xkbi->state.locked_group += XkbSAGroup(&ga);
25+}
26+
27+static XkbFilterPtr _XkbNextFreeFilter(XkbSrvInfoPtr xkbi);
28+
29+static int
30+_XkbFilterLockGroup(XkbSrvInfoPtr xkbi,
31 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
32 {
33- if (pAction && (pAction->type == XkbSA_LockGroup)) {
34- if (pAction->group.flags & XkbSA_GroupAbsolute)
35- xkbi->state.locked_group = XkbSAGroup(&pAction->group);
36- else
37- xkbi->state.locked_group += XkbSAGroup(&pAction->group);
38- return 1;
39+ int sendEvent = 1;
40+
41+ if (!xkbSwitchGroupOnRelease()) {
42+ xkbUpdateLockedGroup(xkbi, pAction);
43+ return sendEvent;
44 }
45+
46+ /* Delay switch till button release */
47+ if (filter->keycode == 0) { /* initial press */
48+ filter->keycode = keycode;
49+ filter->active = 1;
50+ filter->filterOthers = 0; /* for what? */
51+ filter->filter = _XkbFilterLockGroup;
52+
53+ /* filter->priv = 0; */
54+ filter->upAction = *pAction;
55+
56+ /* Ok, now we need to simulate the action which would go if this action didn't block it.
57+ XkbSA_SetMods is the one: it is to set modifier' flag up. */
58+ {
59+ XkbStateRec fake_state = xkbi->state;
60+ XkbAction act;
61+
62+ fake_state.mods = 0;
63+ act = XkbGetKeyAction(xkbi, &fake_state, keycode);
64+
65+ /* KLUDGE: XkbSA_SetMods only? */
66+ if (act.type == XkbSA_SetMods) {
67+ XkbFilterPtr filter = _XkbNextFreeFilter(xkbi);
68+
69+ sendEvent = _XkbFilterSetState(xkbi, filter, keycode, &act);
70+ }
71+ }
72+ }
73+ else {
74+ /* do nothing if some button else is pressed */
75+ if (!pAction)
76+ xkbUpdateLockedGroup(xkbi, &filter->upAction);
77+ filter->active = 0;
78+ }
79+
80+ return sendEvent;
81+}
82+
83+static int
84+_XkbFilterLockMods(XkbSrvInfoPtr xkbi,
85+ XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
86+{
87 if (filter->keycode == 0) { /* initial press */
88 filter->keycode = keycode;
89 filter->active = 1;
90 filter->filterOthers = 0;
91 filter->priv = xkbi->state.locked_mods & pAction->mods.mask;
92- filter->filter = _XkbFilterLockState;
93+ filter->filter = _XkbFilterLockMods;
94 filter->upAction = *pAction;
95 if (!(filter->upAction.mods.flags & XkbSA_LockNoLock))
96 xkbi->state.locked_mods |= pAction->mods.mask;
97@@ -1129,9 +1190,12 @@ XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
98 sendEvent = _XkbFilterLatchState(xkbi, filter, key, &act);
99 break;
100 case XkbSA_LockMods:
101+ filter = _XkbNextFreeFilter(xkbi);
102+ sendEvent = _XkbFilterLockMods(xkbi, filter, key, &act);
103+ break;
104 case XkbSA_LockGroup:
105 filter = _XkbNextFreeFilter(xkbi);
106- sendEvent = _XkbFilterLockState(xkbi, filter, key, &act);
107+ sendEvent = _XkbFilterLockGroup(xkbi, filter, key, &act);
108 break;
109 case XkbSA_ISOLock:
110 filter = _XkbNextFreeFilter(xkbi);