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 <peter.hutterer@who-t.net>
Reviewed-by: Simon Thum <simon.thum@gmx.de>
Reviewed-by: Daniel Stone <daniel@fooishbar.org>
This commit is contained in:
Peter Hutterer 2010-04-13 14:44:59 +10:00
parent 6c42c8c356
commit f4106c0231
3 changed files with 27 additions and 80 deletions

View File

@ -769,6 +769,7 @@ extern _X_EXPORT void XkbDDXUpdateDeviceIndicators(
);
extern _X_EXPORT void XkbDDXFakePointerMotion(
DeviceIntPtr /* dev */,
unsigned int /* flags */,
int /* x */,
int /* y */

View File

@ -28,91 +28,37 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <dix-config.h>
#endif
#include <stdio.h>
#include <X11/X.h>
#include <X11/Xproto.h>
#include <X11/keysym.h>
#include "inputstr.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include <xkbsrv.h>
#include <X11/extensions/XI.h>
#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());
}

View File

@ -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);