summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-09-22 17:12:45 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-09-22 17:12:45 +1000
commit82adee7f82251772ce54760d4b380c95bfed8060 (patch)
tree7255f650ff2c65afceea38ab349b5581947aad07
parentcd7f86f7e52f16ba02649836540dfe2e46671dfd (diff)
parent429f37979a32aa68b8d1b878df6e1c18729467f8 (diff)
Merge branch 'two-screen-coordinates' into nextnext-all
Conflicts: hw/xfree86/common/xf86Xinput.c Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--dix/dispatch.c2
-rw-r--r--dix/events.c25
-rw-r--r--dix/getevents.c61
-rw-r--r--dix/inpututils.c26
-rw-r--r--hw/xfree86/common/xf86Cursor.c2
-rw-r--r--hw/xfree86/common/xf86RandR.c3
-rw-r--r--hw/xfree86/common/xf86Xinput.c19
-rw-r--r--hw/xfree86/common/xf86Xinput.h1
-rw-r--r--hw/xfree86/modes/xf86RandR12.c2
-rw-r--r--include/input.h3
-rw-r--r--include/scrnintstr.h2
-rw-r--r--mi/mipointer.c13
12 files changed, 110 insertions, 49 deletions
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 192c8c34e..a644c5c58 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3911,6 +3911,8 @@ AddScreen(
return -1;
}
+ update_desktop_dimensions();
+
dixRegisterPrivateKey(&cursorScreenDevPriv[i], PRIVATE_CURSOR, 0);
return i;
diff --git a/dix/events.c b/dix/events.c
index e534a699f..013968ae2 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -525,13 +525,6 @@ SyntheticMotion(DeviceIntPtr dev, int x, int y) {
static void PostNewCursor(DeviceIntPtr pDev);
static Bool
-pointOnScreen(ScreenPtr pScreen, int x, int y)
-{
- return x >= pScreen->x && x < pScreen->x + pScreen->width &&
- y >= pScreen->y && y < pScreen->y + pScreen->height;
-}
-
-static Bool
XineramaSetCursorPosition(
DeviceIntPtr pDev,
int x,
@@ -550,13 +543,13 @@ XineramaSetCursorPosition(
x += screenInfo.screens[0]->x;
y += screenInfo.screens[0]->y;
- if(!pointOnScreen(pScreen, x, y))
+ if(!point_on_screen(pScreen, x, y))
{
FOR_NSCREENS(i)
{
if(i == pScreen->myNum)
continue;
- if(pointOnScreen(screenInfo.screens[i], x, y))
+ if(point_on_screen(screenInfo.screens[i], x, y))
{
pScreen = screenInfo.screens[i];
break;
@@ -3361,7 +3354,11 @@ WindowHasNewCursor(WindowPtr pWin)
void
NewCurrentScreen(DeviceIntPtr pDev, ScreenPtr newScreen, int x, int y)
{
- SpritePtr pSprite = pDev->spriteInfo->sprite;
+ DeviceIntPtr ptr;
+ SpritePtr pSprite;
+
+ ptr = IsFloating(pDev) ? pDev : GetXTestDevice(GetMaster(pDev, MASTER_POINTER));
+ pSprite = ptr->spriteInfo->sprite;
pSprite->hotPhys.x = x;
pSprite->hotPhys.y = y;
@@ -3373,15 +3370,15 @@ NewCurrentScreen(DeviceIntPtr pDev, ScreenPtr newScreen, int x, int y)
pSprite->screen = newScreen;
/* Make sure we tell the DDX to update its copy of the screen */
if(pSprite->confineWin)
- XineramaConfineCursorToWindow(pDev,
+ XineramaConfineCursorToWindow(ptr,
pSprite->confineWin, TRUE);
else
- XineramaConfineCursorToWindow(pDev, screenInfo.screens[0]->root, TRUE);
+ XineramaConfineCursorToWindow(ptr, screenInfo.screens[0]->root, TRUE);
/* if the pointer wasn't confined, the DDX won't get
told of the pointer warp so we reposition it here */
if(!syncEvents.playingEvents)
(*pSprite->screen->SetCursorPosition)(
- pDev,
+ ptr,
pSprite->screen,
pSprite->hotPhys.x + screenInfo.screens[0]->x -
pSprite->screen->x,
@@ -3391,7 +3388,7 @@ NewCurrentScreen(DeviceIntPtr pDev, ScreenPtr newScreen, int x, int y)
} else
#endif
if (newScreen != pSprite->hotPhys.pScreen)
- ConfineCursorToWindow(pDev, newScreen->root, TRUE, FALSE);
+ ConfineCursorToWindow(ptr, newScreen->root, TRUE, FALSE);
}
#ifdef PANORAMIX
diff --git a/dix/getevents.c b/dix/getevents.c
index d74599ba4..89dfef1ef 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -790,11 +790,11 @@ positionSprite(DeviceIntPtr dev, int mode, ScreenPtr scr, ValuatorMask *mask,
else
y = dev->last.valuators[1];
- /* scale x&y to screen */
+ /* scale x&y to desktop, in screen coord system */
*screenx = rescaleValuatorAxis(x, dev->valuator->axes + 0, NULL,
- scr->width);
+ screenInfo.width);
*screeny = rescaleValuatorAxis(y, dev->valuator->axes + 1, NULL,
- scr->height);
+ screenInfo.height);
/* miPointerSetPosition takes care of crossing screens for us, as well as
* clipping to the current screen. In the event we actually change screen,
@@ -803,18 +803,19 @@ positionSprite(DeviceIntPtr dev, int mode, ScreenPtr scr, ValuatorMask *mask,
isx = trunc(*screenx);
isy = trunc(*screeny);
miPointerSetPosition(dev, mode, &isx, &isy);
+
scr = miPointerGetScreen(dev);
if (isx != trunc(*screenx))
{
*screenx -= trunc(*screenx) - isx;
x = rescaleValuatorAxis(*screenx, NULL, dev->valuator->axes + 0,
- scr->width);
+ screenInfo.width);
}
if (isy != trunc(*screeny))
{
*screeny -= trunc(*screeny) - isy;
y = rescaleValuatorAxis(*screeny, NULL, dev->valuator->axes + 1,
- scr->height);
+ screenInfo.height);
}
/* Update the MD's co-ordinates, which are always in screen space. */
@@ -860,6 +861,15 @@ queueEventList(DeviceIntPtr device, InternalEvent *events, int nevents)
mieqEnqueue(device, &events[i]);
}
+static void
+event_set_root_coordinates(DeviceEvent* event, double x, double y)
+{
+ event->root_x = trunc(x);
+ event->root_y = trunc(y);
+ event->root_x_frac = x - trunc(x);
+ event->root_y_frac = y - trunc(y);
+}
+
/**
* Generate internal events representing this keyboard event and enqueue
* them on the event queue.
@@ -911,6 +921,11 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
(key_code < 8 || key_code > 255))
return 0;
+ if (mask_in && valuator_mask_size(mask_in) > 1) {
+ ErrorF("[dix] the server does not handle valuator masks with "
+ "keyboard events. This is a bug. You may fix it.\n");
+ }
+
num_events = 1;
events = UpdateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events);
@@ -957,6 +972,11 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
set_valuators(pDev, event, &mask);
+ if (!IsFloating(pDev)) {
+ DeviceIntPtr master = GetMaster(pDev, MASTER_POINTER);
+ event_set_root_coordinates(event, master->last.valuators[0], master->last.valuators[1]);
+ }
+
return num_events;
}
@@ -1070,6 +1090,11 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
switch (type)
{
case MotionNotify:
+ if (!pDev->valuator)
+ {
+ ErrorF("[dix] motion events from device %d without valuators\n", pDev->id);
+ return 0;
+ }
if (!mask_in || valuator_mask_num_valuators(mask_in) <= 0)
return 0;
break;
@@ -1077,6 +1102,11 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
case ButtonRelease:
if (!pDev->button || !buttons)
return 0;
+ if (mask_in && valuator_mask_size(mask_in) > 0 && !pDev->valuator)
+ {
+ ErrorF("[dix] button event with valuator from device %d without valuators\n", pDev->id);
+ return 0;
+ }
break;
default:
return 0;
@@ -1096,22 +1126,27 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
if (flags & POINTER_ABSOLUTE)
{
- if (flags & POINTER_SCREEN) /* valuators are in screen coords */
+ /* valuators are in screen coords but relative to the screen */
+ if (flags & POINTER_SCREEN)
{
double scaled;
if (valuator_mask_isset(&mask, 0))
{
- scaled = rescaleValuatorAxis(valuator_mask_get_double(&mask, 0),
+ scaled = valuator_mask_get_double(&mask, 0);
+ scaled += scr->x; /* convert to desktop-wide coords */
+ scaled = rescaleValuatorAxis(scaled,
NULL, pDev->valuator->axes + 0,
- scr->width);
+ screenInfo.width);
valuator_mask_set_double(&mask, 0, scaled);
}
if (valuator_mask_isset(&mask, 1))
{
- scaled = rescaleValuatorAxis(valuator_mask_get_double(&mask, 1),
+ scaled = valuator_mask_get_double(&mask, 1);
+ scaled += scr->y; /* convert to desktop-wide coords */
+ scaled = rescaleValuatorAxis(scaled,
NULL, pDev->valuator->axes + 1,
- scr->height);
+ screenInfo.height);
valuator_mask_set_double(&mask, 1, scaled);
}
}
@@ -1127,6 +1162,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
if ((flags & POINTER_NORAW) == 0)
set_raw_valuators(raw, &mask, raw->valuators.data);
+ /* x/y are in desktop-wide coordinates */
positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative, scr,
&mask, &screenx, &screeny);
updateHistory(pDev, &mask, ms);
@@ -1159,10 +1195,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
}
/* root_x and root_y must be in screen co-ordinates */
- event->root_x = trunc(screenx);
- event->root_y = trunc(screeny);
- event->root_x_frac = screenx - trunc(screenx);
- event->root_y_frac = screeny - trunc(screeny);
+ event_set_root_coordinates(event, screenx, screeny);
if (flags & POINTER_EMULATED) {
raw->flags = XIPointerEmulated;
diff --git a/dix/inpututils.c b/dix/inpututils.c
index 0a3d3d8b4..2a2b54348 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -37,6 +37,7 @@
#include "xkbstr.h"
#include "inpututils.h"
#include "eventstr.h"
+#include "scrnintstr.h"
/* Check if a button map change is okay with the device.
* Returns -1 for BadValue, as it collides with MappingBusy. */
@@ -619,7 +620,32 @@ void init_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms)
event->sourceid = dev->id;
}
+Bool
+point_on_screen(ScreenPtr pScreen, int x, int y)
+{
+ return x >= pScreen->x && x < pScreen->x + pScreen->width &&
+ y >= pScreen->y && y < pScreen->y + pScreen->height;
+}
+
/**
+ * Update desktop dimensions on the screenInfo struct.
+ */
+void
+update_desktop_dimensions(void)
+{
+ int i;
+ int w = 0, h = 0;
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ ScreenPtr screen = screenInfo.screens[i];
+ w = max(w, screen->x + screen->width);
+ h = max(h, screen->y + screen->height);
+ }
+
+ screenInfo.width = w;
+ screenInfo.height = h;
+}
+
+/*
* Delete the element with the key from the list, freeing all memory
* associated with the element..
*/
diff --git a/hw/xfree86/common/xf86Cursor.c b/hw/xfree86/common/xf86Cursor.c
index 929f047cc..6f5d726f0 100644
--- a/hw/xfree86/common/xf86Cursor.c
+++ b/hw/xfree86/common/xf86Cursor.c
@@ -838,6 +838,8 @@ xf86InitOrigins(void)
FillOutEdge(pLayout->down, pScreen->width);
}
}
+
+ update_desktop_dimensions();
}
void
diff --git a/hw/xfree86/common/xf86RandR.c b/hw/xfree86/common/xf86RandR.c
index 4663d0366..d0e47841e 100644
--- a/hw/xfree86/common/xf86RandR.c
+++ b/hw/xfree86/common/xf86RandR.c
@@ -313,6 +313,9 @@ xf86RandRSetConfig (ScreenPtr pScreen,
return FALSE;
}
+
+ update_desktop_dimensions();
+
/*
* Move the cursor back where it belongs; SwitchMode repositions it
* FIXME: duplicated code, see modes/xf86RandR12.c
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 49b2fb2e8..0640e0ef8 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -1344,25 +1344,6 @@ xf86ScaleAxis(int Cx,
return X;
}
-/*
- * This function checks the given screen against the current screen and
- * makes changes if appropriate. It should be called from an XInput driver's
- * ReadInput function before any events are posted, if the device is screen
- * specific like a touch screen.
- */
-void
-xf86XInputSetScreen(InputInfoPtr pInfo,
- int screen_number,
- int x,
- int y)
-{
- if (miPointerGetScreen(pInfo->dev) !=
- screenInfo.screens[screen_number]) {
- miPointerSetScreen(pInfo->dev, screen_number, x, y);
- }
-}
-
-
Bool
xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
int resolution, int min_res, int max_res, int mode)
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 189f7abaf..909fb57d6 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -143,7 +143,6 @@ extern _X_EXPORT void xf86PostKeyboardEvent(DeviceIntPtr device, unsigned int ke
int is_down);
extern _X_EXPORT InputInfoPtr xf86FirstLocalDevice(void);
extern _X_EXPORT int xf86ScaleAxis(int Cx, int to_max, int to_min, int from_max, int from_min);
-extern _X_EXPORT void xf86XInputSetScreen(InputInfoPtr pInfo, int screen_number, int x, int y);
extern _X_EXPORT void xf86ProcessCommonOptions(InputInfoPtr pInfo, XF86OptionPtr options);
extern _X_EXPORT Bool xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval,
int maxval, int resolution, int min_res,
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index cb20d1c35..d5031a2f1 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -736,6 +736,8 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
xf86SetViewport (pScreen, 0, 0);
finish:
+ update_desktop_dimensions();
+
if (pRoot && pScrn->vtSema)
(*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
#if RANDR_12_INTERFACE
diff --git a/include/input.h b/include/input.h
index 6ba1ab200..2544996a6 100644
--- a/include/input.h
+++ b/include/input.h
@@ -608,4 +608,7 @@ extern _X_EXPORT const char* input_option_get_value(const InputOption *opt);
extern _X_EXPORT void input_option_set_key(InputOption *opt, const char* key);
extern _X_EXPORT void input_option_set_value(InputOption *opt, const char* value);
+extern _X_HIDDEN Bool point_on_screen(ScreenPtr pScreen, int x, int y);
+extern _X_HIDDEN void update_desktop_dimensions(void);
+
#endif /* INPUT_H */
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index a9357e8a5..8ac48b758 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -561,6 +561,8 @@ typedef struct _ScreenInfo {
formats[MAXFORMATS];
int numScreens;
ScreenPtr screens[MAXSCREENS];
+ int width; /* total width of all screens together */
+ int height; /* total height of all screens together */
} ScreenInfo;
extern _X_EXPORT ScreenInfo screenInfo;
diff --git a/mi/mipointer.c b/mi/mipointer.c
index 670f63b6e..039e82c6b 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -580,6 +580,7 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y)
miPointerScreenPtr pScreenPriv;
ScreenPtr pScreen;
ScreenPtr newScreen;
+ Bool switch_screen = FALSE;
miPointerPtr pPointer;
@@ -591,7 +592,17 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y)
if (!pScreen)
return; /* called before ready */
- if (*x < 0 || *x >= pScreen->width || *y < 0 || *y >= pScreen->height)
+ /* x/y is still in desktop-wide coordinates here */
+ if (mode == Absolute) {
+ switch_screen = !point_on_screen(pScreen, *x, *y);
+
+ /* CursorOffScreen and Pointer->limits expect x/y to be relative to the screen. */
+ *x -= pScreen->x;
+ *y -= pScreen->y;
+ } else if (*x < 0 || *x >= pScreen->width || *y < 0 || *y >= pScreen->height)
+ switch_screen = TRUE;
+
+ if (switch_screen)
{
pScreenPriv = GetScreenPrivate (pScreen);
if (!pPointer->confined)