diff --git a/Samples/Tests/main_SDL2.cpp b/Samples/Tests/main_SDL2.cpp index f82bf5e68..e9fc02beb 100644 --- a/Samples/Tests/main_SDL2.cpp +++ b/Samples/Tests/main_SDL2.cpp @@ -98,6 +98,16 @@ void wayland_loop(wi::wayland::Backend &wwbackend, Tests &tests) { bool quit = false; wwbackend.window.on_close = [&quit](wi::wayland::Window*w) { quit = true; }; + wwbackend.window.on_focus_on = [&tests](wi::wayland::Window*w) + { + tests.is_window_active = true; + std::clog << "window on enter" << std::endl; + }; + wwbackend.window.on_focus_off = [&tests](wi::wayland::Window*w) + { + tests.is_window_active = false; + std::clog << "window on leave" << std::endl; + }; while(!quit) { diff --git a/WickedEngine/CMakeLists.txt b/WickedEngine/CMakeLists.txt index e0c8e7356..8e8a0915c 100644 --- a/WickedEngine/CMakeLists.txt +++ b/WickedEngine/CMakeLists.txt @@ -54,6 +54,7 @@ else () pkg_check_modules(WAYLAND_CLIENT REQUIRED wayland-client) pkg_check_modules(WAYLAND_SCANNER REQUIRED wayland-scanner) pkg_check_modules(WAYLAND_PROTOCOLS REQUIRED wayland-protocols) + pkg_check_modules(XKBCOMMON REQUIRED xkbcommon) # Get variables pkg_get_variable(WAYLAND_SCANNER_BIN wayland-scanner wayland_scanner) pkg_get_variable(WAYLAND_PROTOCOLS_DATADIR wayland-protocols pkgdatadir) @@ -194,12 +195,14 @@ else () target_include_directories(${TARGET_NAME} PUBLIC ${WAYLAND_CLIENT_INCLUDE_DIRS} # PRIVATE ${WAYLAND_CURSOR_INCLUDE_DIRS} + PUBLIC ${XKBCOMMON_INCLUDE_DIRS} PUBLIC $ # PUBLIC $ ) target_link_libraries(${TARGET_NAME} PUBLIC ${WAYLAND_CLIENT_LIBRARIES} + PUBLIC ${XKBCOMMON_LIBRARIES} # PRIVATE ${WAYLAND_CURSOR_LIBRARIES} ) endif() diff --git a/WickedEngine/Wayland/wiWaylandBackend.cpp b/WickedEngine/Wayland/wiWaylandBackend.cpp index bb59b8890..5e15e189e 100644 --- a/WickedEngine/Wayland/wiWaylandBackend.cpp +++ b/WickedEngine/Wayland/wiWaylandBackend.cpp @@ -5,6 +5,7 @@ #include #include +#include "wiWaylandInput.h" #include "xdg-shell.h" #include "xdg-decoration-unstable-v1.h" @@ -30,6 +31,159 @@ extern "C" void window_manager_pong(void *data, struct xdg_wm_base *xdg_wm_base, backend->window_manager_pong(serial); } +extern "C" void _static_on_keyboard_keymap(void* data, wl_keyboard* keyboard, + uint32_t format, + int32_t fd, uint32_t size) +{ + Backend *backend = static_cast(data); + wi::input::wayland::SetKeyMap(format, fd, size); +} + +extern "C" void _static_on_keyboard_focuson(void* data, wl_keyboard* keyboard, + uint32_t serial, + wl_surface* surface, + wl_array* keys) +{ + Backend *backend = static_cast(data); + backend->keyboard_focuson(serial, surface, keys); +} + +extern "C" void _static_on_keyboard_focusoff(void* data, wl_keyboard* keyboard, + uint32_t serial, + wl_surface* surface) +{ + Backend *backend = static_cast(data); + backend->keyboard_focusoff(serial, surface); +} + +extern "C" void _static_on_keyboard_key(void* data, wl_keyboard* keyboard, + uint32_t serial, + uint32_t time, + uint32_t key, + uint32_t state) +{ + Backend *backend = static_cast(data); + // fprintf(stderr, "Key is %d state is %d\n", key, state); + // backend->keyboard_key(serial, time, key, state); + wi::input::wayland::ProcessKeyboardEvent(time, key, state); +} + +extern "C" void _static_on_keyboard_modifiers(void* data, wl_keyboard* keyboard, + uint32_t serial, + uint32_t mods_depressed, + uint32_t mods_latched, + uint32_t mods_locked, + uint32_t group) +{ + Backend *backend = static_cast(data); + // backend->keyboard_focusoff(serial, surface); + fprintf(stderr, "Modifiers depressed %d, latched %d, locked %d, group %d\n", + mods_depressed, mods_latched, mods_locked, group); +} + +extern "C" void _static_on_keyboard_repeat_info(void* data, wl_keyboard* keyboard, + int32_t rate, + int32_t delay) +{ + Backend *backend = static_cast(data); + // backend->keyboard_focusoff(serial, surface); +} + +extern "C" void _static_on_pointer_enter(void *data, + struct wl_pointer *wl_pointer, + uint32_t serial, + struct wl_surface *surface, + wl_fixed_t surface_x, + wl_fixed_t surface_y) +{ + Backend *backend = static_cast(data); +} + +extern "C" void _static_on_pointer_leave(void *data, + struct wl_pointer *wl_pointer, + uint32_t serial, + struct wl_surface *surface) +{ + Backend *backend = static_cast(data); +} + +extern "C" void _static_on_pointer_motion(void *data, + struct wl_pointer *wl_pointer, + uint32_t time, + wl_fixed_t surface_x, + wl_fixed_t surface_y) +{ + double x = wl_fixed_to_double(surface_x), y = wl_fixed_to_double(surface_y); + Backend *backend = static_cast(data); + fprintf(stderr, "Mouse movement %f,%f\n", x, y); + wi::input::wayland::ProcessPointerMotion(time, x, y); +} + +extern "C" void _static_on_pointer_button(void *data, + struct wl_pointer *wl_pointer, + uint32_t serial, + uint32_t time, + uint32_t button, + uint32_t state) +{ + Backend *backend = static_cast(data); + wi::input::wayland::ProcessPointerButton(time, button, state); + fprintf(stderr, "Mouse key is %d state is %d\n", button, state); +} + +extern "C" void _static_on_pointer_axis(void *data, + struct wl_pointer *wl_pointer, + uint32_t time, + uint32_t axis, + wl_fixed_t value) +{ + Backend *backend = static_cast(data); +} + +extern "C" void _static_on_pointer_frame(void *data, struct wl_pointer *wl_pointer) +{ + Backend *backend = static_cast(data); +} + +extern "C" void _static_on_pointer_axis_source(void *data, + struct wl_pointer *wl_pointer, + uint32_t axis_source) +{ + Backend *backend = static_cast(data); +} + +extern "C" void _static_on_pointer_axis_stop(void *data, + struct wl_pointer *wl_pointer, + uint32_t time, + uint32_t axis) +{ + Backend *backend = static_cast(data); +} + +extern "C" void _static_on_pointer_axis_discrete(void *data, + struct wl_pointer *wl_pointer, + uint32_t axis, + int32_t discrete) +{ + Backend *backend = static_cast(data); +} + +extern "C" void _static_on_pointer_axis_value120(void *data, + struct wl_pointer *wl_pointer, + uint32_t axis, + int32_t value120) +{ + Backend *backend = static_cast(data); +} + +extern "C" void _static_on_pointer_axis_relative_direction(void *data, + struct wl_pointer *wl_pointer, + uint32_t axis, + uint32_t direction) +{ + Backend *backend = static_cast(data); +} + /// functions callbacks - END bool Backend::Init() @@ -45,8 +199,38 @@ bool Backend::Init() if (!registry_has("xdg_wm_base")) {std::cerr<<"XDG WM BASE not found"<bind("wl_seat", &wl_seat_interface); + return seat != nullptr; +} + bool Backend::init_window_manager() { window_manager_listener.ping = &::window_manager_pong; @@ -95,6 +285,10 @@ bool Backend::init_window_manager() void Backend::DeInit() { + wi::input::wayland::Deinit(); + safe_delete(pointer, wl_pointer_release); + safe_delete(keyboard, wl_keyboard_release); + safe_delete(seat, wl_seat_destroy); safe_delete(decoration_manager, zxdg_decoration_manager_v1_destroy); safe_delete(window_manager, xdg_wm_base_destroy); safe_delete(compositor, wl_compositor_destroy); @@ -139,3 +333,17 @@ void Backend::window_manager_pong(uint32_t serial) { xdg_wm_base_pong(window_manager, serial); } + +void Backend::keyboard_focuson(uint32_t serial, wl_surface* surface, wl_array* keys) +{ + if (surface != window.WLsurface) + return; + if (window.on_focus_on) window.on_focus_on(&window); +} + +void Backend::keyboard_focusoff(uint32_t serial, wl_surface* surface) +{ + if (surface != window.WLsurface) + return; + if (window.on_focus_off) window.on_focus_off(&window); +} diff --git a/WickedEngine/Wayland/wiWaylandBackend.h b/WickedEngine/Wayland/wiWaylandBackend.h index ae713a3e4..f32e7ea2e 100644 --- a/WickedEngine/Wayland/wiWaylandBackend.h +++ b/WickedEngine/Wayland/wiWaylandBackend.h @@ -1,4 +1,5 @@ #pragma once +#include "wayland-client-protocol.h" #include "wiWaylandWindow.h" #include #include @@ -30,6 +31,12 @@ private: xdg_wm_base_listener window_manager_listener; zxdg_decoration_manager_v1 *decoration_manager = nullptr; + wl_seat* seat = nullptr; + wl_keyboard* keyboard = nullptr; + wl_pointer* pointer = nullptr; + wl_keyboard_listener keyboard_listener {}; + wl_pointer_listener pointer_listener {}; + public: Window window; @@ -48,6 +55,8 @@ public: void registry_event_add(uint32_t id, const char* interface, uint32_t version); void registry_event_remove(uint32_t id); void window_manager_pong(uint32_t serial); + void keyboard_focuson(uint32_t serial, wl_surface* surface, wl_array* keys); + void keyboard_focusoff(uint32_t serial, wl_surface* surface); private: bool init_registry(); @@ -74,6 +83,7 @@ private: bool bind_compositor(); bool bind_xdg_wm_base(); bool bind_decoration_manager(); + bool bind_wl_seat(); bool init_window_manager(); diff --git a/WickedEngine/Wayland/wiWaylandInput.cpp b/WickedEngine/Wayland/wiWaylandInput.cpp new file mode 100644 index 000000000..c126cc1c0 --- /dev/null +++ b/WickedEngine/Wayland/wiWaylandInput.cpp @@ -0,0 +1,673 @@ +#include "wiWaylandInput.h" +#include "wiWaylandUtils.h" +#include "wiInput.h" +#include "wiBacklog.h" + +#include +#include + +// Linux specific includes +#include +#include +#include + +#include "wiSDLInput.h" + +namespace wi::input::wayland { + wi::input::KeyboardState keyboard; + wi::input::MouseState mouse; + + /** + * Code imported and adapted from SDL2 + * https://github.com/libsdl-org/SDL/blob/60c65f9fa428cbde2c1cc60debb3f8bd4a92f742/src/events/SDL_keysym_to_scancode.c#L392 + * @param keysym + * @param keycode + * @return wicked code + */ + int64_t wiSDL_GetScancodeFromKeySym(Uint32 keysym, Uint32 keycode); + int64_t to_wicked(uint32_t key, uint32_t keyk); + int64_t to_wicked2(uint32_t key, uint32_t keyk); + + bool use_xkb_v1_keymap = false; + struct xkb_context *xkb_context = nullptr; + struct xkb_keymap *xkb_keymap = nullptr; + struct xkb_state *xkb_keyboard_state = nullptr; + + void Initialize() { + xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + xkb_keymap = nullptr; + if (!xkb_context) + wi::backlog::post("[Wayland Input] XKB common failed to initialize, keyboard input will not work correctly."); + } + + void Deinit() { + using namespace wi::wayland; + safe_delete(xkb_keyboard_state, xkb_state_unref); + safe_delete(xkb_keymap, xkb_keymap_unref); + safe_delete(xkb_context, xkb_context_unref); + } + + void SetKeyMap(uint32_t format, int32_t fd, uint32_t size) { + if (!xkb_context) return; + assert(format == WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP || format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1); + use_xkb_v1_keymap = (format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1); + + if (use_xkb_v1_keymap) { + char* shared_memory = static_cast(mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0)); + + xkb_keymap = xkb_keymap_new_from_string( + xkb_context, shared_memory, XKB_KEYMAP_FORMAT_TEXT_V1, + XKB_KEYMAP_COMPILE_NO_FLAGS); + if (!xkb_keymap) { + wi::backlog::post("[Wayland Input] XKB keymap failed to initialize, keyboard input will not work correctly."); + } else { + xkb_keyboard_state = xkb_state_new(xkb_keymap); + if (!xkb_keyboard_state) + wi::backlog::post("[Wayland Input] XKB keyboard state failed to initialize, keyboard input will not work correctly."); + } + + munmap(shared_memory, size); + close(fd); + } + } + + void ProcessKeyboardEvent(const uint32_t time, const uint32_t key, const uint32_t state) { + wl_keyboard_key_state keystate = (wl_keyboard_key_state) state; + const bool pressed = (keystate == WL_KEYBOARD_KEY_STATE_PRESSED); + uint32_t keyscan = key; + uint32_t keycode = key; + if (use_xkb_v1_keymap && xkb_keyboard_state) { + const xkb_keysym_t keysym = xkb_state_key_get_one_sym(xkb_keyboard_state, key + 8); + //TODO do we want to convert from scancodes to characters actually? we might want to use raw scancode in a + //game engine instead! Providing both codes could actually prove the best. + keycode = keysym; + + // const xkb_keysym_t *keysyms = nullptr; + // int num_keys = xkb_state_key_get_syms(xkb_keyboard_state, key + 8, &keysyms); + // if (num_keys > 0) { + // keyscan = keysyms[0]; + // } + } + + int64_t wicked_key = wiSDL_GetScancodeFromKeySym(keyscan, key); + fprintf(stderr, "Key is %d (%d, %d:%c) -> (%ld:%c) state is %s\n", key, keyscan, keycode, keycode, wicked_key, (int)wicked_key, pressed ? "pressed" : "released"); + wicked_key = to_wicked2(keycode, keyscan); + if (wicked_key > 0) + keyboard.buttons[wicked_key] = pressed; + } + + void ProcessPointerButton(uint32_t time, uint32_t button, uint32_t state) { + const bool pressed = static_cast(state); + switch (button) { + case BTN_LEFT: mouse.left_button_press = pressed; break; + case BTN_MIDDLE: mouse.middle_button_press = pressed; break; + case BTN_RIGHT: mouse.right_button_press = pressed; break; + default: break; + } + } + void ProcessPointerMotion(uint32_t time, double x, double y) { + XMFLOAT2 old_pos = mouse.position; + mouse.position.x = (float) x / 1.0f; + mouse.position.y = (float) y / 1.0f; + mouse.delta_position.x += mouse.position.x - old_pos.x; + mouse.delta_position.y += mouse.position.y - old_pos.y; + } + + + void Update() { + mouse.delta_wheel = 0; // Do not accumulate mouse wheel motion delta + mouse.delta_position = XMFLOAT2(0, 0); // Do not accumulate mouse position delta + } + + void GetKeyboardState(wi::input::KeyboardState* state) { + *state = keyboard; + } + void GetMouseState(wi::input::MouseState* state) { + *state = mouse; + } + + int64_t to_wicked(const uint32_t key, const uint32_t keyk) { + if (key >= '0' && key <= '9') + return (key - '0') + DIGIT_RANGE_START; + if (key >= 'A' && key <= 'Z') + return (key - 'A') + CHARACTER_RANGE_START; + if (key >= 'a' && key <= 'z') + return (key - 'a') + CHARACTER_RANGE_START; + //TODO continue + if(key >= 58 && key <= 69){ // F1 to F12 + return (key - 58) + KEYBOARD_BUTTON_F1; + } + if(key >= 79 && key <= 82){ // Keyboard directional buttons + return (82 - key) + KEYBOARD_BUTTON_UP; + } + switch(key){ // Individual scancode key conversion + case SDL_SCANCODE_SPACE: + return wi::input::KEYBOARD_BUTTON_SPACE; + case SDL_SCANCODE_LSHIFT: + return wi::input::KEYBOARD_BUTTON_LSHIFT; + case SDL_SCANCODE_RSHIFT: + return wi::input::KEYBOARD_BUTTON_RSHIFT; + case SDL_SCANCODE_RETURN: + return wi::input::KEYBOARD_BUTTON_ENTER; + case SDL_SCANCODE_ESCAPE: + return wi::input::KEYBOARD_BUTTON_ESCAPE; + case SDL_SCANCODE_HOME: + return wi::input::KEYBOARD_BUTTON_HOME; + case SDL_SCANCODE_RCTRL: + return wi::input::KEYBOARD_BUTTON_RCONTROL; + case SDL_SCANCODE_LCTRL: + return wi::input::KEYBOARD_BUTTON_LCONTROL; + case SDL_SCANCODE_DELETE: + return wi::input::KEYBOARD_BUTTON_DELETE; + case SDL_SCANCODE_BACKSPACE: + return wi::input::KEYBOARD_BUTTON_BACKSPACE; + case SDL_SCANCODE_PAGEDOWN: + return wi::input::KEYBOARD_BUTTON_PAGEDOWN; + case SDL_SCANCODE_PAGEUP: + return wi::input::KEYBOARD_BUTTON_PAGEUP; + case SDL_SCANCODE_KP_0: + return wi::input::KEYBOARD_BUTTON_NUMPAD0; + case SDL_SCANCODE_KP_1: + return wi::input::KEYBOARD_BUTTON_NUMPAD1; + case SDL_SCANCODE_KP_2: + return wi::input::KEYBOARD_BUTTON_NUMPAD2; + case SDL_SCANCODE_KP_3: + return wi::input::KEYBOARD_BUTTON_NUMPAD3; + case SDL_SCANCODE_KP_4: + return wi::input::KEYBOARD_BUTTON_NUMPAD4; + case SDL_SCANCODE_KP_5: + return wi::input::KEYBOARD_BUTTON_NUMPAD5; + case SDL_SCANCODE_KP_6: + return wi::input::KEYBOARD_BUTTON_NUMPAD6; + case SDL_SCANCODE_KP_7: + return wi::input::KEYBOARD_BUTTON_NUMPAD7; + case SDL_SCANCODE_KP_8: + return wi::input::KEYBOARD_BUTTON_NUMPAD8; + case SDL_SCANCODE_KP_9: + return wi::input::KEYBOARD_BUTTON_NUMPAD9; + case SDL_SCANCODE_KP_MULTIPLY: + return wi::input::KEYBOARD_BUTTON_MULTIPLY; + case SDL_SCANCODE_KP_PLUS: + return wi::input::KEYBOARD_BUTTON_ADD; + case SDL_SCANCODE_SEPARATOR: + return wi::input::KEYBOARD_BUTTON_SEPARATOR; + case SDL_SCANCODE_KP_MINUS: + return wi::input::KEYBOARD_BUTTON_SUBTRACT; + case SDL_SCANCODE_KP_DECIMAL: + return wi::input::KEYBOARD_BUTTON_DECIMAL; + case SDL_SCANCODE_KP_DIVIDE: + return wi::input::KEYBOARD_BUTTON_DIVIDE; + case SDL_SCANCODE_INSERT: + return wi::input::KEYBOARD_BUTTON_INSERT; + case SDL_SCANCODE_TAB: + return wi::input::KEYBOARD_BUTTON_TAB; + case SDL_SCANCODE_GRAVE: + return wi::input::KEYBOARD_BUTTON_TILDE; + case SDL_SCANCODE_LALT: + return wi::input::KEYBOARD_BUTTON_ALT; + case SDL_SCANCODE_RALT: + return wi::input::KEYBOARD_BUTTON_ALTGR; + } + + + // Keycode Conversion Segment + + if(keyk >= 91 && keyk <= 126){ + return keyk; + } + + return -1; + + } + +static const struct { + uint32_t keyscan; + int64_t wikey; +} KeySymToWiScancode[] = { + {1, ''}, // ESC + {41, ''}, // ` + {2, DIGIT_RANGE_START+1}, // 1 + {3, DIGIT_RANGE_START+2}, // 2 + {4, DIGIT_RANGE_START+3}, // 3 + {5, DIGIT_RANGE_START+4}, // 4 + {6, DIGIT_RANGE_START+5}, // 5 + {7, DIGIT_RANGE_START+6}, // 6 + {8, DIGIT_RANGE_START+7}, // 6 + {9, DIGIT_RANGE_START+8}, // 6 + {10, DIGIT_RANGE_START+9}, // 6 + {11, DIGIT_RANGE_START}, // 0 + {12, '-'}, // - + {13, '='}, // = +}; + + int64_t to_wicked2(const uint32_t keycode, const uint32_t keyscan) { + for (const auto&[e_keyscan, e_wikey] : KeySymToWiScancode) { + if (e_keyscan == keyscan) return e_wikey; + } + return -1; + } + +// ---------------------------------------------------------------------------- +// Code section imported and adapted from SDL2 -------------------------------- + +/* *INDENT-OFF* */ // clang-format off +static const struct { + Uint32 keysym; + SDL_Scancode scancode; +} KeySymToSDLScancode[] = { + { 0xFF9C, SDL_SCANCODE_KP_1 }, // XK_KP_End + { 0xFF99, SDL_SCANCODE_KP_2 }, // XK_KP_Down + { 0xFF9B, SDL_SCANCODE_KP_3 }, // XK_KP_Next + { 0xFF96, SDL_SCANCODE_KP_4 }, // XK_KP_Left + { 0xFF9D, SDL_SCANCODE_KP_5 }, // XK_KP_Begin + { 0xFF98, SDL_SCANCODE_KP_6 }, // XK_KP_Right + { 0xFF95, SDL_SCANCODE_KP_7 }, // XK_KP_Home + { 0xFF97, SDL_SCANCODE_KP_8 }, // XK_KP_Up + { 0xFF9A, SDL_SCANCODE_KP_9 }, // XK_KP_Prior + { 0xFF9E, SDL_SCANCODE_KP_0 }, // XK_KP_Insert + { 0xFF9F, SDL_SCANCODE_KP_PERIOD }, // XK_KP_Delete + { 0xFF62, SDL_SCANCODE_EXECUTE }, // XK_Execute + { 0xFFEE, SDL_SCANCODE_APPLICATION }, // XK_Hyper_R + { 0xFE03, SDL_SCANCODE_RALT }, // XK_ISO_Level3_Shift + { 0xFE20, SDL_SCANCODE_TAB }, // XK_ISO_Left_Tab + { 0xFFEB, SDL_SCANCODE_LGUI }, // XK_Super_L + { 0xFFEC, SDL_SCANCODE_RGUI }, // XK_Super_R + { 0xFF7E, SDL_SCANCODE_MODE }, // XK_Mode_switch + { 0x1008FF65, SDL_SCANCODE_MENU }, // XF86MenuKB + { 0x1008FF81, SDL_SCANCODE_F13 }, // XF86Tools + { 0x1008FF45, SDL_SCANCODE_F14 }, // XF86Launch5 + { 0x1008FF46, SDL_SCANCODE_F15 }, // XF86Launch6 + { 0x1008FF47, SDL_SCANCODE_F16 }, // XF86Launch7 + { 0x1008FF48, SDL_SCANCODE_F17 }, // XF86Launch8 + { 0x1008FF49, SDL_SCANCODE_F18 }, // XF86Launch9 +}; + +// This is a mapping from X keysym to Linux keycode +static const Uint32 LinuxKeycodeKeysyms[] = { + /* 0, 0x000 */ 0x0, // NoSymbol + /* 1, 0x001 */ 0xFF1B, // Escape + /* 2, 0x002 */ 0x31, // 1 + /* 3, 0x003 */ 0x32, // 2 + /* 4, 0x004 */ 0x33, // 3 + /* 5, 0x005 */ 0x34, // 4 + /* 6, 0x006 */ 0x35, // 5 + /* 7, 0x007 */ 0x36, // 6 + /* 8, 0x008 */ 0x37, // 7 + /* 9, 0x009 */ 0x38, // 8 + /* 10, 0x00a */ 0x39, // 9 + /* 11, 0x00b */ 0x30, // 0 + /* 12, 0x00c */ 0x2D, // minus + /* 13, 0x00d */ 0x3D, // equal + /* 14, 0x00e */ 0xFF08, // BackSpace + /* 15, 0x00f */ 0xFF09, // Tab + /* 16, 0x010 */ 0x71, // q + /* 17, 0x011 */ 0x77, // w + /* 18, 0x012 */ 0x65, // e + /* 19, 0x013 */ 0x72, // r + /* 20, 0x014 */ 0x74, // t + /* 21, 0x015 */ 0x79, // y + /* 22, 0x016 */ 0x75, // u + /* 23, 0x017 */ 0x69, // i + /* 24, 0x018 */ 0x6F, // o + /* 25, 0x019 */ 0x70, // p + /* 26, 0x01a */ 0x5B, // bracketleft + /* 27, 0x01b */ 0x5D, // bracketright + /* 28, 0x01c */ 0xFF0D, // Return + /* 29, 0x01d */ 0xFFE3, // Control_L + /* 30, 0x01e */ 0x61, // a + /* 31, 0x01f */ 0x73, // s + /* 32, 0x020 */ 0x64, // d + /* 33, 0x021 */ 0x66, // f + /* 34, 0x022 */ 0x67, // g + /* 35, 0x023 */ 0x68, // h + /* 36, 0x024 */ 0x6A, // j + /* 37, 0x025 */ 0x6B, // k + /* 38, 0x026 */ 0x6C, // l + /* 39, 0x027 */ 0x3B, // semicolon + /* 40, 0x028 */ 0x27, // apostrophe + /* 41, 0x029 */ 0x60, // grave + /* 42, 0x02a */ 0xFFE1, // Shift_L + /* 43, 0x02b */ 0x5C, // backslash + /* 44, 0x02c */ 0x7A, // z + /* 45, 0x02d */ 0x78, // x + /* 46, 0x02e */ 0x63, // c + /* 47, 0x02f */ 0x76, // v + /* 48, 0x030 */ 0x62, // b + /* 49, 0x031 */ 0x6E, // n + /* 50, 0x032 */ 0x6D, // m + /* 51, 0x033 */ 0x2C, // comma + /* 52, 0x034 */ 0x2E, // period + /* 53, 0x035 */ 0x2F, // slash + /* 54, 0x036 */ 0xFFE2, // Shift_R + /* 55, 0x037 */ 0xFFAA, // KP_Multiply + /* 56, 0x038 */ 0xFFE9, // Alt_L + /* 57, 0x039 */ 0x20, // space + /* 58, 0x03a */ 0xFFE5, // Caps_Lock + /* 59, 0x03b */ 0xFFBE, // F1 + /* 60, 0x03c */ 0xFFBF, // F2 + /* 61, 0x03d */ 0xFFC0, // F3 + /* 62, 0x03e */ 0xFFC1, // F4 + /* 63, 0x03f */ 0xFFC2, // F5 + /* 64, 0x040 */ 0xFFC3, // F6 + /* 65, 0x041 */ 0xFFC4, // F7 + /* 66, 0x042 */ 0xFFC5, // F8 + /* 67, 0x043 */ 0xFFC6, // F9 + /* 68, 0x044 */ 0xFFC7, // F10 + /* 69, 0x045 */ 0xFF7F, // Num_Lock + /* 70, 0x046 */ 0xFF14, // Scroll_Lock + /* 71, 0x047 */ 0xFFB7, // KP_7 + /* 72, 0x048 */ 0XFFB8, // KP_8 + /* 73, 0x049 */ 0XFFB9, // KP_9 + /* 74, 0x04a */ 0xFFAD, // KP_Subtract + /* 75, 0x04b */ 0xFFB4, // KP_4 + /* 76, 0x04c */ 0xFFB5, // KP_5 + /* 77, 0x04d */ 0xFFB6, // KP_6 + /* 78, 0x04e */ 0xFFAB, // KP_Add + /* 79, 0x04f */ 0xFFB1, // KP_1 + /* 80, 0x050 */ 0xFFB2, // KP_2 + /* 81, 0x051 */ 0xFFB3, // KP_3 + /* 82, 0x052 */ 0xFFB0, // KP_0 + /* 83, 0x053 */ 0xFFAE, // KP_Decimal + /* 84, 0x054 */ 0x0, // NoSymbol + /* 85, 0x055 */ 0x0, // NoSymbol + /* 86, 0x056 */ 0x3C, // less + /* 87, 0x057 */ 0xFFC8, // F11 + /* 88, 0x058 */ 0xFFC9, // F12 + /* 89, 0x059 */ 0x0, // NoSymbol + /* 90, 0x05a */ 0xFF26, // Katakana + /* 91, 0x05b */ 0xFF25, // Hiragana + /* 92, 0x05c */ 0xFF23, // Henkan_Mode + /* 93, 0x05d */ 0xFF27, // Hiragana_Katakana + /* 94, 0x05e */ 0xFF22, // Muhenkan + /* 95, 0x05f */ 0x0, // NoSymbol + /* 96, 0x060 */ 0xFF8D, // KP_Enter + /* 97, 0x061 */ 0xFFE4, // Control_R + /* 98, 0x062 */ 0xFFAF, // KP_Divide + /* 99, 0x063 */ 0xFF15, // Sys_Req + /* 100, 0x064 */ 0xFFEA, // Alt_R + /* 101, 0x065 */ 0xFF0A, // Linefeed + /* 102, 0x066 */ 0xFF50, // Home + /* 103, 0x067 */ 0xFF52, // Up + /* 104, 0x068 */ 0xFF55, // Prior + /* 105, 0x069 */ 0xFF51, // Left + /* 106, 0x06a */ 0xFF53, // Right + /* 107, 0x06b */ 0xFF57, // End + /* 108, 0x06c */ 0xFF54, // Down + /* 109, 0x06d */ 0xFF56, // Next + /* 110, 0x06e */ 0xFF63, // Insert + /* 111, 0x06f */ 0xFFFF, // Delete + /* 112, 0x070 */ 0x0, // NoSymbol + /* 113, 0x071 */ 0x1008FF12, // XF86AudioMute + /* 114, 0x072 */ 0x1008FF11, // XF86AudioLowerVolume + /* 115, 0x073 */ 0x1008FF13, // XF86AudioRaiseVolume + /* 116, 0x074 */ 0x1008FF2A, // XF86PowerOff + /* 117, 0x075 */ 0xFFBD, // KP_Equal + /* 118, 0x076 */ 0xB1, // plusminus + /* 119, 0x077 */ 0xFF13, // Pause + /* 120, 0x078 */ 0x1008FF4A, // XF86LaunchA + /* 121, 0x079 */ 0xFFAC, // KP_Separator + /* 122, 0x07a */ 0xFF31, // Hangul + /* 123, 0x07b */ 0xFF34, // Hangul_Hanja + /* 124, 0x07c */ 0x0, // NoSymbol + /* 125, 0x07d */ 0xFFE7, // Meta_L + /* 126, 0x07e */ 0xFFE8, // Meta_R + /* 127, 0x07f */ 0xFF67, // Menu + /* 128, 0x080 */ 0x00, // NoSymbol + /* 129, 0x081 */ 0xFF66, // Redo + /* 130, 0x082 */ 0x1005FF70, // SunProps + /* 131, 0x083 */ 0xFF65, // Undo + /* 132, 0x084 */ 0x1005FF71, // SunFront + /* 133, 0x085 */ 0x1008FF57, // XF86Copy + /* 134, 0x086 */ 0x1008FF6B, // XF86Open + /* 135, 0x087 */ 0x1008FF6D, // XF86Paste + /* 136, 0x088 */ 0xFF68, // Find + /* 137, 0x089 */ 0x1008FF58, // XF86Cut + /* 138, 0x08a */ 0xFF6A, // Help + /* 139, 0x08b */ 0xFF67, // Menu + /* 140, 0x08c */ 0x1008FF1D, // XF86Calculator + /* 141, 0x08d */ 0x0, // NoSymbol + /* 142, 0x08e */ 0x1008FF2F, // XF86Sleep + /* 143, 0x08f */ 0x1008FF2B, // XF86WakeUp + /* 144, 0x090 */ 0x1008FF5D, // XF86Explorer + /* 145, 0x091 */ 0x1008FF7B, // XF86Send + /* 146, 0x092 */ 0x0, // NoSymbol + /* 147, 0x093 */ 0x1008FF8A, // XF86Xfer + /* 148, 0x094 */ 0x1008FF41, // XF86Launch1 + /* 149, 0x095 */ 0x1008FF42, // XF86Launch2 + /* 150, 0x096 */ 0x1008FF2E, // XF86WWW + /* 151, 0x097 */ 0x1008FF5A, // XF86DOS + /* 152, 0x098 */ 0x1008FF2D, // XF86ScreenSaver + /* 153, 0x099 */ 0x1008FF74, // XF86RotateWindows + /* 154, 0x09a */ 0x1008FF7F, // XF86TaskPane + /* 155, 0x09b */ 0x1008FF19, // XF86Mail + /* 156, 0x09c */ 0x1008FF30, // XF86Favorites + /* 157, 0x09d */ 0x1008FF33, // XF86MyComputer + /* 158, 0x09e */ 0x1008FF26, // XF86Back + /* 159, 0x09f */ 0x1008FF27, // XF86Forward + /* 160, 0x0a0 */ 0x0, // NoSymbol + /* 161, 0x0a1 */ 0x1008FF2C, // XF86Eject + /* 162, 0x0a2 */ 0x1008FF2C, // XF86Eject + /* 163, 0x0a3 */ 0x1008FF17, // XF86AudioNext + /* 164, 0x0a4 */ 0x1008FF14, // XF86AudioPlay + /* 165, 0x0a5 */ 0x1008FF16, // XF86AudioPrev + /* 166, 0x0a6 */ 0x1008FF15, // XF86AudioStop + /* 167, 0x0a7 */ 0x1008FF1C, // XF86AudioRecord + /* 168, 0x0a8 */ 0x1008FF3E, // XF86AudioRewind + /* 169, 0x0a9 */ 0x1008FF6E, // XF86Phone + /* 170, 0x0aa */ 0x0, // NoSymbol + /* 171, 0x0ab */ 0x1008FF81, // XF86Tools + /* 172, 0x0ac */ 0x1008FF18, // XF86HomePage + /* 173, 0x0ad */ 0x1008FF73, // XF86Reload + /* 174, 0x0ae */ 0x1008FF56, // XF86Close + /* 175, 0x0af */ 0x0, // NoSymbol + /* 176, 0x0b0 */ 0x0, // NoSymbol + /* 177, 0x0b1 */ 0x1008FF78, // XF86ScrollUp + /* 178, 0x0b2 */ 0x1008FF79, // XF86ScrollDown + /* 179, 0x0b3 */ 0x0, // NoSymbol + /* 180, 0x0b4 */ 0x0, // NoSymbol + /* 181, 0x0b5 */ 0x1008FF68, // XF86New + /* 182, 0x0b6 */ 0xFF66, // Redo + /* 183, 0x0b7 */ 0xFFCA, // F13 + /* 184, 0x0b8 */ 0xFFCB, // F14 + /* 185, 0x0b9 */ 0xFFCC, // F15 + /* 186, 0x0ba */ 0xFFCD, // F16 + /* 187, 0x0bb */ 0xFFCE, // F17 + /* 188, 0x0bc */ 0xFFCF, // F18 + /* 189, 0x0bd */ 0xFFD0, // F19 + /* 190, 0x0be */ 0xFFD1, // F20 + /* 191, 0x0bf */ 0xFFD2, // F21 + /* 192, 0x0c0 */ 0xFFD3, // F22 + /* 193, 0x0c1 */ 0xFFD4, // F23 + /* 194, 0x0c2 */ 0xFFD5, // F24 + /* 195, 0x0c3 */ 0x0, // NoSymbol + /* 196, 0x0c4 */ 0x0, // NoSymbol + /* 197, 0x0c5 */ 0x0, // NoSymbol + /* 198, 0x0c6 */ 0x0, // NoSymbol + /* 199, 0x0c7 */ 0x0, // NoSymbol + /* 200, 0x0c8 */ 0x1008FF14, // XF86AudioPlay + /* 201, 0x0c9 */ 0x1008FF31, // XF86AudioPause + /* 202, 0x0ca */ 0x1008FF43, // XF86Launch3 + /* 203, 0x0cb */ 0x1008FF44, // XF86Launch4 + /* 204, 0x0cc */ 0x1008FF4B, // XF86LaunchB + /* 205, 0x0cd */ 0x1008FFA7, // XF86Suspend + /* 206, 0x0ce */ 0x1008FF56, // XF86Close + /* 207, 0x0cf */ 0x1008FF14, // XF86AudioPlay + /* 208, 0x0d0 */ 0x1008FF97, // XF86AudioForward + /* 209, 0x0d1 */ 0x0, // NoSymbol + /* 210, 0x0d2 */ 0xFF61, // Print + /* 211, 0x0d3 */ 0x0, // NoSymbol + /* 212, 0x0d4 */ 0x1008FF8F, // XF86WebCam + /* 213, 0x0d5 */ 0x1008FFB6, // XF86AudioPreset + /* 214, 0x0d6 */ 0x0, // NoSymbol + /* 215, 0x0d7 */ 0x1008FF19, // XF86Mail + /* 216, 0x0d8 */ 0x1008FF8E, // XF86Messenger + /* 217, 0x0d9 */ 0x1008FF1B, // XF86Search + /* 218, 0x0da */ 0x1008FF5F, // XF86Go + /* 219, 0x0db */ 0x1008FF3C, // XF86Finance + /* 220, 0x0dc */ 0x1008FF5E, // XF86Game + /* 221, 0x0dd */ 0x1008FF36, // XF86Shop + /* 222, 0x0de */ 0x0, // NoSymbol + /* 223, 0x0df */ 0xFF69, // Cancel + /* 224, 0x0e0 */ 0x1008FF03, // XF86MonBrightnessDown + /* 225, 0x0e1 */ 0x1008FF02, // XF86MonBrightnessUp + /* 226, 0x0e2 */ 0x1008FF32, // XF86AudioMedia + /* 227, 0x0e3 */ 0x1008FF59, // XF86Display + /* 228, 0x0e4 */ 0x1008FF04, // XF86KbdLightOnOff + /* 229, 0x0e5 */ 0x1008FF06, // XF86KbdBrightnessDown + /* 230, 0x0e6 */ 0x1008FF05, // XF86KbdBrightnessUp + /* 231, 0x0e7 */ 0x1008FF7B, // XF86Send + /* 232, 0x0e8 */ 0x1008FF72, // XF86Reply + /* 233, 0x0e9 */ 0x1008FF90, // XF86MailForward + /* 234, 0x0ea */ 0x1008FF77, // XF86Save + /* 235, 0x0eb */ 0x1008FF5B, // XF86Documents + /* 236, 0x0ec */ 0x1008FF93, // XF86Battery + /* 237, 0x0ed */ 0x1008FF94, // XF86Bluetooth + /* 238, 0x0ee */ 0x1008FF95, // XF86WLAN + /* 239, 0x0ef */ 0x1008FF96, // XF86UWB + /* 240, 0x0f0 */ 0x0, // NoSymbol + /* 241, 0x0f1 */ 0x1008FE22, // XF86Next_VMode + /* 242, 0x0f2 */ 0x1008FE23, // XF86Prev_VMode + /* 243, 0x0f3 */ 0x1008FF07, // XF86MonBrightnessCycle + /* 244, 0x0f4 */ 0x100810F4, // XF86BrightnessAuto + /* 245, 0x0f5 */ 0x100810F5, // XF86DisplayOff + /* 246, 0x0f6 */ 0x1008FFB4, // XF86WWAN + /* 247, 0x0f7 */ 0x1008FFB5, // XF86RFKill +}; + +#if 0 // Here is a script to generate the ExtendedLinuxKeycodeKeysyms table +#!/bin/bash + +function process_line +{ + sym=$(echo "$1" | awk '{print $3}') + code=$(echo "$1" | sed 's,.*_EVDEVK(\(0x[0-9A-Fa-f]*\)).*,\1,') + value=$(grep -E "#define ${sym}\s" -R /usr/include/X11 | awk '{print $3}') + printf " { 0x%.8X, 0x%.3x }, /* $sym */\n" $value $code +} + +grep -F "/* Use: " /usr/include/xkbcommon/xkbcommon-keysyms.h | grep -F _EVDEVK | while read line; do + process_line "$line" +done +#endif + +static const struct { + Uint32 keysym; + int linux_keycode; +} ExtendedLinuxKeycodeKeysyms[] = { + { 0x1008FF2C, 0x0a2 }, // XF86XK_Eject + { 0x1008FF68, 0x0b5 }, // XF86XK_New + { 0x0000FF66, 0x0b6 }, // XK_Redo + { 0x1008FF4B, 0x0cc }, // XF86XK_LaunchB + { 0x1008FF59, 0x0e3 }, // XF86XK_Display + { 0x1008FF04, 0x0e4 }, // XF86XK_KbdLightOnOff + { 0x1008FF06, 0x0e5 }, // XF86XK_KbdBrightnessDown + { 0x1008FF05, 0x0e6 }, // XF86XK_KbdBrightnessUp + { 0x1008FF7B, 0x0e7 }, // XF86XK_Send + { 0x1008FF72, 0x0e8 }, // XF86XK_Reply + { 0x1008FF90, 0x0e9 }, // XF86XK_MailForward + { 0x1008FF77, 0x0ea }, // XF86XK_Save + { 0x1008FF5B, 0x0eb }, // XF86XK_Documents + { 0x1008FF93, 0x0ec }, // XF86XK_Battery + { 0x1008FF94, 0x0ed }, // XF86XK_Bluetooth + { 0x1008FF95, 0x0ee }, // XF86XK_WLAN + { 0x1008FF96, 0x0ef }, // XF86XK_UWB + { 0x1008FE22, 0x0f1 }, // XF86XK_Next_VMode + { 0x1008FE23, 0x0f2 }, // XF86XK_Prev_VMode + { 0x1008FF07, 0x0f3 }, // XF86XK_MonBrightnessCycle + { 0x1008FFB4, 0x0f6 }, // XF86XK_WWAN + { 0x1008FFB5, 0x0f7 }, // XF86XK_RFKill + { 0x1008FFB2, 0x0f8 }, // XF86XK_AudioMicMute + { 0x1008FF9C, 0x173 }, // XF86XK_CycleAngle + { 0x1008FFB8, 0x174 }, // XF86XK_FullScreen + { 0x1008FF87, 0x189 }, // XF86XK_Video + { 0x1008FF20, 0x18d }, // XF86XK_Calendar + { 0x1008FF99, 0x19a }, // XF86XK_AudioRandomPlay + { 0x1008FF5E, 0x1a1 }, // XF86XK_Game + { 0x1008FF8B, 0x1a2 }, // XF86XK_ZoomIn + { 0x1008FF8C, 0x1a3 }, // XF86XK_ZoomOut + { 0x1008FF89, 0x1a5 }, // XF86XK_Word + { 0x1008FF5C, 0x1a7 }, // XF86XK_Excel + { 0x1008FF69, 0x1ab }, // XF86XK_News + { 0x1008FF8E, 0x1ae }, // XF86XK_Messenger + { 0x1008FF61, 0x1b1 }, // XF86XK_LogOff + { 0x00000024, 0x1b2 }, // XK_dollar + { 0x000020AC, 0x1b3 }, // XK_EuroSign + { 0x1008FF9D, 0x1b4 }, // XF86XK_FrameBack + { 0x1008FF9E, 0x1b5 }, // XF86XK_FrameForward + { 0x0000FFF1, 0x1f1 }, // XK_braille_dot_1 + { 0x0000FFF2, 0x1f2 }, // XK_braille_dot_2 + { 0x0000FFF3, 0x1f3 }, // XK_braille_dot_3 + { 0x0000FFF4, 0x1f4 }, // XK_braille_dot_4 + { 0x0000FFF5, 0x1f5 }, // XK_braille_dot_5 + { 0x0000FFF6, 0x1f6 }, // XK_braille_dot_6 + { 0x0000FFF7, 0x1f7 }, // XK_braille_dot_7 + { 0x0000FFF8, 0x1f8 }, // XK_braille_dot_8 + { 0x0000FFF9, 0x1f9 }, // XK_braille_dot_9 + { 0x0000FFF1, 0x1fa }, // XK_braille_dot_1 + { 0x1008FFA9, 0x212 }, // XF86XK_TouchpadToggle + { 0x1008FFB0, 0x213 }, // XF86XK_TouchpadOn + { 0x1008FFB1, 0x214 }, // XF86XK_TouchpadOff + { 0x1008FFB7, 0x231 }, // XF86XK_RotationLockToggle + { 0x0000FE08, 0x248 }, // XK_ISO_Next_Group +}; +/* *INDENT-ON* */ // clang-format on + + /** + * Code imported and adapted from SDL2 + * https://github.com/libsdl-org/SDL/blob/60c65f9fa428cbde2c1cc60debb3f8bd4a92f742/src/events/SDL_keysym_to_scancode.c#L392 + * @param keysym + * @param keycode + * @return wicked code + */ + int64_t wiSDL_GetScancodeFromKeySym(Uint32 keysym, Uint32 keycode) + { + int i; + Uint32 linux_keycode = 0; + + // First check our custom list + for (i = 0; i < std::size(KeySymToSDLScancode); ++i) { + if (keysym == KeySymToSDLScancode[i].keysym) { + return KeySymToSDLScancode[i].scancode; + } + } + + if (keysym >= 0x41 && keysym <= 0x5a) { + // Normalize alphabetic keysyms to the lowercase form + keysym += 0x20; + } else if (keysym >= 0x10081000 && keysym <= 0x10081FFF) { + /* The rest of the keysyms map to Linux keycodes, so use that mapping + * Per xkbcommon-keysyms.h, this is actually a linux keycode. + */ + linux_keycode = (keysym - 0x10081000); + } + if (!linux_keycode) { + // See if this keysym is an exact match in our table + i = keycode; + if (i >= 0 && i < std::size(LinuxKeycodeKeysyms) && keysym == LinuxKeycodeKeysyms[i]) { + linux_keycode = i; + } else { + // Scan the table for this keysym + for (i = 0; i < std::size(LinuxKeycodeKeysyms); ++i) { + if (keysym == LinuxKeycodeKeysyms[i]) { + linux_keycode = i; + break; + } + } + } + } + if (!linux_keycode) { + // Scan the extended table for this keysym + for (i = 0; i < std::size(ExtendedLinuxKeycodeKeysyms); ++i) { + if (keysym == ExtendedLinuxKeycodeKeysyms[i].keysym) { + linux_keycode = ExtendedLinuxKeycodeKeysyms[i].linux_keycode; + break; + } + } + } + return -1;//SDL_GetScancodeFromTable(SDL_SCANCODE_TABLE_LINUX, linux_keycode); + } + +// END Code section imported and adapted from SDL2 ---------------------------- +//----------------------------------------------------------------------------- + +} diff --git a/WickedEngine/Wayland/wiWaylandInput.h b/WickedEngine/Wayland/wiWaylandInput.h new file mode 100644 index 000000000..780d81d59 --- /dev/null +++ b/WickedEngine/Wayland/wiWaylandInput.h @@ -0,0 +1,34 @@ +#pragma once +#include + +#include "wiInput.h" + +typedef int Event; + +namespace wi::input::wayland { + struct Event { + enum EventType { + None = 0, + Keyboard, + Mouse, + } type; + struct KeyboardEvent { + uint32_t time, key, state; + } keyboard_event; + }; + + void Initialize(); + void Deinit(); + + void SetKeyMap(uint32_t format, int32_t fd, uint32_t size); + void ProcessKeyboardEvent(uint32_t time, uint32_t key, uint32_t state); + + void ProcessPointerButton(uint32_t time, uint32_t uint32, uint32_t state); + void ProcessPointerMotion(uint32_t time, double x, double y); + + void Update(); + + void GetKeyboardState(wi::input::KeyboardState* state); + + void GetMouseState(wi::input::MouseState* state); +} diff --git a/WickedEngine/Wayland/wiWaylandWindow.cpp b/WickedEngine/Wayland/wiWaylandWindow.cpp index 66dcbb434..99c011184 100644 --- a/WickedEngine/Wayland/wiWaylandWindow.cpp +++ b/WickedEngine/Wayland/wiWaylandWindow.cpp @@ -17,31 +17,31 @@ extern "C" void _static_on_redraw(void *data, wl_callback *wl_callback, uint32_t time) { - static_cast(data)->on_redraw(wl_callback, time); + static_cast(data)->_on_redraw(wl_callback, time); } -extern "C" void _static_on_enter(void *data, +extern "C" void _static_on_enter_monitor(void *data, wl_surface *wl_surface, wl_output *output) { - static_cast(data)->on_enter(output); + static_cast(data)->_on_enter_monitor(output); } -extern "C" void _static_on_leave(void *data, +extern "C" void _static_on_leave_monitor(void *data, wl_surface *wl_surface, wl_output *output) { - static_cast(data)->on_leave(output); + static_cast(data)->_on_leave_monitor(output); } extern "C" void _static_xdg_surface_configure(void* data, xdg_surface* raw, uint32_t serial) { - static_cast(data)->on_xdg_surface_ack_configure(serial); + static_cast(data)->_on_xdg_surface_ack_configure(serial); } extern "C" void _static_toplevel_close(void *data, xdg_toplevel *xdg_toplevel) { - static_cast(data)->on_toplevel_close(); + static_cast(data)->_on_toplevel_close(); } extern "C" void _static_toplevel_configure(void *data, @@ -50,7 +50,7 @@ extern "C" void _static_toplevel_configure(void *data, int32_t height, wl_array *states) { - static_cast(data)->on_toplevel_configure(width, height, states); + static_cast(data)->_on_toplevel_configure(width, height, states); } extern "C" void _static_toplevel_configure_bounds(void *data, @@ -58,16 +58,16 @@ extern "C" void _static_toplevel_configure_bounds(void *data, int32_t width, int32_t height) { - static_cast(data)->on_toplevel_configure_bounds(width, height); + static_cast(data)->_on_toplevel_configure_bounds(width, height); } -void Window::on_enter(wl_output *output) +void Window::_on_enter_monitor(wl_output *output) {} -void Window::on_leave(wl_output *output) +void Window::_on_leave_monitor(wl_output *output) {} -void Window::on_redraw(wl_callback *wl_callback, uint32_t time) +void Window::_on_redraw(wl_callback *wl_callback, uint32_t time) { if(frame_callback != nullptr) { wl_callback_destroy(frame_callback); @@ -77,23 +77,23 @@ void Window::on_redraw(wl_callback *wl_callback, uint32_t time) on_redraw_callback(this); } -void Window::on_xdg_surface_ack_configure(uint32_t serial) +void Window::_on_xdg_surface_ack_configure(uint32_t serial) { xdg_surface_ack_configure(XDGsurface, serial); } -void Window::on_toplevel_close() +void Window::_on_toplevel_close() { if (on_close) on_close(this); } -void Window::on_toplevel_configure(int32_t width, int32_t height, wl_array* states) +void Window::_on_toplevel_configure(int32_t width, int32_t height, wl_array* states) { desired_width = width; desired_height = height; } -void Window::on_toplevel_configure_bounds(int32_t width, int32_t height) +void Window::_on_toplevel_configure_bounds(int32_t width, int32_t height) {} @@ -104,8 +104,8 @@ bool Window::Init(Backend* backend, const char* title) // Surface WLsurface = wl_compositor_create_surface(backend->compositor); if (WLsurface == nullptr) {std::cerr << "Could not create surface from compositor" << std::endl; return false;} - WLsurface_listener.enter = &_static_on_enter; - WLsurface_listener.leave = &_static_on_leave; + WLsurface_listener.enter = &_static_on_enter_monitor; + WLsurface_listener.leave = &_static_on_leave_monitor; frame_listener.done = &_static_on_redraw; wl_surface_add_listener(WLsurface, &WLsurface_listener, this); @@ -133,6 +133,7 @@ bool Window::Init(Backend* backend, const char* title) } } + xdg_toplevel_set_app_id(toplevel, "WickedEngine"); SetTitle(title); return true; } diff --git a/WickedEngine/Wayland/wiWaylandWindow.h b/WickedEngine/Wayland/wiWaylandWindow.h index 5b743d278..8c5f7997b 100644 --- a/WickedEngine/Wayland/wiWaylandWindow.h +++ b/WickedEngine/Wayland/wiWaylandWindow.h @@ -43,6 +43,8 @@ private: public: std::function on_redraw_callback; std::function on_close; + std::function on_focus_on; + std::function on_focus_off; public: ~Window() { Deinit(); } @@ -59,13 +61,15 @@ public: VkResult CreateVulkanSurface(VkInstance instance, VkSurfaceKHR* VKSurface); // callbacks - void on_enter(wl_output *output); - void on_leave(wl_output *output); - void on_redraw(wl_callback *wl_callback, uint32_t time); - void on_xdg_surface_ack_configure(uint32_t serial); - void on_toplevel_close(); - void on_toplevel_configure(int32_t width, int32_t height, wl_array *states); - void on_toplevel_configure_bounds(int32_t width, int32_t height); + void _on_enter_monitor(wl_output *output); + void _on_leave_monitor(wl_output *output); + void _on_redraw(wl_callback *wl_callback, uint32_t time); + void _on_xdg_surface_ack_configure(uint32_t serial); + void _on_toplevel_close(); + void _on_toplevel_configure(int32_t width, int32_t height, wl_array *states); + void _on_toplevel_configure_bounds(int32_t width, int32_t height); + +friend class Backend; }; } diff --git a/WickedEngine/wiInput.cpp b/WickedEngine/wiInput.cpp index e7b87d5cf..0ce3a4f7d 100644 --- a/WickedEngine/wiInput.cpp +++ b/WickedEngine/wiInput.cpp @@ -3,6 +3,7 @@ #include "wiXInput.h" #include "wiRawInput.h" #include "wiSDLInput.h" +#include "Wayland/wiWaylandInput.h" #include "wiHelper.h" #include "wiBacklog.h" #include "wiProfiler.h" @@ -148,6 +149,7 @@ namespace wi::input wi::input::xinput::Update(); wi::input::rawinput::Update(); wi::input::sdlinput::Update(); + wi::input::wayland::Update(); #ifdef PLATFORM_PS5 wi::input::ps5::Update(); @@ -170,12 +172,17 @@ namespace wi::input mouse.position.y = (float)p.y; mouse.position.x /= canvas.GetDPIScaling(); mouse.position.y /= canvas.GetDPIScaling(); - #elif SDL2 - wi::input::sdlinput::GetMouseState(&mouse); - mouse.position.x /= canvas.GetDPIScaling(); - mouse.position.y /= canvas.GetDPIScaling(); - wi::input::sdlinput::GetKeyboardState(&keyboard); + if (window.type == platform::LinuxWindow::eSDLWindow) { + wi::input::sdlinput::GetMouseState(&mouse); + mouse.position.x /= canvas.GetDPIScaling(); + mouse.position.y /= canvas.GetDPIScaling(); + wi::input::sdlinput::GetKeyboardState(&keyboard); + } + else if (window.type == platform::LinuxWindow::eWaylandWindow) { + wi::input::wayland::GetMouseState(&mouse); + wi::input::wayland::GetKeyboardState(&keyboard); + } //TODO controllers //TODO touch #endif diff --git a/WickedEngine/wiSDLInput.h b/WickedEngine/wiSDLInput.h index 2024efd15..5dc4796da 100644 --- a/WickedEngine/wiSDLInput.h +++ b/WickedEngine/wiSDLInput.h @@ -36,4 +36,7 @@ namespace wi::input::sdlinput // Call this within the main.cpp program loop for the engine to be able handle the input void ProcessEvent(const SDL_Event &event); #endif + + // Helper function to convert into Wicked Key "space" + int to_wicked(const SDL_Scancode &key, const SDL_Keycode &keyk); }