1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
15
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25 ********************************************************/
26
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
29 #endif
30
31 #include <stdio.h>
32 #include <math.h>
33 #include <X11/X.h>
34 #include <X11/Xproto.h>
35 #include <X11/keysym.h>
36 #include "misc.h"
37 #include "inputstr.h"
38 #include "exevents.h"
39 #include "eventstr.h"
40 #include <xkbsrv.h>
41 #include "xkb.h"
42 #include <ctype.h>
43 #include "mi.h"
44 #include "mipointer.h"
45 #include "inpututils.h"
46 #define EXTENSION_EVENT_BASE 64
47
48 DevPrivateKeyRec xkbDevicePrivateKeyRec;
49
50 static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x,
51 int y);
52
53 void
xkbUnwrapProc(DeviceIntPtr device,DeviceHandleProc proc,void * data)54 xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, void *data)
55 {
56 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
57 ProcessInputProc backupproc;
58
59 if (xkbPrivPtr->unwrapProc)
60 xkbPrivPtr->unwrapProc = NULL;
61
62 UNWRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, backupproc);
63 proc(device, data);
64 COND_WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, backupproc, xkbUnwrapProc);
65 }
66
67 Bool
XkbInitPrivates(void)68 XkbInitPrivates(void)
69 {
70 return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec, PRIVATE_DEVICE,
71 sizeof(xkbDeviceInfoRec));
72 }
73
74 void
XkbSetExtension(DeviceIntPtr device,ProcessInputProc proc)75 XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
76 {
77 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
78
79 WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc);
80 }
81
82 /***====================================================================***/
83
84 static XkbAction
_FixUpAction(XkbDescPtr xkb,XkbAction * act)85 _FixUpAction(XkbDescPtr xkb, XkbAction *act)
86 {
87 static XkbAction fake;
88
89 if (XkbIsPtrAction(act) &&
90 (!(xkb->ctrls->enabled_ctrls & XkbMouseKeysMask))) {
91 fake.type = XkbSA_NoAction;
92 return fake;
93 }
94 if (xkb->ctrls->enabled_ctrls & XkbStickyKeysMask) {
95 if (act->any.type == XkbSA_SetMods) {
96 fake.mods.type = XkbSA_LatchMods;
97 fake.mods.mask = act->mods.mask;
98 if (XkbAX_NeedOption(xkb->ctrls, XkbAX_LatchToLockMask))
99 fake.mods.flags = XkbSA_ClearLocks | XkbSA_LatchToLock;
100 else
101 fake.mods.flags = XkbSA_ClearLocks;
102 return fake;
103 }
104 if (act->any.type == XkbSA_SetGroup) {
105 fake.group.type = XkbSA_LatchGroup;
106 if (XkbAX_NeedOption(xkb->ctrls, XkbAX_LatchToLockMask))
107 fake.group.flags = XkbSA_ClearLocks | XkbSA_LatchToLock;
108 else
109 fake.group.flags = XkbSA_ClearLocks;
110 XkbSASetGroup(&fake.group, XkbSAGroup(&act->group));
111 return fake;
112 }
113 }
114 return *act;
115 }
116
117 static XkbAction
XkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key)118 XkbGetKeyAction(XkbSrvInfoPtr xkbi, XkbStatePtr xkbState, CARD8 key)
119 {
120 int effectiveGroup;
121 int col;
122 XkbDescPtr xkb;
123 XkbKeyTypePtr type;
124 XkbAction *pActs;
125 static XkbAction fake;
126
127 xkb = xkbi->desc;
128 if (!XkbKeyHasActions(xkb, key) || !XkbKeycodeInRange(xkb, key)) {
129 fake.type = XkbSA_NoAction;
130 return fake;
131 }
132 pActs = XkbKeyActionsPtr(xkb, key);
133 col = 0;
134
135 effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key);
136 if (effectiveGroup != XkbGroup1Index)
137 col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key));
138
139 type = XkbKeyKeyType(xkb, key, effectiveGroup);
140 if (type->map != NULL) {
141 register unsigned i, mods;
142 register XkbKTMapEntryPtr entry;
143
144 mods = xkbState->mods & type->mods.mask;
145 for (entry = type->map, i = 0; i < type->map_count; i++, entry++) {
146 if ((entry->active) && (entry->mods.mask == mods)) {
147 col += entry->level;
148 break;
149 }
150 }
151 }
152 if (pActs[col].any.type == XkbSA_NoAction)
153 return pActs[col];
154 fake = _FixUpAction(xkb, &pActs[col]);
155 return fake;
156 }
157
158 static XkbAction
XkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button)159 XkbGetButtonAction(DeviceIntPtr kbd, DeviceIntPtr dev, int button)
160 {
161 XkbAction fake;
162
163 if ((dev->button) && (dev->button->xkb_acts)) {
164 if (dev->button->xkb_acts[button - 1].any.type != XkbSA_NoAction) {
165 fake = _FixUpAction(kbd->key->xkbInfo->desc,
166 &dev->button->xkb_acts[button - 1]);
167 return fake;
168 }
169 }
170 fake.any.type = XkbSA_NoAction;
171 return fake;
172 }
173
174 /***====================================================================***/
175
176 #define SYNTHETIC_KEYCODE 1
177 #define BTN_ACT_FLAG 0x100
178
179 static int
_XkbFilterSetState(XkbSrvInfoPtr xkbi,XkbFilterPtr filter,unsigned keycode,XkbAction * pAction)180 _XkbFilterSetState(XkbSrvInfoPtr xkbi,
181 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
182 {
183 if (filter->keycode == 0) { /* initial press */
184 AccessXCancelRepeatKey(xkbi, keycode);
185 filter->keycode = keycode;
186 filter->active = 1;
187 filter->filterOthers = ((pAction->mods.mask & XkbSA_ClearLocks) != 0);
188 filter->priv = 0;
189 filter->filter = _XkbFilterSetState;
190 if (pAction->type == XkbSA_SetMods) {
191 filter->upAction = *pAction;
192 xkbi->setMods = pAction->mods.mask;
193 }
194 else {
195 xkbi->groupChange = XkbSAGroup(&pAction->group);
196 if (pAction->group.flags & XkbSA_GroupAbsolute)
197 xkbi->groupChange -= xkbi->state.base_group;
198 filter->upAction = *pAction;
199 XkbSASetGroup(&filter->upAction.group, xkbi->groupChange);
200 }
201 }
202 else if (filter->keycode == keycode) {
203 if (filter->upAction.type == XkbSA_SetMods) {
204 xkbi->clearMods = filter->upAction.mods.mask;
205 if (filter->upAction.mods.flags & XkbSA_ClearLocks) {
206 xkbi->state.locked_mods &= ~filter->upAction.mods.mask;
207 }
208 }
209 else {
210 if (filter->upAction.group.flags & XkbSA_ClearLocks) {
211 xkbi->state.locked_group = 0;
212 }
213 xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
214 }
215 filter->active = 0;
216 }
217 else {
218 filter->upAction.mods.flags &= ~XkbSA_ClearLocks;
219 filter->filterOthers = 0;
220 }
221 return 1;
222 }
223
224 #define LATCH_KEY_DOWN 1
225 #define LATCH_PENDING 2
226
227 static int
_XkbFilterLatchState(XkbSrvInfoPtr xkbi,XkbFilterPtr filter,unsigned keycode,XkbAction * pAction)228 _XkbFilterLatchState(XkbSrvInfoPtr xkbi,
229 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
230 {
231
232 if (filter->keycode == 0) { /* initial press */
233 AccessXCancelRepeatKey(xkbi,keycode);
234 filter->keycode = keycode;
235 filter->active = 1;
236 filter->filterOthers = 1;
237 filter->priv = LATCH_KEY_DOWN;
238 filter->filter = _XkbFilterLatchState;
239 if (pAction->type == XkbSA_LatchMods) {
240 filter->upAction = *pAction;
241 xkbi->setMods = pAction->mods.mask;
242 }
243 else {
244 xkbi->groupChange = XkbSAGroup(&pAction->group);
245 if (pAction->group.flags & XkbSA_GroupAbsolute)
246 xkbi->groupChange -= xkbi->state.base_group;
247 filter->upAction = *pAction;
248 XkbSASetGroup(&filter->upAction.group, xkbi->groupChange);
249 }
250 }
251 else if (pAction && (filter->priv == LATCH_PENDING)) {
252 if (((1 << pAction->type) & XkbSA_BreakLatch) != 0) {
253 filter->active = 0;
254 /* If one latch is broken, all latches are broken, so it's no use
255 to find out which particular latch this filter tracks. */
256 xkbi->state.latched_mods = 0;
257 xkbi->state.latched_group = 0;
258 }
259 }
260 else if (filter->keycode == keycode && filter->priv != LATCH_PENDING){
261 /* The test above for LATCH_PENDING skips subsequent releases of the
262 key after it has been released first time and the latch became
263 pending. */
264 XkbControlsPtr ctrls = xkbi->desc->ctrls;
265 int needBeep = ((ctrls->enabled_ctrls & XkbStickyKeysMask) &&
266 XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask));
267
268 if (filter->upAction.type == XkbSA_LatchMods) {
269 unsigned char mask = filter->upAction.mods.mask;
270 unsigned char common;
271
272 xkbi->clearMods = mask;
273
274 /* ClearLocks */
275 common = mask & xkbi->state.locked_mods;
276 if ((filter->upAction.mods.flags & XkbSA_ClearLocks) && common) {
277 mask &= ~common;
278 xkbi->state.locked_mods &= ~common;
279 if (needBeep)
280 XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK,
281 XkbStickyKeysMask);
282 }
283 /* LatchToLock */
284 common = mask & xkbi->state.latched_mods;
285 if ((filter->upAction.mods.flags & XkbSA_LatchToLock) && common) {
286 unsigned char newlocked;
287
288 mask &= ~common;
289 newlocked = common & ~xkbi->state.locked_mods;
290 if(newlocked){
291 xkbi->state.locked_mods |= newlocked;
292 if (needBeep)
293 XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK,
294 XkbStickyKeysMask);
295
296 }
297 xkbi->state.latched_mods &= ~common;
298 }
299 /* Latch remaining modifiers, if any. */
300 if (mask) {
301 xkbi->state.latched_mods |= mask;
302 filter->priv = LATCH_PENDING;
303 if (needBeep)
304 XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH,
305 XkbStickyKeysMask);
306 }
307 }
308 else {
309 xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
310 /* ClearLocks */
311 if ((filter->upAction.group.flags & XkbSA_ClearLocks) &&
312 (xkbi->state.locked_group)) {
313 xkbi->state.locked_group = 0;
314 if (needBeep)
315 XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK,
316 XkbStickyKeysMask);
317 }
318 /* LatchToLock */
319 else if ((filter->upAction.group.flags & XkbSA_LatchToLock)
320 && (xkbi->state.latched_group)) {
321 xkbi->state.locked_group += XkbSAGroup(&filter->upAction.group);
322 xkbi->state.latched_group -= XkbSAGroup(&filter->upAction.group);
323 if(XkbSAGroup(&filter->upAction.group) && needBeep)
324 XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK,
325 XkbStickyKeysMask);
326 }
327 /* Latch group */
328 else if(XkbSAGroup(&filter->upAction.group)){
329 xkbi->state.latched_group += XkbSAGroup(&filter->upAction.group);
330 filter->priv = LATCH_PENDING;
331 if (needBeep)
332 XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH,
333 XkbStickyKeysMask);
334 }
335 }
336
337 if (filter->priv != LATCH_PENDING)
338 filter->active = 0;
339 }
340 else if (pAction && (filter->priv == LATCH_KEY_DOWN)) {
341 /* Latch was broken before it became pending: degrade to a
342 SetMods/SetGroup. */
343 if (filter->upAction.type == XkbSA_LatchMods)
344 filter->upAction.type = XkbSA_SetMods;
345 else
346 filter->upAction.type = XkbSA_SetGroup;
347 filter->filter = _XkbFilterSetState;
348 filter->priv = 0;
349 return filter->filter(xkbi, filter, keycode, pAction);
350 }
351 return 1;
352 }
353
354 static int
_XkbFilterLockState(XkbSrvInfoPtr xkbi,XkbFilterPtr filter,unsigned keycode,XkbAction * pAction)355 _XkbFilterLockState(XkbSrvInfoPtr xkbi,
356 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
357 {
358 if (filter->keycode == 0) /* initial press */
359 AccessXCancelRepeatKey(xkbi, keycode);
360
361 if (pAction && (pAction->type == XkbSA_LockGroup)) {
362 if (pAction->group.flags & XkbSA_GroupAbsolute)
363 xkbi->state.locked_group = XkbSAGroup(&pAction->group);
364 else
365 xkbi->state.locked_group += XkbSAGroup(&pAction->group);
366 return 1;
367 }
368 if (filter->keycode == 0) { /* initial press */
369 filter->keycode = keycode;
370 filter->active = 1;
371 filter->filterOthers = 0;
372 filter->priv = xkbi->state.locked_mods & pAction->mods.mask;
373 filter->filter = _XkbFilterLockState;
374 filter->upAction = *pAction;
375 if (!(filter->upAction.mods.flags & XkbSA_LockNoLock))
376 xkbi->state.locked_mods |= pAction->mods.mask;
377 xkbi->setMods = pAction->mods.mask;
378 }
379 else if (filter->keycode == keycode) {
380 filter->active = 0;
381 xkbi->clearMods = filter->upAction.mods.mask;
382 if (!(filter->upAction.mods.flags & XkbSA_LockNoUnlock))
383 xkbi->state.locked_mods &= ~filter->priv;
384 }
385 return 1;
386 }
387
388 #define ISO_KEY_DOWN 0
389 #define NO_ISO_LOCK 1
390
391 static int
_XkbFilterISOLock(XkbSrvInfoPtr xkbi,XkbFilterPtr filter,unsigned keycode,XkbAction * pAction)392 _XkbFilterISOLock(XkbSrvInfoPtr xkbi,
393 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
394 {
395
396 if (filter->keycode == 0) { /* initial press */
397 CARD8 flags = pAction->iso.flags;
398
399 filter->keycode = keycode;
400 filter->active = 1;
401 filter->filterOthers = 1;
402 filter->priv = ISO_KEY_DOWN;
403 filter->upAction = *pAction;
404 filter->filter = _XkbFilterISOLock;
405 if (flags & XkbSA_ISODfltIsGroup) {
406 xkbi->groupChange = XkbSAGroup(&pAction->iso);
407 xkbi->setMods = 0;
408 }
409 else {
410 xkbi->setMods = pAction->iso.mask;
411 xkbi->groupChange = 0;
412 }
413 if ((!(flags & XkbSA_ISONoAffectMods)) && (xkbi->state.base_mods)) {
414 filter->priv = NO_ISO_LOCK;
415 xkbi->state.locked_mods ^= xkbi->state.base_mods;
416 }
417 if ((!(flags & XkbSA_ISONoAffectGroup)) && (xkbi->state.base_group)) {
418 /* 6/22/93 (ef) -- lock groups if group key is down first */
419 }
420 if (!(flags & XkbSA_ISONoAffectPtr)) {
421 /* 6/22/93 (ef) -- lock mouse buttons if they're down */
422 }
423 }
424 else if (filter->keycode == keycode) {
425 CARD8 flags = filter->upAction.iso.flags;
426
427 if (flags & XkbSA_ISODfltIsGroup) {
428 xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
429 xkbi->clearMods = 0;
430 if (filter->priv == ISO_KEY_DOWN)
431 xkbi->state.locked_group += XkbSAGroup(&filter->upAction.iso);
432 }
433 else {
434 xkbi->clearMods = filter->upAction.iso.mask;
435 xkbi->groupChange = 0;
436 if (filter->priv == ISO_KEY_DOWN)
437 xkbi->state.locked_mods ^= filter->upAction.iso.mask;
438 }
439 filter->active = 0;
440 }
441 else if (pAction) {
442 CARD8 flags = filter->upAction.iso.flags;
443
444 switch (pAction->type) {
445 case XkbSA_SetMods:
446 case XkbSA_LatchMods:
447 if (!(flags & XkbSA_ISONoAffectMods)) {
448 pAction->type = XkbSA_LockMods;
449 filter->priv = NO_ISO_LOCK;
450 }
451 break;
452 case XkbSA_SetGroup:
453 case XkbSA_LatchGroup:
454 if (!(flags & XkbSA_ISONoAffectGroup)) {
455 pAction->type = XkbSA_LockGroup;
456 filter->priv = NO_ISO_LOCK;
457 }
458 break;
459 case XkbSA_PtrBtn:
460 if (!(flags & XkbSA_ISONoAffectPtr)) {
461 pAction->type = XkbSA_LockPtrBtn;
462 filter->priv = NO_ISO_LOCK;
463 }
464 break;
465 case XkbSA_SetControls:
466 if (!(flags & XkbSA_ISONoAffectCtrls)) {
467 pAction->type = XkbSA_LockControls;
468 filter->priv = NO_ISO_LOCK;
469 }
470 break;
471 }
472 }
473 return 1;
474 }
475
476 static CARD32
_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,void * arg)477 _XkbPtrAccelExpire(OsTimerPtr timer, CARD32 now, void *arg)
478 {
479 XkbSrvInfoPtr xkbi = (XkbSrvInfoPtr) arg;
480 XkbControlsPtr ctrls = xkbi->desc->ctrls;
481 int dx, dy;
482
483 if (xkbi->mouseKey == 0)
484 return 0;
485
486 if (xkbi->mouseKeysAccel) {
487 if ((xkbi->mouseKeysCounter) < ctrls->mk_time_to_max) {
488 double step;
489
490 xkbi->mouseKeysCounter++;
491 step = xkbi->mouseKeysCurveFactor *
492 pow((double) xkbi->mouseKeysCounter, xkbi->mouseKeysCurve);
493 if (xkbi->mouseKeysDX < 0)
494 dx = floor(((double) xkbi->mouseKeysDX) * step);
495 else
496 dx = ceil(((double) xkbi->mouseKeysDX) * step);
497 if (xkbi->mouseKeysDY < 0)
498 dy = floor(((double) xkbi->mouseKeysDY) * step);
499 else
500 dy = ceil(((double) xkbi->mouseKeysDY) * step);
501 }
502 else {
503 dx = xkbi->mouseKeysDX * ctrls->mk_max_speed;
504 dy = xkbi->mouseKeysDY * ctrls->mk_max_speed;
505 }
506 if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteX)
507 dx = xkbi->mouseKeysDX;
508 if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteY)
509 dy = xkbi->mouseKeysDY;
510 }
511 else {
512 dx = xkbi->mouseKeysDX;
513 dy = xkbi->mouseKeysDY;
514 }
515 XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags, dx, dy);
516 return xkbi->desc->ctrls->mk_interval;
517 }
518
519 static int
_XkbFilterPointerMove(XkbSrvInfoPtr xkbi,XkbFilterPtr filter,unsigned keycode,XkbAction * pAction)520 _XkbFilterPointerMove(XkbSrvInfoPtr xkbi,
521 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
522 {
523 int x, y;
524 Bool accel;
525
526 if (filter->keycode == 0) { /* initial press */
527 filter->keycode = keycode;
528 filter->active = 1;
529 filter->filterOthers = 0;
530 filter->priv = 0;
531 filter->filter = _XkbFilterPointerMove;
532 filter->upAction = *pAction;
533 xkbi->mouseKeysCounter = 0;
534 xkbi->mouseKey = keycode;
535 accel = ((pAction->ptr.flags & XkbSA_NoAcceleration) == 0);
536 x = XkbPtrActionX(&pAction->ptr);
537 y = XkbPtrActionY(&pAction->ptr);
538 XkbFakePointerMotion(xkbi->device, pAction->ptr.flags, x, y);
539 AccessXCancelRepeatKey(xkbi, keycode);
540 xkbi->mouseKeysAccel = accel &&
541 (xkbi->desc->ctrls->enabled_ctrls & XkbMouseKeysAccelMask);
542 xkbi->mouseKeysFlags = pAction->ptr.flags;
543 xkbi->mouseKeysDX = XkbPtrActionX(&pAction->ptr);
544 xkbi->mouseKeysDY = XkbPtrActionY(&pAction->ptr);
545 xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0,
546 xkbi->desc->ctrls->mk_delay,
547 _XkbPtrAccelExpire, (void *) xkbi);
548 }
549 else if (filter->keycode == keycode) {
550 filter->active = 0;
551 if (xkbi->mouseKey == keycode) {
552 xkbi->mouseKey = 0;
553 xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0, 0,
554 NULL, NULL);
555 }
556 }
557 return 0;
558 }
559
560 static int
_XkbFilterPointerBtn(XkbSrvInfoPtr xkbi,XkbFilterPtr filter,unsigned keycode,XkbAction * pAction)561 _XkbFilterPointerBtn(XkbSrvInfoPtr xkbi,
562 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
563 {
564 if (filter->keycode == 0) { /* initial press */
565 int button = pAction->btn.button;
566
567 if (button == XkbSA_UseDfltButton)
568 button = xkbi->desc->ctrls->mk_dflt_btn;
569
570 filter->keycode = keycode;
571 filter->active = 1;
572 filter->filterOthers = 0;
573 filter->priv = 0;
574 filter->filter = _XkbFilterPointerBtn;
575 filter->upAction = *pAction;
576 filter->upAction.btn.button = button;
577 switch (pAction->type) {
578 case XkbSA_LockPtrBtn:
579 if (((xkbi->lockedPtrButtons & (1 << button)) == 0) &&
580 ((pAction->btn.flags & XkbSA_LockNoLock) == 0)) {
581 xkbi->lockedPtrButtons |= (1 << button);
582 AccessXCancelRepeatKey(xkbi, keycode);
583 XkbFakeDeviceButton(xkbi->device, 1, button);
584 filter->upAction.type = XkbSA_NoAction;
585 }
586 break;
587 case XkbSA_PtrBtn:
588 {
589 register int i, nClicks;
590
591 AccessXCancelRepeatKey(xkbi, keycode);
592 if (pAction->btn.count > 0) {
593 nClicks = pAction->btn.count;
594 for (i = 0; i < nClicks; i++) {
595 XkbFakeDeviceButton(xkbi->device, 1, button);
596 XkbFakeDeviceButton(xkbi->device, 0, button);
597 }
598 filter->upAction.type = XkbSA_NoAction;
599 }
600 else
601 XkbFakeDeviceButton(xkbi->device, 1, button);
602 }
603 break;
604 case XkbSA_SetPtrDflt:
605 {
606 XkbControlsPtr ctrls = xkbi->desc->ctrls;
607 XkbControlsRec old;
608 xkbControlsNotify cn;
609
610 old = *ctrls;
611 AccessXCancelRepeatKey(xkbi, keycode);
612 switch (pAction->dflt.affect) {
613 case XkbSA_AffectDfltBtn:
614 if (pAction->dflt.flags & XkbSA_DfltBtnAbsolute)
615 ctrls->mk_dflt_btn = XkbSAPtrDfltValue(&pAction->dflt);
616 else {
617 ctrls->mk_dflt_btn += XkbSAPtrDfltValue(&pAction->dflt);
618 if (ctrls->mk_dflt_btn > 5)
619 ctrls->mk_dflt_btn = 5;
620 else if (ctrls->mk_dflt_btn < 1)
621 ctrls->mk_dflt_btn = 1;
622 }
623 break;
624 default:
625 ErrorF
626 ("Attempt to change unknown pointer default (%d) ignored\n",
627 pAction->dflt.affect);
628 break;
629 }
630 if (XkbComputeControlsNotify(xkbi->device,
631 &old, xkbi->desc->ctrls, &cn, FALSE)) {
632 cn.keycode = keycode;
633 /* XXX: what about DeviceKeyPress? */
634 cn.eventType = KeyPress;
635 cn.requestMajor = 0;
636 cn.requestMinor = 0;
637 XkbSendControlsNotify(xkbi->device, &cn);
638 }
639 }
640 break;
641 }
642 return 0;
643 }
644 else if (filter->keycode == keycode) {
645 int button = filter->upAction.btn.button;
646
647 switch (filter->upAction.type) {
648 case XkbSA_LockPtrBtn:
649 if (((filter->upAction.btn.flags & XkbSA_LockNoUnlock) != 0) ||
650 ((xkbi->lockedPtrButtons & (1 << button)) == 0)) {
651 break;
652 }
653 xkbi->lockedPtrButtons &= ~(1 << button);
654
655 if (IsMaster(xkbi->device)) {
656 XkbMergeLockedPtrBtns(xkbi->device);
657 /* One SD still has lock set, don't post event */
658 if ((xkbi->lockedPtrButtons & (1 << button)) != 0)
659 break;
660 }
661
662 /* fallthrough */
663 case XkbSA_PtrBtn:
664 XkbFakeDeviceButton(xkbi->device, 0, button);
665 break;
666 }
667 filter->active = 0;
668 return 0;
669 }
670 return 1;
671 }
672
673 static int
_XkbFilterControls(XkbSrvInfoPtr xkbi,XkbFilterPtr filter,unsigned keycode,XkbAction * pAction)674 _XkbFilterControls(XkbSrvInfoPtr xkbi,
675 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
676 {
677 XkbControlsRec old;
678 XkbControlsPtr ctrls;
679 DeviceIntPtr kbd;
680 unsigned int change;
681 XkbEventCauseRec cause;
682
683 kbd = xkbi->device;
684 ctrls = xkbi->desc->ctrls;
685 old = *ctrls;
686 if (filter->keycode == 0) { /* initial press */
687 AccessXCancelRepeatKey(xkbi, keycode);
688 filter->keycode = keycode;
689 filter->active = 1;
690 filter->filterOthers = 0;
691 change = XkbActionCtrls(&pAction->ctrls);
692 filter->priv = change;
693 filter->filter = _XkbFilterControls;
694 filter->upAction = *pAction;
695
696 if (pAction->type == XkbSA_LockControls) {
697 filter->priv = (ctrls->enabled_ctrls & change);
698 change &= ~ctrls->enabled_ctrls;
699 }
700
701 if (change) {
702 xkbControlsNotify cn;
703 XkbSrvLedInfoPtr sli;
704
705 ctrls->enabled_ctrls |= change;
706 if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE)) {
707 cn.keycode = keycode;
708 /* XXX: what about DeviceKeyPress? */
709 cn.eventType = KeyPress;
710 cn.requestMajor = 0;
711 cn.requestMinor = 0;
712 XkbSendControlsNotify(kbd, &cn);
713 }
714
715 XkbSetCauseKey(&cause, keycode, KeyPress);
716
717 /* If sticky keys were disabled, clear all locks and latches */
718 if ((old.enabled_ctrls & XkbStickyKeysMask) &&
719 (!(ctrls->enabled_ctrls & XkbStickyKeysMask))) {
720 XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE, &cause);
721 }
722 sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0);
723 XkbUpdateIndicators(kbd, sli->usesControls, TRUE, NULL, &cause);
724 if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask))
725 XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_ON, change);
726 }
727 }
728 else if (filter->keycode == keycode) {
729 change = filter->priv;
730 if (change) {
731 xkbControlsNotify cn;
732 XkbSrvLedInfoPtr sli;
733
734 ctrls->enabled_ctrls &= ~change;
735 if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE)) {
736 cn.keycode = keycode;
737 cn.eventType = KeyRelease;
738 cn.requestMajor = 0;
739 cn.requestMinor = 0;
740 XkbSendControlsNotify(kbd, &cn);
741 }
742
743 XkbSetCauseKey(&cause, keycode, KeyRelease);
744 /* If sticky keys were disabled, clear all locks and latches */
745 if ((old.enabled_ctrls & XkbStickyKeysMask) &&
746 (!(ctrls->enabled_ctrls & XkbStickyKeysMask))) {
747 XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE, &cause);
748 }
749 sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0);
750 XkbUpdateIndicators(kbd, sli->usesControls, TRUE, NULL, &cause);
751 if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask))
752 XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_OFF, change);
753 }
754 filter->keycode = 0;
755 filter->active = 0;
756 }
757 return 1;
758 }
759
760 static int
_XkbFilterActionMessage(XkbSrvInfoPtr xkbi,XkbFilterPtr filter,unsigned keycode,XkbAction * pAction)761 _XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
762 XkbFilterPtr filter,
763 unsigned keycode, XkbAction *pAction)
764 {
765 XkbMessageAction *pMsg;
766 DeviceIntPtr kbd;
767
768 if ((filter->keycode != 0) && (filter->keycode != keycode))
769 return 1;
770
771 /* This can happen if the key repeats, and the state (modifiers or group)
772 changes meanwhile. */
773 if ((filter->keycode == keycode) && pAction &&
774 (pAction->type != XkbSA_ActionMessage))
775 return 1;
776
777 kbd = xkbi->device;
778 if (filter->keycode == 0) { /* initial press */
779 pMsg = &pAction->msg;
780 if ((pMsg->flags & XkbSA_MessageOnRelease) ||
781 ((pMsg->flags & XkbSA_MessageGenKeyEvent) == 0)) {
782 filter->keycode = keycode;
783 filter->active = 1;
784 filter->filterOthers = 0;
785 filter->priv = 0;
786 filter->filter = _XkbFilterActionMessage;
787 filter->upAction = *pAction;
788 }
789 if (pMsg->flags & XkbSA_MessageOnPress) {
790 xkbActionMessage msg;
791
792 msg.keycode = keycode;
793 msg.press = 1;
794 msg.keyEventFollows =
795 ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
796 memcpy((char *) msg.message, (char *) pMsg->message,
797 XkbActionMessageLength);
798 XkbSendActionMessage(kbd, &msg);
799 }
800 return ((pAction->msg.flags & XkbSA_MessageGenKeyEvent) != 0);
801 }
802 else if (filter->keycode == keycode) {
803 pMsg = &filter->upAction.msg;
804 if (pAction == NULL) {
805 if (pMsg->flags & XkbSA_MessageOnRelease) {
806 xkbActionMessage msg;
807
808 msg.keycode = keycode;
809 msg.press = 0;
810 msg.keyEventFollows =
811 ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
812 memcpy((char *) msg.message, (char *) pMsg->message,
813 XkbActionMessageLength);
814 XkbSendActionMessage(kbd, &msg);
815 }
816 filter->keycode = 0;
817 filter->active = 0;
818 return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
819 } else if (memcmp(pMsg, pAction, 8) == 0) {
820 /* Repeat: If we send the same message, avoid multiple messages
821 on release from piling up. */
822 filter->keycode = 0;
823 filter->active = 0;
824 }
825 }
826 return 1;
827 }
828
829 static int
_XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,XkbFilterPtr filter,unsigned keycode,XkbAction * pAction)830 _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
831 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
832 {
833 DeviceEvent ev;
834 int x, y;
835 XkbStateRec old, old_prev;
836 unsigned mods, mask;
837 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
838 ProcessInputProc backupproc;
839
840 if ((filter->keycode != 0) && (filter->keycode != keycode))
841 return 1;
842
843 /* This can happen if the key repeats, and the state (modifiers or group)
844 changes meanwhile. */
845 if ((filter->keycode == keycode) && pAction &&
846 (pAction->type != XkbSA_RedirectKey))
847 return 1;
848
849 /* never actually used uninitialised, but gcc isn't smart enough
850 * to work that out. */
851 memset(&old, 0, sizeof(old));
852 memset(&old_prev, 0, sizeof(old_prev));
853 memset(&ev, 0, sizeof(ev));
854
855 GetSpritePosition(xkbi->device, &x, &y);
856 ev.header = ET_Internal;
857 ev.length = sizeof(DeviceEvent);
858 ev.time = GetTimeInMillis();
859 ev.root_x = x;
860 ev.root_y = y;
861 /* redirect actions do not work across devices, therefore the following is
862 * correct: */
863 ev.deviceid = xkbi->device->id;
864 /* filter->priv must be set up by the caller for the initial press. */
865 ev.sourceid = filter->priv;
866
867 if (filter->keycode == 0) { /* initial press */
868 if ((pAction->redirect.new_key < xkbi->desc->min_key_code) ||
869 (pAction->redirect.new_key > xkbi->desc->max_key_code)) {
870 return 1;
871 }
872 filter->keycode = keycode;
873 filter->active = 1;
874 filter->filterOthers = 0;
875 filter->filter = _XkbFilterRedirectKey;
876 filter->upAction = *pAction;
877
878 ev.type = ET_KeyPress;
879 ev.detail.key = pAction->redirect.new_key;
880
881 mask = XkbSARedirectVModsMask(&pAction->redirect);
882 mods = XkbSARedirectVMods(&pAction->redirect);
883 if (mask)
884 XkbVirtualModsToReal(xkbi->desc, mask, &mask);
885 if (mods)
886 XkbVirtualModsToReal(xkbi->desc, mods, &mods);
887 mask |= pAction->redirect.mods_mask;
888 mods |= pAction->redirect.mods;
889
890 if (mask || mods) {
891 old = xkbi->state;
892 old_prev = xkbi->prev_state;
893 xkbi->state.base_mods &= ~mask;
894 xkbi->state.base_mods |= (mods & mask);
895 xkbi->state.latched_mods &= ~mask;
896 xkbi->state.latched_mods |= (mods & mask);
897 xkbi->state.locked_mods &= ~mask;
898 xkbi->state.locked_mods |= (mods & mask);
899 XkbComputeDerivedState(xkbi);
900 xkbi->prev_state = xkbi->state;
901 }
902
903 UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
904 xkbi->device->public.processInputProc((InternalEvent *) &ev,
905 xkbi->device);
906 COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
907 xkbUnwrapProc);
908
909 if (mask || mods) {
910 xkbi->state = old;
911 xkbi->prev_state = old_prev;
912 }
913 return 0;
914 }
915 else {
916 /* If it is a key release, or we redirect to another key, release the
917 previous new_key. Otherwise, repeat. */
918 ev.detail.key = filter->upAction.redirect.new_key;
919 if (pAction == NULL || ev.detail.key != pAction->redirect.new_key) {
920 ev.type = ET_KeyRelease;
921 filter->active = 0;
922 }
923 else {
924 ev.type = ET_KeyPress;
925 ev.key_repeat = TRUE;
926 }
927
928 mask = XkbSARedirectVModsMask(&filter->upAction.redirect);
929 mods = XkbSARedirectVMods(&filter->upAction.redirect);
930 if (mask)
931 XkbVirtualModsToReal(xkbi->desc, mask, &mask);
932 if (mods)
933 XkbVirtualModsToReal(xkbi->desc, mods, &mods);
934 mask |= filter->upAction.redirect.mods_mask;
935 mods |= filter->upAction.redirect.mods;
936
937 if (mask || mods) {
938 old = xkbi->state;
939 old_prev = xkbi->prev_state;
940 xkbi->state.base_mods &= ~mask;
941 xkbi->state.base_mods |= (mods & mask);
942 xkbi->state.latched_mods &= ~mask;
943 xkbi->state.latched_mods |= (mods & mask);
944 xkbi->state.locked_mods &= ~mask;
945 xkbi->state.locked_mods |= (mods & mask);
946 XkbComputeDerivedState(xkbi);
947 xkbi->prev_state = xkbi->state;
948 }
949
950 UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
951 xkbi->device->public.processInputProc((InternalEvent *) &ev,
952 xkbi->device);
953 COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
954 xkbUnwrapProc);
955
956 if (mask || mods) {
957 xkbi->state = old;
958 xkbi->prev_state = old_prev;
959 }
960
961 /* We return 1 in case we have sent a release event because the new_key
962 has changed. Then, subsequently, we will call this function again
963 with the same pAction, which will create the press for the new
964 new_key. */
965 return (pAction && ev.detail.key != pAction->redirect.new_key);
966 }
967 }
968
969 static int
_XkbFilterSwitchScreen(XkbSrvInfoPtr xkbi,XkbFilterPtr filter,unsigned keycode,XkbAction * pAction)970 _XkbFilterSwitchScreen(XkbSrvInfoPtr xkbi,
971 XkbFilterPtr filter,
972 unsigned keycode, XkbAction *pAction)
973 {
974 DeviceIntPtr dev = xkbi->device;
975
976 if (dev == inputInfo.keyboard)
977 return 0;
978
979 if (filter->keycode == 0) { /* initial press */
980 filter->keycode = keycode;
981 filter->active = 1;
982 filter->filterOthers = 0;
983 filter->filter = _XkbFilterSwitchScreen;
984 AccessXCancelRepeatKey(xkbi, keycode);
985 XkbDDXSwitchScreen(dev, keycode, pAction);
986 return 0;
987 }
988 else if (filter->keycode == keycode) {
989 filter->active = 0;
990 return 0;
991 }
992 return 1;
993 }
994
995 static int
_XkbFilterXF86Private(XkbSrvInfoPtr xkbi,XkbFilterPtr filter,unsigned keycode,XkbAction * pAction)996 _XkbFilterXF86Private(XkbSrvInfoPtr xkbi,
997 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
998 {
999 DeviceIntPtr dev = xkbi->device;
1000
1001 if (dev == inputInfo.keyboard)
1002 return 0;
1003
1004 if (filter->keycode == 0) { /* initial press */
1005 filter->keycode = keycode;
1006 filter->active = 1;
1007 filter->filterOthers = 0;
1008 filter->filter = _XkbFilterXF86Private;
1009 XkbDDXPrivate(dev, keycode, pAction);
1010 return 0;
1011 }
1012 else if (filter->keycode == keycode) {
1013 filter->active = 0;
1014 return 0;
1015 }
1016 return 1;
1017 }
1018
1019 static int
_XkbFilterDeviceBtn(XkbSrvInfoPtr xkbi,XkbFilterPtr filter,unsigned keycode,XkbAction * pAction)1020 _XkbFilterDeviceBtn(XkbSrvInfoPtr xkbi,
1021 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
1022 {
1023 if (xkbi->device == inputInfo.keyboard)
1024 return 0;
1025
1026 if (filter->keycode == 0) { /* initial press */
1027 DeviceIntPtr dev;
1028 int button;
1029
1030 _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient,
1031 DixUnknownAccess, &button);
1032 if (!dev || !dev->public.on)
1033 return 1;
1034
1035 button = pAction->devbtn.button;
1036 if ((button < 1) || (button > dev->button->numButtons))
1037 return 1;
1038
1039 filter->keycode = keycode;
1040 filter->active = 1;
1041 filter->filterOthers = 0;
1042 filter->priv = 0;
1043 filter->filter = _XkbFilterDeviceBtn;
1044 filter->upAction = *pAction;
1045 switch (pAction->type) {
1046 case XkbSA_LockDeviceBtn:
1047 if ((pAction->devbtn.flags & XkbSA_LockNoLock) ||
1048 BitIsOn(dev->button->down, button))
1049 return 0;
1050 XkbFakeDeviceButton(dev, TRUE, button);
1051 filter->upAction.type = XkbSA_NoAction;
1052 break;
1053 case XkbSA_DeviceBtn:
1054 if (pAction->devbtn.count > 0) {
1055 int nClicks, i;
1056
1057 nClicks = pAction->btn.count;
1058 for (i = 0; i < nClicks; i++) {
1059 XkbFakeDeviceButton(dev, TRUE, button);
1060 XkbFakeDeviceButton(dev, FALSE, button);
1061 }
1062 filter->upAction.type = XkbSA_NoAction;
1063 }
1064 else
1065 XkbFakeDeviceButton(dev, TRUE, button);
1066 break;
1067 }
1068 }
1069 else if (filter->keycode == keycode) {
1070 DeviceIntPtr dev;
1071 int button;
1072
1073 filter->active = 0;
1074 _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device,
1075 serverClient, DixUnknownAccess, &button);
1076 if (!dev || !dev->public.on)
1077 return 1;
1078
1079 button = filter->upAction.btn.button;
1080 switch (filter->upAction.type) {
1081 case XkbSA_LockDeviceBtn:
1082 if ((filter->upAction.devbtn.flags & XkbSA_LockNoUnlock) ||
1083 !BitIsOn(dev->button->down, button))
1084 return 0;
1085 XkbFakeDeviceButton(dev, FALSE, button);
1086 break;
1087 case XkbSA_DeviceBtn:
1088 XkbFakeDeviceButton(dev, FALSE, button);
1089 break;
1090 }
1091 filter->active = 0;
1092 }
1093 return 0;
1094 }
1095
1096 static XkbFilterPtr
_XkbNextFreeFilter(XkbSrvInfoPtr xkbi)1097 _XkbNextFreeFilter(XkbSrvInfoPtr xkbi)
1098 {
1099 register int i;
1100
1101 if (xkbi->szFilters == 0) {
1102 xkbi->szFilters = 4;
1103 xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec));
1104 /* 6/21/93 (ef) -- XXX! deal with allocation failure */
1105 }
1106 for (i = 0; i < xkbi->szFilters; i++) {
1107 if (!xkbi->filters[i].active) {
1108 xkbi->filters[i].keycode = 0;
1109 return &xkbi->filters[i];
1110 }
1111 }
1112 xkbi->szFilters *= 2;
1113 xkbi->filters = reallocarray(xkbi->filters,
1114 xkbi->szFilters, sizeof(XkbFilterRec));
1115 /* 6/21/93 (ef) -- XXX! deal with allocation failure */
1116 memset(&xkbi->filters[xkbi->szFilters / 2], 0,
1117 (xkbi->szFilters / 2) * sizeof(XkbFilterRec));
1118 return &xkbi->filters[xkbi->szFilters / 2];
1119 }
1120
1121 static int
_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction * pAction)1122 _XkbApplyFilters(XkbSrvInfoPtr xkbi, unsigned kc, XkbAction *pAction)
1123 {
1124 register int i, send;
1125
1126 send = 1;
1127 for (i = 0; i < xkbi->szFilters; i++) {
1128 if ((xkbi->filters[i].active) && (xkbi->filters[i].filter))
1129 send =
1130 ((*xkbi->filters[i].filter) (xkbi, &xkbi->filters[i], kc,
1131 pAction)
1132 && send);
1133 }
1134 return send;
1135 }
1136
1137 static int
_XkbEnsureStateChange(XkbSrvInfoPtr xkbi)1138 _XkbEnsureStateChange(XkbSrvInfoPtr xkbi)
1139 {
1140 Bool genStateNotify = FALSE;
1141
1142 /* The state may change, so if we're not in the middle of sending a state
1143 * notify, prepare for it */
1144 if ((xkbi->flags & _XkbStateNotifyInProgress) == 0) {
1145 xkbi->prev_state = xkbi->state;
1146 xkbi->flags |= _XkbStateNotifyInProgress;
1147 genStateNotify = TRUE;
1148 }
1149
1150 return genStateNotify;
1151 }
1152
1153 static void
_XkbApplyState(DeviceIntPtr dev,Bool genStateNotify,int evtype,int key)1154 _XkbApplyState(DeviceIntPtr dev, Bool genStateNotify, int evtype, int key)
1155 {
1156 XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
1157 int changed;
1158
1159 XkbComputeDerivedState(xkbi);
1160
1161 changed = XkbStateChangedFlags(&xkbi->prev_state, &xkbi->state);
1162 if (genStateNotify) {
1163 if (changed) {
1164 xkbStateNotify sn;
1165
1166 sn.keycode = key;
1167 sn.eventType = evtype;
1168 sn.requestMajor = sn.requestMinor = 0;
1169 sn.changed = changed;
1170 XkbSendStateNotify(dev, &sn);
1171 }
1172 xkbi->flags &= ~_XkbStateNotifyInProgress;
1173 }
1174
1175 changed = XkbIndicatorsToUpdate(dev, changed, FALSE);
1176 if (changed) {
1177 XkbEventCauseRec cause;
1178 XkbSetCauseKey(&cause, key, evtype);
1179 XkbUpdateIndicators(dev, changed, FALSE, NULL, &cause);
1180 }
1181 }
1182
1183 void
XkbPushLockedStateToSlaves(DeviceIntPtr master,int evtype,int key)1184 XkbPushLockedStateToSlaves(DeviceIntPtr master, int evtype, int key)
1185 {
1186 DeviceIntPtr dev;
1187 Bool genStateNotify;
1188
1189 nt_list_for_each_entry(dev, inputInfo.devices, next) {
1190 if (!dev->key || GetMaster(dev, MASTER_KEYBOARD) != master)
1191 continue;
1192
1193 genStateNotify = _XkbEnsureStateChange(dev->key->xkbInfo);
1194
1195 dev->key->xkbInfo->state.locked_mods =
1196 master->key->xkbInfo->state.locked_mods;
1197
1198 _XkbApplyState(dev, genStateNotify, evtype, key);
1199 }
1200 }
1201
1202 static void
XkbActionGetFilter(DeviceIntPtr dev,DeviceEvent * event,KeyCode key,XkbAction * act,int * sendEvent)1203 XkbActionGetFilter(DeviceIntPtr dev, DeviceEvent *event, KeyCode key,
1204 XkbAction *act, int *sendEvent)
1205 {
1206 XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
1207 XkbFilterPtr filter;
1208
1209 /* For focus events, we only want to run actions which update our state to
1210 * (hopefully vaguely kinda) match that of the host server, rather than
1211 * actually execute anything. For example, if we enter our VT with
1212 * Ctrl+Alt+Backspace held down, we don't want to terminate our server
1213 * immediately, but we _do_ want Ctrl+Alt to be latched down, so if
1214 * Backspace is released and then pressed again, the server will terminate.
1215 *
1216 * This is pretty flaky, and we should in fact inherit the complete state
1217 * from the host server. There are some state combinations that we cannot
1218 * express by running the state machine over every key, e.g. if AltGr+Shift
1219 * generates a different state to Shift+AltGr. */
1220 if (event->source_type == EVENT_SOURCE_FOCUS) {
1221 switch (act->type) {
1222 case XkbSA_SetMods:
1223 case XkbSA_SetGroup:
1224 case XkbSA_LatchMods:
1225 case XkbSA_LatchGroup:
1226 case XkbSA_LockMods:
1227 case XkbSA_LockGroup:
1228 break;
1229 default:
1230 *sendEvent = 1;
1231 return;
1232 }
1233 }
1234
1235 switch (act->type) {
1236 case XkbSA_SetMods:
1237 case XkbSA_SetGroup:
1238 filter = _XkbNextFreeFilter(xkbi);
1239 *sendEvent = _XkbFilterSetState(xkbi, filter, key, act);
1240 break;
1241 case XkbSA_LatchMods:
1242 case XkbSA_LatchGroup:
1243 filter = _XkbNextFreeFilter(xkbi);
1244 *sendEvent = _XkbFilterLatchState(xkbi, filter, key, act);
1245 break;
1246 case XkbSA_LockMods:
1247 case XkbSA_LockGroup:
1248 filter = _XkbNextFreeFilter(xkbi);
1249 *sendEvent = _XkbFilterLockState(xkbi, filter, key, act);
1250 break;
1251 case XkbSA_ISOLock:
1252 filter = _XkbNextFreeFilter(xkbi);
1253 *sendEvent = _XkbFilterISOLock(xkbi, filter, key, act);
1254 break;
1255 case XkbSA_MovePtr:
1256 filter = _XkbNextFreeFilter(xkbi);
1257 *sendEvent = _XkbFilterPointerMove(xkbi, filter, key, act);
1258 break;
1259 case XkbSA_PtrBtn:
1260 case XkbSA_LockPtrBtn:
1261 case XkbSA_SetPtrDflt:
1262 filter = _XkbNextFreeFilter(xkbi);
1263 *sendEvent = _XkbFilterPointerBtn(xkbi, filter, key, act);
1264 break;
1265 case XkbSA_Terminate:
1266 *sendEvent = XkbDDXTerminateServer(dev, key, act);
1267 break;
1268 case XkbSA_SwitchScreen:
1269 filter = _XkbNextFreeFilter(xkbi);
1270 *sendEvent = _XkbFilterSwitchScreen(xkbi, filter, key, act);
1271 break;
1272 case XkbSA_SetControls:
1273 case XkbSA_LockControls:
1274 filter = _XkbNextFreeFilter(xkbi);
1275 *sendEvent = _XkbFilterControls(xkbi, filter, key, act);
1276 break;
1277 case XkbSA_ActionMessage:
1278 filter = _XkbNextFreeFilter(xkbi);
1279 *sendEvent = _XkbFilterActionMessage(xkbi, filter, key, act);
1280 break;
1281 case XkbSA_RedirectKey:
1282 filter = _XkbNextFreeFilter(xkbi);
1283 /* redirect actions must create a new DeviceEvent. The
1284 * source device id for this event cannot be obtained from
1285 * xkbi, so we pass it here explicitly. The field deviceid
1286 * equals to xkbi->device->id. */
1287 filter->priv = event->sourceid;
1288 *sendEvent = _XkbFilterRedirectKey(xkbi, filter, key, act);
1289 break;
1290 case XkbSA_DeviceBtn:
1291 case XkbSA_LockDeviceBtn:
1292 filter = _XkbNextFreeFilter(xkbi);
1293 *sendEvent = _XkbFilterDeviceBtn(xkbi, filter, key, act);
1294 break;
1295 case XkbSA_XFree86Private:
1296 filter = _XkbNextFreeFilter(xkbi);
1297 *sendEvent = _XkbFilterXF86Private(xkbi, filter, key, act);
1298 break;
1299 }
1300 }
1301
1302 void
XkbHandleActions(DeviceIntPtr dev,DeviceIntPtr kbd,DeviceEvent * event)1303 XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
1304 {
1305 int key, bit, i;
1306 XkbSrvInfoPtr xkbi;
1307 KeyClassPtr keyc;
1308 int sendEvent;
1309 Bool genStateNotify;
1310 XkbAction act;
1311 Bool keyEvent;
1312 Bool pressEvent;
1313 ProcessInputProc backupproc;
1314
1315 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
1316
1317 keyc = kbd->key;
1318 xkbi = keyc->xkbInfo;
1319 key = event->detail.key;
1320
1321 genStateNotify = _XkbEnsureStateChange(xkbi);
1322
1323 xkbi->clearMods = xkbi->setMods = 0;
1324 xkbi->groupChange = 0;
1325
1326 sendEvent = 1;
1327 keyEvent = ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
1328 pressEvent = ((event->type == ET_KeyPress) ||
1329 (event->type == ET_ButtonPress));
1330
1331 if (pressEvent) {
1332 if (keyEvent)
1333 act = XkbGetKeyAction(xkbi, &xkbi->state, key);
1334 else {
1335 act = XkbGetButtonAction(kbd, dev, key);
1336 key |= BTN_ACT_FLAG;
1337 }
1338
1339 sendEvent = _XkbApplyFilters(xkbi, key, &act);
1340 if (sendEvent)
1341 XkbActionGetFilter(dev, event, key, &act, &sendEvent);
1342 }
1343 else {
1344 if (!keyEvent)
1345 key |= BTN_ACT_FLAG;
1346 sendEvent = _XkbApplyFilters(xkbi, key, NULL);
1347 }
1348
1349 if (xkbi->groupChange != 0)
1350 xkbi->state.base_group += xkbi->groupChange;
1351 if (xkbi->setMods) {
1352 for (i = 0, bit = 1; xkbi->setMods; i++, bit <<= 1) {
1353 if (xkbi->setMods & bit) {
1354 keyc->modifierKeyCount[i]++;
1355 xkbi->state.base_mods |= bit;
1356 xkbi->setMods &= ~bit;
1357 }
1358 }
1359 }
1360 if (xkbi->clearMods) {
1361 for (i = 0, bit = 1; xkbi->clearMods; i++, bit <<= 1) {
1362 if (xkbi->clearMods & bit) {
1363 keyc->modifierKeyCount[i]--;
1364 if (keyc->modifierKeyCount[i] <= 0) {
1365 xkbi->state.base_mods &= ~bit;
1366 keyc->modifierKeyCount[i] = 0;
1367 }
1368 xkbi->clearMods &= ~bit;
1369 }
1370 }
1371 }
1372
1373 if (sendEvent) {
1374 DeviceIntPtr tmpdev;
1375
1376 if (keyEvent)
1377 tmpdev = dev;
1378 else
1379 tmpdev = GetMaster(dev, POINTER_OR_FLOAT);
1380
1381 UNWRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, backupproc);
1382 dev->public.processInputProc((InternalEvent *) event, tmpdev);
1383 COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
1384 backupproc, xkbUnwrapProc);
1385 }
1386 else if (keyEvent) {
1387 FixKeyState(event, dev);
1388 }
1389
1390 _XkbApplyState(dev, genStateNotify, event->type, key);
1391 XkbPushLockedStateToSlaves(dev, event->type, key);
1392 }
1393
1394 int
XkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches)1395 XkbLatchModifiers(DeviceIntPtr pXDev, CARD8 mask, CARD8 latches)
1396 {
1397 XkbSrvInfoPtr xkbi;
1398 XkbFilterPtr filter;
1399 XkbAction act;
1400 unsigned clear;
1401
1402 if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
1403 xkbi = pXDev->key->xkbInfo;
1404 clear = (mask & (~latches));
1405 xkbi->state.latched_mods &= ~clear;
1406 /* Clear any pending latch to locks.
1407 */
1408 act.type = XkbSA_NoAction;
1409 _XkbApplyFilters(xkbi, SYNTHETIC_KEYCODE, &act);
1410 act.type = XkbSA_LatchMods;
1411 act.mods.flags = 0;
1412 act.mods.mask = mask & latches;
1413 filter = _XkbNextFreeFilter(xkbi);
1414 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act);
1415 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE,
1416 (XkbAction *) NULL);
1417 return Success;
1418 }
1419 return BadValue;
1420 }
1421
1422 int
XkbLatchGroup(DeviceIntPtr pXDev,int group)1423 XkbLatchGroup(DeviceIntPtr pXDev, int group)
1424 {
1425 XkbSrvInfoPtr xkbi;
1426 XkbFilterPtr filter;
1427 XkbAction act;
1428
1429 if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
1430 xkbi = pXDev->key->xkbInfo;
1431 act.type = XkbSA_LatchGroup;
1432 act.group.flags = 0;
1433 XkbSASetGroup(&act.group, group);
1434 filter = _XkbNextFreeFilter(xkbi);
1435 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act);
1436 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE,
1437 (XkbAction *) NULL);
1438 return Success;
1439 }
1440 return BadValue;
1441 }
1442
1443 /***====================================================================***/
1444
1445 void
XkbClearAllLatchesAndLocks(DeviceIntPtr dev,XkbSrvInfoPtr xkbi,Bool genEv,XkbEventCausePtr cause)1446 XkbClearAllLatchesAndLocks(DeviceIntPtr dev,
1447 XkbSrvInfoPtr xkbi,
1448 Bool genEv, XkbEventCausePtr cause)
1449 {
1450 XkbStateRec os;
1451 xkbStateNotify sn;
1452
1453 sn.changed = 0;
1454 os = xkbi->state;
1455 if (os.latched_mods) { /* clear all latches */
1456 XkbLatchModifiers(dev, ~0, 0);
1457 sn.changed |= XkbModifierLatchMask;
1458 }
1459 if (os.latched_group) {
1460 XkbLatchGroup(dev, 0);
1461 sn.changed |= XkbGroupLatchMask;
1462 }
1463 if (os.locked_mods) {
1464 xkbi->state.locked_mods = 0;
1465 sn.changed |= XkbModifierLockMask;
1466 }
1467 if (os.locked_group) {
1468 xkbi->state.locked_group = 0;
1469 sn.changed |= XkbGroupLockMask;
1470 }
1471 if (genEv && sn.changed) {
1472 CARD32 changed;
1473
1474 XkbComputeDerivedState(xkbi);
1475 sn.keycode = cause->kc;
1476 sn.eventType = cause->event;
1477 sn.requestMajor = cause->mjr;
1478 sn.requestMinor = cause->mnr;
1479 sn.changed = XkbStateChangedFlags(&os, &xkbi->state);
1480 XkbSendStateNotify(dev, &sn);
1481 changed = XkbIndicatorsToUpdate(dev, sn.changed, FALSE);
1482 if (changed) {
1483 XkbUpdateIndicators(dev, changed, TRUE, NULL, cause);
1484 }
1485 }
1486 return;
1487 }
1488
1489 /*
1490 * The event is injected into the event processing, not the EQ. Thus,
1491 * ensure that we restore the master after the event sequence to the
1492 * original set of classes. Otherwise, the master remains on the XTEST
1493 * classes and drops events that don't fit into the XTEST layout (e.g.
1494 * events with more than 2 valuators).
1495 *
1496 * FIXME: EQ injection in the processing stage is not designed for, so this
1497 * is a rather awkward hack. The event list returned by GetPointerEvents()
1498 * and friends is always prefixed with a DCE if the last _posted_ device was
1499 * different. For normal events, this sequence then resets the master during
1500 * the processing stage. Since we inject the PointerKey events in the
1501 * processing stage though, we need to manually reset to restore the
1502 * previous order, because the events already in the EQ must be sent for the
1503 * right device.
1504 * So we post-fix the event list we get from GPE with a DCE back to the
1505 * previous slave device.
1506 *
1507 * First one on drinking island wins!
1508 */
1509 static void
InjectPointerKeyEvents(DeviceIntPtr dev,int type,int button,int flags,ValuatorMask * mask)1510 InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags,
1511 ValuatorMask *mask)
1512 {
1513 ScreenPtr pScreen;
1514 InternalEvent *events;
1515 int nevents, i;
1516 DeviceIntPtr ptr, mpointer, lastSlave = NULL;
1517 Bool saveWait;
1518
1519 if (IsMaster(dev)) {
1520 mpointer = GetMaster(dev, MASTER_POINTER);
1521 lastSlave = mpointer->lastSlave;
1522 ptr = GetXTestDevice(mpointer);
1523 }
1524 else if (IsFloating(dev))
1525 ptr = dev;
1526 else
1527 return;
1528
1529 events = InitEventList(GetMaximumEventsNum() + 1);
1530 input_lock();
1531 pScreen = miPointerGetScreen(ptr);
1532 saveWait = miPointerSetWaitForUpdate(pScreen, FALSE);
1533 nevents = GetPointerEvents(events, ptr, type, button, flags, mask);
1534 if (IsMaster(dev) && (lastSlave && lastSlave != ptr))
1535 UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT,
1536 &nevents);
1537 miPointerSetWaitForUpdate(pScreen, saveWait);
1538
1539 for (i = 0; i < nevents; i++)
1540 mieqProcessDeviceEvent(ptr, &events[i], NULL);
1541 input_unlock();
1542
1543 FreeEventList(events, GetMaximumEventsNum());
1544 }
1545
1546 static void
XkbFakePointerMotion(DeviceIntPtr dev,unsigned flags,int x,int y)1547 XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x, int y)
1548 {
1549 ValuatorMask mask;
1550 int gpe_flags = 0;
1551
1552 /* ignore attached SDs */
1553 if (!IsMaster(dev) && !IsFloating(dev))
1554 return;
1555
1556 if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
1557 gpe_flags = POINTER_ABSOLUTE;
1558 else
1559 gpe_flags = POINTER_RELATIVE;
1560
1561 valuator_mask_set_range(&mask, 0, 2, (int[]) {
1562 x, y});
1563
1564 InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, &mask);
1565 }
1566
1567 void
XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)1568 XkbFakeDeviceButton(DeviceIntPtr dev, Bool press, int button)
1569 {
1570 DeviceIntPtr ptr;
1571 int down;
1572
1573 /* If dev is a slave device, and the SD is attached, do nothing. If we'd
1574 * post through the attached master pointer we'd get duplicate events.
1575 *
1576 * if dev is a master keyboard, post through the XTEST device
1577 *
1578 * if dev is a floating slave, post through the device itself.
1579 */
1580
1581 if (IsMaster(dev)) {
1582 DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER);
1583
1584 ptr = GetXTestDevice(mpointer);
1585 }
1586 else if (IsFloating(dev))
1587 ptr = dev;
1588 else
1589 return;
1590
1591 down = button_is_down(ptr, button, BUTTON_PROCESSED);
1592 if (press == down)
1593 return;
1594
1595 InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,
1596 button, 0, NULL);
1597 }
1598