aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Bzdek <joey@lunarg.com>2017-06-07 09:40:36 -0600
committerjoey-lunarg <joey@lunarg.com>2017-07-14 14:15:00 -0600
commit15eb070fdbfc376e872555ba170429fc5aacebda (patch)
tree469c3d56880e847fe8ba1060c0763279c3319b2c
parentbaf6647a08476a85ba40ee1087af96fa9b868ddb (diff)
downloadusermoji-15eb070fdbfc376e872555ba170429fc5aacebda.tar.xz
demos: Add Wayland input handling to cube
Change-Id: I314ad9bc3e297da93f4d5c1d44289c9cca3a8fde
-rw-r--r--demos/cube.c116
-rw-r--r--demos/cube.cpp102
2 files changed, 202 insertions, 16 deletions
diff --git a/demos/cube.c b/demos/cube.c
index 576f0a42..0fd29f91 100644
--- a/demos/cube.c
+++ b/demos/cube.c
@@ -35,6 +35,8 @@
#include <signal.h>
#if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR)
#include <X11/Xutil.h>
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+#include <linux/input.h>
#endif
#ifdef _WIN32
@@ -335,6 +337,9 @@ struct demo {
struct wl_surface *window;
struct wl_shell *shell;
struct wl_shell_surface *shell_surface;
+ struct wl_seat *seat;
+ struct wl_pointer *pointer;
+ struct wl_keyboard *keyboard;
#elif defined(VK_USE_PLATFORM_MIR_KHR)
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
ANativeWindow *window;
@@ -510,7 +515,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL dbgFunc(VkFlags msgFlags, VkDebugReportObjectType
free(message);
- //clang-format on
+ // clang-format on
/*
* false indicates that layer should not bail-out of an
@@ -2403,6 +2408,9 @@ static void demo_cleanup(struct demo *demo) {
xcb_disconnect(demo->connection);
free(demo->atom_wm_delete_window);
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+ wl_keyboard_destroy(demo->keyboard);
+ wl_pointer_destroy(demo->pointer);
+ wl_seat_destroy(demo->seat);
wl_shell_surface_destroy(demo->shell_surface);
wl_surface_destroy(demo->window);
wl_shell_destroy(demo->shell);
@@ -2771,10 +2779,15 @@ static void demo_create_xcb_window(struct demo *demo) {
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
static void demo_run(struct demo *demo) {
while (!demo->quit) {
- demo_draw(demo);
- demo->curFrame++;
- if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount)
- demo->quit = true;
+ if (demo->pause) {
+ wl_display_dispatch(demo->display); // block and wait for input
+ }
+ else {
+ wl_display_dispatch_pending(demo->display); // don't block
+ demo_draw(demo);
+ demo->curFrame++;
+ if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) demo->quit = true;
+ }
}
}
@@ -3715,17 +3728,96 @@ static void demo_init_vk_swapchain(struct demo *demo) {
}
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
-static void registry_handle_global(void *data, struct wl_registry *registry,
- uint32_t name, const char *interface,
+static void pointer_handle_enter(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t sx,
+ wl_fixed_t sy) {}
+
+static void pointer_handle_leave(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface) {}
+
+static void pointer_handle_motion(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy) {}
+
+static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button,
+ uint32_t state) {
+ struct demo *demo = data;
+ if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED) {
+ wl_shell_surface_move(demo->shell_surface, demo->seat, serial);
+ }
+}
+
+static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {}
+
+static const struct wl_pointer_listener pointer_listener = {
+ pointer_handle_enter, pointer_handle_leave, pointer_handle_motion, pointer_handle_button, pointer_handle_axis,
+};
+
+static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size) {}
+
+static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface,
+ struct wl_array *keys) {}
+
+static void keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface) {}
+
+static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key,
+ uint32_t state) {
+ if (state != WL_KEYBOARD_KEY_STATE_RELEASED) return;
+ struct demo *demo = data;
+ switch (key) {
+ case KEY_ESC: // Escape
+ demo->quit = true;
+ break;
+ case KEY_LEFT: // left arrow key
+ demo->spin_angle -= demo->spin_increment;
+ break;
+ case KEY_RIGHT: // right arrow key
+ demo->spin_angle += demo->spin_increment;
+ break;
+ case KEY_SPACE: // space bar
+ demo->pause = !demo->pause;
+ break;
+ }
+}
+
+static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed,
+ uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {}
+
+static const struct wl_keyboard_listener keyboard_listener = {
+ keyboard_handle_keymap, keyboard_handle_enter, keyboard_handle_leave, keyboard_handle_key, keyboard_handle_modifiers,
+};
+
+static void seat_handle_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps) {
+ // Subscribe to pointer events
+ struct demo *demo = data;
+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !demo->pointer) {
+ demo->pointer = wl_seat_get_pointer(seat);
+ wl_pointer_add_listener(demo->pointer, &pointer_listener, demo);
+ } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && demo->pointer) {
+ wl_pointer_destroy(demo->pointer);
+ demo->pointer = NULL;
+ }
+ // Subscribe to keyboard events
+ if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
+ demo->keyboard = wl_seat_get_keyboard(seat);
+ wl_keyboard_add_listener(demo->keyboard, &keyboard_listener, demo);
+ } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
+ wl_keyboard_destroy(demo->keyboard);
+ demo->keyboard = NULL;
+ }
+}
+
+static const struct wl_seat_listener seat_listener = {
+ seat_handle_capabilities,
+};
+
+static void registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface,
uint32_t version UNUSED) {
struct demo *demo = data;
+ // pickup wayland objects when they appear
if (strcmp(interface, "wl_compositor") == 0) {
- demo->compositor =
- wl_registry_bind(registry, name, &wl_compositor_interface, 3);
- /* Todo: When xdg_shell protocol has stablized, we should move wl_shell
- * tp xdg_shell */
+ demo->compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 1);
} else if (strcmp(interface, "wl_shell") == 0) {
- demo->shell = wl_registry_bind(registry, name, &wl_shell_interface, 1);
+ demo->shell = wl_registry_bind(registry, id, &wl_shell_interface, 1);
+ } else if (strcmp(interface, "wl_seat") == 0) {
+ demo->seat = wl_registry_bind(registry, id, &wl_seat_interface, 1);
+ wl_seat_add_listener(demo->seat, &seat_listener, demo);
}
}
diff --git a/demos/cube.cpp b/demos/cube.cpp
index f6a6975b..87a01d99 100644
--- a/demos/cube.cpp
+++ b/demos/cube.cpp
@@ -20,6 +20,8 @@
#if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR)
#include <X11/Xutil.h>
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+#include <linux/input.h>
#endif
#include <cassert>
@@ -399,12 +401,101 @@ static void handle_popup_done(void *data, wl_shell_surface *shell_surface) {}
static const wl_shell_surface_listener shell_surface_listener = {handle_ping, handle_configure, handle_popup_done};
-static void handle_announce_global_object(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface,
- uint32_t version) {}
+static void pointer_handle_enter(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t sx,
+ wl_fixed_t sy) {}
+
+static void pointer_handle_leave(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface) {}
+
+static void pointer_handle_motion(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy) {}
+
+static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button,
+ uint32_t state) {
+ Demo *demo = (Demo *)data;
+ if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED) {
+ wl_shell_surface_move(demo->shell_surface, demo->seat, serial);
+ }
+}
+
+static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {}
+
+static const struct wl_pointer_listener pointer_listener = {
+ pointer_handle_enter, pointer_handle_leave, pointer_handle_motion, pointer_handle_button, pointer_handle_axis,
+};
+
+static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size) {}
+
+static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface,
+ struct wl_array *keys) {}
+
+static void keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface) {}
+
+static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key,
+ uint32_t state) {
+ if (state != WL_KEYBOARD_KEY_STATE_RELEASED) return;
+ Demo *demo = (Demo *)data;
+ switch (key) {
+ case KEY_ESC: // Escape
+ demo->quit = true;
+ break;
+ case KEY_LEFT: // left arrow key
+ demo->spin_angle -= demo->spin_increment;
+ break;
+ case KEY_RIGHT: // right arrow key
+ demo->spin_angle += demo->spin_increment;
+ break;
+ case KEY_SPACE: // space bar
+ demo->pause = !demo->pause;
+ break;
+ }
+}
+
+static void keyboard_handle_modifiers(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed,
+ uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {}
+
+static const struct wl_keyboard_listener keyboard_listener = {
+ keyboard_handle_keymap, keyboard_handle_enter, keyboard_handle_leave, keyboard_handle_key, keyboard_handle_modifiers,
+};
+
+static void seat_handle_capabilities(void *data, wl_seat *seat, uint32_t caps) {
+ // Subscribe to pointer events
+ Demo *demo = (Demo *)data;
+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !demo->pointer) {
+ demo->pointer = wl_seat_get_pointer(seat);
+ wl_pointer_add_listener(demo->pointer, &pointer_listener, demo);
+ } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && demo->pointer) {
+ wl_pointer_destroy(demo->pointer);
+ demo->pointer = NULL;
+ }
+ // Subscribe to keyboard events
+ if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
+ demo->keyboard = wl_seat_get_keyboard(seat);
+ wl_keyboard_add_listener(demo->keyboard, &keyboard_listener, demo);
+ } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
+ wl_keyboard_destroy(demo->keyboard);
+ demo->keyboard = NULL;
+ }
+}
+
+static const wl_seat_listener seat_listener = {
+ seat_handle_capabilities,
+};
+
+static void registry_handle_global(void *data, wl_registry *registry, uint32_t id, const char *interface, uint32_t version) {
+ Demo *demo = (Demo *)data;
+ // pickup wayland objects when they appear
+ if (strcmp(interface, "wl_compositor") == 0) {
+ demo->compositor = (wl_compositor *)wl_registry_bind(registry, id, &wl_compositor_interface, 1);
+ } else if (strcmp(interface, "wl_shell") == 0) {
+ demo->shell = (wl_shell *)wl_registry_bind(registry, id, &wl_shell_interface, 1);
+ } else if (strcmp(interface, "wl_seat") == 0) {
+ demo->seat = (wl_seat *)wl_registry_bind(registry, id, &wl_seat_interface, 1);
+ wl_seat_add_listener(demo->seat, &seat_listener, demo);
+ }
+}
-static void handle_announce_global_object_remove(void *data, struct wl_registry *wl_registry, uint32_t name) {}
+static void registry_handle_global_remove(void *data, wl_registry *registry, uint32_t name) {}
-static const wl_registry_listener registry_listener = {handle_announce_global_object, handle_announce_global_object_remove};
+static const wl_registry_listener registry_listener = {registry_handle_global, registry_handle_global_remove};
#elif defined(VK_USE_PLATFORM_MIR_KHR)
#endif
@@ -570,6 +661,9 @@ Demo::Demo()
xcb_disconnect(connection);
free(atom_wm_delete_window);
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+ wl_keyboard_destroy(keyboard);
+ wl_pointer_destroy(pointer);
+ wl_seat_destroy(seat);
wl_shell_surface_destroy(shell_surface);
wl_surface_destroy(window);
wl_shell_destroy(shell);