1 /**
2 * Copyright (c) 2006-2019 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
25 namespace love
26 {
27 namespace mouse
28 {
29 namespace sdl
30 {
31
Cursor(image::ImageData * data,int hotx,int hoty)32 Cursor::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
Cursor(mouse::Cursor::SystemCursor cursortype)65 Cursor::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
~Cursor()81 Cursor::~Cursor()
82 {
83 if (cursor)
84 SDL_FreeCursor(cursor);
85 }
86
getHandle() const87 void *Cursor::getHandle() const
88 {
89 return cursor;
90 }
91
getType() const92 Cursor::CursorType Cursor::getType() const
93 {
94 return type;
95 }
96
getSystemType() const97 Cursor::SystemCursor Cursor::getSystemType() const
98 {
99 return systemType;
100 }
101
102 EnumMap<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
118 EnumMap<Cursor::SystemCursor, SDL_SystemCursor, Cursor::CURSOR_MAX_ENUM> Cursor::systemCursors(Cursor::systemCursorEntries, sizeof(Cursor::systemCursorEntries));
119
120 } // sdl
121 } // mouse
122 } // love
123