|
| 1 | +#pragma once |
| 2 | + |
| 3 | +#include <vsg/app/Window.h> |
| 4 | +#include <vsg/ui/KeyEvent.h> |
| 5 | + |
| 6 | +#include <wayland-client.h> |
| 7 | +#include <wayland-egl.h> |
| 8 | +#include <wayland-cursor.h> |
| 9 | +#include <xkbcommon/xkbcommon.h> |
| 10 | + |
| 11 | +#include <vsg/platform/wayland/wayland-xdg-shell-client-protocol.h> |
| 12 | +#include <vsg/platform/wayland/xdg-decoration-client.h> |
| 13 | +#include <vsg/ui/PointerEvent.h> |
| 14 | +#include <vulkan/vulkan_wayland.h> |
| 15 | + |
| 16 | +namespace vsgWayland |
| 17 | +{ |
| 18 | + |
| 19 | + class KeyboardMap : public vsg::Object |
| 20 | + { |
| 21 | + public: |
| 22 | + KeyboardMap(); |
| 23 | + |
| 24 | + using KeycodeModifier = std::pair<uint32_t, uint32_t>; |
| 25 | + using KeycodeMap = std::map<KeycodeModifier, vsg::KeySymbol>; |
| 26 | + |
| 27 | + void add(uint32_t keycode, uint32_t modifier, vsg::KeySymbol key); |
| 28 | + |
| 29 | + void add(uint32_t keycode, std::initializer_list<std::pair<uint32_t, vsg::KeySymbol>> combinations); |
| 30 | + |
| 31 | + vsg::KeySymbol getKeySymbol(uint32_t keycode, uint32_t modifier); |
| 32 | + vsg::KeyModifier getKeyModifier(vsg::KeySymbol keySym, uint32_t modifier, bool pressed); |
| 33 | + |
| 34 | + protected: |
| 35 | + KeycodeMap _keycodeMap; |
| 36 | + uint32_t _modifierMask; |
| 37 | + }; |
| 38 | + |
| 39 | + class Wayland_surface : public vsg::Surface |
| 40 | + { |
| 41 | + public: |
| 42 | + Wayland_surface(vsg::Instance* instance, wl_display* wlDisplay, wl_surface* wlSurface); |
| 43 | + }; |
| 44 | + |
| 45 | + class Wayland_Window : public vsg::Inherit<vsg::Window, Wayland_Window> |
| 46 | + { |
| 47 | + public: |
| 48 | + Wayland_Window(vsg::ref_ptr<vsg::WindowTraits> traits); |
| 49 | + Wayland_Window() = delete; |
| 50 | + Wayland_Window(const Wayland_Window&) = delete; |
| 51 | + Wayland_Window& operator=(const Wayland_Window&) = delete; |
| 52 | + |
| 53 | + const char* instanceExtensionSurfaceName() const override { return VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME; } |
| 54 | + |
| 55 | + bool valid() const override; |
| 56 | + |
| 57 | + bool visible() const override; |
| 58 | + |
| 59 | + void releaseWindow() override; |
| 60 | + void releaseConnection() override; |
| 61 | + |
| 62 | + bool pollEvents(vsg::UIEvents& events) override; |
| 63 | + |
| 64 | + void resize() override; |
| 65 | + protected: |
| 66 | + ~Wayland_Window(); |
| 67 | + |
| 68 | + void _initSurface() override; |
| 69 | + |
| 70 | + static void keymapEvent(void* data, wl_keyboard *wl_keyboard, uint32_t format, int32_t fd, uint32_t size); |
| 71 | + static void kbd_enter_event(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys); |
| 72 | + static void kbd_leave_event(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface); |
| 73 | + static void kbd_key_event(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state); |
| 74 | + static void kbd_modifier_event(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group); |
| 75 | + constexpr static struct wl_keyboard_listener wl_keyboard_listener = { |
| 76 | + .keymap = keymapEvent, |
| 77 | + .enter = kbd_enter_event, |
| 78 | + .leave = kbd_leave_event, |
| 79 | + .key = kbd_key_event, |
| 80 | + .modifiers = kbd_modifier_event |
| 81 | + }; |
| 82 | + |
| 83 | + static void xdg_surface_handle_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial); |
| 84 | + constexpr static struct xdg_surface_listener xdg_surface_listener = { |
| 85 | + .configure = xdg_surface_handle_configure, |
| 86 | + }; |
| 87 | + |
| 88 | + static void xdg_toplevel_handle_configure(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *states); |
| 89 | + static void xdg_toplevel_handle_close(void *data, struct xdg_toplevel *xdg_toplevel); |
| 90 | + constexpr static struct xdg_toplevel_listener xdg_toplevel_listener = { |
| 91 | + .configure = xdg_toplevel_handle_configure, |
| 92 | + .close = xdg_toplevel_handle_close, |
| 93 | + }; |
| 94 | + |
| 95 | + static void xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial); |
| 96 | + constexpr static struct xdg_wm_base_listener xdg_wm_base_listener = { |
| 97 | + .ping = xdg_wm_base_ping |
| 98 | + }; |
| 99 | + |
| 100 | + static void pointer_enter (void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y); |
| 101 | + static void pointer_leave (void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface); |
| 102 | + static void pointer_motion (void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y); |
| 103 | + static void pointer_button (void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state); |
| 104 | + static void pointer_axis (void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value); |
| 105 | + constexpr static struct wl_pointer_listener pointer_listener = { |
| 106 | + &pointer_enter, |
| 107 | + &pointer_leave, |
| 108 | + &pointer_motion, |
| 109 | + &pointer_button, |
| 110 | + &pointer_axis |
| 111 | + }; |
| 112 | + |
| 113 | + static void seat_capabilities (void *data, struct wl_seat *seat, uint32_t capabilities); |
| 114 | + constexpr static struct wl_seat_listener seat_listener = { |
| 115 | + &seat_capabilities |
| 116 | + }; |
| 117 | + |
| 118 | + static void registry_add_object(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version); |
| 119 | + static void registry_remove_object(void *data, struct wl_registry *registry, uint32_t id); |
| 120 | + constexpr static struct wl_registry_listener registry_listener = { |
| 121 | + ®istry_add_object, |
| 122 | + ®istry_remove_object |
| 123 | + }; |
| 124 | + |
| 125 | + static void shell_surface_ping (void *data, struct wl_shell_surface *shell_surface, uint32_t serial); |
| 126 | + static void shell_surface_configure(void *data, struct wl_shell_surface *shell_surface, uint32_t edges, int32_t width, int32_t height); |
| 127 | + static void shell_surface_popup_done (void *data, struct wl_shell_surface *shell_surface); |
| 128 | + constexpr static struct wl_shell_surface_listener shell_surface_listener = { |
| 129 | + &shell_surface_ping, |
| 130 | + &shell_surface_configure, |
| 131 | + &shell_surface_popup_done |
| 132 | + }; |
| 133 | + |
| 134 | + struct wl_display* _wlDisplay = nullptr; |
| 135 | + struct wl_registry* _wlRegistry = nullptr; |
| 136 | + struct wl_compositor* _wlCompositor = nullptr; |
| 137 | + struct wl_seat* _seat = nullptr; |
| 138 | + struct wl_shm* _shm = nullptr; |
| 139 | + struct wl_cursor_theme* _cursorTheme = nullptr; |
| 140 | + struct wl_surface* _cursorSurface = nullptr; |
| 141 | + struct zxdg_decoration_manager_v1* _decorationManager = nullptr; |
| 142 | + struct xdg_wm_base* _xdgWmBase = nullptr; |
| 143 | + //struct wl_subcompositor *subcompositor; |
| 144 | + struct wl_surface* _wlSurface = nullptr; |
| 145 | + struct xdg_surface* _xdgSurface = nullptr; |
| 146 | + struct xdg_toplevel* _xdgToplevel = nullptr; |
| 147 | + struct wl_surface* _currentSurface = nullptr; |
| 148 | + struct zxdg_toplevel_decoration_v1* _topDecoration = nullptr; |
| 149 | + struct xkb_state *_xkb_state; |
| 150 | + struct xkb_context *_xkb_context; |
| 151 | + struct xkb_keymap *_xkb_keymap; |
| 152 | + |
| 153 | + int _width = 256; |
| 154 | + int _height = 256; |
| 155 | + int cursor_x = -1; |
| 156 | + int cursor_y = -1; |
| 157 | + bool _resize = false; |
| 158 | + uint16_t maskButtons; |
| 159 | + |
| 160 | + vsg::ref_ptr<KeyboardMap> _keyboard; |
| 161 | + }; |
| 162 | +} // namespace vsgWayland |
| 163 | + |
| 164 | +EVSG_type_name(vsgWayland::Wayland_Window); |
0 commit comments