From c8c5105c1d5c093675d7f571f158147f22f7572b Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 29 Oct 2013 14:33:56 +1000 Subject: [PATCH 1/5] ephyr: xcb_connect returns an error, not NULL Signed-off-by: Peter Hutterer Reviewed-by: Keith Packard --- hw/kdrive/ephyr/hostx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index ee9ae455c..3e01a4770 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -304,8 +304,8 @@ hostx_init(void) | XCB_EVENT_MASK_STRUCTURE_NOTIFY; EPHYR_DBG("mark"); - - if ((HostX.conn = xcb_connect(NULL, &HostX.screen)) == NULL) { + HostX.conn = xcb_connect(NULL, &HostX.screen); + if (xcb_connection_has_error(HostX.conn)) { fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n"); exit(1); } From d66832a3b8a8675f1e5f3656dcb1bbe95598f0ea Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 14 Nov 2013 13:21:54 +1000 Subject: [PATCH 2/5] kdrive: handle WxH as valid geometry spec If a screen size was specified as WxH, the loop returned early and kdOrigin was never advanced. Thus, screen->origin was always 0 (or whatever was given at the -origin commandline flag). If a screen size was given with a bit depth (WxHxD), kdOrigin would always advance by the current screen, offsetting the next screen. Signed-off-by: Keith Packard Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- hw/kdrive/src/kdrive.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c index f8949bec3..382968420 100644 --- a/hw/kdrive/src/kdrive.c +++ b/hw/kdrive/src/kdrive.c @@ -328,7 +328,8 @@ KdParseScreen(KdScreenInfo * screen, const char *arg) screen->height = pixels; screen->height_mm = mm; } - if (delim != 'x' && delim != '@' && delim != 'X' && delim != 'Y') + if (delim != 'x' && delim != '@' && delim != 'X' && delim != 'Y' && + (delim != '\0' || i == 0)) return; } From a94d945065177d73f3ee8dc0b9147264ba281136 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 29 Oct 2013 14:24:41 +1000 Subject: [PATCH 3/5] kdrive: modify ephyr events to use POINTER_DESKTOP and scale them to that A multi-head Xephyr instance has the pointer stuck on one screen because of bad coordinate calculation. The coordinates passed to GetPointerEvents are per-screen, so the cursor gets stuck on the left-most screen by default. Adjust and mark the events as POINTER_DESKTOP, so the DIX can adjust them accordingly. Signed-off-by: Peter Hutterer Reviewed-by: Keith Packard --- hw/kdrive/ephyr/ephyr.c | 9 ++++++++- hw/kdrive/src/kdrive.h | 1 + hw/kdrive/src/kinput.c | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index 91e949d79..ef4b3210c 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -959,7 +959,14 @@ ephyrProcessMouseMotion(xcb_generic_event_t *xev) } EPHYR_LOG("final (x,y):(%d,%d)\n", x, y); #endif - KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0); + + /* convert coords into desktop-wide coordinates. + * fill_pointer_events will convert that back to + * per-screen coordinates where needed */ + x += screen->pScreen->x; + y += screen->pScreen->y; + + KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_POINTER_DESKTOP, x, y, 0); } } diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h index d5d0799df..296d611ed 100644 --- a/hw/kdrive/src/kdrive.h +++ b/hw/kdrive/src/kdrive.h @@ -506,6 +506,7 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo * ki, unsigned char scan_code, #define KD_BUTTON_4 0x08 #define KD_BUTTON_5 0x10 #define KD_BUTTON_8 0x80 +#define KD_POINTER_DESKTOP 0x40000000 #define KD_MOUSE_DELTA 0x80000000 void diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index d845830cc..abda69314 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -1895,6 +1895,8 @@ KdEnqueuePointerEvent(KdPointerInfo * pi, unsigned long flags, int rx, int ry, } else { dixflags = POINTER_ABSOLUTE; + if (flags & KD_POINTER_DESKTOP) + dixflags |= POINTER_DESKTOP; if (x != pi->dixdev->last.valuators[0] || y != pi->dixdev->last.valuators[1]) _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, From 550baf38f6096658f0bcf0ad647c4fedf93132f2 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 4 Oct 2013 10:55:52 +1000 Subject: [PATCH 4/5] kdrive: fix cursor jumps on CursorOffScreen behavior This patch fixes cursor jumps when there is a grab on the Xephyr window and the pointer moves outside the window. So on two side-by-side 640x480 screens, a coordinate of 0/481 triggers KdCursorOffscreen. If the delta between two screens is 0, they share the same offset for that dimension. When searching for the new screen, the loop always rules out the current screen. So we get to the second screen, trigger the conditions where dy <= 0 and decide that this new screen is the correct one. The result is that whenever KdCursorOffScreen is called, the pointer jumps to the other screen. Change to check for dy < 0 etc. so that the cursor stays on the same screen if there is no other screen at the target location. Signed-off-by: Peter Hutterer Reviewed-by: Keith Packard --- hw/kdrive/src/kinput.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index abda69314..a9a9fa583 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -2030,25 +2030,25 @@ KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) dx = KdScreenOrigin(pNewScreen)->x - KdScreenOrigin(pScreen)->x; dy = KdScreenOrigin(pNewScreen)->y - KdScreenOrigin(pScreen)->y; if (*x < 0) { - if (dx <= 0 && -dx < best_x) { + if (dx < 0 && -dx < best_x) { best_x = -dx; n_best_x = n; } } else if (*x >= pScreen->width) { - if (dx >= 0 && dx < best_x) { + if (dx > 0 && dx < best_x) { best_x = dx; n_best_x = n; } } if (*y < 0) { - if (dy <= 0 && -dy < best_y) { + if (dy < 0 && -dy < best_y) { best_y = -dy; n_best_y = n; } } else if (*y >= pScreen->height) { - if (dy >= 0 && dy < best_y) { + if (dy > 0 && dy < best_y) { best_y = dy; n_best_y = n; } From 8ff7e32c3ef7b0c13c4ab9664f651e9782d35a85 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 13 Nov 2013 17:14:11 +1000 Subject: [PATCH 5/5] include: export key_is_down and friends VNC needs key_is_down to check if a key is processed as down before it simulates various key releases. Make it available, because I seriously can't be bothered thinking about how to rewrite VNC to not need that. Signed-off-by: Peter Hutterer Acked-by: Keith Packard --- include/input.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/input.h b/include/input.h index 350dabad4..2d5e531ef 100644 --- a/include/input.h +++ b/include/input.h @@ -244,12 +244,12 @@ typedef struct _InputAttributes { #define KEY_POSTED 2 #define BUTTON_POSTED 2 -extern void set_key_down(DeviceIntPtr pDev, int key_code, int type); -extern void set_key_up(DeviceIntPtr pDev, int key_code, int type); -extern int key_is_down(DeviceIntPtr pDev, int key_code, int type); -extern void set_button_down(DeviceIntPtr pDev, int button, int type); -extern void set_button_up(DeviceIntPtr pDev, int button, int type); -extern int button_is_down(DeviceIntPtr pDev, int button, int type); +extern _X_EXPORT void set_key_down(DeviceIntPtr pDev, int key_code, int type); +extern _X_EXPORT void set_key_up(DeviceIntPtr pDev, int key_code, int type); +extern _X_EXPORT int key_is_down(DeviceIntPtr pDev, int key_code, int type); +extern _X_EXPORT void set_button_down(DeviceIntPtr pDev, int button, int type); +extern _X_EXPORT void set_button_up(DeviceIntPtr pDev, int button, int type); +extern _X_EXPORT int button_is_down(DeviceIntPtr pDev, int button, int type); extern void InitCoreDevices(void); extern void InitXTestDevices(void);