SDL  2.0
SDL_waylandwindow.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 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 #include "SDL_waylanddyn.h"
33 
34 static void
35 handle_ping(void *data, struct wl_shell_surface *shell_surface,
36  uint32_t serial)
37 {
38  wl_shell_surface_pong(shell_surface, serial);
39 }
40 
41 static void
42 handle_configure(void *data, struct wl_shell_surface *shell_surface,
44 {
45  SDL_WindowData *wind = (SDL_WindowData *)data;
46  SDL_Window *window = wind->sdlwindow;
47  struct wl_region *region;
48 
49  window->w = width;
50  window->h = height;
51  WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
52 
53  region = wl_compositor_create_region(wind->waylandData->compositor);
54  wl_region_add(region, 0, 0, window->w, window->h);
55  wl_surface_set_opaque_region(wind->surface, region);
56  wl_region_destroy(region);
57  SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, window->w, window->h);
58 }
59 
60 static void
61 handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
62 {
63 }
64 
65 static const struct wl_shell_surface_listener shell_surface_listener = {
66  handle_ping,
67  handle_configure,
68  handle_popup_done
69 };
70 
71 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
72 static void
73 handle_onscreen_visibility(void *data,
74  struct qt_extended_surface *qt_extended_surface, int32_t visible)
75 {
76 }
77 
78 static void
79 handle_set_generic_property(void *data,
80  struct qt_extended_surface *qt_extended_surface, const char *name,
81  struct wl_array *value)
82 {
83 }
84 
85 static void
86 handle_close(void *data, struct qt_extended_surface *qt_extended_surface)
87 {
90 }
91 
92 static const struct qt_extended_surface_listener extended_surface_listener = {
93  handle_onscreen_visibility,
94  handle_set_generic_property,
95  handle_close,
96 };
97 #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
98 
101 {
103 
104  info->info.wl.display = data->waylandData->display;
105  info->info.wl.surface = data->surface;
106  info->info.wl.shell_surface = data->shell_surface;
108 
109  return SDL_TRUE;
110 }
111 
112 int
114 {
115  return 0; /* just succeed, the real work is done elsewhere. */
116 }
117 
119 {
120  SDL_WindowData *wind = window->driverdata;
121 
122  if (window->flags & SDL_WINDOW_FULLSCREEN)
123  wl_shell_surface_set_fullscreen(wind->shell_surface,
124  WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
125  0, (struct wl_output *)window->fullscreen_mode.driverdata);
126  else
127  wl_shell_surface_set_toplevel(wind->shell_surface);
128 
129  WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
130 }
131 
132 void
134  SDL_VideoDisplay * _display, SDL_bool fullscreen)
135 {
136  SDL_WindowData *wind = window->driverdata;
137 
138  if (fullscreen)
139  wl_shell_surface_set_fullscreen(wind->shell_surface,
140  WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE,
141  0, (struct wl_output *)_display->driverdata);
142  else
143  wl_shell_surface_set_toplevel(wind->shell_surface);
144 
145  WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
146 }
147 
149 {
151  SDL_VideoData *c;
152  struct wl_region *region;
153 
154  data = calloc(1, sizeof *data);
155  if (data == NULL)
156  return SDL_OutOfMemory();
157 
158  c = _this->driverdata;
159  window->driverdata = data;
160 
161  if (!(window->flags & SDL_WINDOW_OPENGL)) {
163  window->flags |= SDL_WINDOW_OPENGL;
164  }
165 
166  if (window->x == SDL_WINDOWPOS_UNDEFINED) {
167  window->x = 0;
168  }
169  if (window->y == SDL_WINDOWPOS_UNDEFINED) {
170  window->y = 0;
171  }
172 
173  data->waylandData = c;
174  data->sdlwindow = window;
175 
176  data->surface =
177  wl_compositor_create_surface(c->compositor);
178  wl_surface_set_user_data(data->surface, data);
179  data->shell_surface = wl_shell_get_shell_surface(c->shell,
180  data->surface);
181 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
182  if (c->surface_extension) {
183  data->extended_surface = qt_surface_extension_get_extended_surface(
184  c->surface_extension, data->surface);
185  }
186 #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
187 
188  data->egl_window = WAYLAND_wl_egl_window_create(data->surface,
189  window->w, window->h);
190 
191  /* Create the GLES window surface */
192  data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window);
193 
194  if (data->egl_surface == EGL_NO_SURFACE) {
195  return SDL_SetError("failed to create a window surface");
196  }
197 
198  if (data->shell_surface) {
199  wl_shell_surface_set_user_data(data->shell_surface, data);
200  wl_shell_surface_add_listener(data->shell_surface,
201  &shell_surface_listener, data);
202  }
203 
204 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
205  if (data->extended_surface) {
206  qt_extended_surface_set_user_data(data->extended_surface, data);
207  qt_extended_surface_add_listener(data->extended_surface,
208  &extended_surface_listener, data);
209  }
210 #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
211 
212  region = wl_compositor_create_region(c->compositor);
213  wl_region_add(region, 0, 0, window->w, window->h);
214  wl_surface_set_opaque_region(data->surface, region);
215  wl_region_destroy(region);
216 
217  WAYLAND_wl_display_flush(c->display);
218 
219  return 0;
220 }
221 
222 void Wayland_SetWindowSize(_THIS, SDL_Window * window)
223 {
224  SDL_VideoData *data = _this->driverdata;
225  SDL_WindowData *wind = window->driverdata;
226  struct wl_region *region;
227 
228  WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
229 
230  region =wl_compositor_create_region(data->compositor);
231  wl_region_add(region, 0, 0, window->w, window->h);
232  wl_surface_set_opaque_region(wind->surface, region);
233  wl_region_destroy(region);
234 }
235 
237 {
238  SDL_VideoData *data = _this->driverdata;
239  SDL_WindowData *wind = window->driverdata;
240 
241  if (data) {
242  SDL_EGL_DestroySurface(_this, wind->egl_surface);
243  WAYLAND_wl_egl_window_destroy(wind->egl_window);
244 
245  if (wind->shell_surface)
246  wl_shell_surface_destroy(wind->shell_surface);
247 
248 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
249  if (wind->extended_surface)
250  qt_extended_surface_destroy(wind->extended_surface);
251 #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
252  wl_surface_destroy(wind->surface);
253 
254  SDL_free(wind);
255  WAYLAND_wl_display_flush(data->display);
256  }
257  window->driverdata = NULL;
258 }
259 
260 #endif /* SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL */
261 
262 /* vi: set ts=4 sw=4 expandtab: */
void Wayland_SetWindowSize(_THIS, SDL_Window *window)
void Wayland_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *_display, SDL_bool fullscreen)
SDL_DisplayMode fullscreen_mode
Definition: SDL_sysvideo.h:87
Display * display
Definition: SDL_syswm.h:203
signed int int32_t
int Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
struct wl_display * display
SDL_Window * window
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1967
void Wayland_ShowWindow(_THIS, SDL_Window *window)
GLint GLint GLsizei width
Definition: SDL_opengl.h:1565
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:184
#define SDL_WINDOWPOS_UNDEFINED
Definition: SDL_video.h:120
GLuint const GLchar * name
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
#define SDL_GL_LoadLibrary
int Wayland_CreateWindow(_THIS, SDL_Window *window)
#define calloc
Definition: SDL_malloc.c:642
SDL_Surface * surface
static SDL_VideoDevice * _this
Definition: SDL_video.c:114
SDL_bool
Definition: SDL_stdinc.h:126
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1565
void Wayland_DestroyWindow(_THIS, SDL_Window *window)
GLsizei const GLfloat * value
#define _THIS
void SDL_free(void *mem)
void * driverdata
Definition: SDL_video.h:59
SDL_Window * sdlwindow
struct wl_shell_surface * shell_surface
SDL_bool Wayland_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
struct wl_shell * shell
SDL_VideoData * waylandData
const GLubyte * c
GLenum GLenum GLsizei const GLuint GLboolean enabled
#define NULL
Definition: begin_code.h:143
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
unsigned int uint32_t
#define SDL_SetError
struct wl_compositor * compositor
The type used to identify a window.
Definition: SDL_sysvideo.h:71
union SDL_SysWMinfo::@18 info
void * driverdata
Definition: SDL_sysvideo.h:106
Uint32 flags
Definition: SDL_sysvideo.h:81
EGLSurface egl_surface
struct wl_egl_window * egl_window