SDL 2.0
SDL_waylandwindow.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 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_waylandevents_c.h"
30#include "SDL_waylandwindow.h"
31#include "SDL_waylandvideo.h"
32#include "SDL_waylandtouch.h"
33#include "SDL_waylanddyn.h"
34#include "SDL_hints.h"
35
40
41static float get_window_scale_factor(SDL_Window *window) {
42 return ((SDL_WindowData*)window->driverdata)->scale_factor;
43}
44
45/* On modern desktops, we probably will use the xdg-shell protocol instead
46 of wl_shell, but wl_shell might be useful on older Wayland installs that
47 don't have the newer protocol, or embedded things that don't have a full
48 window manager. */
49
50static void
51handle_ping_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface,
52 uint32_t serial)
53{
54 wl_shell_surface_pong(shell_surface, serial);
55}
56
57static void
58handle_configure_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface,
60{
63
64 /* wl_shell_surface spec states that this is a suggestion.
65 Ignore if less than or greater than max/min size. */
66
67 if (width == 0 || height == 0) {
68 return;
69 }
70
71 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
72 if ((window->flags & SDL_WINDOW_RESIZABLE)) {
73 if (window->max_w > 0) {
74 width = SDL_min(width, window->max_w);
75 }
76 width = SDL_max(width, window->min_w);
77
78 if (window->max_h > 0) {
79 height = SDL_min(height, window->max_h);
80 }
81 height = SDL_max(height, window->min_h);
82 } else {
83 return;
84 }
85 }
86
87 wind->resize.width = width;
88 wind->resize.height = height;
89 wind->resize.pending = SDL_TRUE;
90}
91
92static void
93handle_popup_done_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface)
94{
95}
96
97static const struct wl_shell_surface_listener shell_surface_listener_wl = {
98 handle_ping_wl_shell_surface,
99 handle_configure_wl_shell_surface,
100 handle_popup_done_wl_shell_surface
101};
102
103
104
105
106static void
107handle_configure_zxdg_shell_surface(void *data, struct zxdg_surface_v6 *zxdg, uint32_t serial)
108{
110 SDL_Window *window = wind->sdlwindow;
111 struct wl_region *region;
112
114 window->w = 0;
115 window->h = 0;
117 window->w = wind->resize.width;
118 window->h = wind->resize.height;
119
120 wl_surface_set_buffer_scale(wind->surface, get_window_scale_factor(window));
121 WAYLAND_wl_egl_window_resize(wind->egl_window, window->w * get_window_scale_factor(window), window->h * get_window_scale_factor(window), 0, 0);
122
123 zxdg_surface_v6_ack_configure(zxdg, serial);
124
126 wl_region_add(region, 0, 0, window->w, window->h);
128 wl_region_destroy(region);
129
131 } else {
132 wind->resize.pending = SDL_TRUE;
133 wind->resize.configure = SDL_TRUE;
134 wind->resize.serial = serial;
135 }
136}
137
138static const struct zxdg_surface_v6_listener shell_surface_listener_zxdg = {
139 handle_configure_zxdg_shell_surface
140};
141
142
143static void
144handle_configure_zxdg_toplevel(void *data,
145 struct zxdg_toplevel_v6 *zxdg_toplevel_v6,
148 struct wl_array *states)
149{
151 SDL_Window *window = wind->sdlwindow;
152
154 SDL_bool fullscreen = SDL_FALSE;
155 wl_array_for_each(state, states) {
157 fullscreen = SDL_TRUE;
158 }
159 }
160
161 if (!fullscreen) {
162 if (width == 0 || height == 0) {
163 width = window->windowed.w;
164 height = window->windowed.h;
165 }
166
167 /* zxdg_toplevel spec states that this is a suggestion.
168 Ignore if less than or greater than max/min size. */
169
170 if ((window->flags & SDL_WINDOW_RESIZABLE)) {
171 if (window->max_w > 0) {
172 width = SDL_min(width, window->max_w);
173 }
174 width = SDL_max(width, window->min_w);
175
176 if (window->max_h > 0) {
177 height = SDL_min(height, window->max_h);
178 }
179 height = SDL_max(height, window->min_h);
180 } else {
181 wind->resize.width = window->w;
182 wind->resize.height = window->h;
183 return;
184 }
185 }
186
187 if (width == 0 || height == 0) {
188 wind->resize.width = window->w;
189 wind->resize.height = window->h;
190 return;
191 }
192
193 wind->resize.width = width;
194 wind->resize.height = height;
195}
196
197static void
198handle_close_zxdg_toplevel(void *data, struct zxdg_toplevel_v6 *zxdg_toplevel_v6)
199{
202}
203
204static const struct zxdg_toplevel_v6_listener toplevel_listener_zxdg = {
205 handle_configure_zxdg_toplevel,
206 handle_close_zxdg_toplevel
207};
208
209
210
211static void
212handle_configure_xdg_shell_surface(void *data, struct xdg_surface *xdg, uint32_t serial)
213{
215 SDL_Window *window = wind->sdlwindow;
216 struct wl_region *region;
217
219 window->w = 0;
220 window->h = 0;
222 window->w = wind->resize.width;
223 window->h = wind->resize.height;
224
225 wl_surface_set_buffer_scale(wind->surface, get_window_scale_factor(window));
226 WAYLAND_wl_egl_window_resize(wind->egl_window, window->w * get_window_scale_factor(window), window->h * get_window_scale_factor(window), 0, 0);
227
228 xdg_surface_ack_configure(xdg, serial);
229
231 wl_region_add(region, 0, 0, window->w, window->h);
233 wl_region_destroy(region);
234
236 } else {
237 wind->resize.pending = SDL_TRUE;
238 wind->resize.configure = SDL_TRUE;
239 wind->resize.serial = serial;
240 }
241}
242
243static const struct xdg_surface_listener shell_surface_listener_xdg = {
244 handle_configure_xdg_shell_surface
245};
246
247
248static void
249handle_configure_xdg_toplevel(void *data,
250 struct xdg_toplevel *xdg_toplevel,
253 struct wl_array *states)
254{
256 SDL_Window *window = wind->sdlwindow;
257
259 SDL_bool fullscreen = SDL_FALSE;
260 wl_array_for_each(state, states) {
262 fullscreen = SDL_TRUE;
263 }
264 }
265
266 if (!fullscreen) {
267 if (width == 0 || height == 0) {
268 width = window->windowed.w;
269 height = window->windowed.h;
270 }
271
272 /* xdg_toplevel spec states that this is a suggestion.
273 Ignore if less than or greater than max/min size. */
274
275 if ((window->flags & SDL_WINDOW_RESIZABLE)) {
276 if (window->max_w > 0) {
277 width = SDL_min(width, window->max_w);
278 }
279 width = SDL_max(width, window->min_w);
280
281 if (window->max_h > 0) {
282 height = SDL_min(height, window->max_h);
283 }
284 height = SDL_max(height, window->min_h);
285 } else {
286 wind->resize.width = window->w;
287 wind->resize.height = window->h;
288 return;
289 }
290 }
291
292 if (width == 0 || height == 0) {
293 wind->resize.width = window->w;
294 wind->resize.height = window->h;
295 return;
296 }
297
298 wind->resize.width = width;
299 wind->resize.height = height;
300}
301
302static void
303handle_close_xdg_toplevel(void *data, struct xdg_toplevel *xdg_toplevel)
304{
307}
308
309static const struct xdg_toplevel_listener toplevel_listener_xdg = {
310 handle_configure_xdg_toplevel,
311 handle_close_xdg_toplevel
312};
313
314
315
316
317#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
318static void
319handle_onscreen_visibility(void *data,
320 struct qt_extended_surface *qt_extended_surface, int32_t visible)
321{
322}
323
324static void
325handle_set_generic_property(void *data,
326 struct qt_extended_surface *qt_extended_surface, const char *name,
327 struct wl_array *value)
328{
329}
330
331static void
332handle_close(void *data, struct qt_extended_surface *qt_extended_surface)
333{
336}
337
338static const struct qt_extended_surface_listener extended_surface_listener = {
339 handle_onscreen_visibility,
340 handle_set_generic_property,
341 handle_close,
342};
343#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
344
345static void
346update_scale_factor(SDL_WindowData *window) {
347 float old_factor = window->scale_factor, new_factor = 0.0;
348 int i;
349
350 if (!(window->sdlwindow->flags & SDL_WINDOW_ALLOW_HIGHDPI)) {
351 return;
352 }
353
354 if (!window->num_outputs) {
355 new_factor = old_factor;
356 }
357
358 if (FULLSCREEN_VISIBLE(window->sdlwindow) && window->sdlwindow->fullscreen_mode.driverdata) {
359 new_factor = ((SDL_WaylandOutputData*)(wl_output_get_user_data(window->sdlwindow->fullscreen_mode.driverdata)))->scale_factor;
360 }
361
362 for (i = 0; i < window->num_outputs; i++) {
363 float factor = ((SDL_WaylandOutputData*)(wl_output_get_user_data(window->outputs[i])))->scale_factor;
364 if (factor > new_factor) {
365 new_factor = factor;
366 }
367 }
368
369 if (new_factor != old_factor) {
370 /* force the resize event to trigger, as the logical size didn't change */
371 window->resize.width = window->sdlwindow->w;
372 window->resize.height = window->sdlwindow->h;
373 window->resize.scale_factor = new_factor;
374 window->resize.pending = SDL_TRUE;
375 }
376}
377
378static void
379handle_surface_enter(void *data, struct wl_surface *surface,
380 struct wl_output *output) {
382
383 window->outputs = SDL_realloc(window->outputs, (window->num_outputs + 1) * sizeof *window->outputs);
384 window->outputs[window->num_outputs++] = output;
385 update_scale_factor(window);
386}
387
388static void
389handle_surface_leave(void *data, struct wl_surface *surface,
390 struct wl_output *output) {
392 int i;
393
394 if (window->num_outputs > 1) {
395 struct wl_output **new_outputs = SDL_malloc((window->num_outputs - 1) * sizeof *window->outputs), **iter = new_outputs;
396 for (i=0; i < window->num_outputs; i++) {
397 if (window->outputs[i] != output) {
398 *iter = window->outputs[i];
399 iter++;
400 }
401 }
402 SDL_free(window->outputs);
403 window->outputs = new_outputs;
404 window->num_outputs--;
405 } else {
406 window->num_outputs = 0;
407 SDL_free(window->outputs);
408 window->outputs = NULL;
409 }
410
411 update_scale_factor(window);
412}
413
414static const struct wl_surface_listener surface_listener = {
415 handle_surface_enter,
416 handle_surface_leave
417};
418
421{
422 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
423 const Uint32 version = ((((Uint32) info->version.major) * 1000000) +
424 (((Uint32) info->version.minor) * 10000) +
425 (((Uint32) info->version.patch)));
426
427 /* Before 2.0.6, it was possible to build an SDL with Wayland support
428 (SDL_SysWMinfo will be large enough to hold Wayland info), but build
429 your app against SDL headers that didn't have Wayland support
430 (SDL_SysWMinfo could be smaller than Wayland needs. This would lead
431 to an app properly using SDL_GetWindowWMInfo() but we'd accidentally
432 overflow memory on the stack or heap. To protect against this, we've
433 padded out the struct unconditionally in the headers and Wayland will
434 just return an error for older apps using this function. Those apps
435 will need to be recompiled against newer headers or not use Wayland,
436 maybe by forcing SDL_VIDEODRIVER=x11. */
437 if (version < 2000006) {
439 SDL_SetError("Version must be 2.0.6 or newer");
440 return SDL_FALSE;
441 }
442
443 info->info.wl.display = data->waylandData->display;
444 info->info.wl.surface = data->surface;
445 info->info.wl.shell_surface = data->shell_surface.wl;
447
448 return SDL_TRUE;
449}
450
451int
453{
454 return 0; /* just succeed, the real work is done elsewhere. */
455}
456
457static void
458SetFullscreen(_THIS, SDL_Window * window, struct wl_output *output)
459{
460 const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata;
461 SDL_WindowData *wind = window->driverdata;
462
463 if (viddata->shell.xdg) {
464 if (output) {
466 } else {
468 }
469 } else if (viddata->shell.zxdg) {
470 if (output) {
472 } else {
474 }
475 } else {
476 if (output) {
479 0, output);
480 } else {
482 }
483 }
484
485 WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
486}
487
489{
490 struct wl_output *output = (struct wl_output *) window->fullscreen_mode.driverdata;
491 SetFullscreen(_this, window, (window->flags & SDL_WINDOW_FULLSCREEN) ? output : NULL);
492}
493
494#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
495static void SDLCALL
496QtExtendedSurface_OnHintChanged(void *userdata, const char *name,
497 const char *oldValue, const char *newValue)
498{
499 struct qt_extended_surface *qt_extended_surface = userdata;
500
501 if (name == NULL) {
502 return;
503 }
504
506 int32_t orientation = QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION;
507
508 if (newValue != NULL) {
509 if (strcmp(newValue, "portrait") == 0) {
510 orientation = QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION;
511 } else if (strcmp(newValue, "landscape") == 0) {
512 orientation = QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION;
513 } else if (strcmp(newValue, "inverted-portrait") == 0) {
514 orientation = QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION;
515 } else if (strcmp(newValue, "inverted-landscape") == 0) {
516 orientation = QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION;
517 }
518 }
519
520 qt_extended_surface_set_content_orientation(qt_extended_surface, orientation);
521 } else if (strcmp(name, SDL_HINT_QTWAYLAND_WINDOW_FLAGS) == 0) {
522 uint32_t flags = 0;
523
524 if (newValue != NULL) {
525 char *tmp = strdup(newValue);
526 char *saveptr = NULL;
527
528 char *flag = strtok_r(tmp, " ", &saveptr);
529 while (flag) {
530 if (strcmp(flag, "OverridesSystemGestures") == 0) {
531 flags |= QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES;
532 } else if (strcmp(flag, "StaysOnTop") == 0) {
533 flags |= QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP;
534 } else if (strcmp(flag, "BypassWindowManager") == 0) {
535 // See https://github.com/qtproject/qtwayland/commit/fb4267103d
536 flags |= 4 /* QT_EXTENDED_SURFACE_WINDOWFLAG_BYPASSWINDOWMANAGER */;
537 }
538
539 flag = strtok_r(NULL, " ", &saveptr);
540 }
541
542 free(tmp);
543 }
544
545 qt_extended_surface_set_window_flags(qt_extended_surface, flags);
546 }
547}
548
549static void QtExtendedSurface_Subscribe(struct qt_extended_surface *surface, const char *name)
550{
551 SDL_AddHintCallback(name, QtExtendedSurface_OnHintChanged, surface);
552}
553
554static void QtExtendedSurface_Unsubscribe(struct qt_extended_surface *surface, const char *name)
555{
556 SDL_DelHintCallback(name, QtExtendedSurface_OnHintChanged, surface);
557}
558#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
559
560void
562 SDL_VideoDisplay * _display, SDL_bool fullscreen)
563{
564 struct wl_output *output = ((SDL_WaylandOutputData*) _display->driverdata)->output;
565 SetFullscreen(_this, window, fullscreen ? output : NULL);
566}
567
568void
570{
571 SDL_WindowData *wind = window->driverdata;
572 const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata;
573
574 if (viddata->shell.xdg) {
575 } else if (viddata->shell.zxdg) {
576 } else {
578 }
579
580 WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
581}
582
583void
585{
586 SDL_WindowData *wind = window->driverdata;
587 const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata;
588 if ((viddata->decoration_manager) && (wind->server_decoration)) {
591 } else if ((viddata->kwin_server_decoration_manager) && (wind->kwin_server_decoration)) {
594 }
595}
596
597void
599{
600 SDL_WindowData *wind = window->driverdata;
602
603 if (viddata->shell.xdg) {
605 } else if (viddata->shell.zxdg) {
607 } else {
609 }
610
611 WAYLAND_wl_display_flush( viddata->display );
612}
613
615{
618 struct wl_region *region;
619
620 data = calloc(1, sizeof *data);
621 if (data == NULL)
622 return SDL_OutOfMemory();
623
624 c = _this->driverdata;
625 window->driverdata = data;
626
627 if (!(window->flags & SDL_WINDOW_OPENGL)) {
629 window->flags |= SDL_WINDOW_OPENGL;
630 }
631
633 window->x = 0;
634 }
636 window->y = 0;
637 }
638
639 data->waylandData = c;
640 data->sdlwindow = window;
641
642 data->scale_factor = 1.0;
643
644 if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
645 int i;
646 for (i=0; i < SDL_GetVideoDevice()->num_displays; i++) {
648 if (scale > data->scale_factor) {
649 data->scale_factor = scale;
650 }
651 }
652 }
653
654 data->resize.pending = SDL_FALSE;
655 data->resize.width = window->w;
656 data->resize.height = window->h;
657 data->resize.scale_factor = data->scale_factor;
658
659 data->outputs = NULL;
660 data->num_outputs = 0;
661
662 data->surface =
663 wl_compositor_create_surface(c->compositor);
664 wl_surface_add_listener(data->surface, &surface_listener, data);
665
666 if (c->shell.xdg) {
667 data->shell_surface.xdg.surface = xdg_wm_base_get_xdg_surface(c->shell.xdg, data->surface);
668 /* !!! FIXME: add popup role */
669 data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface);
670 xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data);
671 xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname);
672 } else if (c->shell.zxdg) {
673 data->shell_surface.zxdg.surface = zxdg_shell_v6_get_xdg_surface(c->shell.zxdg, data->surface);
674 /* !!! FIXME: add popup role */
675 data->shell_surface.zxdg.roleobj.toplevel = zxdg_surface_v6_get_toplevel(data->shell_surface.zxdg.surface);
676 zxdg_toplevel_v6_add_listener(data->shell_surface.zxdg.roleobj.toplevel, &toplevel_listener_zxdg, data);
677 zxdg_toplevel_v6_set_app_id(data->shell_surface.zxdg.roleobj.toplevel, c->classname);
678 } else {
679 data->shell_surface.wl = wl_shell_get_shell_surface(c->shell.wl, data->surface);
680 wl_shell_surface_set_class(data->shell_surface.wl, c->classname);
681 }
682
683#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
684 if (c->surface_extension) {
685 data->extended_surface = qt_surface_extension_get_extended_surface(
686 c->surface_extension, data->surface);
687
688 QtExtendedSurface_Subscribe(data->extended_surface, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION);
689 QtExtendedSurface_Subscribe(data->extended_surface, SDL_HINT_QTWAYLAND_WINDOW_FLAGS);
690 }
691#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
692
693 data->egl_window = WAYLAND_wl_egl_window_create(data->surface,
694 window->w * data->scale_factor, window->h * data->scale_factor);
695
696 /* Create the GLES window surface */
697 data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window);
698
699 if (data->egl_surface == EGL_NO_SURFACE) {
700 return SDL_SetError("failed to create a window surface");
701 }
702
703 if (c->shell.xdg) {
704 if (data->shell_surface.xdg.surface) {
705 xdg_surface_set_user_data(data->shell_surface.xdg.surface, data);
706 xdg_surface_add_listener(data->shell_surface.xdg.surface, &shell_surface_listener_xdg, data);
707 }
708 } else if (c->shell.zxdg) {
709 if (data->shell_surface.zxdg.surface) {
710 zxdg_surface_v6_set_user_data(data->shell_surface.zxdg.surface, data);
711 zxdg_surface_v6_add_listener(data->shell_surface.zxdg.surface, &shell_surface_listener_zxdg, data);
712 }
713 } else {
714 if (data->shell_surface.wl) {
715 wl_shell_surface_set_user_data(data->shell_surface.wl, data);
716 wl_shell_surface_add_listener(data->shell_surface.wl, &shell_surface_listener_wl, data);
717 }
718 }
719
720#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
721 if (data->extended_surface) {
722 qt_extended_surface_set_user_data(data->extended_surface, data);
723 qt_extended_surface_add_listener(data->extended_surface,
724 &extended_surface_listener, data);
725 }
726#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
727
728 if (c->decoration_manager && c->shell.xdg && data->shell_surface.xdg.surface) {
729 data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel);
730 if (data->server_decoration) {
731 const SDL_bool bordered = (window->flags & SDL_WINDOW_BORDERLESS) == 0;
734 }
735 } else if (c->kwin_server_decoration_manager) {
736 data->kwin_server_decoration = org_kde_kwin_server_decoration_manager_create(c->kwin_server_decoration_manager, data->surface);
737 if (data->kwin_server_decoration) {
738 const SDL_bool bordered = (window->flags & SDL_WINDOW_BORDERLESS) == 0;
740 org_kde_kwin_server_decoration_request_mode(data->kwin_server_decoration, mode);
741 }
742 }
743
744 region = wl_compositor_create_region(c->compositor);
745 wl_region_add(region, 0, 0, window->w, window->h);
746 wl_surface_set_opaque_region(data->surface, region);
747 wl_region_destroy(region);
748
749 if (c->relative_mouse_mode) {
751 }
752
753 wl_surface_commit(data->surface);
754 WAYLAND_wl_display_flush(c->display);
755
756 /* we have to wait until the surface gets a "configure" event, or
757 use of this surface will fail. This is a new rule for xdg_shell. */
758 if (c->shell.xdg) {
759 if (data->shell_surface.xdg.surface) {
760 while (!data->shell_surface.xdg.initial_configure_seen) {
761 WAYLAND_wl_display_flush(c->display);
762 WAYLAND_wl_display_dispatch(c->display);
763 }
764 }
765 } else if (c->shell.zxdg) {
766 if (data->shell_surface.zxdg.surface) {
767 while (!data->shell_surface.zxdg.initial_configure_seen) {
768 WAYLAND_wl_display_flush(c->display);
769 WAYLAND_wl_display_dispatch(c->display);
770 }
771 }
772 }
773
774 return 0;
775}
776
778{
780 SDL_WindowData *wind = window->driverdata;
781 struct wl_region *region;
782
783 wl_surface_set_buffer_scale(wind->surface, get_window_scale_factor(window));
784 WAYLAND_wl_egl_window_resize(wind->egl_window, window->w * get_window_scale_factor(window), window->h * get_window_scale_factor(window), 0, 0);
785
786 region = wl_compositor_create_region(data->compositor);
787 wl_region_add(region, 0, 0, window->w, window->h);
789 wl_region_destroy(region);
790}
791
793{
794 SDL_WindowData *wind = window->driverdata;
796
797 if (window->title != NULL) {
798 if (viddata->shell.xdg) {
800 } else if (viddata->shell.zxdg) {
802 } else {
804 }
805 }
806
807 WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
808}
809
811{
813 SDL_WindowData *wind = window->driverdata;
814
815 if (data) {
816 SDL_EGL_DestroySurface(_this, wind->egl_surface);
817 WAYLAND_wl_egl_window_destroy(wind->egl_window);
818
819 if (wind->server_decoration) {
821 }
822
823 if (wind->kwin_server_decoration) {
825 }
826
827 if (data->shell.xdg) {
828 if (wind->shell_surface.xdg.roleobj.toplevel) {
830 }
831 if (wind->shell_surface.zxdg.surface) {
833 }
834 } else if (data->shell.zxdg) {
837 }
838 if (wind->shell_surface.zxdg.surface) {
840 }
841 } else {
842 if (wind->shell_surface.wl) {
844 }
845 }
846
847#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
848 if (wind->extended_surface) {
849 QtExtendedSurface_Unsubscribe(wind->extended_surface, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION);
850 QtExtendedSurface_Unsubscribe(wind->extended_surface, SDL_HINT_QTWAYLAND_WINDOW_FLAGS);
851 qt_extended_surface_destroy(wind->extended_surface);
852 }
853#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
855
856 SDL_free(wind);
857 WAYLAND_wl_display_flush(data->display);
858 }
859 window->driverdata = NULL;
860}
861
862#endif /* SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL */
863
864/* vi: set ts=4 sw=4 expandtab: */
#define _THIS
unsigned int uint32_t
signed int int32_t
#define SDL_SetError
#define SDL_DelHintCallback
#define SDL_GL_LoadLibrary
#define SDL_malloc
#define SDL_realloc
#define SDL_free
#define SDL_AddHintCallback
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_EventEntry * free
Definition: SDL_events.c:82
#define SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION
A variable describing the content orientation on QtWayland-based platforms.
Definition: SDL_hints.h:622
#define SDL_HINT_QTWAYLAND_WINDOW_FLAGS
Flags to set on QtWayland windows to integrate with the native window manager.
Definition: SDL_hints.h:633
#define SDLCALL
Definition: SDL_internal.h:49
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLenum mode
GLenum GLenum GLenum GLenum GLenum scale
const GLubyte * c
GLuint const GLchar * name
GLbitfield flags
GLsizei const GLfloat * value
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
uint32_t Uint32
Definition: SDL_stdinc.h:203
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
#define SDL_max(x, y)
Definition: SDL_stdinc.h:407
#define FULLSCREEN_VISIBLE(W)
Definition: SDL_sysvideo.h:116
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:583
@ SDL_SYSWM_UNKNOWN
Definition: SDL_syswm.h:121
@ SDL_SYSWM_WAYLAND
Definition: SDL_syswm.h:127
static SDL_VideoDevice * _this
Definition: SDL_video.c:118
#define SDL_WINDOWPOS_UNDEFINED
Definition: SDL_video.h:130
@ SDL_WINDOW_ALLOW_HIGHDPI
Definition: SDL_video.h:113
@ SDL_WINDOW_OPENGL
Definition: SDL_video.h:101
@ SDL_WINDOW_RESIZABLE
Definition: SDL_video.h:105
@ SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:100
@ SDL_WINDOW_BORDERLESS
Definition: SDL_video.h:104
@ SDL_WINDOWEVENT_CLOSE
Definition: SDL_video.h:167
@ SDL_WINDOWEVENT_RESIZED
Definition: SDL_video.h:155
int Wayland_input_lock_pointer(struct SDL_WaylandInput *input)
struct xkb_state * state
void Wayland_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *_display, SDL_bool fullscreen)
SDL_bool Wayland_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
void Wayland_RestoreWindow(_THIS, SDL_Window *window)
void Wayland_SetWindowTitle(_THIS, SDL_Window *window)
int Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
void Wayland_ShowWindow(_THIS, SDL_Window *window)
int Wayland_CreateWindow(_THIS, SDL_Window *window)
void Wayland_SetWindowSize(_THIS, SDL_Window *window)
void Wayland_DestroyWindow(_THIS, SDL_Window *window)
void Wayland_MaximizeWindow(_THIS, SDL_Window *window)
void Wayland_SetWindowBordered(_THIS, SDL_Window *window, SDL_bool bordered)
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
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)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:167
#define EGL_NO_SURFACE
Definition: egl.h:100
EGLSurface surface
Definition: eglext.h:248
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
EGLNativeWindowType NativeWindowType
Definition: eglplatform.h:112
static struct org_kde_kwin_server_decoration * org_kde_kwin_server_decoration_manager_create(struct org_kde_kwin_server_decoration_manager *org_kde_kwin_server_decoration_manager, struct wl_surface *surface)
static void org_kde_kwin_server_decoration_request_mode(struct org_kde_kwin_server_decoration *org_kde_kwin_server_decoration, uint32_t mode)
static void org_kde_kwin_server_decoration_release(struct org_kde_kwin_server_decoration *org_kde_kwin_server_decoration)
static struct wl_surface * wl_compositor_create_surface(struct wl_compositor *wl_compositor)
static struct wl_region * wl_compositor_create_region(struct wl_compositor *wl_compositor)
static void * wl_output_get_user_data(struct wl_output *wl_output)
static void wl_region_add(struct wl_region *wl_region, int32_t x, int32_t y, int32_t width, int32_t height)
static void wl_region_destroy(struct wl_region *wl_region)
static void wl_shell_surface_set_class(struct wl_shell_surface *wl_shell_surface, const char *class_)
static void wl_shell_surface_pong(struct wl_shell_surface *wl_shell_surface, uint32_t serial)
static void wl_shell_surface_set_user_data(struct wl_shell_surface *wl_shell_surface, void *user_data)
static void wl_shell_surface_set_fullscreen(struct wl_shell_surface *wl_shell_surface, uint32_t method, uint32_t framerate, struct wl_output *output)
static void wl_shell_surface_set_toplevel(struct wl_shell_surface *wl_shell_surface)
static int wl_shell_surface_add_listener(struct wl_shell_surface *wl_shell_surface, const struct wl_shell_surface_listener *listener, void *data)
static void wl_shell_surface_set_maximized(struct wl_shell_surface *wl_shell_surface, struct wl_output *output)
static void wl_shell_surface_destroy(struct wl_shell_surface *wl_shell_surface)
static void wl_shell_surface_set_title(struct wl_shell_surface *wl_shell_surface, const char *title)
@ WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT
static struct wl_shell_surface * wl_shell_get_shell_surface(struct wl_shell *wl_shell, struct wl_surface *surface)
static void wl_surface_set_opaque_region(struct wl_surface *wl_surface, struct wl_region *region)
static void wl_surface_set_buffer_scale(struct wl_surface *wl_surface, int32_t scale)
static void wl_surface_destroy(struct wl_surface *wl_surface)
static int wl_surface_add_listener(struct wl_surface *wl_surface, const struct wl_surface_listener *listener, void *data)
static void wl_surface_commit(struct wl_surface *wl_surface)
static int xdg_surface_add_listener(struct xdg_surface *xdg_surface, const struct xdg_surface_listener *listener, void *data)
static void xdg_surface_destroy(struct xdg_surface *xdg_surface)
static struct xdg_toplevel * xdg_surface_get_toplevel(struct xdg_surface *xdg_surface)
static void xdg_surface_set_user_data(struct xdg_surface *xdg_surface, void *user_data)
static void xdg_surface_ack_configure(struct xdg_surface *xdg_surface, uint32_t serial)
static void xdg_toplevel_set_title(struct xdg_toplevel *xdg_toplevel, const char *title)
static void xdg_toplevel_set_app_id(struct xdg_toplevel *xdg_toplevel, const char *app_id)
static void xdg_toplevel_set_fullscreen(struct xdg_toplevel *xdg_toplevel, struct wl_output *output)
static void xdg_toplevel_set_maximized(struct xdg_toplevel *xdg_toplevel)
static int xdg_toplevel_add_listener(struct xdg_toplevel *xdg_toplevel, const struct xdg_toplevel_listener *listener, void *data)
static void xdg_toplevel_destroy(struct xdg_toplevel *xdg_toplevel)
static void xdg_toplevel_unset_fullscreen(struct xdg_toplevel *xdg_toplevel)
@ XDG_TOPLEVEL_STATE_FULLSCREEN
static struct xdg_surface * xdg_wm_base_get_xdg_surface(struct xdg_wm_base *xdg_wm_base, struct wl_surface *surface)
static struct zxdg_toplevel_decoration_v1 * zxdg_decoration_manager_v1_get_toplevel_decoration(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, struct xdg_toplevel *toplevel)
static struct zxdg_surface_v6 * zxdg_shell_v6_get_xdg_surface(struct zxdg_shell_v6 *zxdg_shell_v6, struct wl_surface *surface)
static int zxdg_surface_v6_add_listener(struct zxdg_surface_v6 *zxdg_surface_v6, const struct zxdg_surface_v6_listener *listener, void *data)
static void zxdg_surface_v6_set_user_data(struct zxdg_surface_v6 *zxdg_surface_v6, void *user_data)
static void zxdg_surface_v6_destroy(struct zxdg_surface_v6 *zxdg_surface_v6)
static struct zxdg_toplevel_v6 * zxdg_surface_v6_get_toplevel(struct zxdg_surface_v6 *zxdg_surface_v6)
static void zxdg_surface_v6_ack_configure(struct zxdg_surface_v6 *zxdg_surface_v6, uint32_t serial)
static void zxdg_toplevel_decoration_v1_set_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t mode)
static void zxdg_toplevel_decoration_v1_destroy(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
static void zxdg_toplevel_v6_set_title(struct zxdg_toplevel_v6 *zxdg_toplevel_v6, const char *title)
static void zxdg_toplevel_v6_set_fullscreen(struct zxdg_toplevel_v6 *zxdg_toplevel_v6, struct wl_output *output)
static void zxdg_toplevel_v6_unset_fullscreen(struct zxdg_toplevel_v6 *zxdg_toplevel_v6)
static void zxdg_toplevel_v6_set_maximized(struct zxdg_toplevel_v6 *zxdg_toplevel_v6)
static void zxdg_toplevel_v6_set_app_id(struct zxdg_toplevel_v6 *zxdg_toplevel_v6, const char *app_id)
static void zxdg_toplevel_v6_destroy(struct zxdg_toplevel_v6 *zxdg_toplevel_v6)
static int zxdg_toplevel_v6_add_listener(struct zxdg_toplevel_v6 *zxdg_toplevel_v6, const struct zxdg_toplevel_v6_listener *listener, void *data)
union SDL_SysWMinfo::@17 info
struct wl_surface * surface
Definition: SDL_syswm.h:259
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:200
Display * display
Definition: SDL_syswm.h:220
struct wl_shell_surface * shell_surface
Definition: SDL_syswm.h:260
struct SDL_SysWMinfo::@17::@19 wl
SDL_version version
Definition: SDL_syswm.h:199
struct zxdg_shell_v6 * zxdg
struct xdg_wm_base * xdg
struct wl_compositor * compositor
struct zxdg_decoration_manager_v1 * decoration_manager
struct SDL_VideoData::@264 shell
struct org_kde_kwin_server_decoration_manager * kwin_server_decoration_manager
struct wl_display * display
SDL_VideoDisplay * displays
Definition: SDL_sysvideo.h:316
struct wl_egl_window * egl_window
union SDL_WindowData::@267 shell_surface
SDL_Surface * surface
struct zxdg_toplevel_decoration_v1 * server_decoration
struct qt_extended_surface * extended_surface
SDL_VideoData * waylandData
SDL_Window * sdlwindow
EGLSurface egl_surface
SDL_xdg_shell_surface xdg
struct wl_shell_surface * wl
struct org_kde_kwin_server_decoration * kwin_server_decoration
SDL_zxdg_shell_surface zxdg
struct SDL_WindowData::@268 resize
The type used to identify a window.
Definition: SDL_sysvideo.h:74
Uint8 minor
Definition: SDL_version.h:54
Uint8 patch
Definition: SDL_version.h:55
Uint8 major
Definition: SDL_version.h:53
struct xdg_surface * surface
struct xdg_toplevel * toplevel
union SDL_xdg_shell_surface::@266 roleobj
struct zxdg_toplevel_v6 * toplevel
union SDL_zxdg_shell_surface::@265 roleobj
struct zxdg_surface_v6 * surface
#define strdup