Merge pull request #530 from soreau/master

wayland: Port to xdg-shell stable
This commit is contained in:
Sascha Willems 2019-01-20 10:01:51 +01:00 committed by GitHub
commit 7d5e022d54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 24 deletions

View file

@ -49,12 +49,28 @@ IF(USE_D2D_WSI)
MESSAGE("Using direct to display extension...") MESSAGE("Using direct to display extension...")
add_definitions(-D_DIRECT2DISPLAY) add_definitions(-D_DIRECT2DISPLAY)
ELSEIF(USE_WAYLAND_WSI) ELSEIF(USE_WAYLAND_WSI)
find_program(PKG_CONFIG pkg-config)
if (NOT PKG_CONFIG)
message(FATAL_ERROR "pkg-config binary not found")
endif ()
find_package(Wayland REQUIRED) find_package(Wayland REQUIRED)
if (NOT WAYLAND_FOUND) if (NOT WAYLAND_FOUND)
message(FATAL_ERROR "Wayland development package not found") message(FATAL_ERROR "Wayland development package not found")
endif () endif ()
pkg_check_modules(WAYLAND_PROTOCOLS REQUIRED wayland-protocols)
if (NOT WAYLAND_PROTOCOLS_FOUND)
message(FATAL_ERROR "Wayland protocols package not found")
endif ()
find_program(WAYLAND_SCANNER wayland-scanner)
if (NOT WAYLAND_SCANNER)
message(FATAL_ERROR "wayland-scanner binary not found")
endif ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_WAYLAND_KHR") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_WAYLAND_KHR")
include_directories(${WAYLAND_INCLUDE_DIR}) include_directories(${WAYLAND_INCLUDE_DIR})
execute_process(COMMAND ${PKG_CONFIG} --variable=pkgdatadir wayland-protocols OUTPUT_VARIABLE protocol_dir OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${WAYLAND_SCANNER} client-header ${protocol_dir}/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.h
COMMAND ${WAYLAND_SCANNER} private-code ${protocol_dir}/stable/xdg-shell/xdg-shell.xml xdg-shell-protocol.c)
include_directories(${CMAKE_BINARY_DIR})
ELSE(USE_D2D_WSI) ELSE(USE_D2D_WSI)
find_package(XCB REQUIRED) find_package(XCB REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_XCB_KHR") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_XCB_KHR")
@ -78,7 +94,7 @@ endif()
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_definitions(-std=c++11) set(CXXFLAGS -std=c++11)
file(GLOB SOURCE *.cpp ) file(GLOB SOURCE *.cpp )

View file

