1409 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1409 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			C
		
	
	
	
/************************************************************
 | 
						|
Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
 | 
						|
 | 
						|
Permission to use, copy, modify, and distribute this
 | 
						|
software and its documentation for any purpose and without
 | 
						|
fee is hereby granted, provided that the above copyright
 | 
						|
notice appear in all copies and that both that copyright
 | 
						|
notice and this permission notice appear in supporting
 | 
						|
documentation, and that the name of Silicon Graphics not be 
 | 
						|
used in advertising or publicity pertaining to distribution 
 | 
						|
of the software without specific prior written permission.
 | 
						|
Silicon Graphics makes no representation about the suitability 
 | 
						|
of this software for any purpose. It is provided "as is"
 | 
						|
without any express or implied warranty.
 | 
						|
 | 
						|
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
 | 
						|
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
 | 
						|
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
 | 
						|
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 
 | 
						|
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 
 | 
						|
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
 | 
						|
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
 | 
						|
THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 | 
						|
********************************************************/
 | 
						|
 | 
						|
#ifdef HAVE_DIX_CONFIG_H
 | 
						|
#include <dix-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <math.h>
 | 
						|
#include <X11/X.h>
 | 
						|
#include <X11/Xproto.h>
 | 
						|
#include <X11/keysym.h>
 | 
						|
#include "misc.h"
 | 
						|
#include "inputstr.h"
 | 
						|
#include "exevents.h"
 | 
						|
#include "eventstr.h"
 | 
						|
#include <xkbsrv.h>
 | 
						|
#include "xkb.h"
 | 
						|
#include <ctype.h>
 | 
						|
#include "mi.h"
 | 
						|
#include "mipointer.h"
 | 
						|
#define EXTENSION_EVENT_BASE 64
 | 
						|
 | 
						|
DevPrivateKeyRec xkbDevicePrivateKeyRec;
 | 
						|
 | 
						|
void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button);
 | 
						|
static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y);
 | 
						|
 | 
						|
void
 | 
						|
xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc,
 | 
						|
                   pointer data)
 | 
						|
{
 | 
						|
    xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
 | 
						|
    ProcessInputProc backupproc;
 | 
						|
    if(xkbPrivPtr->unwrapProc)
 | 
						|
	xkbPrivPtr->unwrapProc = NULL;
 | 
						|
 | 
						|
    UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc);
 | 
						|
    proc(device,data);
 | 
						|
    COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr,
 | 
						|
				 backupproc,xkbUnwrapProc);
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
XkbInitPrivates(void)
 | 
						|
{
 | 
						|
    return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec, PRIVATE_DEVICE, 0);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
 | 
						|
{
 | 
						|
    xkbDeviceInfoPtr xkbPrivPtr;
 | 
						|
 | 
						|
    xkbPrivPtr = (xkbDeviceInfoPtr) calloc(1, sizeof(xkbDeviceInfoRec));
 | 
						|
    if (!xkbPrivPtr)
 | 
						|
	return;
 | 
						|
    xkbPrivPtr->unwrapProc = NULL;
 | 
						|
 | 
						|
    dixSetPrivate(&device->devPrivates, xkbDevicePrivateKey, xkbPrivPtr);
 | 
						|
    WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc);
 | 
						|
}
 | 
						|
 | 
						|
/***====================================================================***/
 | 
						|
 | 
						|
static XkbAction
 | 
						|
_FixUpAction(XkbDescPtr xkb,XkbAction *act)
 | 
						|
{
 | 
						|
static XkbAction	fake;
 | 
						|
 | 
						|
    if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) {
 | 
						|
	fake.type = XkbSA_NoAction;
 | 
						|
	return fake;
 | 
						|
    }
 | 
						|
    if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) {
 | 
						|
	if (act->any.type==XkbSA_SetMods) {
 | 
						|
	    fake.mods.type = XkbSA_LatchMods;
 | 
						|
	    fake.mods.mask = act->mods.mask;
 | 
						|
	    if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
 | 
						|
		 fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
 | 
						|
	    else fake.mods.flags= XkbSA_ClearLocks;
 | 
						|
	    return fake;
 | 
						|
	}
 | 
						|
	if (act->any.type==XkbSA_SetGroup) {
 | 
						|
	    fake.group.type = XkbSA_LatchGroup;
 | 
						|
	    if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
 | 
						|
		 fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
 | 
						|
	    else fake.group.flags= XkbSA_ClearLocks;
 | 
						|
	    XkbSASetGroup(&fake.group,XkbSAGroup(&act->group));
 | 
						|
	    return fake;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    return *act;
 | 
						|
}
 | 
						|
 | 
						|
static XkbAction
 | 
						|
XkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key)
 | 
						|
{
 | 
						|
int			effectiveGroup;
 | 
						|
int			col;
 | 
						|
XkbDescPtr		xkb;
 | 
						|
XkbKeyTypePtr		type;
 | 
						|
XkbAction *		pActs;
 | 
						|
static XkbAction 	fake;
 | 
						|
 | 
						|
    xkb= xkbi->desc;
 | 
						|
    if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) {
 | 
						|
	fake.type = XkbSA_NoAction;
 | 
						|
	return fake;
 | 
						|
    }
 | 
						|
    pActs= XkbKeyActionsPtr(xkb,key);
 | 
						|
    col= 0;
 | 
						|
 | 
						|
    effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key);
 | 
						|
    if (effectiveGroup != XkbGroup1Index)
 | 
						|
        col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key));
 | 
						|
 | 
						|
    type= XkbKeyKeyType(xkb,key,effectiveGroup);
 | 
						|
    if (type->map!=NULL) {
 | 
						|
	register unsigned		i,mods;
 | 
						|
	register XkbKTMapEntryPtr	entry;
 | 
						|
	mods= xkbState->mods&type->mods.mask;
 | 
						|
	for (entry= type->map,i=0;i<type->map_count;i++,entry++) {
 | 
						|
	    if ((entry->active)&&(entry->mods.mask==mods)) {
 | 
						|
		col+= entry->level;
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    if (pActs[col].any.type==XkbSA_NoAction)
 | 
						|
	return pActs[col];
 | 
						|
    fake= _FixUpAction(xkb,&pActs[col]);
 | 
						|
    return fake;
 | 
						|
}
 | 
						|
 | 
						|
static XkbAction
 | 
						|
XkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button)
 | 
						|
{
 | 
						|
XkbAction fake;
 | 
						|
   if ((dev->button)&&(dev->button->xkb_acts)) {
 | 
						|
	if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) {
 | 
						|
	    fake= _FixUpAction(kbd->key->xkbInfo->desc,
 | 
						|
					&dev->button->xkb_acts[button-1]);
 | 
						|
	    return fake;
 | 
						|
	}
 | 
						|
   }
 | 
						|
   fake.any.type= XkbSA_NoAction;
 | 
						|
   return fake;
 | 
						|
}
 | 
						|
 | 
						|
/***====================================================================***/
 | 
						|
 | 
						|
#define	SYNTHETIC_KEYCODE	1
 | 
						|
#define	BTN_ACT_FLAG		0x100
 | 
						|
 | 
						|
static int
 | 
						|
