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