@ -456,6 +456,8 @@ void VulkanExampleBase::renderLoop()
viewChanged(); viewChanged();
} }
while (!configured)
wl_display_dispatch(display);
while (wl_display_prepare_read(display) != 0) while (wl_display_prepare_read(display) != 0)
wl_display_dispatch_pending(display); wl_display_dispatch_pending(display);
wl_display_flush(display); wl_display_flush(display);
@ -487,7 +489,7 @@ void VulkanExampleBase::renderLoop()
if (!settings.overlay) if (!settings.overlay)
{ {
std::string windowTitle = getWindowTitle(); std::string windowTitle = getWindowTitle();
wl_shell_surface_set_title(shell_surface, windowTitle.c_str()); xdg_toplevel_set_title(xdg_toplevel, windowTitle.c_str());
} }
lastFPS = (float)frameCounter * (1000.0f / fpsTimer); lastFPS = (float)frameCounter * (1000.0f / fpsTimer);
fpsTimer = 0.0f; fpsTimer = 0.0f;
@ -800,14 +802,15 @@ VulkanExampleBase::~VulkanExampleBase()
#if defined(_DIRECT2DISPLAY) #if defined(_DIRECT2DISPLAY)
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) #elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
wl_shell_surface_destroy(shell_surface); xdg_toplevel_destroy(xdg_toplevel);
xdg_surface_destroy(xdg_surface);
wl_surface_destroy(surface); wl_surface_destroy(surface);
if (keyboard) if (keyboard)
wl_keyboard_destroy(keyboard); wl_keyboard_destroy(keyboard);
if (pointer) if (pointer)
wl_pointer_destroy(pointer); wl_pointer_destroy(pointer);
wl_seat_destroy(seat); wl_seat_destroy(seat);
wl_shell_destroy(shell); xdg_wm_base_destroy(shell);
wl_compositor_destroy(compositor); wl_compositor_destroy(compositor);
wl_registry_destroy(registry); wl_registry_destroy(registry);
wl_display_disconnect(display); wl_display_disconnect(display);
@ -1631,6 +1634,15 @@ void VulkanExampleBase::seatCapabilities(wl_seat *seat, uint32_t caps)
} }
} }
static void xdg_wm_base_ping(void *data, struct xdg_wm_base *shell, uint32_t serial)
{
xdg_wm_base_pong(shell, serial);
}
static const struct xdg_wm_base_listener xdg_wm_base_listener = {
xdg_wm_base_ping,
};
void VulkanExampleBase::registryGlobal(wl_registry *registry, uint32_t name, void VulkanExampleBase::registryGlobal(wl_registry *registry, uint32_t name,
const char *interface, uint32_t version) const char *interface, uint32_t version)
{ {
@ -1639,10 +1651,11 @@ void VulkanExampleBase::registryGlobal(wl_registry *registry, uint32_t name,
compositor = (wl_compositor *) wl_registry_bind(registry, name, compositor = (wl_compositor *) wl_registry_bind(registry, name,
&wl_compositor_interface, 3); &wl_compositor_interface, 3);
} }
else if (strcmp(interface, "wl_shell") == 0) else if (strcmp(interface, "xdg_wm_base") == 0)
{ {
shell = (wl_shell *) wl_registry_bind(registry, name, shell = (xdg_wm_base *) wl_registry_bind(registry, name,
&wl_shell_interface, 1); &xdg_wm_base_interface, 1);
xdg_wm_base_add_listener(shell, &xdg_wm_base_listener, nullptr);
} }
else if (strcmp(interface, "wl_seat") == 0) else if (strcmp(interface, "wl_seat") == 0)
{ {
@ -1691,34 +1704,70 @@ void VulkanExampleBase::initWaylandConnection()
} }
} }
static void PingCb(void *data, struct wl_shell_surface *shell_surface, void VulkanExampleBase::setSize(int width, int height)
uint32_t serial)
{ {
wl_shell_surface_pong(shell_surface, serial); if (width <= 0 || height <= 0)
return;
destWidth = width;
destHeight = height;
windowResize();
} }
static void ConfigureCb(void *data, struct wl_shell_surface *shell_surface, static void
uint32_t edges, int32_t width, int32_t height) xdg_surface_handle_configure(void *data, struct xdg_surface *surface,
uint32_t serial)
{ {
VulkanExampleBase *base = (VulkanExampleBase *) data;
xdg_surface_ack_configure(surface, serial);
base->configured = true;
} }
static void PopupDoneCb(void *data, struct wl_shell_surface *shell_surface) static const struct xdg_surface_listener xdg_surface_listener = {
xdg_surface_handle_configure,
};
static void
xdg_toplevel_handle_configure(void *data, struct xdg_toplevel *toplevel,
int32_t width, int32_t height,
struct wl_array *states)
{ {
VulkanExampleBase *base = (VulkanExampleBase *) data;
base->setSize(width, height);
} }
wl_shell_surface *VulkanExampleBase::setupWindow() static void
xdg_toplevel_handle_close(void *data, struct xdg_toplevel *xdg_toplevel)
{
VulkanExampleBase *base = (VulkanExampleBase *) data;
base->quit = true;
}
static const struct xdg_toplevel_listener xdg_toplevel_listener = {
xdg_toplevel_handle_configure,
xdg_toplevel_handle_close,
};
struct xdg_surface *VulkanExampleBase::setupWindow()
{ {
surface = wl_compositor_create_surface(compositor); surface = wl_compositor_create_surface(compositor);
shell_surface = wl_shell_get_shell_surface(shell, surface); xdg_surface = xdg_wm_base_get_xdg_surface(shell, surface);
static const struct wl_shell_surface_listener shell_surface_listener = xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, this);
{ PingCb, ConfigureCb, PopupDoneCb }; xdg_toplevel = xdg_surface_get_toplevel(xdg_surface);
xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, this);
wl_shell_surface_add_listener(shell_surface, &shell_surface_listener, this);
wl_shell_surface_set_toplevel(shell_surface);
std::string windowTitle = getWindowTitle(); std::string windowTitle = getWindowTitle();
wl_shell_surface_set_title(shell_surface, windowTitle.c_str()); xdg_toplevel_set_title(xdg_toplevel, windowTitle.c_str());
return shell_surface; wl_surface_commit(surface);
return xdg_surface;
} }
#elif defined(VK_USE_PLATFORM_XCB_KHR) #elif defined(VK_USE_PLATFORM_XCB_KHR)

