Utility: Rework cursors

-Rename WindowCursor to SystemCursor
-Merged Cursor class with SystemCursor enum
This commit is contained in:
Lynix
2017-01-16 00:32:59 +01:00
parent 954298dc1e
commit f406068c45
16 changed files with 281 additions and 202 deletions

View File

@@ -159,16 +159,96 @@ namespace Nz
return true;
}
bool CursorImpl::Create(SystemCursor cursor)
{
ScopedXCBConnection connection;
if (xcb_cursor_context_new(connection, m_screen, &m_cursorContext) >= 0)
m_cursor = xcb_cursor_load_cursor(ctx, s_systemCursorIds[cursor]);
return true;
}
void CursorImpl::Destroy()
{
ScopedXCBConnection connection;
xcb_free_cursor(connection, m_cursor);
m_cursor = 0;
if (m_cursorContext)
xcb_cursor_context_free(m_cursorContext);
}
xcb_cursor_t CursorImpl::GetCursor()
{
return m_cursor;
}
bool CursorImpl::Initialize()
{
ScopedXCBConnection connection;
XCBPixmap cursorPixmap(connection);
xcb_window_t window = X11::XCBDefaultRootWindow(connection);
if (!cursorPixmap.Create(1, window, 1, 1))
{
NazaraError("Failed to create pixmap for hidden cursor");
return false;
}
hiddenCursor = xcb_generate_id(connection);
// Create the cursor, using the pixmap as both the shape and the mask of the cursor
if (!X11::CheckCookie(
connection, xcb_create_cursor(connection,
hiddenCursor,
cursorPixmap,
cursorPixmap,
0, 0, 0, // Foreground RGB color
0, 0, 0, // Background RGB color
0, // X
0 // Y
)))
{
NazaraError("Failed to create hidden cursor");
return false;
}
return true;
}
void CursorImpl::Uninitialize()
{
if (s_hiddenCursor)
{
ScopedXCBConnection connection;
xcb_free_cursor(connection, s_hiddenCursor);
s_hiddenCursor = 0;
}
}
std::array<const char*, SystemCursor_Max + 1> CursorImpl::s_systemCursorIds =
{
// http://gnome-look.org/content/preview.php?preview=1&id=128170&file1=128170-1.png&file2=&file3=&name=Dummy+X11+cursors&PHPSESSID=6
"crosshair", // SystemCursor_Crosshair
"left_ptr", // SystemCursor_Default
"hand", // SystemCursor_Hand
"help", // SystemCursor_Help
"fleur", // SystemCursor_Move
nullptr, // SystemCursor_None
"hand", // SystemCursor_Pointer
"watch", // SystemCursor_Progress
"right_side", // SystemCursor_ResizeE
"top_side", // SystemCursor_ResizeN
"top_right_corner", // SystemCursor_ResizeNE
"top_left_corner", // SystemCursor_ResizeNW
"bottom_side", // SystemCursor_ResizeS
"bottom_right_corner", // SystemCursor_ResizeSE
"bottom_left_corner", // SystemCursor_ResizeSW
"left_side", // SystemCursor_ResizeW
"xterm", // SystemCursor_Text
"watch" // SystemCursor_Wait
};
static_assert(SystemCursor_Max + 1 == 18, "System cursor array is incomplete");
}

View File

@@ -8,6 +8,7 @@
#define NAZARA_CURSORIMPL_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Utility/Enums.hpp>
#include <xcb/xcb_cursor.h>
namespace Nz
@@ -16,14 +17,24 @@ namespace Nz
class CursorImpl
{
friend class Cursor;
public:
bool Create(const Image& image, int hotSpotX, int hotSpotY);
bool Create(SystemCursor cursor);
void Destroy();
xcb_cursor_t GetCursor();
private:
xcb_cursor_t m_cursor;
static bool Initialize();
static void Uninitialize();
xcb_cursor_t m_cursor = 0;
xcb_cursor_context_t* m_cursorContext = nullptr;
static std::array<const char*, SystemCursor_Max + 1> s_systemCursorIds;
};
}

View File

