void Wayland_PumpEvents(_THIS) { SDL_VideoData *d = _this->driverdata; struct pollfd pfd[1]; pfd[0].fd = WAYLAND_wl_display_get_fd(d->display); pfd[0].events = POLLIN; poll(pfd, 1, 0); if (pfd[0].revents & POLLIN) WAYLAND_wl_display_dispatch(d->display); else WAYLAND_wl_display_dispatch_pending(d->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); 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; }