22 #include "../../SDL_internal.h"
24 #if SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL
26 #include "../SDL_sysvideo.h"
27 #include "../../events/SDL_windowevents_c.h"
28 #include "../SDL_egl_c.h"
36 #include "xdg-shell-client-protocol.h"
37 #include "xdg-shell-unstable-v6-client-protocol.h"
38 #include "xdg-decoration-unstable-v1-client-protocol.h"
39 #include "org-kde-kwin-server-decoration-manager-client-protocol.h"
51 handle_ping_wl_shell_surface(
void *
data,
struct wl_shell_surface *shell_surface,
54 wl_shell_surface_pong(shell_surface, serial);
58 handle_configure_wl_shell_surface(
void *
data,
struct wl_shell_surface *shell_surface,
93 handle_popup_done_wl_shell_surface(
void *
data,
struct wl_shell_surface *shell_surface)
97 static 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
107 handle_configure_zxdg_shell_surface(
void *
data,
struct zxdg_surface_v6 *zxdg,
uint32_t serial)
111 struct wl_region *region;
120 wl_surface_set_buffer_scale(wind->
surface, get_window_scale_factor(
window));
123 zxdg_surface_v6_ack_configure(zxdg, serial);
127 wl_surface_set_opaque_region(wind->
surface, region);
128 wl_region_destroy(region);
138 static const struct zxdg_surface_v6_listener shell_surface_listener_zxdg = {
139 handle_configure_zxdg_shell_surface
144 handle_configure_zxdg_toplevel(
void *
data,
145 struct zxdg_toplevel_v6 *zxdg_toplevel_v6,
148 struct wl_array *states)
153 enum zxdg_toplevel_v6_state *
state;
155 wl_array_for_each(
state, states) {
156 if (*
state == ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN) {
198 handle_close_zxdg_toplevel(
void *
data,
struct zxdg_toplevel_v6 *zxdg_toplevel_v6)
204 static const struct zxdg_toplevel_v6_listener toplevel_listener_zxdg = {
205 handle_configure_zxdg_toplevel,
206 handle_close_zxdg_toplevel
212 handle_configure_xdg_shell_surface(
void *
data,
struct xdg_surface *xdg,
uint32_t serial)
216 struct wl_region *region;
225 wl_surface_set_buffer_scale(wind->
surface, get_window_scale_factor(
window));
228 xdg_surface_ack_configure(xdg, serial);
232 wl_surface_set_opaque_region(wind->
surface, region);
233 wl_region_destroy(region);
243 static const struct xdg_surface_listener shell_surface_listener_xdg = {
244 handle_configure_xdg_shell_surface
249 handle_configure_xdg_toplevel(
void *
data,
250 struct xdg_toplevel *xdg_toplevel,
253 struct wl_array *states)
258 enum xdg_toplevel_state *
state;
260 wl_array_for_each(
state, states) {
261 if (*
state == XDG_TOPLEVEL_STATE_FULLSCREEN) {
303 handle_close_xdg_toplevel(
void *
data,
struct xdg_toplevel *xdg_toplevel)
309 static const struct xdg_toplevel_listener toplevel_listener_xdg = {
310 handle_configure_xdg_toplevel,
311 handle_close_xdg_toplevel
317 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
319 handle_onscreen_visibility(
void *
data,
320 struct qt_extended_surface *qt_extended_surface,
int32_t visible)
325 handle_set_generic_property(
void *
data,
326 struct qt_extended_surface *qt_extended_surface,
const char *
name,
327 struct wl_array *
value)
332 handle_close(
void *
data,
struct qt_extended_surface *qt_extended_surface)
338 static const struct qt_extended_surface_listener extended_surface_listener = {
339 handle_onscreen_visibility,
340 handle_set_generic_property,
347 float old_factor =
window->scale_factor, new_factor = 0.0;
354 if (!
window->num_outputs) {
355 new_factor = old_factor;
362 for (
i = 0;
i <
window->num_outputs;
i++) {
364 if (factor > new_factor) {
369 if (new_factor != old_factor) {
373 window->resize.scale_factor = new_factor;
379 handle_surface_enter(
void *
data,
struct wl_surface *
surface,
380 struct wl_output *
output) {
385 update_scale_factor(
window);
389 handle_surface_leave(
void *
data,
struct wl_surface *
surface,
390 struct wl_output *
output) {
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++) {
403 window->outputs = new_outputs;
411 update_scale_factor(
window);
414 static const struct wl_surface_listener surface_listener = {
415 handle_surface_enter,
437 if (version < 2000006) {
444 info->
info.wl.surface =
data->surface;
445 info->
info.wl.shell_surface =
data->shell_surface.wl;
478 WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
490 struct wl_output *
output = (
struct wl_output *)
window->fullscreen_mode.driverdata;
494 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
496 QtExtendedSurface_OnHintChanged(
void *userdata,
const char *
name,
497 const char *oldValue,
const char *newValue)
499 struct qt_extended_surface *qt_extended_surface = userdata;
506 int32_t orientation = QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION;
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;
520 qt_extended_surface_set_content_orientation(qt_extended_surface, orientation);
524 if (newValue !=
NULL) {
525 char *tmp =
strdup(newValue);
526 char *saveptr =
NULL;
528 char *flag = strtok_r(tmp,
" ", &saveptr);
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) {
539 flag = strtok_r(
NULL,
" ", &saveptr);
545 qt_extended_surface_set_window_flags(qt_extended_surface,
flags);
549 static void QtExtendedSurface_Subscribe(
struct qt_extended_surface *
surface,
const char *
name)
554 static void QtExtendedSurface_Unsubscribe(
struct qt_extended_surface *
surface,
const char *
name)
589 const enum zxdg_toplevel_decoration_v1_mode
mode = bordered ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE : ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
592 const enum org_kde_kwin_server_decoration_mode
mode = bordered ? ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER : ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_NONE;
611 WAYLAND_wl_display_flush( viddata->
display );
618 struct wl_region *region;
639 data->waylandData =
c;
642 data->scale_factor = 1.0;
657 data->resize.scale_factor =
data->scale_factor;
660 data->num_outputs = 0;
663 wl_compositor_create_surface(
c->compositor);
664 wl_surface_add_listener(
data->surface, &surface_listener,
data);
667 data->shell_surface.xdg.surface = xdg_wm_base_get_xdg_surface(
c->shell.xdg,
data->surface);
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);
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);
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);
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);
693 data->egl_window = WAYLAND_wl_egl_window_create(
data->surface,
700 return SDL_SetError(
"failed to create a window surface");
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);
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);
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);
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);
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) {
732 const enum zxdg_toplevel_decoration_v1_mode
mode = bordered ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE : ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
733 zxdg_toplevel_decoration_v1_set_mode(
data->server_decoration,
mode);
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) {
739 const enum org_kde_kwin_server_decoration_mode
mode = bordered ? ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER : ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_NONE;
740 org_kde_kwin_server_decoration_request_mode(
data->kwin_server_decoration,
mode);
744 region = wl_compositor_create_region(
c->compositor);
746 wl_surface_set_opaque_region(
data->surface, region);
747 wl_region_destroy(region);
749 if (
c->relative_mouse_mode) {
753 wl_surface_commit(
data->surface);
754 WAYLAND_wl_display_flush(
c->display);
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);
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);
781 struct wl_region *region;
783 wl_surface_set_buffer_scale(wind->
surface, get_window_scale_factor(
window));
786 region = wl_compositor_create_region(
data->compositor);
788 wl_surface_set_opaque_region(wind->
surface, region);
789 wl_region_destroy(region);
817 WAYLAND_wl_egl_window_destroy(wind->
egl_window);
827 if (
data->shell.xdg) {
834 }
else if (
data->shell.zxdg) {
847 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
848 if (wind->extended_surface) {
851 qt_extended_surface_destroy(wind->extended_surface);
854 wl_surface_destroy(wind->
surface);
857 WAYLAND_wl_display_flush(
data->display);