From a780e5b3638a0ff81301fc68aca15b47ba0befb7 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Wed, 14 Apr 2010 17:27:51 +0200 Subject: [PATCH 1/6] xf86ScaleAxis: support for high resolution devices High resolution devices was generating integer overflow. For instance the wacom Cintiq 21UX has an axis value up to 87000. Thus the term (dSx * (Cx - Rxlow)) is greater than MAX_INT32. Using 64bits integer avoids such problem. Signed-off-by: Philippe Ribet Signed-off-by: Benjamin Tissoires Reviewed-by: Keith Packard Signed-off-by: Peter Hutterer --- hw/xfree86/common/xf86Xinput.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index 7723ba683..dba3370f3 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -86,6 +86,7 @@ #include "windowstr.h" /* screenIsSaved */ #include +#include /* for int64_t */ #include @@ -1177,12 +1178,11 @@ xf86ScaleAxis(int Cx, int Rxlow ) { int X; - int dSx = Sxhigh - Sxlow; - int dRx = Rxhigh - Rxlow; + int64_t dSx = Sxhigh - Sxlow; + int64_t dRx = Rxhigh - Rxlow; - dSx = Sxhigh - Sxlow; if (dRx) { - X = ((dSx * (Cx - Rxlow)) / dRx) + Sxlow; + X = (int)(((dSx * (Cx - Rxlow)) / dRx) + Sxlow); } else { X = 0; From 108457dff816569453a2d88cd72595fa7eb02479 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 13 Apr 2010 14:41:07 +1000 Subject: [PATCH 2/6] xkb: Post PointerKeys through the XTEST device. Posting an event through a master device may cause pointer jumps once lastSlave == master, caused by double scaling. To avoid this, post the fake event generated by XKB through the XTEST device instead. Fedora bug #560356 Tested-by: Andrew McNabb Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone --- xkb/ddxDevBtn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xkb/ddxDevBtn.c b/xkb/ddxDevBtn.c index 94630d1c9..3bee84b1e 100644 --- a/xkb/ddxDevBtn.c +++ b/xkb/ddxDevBtn.c @@ -51,13 +51,13 @@ XkbDDXFakeDeviceButton(DeviceIntPtr dev,Bool press,int button) /* 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 master pointer. + * 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 = GetMaster(dev, MASTER_POINTER); + ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER)); else if (!dev->u.master) ptr = dev; else From 6c42c8c356be305dc7f3f92ad8d58675da8c2f07 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 14 Apr 2010 10:51:41 +1000 Subject: [PATCH 3/6] xkb: Guard against SIGIO updates during PointerKeys. In theory, an event coming in during GPE could reset our lastSlave, leading to rather interesting events lateron. Signed-off-by: Peter Hutterer Reviewed-by: Simon Thum Reviewed-by: Daniel Stone --- xkb/ddxDevBtn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xkb/ddxDevBtn.c b/xkb/ddxDevBtn.c index 3bee84b1e..b8a222d0b 100644 --- a/xkb/ddxDevBtn.c +++ b/xkb/ddxDevBtn.c @@ -64,11 +64,12 @@ XkbDDXFakeDeviceButton(DeviceIntPtr dev,Bool press,int button) 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); From f4106c02318fcc4b534224df5b95a58aff555fb4 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 13 Apr 2010 14:44:59 +1000 Subject: [PATCH 4/6] xkb: use GPE for XKB fake motion events. Section 4.6.1 of the XKB spec says that "the initial event always moves the cursor the distance specified in the action [...]", so skip the POINTER_ACCELERATE flag for GPE, it would cause double-acceleration. Potential regression - GPE expects the coordinates to be either relative or both. XKB in theory allows for x to be relative and y to be absolute (or vice versa). Let's pretend that scenario has no users. Signed-off-by: Peter Hutterer Reviewed-by: Simon Thum Reviewed-by: Daniel Stone --- include/xkbsrv.h | 1 + xkb/ddxFakeMtn.c | 102 +++++++++++------------------------------------ xkb/xkbActions.c | 4 +- 3 files changed, 27 insertions(+), 80 deletions(-) diff --git a/include/xkbsrv.h b/include/xkbsrv.h index 278ff769d..239b7a180 100644 --- a/include/xkbsrv.h +++ b/include/xkbsrv.h @@ -769,6 +769,7 @@ extern _X_EXPORT void XkbDDXUpdateDeviceIndicators( ); extern _X_EXPORT void XkbDDXFakePointerMotion( + DeviceIntPtr /* dev */, unsigned int /* flags */, int /* x */, int /* y */ diff --git a/xkb/ddxFakeMtn.c b/xkb/ddxFakeMtn.c index f90d2099a..b38371614 100644 --- a/xkb/ddxFakeMtn.c +++ b/xkb/ddxFakeMtn.c @@ -28,91 +28,37 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #endif -#include -#include -#include -#include #include "inputstr.h" -#include "scrnintstr.h" -#include "windowstr.h" #include -#include - -#ifdef PANORAMIX -#include "panoramiX.h" -#include "panoramiXsrv.h" -#endif - -#include "mipointer.h" -#include "mipointrst.h" +#include "mi.h" void -XkbDDXFakePointerMotion(unsigned flags,int x,int y) +XkbDDXFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y) { -int oldX,oldY; -ScreenPtr pScreen, oldScreen; + EventListPtr events; + int nevents, i; + DeviceIntPtr ptr; + int gpe_flags = 0; - GetSpritePosition(inputInfo.pointer, &oldX, &oldY); - pScreen = oldScreen = GetSpriteWindow(inputInfo.pointer)->drawable.pScreen; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - BoxRec box; - int i; - - if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum], - oldX, oldY, &box)) { - FOR_NSCREENS(i) { - if(i == pScreen->myNum) - continue; - if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], - oldX, oldY, &box)) { - pScreen = screenInfo.screens[i]; - break; - } - } - } - oldScreen = pScreen; - - if (flags&XkbSA_MoveAbsoluteX) - oldX= x; - else oldX+= x; - if (flags&XkbSA_MoveAbsoluteY) - oldY= y; - else oldY+= y; - - if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum], - oldX, oldY, &box)) { - FOR_NSCREENS(i) { - if(i == pScreen->myNum) - continue; - if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], - oldX, oldY, &box)) { - pScreen = screenInfo.screens[i]; - break; - } - } - } - oldX -= panoramiXdataPtr[pScreen->myNum].x; - oldY -= panoramiXdataPtr[pScreen->myNum].y; - } + if (!dev->u.master) + ptr = dev; else -#endif - { - if (flags&XkbSA_MoveAbsoluteX) - oldX= x; - else oldX+= x; - if (flags&XkbSA_MoveAbsoluteY) - oldY= y; - else oldY+= y; + ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER)); -#define GetScreenPrivate(s) ((miPointerScreenPtr)dixLookupPrivate(&(s)->devPrivates, miPointerScreenKey)) - (*(GetScreenPrivate(oldScreen))->screenFuncs->CursorOffScreen) - (&pScreen, &oldX, &oldY); - } + if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY) + gpe_flags = POINTER_ABSOLUTE; + else + gpe_flags = POINTER_RELATIVE; - if (pScreen != oldScreen) - NewCurrentScreen(inputInfo.pointer, pScreen, oldX, oldY); - if (pScreen->SetCursorPosition) - (*pScreen->SetCursorPosition)(inputInfo.pointer, pScreen, oldX, oldY, TRUE); + events = InitEventList(GetMaximumEventsNum()); + OsBlockSignals(); + nevents = GetPointerEvents(events, ptr, + MotionNotify, 0, + gpe_flags, 0, 2, (int[]){x, y}); + OsReleaseSignals(); + + for (i = 0; i < nevents; i++) + mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL); + + FreeEventList(events, GetMaximumEventsNum()); } diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c index 2cdb6fcea..4c7bce2e4 100644 --- a/xkb/xkbActions.c +++ b/xkb/xkbActions.c @@ -479,7 +479,7 @@ int dx,dy; dx= xkbi->mouseKeysDX; dy= xkbi->mouseKeysDY; } - XkbDDXFakePointerMotion(xkbi->mouseKeysFlags,dx,dy); + XkbDDXFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy); return xkbi->desc->ctrls->mk_interval; } @@ -507,7 +507,7 @@ Bool accel; accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0); x= XkbPtrActionX(&pAction->ptr); y= XkbPtrActionY(&pAction->ptr); - XkbDDXFakePointerMotion(pAction->ptr.flags,x,y); + XkbDDXFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y); AccessXCancelRepeatKey(xkbi,keycode); xkbi->mouseKeysAccel= accel&& (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask); From da4e2e382828d7ba460766709368ec6214b286dd Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 14 Apr 2010 09:48:53 +1000 Subject: [PATCH 5/6] xkb: purge unneeded includes from ddxDevBtn.c Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone Reviewed-by: Dan Nicholson --- xkb/ddxDevBtn.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/xkb/ddxDevBtn.c b/xkb/ddxDevBtn.c index b8a222d0b..b8a125514 100644 --- a/xkb/ddxDevBtn.c +++ b/xkb/ddxDevBtn.c @@ -28,18 +28,9 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #endif -#include -#include -#include -#include #include "inputstr.h" -#include "scrnintstr.h" -#include "windowstr.h" -#include "eventstr.h" #include #include "mi.h" -#include -#include void XkbDDXFakeDeviceButton(DeviceIntPtr dev,Bool press,int button) From 0ad022a729bafa56cc7b5d241f567444a34514ad Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 14 Apr 2010 10:54:29 +1000 Subject: [PATCH 6/6] xkb: rename XkbFakeDeviceButton and XkbFakeDeviceMotion, move into xkbActions.c The name XkbDDXFakeDeviceButton and XkbDDXFakeDeviceMotion is somewhat misleading, there's no DDX involved in the game at all anymore. This removes XkbFakeDeviceMotion and XkbFakeDeviceButton from the API where it arguably shouldn't have been in the first place. Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone Reviewed-by: Dan Nicholson --- include/xkbsrv.h | 13 ------- xkb/Makefile.am | 4 +- xkb/ddxDevBtn.c | 69 ---------------------------------- xkb/ddxFakeMtn.c | 64 -------------------------------- xkb/xkbActions.c | 97 +++++++++++++++++++++++++++++++++++++++++------- 5 files changed, 85 insertions(+), 162 deletions(-) delete mode 100644 xkb/ddxDevBtn.c delete mode 100644 xkb/ddxFakeMtn.c diff --git a/include/xkbsrv.h b/include/xkbsrv.h index 239b7a180..a5d25d009 100644 --- a/include/xkbsrv.h +++ b/include/xkbsrv.h @@ -768,19 +768,6 @@ extern _X_EXPORT void XkbDDXUpdateDeviceIndicators( CARD32 /* newState */ ); -extern _X_EXPORT void XkbDDXFakePointerMotion( - DeviceIntPtr /* dev */, - unsigned int /* flags */, - int /* x */, - int /* y */ -); - -extern _X_EXPORT void XkbDDXFakeDeviceButton( - DeviceIntPtr /* dev */, - Bool /* press */, - int /* button */ -); - extern _X_EXPORT int XkbDDXTerminateServer( DeviceIntPtr /* dev */, KeyCode /* key */, diff --git a/xkb/Makefile.am b/xkb/Makefile.am index e54ce59f0..fb3ccbf6f 100644 --- a/xkb/Makefile.am +++ b/xkb/Makefile.am @@ -5,11 +5,9 @@ AM_CFLAGS = $(DIX_CFLAGS) DDX_SRCS = \ ddxBeep.c \ ddxCtrls.c \ - ddxFakeMtn.c \ ddxLEDs.c \ ddxLoad.c \ - ddxList.c \ - ddxDevBtn.c + ddxList.c DIX_SRCS = \ xkb.c \ diff --git a/xkb/ddxDevBtn.c b/xkb/ddxDevBtn.c deleted file mode 100644 index b8a125514..000000000 --- a/xkb/ddxDevBtn.c +++ /dev/null @@ -1,69 +0,0 @@ -/************************************************************ -Copyright (c) 1995 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 -#endif - -#include "inputstr.h" -#include -#include "mi.h" - -void -XkbDDXFakeDeviceButton(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()); -} diff --git a/xkb/ddxFakeMtn.c b/xkb/ddxFakeMtn.c deleted file mode 100644 index b38371614..000000000 --- a/xkb/ddxFakeMtn.c +++ /dev/null @@ -1,64 +0,0 @@ -/************************************************************ -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 -#endif - -#include "inputstr.h" -#include -#include "mi.h" - -void -XkbDDXFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y) -{ - EventListPtr events; - int nevents, i; - DeviceIntPtr ptr; - int gpe_flags = 0; - - if (!dev->u.master) - ptr = dev; - else - ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER)); - - if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY) - gpe_flags = POINTER_ABSOLUTE; - else - gpe_flags = POINTER_RELATIVE; - - events = InitEventList(GetMaximumEventsNum()); - OsBlockSignals(); - nevents = GetPointerEvents(events, ptr, - MotionNotify, 0, - gpe_flags, 0, 2, (int[]){x, y}); - OsReleaseSignals(); - - for (i = 0; i < nevents; i++) - mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL); - - FreeEventList(events, GetMaximumEventsNum()); -} diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c index 4c7bce2e4..6a9943fbc 100644 --- a/xkb/xkbActions.c +++ b/xkb/xkbActions.c @@ -40,11 +40,15 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "xkb.h" #include +#include "mi.h" #define EXTENSION_EVENT_BASE 64 static int xkbDevicePrivateKeyIndex; DevPrivateKey xkbDevicePrivateKey = &xkbDevicePrivateKeyIndex; +static 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) @@ -479,7 +483,7 @@ int dx,dy; dx= xkbi->mouseKeysDX; dy= xkbi->mouseKeysDY; } - XkbDDXFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy); + XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy); return xkbi->desc->ctrls->mk_interval; } @@ -507,7 +511,7 @@ Bool accel; accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0); x= XkbPtrActionX(&pAction->ptr); y= XkbPtrActionY(&pAction->ptr); - XkbDDXFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y); + XkbFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y); AccessXCancelRepeatKey(xkbi,keycode); xkbi->mouseKeysAccel= accel&& (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask); @@ -554,7 +558,7 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi, ((pAction->btn.flags&XkbSA_LockNoLock)==0)) { xkbi->lockedPtrButtons|= (1<device, 1, button); + XkbFakeDeviceButton(xkbi->device, 1, button); filter->upAction.type= XkbSA_NoAction; } break; @@ -565,12 +569,12 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi, if (pAction->btn.count>0) { nClicks= pAction->btn.count; for (i=0;idevice, 1, button); - XkbDDXFakeDeviceButton(xkbi->device, 0, button); + XkbFakeDeviceButton(xkbi->device, 1, button); + XkbFakeDeviceButton(xkbi->device, 0, button); } filter->upAction.type= XkbSA_NoAction; } - else XkbDDXFakeDeviceButton(xkbi->device, 1, button); + else XkbFakeDeviceButton(xkbi->device, 1, button); } break; case XkbSA_SetPtrDflt: @@ -626,7 +630,7 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi, } xkbi->lockedPtrButtons&= ~(1<device, 0, button); + XkbFakeDeviceButton(xkbi->device, 0, button); break; } filter->active = 0; @@ -964,7 +968,7 @@ int button; if ((pAction->devbtn.flags&XkbSA_LockNoLock)|| BitIsOn(dev->button->down, button)) return 0; - XkbDDXFakeDeviceButton(dev,TRUE,button); + XkbFakeDeviceButton(dev,TRUE,button); filter->upAction.type= XkbSA_NoAction; break; case XkbSA_DeviceBtn: @@ -972,12 +976,12 @@ int button; int nClicks,i; nClicks= pAction->btn.count; for (i=0;iupAction.type= XkbSA_NoAction; } - else XkbDDXFakeDeviceButton(dev,TRUE,button); + else XkbFakeDeviceButton(dev,TRUE,button); break; } } @@ -996,10 +1000,10 @@ int button; if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)|| !BitIsOn(dev->button->down, button)) return 0; - XkbDDXFakeDeviceButton(dev,FALSE,button); + XkbFakeDeviceButton(dev,FALSE,button); break; case XkbSA_DeviceBtn: - XkbDDXFakeDeviceButton(dev,FALSE,button); + XkbFakeDeviceButton(dev,FALSE,button); break; } filter->active = 0; @@ -1316,3 +1320,70 @@ xkbStateNotify sn; return; } +static void +XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y) +{ + EventListPtr events; + int nevents, i; + DeviceIntPtr ptr; + int gpe_flags = 0; + + if (!dev->u.master) + ptr = dev; + else + ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER)); + + if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY) + gpe_flags = POINTER_ABSOLUTE; + else + gpe_flags = POINTER_RELATIVE; + + events = InitEventList(GetMaximumEventsNum()); + OsBlockSignals(); + nevents = GetPointerEvents(events, ptr, + MotionNotify, 0, + gpe_flags, 0, 2, (int[]){x, y}); + OsReleaseSignals(); + + for (i = 0; i < nevents; i++) + mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL); + + FreeEventList(events, GetMaximumEventsNum()); +} + +static 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()); +}