mipointer: take device arguments, split miPointerAbsoluteCursor

Update mipointer API to take a device argument to (almost) all functions,
and split miPointerAbsoluteCursor into a couple of separate functions.
Remove miPointerAbsoluteCursor call from mieq, as we now deal with it in
GetPointerEvents.
Make miPointerSetPosition (successor of miPointerAbsoluteCursor) take
pointers to x and y, so it can return the clipped values.
Modify callers of miPointer*() functions to generally use the new
functions.
This should fix things with multi-head setups.
This commit is contained in:
Daniel Stone 2006-10-08 20:34:32 +03:00 committed by Daniel Stone
parent be8dfafd1d
commit 41bb9fce47
8 changed files with 150 additions and 99 deletions

View File

@ -131,6 +131,8 @@ of the copyright holder.
#endif
#include "globals.h"
#include "mipointer.h"
#ifdef XKB
#include <X11/extensions/XKBproto.h>
#include <X11/extensions/XKBsrv.h>
@ -4874,6 +4876,7 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
AxisInfoPtr axes = NULL;
Bool sendValuators = (type == MotionNotify || flags & POINTER_ABSOLUTE);
DeviceIntPtr cp = inputInfo.pointer;
int x = 0, y = 0;
if (type != MotionNotify && type != ButtonPress && type != ButtonRelease)
return 0;
@ -4910,23 +4913,23 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
if (flags & POINTER_ABSOLUTE) {
if (num_valuators >= 1 && first_valuator == 0) {
kbp->root_x = valuators[0];
x = valuators[0];
}
else {
if (pDev->coreEvents)
kbp->root_x = cp->valuator->lastx;
x = cp->valuator->lastx;
else
kbp->root_x = pDev->valuator->lastx;
x = pDev->valuator->lastx;
}
if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
kbp->root_y = valuators[1 - first_valuator];
y = valuators[1 - first_valuator];
}
else {
if (pDev->coreEvents)
kbp->root_x = cp->valuator->lasty;
x = cp->valuator->lasty;
else
kbp->root_y = pDev->valuator->lasty;
y = pDev->valuator->lasty;
}
}
else {
@ -4936,49 +4939,52 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
if (pDev->coreEvents) {
if (first_valuator == 0 && num_valuators >= 1)
kbp->root_x = cp->valuator->lastx + valuators[0];
x = cp->valuator->lastx + valuators[0];
else
kbp->root_x = cp->valuator->lastx;
x = cp->valuator->lastx;
if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
kbp->root_y = cp->valuator->lasty +
valuators[1 - first_valuator];
y = cp->valuator->lasty + valuators[1 - first_valuator];
else
kbp->root_y = cp->valuator->lasty;
y = cp->valuator->lasty;
}
else {
if (first_valuator == 0 && num_valuators >= 1)
kbp->root_x = pDev->valuator->lastx + valuators[0];
x = pDev->valuator->lastx + valuators[0];
else
kbp->root_x = pDev->valuator->lastx;
x = pDev->valuator->lastx;
if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
kbp->root_y = pDev->valuator->lasty +
valuators[1 - first_valuator];
y = pDev->valuator->lasty + valuators[1 - first_valuator];
else
kbp->root_y = pDev->valuator->lasty;
y = pDev->valuator->lasty;
}
}
/* FIXME: need mipointer-like semantics to move on to different screens. */
axes = pDev->valuator->axes;
if (kbp->root_x < axes->min_value)
kbp->root_x = axes->min_value;
if (axes->max_value > 0 && kbp->root_x > axes->max_value)
kbp->root_x = axes->max_value;
if (x < axes->min_value)
x = axes->min_value;
if (axes->max_value > 0 && x > axes->max_value)
x = axes->max_value;
axes++;
if (kbp->root_y < axes->min_value)
kbp->root_y = axes->min_value;
if (axes->max_value > 0 && kbp->root_y > axes->max_value)
kbp->root_y = axes->max_value;
if (y < axes->min_value)
y = axes->min_value;
if (axes->max_value > 0 && y > axes->max_value)
y = axes->max_value;
/* This takes care of crossing screens for us, as well as clipping
* to the current screen. Right now, we only have one history buffer,
* so we don't set this for both the device and core.*/
miPointerSetPosition(pDev, &x, &y, ms);
if (pDev->coreEvents) {
cp->valuator->lastx = kbp->root_x;
cp->valuator->lasty = kbp->root_y;
cp->valuator->lastx = x;
cp->valuator->lasty = y;
}
pDev->valuator->lastx = kbp->root_x;
pDev->valuator->lasty = kbp->root_y;
pDev->valuator->lastx = x;
pDev->valuator->lasty = y;
if (type == MotionNotify) {
kbp->type = DeviceMotionNotify;
@ -4991,6 +4997,9 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
kbp->detail = pDev->button->map[buttons];
}
kbp->root_x = x;
kbp->root_y = y;
if (final_valuator > 2 && sendValuators) {
kbp->deviceid |= MORE_EVENTS;
for (i = first_valuator; i < final_valuator; i += 6) {
@ -5028,10 +5037,8 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
events++;
events->u.u.type = type;
events->u.keyButtonPointer.time = ms;
events->u.keyButtonPointer.rootX = kbp->root_x;
events->u.keyButtonPointer.rootY = kbp->root_y;
cp->valuator->lastx = kbp->root_x;
cp->valuator->lasty = kbp->root_y;
events->u.keyButtonPointer.rootX = x;
events->u.keyButtonPointer.rootY = y;
if (type == ButtonPress || type == ButtonRelease) {
/* We hijack SetPointerMapping to work on all core-sending

View File

@ -223,9 +223,9 @@ xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
if (mode->HDisplay > pScr->virtualX || mode->VDisplay > pScr->virtualY)
return FALSE;
pCursorScreen = miPointerCurrentScreen();
pCursorScreen = miPointerGetScreen(inputInfo.pointer);
if (pScreen == pCursorScreen)
miPointerPosition(&px, &py);
miPointerGetPosition(inputInfo.pointer, &px, &py);
xf86EnterServerState(SETUP);
Switched = (*pScr->SwitchMode)(pScr->scrnIndex, mode, 0);

View File

@ -253,9 +253,9 @@ ProcessInputEvents ()
xf86Info.inputPending = FALSE;
mieqProcessInputEvents();
miPointerUpdate();
miPointerUpdateSprite(inputInfo.pointer);
miPointerPosition(&x, &y);
miPointerGetPosition(inputInfo.pointer, &x, &y);
xf86SetViewport(xf86Info.currentScreen, x, y);
}
@ -793,7 +793,7 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
{
KeyClassPtr keyc = NULL;
KeySym *map = NULL;
xEvent *events = NULL, ke;
xEvent ke;
int i = 0, j = 0, nevents = 0;
ErrorF("releasekeys: called on device %s (%d)\n", pDev->name, pDev->id);
@ -818,7 +818,6 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
for (i = keyc->curKeySyms.minKeyCode, map = keyc->curKeySyms.map;
i < keyc->curKeySyms.maxKeyCode;
i++, map += keyc->curKeySyms.mapWidth) {
ErrorF("key %d: pressed is %s\n", i, KeyPressed(i) ? "true" : "false");
if (KeyPressed(i)) {
switch (*map) {
/* Don't release the lock keys */
@ -838,10 +837,9 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
(*pDev->public.processInputProc) (&ke, pDev, 1);
}
else {
nevents = GetKeyboardEvents(&events, pDev, KeyRelease, i);
ErrorF("device %s: got %d events for %d key\n", pDev->name, nevents, i);
nevents = GetKeyboardEvents(xf86Events, pDev, KeyRelease, i);
for (j = 0; j < nevents; j++)
mieqEnqueue(events++);
mieqEnqueue(xf86Events + i);
}
break;
}

View File

@ -203,6 +203,9 @@ void xf86UnlockServer(void);
void xf86InitXkb(void);
/* xf86Xinput.c */
extern xEvent *xf86Events;
#endif /* _NO_XF86_PROTOTYPES */

View File

@ -88,27 +88,19 @@
#include <X11/Xpoll.h>
#include "xf86_OSproc.h" /* sigio stuff */
#include "mi.h"
/******************************************************************************
* debugging macro
*****************************************************************************/
#ifdef DBG
#undef DBG
#endif
#ifdef DEBUG
#undef DEBUG
#endif
#define DEBUG 0
#if DEBUG
static int debug_level = 0;
#define DBG(lvl, f) {if ((lvl) <= debug_level) f;}
#else
#define DBG(lvl, f)
#endif
static xEvent *xf86Events = NULL;
xEvent *xf86Events = NULL;
static Bool
xf86SendDragEvents(DeviceIntPtr device)
@ -558,7 +550,6 @@ NewInputDeviceRequest (InputOption *options)
InputInfoPtr pInfo = NULL;
InputOption *option = NULL;
DeviceIntPtr dev = NULL;
int i;
idev = xcalloc(sizeof(*idev), 1);
if (!idev)
@ -981,8 +972,9 @@ xf86XInputSetScreen(LocalDevicePtr local,
int y)
{
if (local->dev->coreEvents &&
(miPointerCurrentScreen() != screenInfo.screens[screen_number])) {
miPointerSetNewScreen (screen_number, x, y);
(miPointerGetScreen(inputInfo.pointer) !=
screenInfo.screens[screen_number])) {
miPointerSetScreen(inputInfo.pointer, screen_number, x, y);
}
}

View File

@ -104,9 +104,6 @@ mieqEnqueue (xEvent *e)
&laste->event[0];
if (e->u.u.type == MotionNotify) {
miPointerSetPosition(pDev, e->u.keyButtonPointer.rootX,
e->u.keyButtonPointer.rootY,
e->u.keyButtonPointer.time);
pDev = inputInfo.pointer;
isMotion = inputInfo.pointer->id & DEVICE_BITS;
}

View File

@ -320,13 +320,18 @@ miPointerUpdateSprite (DeviceIntPtr pDev)
CursorPtr pCursor;
int x, y, devx, devy;
if (!pDev || !(pDev->coreEvents || pDev == inputInfo.pointer))
return;
pScreen = miPointer.pScreen;
if (!pScreen)
return;
x = miPointer.x;
y = miPointer.y;
devx = miPointer.devx;
devy = miPointer.devy;
if (!pScreen)
return;
pScreenPriv = GetScreenPrivate (pScreen);
/*
* if the cursor has switched screens, disable the sprite
@ -385,12 +390,19 @@ miPointerUpdateSprite (DeviceIntPtr pDev)
void
miPointerDeltaCursor (int dx, int dy, unsigned long time)
{
miPointerSetPosition(inputInfo.pointer, miPointer.x + dx,
miPointer.y + dy, time);
int x = miPointer.x + dx, y = miPointer.y + dy;
miPointerSetPosition(inputInfo.pointer, &x, &y, time);
}
void
miPointerSetNewScreen(int screen_no, int x, int y)
{
miPointerSetScreen(inputInfo.pointer, screen_no, x, y);
}
void
miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y)
{
miPointerScreenPtr pScreenPriv;
ScreenPtr pScreen;
@ -406,21 +418,26 @@ miPointerSetNewScreen(int screen_no, int x, int y)
_X_EXPORT ScreenPtr
miPointerCurrentScreen ()
{
return (miPointer.pScreen);
return miPointerGetScreen(inputInfo.pointer);
}
/*
* miPointerAbsoluteCursor. The pointer has moved to x,y
*/
_X_EXPORT ScreenPtr
miPointerGetScreen(DeviceIntPtr pDev)
{
return miPointer.pScreen;
}
/* Move the pointer to x, y on the current screen, update the sprite, and
* the motion history. Generates no events. Does not return changed x
* and y if they are clipped; use miPointerSetPosition instead. */
_X_EXPORT void
miPointerAbsoluteCursor (int x, int y, unsigned long time)
{
miPointerSetPosition(inputInfo.pointer, x, y, time);
miPointerSetPosition(inputInfo.pointer, &x, &y, time);
}
_X_EXPORT void
miPointerSetPosition(DeviceIntPtr pDev, int x, int y, unsigned long time)
miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y, unsigned long time)
{
miPointerScreenPtr pScreenPriv;
ScreenPtr pScreen;
@ -430,13 +447,16 @@ miPointerSetPosition(DeviceIntPtr pDev, int x, int y, unsigned long time)
if (!pScreen)
return; /* called before ready */
if (x < 0 || x >= pScreen->width || y < 0 || y >= pScreen->height)
if (!pDev || !(pDev->coreEvents || pDev == inputInfo.pointer))
return;
if (*x < 0 || *x >= pScreen->width || *y < 0 || *y >= pScreen->height)
{
pScreenPriv = GetScreenPrivate (pScreen);
if (!miPointer.confined)
{
newScreen = pScreen;
(*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, &x, &y);
(*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, x, y);
if (newScreen != pScreen)
{
pScreen = newScreen;
@ -448,21 +468,20 @@ miPointerSetPosition(DeviceIntPtr pDev, int x, int y, unsigned long time)
}
}
}
/*
* constrain the hot-spot to the current
* limits
*/
if (x < miPointer.limits.x1)
x = miPointer.limits.x1;
if (x >= miPointer.limits.x2)
x = miPointer.limits.x2 - 1;
if (y < miPointer.limits.y1)
y = miPointer.limits.y1;
if (y >= miPointer.limits.y2)
y = miPointer.limits.y2 - 1;
if (miPointer.x == x && miPointer.y == y && miPointer.pScreen == pScreen)
/* Constrain the sprite to the current limits. */
if (*x < miPointer.limits.x1)
*x = miPointer.limits.x1;
if (*x >= miPointer.limits.x2)
*x = miPointer.limits.x2 - 1;
if (*y < miPointer.limits.y1)
*y = miPointer.limits.y1;
if (*y >= miPointer.limits.y2)
*y = miPointer.limits.y2 - 1;
if (miPointer.x == *x && miPointer.y == *y && miPointer.pScreen == pScreen)
return;
miPointerMove (pScreen, x, y, time);
miPointerMoved(pDev, pScreen, *x, *y, time);
}
_X_EXPORT void
@ -478,27 +497,39 @@ miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y)
*y = miPointer.y;
}
/*
* miPointerMove. The pointer has moved to x,y on current screen
*/
void
miPointerMove (ScreenPtr pScreen, int x, int y, unsigned long time)
{
miPointerMoved(inputInfo.pointer, pScreen, x, y, time);
}
static void
miPointerMove (pScreen, x, y, time)
ScreenPtr pScreen;
int x, y;
unsigned long time;
/* Move the pointer on the current screen, and update the sprite. */
void
miPointerMoved (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y,
unsigned long time)
{
SetupScreen(pScreen);
miHistoryPtr history;
int prev, end, start;
if (!pScreenPriv->waitForUpdate && pScreen == miPointer.pSpriteScreen)
if (pDev && (pDev->coreEvents || pDev == inputInfo.pointer) &&
!pScreenPriv->waitForUpdate && pScreen == miPointer.pSpriteScreen)
{
miPointer.devx = x;
miPointer.devy = y;
if(!miPointer.pCursor->bits->emptyMask)
(*pScreenPriv->spriteFuncs->MoveCursor) (pScreen, x, y);
}
miPointerUpdateHistory(pDev, pScreen, x, y, time);
}
/* The pointer has moved to x, y; update the motion history. */
void
miPointerUpdateHistory (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y,
unsigned long time)
{
miHistoryPtr history;
int prev, end, start;
miPointer.x = x;
miPointer.y = y;
miPointer.pScreen = pScreen;

View File

@ -149,22 +149,45 @@ extern ScreenPtr miPointerCurrentScreen(
extern ScreenPtr miPointerGetScreen(
DeviceIntPtr pDev);
extern void miPointerSetScreen(
DeviceIntPtr pDev);
DeviceIntPtr pDev,
int screen_num,
int x,
int y);
/* Returns the current cursor position. */
extern void miPointerGetPosition(
DeviceIntPtr pDev,
int *x,
int *y);
/* Moves the cursor to the specified position. May clip the co-ordinates:
* x and y are modified in-place. */
extern void miPointerSetPosition(
DeviceIntPtr pDev,
int x,
int y,
int *x,
int *y,
unsigned long time);
extern void miPointerUpdateSprite(
DeviceIntPtr pDev);
/* Moves the sprite to x, y on the current screen, and updates the event
* history. */
extern void miPointerMoved(
DeviceIntPtr pDev,
ScreenPtr pScreen,
int x,
int y,
unsigned long time);
/* Updates the event history. */
extern void miPointerUpdateHistory(
DeviceIntPtr pDev,
ScreenPtr pScreen,
int x,
int y,
unsigned long time);
extern int miPointerScreenIndex;
#endif /* MIPOINTER_H */