Imported Debian patch 2:1.15.1-0ubuntu2.6
[deb_xorg-server.git] / debian / patches / 208_switch_on_release.diff
1 diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
2 index 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);