#include #include #include #include namespace psemek::sdl2 { namespace { struct cursor_deleter { void operator() (SDL_Cursor * c) const { SDL_FreeCursor(c); } }; using cursor_ptr = std::unique_ptr; } struct cursor { cursor_ptr cursor; }; namespace { SDL_Cursor * create_system_cursor(SDL_SystemCursor id) { auto cursor = SDL_CreateSystemCursor(id); if (!cursor) log::warning() << "Failed to create system cursor: " << SDL_GetError(); return cursor; } struct system_cursor_provider_impl : cursor_provider { system_cursor_provider_impl() { arrow_.cursor.reset(create_system_cursor(SDL_SYSTEM_CURSOR_ARROW)); beam_.cursor.reset(create_system_cursor(SDL_SYSTEM_CURSOR_IBEAM)); hand_.cursor.reset(create_system_cursor(SDL_SYSTEM_CURSOR_HAND)); } cursor const & arrow() const override { return arrow_; } cursor const & beam() const override { return beam_; } cursor const & hand() const override { return hand_; } private: cursor arrow_; cursor beam_; cursor hand_; }; } std::unique_ptr system_cursor_provider() { return std::make_unique(); } static std::unique_ptr current_provider; std::unique_ptr set_cursor_provider(std::unique_ptr new_provider) { std::swap(current_provider, new_provider); return new_provider; } cursor_provider const * get_cursor_provider() { static system_cursor_provider_impl const fallback; if (!current_provider) return &fallback; return current_provider.get(); } void set_cursor(cursor const & c) { SDL_SetCursor(c.cursor.get()); } }