@@ -50,45 +50,7 @@ namespace Nz
XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_STRUCTURE_NOTIFY |
XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW;
xcb_cursor_t hiddenCursor = 0;
xcb_connection_t* connection = nullptr;
void CreateHiddenCursor()
{
XCBPixmap cursorPixmap(connection);
xcb_window_t window = X11::XCBDefaultRootWindow(connection);
if (!cursorPixmap.Create(
1,
window,
1,
1
))
{
NazaraError("Failed to create pixmap for hidden cursor");
return;
}
hiddenCursor = xcb_generate_id(connection);
// Create the cursor, using the pixmap as both the shape and the mask of the cursor
if (!X11::CheckCookie(
connection,
xcb_create_cursor(
connection,
hiddenCursor,
cursorPixmap,
cursorPixmap,
0, 0, 0, // Foreground RGB color
0, 0, 0, // Background RGB color
0, // X
0 // Y
))
)
NazaraError("Failed to create hidden cursor");
}
}
WindowImpl::WindowImpl(Window* parent) :
@@ -452,34 +414,13 @@ namespace Nz
}
}
void WindowImpl::SetCursor(Nz::WindowCursor windowCursor)
{
if (windowCursor == Nz::WindowCursor_None)
SetCursor(hiddenCursor);
else
{
const char* name = ConvertWindowCursorToXName(windowCursor);
xcb_cursor_context_t* ctx;
if (xcb_cursor_context_new(connection, m_screen, &ctx) >= 0)
{
xcb_cursor_t cursor = xcb_cursor_load_cursor(ctx, name);
SetCursor(cursor);
xcb_free_cursor(connection, cursor);
xcb_cursor_context_free(ctx);
}
}
}
void WindowImpl::SetCursor(const Cursor& cursor)
{
if (!cursor.IsValid())
{
NazaraError("Cursor is not valid");
return;
}
xcb_cursor_t cursorImpl = cursor.m_impl->GetCursor();
if (!X11::CheckCookie(connection, xcb_change_window_attributes(connection, m_window, XCB_CW_CURSOR, &cursor)))
NazaraError("Failed to change mouse cursor");
SetCursor(cursor.m_impl->GetCursor());
xcb_flush(connection);
}
void WindowImpl::SetEventListener(bool listener)
@@ -998,7 +939,7 @@ namespace Nz
}
}
const char* WindowImpl::ConvertWindowCursorToXName(Nz::WindowCursor cursor)
const char* WindowImpl::ConvertWindowCursorToXName(SystemCursor cursor)
{
// http://gnome-look.org/content/preview.php?preview=1&id=128170&file1=128170-1.png&file2=&file3=&name=Dummy+X11+cursors&PHPSESSID=6
switch (cursor)
@@ -1444,22 +1385,6 @@ namespace Nz
}
}
void WindowImpl::SetCursor(xcb_cursor_t cursor)
{
if (!X11::CheckCookie(
connection,
xcb_change_window_attributes(
connection,
m_window,
XCB_CW_CURSOR,
&cursor
))
)
NazaraError("Failed to change mouse cursor");
xcb_flush(connection);
}
void WindowImpl::SetMotifHints()
{
ScopedXCB<xcb_generic_error_t> error(nullptr);

View File

@@ -60,7 +60,6 @@ namespace Nz
void ProcessEvents(bool block);
void SetCursor(WindowCursor cursor);
void SetCursor(const Cursor& cursor);
void SetEventListener(bool listener);
void SetFocus();
@@ -84,7 +83,7 @@ namespace Nz
void CleanUp();
xcb_keysym_t ConvertKeyCodeToKeySym(xcb_keycode_t keycode, uint16_t state);
Keyboard::Key ConvertVirtualKey(xcb_keysym_t symbol);
const char* ConvertWindowCursorToXName(WindowCursor cursor);
const char* ConvertWindowCursorToXName(SystemCursor cursor);
void CommonInitialize();
char32_t GetRepresentation(xcb_keysym_t keysym) const;
@@ -93,7 +92,6 @@ namespace Nz
void ResetVideoMode();
void SetCursor(xcb_cursor_t cursor);
void SetMotifHints();
void SetVideoMode(const VideoMode& mode);
void SwitchToFullscreen();