_XkbFilterSetState(	XkbSrvInfoPtr	xkbi,
 | 
						|
			XkbFilterPtr	filter,
 | 
						|
			unsigned	keycode,
 | 
						|
			XkbAction *pAction)
 | 
						|
{
 | 
						|
    if (filter->keycode==0) {		/* initial press */
 | 
						|
	filter->keycode = keycode;
 | 
						|
	filter->active = 1;
 | 
						|
	filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0);
 | 
						|
	filter->priv = 0;
 | 
						|
	filter->filter = _XkbFilterSetState;
 | 
						|
	if (pAction->type==XkbSA_SetMods) {
 | 
						|
	    filter->upAction = *pAction;
 | 
						|
	    xkbi->setMods= pAction->mods.mask;
 | 
						|
	}
 | 
						|
	else {
 | 
						|
	    xkbi->groupChange = XkbSAGroup(&pAction->group);
 | 
						|
	    if (pAction->group.flags&XkbSA_GroupAbsolute)
 | 
						|
		xkbi->groupChange-= xkbi->state.base_group;
 | 
						|
	    filter->upAction= *pAction;
 | 
						|
	    XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
 | 
						|
	}
 | 
						|
    }
 | 
						|
    else if (filter->keycode==keycode) {
 | 
						|
	if (filter->upAction.type==XkbSA_SetMods) {
 | 
						|
	    xkbi->clearMods = filter->upAction.mods.mask;
 | 
						|
	    if (filter->upAction.mods.flags&XkbSA_ClearLocks) {
 | 
						|
		xkbi->state.locked_mods&= ~filter->upAction.mods.mask;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	else {
 | 
						|
	    if (filter->upAction.group.flags&XkbSA_ClearLocks) {
 | 
						|
		xkbi->state.locked_group = 0;
 | 
						|
	    }
 | 
						|
	    xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
 | 
						|
	}
 | 
						|
	filter->active = 0;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	filter->upAction.mods.flags&= ~XkbSA_ClearLocks;
 | 
						|
	filter->filterOthers = 0;
 | 
						|
    }
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
#define	LATCH_KEY_DOWN	1
 | 
						|
#define	LATCH_PENDING	2
 | 
						|
#define	NO_LATCH	3
 | 
						|
 | 
						|
static int
 | 
						|
_XkbFilterLatchState(	XkbSrvInfoPtr	xkbi,
 | 
						|
			XkbFilterPtr	filter,
 | 
						|
			unsigned	keycode,
 | 
						|
			XkbAction *	pAction)
 | 
						|
{
 | 
						|
 | 
						|
    if (filter->keycode==0) {			/* initial press */
 | 
						|
	filter->keycode = keycode;
 | 
						|
	filter->active = 1;
 | 
						|
	filter->filterOthers = 1;
 | 
						|
	filter->priv = LATCH_KEY_DOWN;
 | 
						|
	filter->filter = _XkbFilterLatchState;
 | 
						|
	if (pAction->type==XkbSA_LatchMods) {
 | 
						|
	    filter->upAction = *pAction;
 | 
						|
	    xkbi->setMods = pAction->mods.mask;
 | 
						|
	}
 | 
						|
	else {
 | 
						|
	    xkbi->groupChange = XkbSAGroup(&pAction->group);
 | 
						|
	    if (pAction->group.flags&XkbSA_GroupAbsolute)
 | 
						|
		 xkbi->groupChange-= xkbi->state.base_group;
 | 
						|
	    filter->upAction= *pAction;
 | 
						|
	    XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
 | 
						|
	}
 | 
						|
    }
 | 
						|
    else if ( pAction && (filter->priv==LATCH_PENDING) ) {
 | 
						|
	if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) {
 | 
						|
	    filter->active = 0;
 | 
						|
	    if (filter->upAction.type==XkbSA_LatchMods)
 | 
						|
		 xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
 | 
						|
	    else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
 | 
						|
	}
 | 
						|
	else if ((pAction->type==filter->upAction.type)&&
 | 
						|
		 (pAction->mods.flags==filter->upAction.mods.flags)&&
 | 
						|
		 (pAction->mods.mask==filter->upAction.mods.mask)) {
 | 
						|
	    if (filter->upAction.mods.flags&XkbSA_LatchToLock) {
 | 
						|
		XkbControlsPtr ctrls= xkbi->desc->ctrls;
 | 
						|
		if (filter->upAction.type==XkbSA_LatchMods)
 | 
						|
		     pAction->mods.type= XkbSA_LockMods;
 | 
						|
		else pAction->group.type= XkbSA_LockGroup;
 | 
						|
		if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&&
 | 
						|
		    		(ctrls->enabled_ctrls&XkbStickyKeysMask)) {
 | 
						|
		    XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK,
 | 
						|
						XkbStickyKeysMask);
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	    else {
 | 
						|
		if (filter->upAction.type==XkbSA_LatchMods)
 | 
						|
		     pAction->mods.type= XkbSA_SetMods;
 | 
						|
		else pAction->group.type= XkbSA_SetGroup;
 | 
						|
	    }
 | 
						|
	    if (filter->upAction.type==XkbSA_LatchMods)
 | 
						|
		 xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
 | 
						|
	    else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
 | 
						|
	    filter->active = 0;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    else if (filter->keycode==keycode) {	/* release */
 | 
						|
	XkbControlsPtr	ctrls= xkbi->desc->ctrls;
 | 
						|
	int		needBeep;
 | 
						|
	int		beepType= _BEEP_NONE;
 | 
						|
 | 
						|
	needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&&
 | 
						|
			XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask));
 | 
						|
	if (filter->upAction.type==XkbSA_LatchMods) {
 | 
						|
	    xkbi->clearMods = filter->upAction.mods.mask;
 | 
						|
	    if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&&
 | 
						|
		 (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) {
 | 
						|
		xkbi->state.locked_mods&= ~xkbi->clearMods;
 | 
						|
		filter->priv= NO_LATCH;
 | 
						|
		beepType= _BEEP_STICKY_UNLOCK;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	else {
 | 
						|
	    xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
 | 
						|
	    if ((filter->upAction.group.flags&XkbSA_ClearLocks)&&
 | 
						|
						(xkbi->state.locked_group)) {
 | 
						|
		xkbi->state.locked_group = 0;
 | 
						|
		filter->priv = NO_LATCH;
 | 
						|
		beepType= _BEEP_STICKY_UNLOCK;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	if (filter->priv==NO_LATCH) {
 | 
						|
	    filter->active= 0;
 | 
						|
	}
 | 
						|
	else {
 | 
						|
	    filter->priv= LATCH_PENDING;
 | 
						|
	    if (filter->upAction.type==XkbSA_LatchMods) {
 | 
						|
		xkbi->state.latched_mods |= filter->upAction.mods.mask;
 | 
						|
		needBeep = xkbi->state.latched_mods ? needBeep : 0;
 | 
						|
		xkbi->state.latched_mods |= filter->upAction.mods.mask;
 | 
						|
	    }
 | 
						|
	    else {
 | 
						|
		xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group);
 | 
						|
	    }
 | 
						|
	    if (needBeep && (beepType==_BEEP_NONE))
 | 
						|
		beepType= _BEEP_STICKY_LATCH;
 | 
						|
	}
 | 
						|
	if (needBeep && (beepType!=_BEEP_NONE))
 | 
						|
	    XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask);
 | 
						|
    }
 | 
						|
    else if (filter->priv==LATCH_KEY_DOWN) {
 | 
						|
	filter->priv= NO_LATCH;
 | 
						|
	filter->filterOthers = 0;
 | 
						|
    }
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
_XkbFilterLockState(	XkbSrvInfoPtr	xkbi,
 | 
						|
			XkbFilterPtr	filter,
 | 
						|
			unsigned	keycode,
 | 
						|
			XkbAction *	pAction)
 | 
						|
{
 | 
						|
    if (pAction&&(pAction->type==XkbSA_LockGroup)) {
 | 
						|
	if (pAction->group.flags&XkbSA_GroupAbsolute)
 | 
						|
	     xkbi->state.locked_group= XkbSAGroup(&pAction->group);
 | 
						|
	else xkbi->state.locked_group+= XkbSAGroup(&pAction->group);
 | 
						|
	return 1;
 | 
						|
    }
 | 
						|
    if (filter->keycode==0) {		/* initial press */
 | 
						|
	filter->keycode = keycode;
 | 
						|
	filter->active = 1;
 | 
						|
	filter->filterOthers = 0;
 | 
						|
	filter->priv = 0;
 | 
						|
	filter->filter = _XkbFilterLockState;
 | 
						|
	filter->upAction = *pAction;
 | 
						|
	xkbi->state.locked_mods^= pAction->mods.mask;
 | 
						|
	xkbi->setMods = pAction->mods.mask;
 | 
						|
    }
 | 
						|
    else if (filter->keycode==keycode) {
 | 
						|
	filter->active = 0;
 | 
						|
	xkbi->clearMods = filter->upAction.mods.mask;
 | 
						|
    }
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
#define	ISO_KEY_DOWN		0
 | 
						|
#define	NO_ISO_LOCK		1
 | 
						|
 | 
						|
static int
 | 
						|
_XkbFilterISOLock(	XkbSrvInfoPtr	xkbi,
 | 
						|
			XkbFilterPtr	filter,
 | 
						|
			unsigned	keycode,
 | 
						|
			XkbAction *	pAction)
 | 
						|
{
 | 
						|
 | 
						|
    if (filter->keycode==0) {		/* initial press */
 | 
						|
	CARD8	flags= pAction->iso.flags;
 | 
						|
 | 
						|
	filter->keycode = keycode;
 | 
						|
	filter->active = 1;
 | 
						|
	filter->filterOthers = 1;
 | 
						|
	filter->priv = ISO_KEY_DOWN;
 | 
						|
	filter->upAction = *pAction;
 | 
						|
	filter->filter = _XkbFilterISOLock;
 | 
						|
	if (flags&XkbSA_ISODfltIsGroup) {
 | 
						|
	    xkbi->groupChange = XkbSAGroup(&pAction->iso);
 | 
						|
	    xkbi->setMods = 0;
 | 
						|
	}
 | 
						|
	else {
 | 
						|
	    xkbi->setMods = pAction->iso.mask;
 | 
						|
	    xkbi->groupChange = 0;
 | 
						|
	}
 | 
						|
	if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) {
 | 
						|
	    filter->priv= NO_ISO_LOCK;
 | 
						|
	    xkbi->state.locked_mods^= xkbi->state.base_mods;
 | 
						|
	}
 | 
						|
	if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) {
 | 
						|
/* 6/22/93 (ef) -- lock groups if group key is down first */
 | 
						|
	}
 | 
						|
	if (!(flags&XkbSA_ISONoAffectPtr)) {
 | 
						|
/* 6/22/93 (ef) -- lock mouse buttons if they're down */
 | 
						|
	}
 | 
						|
    }
 | 
						|
    else if (filter->keycode==keycode) {
 | 
						|
	CARD8	flags= filter->upAction.iso.flags;
 | 
						|
 | 
						|
	if (flags&XkbSA_ISODfltIsGroup) {
 | 
						|
	    xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
 | 
						|
	    xkbi->clearMods = 0;
 | 
						|
	    if (filter->priv==ISO_KEY_DOWN)
 | 
						|
		xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso);
 | 
						|
	}
 | 
						|
	else {
 | 
						|
	    xkbi->clearMods= filter->upAction.iso.mask;
 | 
						|
	    xkbi->groupChange= 0;
 | 
						|
	    if (filter->priv==ISO_KEY_DOWN)
 | 
						|
		xkbi->state.locked_mods^= filter->upAction.iso.mask;
 | 
						|
	}
 | 
						|
	filter->active = 0;
 | 
						|
    }
 | 
						|
    else if (pAction) {
 | 
						|
	CARD8	flags= filter->upAction.iso.flags;
 | 
						|
 | 
						|
	switch (pAction->type) {
 | 
						|
	    case XkbSA_SetMods: case XkbSA_LatchMods:
 | 
						|
		if (!(flags&XkbSA_ISONoAffectMods)) {
 | 
						|
		    pAction->type= XkbSA_LockMods;
 | 
						|
		    filter->priv= NO_ISO_LOCK;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	    case XkbSA_SetGroup: case XkbSA_LatchGroup:
 | 
						|
		if (!(flags&XkbSA_ISONoAffectGroup)) {
 | 
						|
		    pAction->type= XkbSA_LockGroup;
 | 
						|
		    filter->priv= NO_ISO_LOCK;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	    case XkbSA_PtrBtn:
 | 
						|
		if (!(flags&XkbSA_ISONoAffectPtr)) {
 | 
						|
		     pAction->type= XkbSA_LockPtrBtn;
 | 
						|
		     filter->priv= NO_ISO_LOCK;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	    case XkbSA_SetControls:
 | 
						|
		if (!(flags&XkbSA_ISONoAffectCtrls)) {
 | 
						|
		    pAction->type= XkbSA_LockControls;
 | 
						|
		    filter->priv= NO_ISO_LOCK;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static CARD32
 | 
						|
_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg)
 | 
						|
{
 | 
						|
XkbSrvInfoPtr	xkbi= (XkbSrvInfoPtr)arg;
 | 
						|
XkbControlsPtr	ctrls= xkbi->desc->ctrls;
 | 
						|
int		dx,dy;
 | 
						|
 | 
						|
    if (xkbi->mouseKey==0)
 | 
						|
	return 0;
 | 
						|
 | 
						|
    if (xkbi->mouseKeysAccel) {
 | 
						|
	if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) {
 | 
						|
	    double step;
 | 
						|
	    xkbi->mouseKeysCounter++;
 | 
						|
	    step= xkbi->mouseKeysCurveFactor*
 | 
						|
		 pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve);
 | 
						|
	    if (xkbi->mouseKeysDX<0)
 | 
						|
		 dx= floor( ((double)xkbi->mouseKeysDX)*step );
 | 
						|
	    else dx=  ceil( ((double)xkbi->mouseKeysDX)*step );
 | 
						|
	    if (xkbi->mouseKeysDY<0)
 | 
						|
		 dy= floor( ((double)xkbi->mouseKeysDY)*step );
 | 
						|
	    else dy=  ceil( ((double)xkbi->mouseKeysDY)*step );
 | 
						|
	}
 | 
						|
	else {
 | 
						|
	    dx= xkbi->mouseKeysDX*ctrls->mk_max_speed;
 | 
						|
	    dy= xkbi->mouseKeysDY*ctrls->mk_max_speed;
 | 
						|
	}
 | 
						|
	if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX)
 | 
						|
	    dx= xkbi->mouseKeysDX;
 | 
						|
	if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY)
 | 
						|
	    dy= xkbi->mouseKeysDY;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	dx= xkbi->mouseKeysDX;
 | 
						|
	dy= xkbi->mouseKeysDY;
 | 
						|
    }
 | 
						|
    XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy);
 | 
						|
    return xkbi->desc->ctrls->mk_interval;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
_XkbFilterPointerMove(	XkbSrvInfoPtr	xkbi,
 | 
						|
			XkbFilterPtr	filter,
 | 
						|
			unsigned	keycode,
 | 
						|
			XkbAction *	pAction)
 | 
						|
{
 | 
						|
int	x,y;
 | 
						|
Bool	accel;
 | 
						|
 | 
						|
    if (filter->keycode==0) {		/* initial press */
 | 
						|
	filter->keycode = keycode;
 | 
						|
	filter->active = 1;
 | 
						|
	filter->filterOthers = 0;
 | 
						|
	filter->priv=0;
 | 
						|
	filter->filter = _XkbFilterPointerMove;
 | 
						|
	filter->upAction= *pAction;
 | 
						|
	xkbi->mouseKeysCounter= 0;
 | 
						|
	xkbi->mouseKey= keycode;
 | 
						|
	accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0);
 | 
						|
	x= XkbPtrActionX(&pAction->ptr);
 | 
						|
	y= XkbPtrActionY(&pAction->ptr);
 | 
						|
	XkbFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y);
 | 
						|
	AccessXCancelRepeatKey(xkbi,keycode);
 | 
						|
	xkbi->mouseKeysAccel= accel&&
 | 
						|
		(xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask);
 | 
						|
	xkbi->mouseKeysFlags= pAction->ptr.flags;
 | 
						|
	xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr);
 | 
						|
	xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr);
 | 
						|
	xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0,
 | 
						|
				xkbi->desc->ctrls->mk_delay,
 | 
						|
				_XkbPtrAccelExpire,(pointer)xkbi);
 | 
						|
    }
 | 
						|
    else if (filter->keycode==keycode) {
 | 
						|
	filter->active = 0;
 | 
						|
	if (xkbi->mouseKey==keycode) {
 | 
						|
	    xkbi->mouseKey= 0;
 | 
						|
	    xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0,
 | 
						|
							NULL, NULL);
 | 
						|
	}
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
_XkbFilterPointerBtn(	XkbSrvInfoPtr	xkbi,
 | 
						|
			XkbFilterPtr	filter,
 | 
						|
			unsigned	keycode,
 | 
						|
			XkbAction *	pAction)
 | 
						|
{
 | 
						|
    if (filter->keycode==0) {		/* initial press */
 | 
						|
	int	button= pAction->btn.button;
 | 
						|
 | 
						|
	if (button==XkbSA_UseDfltButton)
 | 
						|
	    button = xkbi->desc->ctrls->mk_dflt_btn;
 | 
						|
 | 
						|
	filter->keycode = keycode;
 | 
						|
	filter->active = 1;
 | 
						|
	filter->filterOthers = 0;
 | 
						|
	filter->priv=0;
 | 
						|
	filter->filter = _XkbFilterPointerBtn;
 | 
						|
	filter->upAction= *pAction;
 | 
						|
	filter->upAction.btn.button= button;
 | 
						|
	switch (pAction->type) {
 | 
						|
	    case XkbSA_LockPtrBtn:
 | 
						|
		if (((xkbi->lockedPtrButtons&(1<<button))==0)&&
 | 
						|
			((pAction->btn.flags&XkbSA_LockNoLock)==0)) {
 | 
						|
		    xkbi->lockedPtrButtons|= (1<<button);
 | 
						|
		    AccessXCancelRepeatKey(xkbi,keycode);
 | 
						|
		    XkbFakeDeviceButton(xkbi->device, 1, button);
 | 
						|
		    filter->upAction.type= XkbSA_NoAction;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	    case XkbSA_PtrBtn:
 | 
						|
		{
 | 
						|
		    register int i,nClicks;
 | 
						|
		    AccessXCancelRepeatKey(xkbi,keycode);
 | 
						|
		    if (pAction->btn.count>0) {
 | 
						|
			nClicks= pAction->btn.count;
 | 
						|
			for (i=0;i<nClicks;i++) {
 | 
						|
			    XkbFakeDeviceButton(xkbi->device, 1, button);
 | 
						|
			    XkbFakeDeviceButton(xkbi->device, 0, button);
 | 
						|
			}
 | 
						|
			filter->upAction.type= XkbSA_NoAction;
 | 
						|
		    }
 | 
						|
		    else XkbFakeDeviceButton(xkbi->device, 1, button);
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	    case XkbSA_SetPtrDflt:
 | 
						|
		{
 | 
						|
		    XkbControlsPtr	ctrls= xkbi->desc->ctrls;
 | 
						|
		    XkbControlsRec	old;
 | 
						|
		    xkbControlsNotify	cn;
 | 
						|
 | 
						|
		    old= *ctrls;
 | 
						|
		    AccessXCancelRepeatKey(xkbi,keycode);
 | 
						|
		    switch (pAction->dflt.affect) {
 | 
						|
			case XkbSA_AffectDfltBtn:
 | 
						|
			    if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute)
 | 
						|
				ctrls->mk_dflt_btn= 
 | 
						|
					XkbSAPtrDfltValue(&pAction->dflt);
 | 
						|
			    else {
 | 
						|
				ctrls->mk_dflt_btn+=
 | 
						|
					XkbSAPtrDfltValue(&pAction->dflt);
 | 
						|
				if (ctrls->mk_dflt_btn>5)
 | 
						|
				    ctrls->mk_dflt_btn= 5;
 | 
						|
				else if (ctrls->mk_dflt_btn<1)
 | 
						|
				    ctrls->mk_dflt_btn= 1;
 | 
						|
			    }
 | 
						|
			    break;
 | 
						|
			default:
 | 
						|
			    ErrorF(
 | 
						|
		"Attempt to change unknown pointer default (%d) ignored\n",
 | 
						|
							pAction->dflt.affect);
 | 
						|
			    break;
 | 
						|
		    }
 | 
						|
		    if (XkbComputeControlsNotify(xkbi->device,
 | 
						|
						&old,xkbi->desc->ctrls,
 | 
						|
						&cn,FALSE)) {
 | 
						|
			cn.keycode = keycode;
 | 
						|
                        /* XXX: what about DeviceKeyPress? */
 | 
						|
			cn.eventType = KeyPress;
 | 
						|
			cn.requestMajor = 0;
 | 
						|
			cn.requestMinor = 0;
 | 
						|
			XkbSendControlsNotify(xkbi->device,&cn);
 | 
						|
		    }
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    else if (filter->keycode==keycode) {
 | 
						|
	int	button= filter->upAction.btn.button;
 | 
						|
 | 
						|
	switch (filter->upAction.type) {
 | 
						|
	    case XkbSA_LockPtrBtn:
 | 
						|
		if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)||
 | 
						|
				((xkbi->lockedPtrButtons&(1<<button))==0)) {
 | 
						|
		    break;
 | 
						|
		}
 | 
						|
		xkbi->lockedPtrButtons&= ~(1<<button);
 | 
						|
 | 
						|
		if (IsMaster(xkbi->device))
 | 
						|
		{
 | 
						|
		    XkbMergeLockedPtrBtns(xkbi->device);
 | 
						|
                    /* One SD still has lock set, don't post event */
 | 
						|
		    if ((xkbi->lockedPtrButtons & (1 << button)) != 0)
 | 
						|
			break;
 | 
						|
		}
 | 
						|
 | 
						|
		/* fallthrough */
 | 
						|
	    case XkbSA_PtrBtn:
 | 
						|
		XkbFakeDeviceButton(xkbi->device, 0, button);
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	filter->active = 0;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
_XkbFilterControls(	XkbSrvInfoPtr	xkbi,
 | 
						|
			XkbFilterPtr	filter,
 | 
						|
			unsigned	keycode,
 | 
						|
			XkbAction *	pAction)
 | 
						|
{
 | 
						|
XkbControlsRec		old;
 | 
						|
XkbControlsPtr		ctrls;
 | 
						|
DeviceIntPtr		kbd;
 | 
						|
unsigned int		change;
 | 
						|
XkbEventCauseRec	cause;
 | 
						|
 | 
						|
    kbd= xkbi->device;
 | 
						|
    ctrls= xkbi->desc->ctrls;
 | 
						|
    old= *ctrls;
 | 
						|
    if (filter->keycode==0) {		/* initial press */
 | 
						|
	filter->keycode = keycode;
 | 
						|
	filter->active = 1;
 | 
						|
	filter->filterOthers = 0;
 | 
						|
	change= XkbActionCtrls(&pAction->ctrls);
 | 
						|
	filter->priv = change;
 | 
						|
	filter->filter = _XkbFilterControls;
 | 
						|
	filter->upAction = *pAction;
 | 
						|
 | 
						|
	if (pAction->type==XkbSA_LockControls) {
 | 
						|
	    filter->priv= (ctrls->enabled_ctrls&change);
 | 
						|
	    change&= ~ctrls->enabled_ctrls;
 | 
						|
	}
 | 
						|
 | 
						|
	if (change) {
 | 
						|
	    xkbControlsNotify	cn;
 | 
						|
	    XkbSrvLedInfoPtr	sli;
 | 
						|
 | 
						|
	    ctrls->enabled_ctrls|= change;
 | 
						|
	    if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) {
 | 
						|
		cn.keycode = keycode;
 | 
						|
                /* XXX: what about DeviceKeyPress? */
 | 
						|
		cn.eventType = KeyPress;
 | 
						|
		cn.requestMajor = 0;
 | 
						|
		cn.requestMinor = 0;
 | 
						|
		XkbSendControlsNotify(kbd,&cn);
 | 
						|
	    }
 | 
						|
 | 
						|
	    XkbSetCauseKey(&cause,keycode,KeyPress);
 | 
						|
 | 
						|
	    /* If sticky keys were disabled, clear all locks and latches */
 | 
						|
	    if ((old.enabled_ctrls&XkbStickyKeysMask)&&
 | 
						|
		(!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
 | 
						|
		XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause);
 | 
						|
    	    }
 | 
						|
	    sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
 | 
						|
	    XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause);
 | 
						|
	    if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
 | 
						|
		XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change);
 | 
						|
	}
 | 
						|
    }
 | 
						|
    else if (filter->keycode==keycode) {
 | 
						|
	change= filter->priv;
 | 
						|
	if (change) {
 | 
						|
	    xkbControlsNotify 	cn;
 | 
						|
	    XkbSrvLedInfoPtr	sli;
 | 
						|
 | 
						|
	    ctrls->enabled_ctrls&= ~change;
 | 
						|
	    if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) {
 | 
						|
		cn.keycode = keycode;
 | 
						|
		cn.eventType = KeyRelease;
 | 
						|
		cn.requestMajor = 0;
 | 
						|
		cn.requestMinor = 0;
 | 
						|
		XkbSendControlsNotify(kbd,&cn);
 | 
						|
	    }
 | 
						|
 | 
						|
	    XkbSetCauseKey(&cause,keycode,KeyRelease);
 | 
						|
	    /* If sticky keys were disabled, clear all locks and latches */
 | 
						|
	    if ((old.enabled_ctrls&XkbStickyKeysMask)&&
 | 
						|
		(!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
 | 
						|
		XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause);
 | 
						|
    	    }
 | 
						|
	    sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
 | 
						|
	    XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause);
 | 
						|
	    if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
 | 
						|
		XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change);
 | 
						|
	}
 | 
						|
	filter->keycode= 0;
 | 
						|
	filter->active= 0;
 | 
						|
    }
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
_XkbFilterActionMessage(XkbSrvInfoPtr	xkbi,
 | 
						|
			XkbFilterPtr	filter,
 | 
						|
			unsigned	keycode,
 | 
						|
			XkbAction *	pAction)
 | 
						|
{
 | 
						|
XkbMessageAction *	pMsg;
 | 
						|
DeviceIntPtr		kbd;
 | 
						|
 | 
						|
    kbd= xkbi->device;
 | 
						|
    if (filter->keycode==0) {		/* initial press */
 | 
						|
	pMsg= &pAction->msg;
 | 
						|
	if ((pMsg->flags&XkbSA_MessageOnRelease)||
 | 
						|
	    ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) {
 | 
						|
	    filter->keycode = keycode;
 | 
						|
	    filter->active = 1;
 | 
						|
	    filter->filterOthers = 0;
 | 
						|
	    filter->priv = 0;
 | 
						|
	    filter->filter = _XkbFilterActionMessage;
 | 
						|
	    filter->upAction = *pAction;
 | 
						|
	}
 | 
						|
	if (pMsg->flags&XkbSA_MessageOnPress)  {
 | 
						|
	    xkbActionMessage	msg;
 | 
						|
 | 
						|
	    msg.keycode= keycode;
 | 
						|
	    msg.press= 1;
 | 
						|
	    msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
 | 
						|
	    memcpy((char *)msg.message,
 | 
						|
				(char *)pMsg->message,XkbActionMessageLength);
 | 
						|
	    XkbSendActionMessage(kbd,&msg);
 | 
						|
	}
 | 
						|
	return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0);
 | 
						|
    }
 | 
						|
    else if (filter->keycode==keycode) {
 | 
						|
	pMsg= &filter->upAction.msg;
 | 
						|
	if (pMsg->flags&XkbSA_MessageOnRelease) {
 | 
						|
	    xkbActionMessage	msg;
 | 
						|
 | 
						|
	    msg.keycode= keycode;
 | 
						|
	    msg.press= 0;
 | 
						|
	    msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
 | 
						|
	    memcpy((char *)msg.message,(char *)pMsg->message,
 | 
						|
						XkbActionMessageLength);
 | 
						|
	    XkbSendActionMessage(kbd,&msg);
 | 
						|
	}
 | 
						|
	filter->keycode= 0;
 | 
						|
	filter->active= 0;
 | 
						|
	return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
_XkbFilterRedirectKey(	XkbSrvInfoPtr	xkbi,
 | 
						|
			XkbFilterPtr	filter,
 | 
						|
			unsigned	keycode,
 | 
						|
			XkbAction *	pAction)
 | 
						|
{
 | 
						|
DeviceEvent	ev;
 | 
						|
int		x,y;
 | 
						|
XkbStateRec	old;
 | 
						|
unsigned	mods,mask;
 | 
						|
xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
 | 
						|
ProcessInputProc backupproc;
 | 
						|
 | 
						|
    /* never actually used uninitialised, but gcc isn't smart enough
 | 
						|
     * to work that out. */
 | 
						|
    memset(&old, 0, sizeof(old));
 | 
						|
 | 
						|
    if ((filter->keycode!=0)&&(filter->keycode!=keycode))
 | 
						|
	return 1;
 | 
						|
 | 
						|
    GetSpritePosition(xkbi->device, &x,&y);
 | 
						|
    ev.header = ET_Internal;
 | 
						|
    ev.length = sizeof(DeviceEvent);
 | 
						|
    ev.time = GetTimeInMillis();
 | 
						|
    ev.root_x = x;
 | 
						|
    ev.root_y = y;
 | 
						|
 | 
						|
    if (filter->keycode==0) {		/* initial press */
 | 
						|
	if ((pAction->redirect.new_key<xkbi->desc->min_key_code)||
 | 
						|
	    (pAction->redirect.new_key>xkbi->desc->max_key_code)) {
 | 
						|
	    return 1;
 | 
						|
	}
 | 
						|
	filter->keycode = keycode;
 | 
						|
	filter->active = 1;
 | 
						|
	filter->filterOthers = 0;
 | 
						|
	filter->priv = 0;
 | 
						|
	filter->filter = _XkbFilterRedirectKey;
 | 
						|
	filter->upAction = *pAction;
 | 
						|
 | 
						|
        ev.type = ET_KeyPress;
 | 
						|
        ev.detail.key = pAction->redirect.new_key;
 | 
						|
 | 
						|
        mask= XkbSARedirectVModsMask(&pAction->redirect);
 | 
						|
        mods= XkbSARedirectVMods(&pAction->redirect);
 | 
						|
        if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
 | 
						|
        if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
 | 
						|
        mask|= pAction->redirect.mods_mask;
 | 
						|
        mods|= pAction->redirect.mods;
 | 
						|
 | 
						|
	if ( mask || mods ) {
 | 
						|
	    old= xkbi->state;
 | 
						|
	    xkbi->state.base_mods&= ~mask;
 | 
						|
	    xkbi->state.base_mods|= (mods&mask);
 | 
						|
	    xkbi->state.latched_mods&= ~mask;
 | 
						|
	    xkbi->state.latched_mods|= (mods&mask);
 | 
						|
	    xkbi->state.locked_mods&= ~mask;
 | 
						|
	    xkbi->state.locked_mods|= (mods&mask);
 | 
						|
	    XkbComputeDerivedState(xkbi);
 | 
						|
	}
 | 
						|
 | 
						|
	UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
 | 
						|
	xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
 | 
						|
	COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
 | 
						|
				     backupproc,xkbUnwrapProc);
 | 
						|
	
 | 
						|
	if ( mask || mods )
 | 
						|
	    xkbi->state= old;
 | 
						|
    }
 | 
						|
    else if (filter->keycode==keycode) {
 | 
						|
 | 
						|
        ev.type = ET_KeyRelease;
 | 
						|
        ev.detail.key = filter->upAction.redirect.new_key;
 | 
						|
 | 
						|
        mask= XkbSARedirectVModsMask(&filter->upAction.redirect);
 | 
						|
        mods= XkbSARedirectVMods(&filter->upAction.redirect);
 | 
						|
        if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
 | 
						|
        if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
 | 
						|
        mask|= filter->upAction.redirect.mods_mask;
 | 
						|
        mods|= filter->upAction.redirect.mods;
 | 
						|
 | 
						|
	if ( mask || mods ) {
 | 
						|
	    old= xkbi->state;
 | 
						|
	    xkbi->state.base_mods&= ~mask;
 | 
						|
	    xkbi->state.base_mods|= (mods&mask);
 | 
						|
	    xkbi->state.latched_mods&= ~mask;
 | 
						|
	    xkbi->state.latched_mods|= (mods&mask);
 | 
						|
	    xkbi->state.locked_mods&= ~mask;
 | 
						|
	    xkbi->state.locked_mods|= (mods&mask);
 | 
						|
	    XkbComputeDerivedState(xkbi);
 | 
						|
	}
 | 
						|
 | 
						|
	UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
 | 
						|
	xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
 | 
						|
	COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
 | 
						|
				     backupproc,xkbUnwrapProc);
 | 
						|
 | 
						|
	if ( mask || mods )
 | 
						|
	    xkbi->state= old;
 | 
						|
 | 
						|
	filter->keycode= 0;
 | 
						|
	filter->active= 0;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
_XkbFilterSwitchScreen(	XkbSrvInfoPtr	xkbi,
 | 
						|
			XkbFilterPtr	filter,
 | 
						|
			unsigned	keycode,
 | 
						|
			XkbAction *	pAction)
 | 
						|
{
 | 
						|
    DeviceIntPtr dev = xkbi->device;
 | 
						|
    if (dev == inputInfo.keyboard)
 | 
						|
        return 0;
 | 
						|
 | 
						|
    if (filter->keycode==0) {		/* initial press */
 | 
						|
	filter->keycode = keycode;
 | 
						|
	filter->active = 1;
 | 
						|
	filter->filterOthers = 0;
 | 
						|
	filter->filter = _XkbFilterSwitchScreen;
 | 
						|
	AccessXCancelRepeatKey(xkbi, keycode);
 | 
						|
	XkbDDXSwitchScreen(dev,keycode,pAction);
 | 
						|
        return 0; 
 | 
						|
    }
 | 
						|
    else if (filter->keycode==keycode) {
 | 
						|
	filter->active= 0;
 | 
						|
        return 0; 
 | 
						|
    }
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
_XkbFilterXF86Private(	XkbSrvInfoPtr	xkbi,
 | 
						|
			XkbFilterPtr	filter,
 | 
						|
			unsigned	keycode,
 | 
						|
			XkbAction *	pAction)
 | 
						|
{
 | 
						|
    DeviceIntPtr dev = xkbi->device;
 | 
						|
    if (dev == inputInfo.keyboard)
 | 
						|
        return 0;
 | 
						|
 | 
						|
    if (filter->keycode==0) {		/* initial press */
 | 
						|
	filter->keycode = keycode;
 | 
						|
	filter->active = 1;
 | 
						|
	filter->filterOthers = 0;
 | 
						|
	filter->filter = _XkbFilterXF86Private;
 | 
						|
	XkbDDXPrivate(dev,keycode,pAction);
 | 
						|
        return 0; 
 | 
						|
    }
 | 
						|
    else if (filter->keycode==keycode) {
 | 
						|
	filter->active= 0;
 | 
						|
        return 0; 
 | 
						|
    }
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static int
 | 
						|
_XkbFilterDeviceBtn(	XkbSrvInfoPtr	xkbi,
 | 
						|
			XkbFilterPtr	filter,
 | 
						|
			unsigned	keycode,
 | 
						|
			XkbAction *	pAction)
 | 
						|
{
 | 
						|
DeviceIntPtr	dev;
 | 
						|
int		button;
 | 
						|
 | 
						|
    if (xkbi->device == inputInfo.keyboard)
 | 
						|
        return 0;
 | 
						|
 | 
						|
    if (filter->keycode==0) {		/* initial press */
 | 
						|
	_XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient,
 | 
						|
			       DixUnknownAccess, &button);
 | 
						|
	if (!dev || !dev->public.on)
 | 
						|
	    return 1;
 | 
						|
 | 
						|
	button= pAction->devbtn.button;
 | 
						|
	if ((button<1)||(button>dev->button->numButtons))
 | 
						|
	    return 1;
 | 
						|
 | 
						|
	filter->keycode = keycode;
 | 
						|
	filter->active = 1;
 | 
						|
	filter->filterOthers = 0;
 | 
						|
	filter->priv=0;
 | 
						|
	filter->filter = _XkbFilterDeviceBtn;
 | 
						|
	filter->upAction= *pAction;
 | 
						|
	switch (pAction->type) {
 | 
						|
	    case XkbSA_LockDeviceBtn:
 | 
						|
		if ((pAction->devbtn.flags&XkbSA_LockNoLock)||
 | 
						|
		    BitIsOn(dev->button->down, button))
 | 
						|
		    return 0;
 | 
						|
		XkbFakeDeviceButton(dev,TRUE,button);
 | 
						|
		filter->upAction.type= XkbSA_NoAction;
 | 
						|
		break;
 | 
						|
	    case XkbSA_DeviceBtn:
 | 
						|
		if (pAction->devbtn.count>0) {
 | 
						|
		    int nClicks,i;
 | 
						|
		    nClicks= pAction->btn.count;
 | 
						|
		    for (i=0;i<nClicks;i++) {
 | 
						|
			XkbFakeDeviceButton(dev,TRUE,button);
 | 
						|
			XkbFakeDeviceButton(dev,FALSE,button);
 | 
						|
		    }
 | 
						|
		    filter->upAction.type= XkbSA_NoAction;
 | 
						|
		}
 | 
						|
		else XkbFakeDeviceButton(dev,TRUE,button);
 | 
						|
		break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    else if (filter->keycode==keycode) {
 | 
						|
	int	button;
 | 
						|
 | 
						|
	filter->active= 0;
 | 
						|
	_XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device,
 | 
						|
			       serverClient, DixUnknownAccess, &button);
 | 
						|
	if (!dev || !dev->public.on)
 | 
						|
	    return 1;
 | 
						|
 | 
						|
	button= filter->upAction.btn.button;
 | 
						|
	switch (filter->upAction.type) {
 | 
						|
	    case XkbSA_LockDeviceBtn:
 | 
						|
		if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)||
 | 
						|
		    !BitIsOn(dev->button->down, button))
 | 
						|
		    return 0;
 | 
						|
		XkbFakeDeviceButton(dev,FALSE,button);
 | 
						|
		break;
 | 
						|
	    case XkbSA_DeviceBtn:
 | 
						|
		XkbFakeDeviceButton(dev,FALSE,button);
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	filter->active = 0;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static XkbFilterPtr
 | 
						|
_XkbNextFreeFilter(
 | 
						|
	XkbSrvInfoPtr xkbi
 | 
						|
)
 | 
						|
{
 | 
						|
register int	i;
 | 
						|
 | 
						|
    if (xkbi->szFilters==0) {
 | 
						|
	xkbi->szFilters = 4;
 | 
						|
	xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec));
 | 
						|
	/* 6/21/93 (ef) -- XXX! deal with allocation failure */
 | 
						|
    }
 | 
						|
    for (i=0;i<xkbi->szFilters;i++) {
 | 
						|
	if (!xkbi->filters[i].active) {
 | 
						|
	    xkbi->filters[i].keycode = 0;
 | 
						|
	    return &xkbi->filters[i];
 | 
						|
	}
 | 
						|
    }
 | 
						|
    xkbi->szFilters*=2;
 | 
						|
    xkbi->filters= realloc(xkbi->filters,
 | 
						|
                            xkbi->szFilters * sizeof(XkbFilterRec));
 | 
						|
    /* 6/21/93 (ef) -- XXX! deal with allocation failure */
 | 
						|
    memset(&xkbi->filters[xkbi->szFilters/2], 0,
 | 
						|
            (xkbi->szFilters/2)*sizeof(XkbFilterRec));
 | 
						|
    return &xkbi->filters[xkbi->szFilters/2];
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction)
 | 
						|
{
 | 
						|
register int	i,send;
 | 
						|
 | 
						|
    send= 1;
 | 
						|
    for (i=0;i<xkbi->szFilters;i++) {
 | 
						|
	if ((xkbi->filters[i].active)&&(xkbi->filters[i].filter))
 | 
						|
	    send= ((*xkbi->filters[i].filter)(xkbi,&xkbi->filters[i],kc,pAction) 
 | 
						|
                    && send);
 | 
						|
    }
 | 
						|
    return send;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent* event)
 | 
						|
{
 | 
						|
int		key,bit,i;
 | 
						|
XkbSrvInfoPtr	xkbi;
 | 
						|
KeyClassPtr	keyc;
 | 
						|
int		changed,sendEvent;
 | 
						|
Bool		genStateNotify;
 | 
						|
XkbAction	act;
 | 
						|
XkbFilterPtr	filter;
 | 
						|
Bool		keyEvent;
 | 
						|
Bool		pressEvent;
 | 
						|
ProcessInputProc backupproc;
 | 
						|
    
 | 
						|
xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
 | 
						|
 | 
						|
    keyc= kbd->key;
 | 
						|
    xkbi= keyc->xkbInfo;
 | 
						|
    key= event->detail.key;
 | 
						|
    /* The state may change, so if we're not in the middle of sending a state
 | 
						|
     * notify, prepare for it */
 | 
						|
    if ((xkbi->flags&_XkbStateNotifyInProgress)==0) {
 | 
						|
	xkbi->prev_state = xkbi->state;
 | 
						|
	xkbi->flags|= _XkbStateNotifyInProgress;
 | 
						|
	genStateNotify= TRUE;
 | 
						|
    }
 | 
						|
    else genStateNotify= FALSE;
 | 
						|
 | 
						|
    xkbi->clearMods = xkbi->setMods = 0;
 | 
						|
    xkbi->groupChange = 0;
 | 
						|
 | 
						|
    sendEvent = 1;
 | 
						|
    keyEvent= ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
 | 
						|
    pressEvent= ((event->type == ET_KeyPress)|| (event->type == ET_ButtonPress));
 | 
						|
 | 
						|
    if (pressEvent) {
 | 
						|
	if (keyEvent)	
 | 
						|
	    act = XkbGetKeyAction(xkbi,&xkbi->state,key);
 | 
						|
	else {
 | 
						|
	    act = XkbGetButtonAction(kbd,dev,key);
 | 
						|
	    key|= BTN_ACT_FLAG;
 | 
						|
	}
 | 
						|
	sendEvent = _XkbApplyFilters(xkbi,key,&act);
 | 
						|
	if (sendEvent) {
 | 
						|
	    switch (act.type) {
 | 
						|
		case XkbSA_SetMods:
 | 
						|
		case XkbSA_SetGroup:
 | 
						|
		    filter = _XkbNextFreeFilter(xkbi);
 | 
						|
		    sendEvent = _XkbFilterSetState(xkbi,filter,key,&act);
 | 
						|
		    break;
 | 
						|
		case XkbSA_LatchMods:
 | 
						|
		case XkbSA_LatchGroup:
 | 
						|
		    filter = _XkbNextFreeFilter(xkbi);
 | 
						|
		    sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act);
 | 
						|
		    break;
 | 
						|
		case XkbSA_LockMods:
 | 
						|
		case XkbSA_LockGroup:
 | 
						|
		    filter = _XkbNextFreeFilter(xkbi);
 | 
						|
		    sendEvent=_XkbFilterLockState(xkbi,filter,key,&act);
 | 
						|
		    break;
 | 
						|
		case XkbSA_ISOLock:
 | 
						|
		    filter = _XkbNextFreeFilter(xkbi);
 | 
						|
		    sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act);
 | 
						|
		    break;
 | 
						|
		case XkbSA_MovePtr:
 | 
						|
		    filter = _XkbNextFreeFilter(xkbi);
 | 
						|
		    sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act);
 | 
						|
		    break;
 | 
						|
		case XkbSA_PtrBtn:
 | 
						|
		case XkbSA_LockPtrBtn:
 | 
						|
		case XkbSA_SetPtrDflt:
 | 
						|
		    filter = _XkbNextFreeFilter(xkbi);
 | 
						|
		    sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act);
 | 
						|
		    break;
 | 
						|
		case XkbSA_Terminate:
 | 
						|
		    sendEvent= XkbDDXTerminateServer(dev,key,&act);
 | 
						|
		    break;
 | 
						|
		case XkbSA_SwitchScreen:
 | 
						|
		    filter = _XkbNextFreeFilter(xkbi);
 | 
						|
		    sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act);
 | 
						|
		    break;
 | 
						|
		case XkbSA_SetControls:
 | 
						|
		case XkbSA_LockControls:
 | 
						|
		    filter = _XkbNextFreeFilter(xkbi);
 | 
						|
		    sendEvent=_XkbFilterControls(xkbi,filter,key,&act);
 | 
						|
		    break;
 | 
						|
		case XkbSA_ActionMessage:
 | 
						|
		    filter = _XkbNextFreeFilter(xkbi);
 | 
						|
		    sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act);
 | 
						|
		    break;
 | 
						|
		case XkbSA_RedirectKey:
 | 
						|
		    filter = _XkbNextFreeFilter(xkbi);
 | 
						|
		    sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act);
 | 
						|
		    break;
 | 
						|
		case XkbSA_DeviceBtn:
 | 
						|
		case XkbSA_LockDeviceBtn:
 | 
						|
		    filter = _XkbNextFreeFilter(xkbi);
 | 
						|
		    sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act);
 | 
						|
		    break;
 | 
						|
		case XkbSA_XFree86Private:
 | 
						|
		    filter = _XkbNextFreeFilter(xkbi);
 | 
						|
		    sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act);
 | 
						|
		    break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	if (!keyEvent)
 | 
						|
	    key|= BTN_ACT_FLAG;
 | 
						|
	sendEvent = _XkbApplyFilters(xkbi,key,NULL);
 | 
						|
    }
 | 
						|
 | 
						|
    if (xkbi->groupChange!=0)
 | 
						|
	xkbi->state.base_group+= xkbi->groupChange;
 | 
						|
    if (xkbi->setMods) {
 | 
						|
	for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) {
 | 
						|
	    if (xkbi->setMods&bit) {
 | 
						|
		keyc->modifierKeyCount[i]++;
 | 
						|
		xkbi->state.base_mods|= bit;
 | 
						|
		xkbi->setMods&= ~bit;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    if (xkbi->clearMods) {
 | 
						|
	for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) {
 | 
						|
	    if (xkbi->clearMods&bit) {
 | 
						|
		keyc->modifierKeyCount[i]--;
 | 
						|
		if (keyc->modifierKeyCount[i]<=0) {
 | 
						|
		    xkbi->state.base_mods&= ~bit;
 | 
						|
		    keyc->modifierKeyCount[i] = 0;
 | 
						|
		}
 | 
						|
		xkbi->clearMods&= ~bit;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    if (sendEvent) {
 | 
						|
        DeviceIntPtr tmpdev;
 | 
						|
	if (keyEvent)
 | 
						|
            tmpdev = dev;
 | 
						|
        else
 | 
						|
            tmpdev = GetPairedDevice(dev);
 | 
						|
 | 
						|
        UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc);
 | 
						|
        dev->public.processInputProc((InternalEvent*)event, tmpdev);
 | 
						|
        COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
 | 
						|
                                     backupproc,xkbUnwrapProc);
 | 
						|
    }
 | 
						|
    else if (keyEvent) {
 | 
						|
	FixKeyState(event, dev);
 | 
						|
    }
 | 
						|
 | 
						|
    XkbComputeDerivedState(xkbi);
 | 
						|
    changed = XkbStateChangedFlags(&xkbi->prev_state,&xkbi->state);
 | 
						|
    if (genStateNotify) {
 | 
						|
	if (changed) {
 | 
						|
	    xkbStateNotify	sn;
 | 
						|
	    sn.keycode= key;
 | 
						|
	    sn.eventType= event->type;
 | 
						|
	    sn.requestMajor = sn.requestMinor = 0;
 | 
						|
	    sn.changed= changed;
 | 
						|
	    XkbSendStateNotify(dev,&sn);
 | 
						|
	}
 | 
						|
	xkbi->flags&= ~_XkbStateNotifyInProgress;
 | 
						|
    }
 | 
						|
    changed= XkbIndicatorsToUpdate(dev,changed,FALSE);
 | 
						|
    if (changed) {
 | 
						|
	XkbEventCauseRec	cause;
 | 
						|
	XkbSetCauseKey(&cause, key, event->type);
 | 
						|
	XkbUpdateIndicators(dev,changed,FALSE,NULL,&cause);
 | 
						|
    }
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
XkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches)
 | 
						|
{
 | 
						|
XkbSrvInfoPtr	xkbi;
 | 
						|
XkbFilterPtr	filter;
 | 
						|
XkbAction	act;
 | 
						|
unsigned	clear;
 | 
						|
 | 
						|
    if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
 | 
						|
	xkbi = pXDev->key->xkbInfo;
 | 
						|
	clear= (mask&(~latches));
 | 
						|
	xkbi->state.latched_mods&= ~clear;
 | 
						|
	/* Clear any pending latch to locks.
 | 
						|
	 */
 | 
						|
	act.type = XkbSA_NoAction;
 | 
						|
	_XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act);
 | 
						|
	act.type = XkbSA_LatchMods;
 | 
						|
	act.mods.flags = 0;
 | 
						|
	act.mods.mask  = mask&latches;
 | 
						|
	filter = _XkbNextFreeFilter(xkbi);
 | 
						|
	_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
 | 
						|
	_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
 | 
						|
	return Success;
 | 
						|
    }
 | 
						|
    return BadValue;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
