Fixed bug 3871 - Touch events are not normalised on X11
authorSam Lantinga <slouken@libsdl.org>
Wed, 11 Oct 2017 13:31:21 -0700
changeset 115986fde74294cc9
parent 11597 7ee20a756f96
child 11599 0f2de8f6c959
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
     1.1 --- a/src/video/x11/SDL_x11xinput2.c	Wed Oct 11 13:26:58 2017 -0700
     1.2 +++ b/src/video/x11/SDL_x11xinput2.c	Wed Oct 11 13:31:21 2017 -0700
     1.3 @@ -73,6 +73,24 @@
     1.4  {
     1.5      return ( version >= ((wantmajor * 1000) + wantminor) );
     1.6  }
     1.7 +
     1.8 +static void
     1.9 +xinput2_normalize_touch_coordinates(SDL_VideoData *videodata, Window window,
    1.10 +    double in_x, double in_y, float *out_x, float *out_y)
    1.11 +{
    1.12 +   int i;
    1.13 +   for (i = 0; i < videodata->numwindows; i++) {
    1.14 +      SDL_WindowData *d = videodata->windowlist[i];
    1.15 +      if (d->xwindow == window) {
    1.16 +         *out_x = in_x / (d->window->w-1);
    1.17 +         *out_y = in_y / (d->window->h-1);
    1.18 +         return;
    1.19 +      }
    1.20 +   }
    1.21 +   // couldn't find the window...
    1.22 +   *out_x = in_x;
    1.23 +   *out_y = in_y;
    1.24 +}
    1.25  #endif /* SDL_VIDEO_DRIVER_X11_XINPUT2 */
    1.26  
    1.27  void
    1.28 @@ -171,22 +189,31 @@
    1.29  #if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
    1.30          case XI_TouchBegin: {
    1.31              const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
    1.32 +            float x, y;
    1.33 +            xinput2_normalize_touch_coordinates(videodata, xev->event,
    1.34 +                                  xev->event_x, xev->event_y, &x, &y);
    1.35              SDL_SendTouch(xev->sourceid,xev->detail,
    1.36 -                      SDL_TRUE, xev->event_x, xev->event_y, 1.0);
    1.37 +                      SDL_TRUE, x, y, 1.0);
    1.38              return 1;
    1.39              }
    1.40              break;
    1.41          case XI_TouchEnd: {
    1.42              const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
    1.43 +            float x, y;
    1.44 +            xinput2_normalize_touch_coordinates(videodata, xev->event,
    1.45 +                                  xev->event_x, xev->event_y, &x, &y);
    1.46              SDL_SendTouch(xev->sourceid,xev->detail,
    1.47 -                      SDL_FALSE, xev->event_x, xev->event_y, 1.0);
    1.48 +                      SDL_FALSE, x, y, 1.0);
    1.49              return 1;
    1.50              }
    1.51              break;
    1.52          case XI_TouchUpdate: {
    1.53              const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
    1.54 +            float x, y;
    1.55 +            xinput2_normalize_touch_coordinates(videodata, xev->event,
    1.56 +                                  xev->event_x, xev->event_y, &x, &y);
    1.57              SDL_SendTouchMotion(xev->sourceid,xev->detail,
    1.58 -                                xev->event_x, xev->event_y, 1.0);
    1.59 +                                x, y, 1.0);
    1.60              return 1;
    1.61              }
    1.62              break;