From 5843840411fd88494d0c1499cc6810255553c9d1 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sun, 29 Nov 2015 14:20:20 -1000 Subject: [PATCH] Added cursor change method --- CMakeLists.txt | 1 + include/boo/IWindow.hpp | 11 +++++ lib/x11/ApplicationXlib.hpp | 9 +++- lib/x11/WindowWayland.cpp | 8 ++++ lib/x11/WindowXlib.cpp | 86 ++++++++++++++++++++++++++++--------- lib/x11/XlibCommon.hpp | 20 +++++++++ 6 files changed, 114 insertions(+), 21 deletions(-) create mode 100644 lib/x11/XlibCommon.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 499b464..8c3606c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,7 @@ elseif(APPLE) ${QUARTZCORE_LIBRARY} ${COREVIDEO_LIBRARY}) else(NOT GEKKO) list(APPEND PLAT_SRCS + lib/x11/XlibCommon.hpp lib/x11/ApplicationUnix.cpp lib/x11/ApplicationXlib.hpp lib/x11/ApplicationWayland.hpp diff --git a/include/boo/IWindow.hpp b/include/boo/IWindow.hpp index e040ea6..0c74431 100644 --- a/include/boo/IWindow.hpp +++ b/include/boo/IWindow.hpp @@ -175,6 +175,14 @@ enum class EWindowStyle }; ENABLE_BITWISE_ENUM(EWindowStyle) +enum class EMouseCursor +{ + None = 0, + Pointer = 1, + HorizontalArrow = 2, + VerticalArrow = 3 +}; + class IWindow { public: @@ -189,6 +197,9 @@ public: virtual SystemString getTitle()=0; virtual void setTitle(const SystemString& title)=0; + virtual void setCursor(EMouseCursor cursor)=0; + virtual void setWaitCursor(bool wait)=0; + virtual void setWindowFrameDefault()=0; virtual void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const=0; virtual void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const=0; diff --git a/lib/x11/ApplicationXlib.hpp b/lib/x11/ApplicationXlib.hpp index 9537047..b33f34c 100644 --- a/lib/x11/ApplicationXlib.hpp +++ b/lib/x11/ApplicationXlib.hpp @@ -20,9 +20,13 @@ DBusConnection* RegisterDBus(const char* appName, bool& isFirst); #include #include +#include "XlibCommon.hpp" +#include + namespace boo { static LogVisor::LogModule Log("boo::ApplicationXCB"); +XlibCursors X_CURSORS; int XCB_GLX_EVENT_BASE = 0; int XINPUT_OPCODE = 0; @@ -198,7 +202,10 @@ public: } m_xDefaultScreen = DefaultScreen(m_xDisp); - + X_CURSORS.m_pointer = XCreateFontCursor(m_xDisp, XC_left_ptr); + X_CURSORS.m_hArrow = XCreateFontCursor(m_xDisp, XC_sb_h_double_arrow); + X_CURSORS.m_vArrow = XCreateFontCursor(m_xDisp, XC_sb_v_double_arrow); + X_CURSORS.m_wait = XCreateFontCursor(m_xDisp, XC_watch); /* The xkb extension requests that the X server does not * send repeated keydown events when a key is held */ diff --git a/lib/x11/WindowWayland.cpp b/lib/x11/WindowWayland.cpp index 224ef4c..7fb97c4 100644 --- a/lib/x11/WindowWayland.cpp +++ b/lib/x11/WindowWayland.cpp @@ -128,6 +128,14 @@ struct WindowWayland : IWindow { } + + void setCursor(EMouseCursor cursor) + { + } + + void setWaitCursor(bool wait) + { + } void setWindowFrameDefault() { diff --git a/lib/x11/WindowXlib.cpp b/lib/x11/WindowXlib.cpp index e805797..4a1289b 100644 --- a/lib/x11/WindowXlib.cpp +++ b/lib/x11/WindowXlib.cpp @@ -23,6 +23,8 @@ #include #include +#include "XlibCommon.hpp" + #define REF_DPMM 3.7824 /* 96 DPI */ #define FS_ATOM "_NET_WM_STATE_FULLSCREEN" @@ -468,6 +470,24 @@ class WindowXlib : public IWindow /* Cached window style */ EWindowStyle m_styleFlags; + /* Current cursor enum */ + EMouseCursor m_cursor = EMouseCursor::None; + bool m_cursorWait = false; + static Cursor GetXCursor(EMouseCursor cur) + { + switch (cur) + { + case EMouseCursor::Pointer: + return X_CURSORS.m_pointer; + case EMouseCursor::HorizontalArrow: + return X_CURSORS.m_hArrow; + case EMouseCursor::VerticalArrow: + return X_CURSORS.m_vArrow; + default: break; + } + return X_CURSORS.m_pointer; + } + public: WindowXlib(const std::string& title, @@ -540,9 +560,9 @@ public: /* Initialize context */ XMapWindow(m_xDisp, m_windowId); - XFlush(m_xDisp); - setStyle(EWindowStyle::Default); + setCursor(EMouseCursor::Pointer); + XFlush(m_xDisp); m_gfxCtx.initializeContext(); } @@ -604,6 +624,32 @@ public: PropModeReplace, c_title, title.length()); XUnlockDisplay(m_xDisp); } + + void setCursor(EMouseCursor cursor) + { + if (cursor == m_cursor && !m_cursorWait) + return; + m_cursor = cursor; + XLockDisplay(m_xDisp); + XDefineCursor(m_xDisp, m_windowId, GetXCursor(cursor)); + XUnlockDisplay(m_xDisp); + } + + void setWaitCursor(bool wait) + { + if (wait && !m_cursorWait) + { + XLockDisplay(m_xDisp); + XDefineCursor(m_xDisp, m_windowId, X_CURSORS.m_wait); + XUnlockDisplay(m_xDisp); + m_cursorWait = true; + } + else if (!wait && m_cursorWait) + { + setCursor(m_cursor); + m_cursorWait = false; + } + } void setWindowFrameDefault() { @@ -930,9 +976,9 @@ public: EModifierKey modifierMask = translateModifiers(event->xbutton.state); SWindowCoord coord = { - {(unsigned)event->xbutton.x, (unsigned)event->xbutton.y}, - {(unsigned)(event->xbutton.x / m_pixelFactor), (unsigned)(event->xbutton.y / m_pixelFactor)}, - {float(event->xbutton.x) / float(m_ww), float(event->xbutton.y) / float(m_wh)} + {(unsigned)event->xbutton.x, (unsigned)(m_wh-event->xbutton.y)}, + {(unsigned)(event->xbutton.x / m_pixelFactor), (unsigned)((m_wh-event->xbutton.y) / m_pixelFactor)}, + {float(event->xbutton.x) / float(m_ww), float(m_wh-event->xbutton.y) / float(m_wh)} }; m_callback->mouseDown(coord, (EMouseButton)button, (EModifierKey)modifierMask); @@ -944,9 +990,9 @@ public: { SWindowCoord coord = { - {(unsigned)event->xbutton.x, (unsigned)event->xbutton.y}, - {(unsigned)(event->xbutton.x / m_pixelFactor), (unsigned)(event->xbutton.y / m_pixelFactor)}, - {(float)event->xbutton.x / (float)m_ww, (float)event->xbutton.y / (float)m_wh} + {(unsigned)event->xbutton.x, (unsigned)(m_wh-event->xbutton.y)}, + {(unsigned)(event->xbutton.x / m_pixelFactor), (unsigned)((m_wh-event->xbutton.y) / m_pixelFactor)}, + {(float)event->xbutton.x / (float)m_ww, (float)(m_wh-event->xbutton.y) / (float)m_wh} }; SScrollDelta scrollDelta = { @@ -977,9 +1023,9 @@ public: EModifierKey modifierMask = translateModifiers(event->xbutton.state); SWindowCoord coord = { - {(unsigned)event->xbutton.x, (unsigned)event->xbutton.y}, - {(unsigned)(event->xbutton.x / m_pixelFactor), (unsigned)(event->xbutton.y / m_pixelFactor)}, - {event->xbutton.x / (float)m_ww, event->xbutton.y / (float)m_wh} + {(unsigned)event->xbutton.x, (unsigned)(m_wh-event->xbutton.y)}, + {(unsigned)(event->xbutton.x / m_pixelFactor), (unsigned)((m_wh-event->xbutton.y) / m_pixelFactor)}, + {event->xbutton.x / (float)m_ww, (m_wh-event->xbutton.y) / (float)m_wh} }; m_callback->mouseUp(coord, (EMouseButton)button, (EModifierKey)modifierMask); @@ -1006,9 +1052,9 @@ public: getWindowFrame(m_wx, m_wy, m_ww, m_wh); SWindowCoord coord = { - {(unsigned)event->xmotion.x, (unsigned)event->xmotion.y}, - {(unsigned)(event->xmotion.x / m_pixelFactor), (unsigned)(event->xmotion.y / m_pixelFactor)}, - {event->xmotion.x / (float)m_ww, event->xmotion.y / (float)m_wh} + {(unsigned)event->xmotion.x, (unsigned)(m_wh-event->xmotion.y)}, + {(unsigned)(event->xmotion.x / m_pixelFactor), (unsigned)((m_wh-event->xmotion.y) / m_pixelFactor)}, + {event->xmotion.x / (float)m_ww, (m_wh-event->xmotion.y) / (float)m_wh} }; m_callback->mouseMove(coord); } @@ -1021,9 +1067,9 @@ public: getWindowFrame(m_wx, m_wy, m_ww, m_wh); SWindowCoord coord = { - {(unsigned)event->xcrossing.x, (unsigned)event->xcrossing.y}, - {(unsigned)(event->xcrossing.x / m_pixelFactor), (unsigned)(event->xmotion.y / m_pixelFactor)}, - {event->xcrossing.x / (float)m_ww, event->xcrossing.y / (float)m_wh} + {(unsigned)event->xcrossing.x, (unsigned)(m_wh-event->xcrossing.y)}, + {(unsigned)(event->xcrossing.x / m_pixelFactor), (unsigned)((m_wh-event->xmotion.y) / m_pixelFactor)}, + {event->xcrossing.x / (float)m_ww, (m_wh-event->xcrossing.y) / (float)m_wh} }; m_callback->mouseEnter(coord); } @@ -1036,9 +1082,9 @@ public: getWindowFrame(m_wx, m_wy, m_ww, m_wh); SWindowCoord coord = { - {(unsigned)event->xcrossing.x, (unsigned)event->xcrossing.y}, - {(unsigned)(event->xcrossing.x / m_pixelFactor), (unsigned)(event->xmotion.y / m_pixelFactor)}, - {event->xcrossing.x / (float)m_ww, event->xcrossing.y / (float)m_wh} + {(unsigned)event->xcrossing.x, (unsigned)m_wh-event->xcrossing.y}, + {(unsigned)(event->xcrossing.x / m_pixelFactor), (unsigned)((m_wh-event->xmotion.y) / m_pixelFactor)}, + {event->xcrossing.x / (float)m_ww, (m_wh-event->xcrossing.y) / (float)m_wh} }; m_callback->mouseLeave(coord); } diff --git a/lib/x11/XlibCommon.hpp b/lib/x11/XlibCommon.hpp new file mode 100644 index 0000000..99270af --- /dev/null +++ b/lib/x11/XlibCommon.hpp @@ -0,0 +1,20 @@ +#ifndef BOO_XLIBCOMMON_HPP +#define BOO_XLIBCOMMON_HPP + +#include + +namespace boo +{ + +struct XlibCursors +{ + Cursor m_pointer; + Cursor m_hArrow; + Cursor m_vArrow; + Cursor m_wait; +}; +extern XlibCursors X_CURSORS; + +} + +#endif // BOO_XLIBCOMMON_HPP