<commit_before>// Copyright 2015-2019 <NAME>. All rights reserved.

#include <stdexcept>
#include "core/Setup.h"
#if OUZEL_SUPPORTS_X11
#  include <X11/cursorfont.h>
#  include <X11/Xcursor/Xcursor.h>
#endif
#include "CursorLinux.hpp"
#include "core/linux/EngineLinux.hpp"

namespace ouzel
{
    namespace input
    {
        CursorLinux::CursorLinux(SystemCursor systemCursor)
        {
#if OUZEL_SUPPORTS_X11
            EngineLinux* engineLinux = static_cast<EngineLinux*>(engine);
            Display* display = engineLinux->getDisplay();

            switch (systemCursor)
            {
                case SystemCursor::Default:
                case SystemCursor::Arrow:
                    cursor = XcursorLibraryLoadCursor(display, "arrow");
                    break;
                case SystemCursor::Hand:
                    cursor = XcursorLibraryLoadCursor(display, "hand1");
                    break;
                case SystemCursor::HorizontalResize:
                    cursor = XcursorLibraryLoadCursor(display, "sb_h_double_arrow");
                    break;
                case SystemCursor::VerticalResize:
                    cursor = XcursorLibraryLoadCursor(display, "sb_v_double_arrow");
                    break;
                case SystemCursor::Cross:
                    cursor = XcursorLibraryLoadCursor(display, "crosshair");
                    break;
                case SystemCursor::IBeam:
                    cursor = XcursorLibraryLoadCursor(display, "xterm");
                    break;
            }
#endif
        }

        CursorLinux::CursorLinux(const std::vector<uint8_t>& data,
                                 const Size2F& size,
                                 graphics::PixelFormat pixelFormat,
                                 const Vector2F& hotSpot)
        {
#if OUZEL_SUPPORTS_X11
            EngineLinux* engineLinux = static_cast<EngineLinux*>(engine);
            Display* display = engineLinux->getDisplay();

            if (!data.empty())
            {
                auto width = static_cast<int>(size.v[0]);
                auto height = static_cast<int>(size.v[1]);

                XcursorImage* cursorImage = XcursorImageCreate(width, height);

                if (!cursorImage)
                    throw std::runtime_error("Failed to create cursor image");

                cursorImage->xhot = static_cast<int>(hotSpot.v[0]);
                cursorImage->yhot = height - static_cast<int>(hotSpot.v[1]) - 1;
                cursorImage->delay = 0;

                auto target = reinterpret_cast<unsigned char*>(cursorImage->pixels);

                for (int i = 0; i < width * height; ++i)
                {
                    // premultiply alpha
                    const float opacity = data[i * 4 + 3] / 255.0F;

                    target[i * 4 + 0] = static_cast<unsigned char>(data[i * 4 + 2] * opacity);
                    target[i * 4 + 1] = static_cast<unsigned char>(data[i * 4 + 1] * opacity);
                    target[i * 4 + 2] = static_cast<unsigned char>(data[i * 4 + 0] * opacity);
                    target[i * 4 + 3] = data[i * 4 + 3];
                }<commit_msg>Write pixels directly to cursorImage->pixels<commit_after>// Copyright 2015-2019 <NAME>. All rights reserved.

#include <stdexcept>
#include "core/Setup.h"
#if OUZEL_SUPPORTS_X11
#  include <X11/cursorfont.h>
#  include <X11/Xcursor/Xcursor.h>
#endif
#include "CursorLinux.hpp"
#include "core/linux/EngineLinux.hpp"

namespace ouzel
{
    namespace input
    {
        CursorLinux::CursorLinux(SystemCursor systemCursor)
        {
#if OUZEL_SUPPORTS_X11
            EngineLinux* engineLinux = static_cast<EngineLinux*>(engine);
            Display* display = engineLinux->getDisplay();

            switch (systemCursor)
            {
                case SystemCursor::Default:
                case SystemCursor::Arrow:
                    cursor = XcursorLibraryLoadCursor(display, "arrow");
                    break;
                case SystemCursor::Hand:
                    cursor = XcursorLibraryLoadCursor(display, "hand1");
                    break;
                case SystemCursor::HorizontalResize:
                    cursor = XcursorLibraryLoadCursor(display, "sb_h_double_arrow");
                    break;
                case SystemCursor::VerticalResize:
                    cursor = XcursorLibraryLoadCursor(display, "sb_v_double_arrow");
                    break;
                case SystemCursor::Cross:
                    cursor = XcursorLibraryLoadCursor(display, "crosshair");
                    break;
                case SystemCursor::IBeam:
                    cursor = XcursorLibraryLoadCursor(display, "xterm");
                    break;
            }
#endif
        }

        CursorLinux::CursorLinux(const std::vector<uint8_t>& data,
                                 const Size2F& size,
                                 graphics::PixelFormat pixelFormat,
                                 const Vector2F& hotSpot)
        {
#if OUZEL_SUPPORTS_X11
            EngineLinux* engineLinux = static_cast<EngineLinux*>(engine);
            Display* display = engineLinux->getDisplay();

            if (!data.empty())
            {
                auto width = static_cast<int>(size.v[0]);
                auto height = static_cast<int>(size.v[1]);

                XcursorImage* cursorImage = XcursorImageCreate(width, height);

                if (!cursorImage)
                    throw std::runtime_error("Failed to create cursor image");

                cursorImage->xhot = static_cast<int>(hotSpot.v[0]);
                cursorImage->yhot = height - static_cast<int>(hotSpot.v[1]) - 1;
                cursorImage->delay = 0;

                for (int i = 0; i < width * height; ++i)
                {
                    // premultiply alpha
                    const float opacity = data[i * 4 + 3] / 255.0F;

                    cursorImage->pixels[i] = static_cast<unsigned int>(data[i * 4 + 2] * opacity) |
                        (static_cast<unsigned int>(data[i * 4 + 1] * opacity) << 8) |
                        (static_cast<unsigned int>(data[i * 4 + 0] * opacity) << 16) |
                        (data[i * 4 + 3] << 24);
                }
{'fraction_non_alphanumeric': 0.10253953042644945, 'fraction_numerical': 0.01581217057977959, 'mean_word_length': 1.6167989970748016, 'pattern_counts': {'":': 0, '<': 40, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4718609', 'n_tokens_mistral': 1779, 'n_tokens_neox': 1594, 'n_words': 342}