SDL_waylandwindow.c (8476B)
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21 22#include "../../SDL_internal.h" 23 24#if SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL 25 26#include "../SDL_sysvideo.h" 27#include "../../events/SDL_windowevents_c.h" 28#include "../SDL_egl_c.h" 29#include "SDL_waylandwindow.h" 30#include "SDL_waylandvideo.h" 31#include "SDL_waylandtouch.h" 32 33static void 34handle_ping(void *data, struct wl_shell_surface *shell_surface, 35 uint32_t serial) 36{ 37 wl_shell_surface_pong(shell_surface, serial); 38} 39 40static void 41handle_configure(void *data, struct wl_shell_surface *shell_surface, 42 uint32_t edges, int32_t width, int32_t height) 43{ 44 SDL_WindowData *wind = (SDL_WindowData *)data; 45 SDL_Window *window = wind->sdlwindow; 46 struct wl_region *region; 47 48 window->w = width; 49 window->h = height; 50 WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0); 51 52 region = wl_compositor_create_region(wind->waylandData->compositor); 53 wl_region_add(region, 0, 0, window->w, window->h); 54 wl_surface_set_opaque_region(wind->surface, region); 55 wl_region_destroy(region); 56 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, window->w, window->h); 57} 58 59static void 60handle_popup_done(void *data, struct wl_shell_surface *shell_surface) 61{ 62} 63 64static const struct wl_shell_surface_listener shell_surface_listener = { 65 handle_ping, 66 handle_configure, 67 handle_popup_done 68}; 69 70#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 71static void 72handle_onscreen_visibility(void *data, 73 struct qt_extended_surface *qt_extended_surface, int32_t visible) 74{ 75} 76 77static void 78handle_set_generic_property(void *data, 79 struct qt_extended_surface *qt_extended_surface, const char *name, 80 struct wl_array *value) 81{ 82} 83 84static void 85handle_close(void *data, struct qt_extended_surface *qt_extended_surface) 86{ 87 SDL_WindowData *window = (SDL_WindowData *)data; 88 SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0); 89} 90 91static const struct qt_extended_surface_listener extended_surface_listener = { 92 handle_onscreen_visibility, 93 handle_set_generic_property, 94 handle_close, 95}; 96#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ 97 98SDL_bool 99Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) 100{ 101 SDL_WindowData *data = (SDL_WindowData *) window->driverdata; 102 103 info->info.wl.display = data->waylandData->display; 104 info->info.wl.surface = data->surface; 105 info->info.wl.shell_surface = data->shell_surface; 106 info->subsystem = SDL_SYSWM_WAYLAND; 107 108 return SDL_TRUE; 109} 110 111void Wayland_ShowWindow(_THIS, SDL_Window *window) 112{ 113 SDL_WindowData *wind = window->driverdata; 114 115 if (window->flags & SDL_WINDOW_FULLSCREEN) 116 wl_shell_surface_set_fullscreen(wind->shell_surface, 117 WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 118 0, NULL); 119 else 120 wl_shell_surface_set_toplevel(wind->shell_surface); 121 122 WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); 123} 124 125void 126Wayland_SetWindowFullscreen(_THIS, SDL_Window * window, 127 SDL_VideoDisplay * _display, SDL_bool fullscreen) 128{ 129 SDL_WindowData *wind = window->driverdata; 130 131 if (fullscreen) 132 wl_shell_surface_set_fullscreen(wind->shell_surface, 133 WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 134 0, NULL); 135 else 136 wl_shell_surface_set_toplevel(wind->shell_surface); 137 138 WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); 139} 140 141int Wayland_CreateWindow(_THIS, SDL_Window *window) 142{ 143 SDL_WindowData *data; 144 SDL_VideoData *c; 145 struct wl_region *region; 146 147 data = calloc(1, sizeof *data); 148 if (data == NULL) 149 return 0; 150 151 c = _this->driverdata; 152 window->driverdata = data; 153 154 if (!(window->flags & SDL_WINDOW_OPENGL)) { 155 SDL_GL_LoadLibrary(NULL); 156 window->flags |= SDL_WINDOW_OPENGL; 157 } 158 159 if (window->x == SDL_WINDOWPOS_UNDEFINED) { 160 window->x = 0; 161 } 162 if (window->y == SDL_WINDOWPOS_UNDEFINED) { 163 window->y = 0; 164 } 165 166 data->waylandData = c; 167 data->sdlwindow = window; 168 169 data->surface = 170 wl_compositor_create_surface(c->compositor); 171 wl_surface_set_user_data(data->surface, data); 172 data->shell_surface = wl_shell_get_shell_surface(c->shell, 173 data->surface); 174#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 175 if (c->surface_extension) { 176 data->extended_surface = qt_surface_extension_get_extended_surface( 177 c->surface_extension, data->surface); 178 } 179#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ 180 181 /** 182 * If the user specified 0x0 as the size (turned to 1x1 by SDL_CreateWindow 183 * in SDL_video.c), we want to make the window fill the whole screen 184 **/ 185 if (window->w == 1) { 186 window->w = c->screen_allocation.width; 187 } 188 if (window->h == 1) { 189 window->h = c->screen_allocation.height; 190 } 191 192 data->egl_window = WAYLAND_wl_egl_window_create(data->surface, 193 window->w, window->h); 194 195 /* Create the GLES window surface */ 196 data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window); 197 198 if (data->egl_surface == EGL_NO_SURFACE) { 199 SDL_SetError("failed to create a window surface"); 200 return -1; 201 } 202 203 if (data->shell_surface) { 204 wl_shell_surface_set_user_data(data->shell_surface, data); 205 wl_shell_surface_add_listener(data->shell_surface, 206 &shell_surface_listener, data); 207 } 208 209#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 210 if (data->extended_surface) { 211 qt_extended_surface_set_user_data(data->extended_surface, data); 212 qt_extended_surface_add_listener(data->extended_surface, 213 &extended_surface_listener, data); 214 } 215#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ 216 217 region = wl_compositor_create_region(c->compositor); 218 wl_region_add(region, 0, 0, window->w, window->h); 219 wl_surface_set_opaque_region(data->surface, region); 220 wl_region_destroy(region); 221 222 WAYLAND_wl_display_flush(c->display); 223 224 return 0; 225} 226 227void Wayland_SetWindowSize(_THIS, SDL_Window * window) 228{ 229 SDL_VideoData *data = _this->driverdata; 230 SDL_WindowData *wind = window->driverdata; 231 struct wl_region *region; 232 233 WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0); 234 235 region =wl_compositor_create_region(data->compositor); 236 wl_region_add(region, 0, 0, window->w, window->h); 237 wl_surface_set_opaque_region(wind->surface, region); 238 wl_region_destroy(region); 239} 240 241void Wayland_DestroyWindow(_THIS, SDL_Window *window) 242{ 243 SDL_VideoData *data = _this->driverdata; 244 SDL_WindowData *wind = window->driverdata; 245 246 if (data) { 247 SDL_EGL_DestroySurface(_this, wind->egl_surface); 248 WAYLAND_wl_egl_window_destroy(wind->egl_window); 249 250 if (wind->shell_surface) 251 wl_shell_surface_destroy(wind->shell_surface); 252 253#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 254 if (wind->extended_surface) 255 qt_extended_surface_destroy(wind->extended_surface); 256#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ 257 wl_surface_destroy(wind->surface); 258 259 SDL_free(wind); 260 WAYLAND_wl_display_flush(data->display); 261 } 262 window->driverdata = NULL; 263} 264 265#endif /* SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL */ 266 267/* vi: set ts=4 sw=4 expandtab: */