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