From ae66951f6abda4bc586843b2456e97e7b803b13e Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Mon, 16 Jan 2017 22:16:26 +0100 Subject: [PATCH] [DEV] continue integration of wayland --- gale/context/wayland/Context.cpp | 561 ++++++++++++++----------------- 1 file changed, 260 insertions(+), 301 deletions(-) diff --git a/gale/context/wayland/Context.cpp b/gale/context/wayland/Context.cpp index 046c045..842e0b1 100644 --- a/gale/context/wayland/Context.cpp +++ b/gale/context/wayland/Context.cpp @@ -31,6 +31,7 @@ extern "C" { #include + //https://people.freedesktop.org/~whot/wayland-doxygen/wayland/Client/ #include #include #include @@ -56,47 +57,6 @@ bool hasDisplay = false; #define WAYLAND_CRITICAL GALE_VERBOSE #endif - -bool g_runningSignal = true; - -static void -signal_int(int signum) -{ - g_runningSignal = false; -} - - -struct window; -struct seat; - -struct display { - struct wl_display *display; - struct wl_registry *registry; - struct wl_compositor *compositor; - struct wl_shell *shell; - struct wl_seat *seat; - struct wl_pointer *pointer; - struct wl_keyboard *keyboard; - struct wl_shm *shm; - struct wl_cursor_theme *cursor_theme; - struct wl_cursor *default_cursor; - struct wl_surface *cursor_surface; - struct { - EGLDisplay dpy; - EGLContext ctx; - EGLConfig conf; - } egl; -}; - -struct window { - struct wl_egl_window *native; - struct wl_surface *surface; - struct wl_shell_surface *shell_surface; - EGLSurface egl_surface; - struct wl_callback *callback; - int fullscreen, configured, opaque; -}; - // *********************************************************************** // ** Define all calbac "C" needed to wrap Wayland in C++ // *********************************************************************** @@ -151,7 +111,9 @@ static const struct wl_keyboard_listener keyboard_listener = { keyboard_handle_modifiers, }; - +/** + * @brief Wayland interface context to load specific context wrapper... + */ class WAYLANDInterface : public gale::Context { private: gale::key::Special m_guiKeyBoardMode; @@ -159,50 +121,78 @@ class WAYLANDInterface : public gale::Context { bool m_inputIsPressed[MAX_MANAGE_INPUT]; std::string m_uniqueWindowsName; bool m_run; - struct sigaction m_sigint; - struct display m_display; - struct window m_window; - bool m_fullscreen; + bool m_configured; bool m_opaque; + enum gale::context::cursor m_cursorCurrent; //!< curent cursor + vec2 m_cursorCurrentPosition; + // Wayland interface + struct wl_display* m_display; + struct wl_registry* m_registry; + struct wl_compositor* m_compositor; + struct wl_shell* m_shell; + struct wl_seat* m_seat; + struct wl_pointer* m_pointer; + struct wl_keyboard* m_keyboard; + struct wl_shm* m_shm; + struct wl_cursor_theme* m_cursorTheme; + struct wl_cursor* m_cursorDefault; + struct wl_surface* m_cursorSurface; + struct wl_egl_window *m_eglWindow; + struct wl_surface *m_surface; + struct wl_shell_surface *m_shellSurface; + struct wl_callback *m_callback; + // EGL interface: + EGLDisplay m_eglDisplay; + EGLContext m_eglContext; + EGLConfig m_eglConfig; + EGLSurface m_eglSurface; public: WAYLANDInterface(gale::Application* _application, int32_t _argc, const char* _argv[]) : gale::Context(_application, _argc, _argv), m_size(800,600), m_run(false), m_fullscreen(false), - m_opaque(false) { + m_configured(false), + m_opaque(false), + m_cursorCurrent(gale::context::cursor::leftArrow), + m_display(nullptr), + m_registry(nullptr), + m_compositor(nullptr), + m_shell(nullptr), + m_seat(nullptr), + m_pointer(nullptr), + m_keyboard(nullptr), + m_shm(nullptr), + m_cursorTheme(nullptr), + m_cursorDefault(nullptr), + m_cursorSurface(nullptr), + m_eglWindow(nullptr), + m_surface(nullptr), + m_shellSurface(nullptr), + m_callback(nullptr) { // in case ... - g_runningSignal = true; GALE_WARNING("WAYLAND: INIT [START]"); for (int32_t iii=0; iii Not used ..."); } @@ -371,24 +358,22 @@ class WAYLANDInterface : public gale::Context { /****************************************************************************************/ // screen capabilities void seatHandleCapabilities(struct wl_seat* _seat, enum wl_seat_capability _caps) { - if ((_caps & WL_SEAT_CAPABILITY_POINTER) && !m_display.pointer) { + if ((_caps & WL_SEAT_CAPABILITY_POINTER) && !m_pointer) { GALE_WARNING("Display has a pointer"); - m_display.pointer = wl_seat_get_pointer(_seat); - wl_pointer_add_listener(m_display.pointer, &pointer_listener, this); - //wl_pointer_add_listener(m_display.pointer, &pointer_listener, &m_display); - } else if (!(_caps & WL_SEAT_CAPABILITY_POINTER) && m_display.pointer) { + m_pointer = wl_seat_get_pointer(_seat); + wl_pointer_add_listener(m_pointer, &pointer_listener, this); + } else if (!(_caps & WL_SEAT_CAPABILITY_POINTER) && m_pointer) { GALE_WARNING("Display has No more pointer"); - wl_pointer_destroy(m_display.pointer); - m_display.pointer = nullptr; + wl_pointer_destroy(m_pointer); + m_pointer = nullptr; } - if ((_caps & WL_SEAT_CAPABILITY_KEYBOARD) && !m_display.keyboard) { + if ((_caps & WL_SEAT_CAPABILITY_KEYBOARD) && !m_keyboard) { GALE_WARNING("Display has a keyboard"); - m_display.keyboard = wl_seat_get_keyboard(_seat); - wl_keyboard_add_listener(m_display.keyboard, &keyboard_listener, this); - //wl_keyboard_add_listener(m_display.keyboard, &keyboard_listener, &m_display); - } else if (!(_caps & WL_SEAT_CAPABILITY_KEYBOARD) && m_display.keyboard) { - wl_keyboard_destroy(m_display.keyboard); - m_display.keyboard = nullptr; + m_keyboard = wl_seat_get_keyboard(_seat); + wl_keyboard_add_listener(m_keyboard, &keyboard_listener, this); + } else if (!(_caps & WL_SEAT_CAPABILITY_KEYBOARD) && m_keyboard) { + wl_keyboard_destroy(m_keyboard); + m_keyboard = nullptr; } if (_caps & WL_SEAT_CAPABILITY_TOUCH) { @@ -401,19 +386,20 @@ class WAYLANDInterface : public gale::Context { void pointerHandleEnter(struct wl_pointer* _pointer, uint32_t _serial, struct wl_surface* _surface, ivec2 _pos) { GALE_WARNING("Pointer Enter surface" << _surface << " at pos=" << _pos); + m_cursorCurrentPosition = vec2(_pos.x(), _pos.y()); struct wl_buffer *buffer; - struct wl_cursor *cursor = m_display.default_cursor; + struct wl_cursor *cursor = m_cursorDefault; struct wl_cursor_image *image; - if (m_window.fullscreen) + if (m_fullscreen == true) { wl_pointer_set_cursor(_pointer, _serial, nullptr, 0, 0); - else if (cursor) { - image = m_display.default_cursor->images[0]; + } else if (cursor) { + image = m_cursorDefault->images[0]; buffer = wl_cursor_image_get_buffer(image); - wl_pointer_set_cursor(_pointer, _serial, m_display.cursor_surface, image->hotspot_x, image->hotspot_y); - wl_surface_attach(m_display.cursor_surface, buffer, 0, 0); - wl_surface_damage(m_display.cursor_surface, 0, 0, image->width, image->height); - wl_surface_commit(m_display.cursor_surface); + wl_pointer_set_cursor(_pointer, _serial, m_cursorSurface, image->hotspot_x, image->hotspot_y); + wl_surface_attach(m_cursorSurface, buffer, 0, 0); + wl_surface_damage(m_cursorSurface, 0, 0, image->width, image->height); + wl_surface_commit(m_cursorSurface); } GALE_WARNING("Pointer enter [STOP]"); } @@ -422,53 +408,88 @@ class WAYLANDInterface : public gale::Context { } void pointerHandleMotion(struct wl_pointer* _pointer, uint32_t _time, ivec2 _pos) { GALE_WARNING("Pointer moved at " << _pos); - } - void pointerHandleButton(struct wl_pointer* _wl_pointer, uint32_t _serial, uint32_t _time, uint32_t _button, uint32_t _state) { - GALE_WARNING("Pointer button"); - #if 0 - if ( _button == BTN_LEFT - && _state == WL_POINTER_BUTTON_STATE_PRESSED) { - wl_shell_surface_move(m_window.shell_surface, m_display.seat, _serial); + m_cursorCurrentPosition = vec2(_pos.x(), _pos.y()); + bool findPointer = false; + for (int32_t iii=0; iii no need to redraw ... + if (m_configured == false) { return; } bool hasDisplay = OS_Draw(true); - if ( m_window.opaque - || m_window.fullscreen) { - struct wl_region *region = (struct wl_region *)wl_compositor_create_region(m_display.compositor); + if ( m_opaque == true + || m_fullscreen == true) { + struct wl_region *region = (struct wl_region *)wl_compositor_create_region(m_compositor); wl_region_add(region, 0, 0, m_size.x(), m_size.y()); - wl_surface_set_opaque_region(m_window.surface, region); + wl_surface_set_opaque_region(m_surface, region); wl_region_destroy(region); } else { - wl_surface_set_opaque_region(m_window.surface, nullptr); + wl_surface_set_opaque_region(m_surface, nullptr); } - m_window.callback = wl_surface_frame(m_window.surface); - wl_callback_add_listener(m_window.callback, &frame_listener, this); - eglSwapBuffers(m_display.egl.dpy, m_window.egl_surface); + m_callback = wl_surface_frame(m_surface); + wl_callback_add_listener(m_callback, &frame_listener, this); + eglSwapBuffers(m_eglDisplay, m_eglSurface); GALE_WARNING("REDRAW [STOP]"); } void configureCallback(struct wl_callback* _callback, uint32_t _time) { wl_callback_destroy(_callback); - m_window.configured = 1; - if (m_window.callback == nullptr) { + m_configured = true; + if (m_callback == nullptr) { GALE_ERROR(" ==> nullptr"); redraw(nullptr, _time); } @@ -482,10 +503,11 @@ class WAYLANDInterface : public gale::Context { void handleConfigure(struct wl_shell_surface* _shell_surface, uint32_t _edges, ivec2 _size) { GALE_WARNING("configure surface : _edges=" << _edges << " size=" << _size); - if (m_window.native != nullptr) { - wl_egl_window_resize(m_window.native, _size.x(), _size.y(), 0, 0); + if (m_eglWindow != nullptr) { + wl_egl_window_resize(m_eglWindow, _size.x(), _size.y(), 0, 0); } m_size = _size; + OS_Resize(vec2(m_size.x(), m_size.y())); GALE_WARNING("configure [STOP]"); } @@ -511,13 +533,11 @@ class WAYLANDInterface : public gale::Context { void keyboardKey(struct wl_keyboard* _keyboard, uint32_t _serial, uint32_t _time, uint32_t _key, uint32_t _state) { GALE_WARNING("callback ..."); GALE_INFO("KEY : '" << _key << "'"); - /* - struct display *d = (struct display *)data; - if (key == KEY_F11 && state) - toggle_fullscreen(d->window, d->window->fullscreen ^ 1); - else if (key == KEY_ESC && state) - running = 0; - */ + if (_key == KEY_F11 && _state) { + setFullScreen(m_fullscreen?false:true); + } else if (_key == KEY_ESC && _state) { + m_run = false; + } } static void keyboardModifiers(struct wl_keyboard* _keyboard, uint32_t _serial, uint32_t _modsDepressed, uint32_t _modsLatched, uint32_t _modsLocked, uint32_t _group) { @@ -541,38 +561,9 @@ class WAYLANDInterface : public gale::Context { /****************************************************************************************/ void setFullScreen(bool _status) { WAYLAND_INFO("WAYLAND-API: changeFullscreen=" << _status); - /* - XEvent event; - event.xclient.type = ClientMessage; - event.xclient.serial = 0; - event.xclient.send_event = True; - event.xclient.display = m_display; - event.xclient.window = m_WindowHandle; - event.xclient.message_type = XInternAtom(m_display, "_NET_WM_STATE", False); - event.xclient.format = 32; - if (_status == true) { - event.xclient.data.l[0] = 1;//XInternAtom(m_display, "_NET_WM_STATE_REMOVE", False); - } else { - event.xclient.data.l[0] = 0;//XInternAtom(m_display, "_NET_WM_STATE_ADD", False); - } - event.xclient.data.l[1] = XInternAtom(m_display, "_NET_WM_STATE_FULLSCREEN", False); - event.xclient.data.l[2] = 0; - event.xclient.data.l[3] = 0; - event.xclient.data.l[4] = 0; - - //long mask = SubstructureNotifyMask; - //long mask = StructureNotifyMask | ResizeRedirectMask; - //long mask = SubstructureRedirectMask; - long mask = PropertyChangeMask; - - XSendEvent(m_display, - RootWindow(m_display, DefaultScreen(m_display)), - False, - mask, - &event); - // associate the keyboard grabing (99% associated case) - grabKeyboardEvents(_status); - */ + m_fullscreen = _status; + toggleFullscreen(); + // TODO : Grab all event from keyborad } /****************************************************************************************/ virtual void grabKeyboardEvents(bool _status) { @@ -633,95 +624,68 @@ class WAYLANDInterface : public gale::Context { */ /****************************************************************************************/ virtual void setCursor(enum gale::context::cursor _newCursor) { - /* - if (_newCursor != m_currentCursor) { - WAYLAND_DEBUG("WAYLAND-API: set New Cursor : " << _newCursor); - // undefine previous cursors ... - XUndefineCursor(m_display, m_WindowHandle); - // set the new one : - m_currentCursor = _newCursor; - Cursor myCursor = None; - switch (m_currentCursor) { - case gale::context::cursor::none: - { - Pixmap bitmapNoData; - XColor black; - static char noData[] = { 0,0,0,0,0,0,0,0 }; - black.red = 0; - black.green = 0; - black.blue = 0; - bitmapNoData = XCreateBitmapFromData(m_display, m_WindowHandle, noData, 8, 8); - myCursor = XCreatePixmapCursor(m_display, bitmapNoData, bitmapNoData, - &black, &black, 0, 0); - } - break; - case gale::context::cursor::leftArrow: - myCursor = XCreateFontCursor(m_display, XC_top_left_arrow); - break; - case gale::context::cursor::info: - myCursor = XCreateFontCursor(m_display, XC_hand1); - break; - case gale::context::cursor::destroy: - myCursor = XCreateFontCursor(m_display, XC_pirate); - break; - case gale::context::cursor::help: - myCursor = XCreateFontCursor(m_display, XC_question_arrow); - break; - case gale::context::cursor::cycle: - myCursor = XCreateFontCursor(m_display, XC_exchange); - break; - case gale::context::cursor::spray: - myCursor = XCreateFontCursor(m_display, XC_spraycan); - break; - case gale::context::cursor::wait: - myCursor = XCreateFontCursor(m_display, XC_watch); - break; - case gale::context::cursor::text: - myCursor = XCreateFontCursor(m_display, XC_xterm); - break; - case gale::context::cursor::crossHair: - myCursor = XCreateFontCursor(m_display, XC_crosshair); - break; - case gale::context::cursor::slideUpDown: - myCursor = XCreateFontCursor(m_display, XC_sb_v_double_arrow); - break; - case gale::context::cursor::slideLeftRight: - myCursor = XCreateFontCursor(m_display, XC_sb_h_double_arrow); - break; - case gale::context::cursor::resizeUp: - myCursor = XCreateFontCursor(m_display, XC_top_side); - break; - case gale::context::cursor::resizeDown: - myCursor = XCreateFontCursor(m_display, XC_bottom_side); - break; - case gale::context::cursor::resizeLeft: - myCursor = XCreateFontCursor(m_display, XC_left_side); - break; - case gale::context::cursor::resizeRight: - myCursor = XCreateFontCursor(m_display, XC_right_side); - break; - case gale::context::cursor::cornerTopLeft: - myCursor = XCreateFontCursor(m_display, XC_top_left_corner); - break; - case gale::context::cursor::cornerTopRight: - myCursor = XCreateFontCursor(m_display, XC_top_right_corner); - break; - case gale::context::cursor::cornerButtomLeft: - myCursor = XCreateFontCursor(m_display, XC_bottom_right_corner); - break; - case gale::context::cursor::cornerButtomRight: - myCursor = XCreateFontCursor(m_display, XC_bottom_left_corner); - break; - default : - // nothing to do ... basic pointer ... - break; - } - if (myCursor != None) { - XDefineCursor(m_display, m_WindowHandle, myCursor); - XFreeCursor(m_display, myCursor); - } + if (m_cursorCurrent == _newCursor) { + return; + } + m_cursorCurrent = _newCursor; + WAYLAND_DEBUG("WAYLAND-API: set New Cursor : " << _newCursor); + switch (m_cursorCurrent) { + case gale::context::cursor::none: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, ""); + break; + case gale::context::cursor::leftArrow: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "left_ptr"); + break; + case gale::context::cursor::info: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "help"); + break; + case gale::context::cursor::destroy: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "crossed_circle"); + break; + case gale::context::cursor::help: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "left_ptr"); + break; + case gale::context::cursor::cycle: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "left_ptr"); + break; + case gale::context::cursor::spray: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "hand2"); + break; + case gale::context::cursor::wait: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "watch"); + break; + case gale::context::cursor::text: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "xterm"); + break; + case gale::context::cursor::crossHair: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "crosshair"); + break; + case gale::context::cursor::slideUpDown: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "left_ptr"); + break; + case gale::context::cursor::slideLeftRight: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "left_ptr"); + break; + case gale::context::cursor::resizeUp: + case gale::context::cursor::resizeDown: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "h_double_arrow"); + break; + case gale::context::cursor::resizeLeft: + case gale::context::cursor::resizeRight: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "v_double_arrow"); + break; + case gale::context::cursor::cornerTopLeft: + case gale::context::cursor::cornerTopRight: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "fd_double_arrow"); + break; + case gale::context::cursor::cornerButtomLeft: + case gale::context::cursor::cornerButtomRight: + m_cursorDefault = wl_cursor_theme_get_cursor(m_cursorTheme, "bd_double_arrow"); + break; + default : + // nothing to do ... basic pointer ... + break; } - */ } /****************************************************************************************/ void grabPointerEvents(bool _status, const vec2& _forcedPosition) { @@ -927,17 +891,8 @@ class WAYLANDInterface : public gale::Context { /****************************************************************************************/ void setTitle(const std::string& _title) { WAYLAND_INFO("WAYLAND: set Title (START)"); - /* - XTextProperty tp; - tp.value = (unsigned char *)_title.c_str(); - tp.encoding = XA_WM_NAME; - tp.format = 8; - tp.nitems = strlen((const char*)tp.value); - XSetWMName(m_display, m_WindowHandle, &tp); - XStoreName(m_display, m_WindowHandle, (const char*)tp.value); - XSetIconName(m_display, m_WindowHandle, (const char*)tp.value); - XSetWMIconName(m_display, m_WindowHandle, &tp); - */ + m_uniqueWindowsName = _title; + wl_shell_surface_set_title(m_shellSurface, m_uniqueWindowsName.c_str()); WAYLAND_INFO("WAYLAND: set Title (END)"); } void openURL(const std::string& _url) { @@ -1067,7 +1022,7 @@ static void pointer_handle_motion(void* _data, struct wl_pointer* _pointer, uint GALE_ERROR(" ==> nullptr"); return; } - interface->pointerHandleMotion(_pointer, _time, ivec2(_sx, _sy)); + interface->pointerHandleMotion(_pointer, _time, ivec2(_sx/256, _sy/256)); } static void pointer_handle_button(void* _data, struct wl_pointer* _pointer, uint32_t _serial, uint32_t _time, uint32_t _button, uint32_t _state) { @@ -1077,7 +1032,11 @@ static void pointer_handle_button(void* _data, struct wl_pointer* _pointer, uint GALE_ERROR(" ==> nullptr"); return; } - interface->pointerHandleButton(_pointer, _serial, _time, _button, _state); + interface->pointerHandleButton(_pointer, + _serial, + _time, + _button, + _state==WL_POINTER_BUTTON_STATE_PRESSED); } static void pointer_handle_axis(void* _data, struct wl_pointer* _pointer, uint32_t _time, uint32_t _axis, wl_fixed_t _value) {