Added support for colored cursors in Unix implementation

This commit is contained in:
Corentin Schreiber 2020-08-20 21:20:28 +01:00 committed by Lukas Dürrenberger
parent fc573bc584
commit 54ac286a67
2 changed files with 69 additions and 0 deletions

View File

@ -29,6 +29,7 @@
#include <SFML/Window/Unix/Display.hpp> #include <SFML/Window/Unix/Display.hpp>
#include <X11/cursorfont.h> #include <X11/cursorfont.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/Xcursor/Xcursor.h>
#include <cassert> #include <cassert>
#include <cstdlib> #include <cstdlib>
#include <vector> #include <vector>
@ -61,6 +62,45 @@ bool CursorImpl::loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hot
{ {
release(); 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!). // Convert the image into a bitmap (monochrome!).
std::size_t bytes = (size.x + 7) / 8 * size.y; std::size_t bytes = (size.x + 7) / 8 * size.y;
std::vector<Uint8> mask(bytes, 0); // Defines which pixel is transparent. std::vector<Uint8> 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() void CursorImpl::release()
{ {

View File

@ -83,6 +83,28 @@ private:
friend class WindowImplX11; 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. /// \brief Release the cursor, if we have loaded one.
/// ///