| | |
| | | /* |
| | | Simple DirectMedia Layer |
| | | Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org> |
| | | Copyright (C) 1997-2018 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 |
| | |
| | | #include "SDL_waylandopengles.h" |
| | | #include "SDL_waylandmouse.h" |
| | | #include "SDL_waylandtouch.h" |
| | | #include "SDL_waylandclipboard.h" |
| | | #include "SDL_waylandvulkan.h" |
| | | |
| | | #include <sys/types.h> |
| | | #include <unistd.h> |
| | |
| | | |
| | | #include "SDL_waylanddyn.h" |
| | | #include <wayland-util.h> |
| | | |
| | | #include "xdg-shell-unstable-v6-client-protocol.h" |
| | | |
| | | #define WAYLANDVID_DRIVER_NAME "wayland" |
| | | |
| | |
| | | static char * |
| | | get_classname() |
| | | { |
| | | /* !!! FIXME: this is probably wrong, albeit harmless in many common cases. From protocol spec: |
| | | "The surface class identifies the general class of applications |
| | | to which the surface belongs. A common convention is to use the |
| | | file name (or the full path if it is a non-standard location) of |
| | | the application's .desktop file as the class." */ |
| | | |
| | | char *spot; |
| | | #if defined(__LINUX__) || defined(__FREEBSD__) |
| | | char procfile[1024]; |
| | |
| | | device->GL_GetProcAddress = Wayland_GLES_GetProcAddress; |
| | | device->GL_DeleteContext = Wayland_GLES_DeleteContext; |
| | | |
| | | device->CreateWindow = Wayland_CreateWindow; |
| | | device->CreateSDLWindow = Wayland_CreateWindow; |
| | | device->ShowWindow = Wayland_ShowWindow; |
| | | device->SetWindowFullscreen = Wayland_SetWindowFullscreen; |
| | | device->MaximizeWindow = Wayland_MaximizeWindow; |
| | |
| | | device->SetWindowTitle = Wayland_SetWindowTitle; |
| | | device->DestroyWindow = Wayland_DestroyWindow; |
| | | device->SetWindowHitTest = Wayland_SetWindowHitTest; |
| | | |
| | | device->SetClipboardText = Wayland_SetClipboardText; |
| | | device->GetClipboardText = Wayland_GetClipboardText; |
| | | device->HasClipboardText = Wayland_HasClipboardText; |
| | | |
| | | #if SDL_VIDEO_VULKAN |
| | | device->Vulkan_LoadLibrary = Wayland_Vulkan_LoadLibrary; |
| | | device->Vulkan_UnloadLibrary = Wayland_Vulkan_UnloadLibrary; |
| | | device->Vulkan_GetInstanceExtensions = Wayland_Vulkan_GetInstanceExtensions; |
| | | device->Vulkan_CreateSurface = Wayland_Vulkan_CreateSurface; |
| | | #endif |
| | | |
| | | device->free = Wayland_DeleteDevice; |
| | | |
| | |
| | | SDL_DisplayMode mode; |
| | | |
| | | SDL_zero(mode); |
| | | mode.format = SDL_PIXELFORMAT_RGB888; |
| | | mode.w = width; |
| | | mode.h = height; |
| | | mode.refresh_rate = refresh / 1000; // mHz to Hz |
| | | mode.driverdata = display->driverdata; |
| | | SDL_AddDisplayMode(display, &mode); |
| | | |
| | | if (flags & WL_OUTPUT_MODE_CURRENT) { |
| | |
| | | output = wl_registry_bind(d->registry, id, &wl_output_interface, 2); |
| | | if (!output) { |
| | | SDL_SetError("Failed to retrieve output."); |
| | | SDL_free(display); |
| | | return; |
| | | } |
| | | |
| | |
| | | }; |
| | | #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ |
| | | |
| | | |
| | | static void |
| | | handle_ping_zxdg_shell(void *data, struct zxdg_shell_v6 *zxdg, uint32_t serial) |
| | | { |
| | | zxdg_shell_v6_pong(zxdg, serial); |
| | | } |
| | | |
| | | static const struct zxdg_shell_v6_listener shell_listener_zxdg = { |
| | | handle_ping_zxdg_shell |
| | | }; |
| | | |
| | | |
| | | static void |
| | | display_handle_global(void *data, struct wl_registry *registry, uint32_t id, |
| | | const char *interface, uint32_t version) |
| | |
| | | Wayland_add_display(d, id); |
| | | } else if (strcmp(interface, "wl_seat") == 0) { |
| | | Wayland_display_add_input(d, id); |
| | | } else if (strcmp(interface, "zxdg_shell_v6") == 0) { |
| | | d->shell.zxdg = wl_registry_bind(d->registry, id, &zxdg_shell_v6_interface, 1); |
| | | zxdg_shell_v6_add_listener(d->shell.zxdg, &shell_listener_zxdg, NULL); |
| | | } else if (strcmp(interface, "wl_shell") == 0) { |
| | | d->shell = wl_registry_bind(d->registry, id, &wl_shell_interface, 1); |
| | | d->shell.wl = wl_registry_bind(d->registry, id, &wl_shell_interface, 1); |
| | | } else if (strcmp(interface, "wl_shm") == 0) { |
| | | d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); |
| | | d->cursor_theme = WAYLAND_wl_cursor_theme_load(NULL, 32, d->shm); |
| | |
| | | Wayland_display_add_relative_pointer_manager(d, id); |
| | | } else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) { |
| | | Wayland_display_add_pointer_constraints(d, id); |
| | | } else if (strcmp(interface, "wl_data_device_manager") == 0) { |
| | | d->data_device_manager = wl_registry_bind(d->registry, id, &wl_data_device_manager_interface, 3); |
| | | |
| | | #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH |
| | | } else if (strcmp(interface, "qt_touch_extension") == 0) { |
| | | Wayland_touch_create(d, id); |
| | |
| | | } |
| | | |
| | | static const struct wl_registry_listener registry_listener = { |
| | | display_handle_global |
| | | display_handle_global, |
| | | NULL, /* global_remove */ |
| | | }; |
| | | |
| | | int |
| | |
| | | Wayland_VideoQuit(_THIS) |
| | | { |
| | | SDL_VideoData *data = _this->driverdata; |
| | | int i; |
| | | int i, j; |
| | | |
| | | Wayland_FiniMouse (); |
| | | |
| | |
| | | SDL_VideoDisplay *display = &_this->displays[i]; |
| | | wl_output_destroy(display->driverdata); |
| | | display->driverdata = NULL; |
| | | |
| | | for (j = display->num_display_modes; j--;) { |
| | | display->display_modes[j].driverdata = NULL; |
| | | } |
| | | display->desktop_mode.driverdata = NULL; |
| | | } |
| | | |
| | | Wayland_display_destroy_input(data); |
| | |
| | | if (data->cursor_theme) |
| | | WAYLAND_wl_cursor_theme_destroy(data->cursor_theme); |
| | | |
| | | if (data->shell) |
| | | wl_shell_destroy(data->shell); |
| | | if (data->shell.wl) |
| | | wl_shell_destroy(data->shell.wl); |
| | | |
| | | if (data->shell.zxdg) |
| | | zxdg_shell_v6_destroy(data->shell.zxdg); |
| | | |
| | | if (data->compositor) |
| | | wl_compositor_destroy(data->compositor); |
| | |
| | | } |
| | | |
| | | SDL_free(data->classname); |
| | | free(data); |
| | | SDL_free(data); |
| | | _this->driverdata = NULL; |
| | | } |
| | | |