From 54ac286a672658bd93d82be335eb8f3e160f47c9 Mon Sep 17 00:00:00 2001 From: Corentin Schreiber Date: Thu, 20 Aug 2020 21:20:28 +0100 Subject: [PATCH] Added support for colored cursors in Unix implementation --- src/SFML/Window/Unix/CursorImpl.cpp | 47 +++++++++++++++++++++++++++++ src/SFML/Window/Unix/CursorImpl.hpp | 22 ++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/src/SFML/Window/Unix/CursorImpl.cpp b/src/SFML/Window/Unix/CursorImpl.cpp index d088e482..0a3f1a39 100644 --- a/src/SFML/Window/Unix/CursorImpl.cpp +++ b/src/SFML/Window/Unix/CursorImpl.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,45 @@ bool CursorImpl::loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hot { release(); + if (isColorCursorSupported()) + { + return loadFromPixelsARGB(pixels, size, hotspot); + } + else + { + return loadFromPixelsMonochrome(pixels, size, hotspot); + } +} + + +//////////////////////////////////////////////////////////// +bool CursorImpl::loadFromPixelsARGB(const Uint8* pixels, Vector2u size, Vector2u hotspot) +{ + // Create cursor image, convert from RGBA to ARGB. + XcursorImage* cursorImage = XcursorImageCreate(size.x, size.y); + cursorImage->xhot = hotspot.x; + cursorImage->yhot = hotspot.y; + + const std::size_t numPixels = size.x * size.y; + for (std::size_t i = 0; i < numPixels; ++i) + { + cursorImage->pixels[i] = pixels[4*i+2] + (pixels[4*i+1] << 8) + (pixels[4*i+0] << 16) + (pixels[4*i+3] << 24); + } + + // Create the cursor. + m_cursor = XcursorImageLoadCursor(m_display, cursorImage); + + // Free the resources + XcursorImageDestroy(cursorImage); + + // We assume everything went fine... + return true; +} + + +//////////////////////////////////////////////////////////// +bool CursorImpl::loadFromPixelsMonochrome(const Uint8* pixels, Vector2u size, Vector2u hotspot) +{ // Convert the image into a bitmap (monochrome!). std::size_t bytes = (size.x + 7) / 8 * size.y; std::vector mask(bytes, 0); // Defines which pixel is transparent. @@ -139,6 +179,13 @@ bool CursorImpl::loadFromSystem(Cursor::Type type) } +//////////////////////////////////////////////////////////// +bool CursorImpl::isColorCursorSupported() +{ + return XcursorSupportsARGB(m_display); +} + + //////////////////////////////////////////////////////////// void CursorImpl::release() { diff --git a/src/SFML/Window/Unix/CursorImpl.hpp b/src/SFML/Window/Unix/CursorImpl.hpp index ca39b782..cfd3c305 100644 --- a/src/SFML/Window/Unix/CursorImpl.hpp +++ b/src/SFML/Window/Unix/CursorImpl.hpp @@ -83,6 +83,28 @@ private: friend class WindowImplX11; + //////////////////////////////////////////////////////////// + /// \brief Checks if colored cursors are supported for this display. + /// + //////////////////////////////////////////////////////////// + bool isColorCursorSupported(); + + //////////////////////////////////////////////////////////// + /// \brief Create a cursor with the provided image (ARGB support) + /// + /// Refer to sf::Cursor::loadFromPixels(). + /// + //////////////////////////////////////////////////////////// + bool loadFromPixelsARGB(const Uint8* pixels, Vector2u size, Vector2u hotspot); + + //////////////////////////////////////////////////////////// + /// \brief Create a cursor with the provided image (monochrome) + /// + /// Refer to sf::Cursor::loadFromPixels(). + /// + //////////////////////////////////////////////////////////// + bool loadFromPixelsMonochrome(const Uint8* pixels, Vector2u size, Vector2u hotspot); + //////////////////////////////////////////////////////////// /// \brief Release the cursor, if we have loaded one. ///