From 08cfb3f0e91a6055072b257f2701d3ec935c14ad Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 13 Apr 2010 14:41:07 +1000 Subject: [PATCH 1/3] 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 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xkb/ddxDevBtn.c b/xkb/ddxDevBtn.c index 94630d1..3bee84b 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 -- 1.6.6.1 From f2fe7f8ef94e800be70d0a179c7b27327008d8dd Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 14 Apr 2010 10:51:41 +1000 Subject: [PATCH 2/3] 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 files changed, 2 insertions(+), 1 deletions(-) diff --git a/xkb/ddxDevBtn.c b/xkb/ddxDevBtn.c index 3bee84b..b8a222d 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); -- 1.6.6.1 From ec98f743d4f04da6228e5a089515febbcf627af8 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 13 Apr 2010 14:44:59 +1000 Subject: [PATCH 3/3] 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 | 100 ++++++++++++----------------------------------------- xkb/xkbActions.c | 4 +- 3 files changed, 26 insertions(+), 79 deletions(-) diff --git a/include/xkbsrv.h b/include/xkbsrv.h index ebc7cdb..a19cb43 100644 --- a/include/xkbsrv.h +++ b/include/xkbsrv.h @@ -787,6 +787,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 f90d209..b383716 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; - - GetSpritePosition(inputInfo.pointer, &oldX, &oldY); - pScreen = oldScreen = GetSpriteWindow(inputInfo.pointer)->drawable.pScreen; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - BoxRec box; - int i; + EventListPtr events; + int nevents, i; + DeviceIntPtr ptr; + int gpe_flags = 0; - 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 (!dev->u.master) + ptr = dev; + else + ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER)); - 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 (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY) + gpe_flags = POINTER_ABSOLUTE; else -#endif - { - if (flags&XkbSA_MoveAbsoluteX) - oldX= x; - else oldX+= x; - if (flags&XkbSA_MoveAbsoluteY) - oldY= y; - else oldY+= y; + gpe_flags = POINTER_RELATIVE; + + events = InitEventList(GetMaximumEventsNum()); + OsBlockSignals(); + nevents = GetPointerEvents(events, ptr, + MotionNotify, 0, + gpe_flags, 0, 2, (int[]){x, y}); + OsReleaseSignals(); -#define GetScreenPrivate(s) ((miPointerScreenPtr)dixLookupPrivate(&(s)->devPrivates, miPointerScreenKey)) - (*(GetScreenPrivate(oldScreen))->screenFuncs->CursorOffScreen) - (&pScreen, &oldX, &oldY); - } + for (i = 0; i < nevents; i++) + mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL); - if (pScreen != oldScreen) - NewCurrentScreen(inputInfo.pointer, pScreen, oldX, oldY); - if (pScreen->SetCursorPosition) - (*pScreen->SetCursorPosition)(inputInfo.pointer, pScreen, oldX, oldY, TRUE); + FreeEventList(events, GetMaximumEventsNum()); } diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c index b0ab427..663f033 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); -- 1.6.6.1