diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2011-09-22 17:12:45 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2011-09-22 17:12:45 +1000 |
commit | 82adee7f82251772ce54760d4b380c95bfed8060 (patch) | |
tree | 7255f650ff2c65afceea38ab349b5581947aad07 | |
parent | cd7f86f7e52f16ba02649836540dfe2e46671dfd (diff) | |
parent | 429f37979a32aa68b8d1b878df6e1c18729467f8 (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.c | 2 | ||||
-rw-r--r-- | dix/events.c | 25 | ||||
-rw-r--r-- | dix/getevents.c | 61 | ||||
-rw-r--r-- | dix/inpututils.c | 26 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Cursor.c | 2 | ||||
-rw-r--r-- | hw/xfree86/common/xf86RandR.c | 3 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Xinput.c | 19 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Xinput.h | 1 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86RandR12.c | 2 | ||||
-rw-r--r-- | include/input.h | 3 | ||||
-rw-r--r-- | include/scrnintstr.h | 2 | ||||
-rw-r--r-- | mi/mipointer.c | 13 |
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) |