From 36368041ee580bceaeefd599706c75ea6e9954fa Mon Sep 17 00:00:00 2001 From: Deve Date: Wed, 17 May 2017 22:43:56 +0200 Subject: [PATCH] Mostly cleanup and style modifications --- .../source/Irrlicht/CIrrDeviceWayland.cpp | 2270 ++++++++--------- .../source/Irrlicht/CIrrDeviceWayland.h | 510 ++-- 2 files changed, 1369 insertions(+), 1411 deletions(-) diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.cpp index c5a05370f..a7f259638 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.cpp @@ -1,36 +1,41 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2016-2017 Dawid Gan +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + #include "CIrrDeviceWayland.h" #ifdef _IRR_COMPILE_WITH_WAYLAND -#include -#include +#include +#include +#include +#include #include #include -#include -#include "IEventReceiver.h" -#include "ISceneManager.h" -#include "IGUIEnvironment.h" -#include "os.h" -#include "CTimer.h" -#include "irrString.h" -#include "Keycodes.h" -#include "COSOperator.h" -#include "CColorConverter.h" -#include "SIrrCreationParameters.h" -#include "IGUISpriteBank.h" -#include -#include "CVideoModeList.h" -#include "CContextEGL.h" #if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ #include #include - -// linux/joystick.h includes linux/input.h, which #defines values for various KEY_FOO keys. -// These override the irr::KEY_FOO equivalents, which stops key handling from working. -// As a workaround, defining _INPUT_H stops linux/input.h from being included; it -// doesn't actually seem to be necessary except to pull in sys/ioctl.h. +// linux/joystick.h includes linux/input.h, which #defines values for various +// KEY_FOO keys. These override the irr::KEY_FOO equivalents, which stops key +// handling from working. As a workaround, defining _INPUT_H stops linux/input.h +// from being included; it doesn't actually seem to be necessary except to pull +// in sys/ioctl.h. #define _INPUT_H #include // Would normally be included in linux/input.h #include @@ -38,19 +43,33 @@ #endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ -#define MOD_SHIFT_MASK 0x01 -#define MOD_ALT_MASK 0x02 -#define MOD_CONTROL_MASK 0x04 +#include "CColorConverter.h" +#include "CContextEGL.h" +#include "COSOperator.h" +#include "CTimer.h" +#include "CVideoModeList.h" +#include "IEventReceiver.h" +#include "IGUIEnvironment.h" +#include "IGUISpriteBank.h" +#include "irrString.h" +#include "ISceneManager.h" +#include "Keycodes.h" +#include "os.h" +#include "SIrrCreationParameters.h" + +#define MOD_SHIFT_MASK 0x01 +#define MOD_ALT_MASK 0x02 +#define MOD_CONTROL_MASK 0x04 namespace irr { - namespace video - { - extern bool useCoreContext; - IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, - io::IFileSystem* io, CIrrDeviceWayland* device); - } -} // end namespace irr + namespace video + { + extern bool useCoreContext; + IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, + io::IFileSystem* io, CIrrDeviceWayland* device); + } +} namespace irr { @@ -58,1238 +77,1209 @@ namespace irr class WaylandCallbacks { public: - // from http://cgit.freedesktop.org/wayland/weston/tree/clients/simple-egl.c - 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) - { - printf("enter!\n"); - - CIrrDeviceWayland *device = static_cast(data); - - device->enter_serial = serial; - device->updateCursor(); - } + static const wl_pointer_listener pointer_listener; + static const wl_seat_listener seat_listener; + static const wl_keyboard_listener keyboard_listener; + static const wl_output_listener output_listener; + static const wl_shell_surface_listener shell_surface_listener; + static const wl_registry_listener registry_listener; - static void - pointer_handle_leave(void *data, struct wl_pointer *pointer, - uint32_t serial, struct wl_surface *surface) - { - } + static void pointer_enter(void* data, wl_pointer* pointer, uint32_t serial, + wl_surface* surface, wl_fixed_t sx, wl_fixed_t sy) + { + CIrrDeviceWayland* device = static_cast(data); - static void - pointer_handle_motion(void *data, struct wl_pointer *pointer, - uint32_t time, wl_fixed_t sx, wl_fixed_t sy) - { - CIrrDeviceWayland *device = static_cast(data); - - device->getCursorControl()->setPosition(wl_fixed_to_int(sx), - wl_fixed_to_int(sy)); - - SEvent irrevent; - irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; - irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; - irrevent.MouseInput.X = device->getCursorControl()->getPosition().X; - irrevent.MouseInput.Y = device->getCursorControl()->getPosition().Y; - irrevent.MouseInput.Control = (device->modifiers & MOD_CONTROL_MASK) != 0; - irrevent.MouseInput.Shift = (device->modifiers & MOD_SHIFT_MASK) != 0; - irrevent.MouseInput.ButtonStates = device->ButtonStates; + device->m_enter_serial = serial; + device->updateCursor(); + } - device->signalEvent(irrevent); - } + static void pointer_leave(void* data, wl_pointer* pointer, uint32_t serial, + wl_surface* surface) + { + } - static void - pointer_handle_button(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, uint32_t time, uint32_t button, - uint32_t state) - { - CIrrDeviceWayland *device = static_cast(data); + static void pointer_motion(void* data, wl_pointer* pointer, uint32_t time, + wl_fixed_t sx, wl_fixed_t sy) + { + CIrrDeviceWayland* device = static_cast(data); - SEvent irrevent; - irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; - irrevent.MouseInput.X = device->getCursorControl()->getPosition().X; - irrevent.MouseInput.Y = device->getCursorControl()->getPosition().Y; - irrevent.MouseInput.Control = (device->modifiers & MOD_CONTROL_MASK) != 0; - irrevent.MouseInput.Shift = (device->modifiers & MOD_SHIFT_MASK) != 0; - irrevent.MouseInput.Event = irr::EMIE_COUNT; + device->getCursorControl()->setPosition(wl_fixed_to_int(sx), + wl_fixed_to_int(sy)); - switch (button) - { - case 272: - if (state == WL_POINTER_BUTTON_STATE_PRESSED) - { - irrevent.MouseInput.Event = irr::EMIE_LMOUSE_PRESSED_DOWN; - device->ButtonStates |= irr::EMBSM_LEFT; - } - else if (state == WL_POINTER_BUTTON_STATE_RELEASED) - { - irrevent.MouseInput.Event = irr::EMIE_LMOUSE_LEFT_UP; - device->ButtonStates &= ~(irr::EMBSM_LEFT); - } - break; - case 273: - if (state == WL_POINTER_BUTTON_STATE_PRESSED) - { - irrevent.MouseInput.Event = irr::EMIE_RMOUSE_PRESSED_DOWN; - device->ButtonStates |= irr::EMBSM_RIGHT; - } - else if (state == WL_POINTER_BUTTON_STATE_RELEASED) - { - irrevent.MouseInput.Event = irr::EMIE_RMOUSE_LEFT_UP; - device->ButtonStates &= ~(irr::EMBSM_RIGHT); - } - break; - case 274: - if (state == WL_POINTER_BUTTON_STATE_PRESSED) - { - irrevent.MouseInput.Event = irr::EMIE_MMOUSE_PRESSED_DOWN; - device->ButtonStates |= irr::EMBSM_MIDDLE; - } - else if (state == WL_POINTER_BUTTON_STATE_RELEASED) - { - irrevent.MouseInput.Event = irr::EMIE_MMOUSE_LEFT_UP; - device->ButtonStates &= ~(irr::EMBSM_MIDDLE); - } - default: - break; - } - - if (irrevent.MouseInput.Event != irr::EMIE_COUNT) - { - irrevent.MouseInput.ButtonStates = device->ButtonStates; - - device->signalEvent(irrevent); + SEvent irrevent; + irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; + irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; + irrevent.MouseInput.X = device->getCursorControl()->getPosition().X; + irrevent.MouseInput.Y = device->getCursorControl()->getPosition().Y; + irrevent.MouseInput.Control = (device->m_xkb_modifiers & MOD_CONTROL_MASK) != 0; + irrevent.MouseInput.Shift = (device->m_xkb_modifiers & MOD_SHIFT_MASK) != 0; + irrevent.MouseInput.ButtonStates = device->m_mouse_button_states; - // It's not exactly true for middle/right button, but keep consistency with x11 device - if ( irrevent.MouseInput.Event >= EMIE_LMOUSE_PRESSED_DOWN && irrevent.MouseInput.Event <= EMIE_MMOUSE_PRESSED_DOWN ) - { - u32 clicks = device->checkSuccessiveClicks(irrevent.MouseInput.X, irrevent.MouseInput.Y, irrevent.MouseInput.Event); - if ( clicks == 2 ) - { - printf("doubleclick\n"); - irrevent.MouseInput.Event = (EMOUSE_INPUT_EVENT)(EMIE_LMOUSE_DOUBLE_CLICK + irrevent.MouseInput.Event-EMIE_LMOUSE_PRESSED_DOWN); - device->signalEvent(irrevent); - } - else if ( clicks == 3 ) - { - printf("tripleclick\n"); - irrevent.MouseInput.Event = (EMOUSE_INPUT_EVENT)(EMIE_LMOUSE_TRIPLE_CLICK + irrevent.MouseInput.Event-EMIE_LMOUSE_PRESSED_DOWN); - device->signalEvent(irrevent); - } - } - } - } + device->signalEvent(irrevent); + } - static void - pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, - uint32_t time, uint32_t axis, wl_fixed_t value) - { - } + static void pointer_button(void* data, wl_pointer* wl_pointer, + uint32_t serial, uint32_t time, uint32_t button, + uint32_t state) + { + CIrrDeviceWayland* device = static_cast(data); - static const struct wl_pointer_listener pointer_listener; + SEvent irrevent; + irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; + irrevent.MouseInput.X = device->getCursorControl()->getPosition().X; + irrevent.MouseInput.Y = device->getCursorControl()->getPosition().Y; + irrevent.MouseInput.Control = (device->m_xkb_modifiers & MOD_CONTROL_MASK) != 0; + irrevent.MouseInput.Shift = (device->m_xkb_modifiers & MOD_SHIFT_MASK) != 0; + irrevent.MouseInput.Event = irr::EMIE_COUNT; - static void - keyboard_repeat_func(struct task *task, uint32_t events) - { - } + switch (button) + { + case 272: + if (state == WL_POINTER_BUTTON_STATE_PRESSED) + { + irrevent.MouseInput.Event = irr::EMIE_LMOUSE_PRESSED_DOWN; + device->m_mouse_button_states |= irr::EMBSM_LEFT; + } + else if (state == WL_POINTER_BUTTON_STATE_RELEASED) + { + irrevent.MouseInput.Event = irr::EMIE_LMOUSE_LEFT_UP; + device->m_mouse_button_states &= ~(irr::EMBSM_LEFT); + } + break; + case 273: + if (state == WL_POINTER_BUTTON_STATE_PRESSED) + { + irrevent.MouseInput.Event = irr::EMIE_RMOUSE_PRESSED_DOWN; + device->m_mouse_button_states |= irr::EMBSM_RIGHT; + } + else if (state == WL_POINTER_BUTTON_STATE_RELEASED) + { + irrevent.MouseInput.Event = irr::EMIE_RMOUSE_LEFT_UP; + device->m_mouse_button_states &= ~(irr::EMBSM_RIGHT); + } + break; + case 274: + if (state == WL_POINTER_BUTTON_STATE_PRESSED) + { + irrevent.MouseInput.Event = irr::EMIE_MMOUSE_PRESSED_DOWN; + device->m_mouse_button_states |= irr::EMBSM_MIDDLE; + } + else if (state == WL_POINTER_BUTTON_STATE_RELEASED) + { + irrevent.MouseInput.Event = irr::EMIE_MMOUSE_LEFT_UP; + device->m_mouse_button_states &= ~(irr::EMBSM_MIDDLE); + } + default: + break; + } - static void - keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, - uint32_t format, int fd, uint32_t size) - { - CIrrDeviceWayland *device = static_cast(data); - - //~ struct xkb_keymap *keymap; - //~ struct xkb_state *state; - //~ struct xkb_compose_table *compose_table; - //~ struct xkb_compose_state *compose_state; - char *map_str; - - if (!device) { - close(fd); - return; - } - - if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { - close(fd); - return; - } - - map_str = static_cast(mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0)); - if (map_str == MAP_FAILED) { - close(fd); - return; - } - - /* Set up XKB keymap */ - device->keymap = xkb_keymap_new_from_string(device->xkbctx, - map_str, - XKB_KEYMAP_FORMAT_TEXT_V1, - XKB_KEYMAP_COMPILE_NO_FLAGS); - munmap(map_str, size); - close(fd); - - if (!device->keymap) { - fprintf(stderr, "failed to compile keymap\n"); - return; - } - - /* Set up XKB state */ - device->state = xkb_state_new(device->keymap); - if (!device->state) { - fprintf(stderr, "failed to create XKB state\n"); - xkb_keymap_unref(device->keymap); - return; - } - - /* Look up the preferred locale, falling back to "C" as default */ - std::string locale = "C"; - - if (getenv("LC_ALL")) - locale = getenv("LC_ALL"); - else if (getenv("LC_CTYPE")) - locale = getenv("LC_CTYPE"); - else if (getenv("LANG")) - locale = getenv("LANG"); - - /* Set up XKB compose table */ - device->compose_table = - xkb_compose_table_new_from_locale(device->xkbctx, - locale.c_str(), - XKB_COMPOSE_COMPILE_NO_FLAGS); - if (device->compose_table) { - /* Set up XKB compose state */ - device->compose_state = xkb_compose_state_new(device->compose_table, - XKB_COMPOSE_STATE_NO_FLAGS); - if (device->compose_state) { - //~ xkb_compose_state_unref(device->compose_state); - //~ xkb_compose_table_unref(device->compose_table); - //~ device->compose_state = compose_state; - //~ device->compose_table = compose_table; - } else { - fprintf(stderr, "could not create XKB compose state. " - "Disabiling compose.\n"); - xkb_compose_table_unref(device->compose_table); - device->compose_table = NULL; - } - } else { - fprintf(stderr, "could not create XKB compose table for locale '%s'. " - "Disabiling compose\n", locale.c_str()); - } - - //~ xkb_keymap_unref(device->keymap); - //~ xkb_state_unref(device->state); - //~ device->keymap = keymap; - //~ device->state = state; - - device->control_mask = - 1 << xkb_keymap_mod_get_index(device->keymap, "Control"); - device->alt_mask = - 1 << xkb_keymap_mod_get_index(device->keymap, "Mod1"); - device->shift_mask = - 1 << xkb_keymap_mod_get_index(device->keymap, "Shift"); - } + if (irrevent.MouseInput.Event == irr::EMIE_COUNT) + return; - static void - keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, - uint32_t serial, struct wl_surface *surface, - struct wl_array *keys) - { - } + irrevent.MouseInput.ButtonStates = device->m_mouse_button_states; - static void - keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, - uint32_t serial, struct wl_surface *surface) - { - } + device->signalEvent(irrevent); - static void - keyboard_handle_key(void *data, struct wl_keyboard *keyboard, - uint32_t serial, uint32_t time, uint32_t key, - uint32_t state_w) - { - CIrrDeviceWayland *device = static_cast(data); - - uint32_t code; - enum wl_keyboard_key_state state = (wl_keyboard_key_state) state_w; - xkb_keysym_t sym; - uint32_t num_syms; - const xkb_keysym_t *syms; - SEvent irrevent; - - if (!device->state) - return; - - code = key + 8; - - num_syms = xkb_state_key_get_syms(device->state, code, &syms); - - sym = XKB_KEY_NoSymbol; - if (num_syms == 1) - sym = syms[0]; - - CIrrDeviceWayland::SKeyMap mp; - mp.X11Key = sym; - + // It's not exactly true for middle/right button, but keep + // consistency with x11 device + if (irrevent.MouseInput.Event >= EMIE_LMOUSE_PRESSED_DOWN && + irrevent.MouseInput.Event <= EMIE_MMOUSE_PRESSED_DOWN) + { + u32 clicks = device->checkSuccessiveClicks( + irrevent.MouseInput.X, + irrevent.MouseInput.Y, + irrevent.MouseInput.Event); + if (clicks == 2) + { + irrevent.MouseInput.Event = + (EMOUSE_INPUT_EVENT)(EMIE_LMOUSE_DOUBLE_CLICK + + irrevent.MouseInput.Event-EMIE_LMOUSE_PRESSED_DOWN); - if (!device->compose_state) - sym = sym; - if (sym == XKB_KEY_NoSymbol) - sym = sym; - if (xkb_compose_state_feed(device->compose_state, - sym) != XKB_COMPOSE_FEED_ACCEPTED) - sym = sym; + device->signalEvent(irrevent); + } + else if ( clicks == 3 ) + { + irrevent.MouseInput.Event = + (EMOUSE_INPUT_EVENT)(EMIE_LMOUSE_TRIPLE_CLICK + + irrevent.MouseInput.Event-EMIE_LMOUSE_PRESSED_DOWN); - switch (xkb_compose_state_get_status(device->compose_state)) { - case XKB_COMPOSE_COMPOSING: - return; - case XKB_COMPOSE_COMPOSED: - sym = xkb_compose_state_get_one_sym(device->compose_state); - case XKB_COMPOSE_CANCELLED: - return; - case XKB_COMPOSE_NOTHING: - sym = sym; - default: - sym = sym; - } + device->signalEvent(irrevent); + } + } + } - - //~ printf("%c\n", sym); - - if (sym == XKB_KEY_NoSymbol) - sym = 0; - + static void pointer_axis(void* data, wl_pointer* wl_pointer, uint32_t time, + uint32_t axis, wl_fixed_t value) + { + } - - irrevent.EventType = irr::EET_KEY_INPUT_EVENT; - irrevent.KeyInput.PressedDown = (state == WL_KEYBOARD_KEY_STATE_PRESSED); - irrevent.KeyInput.Char = xkb_keysym_to_utf32(sym); - irrevent.KeyInput.Control = (device->modifiers & MOD_CONTROL_MASK) != 0; - irrevent.KeyInput.Shift = (device->modifiers & MOD_SHIFT_MASK) != 0; - - - + static void keyboard_keymap(void* data, wl_keyboard* keyboard, + uint32_t format, int fd, uint32_t size) + { + CIrrDeviceWayland* device = static_cast(data); - - - const s32 idx = device->KeyMap.binary_search(mp); - if (idx != -1) - { - irrevent.KeyInput.Key = (EKEY_CODE)device->KeyMap[idx].Win32Key; - } - else - { - irrevent.KeyInput.Key = (EKEY_CODE)0; - } - if (irrevent.KeyInput.Key == 0) - { - // 1:1 mapping to windows-keys would require testing for keyboard type (us, ger, ...) - // So unless we do that we will have some unknown keys here. - if (idx == -1) - { - // os::Printer::log("Could not find EKEY_CODE, using orig. X11 keycode instead", core::stringc(event.xkey.keycode).c_str(), ELL_INFORMATION); - } - else - { - // os::Printer::log("EKEY_CODE is 0, using orig. X11 keycode instead", core::stringc(event.xkey.keycode).c_str(), ELL_INFORMATION); - } - // Any value is better than none, that allows at least using the keys. - // Worst case is that some keys will be identical, still better than _all_ - // unknown keys being identical. - // irrevent.KeyInput.Key = (EKEY_CODE)event.xkey.keycode; - } - - device->signalEvent(irrevent); - } + if (!device) + { + close(fd); + return; + } - 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) - { - CIrrDeviceWayland *device = static_cast(data); + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) + { + close(fd); + return; + } - xkb_mod_mask_t mask; - - /* If we're not using a keymap, then we don't handle PC-style modifiers */ - if (!device->keymap) - return; - - xkb_state_update_mask(device->state, mods_depressed, mods_latched, - mods_locked, 0, 0, group); - xkb_state_component state_component = (xkb_state_component)( - XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED); - mask = xkb_state_serialize_mods(device->state, - state_component); - - device->modifiers = 0; - if (mask & device->control_mask) - device->modifiers |= MOD_CONTROL_MASK; - if (mask & device->alt_mask) - device->modifiers |= MOD_ALT_MASK; - if (mask & device->shift_mask) - device->modifiers |= MOD_SHIFT_MASK; - } + char* map_str = static_cast(mmap(NULL, size, PROT_READ, + MAP_SHARED, fd, 0)); - static void - set_repeat_info(struct input *input, int32_t rate, int32_t delay) - { - - } + if (map_str == MAP_FAILED) + { + close(fd); + return; + } - static void - keyboard_handle_repeat_info(void *data, struct wl_keyboard *keyboard, - int32_t rate, int32_t delay) - { - } + device->m_xkb_keymap = xkb_keymap_new_from_string( + device->m_xkb_context, + map_str, + XKB_KEYMAP_FORMAT_TEXT_V1, + XKB_KEYMAP_COMPILE_NO_FLAGS); + munmap(map_str, size); + close(fd); - static const struct wl_keyboard_listener keyboard_listener; + if (!device->m_xkb_keymap) + { + return; + } - static void - seat_handle_capabilities(void *data, struct wl_seat *seat, - uint32_t caps) - { - CIrrDeviceWayland *dev = static_cast(data); + device->m_xkb_state = xkb_state_new(device->m_xkb_keymap); - if ((caps & WL_SEAT_CAPABILITY_POINTER) && !dev->pointer) { - dev->pointer = wl_seat_get_pointer(seat); - wl_pointer_add_listener(dev->pointer, &pointer_listener, data); - } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && dev->pointer) { - wl_pointer_destroy(dev->pointer); - dev->pointer = NULL; - } + if (!device->m_xkb_state) + { + xkb_keymap_unref(device->m_xkb_keymap); + device->m_xkb_keymap = NULL; + return; + } - if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !dev->keyboard) { - dev->keyboard = wl_seat_get_keyboard(seat); - wl_keyboard_add_listener(dev->keyboard, &keyboard_listener, dev); - } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && dev->keyboard) { - wl_keyboard_destroy(dev->keyboard); - dev->keyboard = NULL; - } - } + device->m_xkb_control_mask = + 1 << xkb_keymap_mod_get_index(device->m_xkb_keymap, "Control"); + device->m_xkb_alt_mask = + 1 << xkb_keymap_mod_get_index(device->m_xkb_keymap, "Mod1"); + device->m_xkb_shift_mask = + 1 << xkb_keymap_mod_get_index(device->m_xkb_keymap, "Shift"); - static const struct wl_seat_listener seat_listener; + std::string locale = "C"; - static void - display_handle_geometry(void *data, - struct wl_output *wl_output, - int x, int y, - int physical_width, - int physical_height, - int subpixel, - const char *make, - const char *model, - int transform) - { - printf("output model is %s\n", model); - } + if (getenv("LC_ALL")) + { + locale = getenv("LC_ALL"); + } + else if (getenv("LC_CTYPE")) + { + locale = getenv("LC_CTYPE"); + } + else if (getenv("LANG")) + { + locale = getenv("LANG"); + } - static void - display_handle_done(void *data, - struct wl_output *wl_output) - { - printf("done\n"); - } + device->m_xkb_compose_table = xkb_compose_table_new_from_locale( + device->m_xkb_context, + locale.c_str(), + XKB_COMPOSE_COMPILE_NO_FLAGS); - static void - display_handle_scale(void *data, - struct wl_output *wl_output, - int32_t scale) - { - } + if (!device->m_xkb_compose_table) + return; - static void - display_handle_mode(void *data, - struct wl_output *wl_output, - uint32_t flags, - int width, - int height, - int refresh) - { - CIrrDeviceWayland *dev = static_cast(data); - dev->VideoModeList.addMode(core::dimension2du(width, height), 24); - if (flags & WL_OUTPUT_MODE_CURRENT) { - dev->VideoModeList.setDesktop(24, core::dimension2du(width, height)); - } - } - - static void - handle_ping(void *data, struct wl_shell_surface *shell_surface, - uint32_t serial) - { - printf("ping"); - wl_shell_surface_pong(shell_surface, serial); - } - - static void - handle_configure(void *data, struct wl_shell_surface *shell_surface, - uint32_t edges, int32_t width, int32_t height) - { - } - - static void - handle_popup_done(void *data, struct wl_shell_surface *shell_surface) - { - } + device->m_xkb_compose_state = xkb_compose_state_new( + device->m_xkb_compose_table, + XKB_COMPOSE_STATE_NO_FLAGS); - static const struct wl_output_listener output_listener; - static const struct wl_shell_surface_listener shell_surface_listener; + if (!device->m_xkb_compose_state) + { + xkb_compose_table_unref(device->m_xkb_compose_table); + device->m_xkb_compose_table = NULL; + } + } - static void registry_add (void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { - CIrrDeviceWayland *dev = static_cast(data); - if (!strcmp(interface,"wl_compositor")) { - printf("binding compositor\n"); - dev->compositor = static_cast(wl_registry_bind (registry, name, &wl_compositor_interface, 1)); - } - else if (!strcmp(interface,"wl_shell")) { - printf("binding shell\n"); - dev->shell = static_cast(wl_registry_bind (registry, name, &wl_shell_interface, 1)); - } - else if (strcmp(interface, "wl_seat") == 0) { - printf("binding seat\n"); - dev->seat = static_cast(wl_registry_bind(registry, name, &wl_seat_interface, 1)); - } - else if (strcmp(interface, "wl_shm") == 0) { - dev->shm = static_cast(wl_registry_bind(registry, name, &wl_shm_interface, 1)); - dev->cursor_theme = wl_cursor_theme_load(NULL, 32, dev->shm); - if (!dev->cursor_theme) { - printf("unable to load default theme\n"); - return; - } - dev->default_cursor = - wl_cursor_theme_get_cursor(dev->cursor_theme, "left_ptr"); - if (!dev->default_cursor) { - printf("unable to load default left pointer\n"); - } - } - else if (strcmp(interface, "wl_output") == 0) - { - printf("binding output\n"); - dev->output = static_cast(wl_registry_bind(dev->registry, name, &wl_output_interface, 2)); - } - } + static void keyboard_enter(void* data, wl_keyboard* keyboard, + uint32_t serial, wl_surface* surface, + wl_array* keys) + { + } - static void registry_remove (void *data, struct wl_registry *registry, uint32_t name) { - printf ("registry_remove_object\n"); - } + static void keyboard_leave(void* data, wl_keyboard* keyboard, + uint32_t serial, wl_surface* surface) + { + } - static const wl_registry_listener registry_listener; + static void keyboard_key(void* data, wl_keyboard* keyboard, uint32_t serial, + uint32_t time, uint32_t key, uint32_t state_w) + { + CIrrDeviceWayland* device = static_cast(data); + + if (!device->m_xkb_state) + return; + + wl_keyboard_key_state state = (wl_keyboard_key_state)state_w; + uint32_t code = key + 8; + xkb_keysym_t sym = XKB_KEY_NoSymbol; + + const xkb_keysym_t* syms; + uint32_t num_syms = xkb_state_key_get_syms(device->m_xkb_state, code, + &syms); + + if (num_syms == 1) + sym = syms[0]; + + bool ignore = false; + + if (sym != XKB_KEY_NoSymbol && device->m_xkb_compose_state) + { + xkb_compose_feed_result result; + result = xkb_compose_state_feed(device->m_xkb_compose_state, sym); + + if (result == XKB_COMPOSE_FEED_ACCEPTED) + { + xkb_compose_status status; + status = xkb_compose_state_get_status( + device->m_xkb_compose_state); + + if (status == XKB_COMPOSE_COMPOSING || + status == XKB_COMPOSE_CANCELLED) + { + ignore = true; + } + + if (status == XKB_COMPOSE_COMPOSED) + { + sym = xkb_compose_state_get_one_sym( + device->m_xkb_compose_state); + } + } + } + + if (ignore == true) + return; + + SEvent irrevent; + irrevent.EventType = irr::EET_KEY_INPUT_EVENT; + irrevent.KeyInput.PressedDown = (state == WL_KEYBOARD_KEY_STATE_PRESSED); + irrevent.KeyInput.Char = xkb_keysym_to_utf32(sym); + irrevent.KeyInput.Control = (device->m_xkb_modifiers & + MOD_CONTROL_MASK) != 0; + irrevent.KeyInput.Shift = (device->m_xkb_modifiers & + MOD_SHIFT_MASK) != 0; + irrevent.KeyInput.Key = device->m_key_map[sym]; + + device->signalEvent(irrevent); + } + + static void 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) + { + CIrrDeviceWayland* device = static_cast(data); + + if (!device->m_xkb_keymap) + return; + + xkb_state_update_mask(device->m_xkb_state, mods_depressed, mods_latched, + mods_locked, 0, 0, group); + xkb_state_component state_component = (xkb_state_component)( + XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED); + xkb_mod_mask_t mask = xkb_state_serialize_mods(device->m_xkb_state, + state_component); + + device->m_xkb_modifiers = 0; + + if (mask & device->m_xkb_control_mask) + { + device->m_xkb_modifiers |= MOD_CONTROL_MASK; + } + + if (mask & device->m_xkb_alt_mask) + { + device->m_xkb_modifiers |= MOD_ALT_MASK; + } + + if (mask & device->m_xkb_shift_mask) + { + device->m_xkb_modifiers |= MOD_SHIFT_MASK; + } + } + + static void keyboard_repeat_info(void* data, wl_keyboard* keyboard, + int32_t rate, int32_t delay) + { + } + + static void seat_capabilities(void* data, wl_seat* seat, uint32_t caps) + { + CIrrDeviceWayland* device = static_cast(data); + + if ((caps & WL_SEAT_CAPABILITY_POINTER) && !device->m_pointer) + { + device->m_pointer = wl_seat_get_pointer(seat); + wl_pointer_add_listener(device->m_pointer, &pointer_listener, device); + } + else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && device->m_pointer) + { + wl_pointer_destroy(device->m_pointer); + device->m_pointer = NULL; + } + + if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !device->m_keyboard) + { + device->m_keyboard = wl_seat_get_keyboard(seat); + wl_keyboard_add_listener(device->m_keyboard, &keyboard_listener, + device); + } + else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && device->m_keyboard) + { + wl_keyboard_destroy(device->m_keyboard); + device->m_keyboard = NULL; + } + } + + static void output_geometry(void* data, wl_output* wl_output, int32_t x, + int32_t y, int32_t physical_width, + int32_t physical_height, int32_t subpixel, + const char* make, const char* model, + int32_t transform) + + { + } + + static void output_done(void* data, wl_output* wl_output) + { + } + + static void output_scale(void* data, wl_output* wl_output, int32_t scale) + { + } + + static void output_mode(void* data, struct wl_output* wl_output, + uint32_t flags, int32_t width, int32_t height, + int32_t refresh) + { + CIrrDeviceWayland* device = static_cast(data); + + device->VideoModeList.addMode(core::dimension2du(width, height), 24); + + if (flags & WL_OUTPUT_MODE_CURRENT) + { + device->VideoModeList.setDesktop(24, core::dimension2du(width, + height)); + } + } + + static void shell_surface_ping(void* data, wl_shell_surface* shell_surface, + uint32_t serial) + { + wl_shell_surface_pong(shell_surface, serial); + } + + static void shell_surface_configure(void* data, + wl_shell_surface* shell_surface, + uint32_t edges, int32_t width, + int32_t height) + { + } + + static void shell_surface_popup_done(void* data, + wl_shell_surface* shell_surface) + { + } + + static void registry_global(void* data, wl_registry* registry, + uint32_t name, const char* interface, + uint32_t version) + { + CIrrDeviceWayland* device = static_cast(data); + + if (interface == NULL) + return; + + std::string interface_str = interface; + + if (interface_str == "wl_compositor") + { + device->m_compositor = static_cast(wl_registry_bind( + registry, name, &wl_compositor_interface, 1)); + } + else if (interface_str == "wl_shell") + { + device->m_shell = static_cast(wl_registry_bind(registry, + name, &wl_shell_interface, 1)); + } + else if (interface_str == "wl_seat") + { + device->m_seat = static_cast(wl_registry_bind(registry, + name, &wl_seat_interface, 1)); + } + else if (interface_str == "wl_shm") + { + device->m_shm = static_cast(wl_registry_bind(registry, name, + &wl_shm_interface, 1)); + } + else if (interface_str == "wl_output") + { + device->m_output = static_cast(wl_registry_bind(registry, + name, &wl_output_interface, 2)); + } + } + + static void registry_global_remove(void* data, wl_registry* registry, + uint32_t name) + { + } }; -const struct wl_pointer_listener WaylandCallbacks::pointer_listener = { - WaylandCallbacks::pointer_handle_enter, - WaylandCallbacks::pointer_handle_leave, - WaylandCallbacks::pointer_handle_motion, - WaylandCallbacks::pointer_handle_button, - WaylandCallbacks::pointer_handle_axis, -}; - -const struct wl_keyboard_listener WaylandCallbacks::keyboard_listener = { - WaylandCallbacks::keyboard_handle_keymap, - WaylandCallbacks::keyboard_handle_enter, - WaylandCallbacks::keyboard_handle_leave, - WaylandCallbacks::keyboard_handle_key, - WaylandCallbacks::keyboard_handle_modifiers, - WaylandCallbacks::keyboard_handle_repeat_info -}; - -const struct wl_seat_listener WaylandCallbacks::seat_listener = { - WaylandCallbacks::seat_handle_capabilities, -}; - -const struct wl_output_listener WaylandCallbacks::output_listener = { - WaylandCallbacks::display_handle_geometry, - WaylandCallbacks::display_handle_mode, - WaylandCallbacks::display_handle_done, - WaylandCallbacks::display_handle_scale -}; - -const struct wl_shell_surface_listener WaylandCallbacks::shell_surface_listener = +const wl_pointer_listener WaylandCallbacks::pointer_listener = { - WaylandCallbacks::handle_ping, - WaylandCallbacks::handle_configure, - WaylandCallbacks::handle_popup_done + WaylandCallbacks::pointer_enter, + WaylandCallbacks::pointer_leave, + WaylandCallbacks::pointer_motion, + WaylandCallbacks::pointer_button, + WaylandCallbacks::pointer_axis }; -const wl_registry_listener WaylandCallbacks::registry_listener = { - WaylandCallbacks::registry_add, - WaylandCallbacks::registry_remove, +const wl_keyboard_listener WaylandCallbacks::keyboard_listener = +{ + WaylandCallbacks::keyboard_keymap, + WaylandCallbacks::keyboard_enter, + WaylandCallbacks::keyboard_leave, + WaylandCallbacks::keyboard_key, + WaylandCallbacks::keyboard_modifiers, + WaylandCallbacks::keyboard_repeat_info +}; + +const wl_seat_listener WaylandCallbacks::seat_listener = +{ + WaylandCallbacks::seat_capabilities +}; + +const wl_output_listener WaylandCallbacks::output_listener = +{ + WaylandCallbacks::output_geometry, + WaylandCallbacks::output_mode, + WaylandCallbacks::output_done, + WaylandCallbacks::output_scale +}; + +const wl_shell_surface_listener WaylandCallbacks::shell_surface_listener = +{ + WaylandCallbacks::shell_surface_ping, + WaylandCallbacks::shell_surface_configure, + WaylandCallbacks::shell_surface_popup_done +}; + +const wl_registry_listener WaylandCallbacks::registry_listener = +{ + WaylandCallbacks::registry_global, + WaylandCallbacks::registry_global_remove }; bool CIrrDeviceWayland::isWaylandDeviceWorking() { - bool is_working = false; - - wl_display* display = wl_display_connect(NULL); + bool is_working = false; - if (display != NULL) - { - is_working = true; - wl_display_disconnect(display); - } + wl_display* display = wl_display_connect(NULL); + + if (display != NULL) + { + is_working = true; + wl_display_disconnect(display); + } return is_working; } -//! constructor -CIrrDeviceWayland::CIrrDeviceWayland(const SIrrlichtCreationParameters& param) - : CIrrDeviceStub(param), - Width(param.WindowSize.Width), Height(param.WindowSize.Height), - WindowHasFocus(false), WindowMinimized(false) +CIrrDeviceWayland::CIrrDeviceWayland(const SIrrlichtCreationParameters& params) + : CIrrDeviceStub(params) { - #ifdef _DEBUG - setDebugName("CIrrDeviceLinux"); - #endif - - EglContext = NULL; + #ifdef _DEBUG + setDebugName("CIrrDeviceWayland"); + #endif - // print version, distribution etc. - // thx to LynxLuna for pointing me to the uname function - core::stringc linuxversion; - struct utsname LinuxInfo; - uname(&LinuxInfo); + m_compositor = NULL; + m_cursor = NULL; + m_cursor_theme = NULL; + m_display = NULL; + m_egl_window = NULL; + m_keyboard = NULL; + m_output = NULL; + m_pointer = NULL; + m_registry = NULL; + m_seat = NULL; + m_shell = NULL; + m_shell_surface = NULL; + m_shm = NULL; + m_cursor_surface = NULL; + m_surface = NULL; + m_enter_serial = 0; - linuxversion += LinuxInfo.sysname; - linuxversion += " "; - linuxversion += LinuxInfo.release; - linuxversion += " "; - linuxversion += LinuxInfo.version; - linuxversion += " "; - linuxversion += LinuxInfo.machine; + m_xkb_context = NULL; + m_xkb_compose_table = NULL; + m_xkb_compose_state = NULL; + m_xkb_keymap = NULL; + m_xkb_state = NULL; + m_xkb_control_mask = 0; + m_xkb_alt_mask = 0; + m_xkb_shift_mask = 0; + m_xkb_modifiers = 0; - Operator = new COSOperator(linuxversion, this); - os::Printer::log(linuxversion.c_str(), ELL_INFORMATION); + m_egl_context = NULL; - // Retrieve wayland infos - display = wl_display_connect(NULL); - registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, &WaylandCallbacks::registry_listener, this); - wl_display_dispatch(display); + m_mouse_button_states = 0; + m_width = params.WindowSize.Width; + m_height = params.WindowSize.Height; + m_window_has_focus = false; + m_window_minimized = false; - xkbctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + utsname LinuxInfo; + uname(&LinuxInfo); - pointer = 0; - keyboard = 0; - ButtonStates = 0; - enter_serial = 0; + core::stringc linuxversion; + linuxversion += LinuxInfo.sysname; + linuxversion += " "; + linuxversion += LinuxInfo.release; + linuxversion += " "; + linuxversion += LinuxInfo.version; + linuxversion += " "; + linuxversion += LinuxInfo.machine; - wl_seat_add_listener(seat, &WaylandCallbacks::seat_listener, this); - wl_output_add_listener(output, &WaylandCallbacks::output_listener, this); - - shell_surface = NULL; - cursor_surface = NULL; - cursor_theme = NULL; + Operator = new COSOperator(linuxversion, this); + os::Printer::log(linuxversion.c_str(), ELL_INFORMATION); - // create keymap - createKeyMap(); + CursorControl = new CCursorControl(this); - // create window - if (CreationParams.DriverType != video::EDT_NULL) - { - // create the window, only if we do not use the null device - if (!createWindow()) - return; - - cursor_surface = wl_compositor_create_surface(compositor); - } + createKeyMap(); - // create cursor control - CursorControl = new CCursorControl(this, CreationParams.DriverType == video::EDT_NULL); + m_display = wl_display_connect(NULL); + m_registry = wl_display_get_registry(m_display); + wl_registry_add_listener(m_registry, &WaylandCallbacks::registry_listener, this); + wl_display_dispatch(m_display); - // create driver - createDriver(); + m_xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - if (VideoDriver) - createGUIAndScene(); + if (CreationParams.DriverType != video::EDT_NULL) + { + if (!createWindow()) + return; + } - // Sync everything wayland before leaving - wl_display_dispatch(display); + wl_seat_add_listener(m_seat, &WaylandCallbacks::seat_listener, this); + wl_output_add_listener(m_output, &WaylandCallbacks::output_listener, this); + + createDriver(); + + if (VideoDriver) + createGUIAndScene(); + + wl_display_dispatch(m_display); } - //! destructor CIrrDeviceWayland::~CIrrDeviceWayland() { - printf("destroy dev\n"); - - delete EglContext; - - wl_output_destroy(output); - wl_keyboard_destroy(keyboard); - wl_pointer_destroy(pointer); - wl_seat_destroy(seat); - - if (cursor_surface) - wl_surface_destroy(cursor_surface); - - if (cursor_theme) - wl_cursor_theme_destroy(cursor_theme); - - if (shell_surface) - wl_shell_surface_destroy(shell_surface); - - wl_registry_destroy(registry); - wl_display_flush(display); - wl_display_disconnect(display); - xkb_context_unref(xkbctx); - + delete m_egl_context; -#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) - for (u32 joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) - { - if (ActiveJoysticks[joystick].fd >= 0) - { - close(ActiveJoysticks[joystick].fd); - } - } -#endif + if (m_keyboard) + wl_keyboard_destroy(m_keyboard); + + if (m_pointer) + wl_pointer_destroy(m_pointer); + + if (m_cursor_surface) + wl_surface_destroy(m_cursor_surface); + + if (m_cursor_theme) + wl_cursor_theme_destroy(m_cursor_theme); + + if (m_shell_surface) + wl_shell_surface_destroy(m_shell_surface); + + wl_output_destroy(m_output); + wl_seat_destroy(m_seat); + wl_registry_destroy(m_registry); + wl_display_flush(m_display); + wl_display_disconnect(m_display); + + xkb_context_unref(m_xkb_context); + + closeJoysticks(); } - -void CIrrDeviceWayland::initEGL() +bool CIrrDeviceWayland::initEGL() { - egl_window = wl_egl_window_create(surface, Width, Height); + m_egl_window = wl_egl_window_create(m_surface, m_width, m_height); - EglContext = new ContextManagerEGL(); - - ContextEGLParams egl_params; - egl_params.opengl_api = CEGL_API_OPENGL; - egl_params.surface_type = CEGL_SURFACE_WINDOW; - egl_params.force_legacy_device = CreationParams.ForceLegacyDevice; - egl_params.with_alpha_channel = CreationParams.WithAlphaChannel; - egl_params.vsync_enabled = CreationParams.Vsync; - egl_params.window = egl_window; - egl_params.display = display; - - EglContext->init(egl_params); - video::useCoreContext = !EglContext->isLegacyDevice(); - - int w = 0; - int h = 0; - - if (EglContext->getSurfaceDimensions(&w, &h)) - { - Width = w; - Height = h; - CreationParams.WindowSize.Width = Width; - CreationParams.WindowSize.Height = Height; - } + m_egl_context = new ContextManagerEGL(); + + ContextEGLParams egl_params; + egl_params.opengl_api = CEGL_API_OPENGL; + egl_params.surface_type = CEGL_SURFACE_WINDOW; + egl_params.force_legacy_device = CreationParams.ForceLegacyDevice; + egl_params.with_alpha_channel = CreationParams.WithAlphaChannel; + egl_params.vsync_enabled = CreationParams.Vsync; + egl_params.window = m_egl_window; + egl_params.display = m_display; + + bool success = m_egl_context->init(egl_params); + + if (!success) + return false; + + video::useCoreContext = !m_egl_context->isLegacyDevice(); + + int w = 0; + int h = 0; + + if (m_egl_context->getSurfaceDimensions(&w, &h)) + { + m_width = w; + m_height = h; + CreationParams.WindowSize.Width = m_width; + CreationParams.WindowSize.Height = m_height; + } + + return true; } bool CIrrDeviceWayland::createWindow() { - surface = wl_compositor_create_surface(compositor); - shell_surface = wl_shell_get_shell_surface(shell, surface); - - wl_shell_surface_add_listener(shell_surface, - &WaylandCallbacks::shell_surface_listener, this); - - if (CreationParams.Fullscreen) - { - wl_shell_surface_set_fullscreen(shell_surface, - WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, - 0, output); - } - else - { - wl_shell_surface_set_toplevel(shell_surface); - } - - wl_display_flush(display); - - initEGL(); - - wl_region* region = wl_compositor_create_region(compositor); - wl_region_add(region, 0, 0, Width, Height); - wl_surface_set_opaque_region(surface, region); - wl_region_destroy(region); - - wl_display_flush(display); - - return true; -} + m_surface = wl_compositor_create_surface(m_compositor); + m_shell_surface = wl_shell_get_shell_surface(m_shell, m_surface); + wl_shell_surface_add_listener(m_shell_surface, + &WaylandCallbacks::shell_surface_listener, this); + + if (CreationParams.Fullscreen) + { + wl_shell_surface_set_fullscreen(m_shell_surface, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, m_output); + } + else + { + wl_shell_surface_set_toplevel(m_shell_surface); + } + + wl_display_flush(m_display); + + bool success = initEGL(); + + if (!success) + { + os::Printer::log("Couldn't create OpenGL context.", ELL_ERROR); + return false; + } + + wl_region* region = wl_compositor_create_region(m_compositor); + wl_region_add(region, 0, 0, m_width, m_height); + wl_surface_set_opaque_region(m_surface, region); + wl_region_destroy(region); + + wl_display_flush(m_display); + + m_cursor_surface = wl_compositor_create_surface(m_compositor); + m_cursor_theme = wl_cursor_theme_load(NULL, 32, m_shm); + + if (!m_cursor_theme) + { + os::Printer::log("Couldn't load cursor theme.", ELL_ERROR); + } + else + { + m_cursor = wl_cursor_theme_get_cursor(m_cursor_theme, "left_ptr"); + + if (!m_cursor) + { + os::Printer::log("Couldn't load left pointer cursor.", ELL_ERROR); + } + } + + return true; +} //! create the driver void CIrrDeviceWayland::createDriver() { - switch(CreationParams.DriverType) - { - default: - os::Printer::log("Wayland driver only supports OpenGL.", ELL_ERROR); - break; - case video::EDT_OPENGL: - #ifdef _IRR_COMPILE_WITH_OPENGL_ - VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this); - #else - os::Printer::log("No OpenGL support compiled in.", ELL_ERROR); - #endif - break; - } + switch(CreationParams.DriverType) + { + default: + os::Printer::log("Wayland driver only supports OpenGL.", ELL_ERROR); + break; + case video::EDT_OPENGL: + #ifdef _IRR_COMPILE_WITH_OPENGL_ + VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this); + #else + os::Printer::log("No OpenGL support compiled in.", ELL_ERROR); + #endif + break; + } } - void CIrrDeviceWayland::swapBuffers() { - wl_display_dispatch_pending(display); - EglContext->swapBuffers(); + wl_display_dispatch_pending(m_display); + m_egl_context->swapBuffers(); } - void CIrrDeviceWayland::updateCursor() { - if (!getCursorControl()->isVisible() && CreationParams.Fullscreen) - { - wl_pointer_set_cursor(pointer, enter_serial, NULL, 0, 0); - } - else if (default_cursor) - { - wl_cursor_image* image = default_cursor->images[0]; - wl_buffer* buffer = wl_cursor_image_get_buffer(image); - - if (!buffer) - return; - - wl_pointer_set_cursor(pointer, enter_serial, cursor_surface, - image->hotspot_x, image->hotspot_y); - wl_surface_attach(cursor_surface, buffer, 0, 0); - wl_surface_damage(cursor_surface, 0, 0, - image->width, image->height); - wl_surface_commit(cursor_surface); - } -} + if (!getCursorControl()->isVisible() && CreationParams.Fullscreen) + { + wl_pointer_set_cursor(m_pointer, m_enter_serial, NULL, 0, 0); + } + else if (m_cursor) + { + wl_cursor_image* image = m_cursor->images[0]; + wl_buffer* buffer = wl_cursor_image_get_buffer(image); + if (!buffer) + return; -//! runs the device. Returns false if device wants to be deleted -bool CIrrDeviceWayland::run() -{ - os::Timer::tick(); - - for (unsigned i = 0; i < events.size(); i++) - { - postEventFromUser(events[i]); - } - - events.clear(); - - if (!Close) - pollJoysticks(); - - return !Close; -} - - -//! Pause the current process for the minimum time allowed only to allow other processes to execute -void CIrrDeviceWayland::yield() -{ - struct timespec ts = {0,1}; - nanosleep(&ts, NULL); -} - - -//! Pause execution and let other processes to run for a specified amount of time. -void CIrrDeviceWayland::sleep(u32 timeMs, bool pauseTimer=false) -{ - const bool wasStopped = Timer ? Timer->isStopped() : true; - - struct timespec ts; - ts.tv_sec = (time_t) (timeMs / 1000); - ts.tv_nsec = (long) (timeMs % 1000) * 1000000; - - if (pauseTimer && !wasStopped) - Timer->stop(); - - nanosleep(&ts, NULL); - - if (pauseTimer && !wasStopped) - Timer->start(); -} - -CIrrDeviceWayland::CCursorControl::CCursorControl(CIrrDeviceWayland* dev, bool null) - : Device(dev) - , IsVisible(true), Null(null), UseReferenceRect(false) - , ActiveIcon(gui::ECI_NORMAL), ActiveIconStartTime(0) -{ -} - -CIrrDeviceWayland::CCursorControl::~CCursorControl() -{ - // Do not clearCursors here as the display is already closed - // TODO (cutealien): droping cursorcontrol earlier might work, not sure about reason why that's done in stub currently. + wl_pointer_set_cursor(m_pointer, m_enter_serial, m_cursor_surface, + image->hotspot_x, image->hotspot_y); + wl_surface_attach(m_cursor_surface, buffer, 0, 0); + wl_surface_damage(m_cursor_surface, 0, 0, image->width, image->height); + wl_surface_commit(m_cursor_surface); + } } void CIrrDeviceWayland::signalEvent(const SEvent &event) { - events.push_back(event); + m_events.push_back(event); } +//! runs the device. Returns false if device wants to be deleted +bool CIrrDeviceWayland::run() +{ + os::Timer::tick(); + + for (unsigned int i = 0; i < m_events.size(); i++) + { + postEventFromUser(m_events[i]); + } + + m_events.clear(); + + if (!Close) + pollJoysticks(); + + return !Close; +} + +//! Pause the current process for the minimum time allowed only to allow other +//! processes to execute +void CIrrDeviceWayland::yield() +{ + struct timespec ts = {0,1}; + nanosleep(&ts, NULL); +} + +//! Pause execution and let other processes to run for a specified amount of time. +void CIrrDeviceWayland::sleep(u32 timeMs, bool pauseTimer=false) +{ + const bool wasStopped = Timer ? Timer->isStopped() : true; + + struct timespec ts; + ts.tv_sec = (time_t) (timeMs / 1000); + ts.tv_nsec = (long) (timeMs % 1000)* 1000000; + + if (pauseTimer && !wasStopped) + Timer->stop(); + + nanosleep(&ts, NULL); + + if (pauseTimer && !wasStopped) + Timer->start(); +} //! sets the caption of the window void CIrrDeviceWayland::setWindowCaption(const wchar_t* text) { } - //! presents a surface in the client area -bool CIrrDeviceWayland::present(video::IImage* image, void* windowId, core::rect* srcRect) +bool CIrrDeviceWayland::present(video::IImage* image, void* windowId, + core::rect* srcRect) { - return true; + return true; } - //! notifies the device that it should close itself void CIrrDeviceWayland::closeDevice() { - Close = true; + Close = true; } - //! returns if window is active. if not, nothing need to be drawn bool CIrrDeviceWayland::isWindowActive() const { - return (WindowHasFocus && !WindowMinimized); + return (m_window_has_focus && !m_window_minimized); } - //! returns if window has focus. bool CIrrDeviceWayland::isWindowFocused() const { - return WindowHasFocus; + return m_window_has_focus; } - //! returns if window is minimized. bool CIrrDeviceWayland::isWindowMinimized() const { - return WindowMinimized; + return m_window_minimized; } - //! returns color format of the window. video::ECOLOR_FORMAT CIrrDeviceWayland::getColorFormat() const { - return video::ECF_R8G8B8; + return video::ECF_R8G8B8; } - //! Sets if the window should be resizable in windowed mode. void CIrrDeviceWayland::setResizable(bool resize) { } - //! Return pointer to a list with all video modes supported by the gfx adapter. video::IVideoModeList* CIrrDeviceWayland::getVideoModeList() { - printf("retrieve\n"); - return &VideoModeList; + return &VideoModeList; } - //! Minimize window void CIrrDeviceWayland::minimizeWindow() { - } - //! Maximize window void CIrrDeviceWayland::maximizeWindow() { - } - //! Restore original window size void CIrrDeviceWayland::restoreWindow() { - } +//! Set the current Gamma Value for the Display +bool CIrrDeviceWayland::setGammaRamp(f32 red, f32 green, f32 blue, + f32 brightness, f32 contrast) +{ + return false; +} + +//! Get the current Gamma Value for the Display +bool CIrrDeviceWayland::getGammaRamp(f32 &red, f32 &green, f32 &blue, + f32 &brightness, f32 &contrast) +{ + brightness = 0.0f; + contrast = 0.0f; + return false; +} + +//! gets text from the clipboard +//! \return Returns 0 if no string is in there. +const c8* CIrrDeviceWayland::getTextFromClipboard() const +{ + return m_clipboard.c_str(); +} + +//! copies text to the clipboard +void CIrrDeviceWayland::copyToClipboard(const c8* text) const +{ + m_clipboard = text; +} + +//! Remove all messages pending in the system message loop +void CIrrDeviceWayland::clearSystemMessages() +{ +} void CIrrDeviceWayland::createKeyMap() { - KeyMap.reallocate(190); - KeyMap.push_back(SKeyMap(XKB_KEY_BackSpace, KEY_BACK)); - KeyMap.push_back(SKeyMap(XKB_KEY_Tab, KEY_TAB)); - KeyMap.push_back(SKeyMap(XKB_KEY_ISO_Left_Tab, KEY_TAB)); -// KeyMap.push_back(SKeyMap(XK_Linefeed, 0)); // ??? - KeyMap.push_back(SKeyMap(XKB_KEY_Clear, KEY_CLEAR)); - KeyMap.push_back(SKeyMap(XKB_KEY_Return, KEY_RETURN)); - KeyMap.push_back(SKeyMap(XKB_KEY_Pause, KEY_PAUSE)); - KeyMap.push_back(SKeyMap(XKB_KEY_Scroll_Lock, KEY_SCROLL)); -// KeyMap.push_back(SKeyMap(XK_Sys_Req, 0)); // ??? - KeyMap.push_back(SKeyMap(XKB_KEY_Escape, KEY_ESCAPE)); - KeyMap.push_back(SKeyMap(XKB_KEY_Insert, KEY_INSERT)); - KeyMap.push_back(SKeyMap(XKB_KEY_Delete, KEY_DELETE)); - KeyMap.push_back(SKeyMap(XKB_KEY_Home, KEY_HOME)); - KeyMap.push_back(SKeyMap(XKB_KEY_Left, KEY_LEFT)); - KeyMap.push_back(SKeyMap(XKB_KEY_Up, KEY_UP)); - KeyMap.push_back(SKeyMap(XKB_KEY_Right, KEY_RIGHT)); - KeyMap.push_back(SKeyMap(XKB_KEY_Down, KEY_DOWN)); - KeyMap.push_back(SKeyMap(XKB_KEY_Prior, KEY_PRIOR)); - KeyMap.push_back(SKeyMap(XKB_KEY_Page_Up, KEY_PRIOR)); - KeyMap.push_back(SKeyMap(XKB_KEY_Next, KEY_NEXT)); - KeyMap.push_back(SKeyMap(XKB_KEY_Page_Down, KEY_NEXT)); - KeyMap.push_back(SKeyMap(XKB_KEY_End, KEY_END)); - KeyMap.push_back(SKeyMap(XKB_KEY_Begin, KEY_HOME)); - KeyMap.push_back(SKeyMap(XKB_KEY_Num_Lock, KEY_NUMLOCK)); - KeyMap.push_back(SKeyMap(XKB_KEY_space, KEY_SPACE)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Tab, KEY_TAB)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Enter, KEY_RETURN)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_F1, KEY_F1)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_F2, KEY_F2)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_F3, KEY_F3)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_F4, KEY_F4)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Home, KEY_HOME)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Left, KEY_LEFT)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Up, KEY_UP)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Right, KEY_RIGHT)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Down, KEY_DOWN)); - KeyMap.push_back(SKeyMap(XKB_KEY_Print, KEY_PRINT)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Prior, KEY_PRIOR)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Page_Up, KEY_PRIOR)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Next, KEY_NEXT)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Page_Down, KEY_NEXT)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_End, KEY_END)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Begin, KEY_HOME)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Insert, KEY_INSERT)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Delete, KEY_DELETE)); -// KeyMap.push_back(SKeyMap(XK_KP_Equal, 0)); // ??? - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Multiply, KEY_MULTIPLY)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Add, KEY_ADD)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Separator, KEY_SEPARATOR)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Subtract, KEY_SUBTRACT)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Decimal, KEY_DECIMAL)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_Divide, KEY_DIVIDE)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_0, KEY_NUMPAD0)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_1, KEY_NUMPAD1)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_2, KEY_NUMPAD2)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_3, KEY_NUMPAD3)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_4, KEY_NUMPAD4)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_5, KEY_NUMPAD5)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_6, KEY_NUMPAD6)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_7, KEY_NUMPAD7)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_8, KEY_NUMPAD8)); - KeyMap.push_back(SKeyMap(XKB_KEY_KP_9, KEY_NUMPAD9)); - KeyMap.push_back(SKeyMap(XKB_KEY_F1, KEY_F1)); - KeyMap.push_back(SKeyMap(XKB_KEY_F2, KEY_F2)); - KeyMap.push_back(SKeyMap(XKB_KEY_F3, KEY_F3)); - KeyMap.push_back(SKeyMap(XKB_KEY_F4, KEY_F4)); - KeyMap.push_back(SKeyMap(XKB_KEY_F5, KEY_F5)); - KeyMap.push_back(SKeyMap(XKB_KEY_F6, KEY_F6)); - KeyMap.push_back(SKeyMap(XKB_KEY_F7, KEY_F7)); - KeyMap.push_back(SKeyMap(XKB_KEY_F8, KEY_F8)); - KeyMap.push_back(SKeyMap(XKB_KEY_F9, KEY_F9)); - KeyMap.push_back(SKeyMap(XKB_KEY_F10, KEY_F10)); - KeyMap.push_back(SKeyMap(XKB_KEY_F11, KEY_F11)); - KeyMap.push_back(SKeyMap(XKB_KEY_F12, KEY_F12)); - KeyMap.push_back(SKeyMap(XKB_KEY_Shift_L, KEY_LSHIFT)); - KeyMap.push_back(SKeyMap(XKB_KEY_Shift_R, KEY_RSHIFT)); - KeyMap.push_back(SKeyMap(XKB_KEY_Control_L, KEY_LCONTROL)); - KeyMap.push_back(SKeyMap(XKB_KEY_Control_R, KEY_RCONTROL)); - KeyMap.push_back(SKeyMap(XKB_KEY_Caps_Lock, KEY_CAPITAL)); - KeyMap.push_back(SKeyMap(XKB_KEY_Shift_Lock, KEY_CAPITAL)); - KeyMap.push_back(SKeyMap(XKB_KEY_Meta_L, KEY_LWIN)); - KeyMap.push_back(SKeyMap(XKB_KEY_Meta_R, KEY_RWIN)); - KeyMap.push_back(SKeyMap(XKB_KEY_Alt_L, KEY_LMENU)); - KeyMap.push_back(SKeyMap(XKB_KEY_Alt_R, KEY_RMENU)); - KeyMap.push_back(SKeyMap(XKB_KEY_ISO_Level3_Shift, KEY_RMENU)); - KeyMap.push_back(SKeyMap(XKB_KEY_Menu, KEY_MENU)); - KeyMap.push_back(SKeyMap(XKB_KEY_space, KEY_SPACE)); -// KeyMap.push_back(SKeyMap(XKB_key_ex, 0)); //? -// KeyMap.push_back(SKeyMap(XK_quotedbl, 0)); //? -// KeyMap.push_back(SKeyMap(XK_section, 0)); //? - KeyMap.push_back(SKeyMap(XKB_KEY_numbersign, KEY_OEM_2)); -// KeyMap.push_back(SKeyMap(XK_dollar, 0)); //? -// KeyMap.push_back(SKeyMap(XK_percent, 0)); //? -// KeyMap.push_back(SKeyMap(XK_ampersand, 0)); //? - KeyMap.push_back(SKeyMap(XKB_KEY_apostrophe, KEY_OEM_7)); -// KeyMap.push_back(SKeyMap(XK_parenleft, 0)); //? -// KeyMap.push_back(SKeyMap(XK_parenright, 0)); //? -// KeyMap.push_back(SKeyMap(XK_asterisk, 0)); //? - KeyMap.push_back(SKeyMap(XKB_KEY_plus, KEY_PLUS)); //? - KeyMap.push_back(SKeyMap(XKB_KEY_comma, KEY_COMMA)); //? - KeyMap.push_back(SKeyMap(XKB_KEY_minus, KEY_MINUS)); //? - KeyMap.push_back(SKeyMap(XKB_KEY_period, KEY_PERIOD)); //? - KeyMap.push_back(SKeyMap(XKB_KEY_slash, KEY_OEM_2)); //? - KeyMap.push_back(SKeyMap(XKB_KEY_0, KEY_KEY_0)); - KeyMap.push_back(SKeyMap(XKB_KEY_1, KEY_KEY_1)); - KeyMap.push_back(SKeyMap(XKB_KEY_2, KEY_KEY_2)); - KeyMap.push_back(SKeyMap(XKB_KEY_3, KEY_KEY_3)); - KeyMap.push_back(SKeyMap(XKB_KEY_4, KEY_KEY_4)); - KeyMap.push_back(SKeyMap(XKB_KEY_5, KEY_KEY_5)); - KeyMap.push_back(SKeyMap(XKB_KEY_6, KEY_KEY_6)); - KeyMap.push_back(SKeyMap(XKB_KEY_7, KEY_KEY_7)); - KeyMap.push_back(SKeyMap(XKB_KEY_8, KEY_KEY_8)); - KeyMap.push_back(SKeyMap(XKB_KEY_9, KEY_KEY_9)); -// KeyMap.push_back(SKeyMap(XK_colon, 0)); //? - KeyMap.push_back(SKeyMap(XKB_KEY_semicolon, KEY_OEM_1)); - KeyMap.push_back(SKeyMap(XKB_KEY_less, KEY_OEM_102)); - KeyMap.push_back(SKeyMap(XKB_KEY_equal, KEY_PLUS)); -// KeyMap.push_back(SKeyMap(XK_greater, 0)); //? -// KeyMap.push_back(SKeyMap(XK_question, 0)); //? - KeyMap.push_back(SKeyMap(XKB_KEY_at, KEY_KEY_2)); //? -// KeyMap.push_back(SKeyMap(XK_mu, 0)); //? -// KeyMap.push_back(SKeyMap(XK_EuroSign, 0)); //? - KeyMap.push_back(SKeyMap(XKB_KEY_A, KEY_KEY_A)); - KeyMap.push_back(SKeyMap(XKB_KEY_B, KEY_KEY_B)); - KeyMap.push_back(SKeyMap(XKB_KEY_C, KEY_KEY_C)); - KeyMap.push_back(SKeyMap(XKB_KEY_D, KEY_KEY_D)); - KeyMap.push_back(SKeyMap(XKB_KEY_E, KEY_KEY_E)); - KeyMap.push_back(SKeyMap(XKB_KEY_F, KEY_KEY_F)); - KeyMap.push_back(SKeyMap(XKB_KEY_G, KEY_KEY_G)); - KeyMap.push_back(SKeyMap(XKB_KEY_H, KEY_KEY_H)); - KeyMap.push_back(SKeyMap(XKB_KEY_I, KEY_KEY_I)); - KeyMap.push_back(SKeyMap(XKB_KEY_J, KEY_KEY_J)); - KeyMap.push_back(SKeyMap(XKB_KEY_K, KEY_KEY_K)); - KeyMap.push_back(SKeyMap(XKB_KEY_L, KEY_KEY_L)); - KeyMap.push_back(SKeyMap(XKB_KEY_M, KEY_KEY_M)); - KeyMap.push_back(SKeyMap(XKB_KEY_N, KEY_KEY_N)); - KeyMap.push_back(SKeyMap(XKB_KEY_O, KEY_KEY_O)); - KeyMap.push_back(SKeyMap(XKB_KEY_P, KEY_KEY_P)); - KeyMap.push_back(SKeyMap(XKB_KEY_Q, KEY_KEY_Q)); - KeyMap.push_back(SKeyMap(XKB_KEY_R, KEY_KEY_R)); - KeyMap.push_back(SKeyMap(XKB_KEY_S, KEY_KEY_S)); - KeyMap.push_back(SKeyMap(XKB_KEY_T, KEY_KEY_T)); - KeyMap.push_back(SKeyMap(XKB_KEY_U, KEY_KEY_U)); - KeyMap.push_back(SKeyMap(XKB_KEY_V, KEY_KEY_V)); - KeyMap.push_back(SKeyMap(XKB_KEY_W, KEY_KEY_W)); - KeyMap.push_back(SKeyMap(XKB_KEY_X, KEY_KEY_X)); - KeyMap.push_back(SKeyMap(XKB_KEY_Y, KEY_KEY_Y)); - KeyMap.push_back(SKeyMap(XKB_KEY_Z, KEY_KEY_Z)); - KeyMap.push_back(SKeyMap(XKB_KEY_bracketleft, KEY_OEM_4)); - KeyMap.push_back(SKeyMap(XKB_KEY_backslash, KEY_OEM_5)); - KeyMap.push_back(SKeyMap(XKB_KEY_bracketright, KEY_OEM_6)); - KeyMap.push_back(SKeyMap(XKB_KEY_asciicircum, KEY_OEM_5)); -// KeyMap.push_back(SKeyMap(XK_degree, 0)); //? - KeyMap.push_back(SKeyMap(XKB_KEY_underscore, KEY_MINUS)); //? - KeyMap.push_back(SKeyMap(XKB_KEY_grave, KEY_OEM_3)); - KeyMap.push_back(SKeyMap(XKB_KEY_acute, KEY_OEM_6)); - KeyMap.push_back(SKeyMap(XKB_KEY_a, KEY_KEY_A)); - KeyMap.push_back(SKeyMap(XKB_KEY_b, KEY_KEY_B)); - KeyMap.push_back(SKeyMap(XKB_KEY_c, KEY_KEY_C)); - KeyMap.push_back(SKeyMap(XKB_KEY_c, KEY_KEY_D)); - KeyMap.push_back(SKeyMap(XKB_KEY_e, KEY_KEY_E)); - KeyMap.push_back(SKeyMap(XKB_KEY_f, KEY_KEY_F)); - KeyMap.push_back(SKeyMap(XKB_KEY_g, KEY_KEY_G)); - KeyMap.push_back(SKeyMap(XKB_KEY_h, KEY_KEY_H)); - KeyMap.push_back(SKeyMap(XKB_KEY_i, KEY_KEY_I)); - KeyMap.push_back(SKeyMap(XKB_KEY_j, KEY_KEY_J)); - KeyMap.push_back(SKeyMap(XKB_KEY_k, KEY_KEY_K)); - KeyMap.push_back(SKeyMap(XKB_KEY_l, KEY_KEY_L)); - KeyMap.push_back(SKeyMap(XKB_KEY_m, KEY_KEY_M)); - KeyMap.push_back(SKeyMap(XKB_KEY_n, KEY_KEY_N)); - KeyMap.push_back(SKeyMap(XKB_KEY_o, KEY_KEY_O)); - KeyMap.push_back(SKeyMap(XKB_KEY_p, KEY_KEY_P)); - KeyMap.push_back(SKeyMap(XKB_KEY_q, KEY_KEY_Q)); - KeyMap.push_back(SKeyMap(XKB_KEY_r, KEY_KEY_R)); - KeyMap.push_back(SKeyMap(XKB_KEY_s, KEY_KEY_S)); - KeyMap.push_back(SKeyMap(XKB_KEY_t, KEY_KEY_T)); - KeyMap.push_back(SKeyMap(XKB_KEY_u, KEY_KEY_U)); - KeyMap.push_back(SKeyMap(XKB_KEY_v, KEY_KEY_V)); - KeyMap.push_back(SKeyMap(XKB_KEY_w, KEY_KEY_W)); - KeyMap.push_back(SKeyMap(XKB_KEY_x, KEY_KEY_X)); - KeyMap.push_back(SKeyMap(XKB_KEY_y, KEY_KEY_Y)); - KeyMap.push_back(SKeyMap(XKB_KEY_z, KEY_KEY_Z)); - KeyMap.push_back(SKeyMap(XKB_KEY_ssharp, KEY_OEM_4)); - KeyMap.push_back(SKeyMap(XKB_KEY_adiaeresis, KEY_OEM_7)); - KeyMap.push_back(SKeyMap(XKB_KEY_odiaeresis, KEY_OEM_3)); - KeyMap.push_back(SKeyMap(XKB_KEY_udiaeresis, KEY_OEM_1)); - KeyMap.push_back(SKeyMap(XKB_KEY_Super_L, KEY_LWIN)); - KeyMap.push_back(SKeyMap(XKB_KEY_Super_R, KEY_RWIN)); - - KeyMap.sort(); - - + m_key_map[XKB_KEY_NoSymbol] = KEY_UNKNOWN; + m_key_map[XKB_KEY_BackSpace] = KEY_BACK; + m_key_map[XKB_KEY_Tab] = KEY_TAB; + m_key_map[XKB_KEY_ISO_Left_Tab] = KEY_TAB; +// m_key_map[XK_Linefeed] = 0; // ??? + m_key_map[XKB_KEY_Clear] = KEY_CLEAR; + m_key_map[XKB_KEY_Return] = KEY_RETURN; + m_key_map[XKB_KEY_Pause] = KEY_PAUSE; + m_key_map[XKB_KEY_Scroll_Lock] = KEY_SCROLL; +// m_key_map[XK_Sys_Req] = 0; // ??? + m_key_map[XKB_KEY_Escape] = KEY_ESCAPE; + m_key_map[XKB_KEY_Insert] = KEY_INSERT; + m_key_map[XKB_KEY_Delete] = KEY_DELETE; + m_key_map[XKB_KEY_Home] = KEY_HOME; + m_key_map[XKB_KEY_Left] = KEY_LEFT; + m_key_map[XKB_KEY_Up] = KEY_UP; + m_key_map[XKB_KEY_Right] = KEY_RIGHT; + m_key_map[XKB_KEY_Down] = KEY_DOWN; + m_key_map[XKB_KEY_Prior] = KEY_PRIOR; + m_key_map[XKB_KEY_Page_Up] = KEY_PRIOR; + m_key_map[XKB_KEY_Next] = KEY_NEXT; + m_key_map[XKB_KEY_Page_Down] = KEY_NEXT; + m_key_map[XKB_KEY_End] = KEY_END; + m_key_map[XKB_KEY_Begin] = KEY_HOME; + m_key_map[XKB_KEY_Num_Lock] = KEY_NUMLOCK; + m_key_map[XKB_KEY_space] = KEY_SPACE; + m_key_map[XKB_KEY_KP_Tab] = KEY_TAB; + m_key_map[XKB_KEY_KP_Enter] = KEY_RETURN; + m_key_map[XKB_KEY_KP_F1] = KEY_F1; + m_key_map[XKB_KEY_KP_F2] = KEY_F2; + m_key_map[XKB_KEY_KP_F3] = KEY_F3; + m_key_map[XKB_KEY_KP_F4] = KEY_F4; + m_key_map[XKB_KEY_KP_Home] = KEY_HOME; + m_key_map[XKB_KEY_KP_Left] = KEY_LEFT; + m_key_map[XKB_KEY_KP_Up] = KEY_UP; + m_key_map[XKB_KEY_KP_Right] = KEY_RIGHT; + m_key_map[XKB_KEY_KP_Down] = KEY_DOWN; + m_key_map[XKB_KEY_Print] = KEY_PRINT; + m_key_map[XKB_KEY_KP_Prior] = KEY_PRIOR; + m_key_map[XKB_KEY_KP_Page_Up] = KEY_PRIOR; + m_key_map[XKB_KEY_KP_Next] = KEY_NEXT; + m_key_map[XKB_KEY_KP_Page_Down] = KEY_NEXT; + m_key_map[XKB_KEY_KP_End] = KEY_END; + m_key_map[XKB_KEY_KP_Begin] = KEY_HOME; + m_key_map[XKB_KEY_KP_Insert] = KEY_INSERT; + m_key_map[XKB_KEY_KP_Delete] = KEY_DELETE; +// m_key_map[XK_KP_Equal] = 0; // ??? + m_key_map[XKB_KEY_KP_Multiply] = KEY_MULTIPLY; + m_key_map[XKB_KEY_KP_Add] = KEY_ADD; + m_key_map[XKB_KEY_KP_Separator] = KEY_SEPARATOR; + m_key_map[XKB_KEY_KP_Subtract] = KEY_SUBTRACT; + m_key_map[XKB_KEY_KP_Decimal] = KEY_DECIMAL; + m_key_map[XKB_KEY_KP_Divide] = KEY_DIVIDE; + m_key_map[XKB_KEY_KP_0] = KEY_NUMPAD0; + m_key_map[XKB_KEY_KP_1] = KEY_NUMPAD1; + m_key_map[XKB_KEY_KP_2] = KEY_NUMPAD2; + m_key_map[XKB_KEY_KP_3] = KEY_NUMPAD3; + m_key_map[XKB_KEY_KP_4] = KEY_NUMPAD4; + m_key_map[XKB_KEY_KP_5] = KEY_NUMPAD5; + m_key_map[XKB_KEY_KP_6] = KEY_NUMPAD6; + m_key_map[XKB_KEY_KP_7] = KEY_NUMPAD7; + m_key_map[XKB_KEY_KP_8] = KEY_NUMPAD8; + m_key_map[XKB_KEY_KP_9] = KEY_NUMPAD9; + m_key_map[XKB_KEY_F1] = KEY_F1; + m_key_map[XKB_KEY_F2] = KEY_F2; + m_key_map[XKB_KEY_F3] = KEY_F3; + m_key_map[XKB_KEY_F4] = KEY_F4; + m_key_map[XKB_KEY_F5] = KEY_F5; + m_key_map[XKB_KEY_F6] = KEY_F6; + m_key_map[XKB_KEY_F7] = KEY_F7; + m_key_map[XKB_KEY_F8] = KEY_F8; + m_key_map[XKB_KEY_F9] = KEY_F9; + m_key_map[XKB_KEY_F10] = KEY_F10; + m_key_map[XKB_KEY_F11] = KEY_F11; + m_key_map[XKB_KEY_F12] = KEY_F12; + m_key_map[XKB_KEY_Shift_L] = KEY_LSHIFT; + m_key_map[XKB_KEY_Shift_R] = KEY_RSHIFT; + m_key_map[XKB_KEY_Control_L] = KEY_LCONTROL; + m_key_map[XKB_KEY_Control_R] = KEY_RCONTROL; + m_key_map[XKB_KEY_Caps_Lock] = KEY_CAPITAL; + m_key_map[XKB_KEY_Shift_Lock] = KEY_CAPITAL; + m_key_map[XKB_KEY_Meta_L] = KEY_LWIN; + m_key_map[XKB_KEY_Meta_R] = KEY_RWIN; + m_key_map[XKB_KEY_Alt_L] = KEY_LMENU; + m_key_map[XKB_KEY_Alt_R] = KEY_RMENU; + m_key_map[XKB_KEY_ISO_Level3_Shift] = KEY_RMENU; + m_key_map[XKB_KEY_Menu] = KEY_MENU; + m_key_map[XKB_KEY_space] = KEY_SPACE; +// m_key_map[XKB_key_ex] = 0; //? +// m_key_map[XK_quotedbl] = 0; //? +// m_key_map[XK_section] = 0; //? + m_key_map[XKB_KEY_numbersign] = KEY_OEM_2; +// m_key_map[XK_dollar] = 0; //? +// m_key_map[XK_percent] = 0; //? +// m_key_map[XK_ampersand] = 0; //? + m_key_map[XKB_KEY_apostrophe] = KEY_OEM_7; +// m_key_map[XK_parenleft] = 0; //? +// m_key_map[XK_parenright] = 0; //? +// m_key_map[XK_asterisk] = 0; //? + m_key_map[XKB_KEY_plus] = KEY_PLUS; //? + m_key_map[XKB_KEY_comma] = KEY_COMMA; //? + m_key_map[XKB_KEY_minus] = KEY_MINUS; //? + m_key_map[XKB_KEY_period] = KEY_PERIOD; //? + m_key_map[XKB_KEY_slash] = KEY_OEM_2; //? + m_key_map[XKB_KEY_0] = KEY_KEY_0; + m_key_map[XKB_KEY_1] = KEY_KEY_1; + m_key_map[XKB_KEY_2] = KEY_KEY_2; + m_key_map[XKB_KEY_3] = KEY_KEY_3; + m_key_map[XKB_KEY_4] = KEY_KEY_4; + m_key_map[XKB_KEY_5] = KEY_KEY_5; + m_key_map[XKB_KEY_6] = KEY_KEY_6; + m_key_map[XKB_KEY_7] = KEY_KEY_7; + m_key_map[XKB_KEY_8] = KEY_KEY_8; + m_key_map[XKB_KEY_9] = KEY_KEY_9; +// m_key_map[XK_colon] = 0; //? + m_key_map[XKB_KEY_semicolon] = KEY_OEM_1; + m_key_map[XKB_KEY_less] = KEY_OEM_102; + m_key_map[XKB_KEY_equal] = KEY_PLUS; +// m_key_map[XK_greater] = 0; //? +// m_key_map[XK_question] = 0; //? + m_key_map[XKB_KEY_at] = KEY_KEY_2; //? +// m_key_map[XK_mu] = 0; //? +// m_key_map[XK_EuroSign] = 0; //? + m_key_map[XKB_KEY_A] = KEY_KEY_A; + m_key_map[XKB_KEY_B] = KEY_KEY_B; + m_key_map[XKB_KEY_C] = KEY_KEY_C; + m_key_map[XKB_KEY_D] = KEY_KEY_D; + m_key_map[XKB_KEY_E] = KEY_KEY_E; + m_key_map[XKB_KEY_F] = KEY_KEY_F; + m_key_map[XKB_KEY_G] = KEY_KEY_G; + m_key_map[XKB_KEY_H] = KEY_KEY_H; + m_key_map[XKB_KEY_I] = KEY_KEY_I; + m_key_map[XKB_KEY_J] = KEY_KEY_J; + m_key_map[XKB_KEY_K] = KEY_KEY_K; + m_key_map[XKB_KEY_L] = KEY_KEY_L; + m_key_map[XKB_KEY_M] = KEY_KEY_M; + m_key_map[XKB_KEY_N] = KEY_KEY_N; + m_key_map[XKB_KEY_O] = KEY_KEY_O; + m_key_map[XKB_KEY_P] = KEY_KEY_P; + m_key_map[XKB_KEY_Q] = KEY_KEY_Q; + m_key_map[XKB_KEY_R] = KEY_KEY_R; + m_key_map[XKB_KEY_S] = KEY_KEY_S; + m_key_map[XKB_KEY_T] = KEY_KEY_T; + m_key_map[XKB_KEY_U] = KEY_KEY_U; + m_key_map[XKB_KEY_V] = KEY_KEY_V; + m_key_map[XKB_KEY_W] = KEY_KEY_W; + m_key_map[XKB_KEY_X] = KEY_KEY_X; + m_key_map[XKB_KEY_Y] = KEY_KEY_Y; + m_key_map[XKB_KEY_Z] = KEY_KEY_Z; + m_key_map[XKB_KEY_bracketleft] = KEY_OEM_4; + m_key_map[XKB_KEY_backslash] = KEY_OEM_5; + m_key_map[XKB_KEY_bracketright] = KEY_OEM_6; + m_key_map[XKB_KEY_asciicircum] = KEY_OEM_5; +// m_key_map[XK_degree] = 0; //? + m_key_map[XKB_KEY_underscore] = KEY_MINUS; //? + m_key_map[XKB_KEY_grave] = KEY_OEM_3; + m_key_map[XKB_KEY_acute] = KEY_OEM_6; + m_key_map[XKB_KEY_a] = KEY_KEY_A; + m_key_map[XKB_KEY_b] = KEY_KEY_B; + m_key_map[XKB_KEY_c] = KEY_KEY_C; + m_key_map[XKB_KEY_d] = KEY_KEY_D; + m_key_map[XKB_KEY_e] = KEY_KEY_E; + m_key_map[XKB_KEY_f] = KEY_KEY_F; + m_key_map[XKB_KEY_g] = KEY_KEY_G; + m_key_map[XKB_KEY_h] = KEY_KEY_H; + m_key_map[XKB_KEY_i] = KEY_KEY_I; + m_key_map[XKB_KEY_j] = KEY_KEY_J; + m_key_map[XKB_KEY_k] = KEY_KEY_K; + m_key_map[XKB_KEY_l] = KEY_KEY_L; + m_key_map[XKB_KEY_m] = KEY_KEY_M; + m_key_map[XKB_KEY_n] = KEY_KEY_N; + m_key_map[XKB_KEY_o] = KEY_KEY_O; + m_key_map[XKB_KEY_p] = KEY_KEY_P; + m_key_map[XKB_KEY_q] = KEY_KEY_Q; + m_key_map[XKB_KEY_r] = KEY_KEY_R; + m_key_map[XKB_KEY_s] = KEY_KEY_S; + m_key_map[XKB_KEY_t] = KEY_KEY_T; + m_key_map[XKB_KEY_u] = KEY_KEY_U; + m_key_map[XKB_KEY_v] = KEY_KEY_V; + m_key_map[XKB_KEY_w] = KEY_KEY_W; + m_key_map[XKB_KEY_x] = KEY_KEY_X; + m_key_map[XKB_KEY_y] = KEY_KEY_Y; + m_key_map[XKB_KEY_z] = KEY_KEY_Z; + m_key_map[XKB_KEY_ssharp] = KEY_OEM_4; + m_key_map[XKB_KEY_adiaeresis] = KEY_OEM_7; + m_key_map[XKB_KEY_odiaeresis] = KEY_OEM_3; + m_key_map[XKB_KEY_udiaeresis] = KEY_OEM_1; + m_key_map[XKB_KEY_Super_L] = KEY_LWIN; + m_key_map[XKB_KEY_Super_R] = KEY_RWIN; } -bool CIrrDeviceWayland::activateJoysticks(core::array & joystickInfo) +// The joystick code is mostly copied from CIrrDeviceLinux. + +bool CIrrDeviceWayland::activateJoysticks(core::array& joystickInfo) { #if defined (_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) - joystickInfo.clear(); + joystickInfo.clear(); - u32 joystick; - for (joystick = 0; joystick < 32; ++joystick) - { - // The joystick device could be here... - core::stringc devName = "/dev/js"; - devName += joystick; + u32 joystick; + for (joystick = 0; joystick < 32; ++joystick) + { + // The joystick device could be here... + core::stringc devName = "/dev/js"; + devName += joystick; - SJoystickInfo returnInfo; - JoystickInfo info; + JoystickInfo info; + info.fd = open(devName.c_str(), O_RDONLY); + if (info.fd == -1) + { + // ...but Ubuntu and possibly other distros + // create the devices in /dev/input + devName = "/dev/input/js"; + devName += joystick; + info.fd = open(devName.c_str(), O_RDONLY); + } - info.fd = open(devName.c_str(), O_RDONLY); - if (-1 == info.fd) - { - // ...but Ubuntu and possibly other distros - // create the devices in /dev/input - devName = "/dev/input/js"; - devName += joystick; - info.fd = open(devName.c_str(), O_RDONLY); - if (-1 == info.fd) - { - // and BSD here - devName = "/dev/joy"; - devName += joystick; - info.fd = open(devName.c_str(), O_RDONLY); - } - } + if (info.fd == -1) + { + // and BSD here + devName = "/dev/joy"; + devName += joystick; + info.fd = open(devName.c_str(), O_RDONLY); + } - if (-1 == info.fd) - continue; + if (info.fd == -1) + continue; #ifdef __FreeBSD__ - info.axes=2; - info.buttons=2; + info.axes=2; + info.buttons=2; #else - ioctl( info.fd, JSIOCGAXES, &(info.axes) ); - ioctl( info.fd, JSIOCGBUTTONS, &(info.buttons) ); - fcntl( info.fd, F_SETFL, O_NONBLOCK ); + ioctl( info.fd, JSIOCGAXES, &(info.axes) ); + ioctl( info.fd, JSIOCGBUTTONS, &(info.buttons) ); + fcntl( info.fd, F_SETFL, O_NONBLOCK ); #endif - (void)memset(&info.persistentData, 0, sizeof(info.persistentData)); - info.persistentData.EventType = irr::EET_JOYSTICK_INPUT_EVENT; - info.persistentData.JoystickEvent.Joystick = ActiveJoysticks.size(); + (void)memset(&info.persistentData, 0, sizeof(info.persistentData)); + info.persistentData.EventType = irr::EET_JOYSTICK_INPUT_EVENT; + info.persistentData.JoystickEvent.Joystick = m_active_joysticks.size(); - // There's no obvious way to determine which (if any) axes represent a POV - // hat, so we'll just set it to "not used" and forget about it. - info.persistentData.JoystickEvent.POV = 65535; + // There's no obvious way to determine which (if any) axes represent a POV + // hat, so we'll just set it to "not used" and forget about it. + info.persistentData.JoystickEvent.POV = 65535; - ActiveJoysticks.push_back(info); + m_active_joysticks.push_back(info); - returnInfo.HasGenericName = false; - returnInfo.Joystick = joystick; - returnInfo.PovHat = SJoystickInfo::POV_HAT_UNKNOWN; - returnInfo.Axes = info.axes; - returnInfo.Buttons = info.buttons; + SJoystickInfo returnInfo; + returnInfo.HasGenericName = false; + returnInfo.Joystick = joystick; + returnInfo.PovHat = SJoystickInfo::POV_HAT_UNKNOWN; + returnInfo.Axes = info.axes; + returnInfo.Buttons = info.buttons; #ifndef __FreeBSD__ - char name[80]; - ioctl( info.fd, JSIOCGNAME(80), name); - returnInfo.Name = name; + char name[80]; + ioctl( info.fd, JSIOCGNAME(80), name); + returnInfo.Name = name; #endif - joystickInfo.push_back(returnInfo); - } + joystickInfo.push_back(returnInfo); + } - for (joystick = 0; joystick < joystickInfo.size(); ++joystick) - { - char logString[256]; - (void)sprintf(logString, "Found joystick %u, %u axes, %u buttons '%s'", - joystick, joystickInfo[joystick].Axes, - joystickInfo[joystick].Buttons, joystickInfo[joystick].Name.c_str()); - os::Printer::log(logString, ELL_INFORMATION); - } + for (joystick = 0; joystick < joystickInfo.size(); ++joystick) + { + char logString[256]; + (void)sprintf(logString, "Found joystick %u, %u axes, %u buttons '%s'", + joystick, joystickInfo[joystick].Axes, + joystickInfo[joystick].Buttons, joystickInfo[joystick].Name.c_str()); + os::Printer::log(logString, ELL_INFORMATION); + } - return true; + return true; #else - return false; + return false; #endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ } @@ -1297,91 +1287,73 @@ bool CIrrDeviceWayland::activateJoysticks(core::array & joystickI void CIrrDeviceWayland::pollJoysticks() { #if defined (_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) - if (0 == ActiveJoysticks.size()) - return; + if (m_active_joysticks.size() == 0) + return; - for (u32 j= 0; j< ActiveJoysticks.size(); ++j) - { - JoystickInfo & info = ActiveJoysticks[j]; + for (unsigned int i = 0; i < m_active_joysticks.size(); i++) + { + JoystickInfo& info = m_active_joysticks[i]; #ifdef __FreeBSD__ - struct joystick js; - if (read(info.fd, &js, sizeof(js)) == sizeof(js)) - { - info.persistentData.JoystickEvent.ButtonStates = js.b1 | (js.b2 << 1); /* should be a two-bit field */ - info.persistentData.JoystickEvent.Axis[0] = js.x; /* X axis */ - info.persistentData.JoystickEvent.Axis[1] = js.y; /* Y axis */ - } + struct joystick js; + if (read(info.fd, &js, sizeof(js)) == sizeof(js)) + { + /* should be a two-bit field*/ + info.persistentData.JoystickEvent.ButtonStates = js.b1 | (js.b2 << 1); + info.persistentData.JoystickEvent.Axis[0] = js.x; /* X axis*/ + info.persistentData.JoystickEvent.Axis[1] = js.y; /* Y axis*/ + } #else - struct js_event event; - while (sizeof(event) == read(info.fd, &event, sizeof(event))) - { - switch(event.type & ~JS_EVENT_INIT) - { - case JS_EVENT_BUTTON: - if (event.value) - info.persistentData.JoystickEvent.ButtonStates |= (1 << event.number); - else - info.persistentData.JoystickEvent.ButtonStates &= ~(1 << event.number); - break; - - case JS_EVENT_AXIS: - if (event.number < SEvent::SJoystickEvent::NUMBER_OF_AXES) - info.persistentData.JoystickEvent.Axis[event.number] = event.value; - break; - - default: - break; - } - } + struct js_event event; + while (sizeof(event) == read(info.fd, &event, sizeof(event))) + { + switch(event.type & ~JS_EVENT_INIT) + { + case JS_EVENT_BUTTON: + { + if (event.value) + { + info.persistentData.JoystickEvent.ButtonStates |= (1 << event.number); + } + else + { + info.persistentData.JoystickEvent.ButtonStates &= ~(1 << event.number); + } + break; + } + case JS_EVENT_AXIS: + { + if (event.number < SEvent::SJoystickEvent::NUMBER_OF_AXES) + { + info.persistentData.JoystickEvent.Axis[event.number] = event.value; + } + break; + } + default: + break; + } + } #endif - // Send an irrlicht joystick event once per ::run() even if no new data were received. - (void)postEventFromUser(info.persistentData); - } + // Send an irrlicht joystick event once per ::run() even if no new data were received. + (void)postEventFromUser(info.persistentData); + } #endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ } - -//! Set the current Gamma Value for the Display -bool CIrrDeviceWayland::setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ) +void CIrrDeviceWayland::closeJoysticks() { - return false; +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + for (unsigned int i = 0; i < m_active_joysticks.size(); i++) + { + if (m_active_joysticks[i].fd < 0) + continue; + + close(m_active_joysticks[i].fd); + } +#endif } - -//! Get the current Gamma Value for the Display -bool CIrrDeviceWayland::getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ) -{ - brightness = 0.f; - contrast = 0.f; - return false; -} - - -//! gets text from the clipboard -//! \return Returns 0 if no string is in there. -const c8* CIrrDeviceWayland::getTextFromClipboard() const -{ - printf("get text from clipboard: %s\n", Clipboard.c_str()); - return Clipboard.c_str(); - -} - -//! copies text to the clipboard -void CIrrDeviceWayland::copyToClipboard(const c8* text) const -{ - printf("copy to clipboard: %s\n", text); - Clipboard = text; -} - - -//! Remove all messages pending in the system message loop -void CIrrDeviceWayland::clearSystemMessages() -{ -} - - } // end namespace #endif diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.h b/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.h index 3806e3975..97b120a87 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.h +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.h @@ -1,3 +1,21 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2016-2017 Dawid Gan +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + #ifndef CIRRDEVICEWAYLAND_H #define CIRRDEVICEWAYLAND_H @@ -6,340 +24,308 @@ #ifdef _IRR_COMPILE_WITH_WAYLAND #include "CIrrDeviceStub.h" -#include "IrrlichtDevice.h" #include "IImagePresenter.h" #include "ICursorControl.h" -#include "os.h" #include -#include #include +#include #include #include -#include - +#include #include -#define KeySym s32 class ContextManagerEGL; -// Note : only supporting shell interface - namespace irr { + class CIrrDeviceWayland : public CIrrDeviceStub, + public video::IImagePresenter + { + public: + friend class WaylandCallbacks; - class CIrrDeviceWayland : public CIrrDeviceStub, public video::IImagePresenter - { - public: + //! constructor + CIrrDeviceWayland(const SIrrlichtCreationParameters& param); - //! constructor - CIrrDeviceWayland(const SIrrlichtCreationParameters& param); + //! destructor + virtual ~CIrrDeviceWayland(); - //! destructor - virtual ~CIrrDeviceWayland(); + //! runs the device. Returns false if device wants to be deleted + virtual bool run(); - //! runs the device. Returns false if device wants to be deleted - virtual bool run(); + //! Cause the device to temporarily pause execution and let other + //! processes to run. This should bring down processor usage without + //! major performance loss for Irrlicht + virtual void yield(); - //! Cause the device to temporarily pause execution and let other processes to run - // This should bring down processor usage without major performance loss for Irrlicht - virtual void yield(); + //! Pause execution and let other processes to run for a specified + //! amount of time. + virtual void sleep(u32 timeMs, bool pauseTimer); - //! Pause execution and let other processes to run for a specified amount of time. - virtual void sleep(u32 timeMs, bool pauseTimer); + //! sets the caption of the window + virtual void setWindowCaption(const wchar_t* text); - //! sets the caption of the window - virtual void setWindowCaption(const wchar_t* text); + //! returns if window is active. if not, nothing need to be drawn + virtual bool isWindowActive() const; - //! returns if window is active. if not, nothing need to be drawn - virtual bool isWindowActive() const; + //! returns if window has focus. + virtual bool isWindowFocused() const; - //! returns if window has focus. - virtual bool isWindowFocused() const; + //! returns if window is minimized. + virtual bool isWindowMinimized() const; - //! returns if window is minimized. - virtual bool isWindowMinimized() const; + //! returns color format of the window. + virtual video::ECOLOR_FORMAT getColorFormat() const; - //! returns color format of the window. - virtual video::ECOLOR_FORMAT getColorFormat() const; + //! presents a surface in the client area + virtual bool present(video::IImage* surface, void* windowId=0, + core::rect* src=0); - //! presents a surface in the client area - virtual bool present(video::IImage* surface, void* windowId=0, core::rect* src=0 ); + //! notifies the device that it should close itself + virtual void closeDevice(); - //! notifies the device that it should close itself - virtual void closeDevice(); + //! \return Returns a pointer to a list with all video modes + //! supported by the gfx adapter. + video::IVideoModeList* getVideoModeList(); - //! \return Returns a pointer to a list with all video modes - //! supported by the gfx adapter. - video::IVideoModeList* getVideoModeList(); + //! Sets if the window should be resizable in windowed mode. + virtual void setResizable(bool resize=false); - //! Sets if the window should be resizable in windowed mode. - virtual void setResizable(bool resize=false); + //! Minimizes the window. + virtual void minimizeWindow(); - //! Minimizes the window. - virtual void minimizeWindow(); + //! Maximizes the window. + virtual void maximizeWindow(); - //! Maximizes the window. - virtual void maximizeWindow(); + //! Restores the window size. + virtual void restoreWindow(); - //! Restores the window size. - virtual void restoreWindow(); + //! Activate any joysticks, and generate events for them. + virtual bool activateJoysticks(core::array& joystickInfo); - //! Activate any joysticks, and generate events for them. - virtual bool activateJoysticks(core::array & joystickInfo); + //! Set the current Gamma Value for the Display + virtual bool setGammaRamp(f32 red, f32 green, f32 blue, + f32 brightness, f32 contrast); - //! Set the current Gamma Value for the Display - virtual bool setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ); + //! Get the current Gamma Value for the Display + virtual bool getGammaRamp(f32 &red, f32 &green, f32 &blue, + f32 &brightness, f32 &contrast); - //! Get the current Gamma Value for the Display - virtual bool getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ); + //! gets text from the clipboard + //! \return Returns 0 if no string is in there. + virtual const c8* getTextFromClipboard() const; - //! gets text from the clipboard - //! \return Returns 0 if no string is in there. - virtual const c8* getTextFromClipboard() const; + //! copies text to the clipboard + virtual void copyToClipboard(const c8* text) const; - //! copies text to the clipboard - //! This sets the clipboard selection and _not_ the primary selection which you have on X on the middle mouse button. - virtual void copyToClipboard(const c8* text) const; + //! Remove all messages pending in the system message loop + virtual void clearSystemMessages(); - //! Remove all messages pending in the system message loop - virtual void clearSystemMessages(); + //! Get the device type + virtual E_DEVICE_TYPE getType() const + { + return EIDT_WAYLAND; + } - //! Get the device type - virtual E_DEVICE_TYPE getType() const - { - return EIDT_WAYLAND; - } + static bool isWaylandDeviceWorking(); - private: + ContextManagerEGL* getEGLContext() {return m_egl_context;} + void swapBuffers(); + void updateCursor(); + unsigned int getWidth() {return m_width;} + unsigned int getHeight() {return m_height;} - //! create the driver - void createDriver(); + private: - void initEGL(); + #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + struct JoystickInfo + { + int fd; + int axes; + int buttons; + SEvent persistentData; - bool createWindow(); + JoystickInfo() : fd(-1), axes(0), buttons(0) { } + }; - void createKeyMap(); + core::array m_active_joysticks; + #endif - void pollJoysticks(); + wl_compositor* m_compositor; + wl_cursor* m_cursor; + wl_cursor_theme* m_cursor_theme; + wl_display* m_display; + wl_egl_window* m_egl_window; + wl_keyboard* m_keyboard; + wl_output* m_output; + wl_pointer* m_pointer; + wl_registry* m_registry; + wl_seat* m_seat; + wl_shell* m_shell; + wl_shell_surface* m_shell_surface; + wl_shm* m_shm; + wl_surface* m_cursor_surface; + wl_surface* m_surface; + uint32_t m_enter_serial; - //! Implementation of the linux cursor control - class CCursorControl : public gui::ICursorControl - { - public: + xkb_context* m_xkb_context; + xkb_compose_table* m_xkb_compose_table; + xkb_compose_state* m_xkb_compose_state; + xkb_keymap* m_xkb_keymap; + xkb_state* m_xkb_state; + xkb_mod_mask_t m_xkb_control_mask; + xkb_mod_mask_t m_xkb_alt_mask; + xkb_mod_mask_t m_xkb_shift_mask; + uint32_t m_xkb_modifiers; - CCursorControl(CIrrDeviceWayland* dev, bool null); + uint32_t m_mouse_button_states; + unsigned int m_width; + unsigned int m_height; - ~CCursorControl(); + bool m_window_has_focus; + bool m_window_minimized; + mutable core::stringc m_clipboard; + std::map m_key_map; + std::vector m_events; + std::vector m_modes; + ContextManagerEGL* m_egl_context; - //! Changes the visible state of the mouse cursor. - virtual void setVisible(bool visible) - { - if (visible==IsVisible) - return; - - IsVisible = visible; - Device->updateCursor(); - } + void createDriver(); + void createKeyMap(); + bool createWindow(); + bool initEGL(); + void signalEvent(const SEvent&); + void pollJoysticks(); + void closeJoysticks(); + }; - //! Returns if the cursor is currently visible. - virtual bool isVisible() const - { - return IsVisible; - } + //! Implementation of the linux cursor control + class CCursorControl : public gui::ICursorControl + { + public: + CCursorControl(CIrrDeviceWayland* device) : m_device(device), + m_is_visible(true), m_use_reference_rect(false) {}; - //! Sets the new position of the cursor. - virtual void setPosition(const core::position2d &pos) - { - setPosition(pos.X, pos.Y); - } + ~CCursorControl() {}; - //! Sets the new position of the cursor. - virtual void setPosition(f32 x, f32 y) - { - setPosition((s32)(x*Device->Width), (s32)(y*Device->Height)); - } + //! Changes the visible state of the mouse cursor. + virtual void setVisible(bool visible) + { + if (visible == m_is_visible) + return; - //! Sets the new position of the cursor. - virtual void setPosition(const core::position2d &pos) - { - setPosition(pos.X, pos.Y); - } + m_is_visible = visible; + m_device->updateCursor(); + } - //! Sets the new position of the cursor. - virtual void setPosition(s32 x, s32 y) - { - //TODO - CursorPos.X = x; - CursorPos.Y = y; - } + //! Returns if the cursor is currently visible. + virtual bool isVisible() const + { + return m_is_visible; + } - //! Returns the current position of the mouse cursor. - virtual const core::position2d& getPosition() - { - return CursorPos; - } - - virtual core::position2d getRelativePosition() - { - if (!UseReferenceRect) - { - return core::position2d(CursorPos.X / (f32)Device->Width, - CursorPos.Y / (f32)Device->Height); - } + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } - return core::position2d(CursorPos.X / (f32)ReferenceRect.getWidth(), - CursorPos.Y / (f32)ReferenceRect.getHeight()); - } + //! Sets the new position of the cursor. + virtual void setPosition(f32 x, f32 y) + { + setPosition((s32)(x * m_device->getWidth()), + (s32)(y * m_device->getHeight())); + } - virtual void setReferenceRect(core::rect* rect=0) - { - if (rect) - { - ReferenceRect = *rect; - UseReferenceRect = true; + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } - // prevent division through zero and uneven sizes + //! Sets the new position of the cursor. + virtual void setPosition(s32 x, s32 y) + { + m_cursor_pos.X = x; + m_cursor_pos.Y = y; + } - if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2) - ReferenceRect.LowerRightCorner.Y += 1; + //! Returns the current position of the mouse cursor. + virtual const core::position2d& getPosition() + { + return m_cursor_pos; + } - if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2) - ReferenceRect.LowerRightCorner.X += 1; - } - else - UseReferenceRect = false; - } + virtual core::position2d getRelativePosition() + { + if (!m_use_reference_rect) + { + return core::position2d( + m_cursor_pos.X / (f32)m_device->getWidth(), + m_cursor_pos.Y / (f32)m_device->getHeight()); + } - //! Sets the active cursor icon - virtual void setActiveIcon(gui::ECURSOR_ICON iconId) {}; + return core::position2d( + m_cursor_pos.X / (f32)m_reference_rect.getWidth(), + m_cursor_pos.Y / (f32)m_reference_rect.getHeight()); + } - //! Gets the currently active icon - virtual gui::ECURSOR_ICON getActiveIcon() const - { - return ActiveIcon; - } + virtual void setReferenceRect(core::rect* rect=0) + { + m_use_reference_rect = false; - //! Add a custom sprite as cursor icon. - virtual gui::ECURSOR_ICON addIcon(const gui::SCursorSprite& icon) - { - return gui::ECI_NORMAL; - } + if (rect) + { + m_reference_rect = *rect; + m_use_reference_rect = true; - //! replace the given cursor icon. - virtual void changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon) {} + // prevent division through zero and uneven sizes + if (m_reference_rect.getHeight() == 0 || + m_reference_rect.getHeight() % 2) + m_reference_rect.LowerRightCorner.Y += 1; - //! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work. - virtual core::dimension2di getSupportedIconSize() const - { - return core::dimension2di(0, 0); - } - private: + if (m_reference_rect.getWidth() == 0 || + m_reference_rect.getWidth() % 2) + m_reference_rect.LowerRightCorner.X += 1; + } + } - CIrrDeviceWayland* Device; - core::position2d CursorPos; - core::rect ReferenceRect; - bool IsVisible; - bool Null; - bool UseReferenceRect; - gui::ECURSOR_ICON ActiveIcon; - u32 ActiveIconStartTime; - }; + //! Sets the active cursor icon + virtual void setActiveIcon(gui::ECURSOR_ICON iconId) {}; - friend class CCursorControl; + //! Gets the currently active icon + virtual gui::ECURSOR_ICON getActiveIcon() const + { + return gui::ECI_NORMAL; + } - friend class COpenGLDriver; + //! Add a custom sprite as cursor icon. + virtual gui::ECURSOR_ICON addIcon(const gui::SCursorSprite& icon) + { + return gui::ECI_NORMAL; + } - friend class WaylandCallbacks; - std::vector events; - std::vector Modes; - core::dimension2du CurrentModes; + //! replace the given cursor icon. + virtual void changeIcon(gui::ECURSOR_ICON iconId, + const gui::SCursorSprite& icon) {} - ContextManagerEGL* EglContext; - - public: - static bool isWaylandDeviceWorking(); - void signalEvent(const SEvent&); - void addMode(const core::dimension2du &mode) { Modes.push_back(mode); } - void setCurrentMode(const core::dimension2du &mode) { CurrentModes = mode; } + /** Return a system-specific size which is supported for cursors. + Larger icons will fail, smaller icons might work. */ + virtual core::dimension2di getSupportedIconSize() const + { + return core::dimension2di(0, 0); + } - wl_display *display; - wl_registry *registry; - wl_compositor *compositor; - wl_seat *seat; - wl_pointer *pointer; - wl_keyboard *keyboard; - wl_output *output; - - wl_shm* shm; - wl_cursor_theme* cursor_theme; - wl_cursor* default_cursor; - wl_surface* cursor_surface; - - xkb_context *xkbctx; - xkb_keymap *keymap; - xkb_state *state; - xkb_mod_mask_t control_mask; - xkb_mod_mask_t alt_mask; - xkb_mod_mask_t shift_mask; - uint32_t modifiers; - struct xkb_compose_table *compose_table; - struct xkb_compose_state *compose_state; - - wl_shell *shell; - wl_surface *surface; - wl_shell_surface *shell_surface; - wl_egl_window *egl_window; - - u32 ButtonStates; - uint32_t enter_serial; - - ContextManagerEGL* getEGLContext() {return EglContext;} - void swapBuffers(); - void updateCursor(); - - private: - mutable core::stringc Clipboard; - u32 Width, Height; - bool WindowHasFocus; - bool WindowMinimized; -public: - struct SKeyMap - { - SKeyMap() {} - SKeyMap(s32 x11, s32 win32) - : X11Key(x11), Win32Key(win32) - { - } - - KeySym X11Key; - s32 Win32Key; - - bool operator<(const SKeyMap& o) const - { - return X11Key KeyMap; -private: -#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) - struct JoystickInfo - { - int fd; - int axes; - int buttons; - - SEvent persistentData; - - JoystickInfo() : fd(-1), axes(0), buttons(0) { } - }; - core::array ActiveJoysticks; -#endif - }; + private: + CIrrDeviceWayland* m_device; + core::position2d m_cursor_pos; + core::rect m_reference_rect; + bool m_is_visible; + bool m_use_reference_rect; + }; } // end namespace irr