View file

@ -22,6 +22,7 @@
#include "VulkanAndroid.h" #include "VulkanAndroid.h"
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) #elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
#include <wayland-client.h> #include <wayland-client.h>
#include "xdg-shell-client-protocol.h"
#elif defined(_DIRECT2DISPLAY) #elif defined(_DIRECT2DISPLAY)
// //
#elif defined(VK_USE_PLATFORM_XCB_KHR) #elif defined(VK_USE_PLATFORM_XCB_KHR)
@ -227,13 +228,15 @@ public:
wl_display *display = nullptr; wl_display *display = nullptr;
wl_registry *registry = nullptr; wl_registry *registry = nullptr;
wl_compositor *compositor = nullptr; wl_compositor *compositor = nullptr;
wl_shell *shell = nullptr; struct xdg_wm_base *shell = nullptr;
wl_seat *seat = nullptr; wl_seat *seat = nullptr;
wl_pointer *pointer = nullptr; wl_pointer *pointer = nullptr;
wl_keyboard *keyboard = nullptr; wl_keyboard *keyboard = nullptr;
wl_surface *surface = nullptr; wl_surface *surface = nullptr;
wl_shell_surface *shell_surface = nullptr; struct xdg_surface *xdg_surface;
struct xdg_toplevel *xdg_toplevel;
bool quit = false; bool quit = false;
bool configured = false;
#elif defined(_DIRECT2DISPLAY) #elif defined(_DIRECT2DISPLAY)
bool quit = false; bool quit = false;
@ -265,8 +268,9 @@ public:
#elif (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK)) #elif (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK))
void* setupWindow(void* view); void* setupWindow(void* view);
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) #elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
wl_shell_surface *setupWindow(); struct xdg_surface *setupWindow();
void initWaylandConnection(); void initWaylandConnection();
void setSize(int width, int height);
static void registryGlobalCb(void *data, struct wl_registry *registry, static void registryGlobalCb(void *data, struct wl_registry *registry,
uint32_t name, const char *interface, uint32_t version); uint32_t name, const char *interface, uint32_t version);
void registryGlobal(struct wl_registry *registry, uint32_t name, void registryGlobal(struct wl_registry *registry, uint32_t name,

View file

@ -13,6 +13,10 @@ function(buildExample EXAMPLE_NAME)
file(GLOB ADD_SOURCE "../external/imgui/*.cpp") file(GLOB ADD_SOURCE "../external/imgui/*.cpp")
SET(SOURCE ${SOURCE} ${ADD_SOURCE}) SET(SOURCE ${SOURCE} ${ADD_SOURCE})
ENDIF() ENDIF()
# wayland requires additional source files
IF(USE_WAYLAND_WSI)
SET(SOURCE ${SOURCE} ${CMAKE_BINARY_DIR}/xdg-shell-client-protocol.h ${CMAKE_BINARY_DIR}/xdg-shell-protocol.c)
ENDIF()
# Add shaders # Add shaders
set(SHADER_DIR "../data/shaders/${EXAMPLE_NAME}") set(SHADER_DIR "../data/shaders/${EXAMPLE_NAME}")
file(GLOB SHADERS "${SHADER_DIR}/*.vert" "${SHADER_DIR}/*.frag" "${SHADER_DIR}/*.comp" "${SHADER_DIR}/*.geom" "${SHADER_DIR}/*.tesc" "${SHADER_DIR}/*.tese") file(GLOB SHADERS "${SHADER_DIR}/*.vert" "${SHADER_DIR}/*.frag" "${SHADER_DIR}/*.comp" "${SHADER_DIR}/*.geom" "${SHADER_DIR}/*.tesc" "${SHADER_DIR}/*.tese")