diff --git a/src/she/x11/window.cpp b/src/she/x11/window.cpp index bd9a70c7a..eb5335c4a 100644 --- a/src/she/x11/window.cpp +++ b/src/she/x11/window.cpp @@ -13,6 +13,7 @@ #include "gfx/rect.h" #include "she/event.h" +#include #include namespace she { @@ -23,6 +24,9 @@ namespace { // window is pressed by the userh. Atom wmDeleteMessage = 0; +// Cursor Without pixels to simulate a hidden X11 cursor +Cursor empty_xcursor = None; + // See https://bugs.freedesktop.org/show_bug.cgi?id=12871 for more // information, it looks like the official way to convert a X Window // into our own user data pointer (X11Window instance) is using a map. @@ -102,6 +106,8 @@ void X11Window::removeWindow(X11Window* window) X11Window::X11Window(::Display* display, int width, int height, int scale) : m_display(display) + , m_gc(nullptr) + , m_cursor(None) , m_scale(scale) { // Initialize special messages (just the first time a X11Window is @@ -207,7 +213,93 @@ void X11Window::updateWindow(const gfx::Rect& unscaledBounds) bool X11Window::setNativeMouseCursor(NativeCursor cursor) { - return false; + Cursor xcursor = None; + + switch (cursor) { + case kNoCursor: { + if (empty_xcursor == None) { + char data = 0; + Pixmap image = XCreateBitmapFromData( + m_display, m_window, (char*)&data, 1, 1); + + XColor color; + empty_xcursor = XCreatePixmapCursor( + m_display, image, image, &color, &color, 0, 0); + + XFreePixmap(m_display, image); + } + xcursor = empty_xcursor; + break; + } + case kArrowCursor: + xcursor = XCreateFontCursor(m_display, XC_arrow); + break; + case kCrosshairCursor: + xcursor = XCreateFontCursor(m_display, XC_crosshair); + break; + case kIBeamCursor: + xcursor = XCreateFontCursor(m_display, XC_xterm); + break; + case kWaitCursor: + xcursor = XCreateFontCursor(m_display, XC_watch); + break; + case kLinkCursor: + xcursor = XCreateFontCursor(m_display, XC_hand1); + break; + case kHelpCursor: + xcursor = XCreateFontCursor(m_display, XC_question_arrow); + break; + case kForbiddenCursor: + xcursor = XCreateFontCursor(m_display, XC_X_cursor); + break; + case kMoveCursor: + xcursor = XCreateFontCursor(m_display, XC_fleur); + break; + case kSizeNCursor: + xcursor = XCreateFontCursor(m_display, XC_top_side); + break; + case kSizeNSCursor: + xcursor = XCreateFontCursor(m_display, XC_sb_v_double_arrow); + break; + case kSizeSCursor: + xcursor = XCreateFontCursor(m_display, XC_bottom_side); + break; + case kSizeWCursor: + xcursor = XCreateFontCursor(m_display, XC_left_side); + break; + case kSizeECursor: + xcursor = XCreateFontCursor(m_display, XC_right_side); + break; + case kSizeWECursor: + xcursor = XCreateFontCursor(m_display, XC_sb_h_double_arrow); + break; + case kSizeNWCursor: + xcursor = XCreateFontCursor(m_display, XC_top_left_corner); + break; + case kSizeNECursor: + xcursor = XCreateFontCursor(m_display, XC_top_right_corner); + break; + case kSizeSWCursor: + xcursor = XCreateFontCursor(m_display, XC_bottom_left_corner); + break; + case kSizeSECursor: + xcursor = XCreateFontCursor(m_display, XC_bottom_right_corner); + break; + } + + if (m_cursor != None) { + if (m_cursor != empty_xcursor) // Don't delete empty_xcursor + XFreeCursor(m_display, m_cursor); + m_cursor = None; + } + + if (xcursor != None) { + m_cursor = xcursor; + XDefineCursor(m_display, m_window, xcursor); + return true; + } + else + return false; } bool X11Window::setNativeMouseCursor(const she::Surface* surface, diff --git a/src/she/x11/window.h b/src/she/x11/window.h index d5f3c533f..6fdfaa15b 100644 --- a/src/she/x11/window.h +++ b/src/she/x11/window.h @@ -64,6 +64,7 @@ private: ::Display* m_display; ::Window m_window; ::GC m_gc; + ::Cursor m_cursor; int m_scale; };