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) { QtExtendedSurface_Unsubscribe(wind->extended_surface, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION); QtExtendedSurface_Unsubscribe(wind->extended_surface, SDL_HINT_QTWAYLAND_WINDOW_FLAGS); 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; }
static void SetFullscreen(_THIS, SDL_Window * window, struct wl_output *output) { const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata; SDL_WindowData *wind = window->driverdata; if (viddata->shell.xdg) { if (output) { xdg_toplevel_set_fullscreen(wind->shell_surface.xdg.roleobj.toplevel, output); } else { xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel); } } else if (viddata->shell.zxdg) { if (output) { zxdg_toplevel_v6_set_fullscreen(wind->shell_surface.zxdg.roleobj.toplevel, output); } else { zxdg_toplevel_v6_unset_fullscreen(wind->shell_surface.zxdg.roleobj.toplevel); } } else { if (output) { wl_shell_surface_set_fullscreen(wind->shell_surface.wl, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, output); } else { wl_shell_surface_set_toplevel(wind->shell_surface.wl); } } WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); }
int Wayland_GLES_SwapWindow(_THIS, SDL_Window *window) { if (SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface) < 0) { return -1; } WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); return 0; }
SDL_GLContext Wayland_GLES_CreateContext(_THIS, SDL_Window * window) { SDL_GLContext context; context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); return context; }
void Wayland_MaximizeWindow(_THIS, SDL_Window * window) { SDL_WindowData *wind = window->driverdata; wl_shell_surface_set_maximized(wind->shell_surface, NULL); WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); }
void Wayland_RestoreWindow(_THIS, SDL_Window * window) { SDL_WindowData *wind = window->driverdata; wl_shell_surface_set_toplevel(wind->shell_surface); WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); }
void Wayland_VideoQuit(_THIS) { SDL_VideoData *data = _this->driverdata; int i; Wayland_FiniMouse (); for (i = 0; i < _this->num_displays; ++i) { SDL_VideoDisplay *display = &_this->displays[i]; wl_output_destroy(display->driverdata); display->driverdata = NULL; } Wayland_display_destroy_input(data); Wayland_display_destroy_pointer_constraints(data); Wayland_display_destroy_relative_pointer_manager(data); if (data->xkb_context) { WAYLAND_xkb_context_unref(data->xkb_context); data->xkb_context = NULL; } #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH if (data->windowmanager) qt_windowmanager_destroy(data->windowmanager); if (data->surface_extension) qt_surface_extension_destroy(data->surface_extension); Wayland_touch_destroy(data); #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ if (data->shm) wl_shm_destroy(data->shm); if (data->cursor_theme) WAYLAND_wl_cursor_theme_destroy(data->cursor_theme); if (data->shell) wl_shell_destroy(data->shell); if (data->compositor) wl_compositor_destroy(data->compositor); if (data->registry) wl_registry_destroy(data->registry); if (data->display) { WAYLAND_wl_display_flush(data->display); WAYLAND_wl_display_disconnect(data->display); } SDL_free(data->classname); free(data); _this->driverdata = NULL; }
void Wayland_SetWindowTitle(_THIS, SDL_Window * window) { SDL_WindowData *wind = window->driverdata; if (window->title != NULL) { wl_shell_surface_set_title(wind->shell_surface, window->title); } WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); }
int Wayland_GLES_LoadLibrary(_THIS, const char *path) { int ret; SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; ret = SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) data->display); Wayland_PumpEvents(_this); WAYLAND_wl_display_flush(data->display); return ret; }
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, NULL); else wl_shell_surface_set_toplevel(wind->shell_surface); WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); }
void Wayland_RestoreWindow(_THIS, SDL_Window * window) { SDL_WindowData *wind = window->driverdata; const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata; if (viddata->shell.xdg) { } else if (viddata->shell.zxdg) { } else { wl_shell_surface_set_toplevel(wind->shell_surface.wl); } 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, NULL); else wl_shell_surface_set_toplevel(wind->shell_surface); WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); }
int Wayland_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) { int ret; if (window && context) { ret = SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context); } else { ret = SDL_EGL_MakeCurrent(_this, NULL, NULL); } WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); return ret; }
void Wayland_MaximizeWindow(_THIS, SDL_Window * window) { SDL_WindowData *wind = window->driverdata; SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; if (viddata->shell.xdg) { xdg_toplevel_set_maximized(wind->shell_surface.xdg.roleobj.toplevel); } else if (viddata->shell.zxdg) { zxdg_toplevel_v6_set_maximized(wind->shell_surface.zxdg.roleobj.toplevel); } else { wl_shell_surface_set_maximized(wind->shell_surface.wl, NULL); } WAYLAND_wl_display_flush( viddata->display ); }
void Wayland_SetWindowTitle(_THIS, SDL_Window * window) { SDL_WindowData *wind = window->driverdata; SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; if (window->title != NULL) { if (viddata->shell.xdg) { xdg_toplevel_set_title(wind->shell_surface.xdg.roleobj.toplevel, window->title); } else if (viddata->shell.zxdg) { zxdg_toplevel_v6_set_title(wind->shell_surface.zxdg.roleobj.toplevel, window->title); } else { wl_shell_surface_set_title(wind->shell_surface.wl, window->title); } } WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); }
int Wayland_VideoInit(_THIS) { SDL_VideoData *data = SDL_malloc(sizeof *data); if (data == NULL) return SDL_OutOfMemory(); memset(data, 0, sizeof *data); _this->driverdata = data; data->xkb_context = WAYLAND_xkb_context_new(0); if (!data->xkb_context) { return SDL_SetError("Failed to create XKB context"); } data->display = WAYLAND_wl_display_connect(NULL); if (data->display == NULL) { return SDL_SetError("Failed to connect to a Wayland display"); } data->registry = wl_display_get_registry(data->display); if (data->registry == NULL) { return SDL_SetError("Failed to get the Wayland registry"); } wl_registry_add_listener(data->registry, ®istry_listener, data); // First roundtrip to receive all registry objects. WAYLAND_wl_display_roundtrip(data->display); // Second roundtrip to receive all output events. WAYLAND_wl_display_roundtrip(data->display); Wayland_InitMouse(); /* Get the surface class name, usually the name of the application */ data->classname = get_classname(); WAYLAND_wl_display_flush(data->display); return 0; }
void Wayland_display_add_input(SDL_VideoData *d, uint32_t id) { struct SDL_WaylandInput *input; SDL_WaylandDataDevice *data_device = NULL; input = SDL_calloc(1, sizeof *input); if (input == NULL) return; input->display = d; input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, 1); input->sx_w = wl_fixed_from_int(0); input->sy_w = wl_fixed_from_int(0); d->input = input; if (d->data_device_manager != NULL) { data_device = SDL_calloc(1, sizeof *data_device); if (data_device == NULL) { return; } data_device->data_device = wl_data_device_manager_get_data_device( d->data_device_manager, input->seat ); data_device->video_data = d; if (data_device->data_device == NULL) { SDL_free(data_device); } else { wl_data_device_set_user_data(data_device->data_device, data_device); wl_data_device_add_listener(data_device->data_device, &data_device_listener, data_device); input->data_device = data_device; } } wl_seat_add_listener(input->seat, &seat_listener, input); wl_seat_set_user_data(input->seat, input); WAYLAND_wl_display_flush(d->display); }
void Wayland_display_add_input(SDL_VideoData *d, uint32_t id) { struct SDL_WaylandInput *input; input = SDL_calloc(1, sizeof *input); if (input == NULL) return; input->display = d; input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, 1); input->sx_w = wl_fixed_from_int(0); input->sy_w = wl_fixed_from_int(0); d->input = input; wl_seat_add_listener(input->seat, &seat_listener, input); wl_seat_set_user_data(input->seat, input); WAYLAND_wl_display_flush(d->display); }
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; }
void Wayland_GLES_SwapWindow(_THIS, SDL_Window *window) { SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_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); wl_shell_surface_set_class (data->shell_surface, c->classname); #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); QtExtendedSurface_Subscribe(data->extended_surface, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION); QtExtendedSurface_Subscribe(data->extended_surface, SDL_HINT_QTWAYLAND_WINDOW_FLAGS); } #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); if (c->relative_mouse_mode) { Wayland_input_lock_pointer(c->input); } WAYLAND_wl_display_flush(c->display); return 0; }
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); if (c->shell.xdg) { data->shell_surface.xdg.surface = xdg_wm_base_get_xdg_surface(c->shell.xdg, data->surface); /* !!! FIXME: add popup role */ data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface); xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data); xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname); } else if (c->shell.zxdg) { data->shell_surface.zxdg.surface = zxdg_shell_v6_get_xdg_surface(c->shell.zxdg, data->surface); /* !!! FIXME: add popup role */ data->shell_surface.zxdg.roleobj.toplevel = zxdg_surface_v6_get_toplevel(data->shell_surface.zxdg.surface); zxdg_toplevel_v6_add_listener(data->shell_surface.zxdg.roleobj.toplevel, &toplevel_listener_zxdg, data); zxdg_toplevel_v6_set_app_id(data->shell_surface.zxdg.roleobj.toplevel, c->classname); } else { data->shell_surface.wl = wl_shell_get_shell_surface(c->shell.wl, data->surface); wl_shell_surface_set_class(data->shell_surface.wl, c->classname); } #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); QtExtendedSurface_Subscribe(data->extended_surface, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION); QtExtendedSurface_Subscribe(data->extended_surface, SDL_HINT_QTWAYLAND_WINDOW_FLAGS); } #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 (c->shell.xdg) { if (data->shell_surface.xdg.surface) { xdg_surface_set_user_data(data->shell_surface.xdg.surface, data); xdg_surface_add_listener(data->shell_surface.xdg.surface, &shell_surface_listener_xdg, data); } } else if (c->shell.zxdg) { if (data->shell_surface.zxdg.surface) { zxdg_surface_v6_set_user_data(data->shell_surface.zxdg.surface, data); zxdg_surface_v6_add_listener(data->shell_surface.zxdg.surface, &shell_surface_listener_zxdg, data); } } else { if (data->shell_surface.wl) { wl_shell_surface_set_user_data(data->shell_surface.wl, data); wl_shell_surface_add_listener(data->shell_surface.wl, &shell_surface_listener_wl, 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); if (c->relative_mouse_mode) { Wayland_input_lock_pointer(c->input); } wl_surface_commit(data->surface); WAYLAND_wl_display_flush(c->display); /* we have to wait until the surface gets a "configure" event, or use of this surface will fail. This is a new rule for xdg_shell. */ if (c->shell.xdg) { if (data->shell_surface.xdg.surface) { while (!data->shell_surface.xdg.initial_configure_seen) { WAYLAND_wl_display_flush(c->display); WAYLAND_wl_display_dispatch(c->display); } } } else if (c->shell.zxdg) { if (data->shell_surface.zxdg.surface) { while (!data->shell_surface.zxdg.initial_configure_seen) { WAYLAND_wl_display_flush(c->display); WAYLAND_wl_display_dispatch(c->display); } } } return 0; }
void Wayland_GLES_DeleteContext(_THIS, SDL_GLContext context) { SDL_EGL_DeleteContext(_this, context); 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 0; 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 */ /** * If the user specified 0x0 as the size (turned to 1x1 by SDL_CreateWindow * in SDL_video.c), we want to make the window fill the whole screen **/ if (window->w == 1) { window->w = c->screen_allocation.width; } if (window->h == 1) { window->h = c->screen_allocation.height; } 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) { SDL_SetError("failed to create a window surface"); return -1; } 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; }