Enable capturing raw Xinput2 touch events and use to flag global mouse state as dirty

- Touch events may be translated to mouse movement events without the normal Xinput2 raw motion events
  being sent. Not all touch events will necessarily move the mouse but this ensures we update the global
  mouse state just in case.

- Fix up some formatting

CR: saml
This commit is contained in:
Sam Lantinga 2022-07-27 10:31:24 -07:00
parent 42165fe8d1
commit dbf7940541
1 changed files with 30 additions and 15 deletions

View File

@ -120,7 +120,7 @@ X11_InitXinput2(_THIS)
int version = 0; int version = 0;
XIEventMask eventmask; XIEventMask eventmask;
unsigned char mask[3] = { 0,0,0 }; unsigned char mask[4] = { 0, 0, 0, 0 };
int event, err; int event, err;
/* /*
@ -149,7 +149,7 @@ X11_InitXinput2(_THIS)
xinput2_multitouch_supported = xinput2_version_atleast(version, 2, 2); xinput2_multitouch_supported = xinput2_version_atleast(version, 2, 2);
#endif #endif
/* Enable Raw motion events for this display */ /* Enable raw motion events for this display */
eventmask.deviceid = XIAllMasterDevices; eventmask.deviceid = XIAllMasterDevices;
eventmask.mask_len = sizeof(mask); eventmask.mask_len = sizeof(mask);
eventmask.mask = mask; eventmask.mask = mask;
@ -158,7 +158,16 @@ X11_InitXinput2(_THIS)
XISetMask(mask, XI_RawButtonPress); XISetMask(mask, XI_RawButtonPress);
XISetMask(mask, XI_RawButtonRelease); XISetMask(mask, XI_RawButtonRelease);
if (X11_XISelectEvents(data->display,DefaultRootWindow(data->display),&eventmask,1) != Success) { #if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
/* Enable raw touch events if supported */
if (X11_Xinput2IsMultitouchSupported()) {
XISetMask(mask, XI_RawTouchBegin);
XISetMask(mask, XI_RawTouchUpdate);
XISetMask(mask, XI_RawTouchEnd);
}
#endif
if (X11_XISelectEvents(data->display, DefaultRootWindow(data->display), &eventmask,1) != Success) {
return; return;
} }
#endif #endif
@ -168,7 +177,7 @@ int
X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie) X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie)
{ {
#if SDL_VIDEO_DRIVER_X11_XINPUT2 #if SDL_VIDEO_DRIVER_X11_XINPUT2
if(cookie->extension != xinput2_opcode) { if (cookie->extension != xinput2_opcode) {
return 0; return 0;
} }
switch(cookie->evtype) { switch(cookie->evtype) {
@ -197,11 +206,16 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie)
prev_rel_coords[1] = relative_coords[1]; prev_rel_coords[1] = relative_coords[1];
prev_time = rawev->time; prev_time = rawev->time;
return 1; return 1;
} }
break; break;
case XI_RawButtonPress: case XI_RawButtonPress:
case XI_RawButtonRelease: case XI_RawButtonRelease:
#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
case XI_RawTouchBegin:
case XI_RawTouchUpdate:
case XI_RawTouchEnd:
#endif
videodata->global_mouse_changed = SDL_TRUE; videodata->global_mouse_changed = SDL_TRUE;
break; break;
@ -214,7 +228,7 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie)
if (! pointer_emulated) { if (! pointer_emulated) {
SDL_Mouse *mouse = SDL_GetMouse(); SDL_Mouse *mouse = SDL_GetMouse();
if(!mouse->relative_mode || mouse->relative_mode_warp) { if (!mouse->relative_mode || mouse->relative_mode_warp) {
SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event); SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event);
if (window) { if (window) {
SDL_SendMouseMotion(window, 0, 0, xev->event_x, xev->event_y); SDL_SendMouseMotion(window, 0, 0, xev->event_x, xev->event_y);
@ -222,8 +236,8 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie)
} }
} }
return 1; return 1;
} }
break; break;
case XI_TouchBegin: { case XI_TouchBegin: {
const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data; const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
@ -232,8 +246,8 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie)
xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y); xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y);
SDL_SendTouch(xev->sourceid, xev->detail, window, SDL_TRUE, x, y, 1.0); SDL_SendTouch(xev->sourceid, xev->detail, window, SDL_TRUE, x, y, 1.0);
return 1; return 1;
} }
break; break;
case XI_TouchEnd: { case XI_TouchEnd: {
const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data; const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
float x, y; float x, y;
@ -241,8 +255,8 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie)
xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y); xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y);
SDL_SendTouch(xev->sourceid, xev->detail, window, SDL_FALSE, x, y, 1.0); SDL_SendTouch(xev->sourceid, xev->detail, window, SDL_FALSE, x, y, 1.0);
return 1; return 1;
} }
break; break;
case XI_TouchUpdate: { case XI_TouchUpdate: {
const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data; const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
float x, y; float x, y;
@ -250,8 +264,9 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie)
xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y); xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y);
SDL_SendTouchMotion(xev->sourceid, xev->detail, window, x, y, 1.0); SDL_SendTouchMotion(xev->sourceid, xev->detail, window, x, y, 1.0);
return 1; return 1;
} }
break; break;
#endif #endif
} }
#endif #endif