21#include "../../SDL_internal.h"
23#if SDL_VIDEO_DRIVER_X11
27#include "../../events/SDL_mouse_c.h"
28#include "../../events/SDL_touch_c.h"
32#if SDL_VIDEO_DRIVER_X11_XINPUT2
33static int xinput2_initialized = 0;
35#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
36static int xinput2_multitouch_supported = 0;
43static int xinput2_opcode;
45static void parse_valuators(
const double *input_values,
unsigned char *
mask,
int mask_len,
46 double *output_values,
int output_values_len) {
48 int top = mask_len * 8;
52 SDL_memset(output_values,0,output_values_len *
sizeof(
double));
53 for (;
i <
top &&
z < output_values_len;
i++) {
54 if (XIMaskIsSet(
mask,
i)) {
55 const int value = (int) *input_values;
64query_xinput2_version(Display *display,
int major,
int minor)
67 X11_XIQueryVersion(display, &major, &minor);
68 return ((major * 1000) + minor);
72xinput2_version_atleast(
const int version,
const int wantmajor,
const int wantminor)
74 return ( version >= ((wantmajor * 1000) + wantminor) );
77#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
92xinput2_normalize_touch_coordinates(
SDL_Window *
window,
double in_x,
double in_y,
float *out_x,
float *out_y)
98 *out_x = in_x / (
window->w - 1);
103 *out_y = in_y / (
window->h - 1);
118#if SDL_VIDEO_DRIVER_X11_XINPUT2
122 XIEventMask eventmask;
123 unsigned char mask[3] = { 0,0,0 };
135 if (!SDL_X11_HAVE_XINPUT2 ||
136 !X11_XQueryExtension(
data->display,
"XInputExtension", &xinput2_opcode, &
event, &err)) {
141 version = query_xinput2_version(
data->display, 2, 2);
142 if (!xinput2_version_atleast(version, 2, 0)) {
146 xinput2_initialized = 1;
148#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
149 xinput2_multitouch_supported = xinput2_version_atleast(version, 2, 2);
153 eventmask.deviceid = XIAllMasterDevices;
154 eventmask.mask_len =
sizeof(
mask);
155 eventmask.mask =
mask;
157 XISetMask(
mask, XI_RawMotion);
158 XISetMask(
mask, XI_RawButtonPress);
159 XISetMask(
mask, XI_RawButtonRelease);
161 if (X11_XISelectEvents(
data->display,DefaultRootWindow(
data->display),&eventmask,1) != Success) {
170#if SDL_VIDEO_DRIVER_X11_XINPUT2
171 if(cookie->extension != xinput2_opcode) {
174 switch(cookie->evtype) {
176 const XIRawEvent *rawev = (
const XIRawEvent*)cookie->data;
178 double relative_coords[2];
179 static Time prev_time = 0;
180 static double prev_rel_coords[2];
184 if (!mouse->relative_mode || mouse->relative_mode_warp) {
188 parse_valuators(rawev->raw_values,rawev->valuators.mask,
189 rawev->valuators.mask_len,relative_coords,2);
191 if ((rawev->time == prev_time) && (relative_coords[0] == prev_rel_coords[0]) && (relative_coords[1] == prev_rel_coords[1])) {
195 SDL_SendMouseMotion(mouse->focus,mouse->mouseID,1,(
int)relative_coords[0],(
int)relative_coords[1]);
196 prev_rel_coords[0] = relative_coords[0];
197 prev_rel_coords[1] = relative_coords[1];
198 prev_time = rawev->time;
203 case XI_RawButtonPress:
204 case XI_RawButtonRelease:
208#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
212 const XIDeviceEvent *xev = (
const XIDeviceEvent *) cookie->data;
213 int pointer_emulated = (xev->flags & XIPointerEmulated);
215 if (! pointer_emulated) {
228 case XI_TouchBegin: {
229 const XIDeviceEvent *xev = (
const XIDeviceEvent *) cookie->data;
232 xinput2_normalize_touch_coordinates(
window, xev->event_x, xev->event_y, &
x, &
y);
238 const XIDeviceEvent *xev = (
const XIDeviceEvent *) cookie->data;
241 xinput2_normalize_touch_coordinates(
window, xev->event_x, xev->event_y, &
x, &
y);
246 case XI_TouchUpdate: {
247 const XIDeviceEvent *xev = (
const XIDeviceEvent *) cookie->data;
250 xinput2_normalize_touch_coordinates(
window, xev->event_x, xev->event_y, &
x, &
y);
264#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
268 info = X11_XIQueryDevice(
data->display, XIAllDevices, &ndevices);
270 for (
i = 0;
i < ndevices;
i++) {
271 XIDeviceInfo *dev = &info[
i];
272 for (
j = 0;
j < dev->num_classes;
j++) {
275 XIAnyClassInfo *
class = dev->classes[
j];
276 XITouchClassInfo *
t = (XITouchClassInfo*)
class;
279 if (class->type != XITouchClass)
282 if (
t->mode == XIDependentTouch) {
288 touchId =
t->sourceid;
292 X11_XIFreeDeviceInfo(info);
299#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
301 XIEventMask eventmask;
302 unsigned char mask[4] = { 0, 0, 0, 0 };
312 eventmask.deviceid = XIAllMasterDevices;
313 eventmask.mask_len =
sizeof(
mask);
314 eventmask.mask =
mask;
316 XISetMask(
mask, XI_TouchBegin);
317 XISetMask(
mask, XI_TouchUpdate);
318 XISetMask(
mask, XI_TouchEnd);
319 XISetMask(
mask, XI_Motion);
321 X11_XISelectEvents(
data->display,window_data->
xwindow,&eventmask,1);
329#if SDL_VIDEO_DRIVER_X11_XINPUT2
330 return xinput2_initialized;
339#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
340 return xinput2_initialized && xinput2_multitouch_supported;
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
SDL_Mouse * SDL_GetMouse(void)
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
GLint GLint GLint GLint GLint GLint y
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLint GLint GLint GLint GLint x
GLdouble GLdouble GLdouble GLdouble top
GLsizei const GLfloat * value
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_bool down, float x, float y, float pressure)
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, float x, float y, float pressure)
int SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name)
@ SDL_TOUCH_DEVICE_DIRECT
@ SDL_TOUCH_DEVICE_INDIRECT_RELATIVE
static SDL_VideoDevice * _this
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
EGLSurface EGLNativeWindowType * window
SDL_bool relative_mode_warp
SDL_WindowData ** windowlist
SDL_bool global_mouse_changed
The type used to identify a window.