XkbLatchGroup(DeviceIntPtr pXDev,int group)
 | 
						|
{
 | 
						|
XkbSrvInfoPtr	xkbi;
 | 
						|
XkbFilterPtr	filter;
 | 
						|
XkbAction	act;
 | 
						|
 | 
						|
    if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
 | 
						|
	xkbi = pXDev->key->xkbInfo;
 | 
						|
	act.type = XkbSA_LatchGroup;
 | 
						|
	act.group.flags = 0;
 | 
						|
	XkbSASetGroup(&act.group,group);
 | 
						|
	filter = _XkbNextFreeFilter(xkbi);
 | 
						|
	_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
 | 
						|
	_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
 | 
						|
	return Success;
 | 
						|
    }
 | 
						|
    return BadValue;
 | 
						|
}
 | 
						|
 | 
						|
/***====================================================================***/
 | 
						|
 | 
						|
void
 | 
						|
XkbClearAllLatchesAndLocks(	DeviceIntPtr		dev,
 | 
						|
				XkbSrvInfoPtr		xkbi,
 | 
						|
				Bool			genEv,
 | 
						|
				XkbEventCausePtr	cause)
 | 
						|
{
 | 
						|
XkbStateRec	os;
 | 
						|
xkbStateNotify	sn;
 | 
						|
 | 
						|
    sn.changed= 0;
 | 
						|
    os= xkbi->state;
 | 
						|
    if (os.latched_mods) { /* clear all latches */
 | 
						|
	XkbLatchModifiers(dev,~0,0);
 | 
						|
	sn.changed|= XkbModifierLatchMask;
 | 
						|
    }
 | 
						|
    if (os.latched_group) {
 | 
						|
	XkbLatchGroup(dev,0);
 | 
						|
	sn.changed|= XkbGroupLatchMask;
 | 
						|
    }
 | 
						|
    if (os.locked_mods) {
 | 
						|
	xkbi->state.locked_mods= 0;
 | 
						|
	sn.changed|= XkbModifierLockMask;
 | 
						|
    }
 | 
						|
    if (os.locked_group) {
 | 
						|
	xkbi->state.locked_group= 0;
 | 
						|
	sn.changed|= XkbGroupLockMask;
 | 
						|
    }
 | 
						|
    if ( genEv && sn.changed) {
 | 
						|
	CARD32 	changed;
 | 
						|
 | 
						|
	XkbComputeDerivedState(xkbi);
 | 
						|
	sn.keycode= 		cause->kc;
 | 
						|
	sn.eventType=		cause->event;
 | 
						|
	sn.requestMajor= 	cause->mjr;
 | 
						|
	sn.requestMinor= 	cause->mnr;
 | 
						|
	sn.changed= XkbStateChangedFlags(&os,&xkbi->state);
 | 
						|
	XkbSendStateNotify(dev,&sn);
 | 
						|
	changed= XkbIndicatorsToUpdate(dev,sn.changed,FALSE);
 | 
						|
	if (changed) {
 | 
						|
	    XkbUpdateIndicators(dev,changed,TRUE,NULL,cause);
 | 
						|
	}
 | 
						|
    }
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
 | 
						|
{
 | 
						|
    EventListPtr        events;
 | 
						|
    int                 nevents, i;
 | 
						|
    DeviceIntPtr        ptr;
 | 
						|
    ScreenPtr           pScreen;
 | 
						|
    Bool                saveWait;
 | 
						|
    int                 gpe_flags = 0;
 | 
						|
 | 
						|
    if (IsMaster(dev))
 | 
						|
        ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
 | 
						|
    else if (!dev->u.master)
 | 
						|
        ptr = dev;
 | 
						|
    else
 | 
						|
        return;
 | 
						|
 | 
						|
    if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
 | 
						|
        gpe_flags = POINTER_ABSOLUTE;
 | 
						|
    else
 | 
						|
        gpe_flags = POINTER_RELATIVE;
 | 
						|
 | 
						|
    events = InitEventList(GetMaximumEventsNum());
 | 
						|
    OsBlockSignals();
 | 
						|
    pScreen = miPointerGetScreen(ptr);
 | 
						|
    saveWait = miPointerSetWaitForUpdate(pScreen, FALSE);
 | 
						|
    nevents = GetPointerEvents(events, ptr,
 | 
						|
                               MotionNotify, 0,
 | 
						|
                               gpe_flags, 0, 2, (int[]){x, y});
 | 
						|
    miPointerSetWaitForUpdate(pScreen, saveWait);
 | 
						|
    OsReleaseSignals();
 | 
						|
 | 
						|
    for (i = 0; i < nevents; i++)
 | 
						|
        mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
 | 
						|
 | 
						|
    FreeEventList(events, GetMaximumEventsNum());
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
 | 
						|
{
 | 
						|
    EventListPtr        events;
 | 
						|
    int                 nevents, i;
 | 
						|
    DeviceIntPtr        ptr;
 | 
						|
 | 
						|
    /* If dev is a slave device, and the SD is attached, do nothing. If we'd
 | 
						|
     * post through the attached master pointer we'd get duplicate events.
 | 
						|
     *
 | 
						|
     * if dev is a master keyboard, post through the XTEST device
 | 
						|
     *
 | 
						|
     * if dev is a floating slave, post through the device itself.
 | 
						|
     */
 | 
						|
 | 
						|
    if (IsMaster(dev))
 | 
						|
        ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
 | 
						|
    else if (!dev->u.master)
 | 
						|
        ptr = dev;
 | 
						|
    else
 | 
						|
        return;
 | 
						|
 | 
						|
    events = InitEventList(GetMaximumEventsNum());
 | 
						|
    OsBlockSignals();
 | 
						|
    nevents = GetPointerEvents(events, ptr,
 | 
						|
                               press ? ButtonPress : ButtonRelease, button,
 | 
						|
                               0 /* flags */, 0 /* first */,
 | 
						|
                               0 /* num_val */, NULL);
 | 
						|
    OsReleaseSignals();
 | 
						|
 | 
						|
 | 
						|
    for (i = 0; i < nevents; i++)
 | 
						|
        mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
 | 
						|
 | 
						|
    FreeEventList(events, GetMaximumEventsNum());
 | 
						|
}
 |