SDL_waylandwindow.c
Go to the documentation of this file.
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
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_internal.h"
#if SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL
#include "../SDL_sysvideo.h"
#include "../../events/SDL_windowevents_c.h"
#include "../SDL_egl_c.h"
#include "SDL_waylandwindow.h"
#include "SDL_waylandvideo.h"
#include "SDL_waylandtouch.h"
#include "SDL_waylanddyn.h"
static void
handle_ping(void *data, struct wl_shell_surface *shell_surface,
uint32_t serial)
{
wl_shell_surface_pong(shell_surface, serial);
}
static void
handle_configure(void *data, struct wl_shell_surface *shell_surface,
uint32_t edges, int32_t width, int32_t height)
{
SDL_WindowData *wind = (SDL_WindowData *)data;
SDL_Window *window = wind->sdlwindow;
struct wl_region *region;
window->w = width;
window->h = height;
WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
region = wl_compositor_create_region(wind->waylandData->compositor);
wl_region_add(region, 0, 0, window->w, window->h);
wl_surface_set_opaque_region(wind->surface, region);
wl_region_destroy(region);
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, window->w, window->h);
}
static void
handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
{
}
static const struct wl_shell_surface_listener shell_surface_listener = {
handle_ping,
handle_configure,
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)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
info->info.wl.display = data->waylandData->display;
info->info.wl.surface = data->surface;
info->info.wl.shell_surface = data->shell_surface;
info->subsystem = SDL_SYSWM_WAYLAND;
return SDL_TRUE;
}
int
Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
{
return 0; /* just succeed, the real work is done elsewhere. */
}
void Wayland_ShowWindow(_THIS, SDL_Window *window)
{
SDL_WindowData *wind = window->driverdata;
if (window->flags & SDL_WINDOW_FULLSCREEN)
wl_shell_surface_set_fullscreen(wind->shell_surface,
WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
0, (struct wl_output *)window->fullscreen_mode.driverdata);
else
wl_shell_surface_set_toplevel(wind->shell_surface);
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
}
void
Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
SDL_VideoDisplay * _display, SDL_bool fullscreen)
{
SDL_WindowData *wind = window->driverdata;
if (fullscreen)
wl_shell_surface_set_fullscreen(wind->shell_surface,
WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE,
0, (struct wl_output *)_display->driverdata);
else
wl_shell_surface_set_toplevel(wind->shell_surface);
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
}
int Wayland_CreateWindow(_THIS, SDL_Window *window)
{
SDL_WindowData *data;
SDL_VideoData *c;
struct wl_region *region;
data = calloc(1, sizeof *data);
if (data == NULL)
return SDL_OutOfMemory();
c = _this->driverdata;
window->driverdata = data;
if (!(window->flags & SDL_WINDOW_OPENGL)) {
SDL_GL_LoadLibrary(NULL);
window->flags |= SDL_WINDOW_OPENGL;
}
if (window->x == SDL_WINDOWPOS_UNDEFINED) {
window->x = 0;
}
if (window->y == SDL_WINDOWPOS_UNDEFINED) {
window->y = 0;
}
data->waylandData = c;
data->sdlwindow = window;
data->surface =
wl_compositor_create_surface(c->compositor);
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 = WAYLAND_wl_egl_window_create(data->surface,
window->w, window->h);
/* Create the GLES window surface */
data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window);
if (data->egl_surface == EGL_NO_SURFACE) {
return SDL_SetError("failed to create a window surface");
}
if (data->shell_surface) {
wl_shell_surface_set_user_data(data->shell_surface, data);
wl_shell_surface_add_listener(data->shell_surface,
&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);
wl_region_destroy(region);
WAYLAND_wl_display_flush(c->display);
return 0;
}
void Wayland_SetWindowSize(_THIS, SDL_Window * window)
{
SDL_VideoData *data = _this->driverdata;
SDL_WindowData *wind = window->driverdata;
struct wl_region *region;
WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
region =wl_compositor_create_region(data->compositor);
wl_region_add(region, 0, 0, window->w, window->h);
wl_surface_set_opaque_region(wind->surface, region);
wl_region_destroy(region);
}
void Wayland_DestroyWindow(_THIS, SDL_Window *window)
{
SDL_VideoData *data = _this->driverdata;
SDL_WindowData *wind = window->driverdata;
if (data) {
SDL_EGL_DestroySurface(_this, wind->egl_surface);
WAYLAND_wl_egl_window_destroy(wind->egl_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);
WAYLAND_wl_display_flush(data->display);
}
window->driverdata = NULL;
}
#endif /* SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL */
/* vi: set ts=4 sw=4 expandtab: */
Wayland_SetWindowSize
void Wayland_SetWindowSize(_THIS, SDL_Window *window)
Wayland_SetWindowFullscreen
void Wayland_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *_display, SDL_bool fullscreen)
SDL_Window::fullscreen_mode
SDL_DisplayMode fullscreen_mode
Definition: SDL_sysvideo.h:87
width
GLint GLint GLsizei width
Definition: SDL_opengl.h:1565
SDL_Window::w
int w
Definition: SDL_sysvideo.h:78
int32_t
signed int int32_t
Definition: SDL_config_windows.h:61
Wayland_SetWindowHitTest
int Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
SDL_Window::x
int x
Definition: SDL_sysvideo.h:77
SDL_VideoData::display
struct wl_display * display
Definition: SDL_waylandvideo.h:40
window
SDL_Window * window
Definition: testautomation_render.c:26
SDL_waylandtouch.h
SDL_waylandwindow.h
SDL_VideoDevice::driverdata
void * driverdata
Definition: SDL_sysvideo.h:332
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1967
Wayland_ShowWindow
void Wayland_ShowWindow(_THIS, SDL_Window *window)
SDL_SysWMinfo::subsystem
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:184
SDL_WINDOWPOS_UNDEFINED
#define SDL_WINDOWPOS_UNDEFINED
Definition: SDL_video.h:120
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:660
SDL_SendWindowEvent
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
Definition: SDL_windowevents.c:74
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1565
SDL_GL_LoadLibrary
#define SDL_GL_LoadLibrary
Definition: SDL_dynapi_overrides.h:557
Wayland_CreateWindow
int Wayland_CreateWindow(_THIS, SDL_Window *window)
calloc
#define calloc
Definition: SDL_malloc.c:642
SDL_WindowData::surface
SDL_Surface * surface
Definition: SDL_emscriptenvideo.h:38
SDL_WindowData
Definition: SDL_androidwindow.h:34
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:114
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:126
Wayland_DestroyWindow
void Wayland_DestroyWindow(_THIS, SDL_Window *window)
SDL_SysWMinfo
Definition: SDL_syswm.h:181
value
GLsizei const GLfloat * value
Definition: SDL_opengl_glext.h:698
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
SDL_free
void SDL_free(void *mem)
SDL_DisplayMode::driverdata
void * driverdata
Definition: SDL_video.h:59
SDL_WindowData::sdlwindow
SDL_Window * sdlwindow
Definition: SDL_waylandwindow.h:35
SDL_WindowData::shell_surface
struct wl_shell_surface * shell_surface
Definition: SDL_waylandwindow.h:38
Wayland_GetWindowWMInfo
SDL_bool Wayland_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
SDL_VideoData::shell
struct wl_shell * shell
Definition: SDL_waylandvideo.h:47
SDL_WindowData::waylandData
SDL_VideoData * waylandData
Definition: SDL_waylandwindow.h:36
c
const GLubyte * c
Definition: SDL_opengl_glext.h:11093
SDL_Window::y
int y
Definition: SDL_sysvideo.h:77
SDL_waylanddyn.h
SDL_TRUE
Definition: SDL_stdinc.h:129
SDL_WINDOWEVENT_CLOSE
Definition: SDL_video.h:157
enabled
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: SDL_opengl_glext.h:2479
SDL_VideoDisplay
Definition: SDL_sysvideo.h:120
SDL_Window::h
int h
Definition: SDL_sysvideo.h:78
SDL_SYSWM_WAYLAND
Definition: SDL_syswm.h:120
SDL_waylandvideo.h
NULL
#define NULL
Definition: begin_code.h:143
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
uint32_t
unsigned int uint32_t
Definition: SDL_config_windows.h:62
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:36
SDL_VideoData::compositor
struct wl_compositor * compositor
Definition: SDL_waylandvideo.h:42
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:71
SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:98
SDL_VideoData
Definition: SDL_androidvideo.h:35
SDL_SysWMinfo::info
union SDL_SysWMinfo::@18 info
SDL_WINDOW_OPENGL
Definition: SDL_video.h:99
SDL_WINDOWEVENT_RESIZED
Definition: SDL_video.h:145
SDL_SysWMinfo::wl
struct SDL_SysWMinfo::@18::@20 wl
SDL_Window::driverdata
void * driverdata
Definition: SDL_sysvideo.h:106
SDL_Window::flags
Uint32 flags
Definition: SDL_sysvideo.h:81
SDL_WindowData::egl_surface
EGLSurface egl_surface
Definition: SDL_androidwindow.h:36
SDL_VideoDisplay::driverdata
void * driverdata
Definition: SDL_sysvideo.h:133
SDL_WindowData::egl_window
struct wl_egl_window * egl_window
Definition: SDL_waylandwindow.h:39