SDL 2.0
SDL_waylandvideo.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
25
26#include "SDL_video.h"
27#include "SDL_mouse.h"
28#include "SDL_stdinc.h"
29#include "../../events/SDL_events_c.h"
30
31#include "SDL_waylandvideo.h"
32#include "SDL_waylandevents_c.h"
33#include "SDL_waylandwindow.h"
34#include "SDL_waylandopengles.h"
35#include "SDL_waylandmouse.h"
36#include "SDL_waylandtouch.h"
38#include "SDL_waylandvulkan.h"
39
40#include <sys/types.h>
41#include <unistd.h>
42#include <fcntl.h>
43#include <xkbcommon/xkbcommon.h>
44
45#include "SDL_waylanddyn.h"
46#include <wayland-util.h>
47
52
53#define WAYLANDVID_DRIVER_NAME "wayland"
54
55/* Initialization/Query functions */
56static int
57Wayland_VideoInit(_THIS);
58
59static void
60Wayland_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display);
61static int
62Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
63
64static void
65Wayland_VideoQuit(_THIS);
66
67/* Find out what class name we should use
68 * Based on src/video/x11/SDL_x11video.c */
69static char *
70get_classname()
71{
72/* !!! FIXME: this is probably wrong, albeit harmless in many common cases. From protocol spec:
73 "The surface class identifies the general class of applications
74 to which the surface belongs. A common convention is to use the
75 file name (or the full path if it is a non-standard location) of
76 the application's .desktop file as the class." */
77
78 char *spot;
79#if defined(__LINUX__) || defined(__FREEBSD__)
80 char procfile[1024];
81 char linkfile[1024];
82 int linksize;
83#endif
84
85 /* First allow environment variable override */
86 spot = SDL_getenv("SDL_VIDEO_WAYLAND_WMCLASS");
87 if (spot) {
88 return SDL_strdup(spot);
89 } else {
90 /* Fallback to the "old" envvar */
91 spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS");
92 if (spot) {
93 return SDL_strdup(spot);
94 }
95 }
96
97 /* Next look at the application's executable name */
98#if defined(__LINUX__) || defined(__FREEBSD__)
99#if defined(__LINUX__)
100 SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid());
101#elif defined(__FREEBSD__)
102 SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file",
103 getpid());
104#else
105#error Where can we find the executable name?
106#endif
107 linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1);
108 if (linksize > 0) {
109 linkfile[linksize] = '\0';
110 spot = SDL_strrchr(linkfile, '/');
111 if (spot) {
112 return SDL_strdup(spot + 1);
113 } else {
114 return SDL_strdup(linkfile);
115 }
116 }
117#endif /* __LINUX__ || __FREEBSD__ */
118
119 /* Finally use the default we've used forever */
120 return SDL_strdup("SDL_App");
121}
122
123/* Wayland driver bootstrap functions */
124static int
125Wayland_Available(void)
126{
127 struct wl_display *display = NULL;
129 display = WAYLAND_wl_display_connect(NULL);
130 if (display != NULL) {
131 WAYLAND_wl_display_disconnect(display);
132 }
134 }
135
136 return (display != NULL);
137}
138
139static void
140Wayland_DeleteDevice(SDL_VideoDevice *device)
141{
144}
145
146static SDL_VideoDevice *
147Wayland_CreateDevice(int devindex)
148{
150
152 return NULL;
153 }
154
155 /* Initialize all variables that we clean on shutdown */
156 device = SDL_calloc(1, sizeof(SDL_VideoDevice));
157 if (!device) {
160 return NULL;
161 }
162
163 /* Set the function pointers */
164 device->VideoInit = Wayland_VideoInit;
165 device->VideoQuit = Wayland_VideoQuit;
166 device->SetDisplayMode = Wayland_SetDisplayMode;
167 device->GetDisplayModes = Wayland_GetDisplayModes;
168 device->GetWindowWMInfo = Wayland_GetWindowWMInfo;
169
170 device->PumpEvents = Wayland_PumpEvents;
171
172 device->GL_SwapWindow = Wayland_GLES_SwapWindow;
173 device->GL_GetSwapInterval = Wayland_GLES_GetSwapInterval;
174 device->GL_SetSwapInterval = Wayland_GLES_SetSwapInterval;
175 device->GL_GetDrawableSize = Wayland_GLES_GetDrawableSize;
176 device->GL_MakeCurrent = Wayland_GLES_MakeCurrent;
177 device->GL_CreateContext = Wayland_GLES_CreateContext;
178 device->GL_LoadLibrary = Wayland_GLES_LoadLibrary;
179 device->GL_UnloadLibrary = Wayland_GLES_UnloadLibrary;
180 device->GL_GetProcAddress = Wayland_GLES_GetProcAddress;
181 device->GL_DeleteContext = Wayland_GLES_DeleteContext;
182
183 device->CreateSDLWindow = Wayland_CreateWindow;
184 device->ShowWindow = Wayland_ShowWindow;
185 device->SetWindowFullscreen = Wayland_SetWindowFullscreen;
186 device->MaximizeWindow = Wayland_MaximizeWindow;
187 device->RestoreWindow = Wayland_RestoreWindow;
188 device->SetWindowBordered = Wayland_SetWindowBordered;
189 device->SetWindowSize = Wayland_SetWindowSize;
190 device->SetWindowTitle = Wayland_SetWindowTitle;
191 device->DestroyWindow = Wayland_DestroyWindow;
192 device->SetWindowHitTest = Wayland_SetWindowHitTest;
193
194 device->SetClipboardText = Wayland_SetClipboardText;
195 device->GetClipboardText = Wayland_GetClipboardText;
196 device->HasClipboardText = Wayland_HasClipboardText;
197
198#if SDL_VIDEO_VULKAN
199 device->Vulkan_LoadLibrary = Wayland_Vulkan_LoadLibrary;
200 device->Vulkan_UnloadLibrary = Wayland_Vulkan_UnloadLibrary;
201 device->Vulkan_GetInstanceExtensions = Wayland_Vulkan_GetInstanceExtensions;
202 device->Vulkan_CreateSurface = Wayland_Vulkan_CreateSurface;
203 device->Vulkan_GetDrawableSize = Wayland_Vulkan_GetDrawableSize;
204#endif
205
206 device->free = Wayland_DeleteDevice;
207
208 return device;
209}
210
212 WAYLANDVID_DRIVER_NAME, "SDL Wayland video driver",
213 Wayland_Available, Wayland_CreateDevice
214};
215
216static void
217display_handle_geometry(void *data,
218 struct wl_output *output,
219 int x, int y,
220 int physical_width,
221 int physical_height,
222 int subpixel,
223 const char *make,
224 const char *model,
225 int transform)
226
227{
228 SDL_VideoDisplay *display = data;
229
230 display->name = SDL_strdup(model);
231}
232
233static void
234display_handle_mode(void *data,
235 struct wl_output *output,
237 int width,
238 int height,
239 int refresh)
240{
242 SDL_VideoDisplay *display = data;
243
244 SDL_zero(mode);
246 mode.w = width;
247 mode.h = height;
248 mode.refresh_rate = refresh / 1000; // mHz to Hz
249 mode.driverdata = ((SDL_WaylandOutputData*)display->driverdata)->output;
250 SDL_AddDisplayMode(display, &mode);
251
253 display->current_mode = mode;
254 display->desktop_mode = mode;
255 }
256}
257
258static void
259display_handle_done(void *data,
260 struct wl_output *output)
261{
262 /* !!! FIXME: this will fail on any further property changes! */
263 SDL_VideoDisplay *display = data;
264 SDL_AddVideoDisplay(display);
266 SDL_free(display->name);
267 SDL_free(display);
268}
269
270static void
271display_handle_scale(void *data,
272 struct wl_output *output,
273 int32_t factor)
274{
275 SDL_VideoDisplay *display = data;
276 ((SDL_WaylandOutputData*)display->driverdata)->scale_factor = factor;
277}
278
279static const struct wl_output_listener output_listener = {
280 display_handle_geometry,
281 display_handle_mode,
282 display_handle_done,
283 display_handle_scale
284};
285
286static void
287Wayland_add_display(SDL_VideoData *d, uint32_t id)
288{
289 struct wl_output *output;
291 SDL_VideoDisplay *display = SDL_malloc(sizeof *display);
292 if (!display) {
294 return;
295 }
296 SDL_zero(*display);
297
298 output = wl_registry_bind(d->registry, id, &wl_output_interface, 2);
299 if (!output) {
300 SDL_SetError("Failed to retrieve output.");
301 SDL_free(display);
302 return;
303 }
304 data = SDL_malloc(sizeof *data);
305 data->output = output;
306 data->scale_factor = 1.0;
307 display->driverdata = data;
308
309 wl_output_add_listener(output, &output_listener, display);
310}
311
312#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
313static void
314windowmanager_hints(void *data, struct qt_windowmanager *qt_windowmanager,
315 int32_t show_is_fullscreen)
316{
317}
318
319static void
320windowmanager_quit(void *data, struct qt_windowmanager *qt_windowmanager)
321{
322 SDL_SendQuit();
323}
324
325static const struct qt_windowmanager_listener windowmanager_listener = {
326 windowmanager_hints,
327 windowmanager_quit,
328};
329#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
330
331
332static void
333handle_ping_zxdg_shell(void *data, struct zxdg_shell_v6 *zxdg, uint32_t serial)
334{
335 zxdg_shell_v6_pong(zxdg, serial);
336}
337
338static const struct zxdg_shell_v6_listener shell_listener_zxdg = {
339 handle_ping_zxdg_shell
340};
341
342
343static void
344handle_ping_xdg_wm_base(void *data, struct xdg_wm_base *xdg, uint32_t serial)
345{
346 xdg_wm_base_pong(xdg, serial);
347}
348
349static const struct xdg_wm_base_listener shell_listener_xdg = {
350 handle_ping_xdg_wm_base
351};
352
353
354static void
355display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
356 const char *interface, uint32_t version)
357{
359
360 /*printf("WAYLAND INTERFACE: %s\n", interface);*/
361
362 if (strcmp(interface, "wl_compositor") == 0) {
363 d->compositor = wl_registry_bind(d->registry, id, &wl_compositor_interface, SDL_min(3, version));
364 } else if (strcmp(interface, "wl_output") == 0) {
365 Wayland_add_display(d, id);
366 } else if (strcmp(interface, "wl_seat") == 0) {
368 } else if (strcmp(interface, "xdg_wm_base") == 0) {
369 d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, 1);
370 xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL);
371 } else if (strcmp(interface, "zxdg_shell_v6") == 0) {
372 d->shell.zxdg = wl_registry_bind(d->registry, id, &zxdg_shell_v6_interface, 1);
373 zxdg_shell_v6_add_listener(d->shell.zxdg, &shell_listener_zxdg, NULL);
374 } else if (strcmp(interface, "wl_shell") == 0) {
375 d->shell.wl = wl_registry_bind(d->registry, id, &wl_shell_interface, 1);
376 } else if (strcmp(interface, "wl_shm") == 0) {
377 d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
378 d->cursor_theme = WAYLAND_wl_cursor_theme_load(NULL, 32, d->shm);
379 } else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
381 } else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) {
383 } else if (strcmp(interface, "wl_data_device_manager") == 0) {
384 d->data_device_manager = wl_registry_bind(d->registry, id, &wl_data_device_manager_interface, 3);
385 } else if (strcmp(interface, "zxdg_decoration_manager_v1") == 0) {
386 d->decoration_manager = wl_registry_bind(d->registry, id, &zxdg_decoration_manager_v1_interface, 1);
387 } else if (strcmp(interface, "org_kde_kwin_server_decoration_manager") == 0) {
388 d->kwin_server_decoration_manager = wl_registry_bind(d->registry, id, &org_kde_kwin_server_decoration_manager_interface, 1);
389
390#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
391 } else if (strcmp(interface, "qt_touch_extension") == 0) {
392 Wayland_touch_create(d, id);
393 } else if (strcmp(interface, "qt_surface_extension") == 0) {
394 d->surface_extension = wl_registry_bind(registry, id,
395 &qt_surface_extension_interface, 1);
396 } else if (strcmp(interface, "qt_windowmanager") == 0) {
397 d->windowmanager = wl_registry_bind(registry, id,
398 &qt_windowmanager_interface, 1);
399 qt_windowmanager_add_listener(d->windowmanager, &windowmanager_listener, d);
400#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
401 }
402}
403
404static void
405display_remove_global(void *data, struct wl_registry *registry, uint32_t id) {}
406
407static const struct wl_registry_listener registry_listener = {
408 display_handle_global,
409 display_remove_global
410};
411
412int
413Wayland_VideoInit(_THIS)
414{
415 SDL_VideoData *data = SDL_malloc(sizeof *data);
416 if (data == NULL)
417 return SDL_OutOfMemory();
418 memset(data, 0, sizeof *data);
419
421
422 data->xkb_context = WAYLAND_xkb_context_new(0);
423 if (!data->xkb_context) {
424 return SDL_SetError("Failed to create XKB context");
425 }
426
427 data->display = WAYLAND_wl_display_connect(NULL);
428 if (data->display == NULL) {
429 return SDL_SetError("Failed to connect to a Wayland display");
430 }
431
432 data->registry = wl_display_get_registry(data->display);
433 if (data->registry == NULL) {
434 return SDL_SetError("Failed to get the Wayland registry");
435 }
436
437 wl_registry_add_listener(data->registry, &registry_listener, data);
438
439 // First roundtrip to receive all registry objects.
440 WAYLAND_wl_display_roundtrip(data->display);
441
442 // Second roundtrip to receive all output events.
443 WAYLAND_wl_display_roundtrip(data->display);
444
445 Wayland_InitMouse();
446
447 /* Get the surface class name, usually the name of the application */
448 data->classname = get_classname();
449
450 WAYLAND_wl_display_flush(data->display);
451
452 return 0;
453}
454
455static void
456Wayland_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display)
457{
458 // Nothing to do here, everything was already done in the wl_output
459 // callbacks.
460}
461
462static int
463Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
464{
465 return SDL_Unsupported();
466}
467
468void
469Wayland_VideoQuit(_THIS)
470{
472 int i, j;
473
474 Wayland_FiniMouse ();
475
476 for (i = 0; i < _this->num_displays; ++i) {
477 SDL_VideoDisplay *display = &_this->displays[i];
478
480 SDL_free(display->driverdata);
481 display->driverdata = NULL;
482
483 for (j = display->num_display_modes; j--;) {
484 display->display_modes[j].driverdata = NULL;
485 }
486 display->desktop_mode.driverdata = NULL;
487 }
488
492
493 if (data->xkb_context) {
494 WAYLAND_xkb_context_unref(data->xkb_context);
495 data->xkb_context = NULL;
496 }
497#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
498 if (data->windowmanager)
499 qt_windowmanager_destroy(data->windowmanager);
500
501 if (data->surface_extension)
502 qt_surface_extension_destroy(data->surface_extension);
503
504 Wayland_touch_destroy(data);
505#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
506
507 if (data->shm)
508 wl_shm_destroy(data->shm);
509
510 if (data->cursor_theme)
511 WAYLAND_wl_cursor_theme_destroy(data->cursor_theme);
512
513 if (data->shell.wl)
514 wl_shell_destroy(data->shell.wl);
515
516 if (data->shell.xdg)
517 xdg_wm_base_destroy(data->shell.xdg);
518
519 if (data->shell.zxdg)
520 zxdg_shell_v6_destroy(data->shell.zxdg);
521
522 if (data->compositor)
523 wl_compositor_destroy(data->compositor);
524
525 if (data->registry)
526 wl_registry_destroy(data->registry);
527
528 if (data->display) {
529 WAYLAND_wl_display_flush(data->display);
530 WAYLAND_wl_display_disconnect(data->display);
531 }
532
533 SDL_free(data->classname);
534 SDL_free(data);
536}
537
538#endif /* SDL_VIDEO_DRIVER_WAYLAND */
539
540/* vi: set ts=4 sw=4 expandtab: */
#define _THIS
unsigned int uint32_t
signed int int32_t
#define SDL_SetError
#define SDL_strrchr
#define SDL_getenv
#define SDL_malloc
#define SDL_free
#define SDL_strdup
#define SDL_snprintf
#define SDL_calloc
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_Unsupported()
Definition: SDL_error.h:53
int SDL_SendQuit(void)
Definition: SDL_quit.c:201
#define memset
Definition: SDL_malloc.c:627
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
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 GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
GLuint GLenum GLenum transform
GLenum mode
GLbitfield flags
@ SDL_PIXELFORMAT_RGB888
Definition: SDL_pixels.h:236
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
VideoBootStrap Wayland_bootstrap
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
Definition: SDL_video.c:603
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:751
static SDL_VideoDevice * _this
Definition: SDL_video.c:118
SDL_bool Wayland_HasClipboardText(_THIS)
char * Wayland_GetClipboardText(_THIS)
int Wayland_SetClipboardText(_THIS, const char *text)
int SDL_WAYLAND_LoadSymbols(void)
void SDL_WAYLAND_UnloadSymbols(void)
void Wayland_display_destroy_input(SDL_VideoData *d)
void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d)
void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d)
void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id)
void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id)
void Wayland_display_add_input(SDL_VideoData *d, uint32_t id)
void Wayland_PumpEvents(_THIS)
#define Wayland_GLES_UnloadLibrary
int Wayland_GLES_SwapWindow(_THIS, SDL_Window *window)
int Wayland_GLES_LoadLibrary(_THIS, const char *path)
int Wayland_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
SDL_GLContext Wayland_GLES_CreateContext(_THIS, SDL_Window *window)
#define Wayland_GLES_SetSwapInterval
void Wayland_GLES_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
#define Wayland_GLES_GetSwapInterval
#define Wayland_GLES_GetProcAddress
void Wayland_GLES_DeleteContext(_THIS, SDL_GLContext context)
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)
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 int in j)
Definition: SDL_x11sym.h:50
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
static void wl_compositor_destroy(struct wl_compositor *wl_compositor)
static struct wl_registry * wl_display_get_registry(struct wl_display *wl_display)
static void wl_output_set_user_data(struct wl_output *wl_output, void *user_data)
static void wl_output_destroy(struct wl_output *wl_output)
static int wl_output_add_listener(struct wl_output *wl_output, const struct wl_output_listener *listener, void *data)
@ WL_OUTPUT_MODE_CURRENT
static void wl_registry_destroy(struct wl_registry *wl_registry)
static void * wl_registry_bind(struct wl_registry *wl_registry, uint32_t name, const struct wl_interface *interface, uint32_t version)
static int wl_registry_add_listener(struct wl_registry *wl_registry, const struct wl_registry_listener *listener, void *data)
static void wl_shell_destroy(struct wl_shell *wl_shell)
static void wl_shm_destroy(struct wl_shm *wl_shm)
static void xdg_wm_base_destroy(struct xdg_wm_base *xdg_wm_base)
static int xdg_wm_base_add_listener(struct xdg_wm_base *xdg_wm_base, const struct xdg_wm_base_listener *listener, void *data)
static void xdg_wm_base_pong(struct xdg_wm_base *xdg_wm_base, uint32_t serial)
static void zxdg_shell_v6_destroy(struct zxdg_shell_v6 *zxdg_shell_v6)
static int zxdg_shell_v6_add_listener(struct zxdg_shell_v6 *zxdg_shell_v6, const struct zxdg_shell_v6_listener *listener, void *data)
static void zxdg_shell_v6_pong(struct zxdg_shell_v6 *zxdg_shell_v6, uint32_t serial)
static SDL_AudioDeviceID device
Definition: loopwave.c:37
const struct wl_interface org_kde_kwin_server_decoration_manager_interface
The structure that defines a display mode.
Definition: SDL_video.h:54
void * driverdata
Definition: SDL_video.h:59
SDL_VideoDisplay * displays
Definition: SDL_sysvideo.h:316
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:131
SDL_DisplayMode * display_modes
Definition: SDL_sysvideo.h:130
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:132
const struct wl_interface wl_shm_interface
const struct wl_interface wl_output_interface
const struct wl_interface wl_shell_interface
const struct wl_interface wl_compositor_interface
const struct wl_interface wl_data_device_manager_interface
const struct wl_interface zxdg_decoration_manager_v1_interface
const struct wl_interface xdg_wm_base_interface
const struct wl_interface zxdg_shell_v6_interface