diff --git a/configure b/configure index 0cc698a10..9f88235cc 100755 --- a/configure +++ b/configure @@ -818,6 +818,7 @@ enable_sndio_shared enable_diskaudio enable_dummyaudio enable_video_wayland +enable_video_wayland_qt_touch enable_video_x11 with_x enable_x11_shared @@ -1534,6 +1535,9 @@ Optional Features: --enable-diskaudio support the disk writer audio driver [[default=yes]] --enable-dummyaudio support the dummy audio driver [[default=yes]] --enable-video-wayland use Wayland video driver [[default=yes]] + --enable-video-wayland-qt-touch + QtWayland server support for Wayland video driver + [[default=yes]] --enable-video-x11 use X11 video driver [[default=yes]] --enable-x11-shared dynamically load X11 support [[default=maybe]] --enable-video-x11-xcursor @@ -18645,6 +18649,14 @@ else fi + # Check whether --enable-video-wayland-qt-touch was given. +if test "${enable_video_wayland_qt_touch+set}" = set; then : + enableval=$enable_video_wayland_qt_touch; +else + enable_video_wayland_qt_touch=yes +fi + + if test x$enable_video = xyes -a x$enable_video_wayland = xyes; then # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 @@ -18704,6 +18716,11 @@ $as_echo "$video_wayland" >&6; } $as_echo "#define SDL_VIDEO_DRIVER_WAYLAND 1" >>confdefs.h + if test x$enable_video_wayland_qt_touch = xyes; then + +$as_echo "#define SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 1" >>confdefs.h + + fi SOURCES="$SOURCES $srcdir/src/video/wayland/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS" EXTRA_LDFLAGS="$EXTRA_LDFLAGS $WAYLAND_LIBS" diff --git a/configure.in b/configure.in index 941a255e6..0a491ec27 100644 --- a/configure.in +++ b/configure.in @@ -1122,6 +1122,10 @@ CheckWayland() AC_HELP_STRING([--enable-video-wayland], [use Wayland video driver [[default=yes]]]), ,enable_video_wayland=yes) + AC_ARG_ENABLE(video-wayland-qt-touch, +AC_HELP_STRING([--enable-video-wayland-qt-touch], [QtWayland server support for Wayland video driver [[default=yes]]]), + ,enable_video_wayland_qt_touch=yes) + if test x$enable_video = xyes -a x$enable_video_wayland = xyes; then AC_PATH_PROG(PKG_CONFIG, pkg-config, no) AC_MSG_CHECKING(for Wayland support) @@ -1137,6 +1141,9 @@ AC_HELP_STRING([--enable-video-wayland], [use Wayland video driver [[default=yes if test x$video_wayland = xyes; then AC_DEFINE(SDL_VIDEO_DRIVER_WAYLAND, 1, [ ]) + if test x$enable_video_wayland_qt_touch = xyes; then + AC_DEFINE(SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH, 1, [ ]) + fi SOURCES="$SOURCES $srcdir/src/video/wayland/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS" dnl FIXME do dynamic loading code here. diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 14ce7912c..c79dca89a 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -261,6 +261,7 @@ #undef SDL_VIDEO_DRIVER_DUMMY #undef SDL_VIDEO_DRIVER_WINDOWS #undef SDL_VIDEO_DRIVER_WAYLAND +#undef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH #undef SDL_VIDEO_DRIVER_X11 #undef SDL_VIDEO_DRIVER_RPI #undef SDL_VIDEO_DRIVER_X11_DYNAMIC diff --git a/src/video/wayland/SDL_waylandtouch.c b/src/video/wayland/SDL_waylandtouch.c new file mode 100644 index 000000000..9edf2e7ed --- /dev/null +++ b/src/video/wayland/SDL_waylandtouch.c @@ -0,0 +1,253 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* Contributed by Thomas Perl */ + +#include "SDL_config.h" + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + +#include "SDL_waylandtouch.h" +#include "SDL_log.h" +#include "../../events/SDL_touch_c.h" + +struct SDL_WaylandTouch { + struct qt_touch_extension *touch_extension; +}; + + +/** + * Qt TouchPointState + * adapted from qtbase/src/corelib/global/qnamespace.h + **/ +enum QtWaylandTouchPointState { + QtWaylandTouchPointPressed = 0x01, + QtWaylandTouchPointMoved = 0x02, + /* + Never sent by the server: + QtWaylandTouchPointStationary = 0x04, + */ + QtWaylandTouchPointReleased = 0x08, +}; + +static void +touch_handle_touch(void *data, + struct qt_touch_extension *qt_touch_extension, + uint32_t time, + uint32_t id, + uint32_t state, + int32_t x, + int32_t y, + int32_t normalized_x, + int32_t normalized_y, + int32_t width, + int32_t height, + uint32_t pressure, + int32_t velocity_x, + int32_t velocity_y, + uint32_t flags, + struct wl_array *rawdata) +{ + /** + * Event is assembled in QtWayland in TouchExtensionGlobal::postTouchEvent + * (src/compositor/wayland_wrapper/qwltouch.cpp) + **/ + + float FIXED_TO_FLOAT = 1. / 10000.; + float xf = FIXED_TO_FLOAT * x; + float yf = FIXED_TO_FLOAT * y; + + float PRESSURE_TO_FLOAT = 1. / 255.; + float pressuref = PRESSURE_TO_FLOAT * pressure; + + uint32_t touchState = state & 0xFFFF; + /* + Other fields that are sent by the server (qwltouch.cpp), + but not used at the moment can be decoded in this way: + + uint32_t sentPointCount = state >> 16; + uint32_t touchFlags = flags & 0xFFFF; + uint32_t capabilities = flags >> 16; + */ + + SDL_TouchID deviceId = 0; + if (!SDL_GetTouch(deviceId)) { + if (SDL_AddTouch(deviceId, "qt_touch_extension") < 0) { + SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__); + } + } + + switch (touchState) { + case QtWaylandTouchPointPressed: + case QtWaylandTouchPointReleased: + SDL_SendTouch(deviceId, (SDL_FingerID)id, + (touchState == QtWaylandTouchPointPressed) ? SDL_TRUE : SDL_FALSE, + xf, yf, pressuref); + break; + case QtWaylandTouchPointMoved: + SDL_SendTouchMotion(deviceId, (SDL_FingerID)id, xf, yf, pressuref); + break; + default: + /* Should not happen */ + break; + } +} + +static void +touch_handle_configure(void *data, + struct qt_touch_extension *qt_touch_extension, + uint32_t flags) +{ +} + +/* wayland-qt-touch-extension.c BEGINS */ + +static const struct qt_touch_extension_listener touch_listener = { + touch_handle_touch, + touch_handle_configure, +}; + +static const struct wl_interface *qt_touch_extension_types[] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +static const struct wl_message qt_touch_extension_requests[] = { + { "dummy", "", qt_touch_extension_types + 0 }, +}; + +static const struct wl_message qt_touch_extension_events[] = { + { "touch", "uuuiiiiiiuiiua", qt_touch_extension_types + 0 }, + { "configure", "u", qt_touch_extension_types + 0 }, +}; + +WL_EXPORT const struct wl_interface qt_touch_extension_interface = { + "qt_touch_extension", 1, + 1, qt_touch_extension_requests, + 2, qt_touch_extension_events, +}; + +/* wayland-qt-touch-extension.c ENDS */ + +/* wayland-qt-windowmanager.c BEGINS */ +static const struct wl_interface *qt_windowmanager_types[] = { + NULL, + NULL, +}; + +static const struct wl_message qt_windowmanager_requests[] = { + { "open_url", "us", qt_windowmanager_types + 0 }, +}; + +static const struct wl_message qt_windowmanager_events[] = { + { "hints", "i", qt_windowmanager_types + 0 }, + { "quit", "", qt_windowmanager_types + 0 }, +}; + +WL_EXPORT const struct wl_interface qt_windowmanager_interface = { + "qt_windowmanager", 1, + 1, qt_windowmanager_requests, + 2, qt_windowmanager_events, +}; +/* wayland-qt-windowmanager.c ENDS */ + +/* wayland-qt-surface-extension.c BEGINS */ +extern const struct wl_interface qt_extended_surface_interface; +extern const struct wl_interface wl_surface_interface; + +static const struct wl_interface *qt_surface_extension_types[] = { + NULL, + NULL, + &qt_extended_surface_interface, + &wl_surface_interface, +}; + +static const struct wl_message qt_surface_extension_requests[] = { + { "get_extended_surface", "no", qt_surface_extension_types + 2 }, +}; + +WL_EXPORT const struct wl_interface qt_surface_extension_interface = { + "qt_surface_extension", 1, + 1, qt_surface_extension_requests, + 0, NULL, +}; + +static const struct wl_message qt_extended_surface_requests[] = { + { "update_generic_property", "sa", qt_surface_extension_types + 0 }, + { "set_content_orientation", "i", qt_surface_extension_types + 0 }, + { "set_window_flags", "i", qt_surface_extension_types + 0 }, +}; + +static const struct wl_message qt_extended_surface_events[] = { + { "onscreen_visibility", "i", qt_surface_extension_types + 0 }, + { "set_generic_property", "sa", qt_surface_extension_types + 0 }, + { "close", "", qt_surface_extension_types + 0 }, +}; + +WL_EXPORT const struct wl_interface qt_extended_surface_interface = { + "qt_extended_surface", 1, + 3, qt_extended_surface_requests, + 3, qt_extended_surface_events, +}; + +/* wayland-qt-surface-extension.c ENDS */ + +void +Wayland_touch_create(SDL_VideoData *data, uint32_t id) +{ + if (data->touch) { + Wayland_touch_destroy(data); + } + + data->touch = malloc(sizeof(struct SDL_WaylandTouch)); + + struct SDL_WaylandTouch *touch = data->touch; + touch->touch_extension = wl_registry_bind(data->registry, id, &qt_touch_extension_interface, 1); + qt_touch_extension_add_listener(touch->touch_extension, &touch_listener, data); +} + +void +Wayland_touch_destroy(SDL_VideoData *data) +{ + if (data->touch) { + struct SDL_WaylandTouch *touch = data->touch; + if (touch->touch_extension) { + qt_touch_extension_destroy(touch->touch_extension); + } + + free(data->touch); + data->touch = NULL; + } +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ diff --git a/src/video/wayland/SDL_waylandtouch.h b/src/video/wayland/SDL_waylandtouch.h new file mode 100644 index 000000000..ccb645bd9 --- /dev/null +++ b/src/video/wayland/SDL_waylandtouch.h @@ -0,0 +1,351 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_config.h" + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + +#ifndef _SDL_waylandtouch_h +#define _SDL_waylandtouch_h + +#include "SDL_waylandvideo.h" +#include +#include +#include "wayland-client.h" +#include "wayland-util.h" + +void Wayland_touch_create(SDL_VideoData *data, uint32_t id); +void Wayland_touch_destroy(SDL_VideoData *data); + +struct qt_touch_extension; + +/* Autogenerated QT headers */ + +/* + Support for Wayland with QmlCompositor as Server +================================================ + +The Wayland video driver has support for some additional features when +using QtWayland's "qmlcompositor" as Wayland server. This is needed for touch +input when running SDL applications under a qmlcompositor Wayland server. + +The files following headers have been +generated from the Wayland XML Protocol Definition in QtWayland as follows: + +Clone QtWayland from Git: + http://qt.gitorious.org/qt/qtwayland/ + +Generate headers and glue code: + for extension in touch-extension surface-extension windowmanager; do + wayland-scanner client-header < src/extensions/$extension.xml > wayland-qt-$extension.h + wayland-scanner code < src/extensions/$extension.xml > wayland-qt-$extension.c + done + +*/ + +/* wayland-qt-surface-extension.h */ + +struct wl_client; +struct wl_resource; + +struct qt_surface_extension; +struct qt_extended_surface; + +extern const struct wl_interface qt_surface_extension_interface; +extern const struct wl_interface qt_extended_surface_interface; + +#define QT_SURFACE_EXTENSION_GET_EXTENDED_SURFACE 0 + +static inline void +qt_surface_extension_set_user_data(struct qt_surface_extension *qt_surface_extension, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) qt_surface_extension, user_data); +} + +static inline void * +qt_surface_extension_get_user_data(struct qt_surface_extension *qt_surface_extension) +{ + return wl_proxy_get_user_data((struct wl_proxy *) qt_surface_extension); +} + +static inline void +qt_surface_extension_destroy(struct qt_surface_extension *qt_surface_extension) +{ + wl_proxy_destroy((struct wl_proxy *) qt_surface_extension); +} + +static inline struct qt_extended_surface * +qt_surface_extension_get_extended_surface(struct qt_surface_extension *qt_surface_extension, struct wl_surface *surface) +{ + struct wl_proxy *id; + + id = wl_proxy_create((struct wl_proxy *) qt_surface_extension, + &qt_extended_surface_interface); + if (!id) + return NULL; + + wl_proxy_marshal((struct wl_proxy *) qt_surface_extension, + QT_SURFACE_EXTENSION_GET_EXTENDED_SURFACE, id, surface); + + return (struct qt_extended_surface *) id; +} + +#ifndef QT_EXTENDED_SURFACE_ORIENTATION_ENUM +#define QT_EXTENDED_SURFACE_ORIENTATION_ENUM +enum qt_extended_surface_orientation { + QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION = 0, + QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION = 1, + QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION = 2, + QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION = 4, + QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION = 8, +}; +#endif /* QT_EXTENDED_SURFACE_ORIENTATION_ENUM */ + +#ifndef QT_EXTENDED_SURFACE_WINDOWFLAG_ENUM +#define QT_EXTENDED_SURFACE_WINDOWFLAG_ENUM +enum qt_extended_surface_windowflag { + QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES = 1, + QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP = 2, +}; +#endif /* QT_EXTENDED_SURFACE_WINDOWFLAG_ENUM */ + +struct qt_extended_surface_listener { + /** + * onscreen_visibility - (none) + * @visible: (none) + */ + void (*onscreen_visibility)(void *data, + struct qt_extended_surface *qt_extended_surface, + int32_t visible); + /** + * set_generic_property - (none) + * @name: (none) + * @value: (none) + */ + void (*set_generic_property)(void *data, + struct qt_extended_surface *qt_extended_surface, + const char *name, + struct wl_array *value); + /** + * close - (none) + */ + void (*close)(void *data, + struct qt_extended_surface *qt_extended_surface); +}; + +static inline int +qt_extended_surface_add_listener(struct qt_extended_surface *qt_extended_surface, + const struct qt_extended_surface_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) qt_extended_surface, + (void (**)(void)) listener, data); +} + +#define QT_EXTENDED_SURFACE_UPDATE_GENERIC_PROPERTY 0 +#define QT_EXTENDED_SURFACE_SET_CONTENT_ORIENTATION 1 +#define QT_EXTENDED_SURFACE_SET_WINDOW_FLAGS 2 + +static inline void +qt_extended_surface_set_user_data(struct qt_extended_surface *qt_extended_surface, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) qt_extended_surface, user_data); +} + +static inline void * +qt_extended_surface_get_user_data(struct qt_extended_surface *qt_extended_surface) +{ + return wl_proxy_get_user_data((struct wl_proxy *) qt_extended_surface); +} + +static inline void +qt_extended_surface_destroy(struct qt_extended_surface *qt_extended_surface) +{ + wl_proxy_destroy((struct wl_proxy *) qt_extended_surface); +} + +static inline void +qt_extended_surface_update_generic_property(struct qt_extended_surface *qt_extended_surface, const char *name, struct wl_array *value) +{ + wl_proxy_marshal((struct wl_proxy *) qt_extended_surface, + QT_EXTENDED_SURFACE_UPDATE_GENERIC_PROPERTY, name, value); +} + +static inline void +qt_extended_surface_set_content_orientation(struct qt_extended_surface *qt_extended_surface, int32_t orientation) +{ + wl_proxy_marshal((struct wl_proxy *) qt_extended_surface, + QT_EXTENDED_SURFACE_SET_CONTENT_ORIENTATION, orientation); +} + +static inline void +qt_extended_surface_set_window_flags(struct qt_extended_surface *qt_extended_surface, int32_t flags) +{ + wl_proxy_marshal((struct wl_proxy *) qt_extended_surface, + QT_EXTENDED_SURFACE_SET_WINDOW_FLAGS, flags); +} + +/* wayland-qt-touch-extension.h */ + +extern const struct wl_interface qt_touch_extension_interface; + +#ifndef QT_TOUCH_EXTENSION_FLAGS_ENUM +#define QT_TOUCH_EXTENSION_FLAGS_ENUM +enum qt_touch_extension_flags { + QT_TOUCH_EXTENSION_FLAGS_MOUSE_FROM_TOUCH = 0x1, +}; +#endif /* QT_TOUCH_EXTENSION_FLAGS_ENUM */ + +struct qt_touch_extension_listener { + /** + * touch - (none) + * @time: (none) + * @id: (none) + * @state: (none) + * @x: (none) + * @y: (none) + * @normalized_x: (none) + * @normalized_y: (none) + * @width: (none) + * @height: (none) + * @pressure: (none) + * @velocity_x: (none) + * @velocity_y: (none) + * @flags: (none) + * @rawdata: (none) + */ + void (*touch)(void *data, + struct qt_touch_extension *qt_touch_extension, + uint32_t time, + uint32_t id, + uint32_t state, + int32_t x, + int32_t y, + int32_t normalized_x, + int32_t normalized_y, + int32_t width, + int32_t height, + uint32_t pressure, + int32_t velocity_x, + int32_t velocity_y, + uint32_t flags, + struct wl_array *rawdata); + /** + * configure - (none) + * @flags: (none) + */ + void (*configure)(void *data, + struct qt_touch_extension *qt_touch_extension, + uint32_t flags); +}; + +static inline int +qt_touch_extension_add_listener(struct qt_touch_extension *qt_touch_extension, + const struct qt_touch_extension_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) qt_touch_extension, + (void (**)(void)) listener, data); +} + +#define QT_TOUCH_EXTENSION_DUMMY 0 + +static inline void +qt_touch_extension_set_user_data(struct qt_touch_extension *qt_touch_extension, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) qt_touch_extension, user_data); +} + +static inline void * +qt_touch_extension_get_user_data(struct qt_touch_extension *qt_touch_extension) +{ + return wl_proxy_get_user_data((struct wl_proxy *) qt_touch_extension); +} + +static inline void +qt_touch_extension_destroy(struct qt_touch_extension *qt_touch_extension) +{ + wl_proxy_destroy((struct wl_proxy *) qt_touch_extension); +} + +static inline void +qt_touch_extension_dummy(struct qt_touch_extension *qt_touch_extension) +{ + wl_proxy_marshal((struct wl_proxy *) qt_touch_extension, + QT_TOUCH_EXTENSION_DUMMY); +} + + +/* wayland-qt-windowmanager.h */ + +extern const struct wl_interface qt_windowmanager_interface; + +struct qt_windowmanager_listener { + /** + * hints - (none) + * @show_is_fullscreen: (none) + */ + void (*hints)(void *data, + struct qt_windowmanager *qt_windowmanager, + int32_t show_is_fullscreen); + /** + * quit - (none) + */ + void (*quit)(void *data, + struct qt_windowmanager *qt_windowmanager); +}; + +static inline int +qt_windowmanager_add_listener(struct qt_windowmanager *qt_windowmanager, + const struct qt_windowmanager_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) qt_windowmanager, + (void (**)(void)) listener, data); +} + +#define QT_WINDOWMANAGER_OPEN_URL 0 + +static inline void +qt_windowmanager_set_user_data(struct qt_windowmanager *qt_windowmanager, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) qt_windowmanager, user_data); +} + +static inline void * +qt_windowmanager_get_user_data(struct qt_windowmanager *qt_windowmanager) +{ + return wl_proxy_get_user_data((struct wl_proxy *) qt_windowmanager); +} + +static inline void +qt_windowmanager_destroy(struct qt_windowmanager *qt_windowmanager) +{ + wl_proxy_destroy((struct wl_proxy *) qt_windowmanager); +} + +static inline void +qt_windowmanager_open_url(struct qt_windowmanager *qt_windowmanager, uint32_t remaining, const char *url) +{ + wl_proxy_marshal((struct wl_proxy *) qt_windowmanager, + QT_WINDOWMANAGER_OPEN_URL, remaining, url); +} + +#endif /* _SDL_waylandtouch_h */ + +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index e75bea1dc..5c845ac45 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -30,6 +30,7 @@ #include "SDL_waylandwindow.h" #include "SDL_waylandopengles.h" #include "SDL_waylandmouse.h" +#include "SDL_waylandtouch.h" #include #include @@ -202,6 +203,25 @@ static const struct wl_shm_listener shm_listener = { shm_handle_format }; +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH +static void +windowmanager_hints(void *data, struct qt_windowmanager *qt_windowmanager, + int32_t show_is_fullscreen) +{ +} + +static void +windowmanager_quit(void *data, struct qt_windowmanager *qt_windowmanager) +{ + SDL_SendQuit(); +} + +static const struct qt_windowmanager_listener windowmanager_listener = { + windowmanager_hints, + windowmanager_quit, +}; +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + static void display_handle_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) @@ -222,6 +242,18 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id, d->cursor_theme = wl_cursor_theme_load(NULL, 32, d->shm); d->default_cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr"); wl_shm_add_listener(d->shm, &shm_listener, d); + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + } else if (strcmp(interface, "qt_touch_extension") == 0) { + Wayland_touch_create(d, id); + } else if (strcmp(interface, "qt_surface_extension") == 0) { + d->surface_extension = wl_registry_bind(registry, id, + &qt_surface_extension_interface, 1); + } else if (strcmp(interface, "qt_windowmanager") == 0) { + d->windowmanager = wl_registry_bind(registry, id, + &qt_windowmanager_interface, 1); + qt_windowmanager_add_listener(d->windowmanager, &windowmanager_listener, d); +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ } } @@ -334,6 +366,15 @@ Wayland_VideoQuit(_THIS) xkb_context_unref(data->xkb_context); data->xkb_context = NULL; } +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + if (data->windowmanager) + qt_windowmanager_destroy(data->windowmanager); + + if (data->surface_extension) + qt_surface_extension_destroy(data->surface_extension); + + Wayland_touch_destroy(data); +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ if (data->shm) wl_shm_destroy(data->shm); diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h index ca1b66f4e..c44a26418 100644 --- a/src/video/wayland/SDL_waylandvideo.h +++ b/src/video/wayland/SDL_waylandvideo.h @@ -33,6 +33,12 @@ struct xkb_context; struct SDL_WaylandInput; +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH +struct SDL_WaylandTouch; +struct qt_surface_extension; +struct qt_windowmanager; +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + typedef struct { struct wl_display *display; struct wl_registry *registry; @@ -56,6 +62,12 @@ typedef struct { struct xkb_context *xkb_context; struct SDL_WaylandInput *input; + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + struct SDL_WaylandTouch *touch; + struct qt_surface_extension *surface_extension; + struct qt_windowmanager *windowmanager; +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ uint32_t shm_formats; } SDL_VideoData; diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index e530f5b80..f864520cf 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -26,6 +26,7 @@ #include "../SDL_egl_c.h" #include "SDL_waylandwindow.h" #include "SDL_waylandvideo.h" +#include "SDL_waylandtouch.h" static void handle_ping(void *data, struct wl_shell_surface *shell_surface, @@ -51,6 +52,34 @@ static const struct wl_shell_surface_listener shell_surface_listener = { handle_popup_done }; +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH +static void +handle_onscreen_visibility(void *data, + struct qt_extended_surface *qt_extended_surface, int32_t visible) +{ +} + +static void +handle_set_generic_property(void *data, + struct qt_extended_surface *qt_extended_surface, const char *name, + struct wl_array *value) +{ +} + +static void +handle_close(void *data, struct qt_extended_surface *qt_extended_surface) +{ + SDL_WindowData *window = (SDL_WindowData *)data; + SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0); +} + +static const struct qt_extended_surface_listener extended_surface_listener = { + handle_onscreen_visibility, + handle_set_generic_property, + handle_close, +}; +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + SDL_bool Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) { @@ -127,6 +156,12 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window) wl_surface_set_user_data(data->surface, data); data->shell_surface = wl_shell_get_shell_surface(c->shell, data->surface); +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + if (c->surface_extension) { + data->extended_surface = qt_surface_extension_get_extended_surface( + c->surface_extension, data->surface); + } +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ data->egl_window = wl_egl_window_create(data->surface, window->w, window->h); @@ -144,6 +179,14 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window) &shell_surface_listener, data); } +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + if (data->extended_surface) { + qt_extended_surface_set_user_data(data->extended_surface, data); + qt_extended_surface_add_listener(data->extended_surface, + &extended_surface_listener, data); + } +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + region = wl_compositor_create_region(c->compositor); wl_region_add(region, 0, 0, window->w, window->h); wl_surface_set_opaque_region(data->surface, region); @@ -182,6 +225,10 @@ void Wayland_DestroyWindow(_THIS, SDL_Window *window) if (wind->shell_surface) wl_shell_surface_destroy(wind->shell_surface); +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + if (wind->extended_surface) + qt_extended_surface_destroy(wind->extended_surface); +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ wl_surface_destroy(wind->surface); SDL_free(wind); diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h index f4f18361a..f65dc8fef 100644 --- a/src/video/wayland/SDL_waylandwindow.h +++ b/src/video/wayland/SDL_waylandwindow.h @@ -38,8 +38,11 @@ typedef struct { struct wl_shell_surface *shell_surface; struct wl_egl_window *egl_window; struct SDL_WaylandInput *keyboard_device; - EGLSurface egl_surface; + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + struct qt_extended_surface *extended_surface; +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ } SDL_WindowData; extern void Wayland_ShowWindow(_THIS, SDL_Window *window);