diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index e62889f5b2..2e6cce79a4 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -25,6 +25,8 @@ #include /* For getpid() and readlink() */ #include "../../core/linux/SDL_system_theme.h" +#include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_mouse_c.h" #include "../SDL_pixels_c.h" #include "../SDL_sysvideo.h" @@ -415,7 +417,13 @@ int X11_VideoInit(SDL_VideoDevice *_this) return -1; } - X11_InitXinput2(_this); + if (!X11_InitXinput2(_this)) { + /* Assume a mouse and keyboard are attached */ + data->keyboardID = SDL_GetNextObjectID(); + SDL_AddKeyboard(data->keyboardID, SDL_FALSE); + data->mouseID = SDL_GetNextObjectID(); + SDL_AddMouse(data->mouseID, SDL_FALSE); + } #ifdef SDL_VIDEO_DRIVER_X11_XFIXES X11_InitXfixes(_this); diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index 2aa7025ad0..d742ecd783 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -95,6 +95,55 @@ static SDL_Window *xinput2_get_sdlwindow(SDL_VideoData *videodata, Window window return windowdata ? windowdata->window : NULL; } +static void xinput2_init_device_list(SDL_VideoData *videodata) +{ + XIDeviceInfo *info; + int ndevices; + + info = X11_XIQueryDevice(videodata->display, XIAllDevices, &ndevices); + + for (int i = 0; i < ndevices; i++) { + XIDeviceInfo *dev = &info[i]; + + switch (dev->use) { + case XIMasterKeyboard: + videodata->keyboardID = (SDL_KeyboardID)dev->deviceid; + SDL_AddKeyboard(videodata->keyboardID, SDL_FALSE); + break; + case XIMasterPointer: + videodata->mouseID = (SDL_MouseID)dev->deviceid; + SDL_AddMouse(videodata->mouseID, SDL_FALSE); + break; + default: + break; + } + +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + for (int j = 0; j < dev->num_classes; j++) { + SDL_TouchID touchId; + SDL_TouchDeviceType touchType; + XIAnyClassInfo *class = dev->classes[j]; + XITouchClassInfo *t = (XITouchClassInfo *)class; + + /* Only touch devices */ + if (class->type != XITouchClass) { + continue; + } + + if (t->mode == XIDependentTouch) { + touchType = SDL_TOUCH_DEVICE_INDIRECT_RELATIVE; + } else { /* XIDirectTouch */ + touchType = SDL_TOUCH_DEVICE_DIRECT; + } + + touchId = t->sourceid; + SDL_AddTouch(touchId, touchType, dev->name); + } +#endif // SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + } + X11_XIFreeDeviceInfo(info); +} + #ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH static void xinput2_normalize_touch_coordinates(SDL_Window *window, double in_x, double in_y, float *out_x, float *out_y) { @@ -119,7 +168,7 @@ static void xinput2_normalize_touch_coordinates(SDL_Window *window, double in_x, #endif /* SDL_VIDEO_DRIVER_X11_XINPUT2 */ -void X11_InitXinput2(SDL_VideoDevice *_this) +SDL_bool X11_InitXinput2(SDL_VideoDevice *_this) { #ifdef SDL_VIDEO_DRIVER_X11_XINPUT2 SDL_VideoData *data = _this->driverdata; @@ -140,13 +189,13 @@ void X11_InitXinput2(SDL_VideoDevice *_this) */ if (!SDL_X11_HAVE_XINPUT2 || !X11_XQueryExtension(data->display, "XInputExtension", &xinput2_opcode, &event, &err)) { - return; /* X server does not have XInput at all */ + return SDL_FALSE; /* X server does not have XInput at all */ } /* We need at least 2.2 for Multitouch, 2.0 otherwise. */ version = query_xinput2_version(data->display, 2, 2); if (!xinput2_version_atleast(version, 2, 0)) { - return; /* X server does not support the version we want at all. */ + return SDL_FALSE; /* X server does not support the version we want at all. */ } xinput2_initialized = 1; @@ -156,6 +205,8 @@ void X11_InitXinput2(SDL_VideoDevice *_this) #endif /* Enable raw motion events for this display */ + SDL_zero(eventmask); + SDL_zeroa(mask); eventmask.deviceid = XIAllMasterDevices; eventmask.mask_len = sizeof(mask); eventmask.mask = mask; @@ -173,9 +224,7 @@ void X11_InitXinput2(SDL_VideoDevice *_this) } #endif - if (X11_XISelectEvents(data->display, DefaultRootWindow(data->display), &eventmask, 1) != Success) { - return; - } + X11_XISelectEvents(data->display, DefaultRootWindow(data->display), &eventmask, 1); SDL_zero(eventmask); SDL_zeroa(mask); @@ -184,9 +233,13 @@ void X11_InitXinput2(SDL_VideoDevice *_this) eventmask.mask = mask; XISetMask(mask, XI_HierarchyChanged); - if (X11_XISelectEvents(data->display, DefaultRootWindow(data->display), &eventmask, 1) != Success) { - return; - } + X11_XISelectEvents(data->display, DefaultRootWindow(data->display), &eventmask, 1); + + xinput2_init_device_list(data); + + return SDL_TRUE; +#else + return SDL_FALSE; #endif } @@ -512,42 +565,6 @@ int X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie) void X11_InitXinput2Multitouch(SDL_VideoDevice *_this) { -#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH - SDL_VideoData *data = _this->driverdata; - XIDeviceInfo *info; - int ndevices, i, j; - - if (!X11_Xinput2IsMultitouchSupported()) { - return; - } - - info = X11_XIQueryDevice(data->display, XIAllDevices, &ndevices); - - for (i = 0; i < ndevices; i++) { - XIDeviceInfo *dev = &info[i]; - for (j = 0; j < dev->num_classes; j++) { - SDL_TouchID touchId; - SDL_TouchDeviceType touchType; - XIAnyClassInfo *class = dev->classes[j]; - XITouchClassInfo *t = (XITouchClassInfo *)class; - - /* Only touch devices */ - if (class->type != XITouchClass) { - continue; - } - - if (t->mode == XIDependentTouch) { - touchType = SDL_TOUCH_DEVICE_INDIRECT_RELATIVE; - } else { /* XIDirectTouch */ - touchType = SDL_TOUCH_DEVICE_DIRECT; - } - - touchId = t->sourceid; - SDL_AddTouch(touchId, touchType, dev->name); - } - } - X11_XIFreeDeviceInfo(info); -#endif } void X11_Xinput2SelectTouch(SDL_VideoDevice *_this, SDL_Window *window) diff --git a/src/video/x11/SDL_x11xinput2.h b/src/video/x11/SDL_x11xinput2.h index eba6cdf739..e67e1cb4c9 100644 --- a/src/video/x11/SDL_x11xinput2.h +++ b/src/video/x11/SDL_x11xinput2.h @@ -30,7 +30,7 @@ struct XGenericEventCookie; typedef struct XGenericEventCookie XGenericEventCookie; #endif -extern void X11_InitXinput2(SDL_VideoDevice *_this); +extern SDL_bool X11_InitXinput2(SDL_VideoDevice *_this); extern void X11_InitXinput2Multitouch(SDL_VideoDevice *_this); extern int X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie); extern int X11_Xinput2IsInitialized(void);