1
/* $Xorg: xkbActions.c,v 1.3 2000/08/17 19:53:47 cpqbld Exp $ */
2
/************************************************************
3
Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
5
Permission to use, copy, modify, and distribute this
6
software and its documentation for any purpose and without
7
fee is hereby granted, provided that the above copyright
8
notice appear in all copies and that both that copyright
9
notice and this permission notice appear in supporting
10
documentation, and that the name of Silicon Graphics not be
11
used in advertising or publicity pertaining to distribution
12
of the software without specific prior written permission.
13
Silicon Graphics makes no representation about the suitability
14
of this software for any purpose. It is provided "as is"
15
without any express or implied warranty.
17
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
18
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
20
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
21
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
23
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
24
THE USE OR PERFORMANCE OF THIS SOFTWARE.
26
********************************************************/
27
/* $XFree86: xc/programs/Xserver/xkb/xkbActions.c,v 3.11 2003/02/13 15:36:48 dawes Exp $ */
33
#include <X11/Xproto.h>
34
#include <X11/keysym.h>
41
extern void ProcessOtherEvent(
42
#if NeedFunctionPrototypes
44
DeviceIntPtr /* dev */,
50
/***====================================================================***/
53
#if NeedFunctionPrototypes
54
_FixUpAction(XkbDescPtr xkb,XkbAction *act)
61
static XkbAction fake;
63
if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) {
64
fake.type = XkbSA_NoAction;
67
if (XkbDisableLockActions) {
70
fake.mods.type = XkbSA_SetMods;
72
fake.mods.mask = act->mods.mask;
75
fake.mods.type = XkbSA_SetMods;
77
fake.mods.mask = act->mods.mask;
80
if (act->iso.flags&XkbSA_ISODfltIsGroup) {
81
fake.group.type = XkbSA_SetGroup;
82
fake.group.flags = act->iso.flags&XkbSA_GroupAbsolute;
83
XkbSASetGroup(&fake.group,XkbSAGroup(&act->iso));
86
fake.mods.type = XkbSA_SetMods;
88
fake.mods.mask = act->iso.mask;
92
case XkbSA_LatchGroup:
93
/* We want everything from the latch/lock action except the
94
* type should be changed to set.
97
fake.group.type = XkbSA_SetGroup;
102
if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) {
103
if (act->any.type==XkbSA_SetMods) {
104
fake.mods.type = XkbSA_LatchMods;
105
fake.mods.mask = act->mods.mask;
106
if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
107
fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
108
else fake.mods.flags= XkbSA_ClearLocks;
111
if (act->any.type==XkbSA_SetGroup) {
112
fake.group.type = XkbSA_LatchGroup;
113
if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
114
fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
115
else fake.group.flags= XkbSA_ClearLocks;
116
XkbSASetGroup(&fake.group,XkbSAGroup(&act->group));
124
#if NeedFunctionPrototypes
125
XkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key)
127
XkbGetKeyAction(xkbi,xkbState,key)
129
XkbStatePtr xkbState;
138
static XkbAction fake;
141
if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) {
142
fake.type = XkbSA_NoAction;
145
pActs= XkbKeyActionsPtr(xkb,key);
147
effectiveGroup= xkbState->group;
148
if (effectiveGroup!=XkbGroup1Index) {
149
if (XkbKeyNumGroups(xkb,key)>(unsigned)1) {
150
if (effectiveGroup>=XkbKeyNumGroups(xkb,key)) {
151
unsigned gi= XkbKeyGroupInfo(xkb,key);
152
switch (XkbOutOfRangeGroupAction(gi)) {
154
case XkbWrapIntoRange:
155
effectiveGroup %= XkbKeyNumGroups(xkb,key);
157
case XkbClampIntoRange:
158
effectiveGroup = XkbKeyNumGroups(xkb,key)-1;
160
case XkbRedirectIntoRange:
161
effectiveGroup= XkbOutOfRangeGroupInfo(gi);
162
if (effectiveGroup>=XkbKeyNumGroups(xkb,key))
168
else effectiveGroup= XkbGroup1Index;
169
col+= (effectiveGroup*XkbKeyGroupsWidth(xkb,key));
171
type= XkbKeyKeyType(xkb,key,effectiveGroup);
172
if (type->map!=NULL) {
173
register unsigned i,mods;
174
register XkbKTMapEntryPtr entry;
175
mods= xkbState->mods&type->mods.mask;
176
for (entry= type->map,i=0;i<type->map_count;i++,entry++) {
177
if ((entry->active)&&(entry->mods.mask==mods)) {
183
if (pActs[col].any.type==XkbSA_NoAction)
185
fake= _FixUpAction(xkb,&pActs[col]);
190
#if NeedFunctionPrototypes
191
XkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button)
193
XkbGetButtonAction(kbd,dev,button)
200
if ((dev->button)&&(dev->button->xkb_acts)) {
201
if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) {
202
fake= _FixUpAction(kbd->key->xkbInfo->desc,
203
&dev->button->xkb_acts[button-1]);
207
fake.any.type= XkbSA_NoAction;
211
/***====================================================================***/
213
#define SYNTHETIC_KEYCODE 1
214
#define BTN_ACT_FLAG 0x100
216
typedef struct _XkbFilter {
224
#if NeedFunctionPrototypes
225
XkbSrvInfoPtr /* xkbi */,
226
struct _XkbFilter * /* filter */,
227
unsigned /* keycode */,
228
XkbAction * /* action */
231
struct _XkbFilter *next;
232
} XkbFilterRec,*XkbFilterPtr;
235
#if NeedFunctionPrototypes
236
_XkbFilterSetState( XkbSrvInfoPtr xkbi,
241
_XkbFilterSetState(xkbi,filter,keycode,pAction)
248
if (filter->keycode==0) { /* initial press */
249
filter->keycode = keycode;
251
filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0);
253
filter->filter = _XkbFilterSetState;
254
if (pAction->type==XkbSA_SetMods) {
255
filter->upAction = *pAction;
256
xkbi->setMods= pAction->mods.mask;
259
xkbi->groupChange = XkbSAGroup(&pAction->group);
260
if (pAction->group.flags&XkbSA_GroupAbsolute)
261
xkbi->groupChange-= xkbi->state.base_group;
262
filter->upAction= *pAction;
263
XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
266
else if (filter->keycode==keycode) {
267
if (filter->upAction.type==XkbSA_SetMods) {
268
xkbi->clearMods = filter->upAction.mods.mask;
269
if (filter->upAction.mods.flags&XkbSA_ClearLocks) {
270
xkbi->state.locked_mods&= ~filter->upAction.mods.mask;
274
if (filter->upAction.group.flags&XkbSA_ClearLocks) {
275
xkbi->state.locked_group = 0;
277
xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
282
filter->upAction.mods.flags&= ~XkbSA_ClearLocks;
283
filter->filterOthers = 0;
288
#define LATCH_KEY_DOWN 1
289
#define LATCH_PENDING 2
293
#if NeedFunctionPrototypes
294
_XkbFilterLatchState( XkbSrvInfoPtr xkbi,
299
_XkbFilterLatchState(xkbi,filter,keycode,pAction)
307
if (filter->keycode==0) { /* initial press */
308
filter->keycode = keycode;
310
filter->filterOthers = 1;
311
filter->priv = LATCH_KEY_DOWN;
312
filter->filter = _XkbFilterLatchState;
313
if (pAction->type==XkbSA_LatchMods) {
314
filter->upAction = *pAction;
315
xkbi->setMods = pAction->mods.mask;
318
xkbi->groupChange = XkbSAGroup(&pAction->group);
319
if (pAction->group.flags&XkbSA_GroupAbsolute)
320
xkbi->groupChange-= xkbi->state.base_group;
321
filter->upAction= *pAction;
322
XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
325
else if ( pAction && (filter->priv==LATCH_PENDING) ) {
326
if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) {
328
if (filter->upAction.type==XkbSA_LatchMods)
329
xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
330
else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
332
else if ((pAction->type==filter->upAction.type)&&
333
(pAction->mods.flags==filter->upAction.mods.flags)&&
334
(pAction->mods.mask==filter->upAction.mods.mask)) {
335
if (filter->upAction.mods.flags&XkbSA_LatchToLock) {
336
XkbControlsPtr ctrls= xkbi->desc->ctrls;
337
if (filter->upAction.type==XkbSA_LatchMods)
338
pAction->mods.type= XkbSA_LockMods;
339
else pAction->group.type= XkbSA_LockGroup;
340
if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&&
341
(ctrls->enabled_ctrls&XkbStickyKeysMask)) {
342
XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK,
347
if (filter->upAction.type==XkbSA_LatchMods)
348
pAction->mods.type= XkbSA_SetMods;
349
else pAction->group.type= XkbSA_SetGroup;
351
if (filter->upAction.type==XkbSA_LatchMods)
352
xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
353
else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
357
else if (filter->keycode==keycode) { /* release */
358
XkbControlsPtr ctrls= xkbi->desc->ctrls;
360
int beepType= _BEEP_NONE;
362
needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&&
363
XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask));
364
if (filter->upAction.type==XkbSA_LatchMods) {
365
xkbi->clearMods = filter->upAction.mods.mask;
366
if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&&
367
(xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) {
368
xkbi->state.locked_mods&= ~xkbi->clearMods;
369
filter->priv= NO_LATCH;
370
beepType= _BEEP_STICKY_UNLOCK;
374
xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
375
if ((filter->upAction.group.flags&XkbSA_ClearLocks)&&
376
(xkbi->state.locked_group)) {
377
xkbi->state.locked_group = 0;
378
filter->priv = NO_LATCH;
379
beepType= _BEEP_STICKY_UNLOCK;
382
if (filter->priv==NO_LATCH) {
386
filter->priv= LATCH_PENDING;
387
if (filter->upAction.type==XkbSA_LatchMods) {
388
xkbi->state.latched_mods |= filter->upAction.mods.mask;
389
needBeep = xkbi->state.latched_mods ? needBeep : 0;
390
xkbi->state.latched_mods |= filter->upAction.mods.mask;
393
xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group);
395
if (needBeep && (beepType==_BEEP_NONE))
396
beepType= _BEEP_STICKY_LATCH;
398
if (needBeep && (beepType!=_BEEP_NONE))
399
XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask);
401
else if (filter->priv==LATCH_KEY_DOWN) {
402
filter->priv= NO_LATCH;
403
filter->filterOthers = 0;
409
#if NeedFunctionPrototypes
410
_XkbFilterLockState( XkbSrvInfoPtr xkbi,
415
_XkbFilterLockState(xkbi,filter,keycode,pAction)
423
if (pAction&&(pAction->type==XkbSA_LockGroup)) {
424
if (pAction->group.flags&XkbSA_GroupAbsolute)
425
xkbi->state.locked_group= XkbSAGroup(&pAction->group);
426
else xkbi->state.locked_group+= XkbSAGroup(&pAction->group);
429
if (filter->keycode==0) { /* initial press */
430
filter->keycode = keycode;
432
filter->filterOthers = 0;
434
filter->filter = _XkbFilterLockState;
435
filter->upAction = *pAction;
436
xkbi->state.locked_mods^= pAction->mods.mask;
437
xkbi->setMods = pAction->mods.mask;
439
else if (filter->keycode==keycode) {
441
xkbi->clearMods = filter->upAction.mods.mask;
446
#define ISO_KEY_DOWN 0
447
#define NO_ISO_LOCK 1
450
#if NeedFunctionPrototypes
451
_XkbFilterISOLock( XkbSrvInfoPtr xkbi,
456
_XkbFilterISOLock(xkbi,filter,keycode,pAction)
464
if (filter->keycode==0) { /* initial press */
465
CARD8 flags= pAction->iso.flags;
467
filter->keycode = keycode;
469
filter->filterOthers = 1;
470
filter->priv = ISO_KEY_DOWN;
471
filter->upAction = *pAction;
472
filter->filter = _XkbFilterISOLock;
473
if (flags&XkbSA_ISODfltIsGroup) {
474
xkbi->groupChange = XkbSAGroup(&pAction->iso);
478
xkbi->setMods = pAction->iso.mask;
479
xkbi->groupChange = 0;
481
if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) {
482
filter->priv= NO_ISO_LOCK;
483
xkbi->state.locked_mods^= xkbi->state.base_mods;
485
if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) {
486
/* 6/22/93 (ef) -- lock groups if group key is down first */
488
if (!(flags&XkbSA_ISONoAffectPtr)) {
489
/* 6/22/93 (ef) -- lock mouse buttons if they're down */
492
else if (filter->keycode==keycode) {
493
CARD8 flags= filter->upAction.iso.flags;
495
if (flags&XkbSA_ISODfltIsGroup) {
496
xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
498
if (filter->priv==ISO_KEY_DOWN)
499
xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso);
502
xkbi->clearMods= filter->upAction.iso.mask;
503
xkbi->groupChange= 0;
504
if (filter->priv==ISO_KEY_DOWN)
505
xkbi->state.locked_mods^= filter->upAction.iso.mask;
510
CARD8 flags= filter->upAction.iso.flags;
512
switch (pAction->type) {
513
case XkbSA_SetMods: case XkbSA_LatchMods:
514
if (!(flags&XkbSA_ISONoAffectMods)) {
515
pAction->type= XkbSA_LockMods;
516
filter->priv= NO_ISO_LOCK;
519
case XkbSA_SetGroup: case XkbSA_LatchGroup:
520
if (!(flags&XkbSA_ISONoAffectGroup)) {
521
pAction->type= XkbSA_LockGroup;
522
filter->priv= NO_ISO_LOCK;
526
if (!(flags&XkbSA_ISONoAffectPtr)) {
527
pAction->type= XkbSA_LockPtrBtn;
528
filter->priv= NO_ISO_LOCK;
531
case XkbSA_SetControls:
532
if (!(flags&XkbSA_ISONoAffectCtrls)) {
533
pAction->type= XkbSA_LockControls;
534
filter->priv= NO_ISO_LOCK;
544
#if NeedFunctionPrototypes
545
_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg)
547
_XkbPtrAccelExpire(timer,now,arg)
553
XkbSrvInfoPtr xkbi= (XkbSrvInfoPtr)arg;
554
XkbControlsPtr ctrls= xkbi->desc->ctrls;
557
if (xkbi->mouseKey==0)
560
if (xkbi->mouseKeysAccel) {
561
if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) {
563
xkbi->mouseKeysCounter++;
564
step= xkbi->mouseKeysCurveFactor*
565
pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve);
566
if (xkbi->mouseKeysDX<0)
567
dx= floor( ((double)xkbi->mouseKeysDX)*step );
568
else dx= ceil( ((double)xkbi->mouseKeysDX)*step );
569
if (xkbi->mouseKeysDY<0)
570
dy= floor( ((double)xkbi->mouseKeysDY)*step );
571
else dy= ceil( ((double)xkbi->mouseKeysDY)*step );
574
dx= xkbi->mouseKeysDX*ctrls->mk_max_speed;
575
dy= xkbi->mouseKeysDY*ctrls->mk_max_speed;
577
if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX)
578
dx= xkbi->mouseKeysDX;
579
if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY)
580
dy= xkbi->mouseKeysDY;
583
dx= xkbi->mouseKeysDX;
584
dy= xkbi->mouseKeysDY;
586
XkbDDXFakePointerMotion(xkbi->mouseKeysFlags,dx,dy);
587
return xkbi->desc->ctrls->mk_interval;
591
#if NeedFunctionPrototypes
592
_XkbFilterPointerMove( XkbSrvInfoPtr xkbi,
597
_XkbFilterPointerMove(xkbi,filter,keycode,pAction)
607
if (filter->keycode==0) { /* initial press */
608
filter->keycode = keycode;
610
filter->filterOthers = 0;
612
filter->filter = _XkbFilterPointerMove;
613
filter->upAction= *pAction;
614
xkbi->mouseKeysCounter= 0;
615
xkbi->mouseKey= keycode;
616
accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0);
617
x= XkbPtrActionX(&pAction->ptr);
618
y= XkbPtrActionY(&pAction->ptr);
619
XkbDDXFakePointerMotion(pAction->ptr.flags,x,y);
620
AccessXCancelRepeatKey(xkbi,keycode);
621
xkbi->mouseKeysAccel= accel&&
622
(xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask);
623
xkbi->mouseKeysFlags= pAction->ptr.flags;
624
xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr);
625
xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr);
626
xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0,
627
xkbi->desc->ctrls->mk_delay,
628
_XkbPtrAccelExpire,(pointer)xkbi);
630
else if (filter->keycode==keycode) {
632
if (xkbi->mouseKey==keycode) {
634
xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0,
642
#if NeedFunctionPrototypes
643
_XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
648
_XkbFilterPointerBtn(xkbi,filter,keycode,pAction)
655
if (filter->keycode==0) { /* initial press */
656
int button= pAction->btn.button;
658
if (button==XkbSA_UseDfltButton)
659
button = xkbi->desc->ctrls->mk_dflt_btn;
661
filter->keycode = keycode;
663
filter->filterOthers = 0;
665
filter->filter = _XkbFilterPointerBtn;
666
filter->upAction= *pAction;
667
filter->upAction.btn.button= button;
668
switch (pAction->type) {
669
case XkbSA_LockPtrBtn:
670
if (((xkbi->lockedPtrButtons&(1<<button))==0)&&
671
((pAction->btn.flags&XkbSA_LockNoLock)==0)) {
672
xkbi->lockedPtrButtons|= (1<<button);
673
AccessXCancelRepeatKey(xkbi,keycode);
674
XkbDDXFakePointerButton(ButtonPress,button);
675
filter->upAction.type= XkbSA_NoAction;
680
register int i,nClicks;
681
AccessXCancelRepeatKey(xkbi,keycode);
682
if (pAction->btn.count>0) {
683
nClicks= pAction->btn.count;
684
for (i=0;i<nClicks;i++) {
685
XkbDDXFakePointerButton(ButtonPress,button);
686
XkbDDXFakePointerButton(ButtonRelease,button);
688
filter->upAction.type= XkbSA_NoAction;
690
else XkbDDXFakePointerButton(ButtonPress,button);
693
case XkbSA_SetPtrDflt:
695
XkbControlsPtr ctrls= xkbi->desc->ctrls;
697
xkbControlsNotify cn;
700
AccessXCancelRepeatKey(xkbi,keycode);
701
switch (pAction->dflt.affect) {
702
case XkbSA_AffectDfltBtn:
703
if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute)
705
XkbSAPtrDfltValue(&pAction->dflt);
708
XkbSAPtrDfltValue(&pAction->dflt);
709
if (ctrls->mk_dflt_btn>5)
710
ctrls->mk_dflt_btn= 5;
711
else if (ctrls->mk_dflt_btn<1)
712
ctrls->mk_dflt_btn= 1;
717
"Attempt to change unknown pointer default (%d) ignored\n",
718
pAction->dflt.affect);
721
if (XkbComputeControlsNotify(xkbi->device,
722
&old,xkbi->desc->ctrls,
724
cn.keycode = keycode;
725
cn.eventType = KeyPress;
728
XkbSendControlsNotify(xkbi->device,&cn);
734
else if (filter->keycode==keycode) {
735
int button= filter->upAction.btn.button;
737
switch (filter->upAction.type) {
738
case XkbSA_LockPtrBtn:
739
if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)||
740
((xkbi->lockedPtrButtons&(1<<button))==0)) {
743
xkbi->lockedPtrButtons&= ~(1<<button);
745
XkbDDXFakePointerButton(ButtonRelease,button);
754
#if NeedFunctionPrototypes
755
_XkbFilterControls( XkbSrvInfoPtr xkbi,
760
_XkbFilterControls(xkbi,filter,keycode,pAction)
768
XkbControlsPtr ctrls;
771
XkbEventCauseRec cause;
774
ctrls= xkbi->desc->ctrls;
776
if (filter->keycode==0) { /* initial press */
777
filter->keycode = keycode;
779
filter->filterOthers = 0;
780
change= XkbActionCtrls(&pAction->ctrls);
781
filter->priv = change;
782
filter->filter = _XkbFilterControls;
783
filter->upAction = *pAction;
785
if (pAction->type==XkbSA_LockControls) {
786
filter->priv= (ctrls->enabled_ctrls&change);
787
change&= ~ctrls->enabled_ctrls;
791
xkbControlsNotify cn;
792
XkbSrvLedInfoPtr sli;
794
ctrls->enabled_ctrls|= change;
795
if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,False)) {
796
cn.keycode = keycode;
797
cn.eventType = KeyPress;
800
XkbSendControlsNotify(kbd,&cn);
803
XkbSetCauseKey(&cause,keycode,KeyPress);
805
/* If sticky keys were disabled, clear all locks and latches */
806
if ((old.enabled_ctrls&XkbStickyKeysMask)&&
807
(!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
808
XkbClearAllLatchesAndLocks(kbd,xkbi,False,&cause);
810
sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
811
XkbUpdateIndicators(kbd,sli->usesControls,True,NULL,&cause);
812
if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
813
XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change);
816
else if (filter->keycode==keycode) {
817
change= filter->priv;
819
xkbControlsNotify cn;
820
XkbSrvLedInfoPtr sli;
822
ctrls->enabled_ctrls&= ~change;
823
if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,False)) {
824
cn.keycode = keycode;
825
cn.eventType = KeyRelease;
828
XkbSendControlsNotify(kbd,&cn);
831
XkbSetCauseKey(&cause,keycode,KeyRelease);
832
/* If sticky keys were disabled, clear all locks and latches */
833
if ((old.enabled_ctrls&XkbStickyKeysMask)&&
834
(!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
835
XkbClearAllLatchesAndLocks(kbd,xkbi,False,&cause);
837
sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
838
XkbUpdateIndicators(kbd,sli->usesControls,True,NULL,&cause);
839
if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
840
XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change);
849
#if NeedFunctionPrototypes
850
_XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
855
_XkbFilterActionMessage(xkbi,filter,keycode,pAction)
862
XkbMessageAction * pMsg;
866
if (filter->keycode==0) { /* initial press */
868
if ((pMsg->flags&XkbSA_MessageOnRelease)||
869
((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) {
870
filter->keycode = keycode;
872
filter->filterOthers = 0;
874
filter->filter = _XkbFilterActionMessage;
875
filter->upAction = *pAction;
877
if (pMsg->flags&XkbSA_MessageOnPress) {
878
xkbActionMessage msg;
880
msg.keycode= keycode;
882
msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
883
memcpy((char *)msg.message,
884
(char *)pMsg->message,XkbActionMessageLength);
885
XkbSendActionMessage(kbd,&msg);
887
return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0);
889
else if (filter->keycode==keycode) {
890
pMsg= &filter->upAction.msg;
891
if (pMsg->flags&XkbSA_MessageOnRelease) {
892
xkbActionMessage msg;
894
msg.keycode= keycode;
896
msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
897
memcpy((char *)msg.message,(char *)pMsg->message,
898
XkbActionMessageLength);
899
XkbSendActionMessage(kbd,&msg);
903
return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
909
#if NeedFunctionPrototypes
910
_XkbFilterRedirectKey( XkbSrvInfoPtr xkbi,
915
_XkbFilterRedirectKey(xkbi,filter,keycode,pAction)
926
unsigned mods,mask,oldCoreState = 0,oldCorePrevState = 0;
928
if ((filter->keycode!=0)&&(filter->keycode!=keycode))
931
GetSpritePosition(&x,&y);
932
ev.u.keyButtonPointer.time = GetTimeInMillis();
933
ev.u.keyButtonPointer.rootX = x;
934
ev.u.keyButtonPointer.rootY = y;
936
mask= XkbSARedirectVModsMask(&pAction->redirect);
937
mods= XkbSARedirectVMods(&pAction->redirect);
938
if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
939
if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
940
mask|= pAction->redirect.mods_mask;
941
mods|= pAction->redirect.mods;
943
if (filter->keycode==0) { /* initial press */
944
if ((pAction->redirect.new_key<xkbi->desc->min_key_code)||
945
(pAction->redirect.new_key>xkbi->desc->max_key_code)) {
948
filter->keycode = keycode;
950
filter->filterOthers = 0;
952
filter->filter = _XkbFilterRedirectKey;
953
filter->upAction = *pAction;
955
ev.u.u.type = KeyPress;
956
ev.u.u.detail = pAction->redirect.new_key;
958
if ( mask || mods ) {
960
oldCoreState= xkbi->device->key->state;
961
oldCorePrevState= xkbi->device->key->prev_state;
962
xkbi->state.base_mods&= ~mask;
963
xkbi->state.base_mods|= (mods&mask);
964
xkbi->state.latched_mods&= ~mask;
965
xkbi->state.latched_mods|= (mods&mask);
966
xkbi->state.locked_mods&= ~mask;
967
xkbi->state.locked_mods|= (mods&mask);
968
XkbComputeDerivedState(xkbi);
969
xkbi->device->key->state= xkbi->device->key->prev_state=
973
realMods = xkbi->device->key->modifierMap[ev.u.u.detail];
974
xkbi->device->key->modifierMap[ev.u.u.detail] = 0;
975
CoreProcessKeyboardEvent(&ev,xkbi->device,1);
976
xkbi->device->key->modifierMap[ev.u.u.detail] = realMods;
978
if ( mask || mods ) {
979
xkbi->device->key->state= oldCoreState;
980
xkbi->device->key->prev_state= oldCorePrevState;
984
else if (filter->keycode==keycode) {
986
ev.u.u.type = KeyRelease;
987
ev.u.u.detail = filter->upAction.redirect.new_key;
989
if ( mask || mods ) {
991
oldCoreState= xkbi->device->key->state;
992
oldCorePrevState= xkbi->device->key->prev_state;
993
xkbi->state.base_mods&= ~mask;
994
xkbi->state.base_mods|= (mods&mask);
995
xkbi->state.latched_mods&= ~mask;
996
xkbi->state.latched_mods|= (mods&mask);
997
xkbi->state.locked_mods&= ~mask;
998
xkbi->state.locked_mods|= (mods&mask);
999
XkbComputeDerivedState(xkbi);
1000
xkbi->device->key->state= xkbi->device->key->prev_state=
1004
realMods = xkbi->device->key->modifierMap[ev.u.u.detail];
1005
xkbi->device->key->modifierMap[ev.u.u.detail] = 0;
1006
CoreProcessKeyboardEvent(&ev,xkbi->device,1);
1007
xkbi->device->key->modifierMap[ev.u.u.detail] = realMods;
1009
if ( mask || mods ) {
1010
xkbi->device->key->state= oldCoreState;
1011
xkbi->device->key->prev_state= oldCorePrevState;
1022
#if NeedFunctionPrototypes
1023
_XkbFilterSwitchScreen( XkbSrvInfoPtr xkbi,
1024
XkbFilterPtr filter,
1026
XkbAction * pAction)
1028
_XkbFilterSwitchScreen(xkbi,filter,keycode,pAction)
1030
XkbFilterPtr filter;
1032
XkbAction * pAction;
1035
if (filter->keycode==0) { /* initial press */
1036
DeviceIntPtr dev = xkbi->device;
1037
filter->keycode = keycode;
1039
filter->filterOthers = 0;
1040
filter->filter = _XkbFilterSwitchScreen;
1041
AccessXCancelRepeatKey(xkbi, keycode);
1042
XkbDDXSwitchScreen(dev,keycode,pAction);
1045
else if (filter->keycode==keycode) {
1052
#ifdef XFree86Server
1054
#if NeedFunctionPrototypes
1055
_XkbFilterXF86Private( XkbSrvInfoPtr xkbi,
1056
XkbFilterPtr filter,
1058
XkbAction * pAction)
1060
_XkbFilterXF86Private(xkbi,filter,keycode,pAction)
1062
XkbFilterPtr filter;
1064
XkbAction * pAction;
1067
if (filter->keycode==0) { /* initial press */
1068
DeviceIntPtr dev = xkbi->device;
1069
filter->keycode = keycode;
1071
filter->filterOthers = 0;
1072
filter->filter = _XkbFilterXF86Private;
1073
XkbDDXPrivate(dev,keycode,pAction);
1076
else if (filter->keycode==keycode) {
1087
#if NeedFunctionPrototypes
1088
_XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi,
1089
XkbFilterPtr filter,
1091
XkbAction * pAction)
1093
_XkbFilterDeviceBtn(xkbi,filter,keycode,pAction)
1095
XkbFilterPtr filter;
1097
XkbAction * pAction;
1103
if (filter->keycode==0) { /* initial press */
1104
dev= _XkbLookupButtonDevice(pAction->devbtn.device,NULL);
1105
if ((!dev)||(!dev->public.on)||(&dev->public==LookupPointerDevice()))
1108
button= pAction->devbtn.button;
1109
if ((button<1)||(button>dev->button->numButtons))
1112
filter->keycode = keycode;
1114
filter->filterOthers = 0;
1116
filter->filter = _XkbFilterDeviceBtn;
1117
filter->upAction= *pAction;
1118
switch (pAction->type) {
1119
case XkbSA_LockDeviceBtn:
1120
if ((pAction->devbtn.flags&XkbSA_LockNoLock)||
1121
(dev->button->down[button/8]&(1L<<(button%8))))
1123
XkbDDXFakeDeviceButton(dev,True,button);
1124
filter->upAction.type= XkbSA_NoAction;
1126
case XkbSA_DeviceBtn:
1127
if (pAction->devbtn.count>0) {
1129
nClicks= pAction->btn.count;
1130
for (i=0;i<nClicks;i++) {
1131
XkbDDXFakeDeviceButton(dev,True,button);
1132
XkbDDXFakeDeviceButton(dev,False,button);
1134
filter->upAction.type= XkbSA_NoAction;
1136
else XkbDDXFakeDeviceButton(dev,True,button);
1140
else if (filter->keycode==keycode) {
1144
dev= _XkbLookupButtonDevice(filter->upAction.devbtn.device,NULL);
1145
if ((!dev)||(!dev->public.on)||(&dev->public==LookupPointerDevice()))
1148
button= filter->upAction.btn.button;
1149
switch (filter->upAction.type) {
1150
case XkbSA_LockDeviceBtn:
1151
if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)||
1152
((dev->button->down[button/8]&(1L<<(button%8)))==0))
1154
XkbDDXFakeDeviceButton(dev,False,button);
1156
case XkbSA_DeviceBtn:
1157
XkbDDXFakeDeviceButton(dev,False,button);
1166
static int szFilters = 0;
1167
static XkbFilterPtr filters = NULL;
1171
#if NeedFunctionPrototypes
1180
filters = _XkbTypedCalloc(szFilters,XkbFilterRec);
1181
/* 6/21/93 (ef) -- XXX! deal with allocation failure */
1183
for (i=0;i<szFilters;i++) {
1184
if (!filters[i].active) {
1185
filters[i].keycode = 0;
1190
filters= _XkbTypedRealloc(filters,szFilters,XkbFilterRec);
1191
/* 6/21/93 (ef) -- XXX! deal with allocation failure */
1192
bzero(&filters[szFilters/2],(szFilters/2)*sizeof(XkbFilterRec));
1193
return &filters[szFilters/2];
1197
#if NeedFunctionPrototypes
1198
_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction)
1200
_XkbApplyFilters(xkbi,kc,pAction)
1203
XkbAction * pAction;
1206
register int i,send;
1209
for (i=0;i<szFilters;i++) {
1210
if ((filters[i].active)&&(filters[i].filter))
1211
send= ((*filters[i].filter)(xkbi,&filters[i],kc,pAction)&&send);
1217
#if NeedFunctionPrototypes
1218
XkbHandleActions(DeviceIntPtr dev,DeviceIntPtr kbd,xEvent *xE,int count)
1220
XkbHandleActions(dev,kbd,xE,count)
1231
int changed,sendEvent;
1232
Bool genStateNotify;
1233
XkbStateRec oldState;
1235
XkbFilterPtr filter;
1243
xkbi= keyc->xkbInfo;
1244
key= xE->u.u.detail;
1245
if ((xkbi->flags&_XkbStateNotifyInProgress)==0) {
1246
oldState= xkbi->state;
1247
xkbi->flags|= _XkbStateNotifyInProgress;
1248
genStateNotify= True;
1250
else genStateNotify= False;
1252
xkbi->clearMods = xkbi->setMods = 0;
1253
xkbi->groupChange = 0;
1257
keyEvent= ((xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)||
1258
(xE->u.u.type==KeyRelease)||(xE->u.u.type==DeviceKeyRelease));
1259
pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)||
1260
(xE->u.u.type==ButtonPress)||(xE->u.u.type==DeviceButtonPress);
1261
xiEvent= (xE->u.u.type==DeviceKeyPress)||(xE->u.u.type==DeviceKeyRelease)||
1262
(xE->u.u.type==DeviceButtonPress)||
1263
(xE->u.u.type==DeviceButtonRelease);
1265
keyEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease);
1266
pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==ButtonPress);
1271
act = XkbGetKeyAction(xkbi,&xkbi->state,key);
1273
act = XkbGetButtonAction(kbd,dev,key);
1276
sendEvent = _XkbApplyFilters(xkbi,key,&act);
1280
case XkbSA_SetGroup:
1281
filter = _XkbNextFreeFilter();
1282
sendEvent = _XkbFilterSetState(xkbi,filter,key,&act);
1284
case XkbSA_LatchMods:
1285
case XkbSA_LatchGroup:
1286
filter = _XkbNextFreeFilter();
1287
sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act);
1289
case XkbSA_LockMods:
1290
case XkbSA_LockGroup:
1291
filter = _XkbNextFreeFilter();
1292
sendEvent=_XkbFilterLockState(xkbi,filter,key,&act);
1295
filter = _XkbNextFreeFilter();
1296
sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act);
1299
filter = _XkbNextFreeFilter();
1300
sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act);
1303
case XkbSA_LockPtrBtn:
1304
case XkbSA_SetPtrDflt:
1305
filter = _XkbNextFreeFilter();
1306
sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act);
1308
case XkbSA_Terminate:
1309
sendEvent= XkbDDXTerminateServer(dev,key,&act);
1311
case XkbSA_SwitchScreen:
1312
filter = _XkbNextFreeFilter();
1313
sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act);
1315
case XkbSA_SetControls:
1316
case XkbSA_LockControls:
1317
filter = _XkbNextFreeFilter();
1318
sendEvent=_XkbFilterControls(xkbi,filter,key,&act);
1320
case XkbSA_ActionMessage:
1321
filter = _XkbNextFreeFilter();
1322
sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act);
1324
case XkbSA_RedirectKey:
1325
filter = _XkbNextFreeFilter();
1326
sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act);
1329
case XkbSA_DeviceBtn:
1330
case XkbSA_LockDeviceBtn:
1331
filter = _XkbNextFreeFilter();
1332
sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act);
1335
#ifdef XFree86Server
1336
case XkbSA_XFree86Private:
1337
filter = _XkbNextFreeFilter();
1338
sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act);
1347
sendEvent = _XkbApplyFilters(xkbi,key,NULL);
1350
if (xkbi->groupChange!=0)
1351
xkbi->state.base_group+= xkbi->groupChange;
1352
if (xkbi->setMods) {
1353
for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) {
1354
if (xkbi->setMods&bit) {
1355
keyc->modifierKeyCount[i]++;
1356
xkbi->state.base_mods|= bit;
1357
xkbi->setMods&= ~bit;
1361
if (xkbi->clearMods) {
1362
for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) {
1363
if (xkbi->clearMods&bit) {
1364
keyc->modifierKeyCount[i]--;
1365
if (keyc->modifierKeyCount[i]<=0) {
1366
xkbi->state.base_mods&= ~bit;
1367
keyc->modifierKeyCount[i] = 0;
1369
xkbi->clearMods&= ~bit;
1377
ProcessOtherEvent(xE,dev,count);
1381
realMods = keyc->modifierMap[key];
1382
keyc->modifierMap[key] = 0;
1383
CoreProcessKeyboardEvent(xE,dev,count);
1384
keyc->modifierMap[key] = realMods;
1386
else CoreProcessPointerEvent(xE,dev,count);
1389
FixKeyState(xE,dev);
1391
xkbi->prev_state= oldState;
1392
XkbComputeDerivedState(xkbi);
1393
keyc->prev_state= keyc->state;
1394
keyc->state= XkbStateFieldFromRec(&xkbi->state);
1395
changed = XkbStateChangedFlags(&oldState,&xkbi->state);
1396
if (genStateNotify) {
1400
sn.eventType= xE->u.u.type;
1401
sn.requestMajor = sn.requestMinor = 0;
1402
sn.changed= changed;
1403
XkbSendStateNotify(dev,&sn);
1405
xkbi->flags&= ~_XkbStateNotifyInProgress;
1407
changed= XkbIndicatorsToUpdate(dev,changed,False);
1409
XkbEventCauseRec cause;
1410
XkbSetCauseKey(&cause,key,xE->u.u.type);
1411
XkbUpdateIndicators(dev,changed,True,NULL,&cause);
1417
#if NeedFunctionPrototypes
1418
XkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches)
1420
XkbLatchModifiers(pXDev,mask,latches)
1427
XkbFilterPtr filter;
1431
if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
1432
xkbi = pXDev->key->xkbInfo;
1433
clear= (mask&(~latches));
1434
xkbi->state.latched_mods&= ~clear;
1435
/* Clear any pending latch to locks.
1437
act.type = XkbSA_NoAction;
1438
_XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act);
1439
act.type = XkbSA_LatchMods;
1441
act.mods.mask = mask&latches;
1442
filter = _XkbNextFreeFilter();
1443
_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
1444
_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
1451
#if NeedFunctionPrototypes
1452
XkbLatchGroup(DeviceIntPtr pXDev,int group)
1454
XkbLatchGroup(pXDev,group)
1460
XkbFilterPtr filter;
1463
if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
1464
xkbi = pXDev->key->xkbInfo;
1465
act.type = XkbSA_LatchGroup;
1466
act.group.flags = 0;
1467
XkbSASetGroup(&act.group,group);
1468
filter = _XkbNextFreeFilter();
1469
_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
1470
_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
1476
/***====================================================================***/
1479
#if NeedFunctionPrototypes
1480
XkbClearAllLatchesAndLocks( DeviceIntPtr dev,
1483
XkbEventCausePtr cause)
1485
XkbClearAllLatchesAndLocks(dev,xkbi,genEv,cause)
1489
XkbEventCausePtr cause;
1497
if (os.latched_mods) { /* clear all latches */
1498
XkbLatchModifiers(dev,~0,0);
1499
sn.changed|= XkbModifierLatchMask;
1501
if (os.latched_group) {
1502
XkbLatchGroup(dev,0);
1503
sn.changed|= XkbGroupLatchMask;
1505
if (os.locked_mods) {
1506
xkbi->state.locked_mods= 0;
1507
sn.changed|= XkbModifierLockMask;
1509
if (os.locked_group) {
1510
xkbi->state.locked_group= 0;
1511
sn.changed|= XkbGroupLockMask;
1513
if ( genEv && sn.changed) {
1516
XkbComputeDerivedState(xkbi);
1517
sn.keycode= cause->kc;
1518
sn.eventType= cause->event;
1519
sn.requestMajor= cause->mjr;
1520
sn.requestMinor= cause->mnr;
1521
sn.changed= XkbStateChangedFlags(&os,&xkbi->state);
1522
XkbSendStateNotify(dev,&sn);
1523
changed= XkbIndicatorsToUpdate(dev,sn.changed,False);
1525
XkbUpdateIndicators(dev,changed,True,NULL,cause);