From c0019b7f4999cbcad64b9629aefc6b874d23fa3a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 11 Oct 2017 13:31:21 -0700 Subject: [PATCH] Fixed bug 3871 - Touch events are not normalised on X11 Trent Gamblin The documentation for SDL_TouchFingerEvent says that the x and y coordinates are normalised between 0-1. I've found that to be true on Windows, Android and iOS but on X11 they are in pixel coordinates. This patch fixes the issue. This was the cleanest way I could do it with what was available without changing things around a lot but you may know a better way. --- src/video/x11/SDL_x11xinput2.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index 654fb8445b9a6..a4a588201d1c8 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -73,6 +73,24 @@ xinput2_version_atleast(const int version, const int wantmajor, const int wantmi { return ( version >= ((wantmajor * 1000) + wantminor) ); } + +static void +xinput2_normalize_touch_coordinates(SDL_VideoData *videodata, Window window, + double in_x, double in_y, float *out_x, float *out_y) +{ + int i; + for (i = 0; i < videodata->numwindows; i++) { + SDL_WindowData *d = videodata->windowlist[i]; + if (d->xwindow == window) { + *out_x = in_x / (d->window->w-1); + *out_y = in_y / (d->window->h-1); + return; + } + } + // couldn't find the window... + *out_x = in_x; + *out_y = in_y; +} #endif /* SDL_VIDEO_DRIVER_X11_XINPUT2 */ void @@ -171,22 +189,31 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie) #if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH case XI_TouchBegin: { const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data; + float x, y; + xinput2_normalize_touch_coordinates(videodata, xev->event, + xev->event_x, xev->event_y, &x, &y); SDL_SendTouch(xev->sourceid,xev->detail, - SDL_TRUE, xev->event_x, xev->event_y, 1.0); + SDL_TRUE, x, y, 1.0); return 1; } break; case XI_TouchEnd: { const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data; + float x, y; + xinput2_normalize_touch_coordinates(videodata, xev->event, + xev->event_x, xev->event_y, &x, &y); SDL_SendTouch(xev->sourceid,xev->detail, - SDL_FALSE, xev->event_x, xev->event_y, 1.0); + SDL_FALSE, x, y, 1.0); return 1; } break; case XI_TouchUpdate: { const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data; + float x, y; + xinput2_normalize_touch_coordinates(videodata, xev->event, + xev->event_x, xev->event_y, &x, &y); SDL_SendTouchMotion(xev->sourceid,xev->detail, - xev->event_x, xev->event_y, 1.0); + x, y, 1.0); return 1; } break;