1/**
2 * Copyright (c) 2006-2023 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20
21// LOVE
22#include "Cursor.h"
23#include "common/config.h"
24
25namespace love
26{
27namespace mouse
28{
29namespace sdl
30{
31
32Cursor::Cursor(image::ImageData *data, int hotx, int hoty)
33 : cursor(nullptr)
34 , type(CURSORTYPE_IMAGE)
35 , systemType(CURSOR_MAX_ENUM)
36{
37 Uint32 rmask, gmask, bmask, amask;
38#ifdef LOVE_BIG_ENDIAN
39 rmask = 0xFF000000;
40 gmask = 0x00FF0000;
41 bmask = 0x0000FF00;
42 amask = 0x000000FF;
43#else
44 rmask = 0x000000FF;
45 gmask = 0x0000FF00;
46 bmask = 0x00FF0000;
47 amask = 0xFF000000;
48#endif
49
50 int w = data->getWidth();
51 int h = data->getHeight();
52 int pitch = w * 4;
53
54 SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(data->getData(), w, h, 32, pitch, rmask, gmask, bmask, amask);
55 if (!surface)
56 throw love::Exception("Cannot create cursor: out of memory!");
57
58 cursor = SDL_CreateColorCursor(surface, hotx, hoty);
59 SDL_FreeSurface(surface);
60
61 if (!cursor)
62 throw love::Exception("Cannot create cursor: %s", SDL_GetError());
63}
64
65Cursor::Cursor(mouse::Cursor::SystemCursor cursortype)
66 : cursor(nullptr)
67 , type(CURSORTYPE_SYSTEM)
68 , systemType(cursortype)
69{
70 SDL_SystemCursor sdlcursortype;
71
72 if (systemCursors.find(cursortype, sdlcursortype))
73 cursor = SDL_CreateSystemCursor(sdlcursortype);
74 else
75 throw love::Exception("Cannot create system cursor: invalid type.");
76
77 if (!cursor)
78 throw love::Exception("Cannot create system cursor: %s", SDL_GetError());
79}
80
81Cursor::~Cursor()
82{
83 if (cursor)
84 SDL_FreeCursor(cursor);
85}
86
87void *Cursor::getHandle() const
88{
89 return cursor;
90}
91
92Cursor::CursorType Cursor::getType() const
93{
94 return type;
95}
96
97Cursor::SystemCursor Cursor::getSystemType() const
98{
99 return systemType;
100}
101
102EnumMap<Cursor::SystemCursor, SDL_SystemCursor, Cursor::CURSOR_MAX_ENUM>::Entry Cursor::systemCursorEntries[] =
103{
104 {Cursor::CURSOR_ARROW, SDL_SYSTEM_CURSOR_ARROW},
105 {Cursor::CURSOR_IBEAM, SDL_SYSTEM_CURSOR_IBEAM},
106 {Cursor::CURSOR_WAIT, SDL_SYSTEM_CURSOR_WAIT},
107 {Cursor::CURSOR_CROSSHAIR, SDL_SYSTEM_CURSOR_CROSSHAIR},
108 {Cursor::CURSOR_WAITARROW, SDL_SYSTEM_CURSOR_WAITARROW},
109 {Cursor::CURSOR_SIZENWSE, SDL_SYSTEM_CURSOR_SIZENWSE},
110 {Cursor::CURSOR_SIZENESW, SDL_SYSTEM_CURSOR_SIZENESW},
111 {Cursor::CURSOR_SIZEWE, SDL_SYSTEM_CURSOR_SIZEWE},
112 {Cursor::CURSOR_SIZENS, SDL_SYSTEM_CURSOR_SIZENS},
113 {Cursor::CURSOR_SIZEALL, SDL_SYSTEM_CURSOR_SIZEALL},
114 {Cursor::CURSOR_NO, SDL_SYSTEM_CURSOR_NO},
115 {Cursor::CURSOR_HAND, SDL_SYSTEM_CURSOR_HAND},
116};
117
118EnumMap<Cursor::SystemCursor, SDL_SystemCursor, Cursor::CURSOR_MAX_ENUM> Cursor::systemCursors(Cursor::systemCursorEntries, sizeof(Cursor::systemCursorEntries));
119
120} // sdl
121} // mouse
122} // love
123