1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef GRAPHICS_CURSORMAN_H 24 #define GRAPHICS_CURSORMAN_H 25 26 #include "common/scummsys.h" 27 #include "common/stack.h" 28 #include "common/singleton.h" 29 #include "graphics/cursor.h" 30 #include "graphics/pixelformat.h" 31 32 namespace Graphics { 33 34 class CursorManager : public Common::Singleton<CursorManager> { 35 public: 36 /** Query whether the mouse cursor is visible. */ 37 bool isVisible(); 38 39 /** 40 * Show or hide the mouse cursor. 41 * 42 * This function does not call OSystem::updateScreen, when visible is true. 43 * This fact might result in a non visible mouse cursor if the caller does 44 * not call OSystem::updateScreen itself after a showMouse(true) call. 45 * 46 * TODO: We might want to reconsider this behavior, it might be confusing 47 * for the user to call OSystem::updateScreen separately, on the other 48 * hand OSystem::updateScreen might as well display unwanted changes on 49 * the screen. Another alternative would be to let the backend worry 50 * about this on OSystem::showMouse call. 51 * 52 * @see OSystem::showMouse. 53 */ 54 bool showMouse(bool visible); 55 56 /** 57 * Push a new cursor onto the stack, and set it in the backend. A local 58 * copy will be made of the cursor data, so the original buffer can be 59 * safely freed afterwards. 60 * 61 * @param buf the new cursor data 62 * @param w the width 63 * @param h the height 64 * @param hotspotX the hotspot X coordinate 65 * @param hotspotY the hotspot Y coordinate 66 * @param keycolor the color value for the transparent color. This may not exceed 67 * the maximum color value as defined by format. 68 * @param dontScale Whether the cursor should never be scaled. An exception are high ppi displays, where the cursor 69 * would be too small to notice otherwise, these are allowed to scale the cursor anyway. 70 * @param format a pointer to the pixel format which the cursor graphic uses, 71 * CLUT8 will be used if this is NULL or not specified. 72 * @note It is ok for the buffer to be a NULL pointer. It is sometimes 73 * useful to push a "dummy" cursor and modify it later. The 74 * cursor will be added to the stack, but not to the backend. 75 */ 76 void pushCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL); 77 78 /** 79 * Pop a cursor from the stack, and restore the previous one to the 80 * backend. If there is no previous cursor, the cursor is hidden. 81 */ 82 void popCursor(); 83 84 /** 85 * Replace the current cursor on the stack. If the stack is empty, the 86 * cursor is pushed instead. It's a slightly more optimized way of 87 * popping the old cursor before pushing the new one. 88 * 89 * @param buf the new cursor data 90 * @param w the width 91 * @param h the height 92 * @param hotspotX the hotspot X coordinate 93 * @param hotspotY the hotspot Y coordinate 94 * @param keycolor the color value for the transparent color. This may not exceed 95 * the maximum color value as defined by format. 96 * @param dontScale Whether the cursor should never be scaled. An exception are high ppi displays, where the cursor 97 * would be too small to notice otherwise, these are allowed to scale the cursor anyway. 98 * @param format a pointer to the pixel format which the cursor graphic uses, 99 * CLUT8 will be used if this is NULL or not specified. 100 */ 101 void replaceCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL); 102 103 /** 104 * Replace the current cursor on the stack. If the stack is empty, the 105 * cursor is pushed instead. It's a slightly more optimized way of 106 * popping the old cursor before pushing the new one. 107 * 108 * @param cursor the new cursor 109 */ 110 void replaceCursor(const Graphics::Cursor *cursor); 111 112 /** 113 * Pop all of the cursors and cursor palettes from their respective stacks. 114 * The purpose is to ensure that all unecessary cursors are removed from the 115 * stack when returning to the launcher from an engine. 116 * 117 */ 118 void popAllCursors(); 119 120 /** 121 * Test whether cursor palettes are supported. 122 * 123 * This is just an convenience wrapper for checking for 124 * OSystem::kFeatureCursorPalette to be supported by OSystem. 125 * 126 * @see OSystem::kFeatureCursorPalette 127 * @see OSystem::hasFeature 128 */ 129 bool supportsCursorPalettes(); 130 131 /** 132 * Enable/Disable the current cursor palette. 133 * 134 * @param disable 135 */ 136 void disableCursorPalette(bool disable); 137 138 /** 139 * Push a new cursor palette onto the stack, and set it in the backend. 140 * The palette entries from 'start' till (start+num-1) will be replaced 141 * so a full palette updated is accomplished via start=0, num=256. 142 * 143 * The palette data is specified in the same interleaved RGB format as 144 * used by all backends. 145 * 146 * @param colors the new palette data, in interleaved RGB format 147 * @param start the first palette entry to be updated 148 * @param num the number of palette entries to be updated 149 * 150 * @note If num is zero, the cursor palette is disabled. 151 */ 152 void pushCursorPalette(const byte *colors, uint start, uint num); 153 154 /** 155 * Pop a cursor palette from the stack, and restore the previous one to 156 * the backend. If there is no previous palette, the cursor palette is 157 * disabled instead. 158 */ 159 void popCursorPalette(); 160 161 /** 162 * Replace the current cursor palette on the stack. If the stack is 163 * empty, the palette is pushed instead. It's a slightly more optimized 164 * way of popping the old palette before pushing the new one. 165 * 166 * @param colors the new palette data, in interleaved RGB format 167 * @param start the first palette entry to be updated 168 * @param num the number of palette entries to be updated 169 * 170 * @note If num is zero, the cursor palette is disabled. 171 */ 172 void replaceCursorPalette(const byte *colors, uint start, uint num); 173 174 void lock(bool locked); 175 private: 176 friend class Common::Singleton<SingletonBaseType>; 177 // Even though this is basically the default constructor we implement it 178 // ourselves, so it is private and thus there is no way to create this class 179 // except from the Singleton code. CursorManager()180 CursorManager() { 181 _locked = false; 182 } 183 ~CursorManager(); 184 185 struct Cursor { 186 byte *_data; 187 bool _visible; 188 uint _width; 189 uint _height; 190 int _hotspotX; 191 int _hotspotY; 192 uint32 _keycolor; 193 Graphics::PixelFormat _format; 194 bool _dontScale; 195 196 uint _size; 197 198 Cursor(const void *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL); 199 ~Cursor(); 200 }; 201 202 struct Palette { 203 byte *_data; 204 uint _start; 205 uint _num; 206 uint _size; 207 208 bool _disabled; 209 210 Palette(const byte *colors, uint start, uint num); 211 ~Palette(); 212 }; 213 Common::Stack<Cursor *> _cursorStack; 214 Common::Stack<Palette *> _cursorPaletteStack; 215 bool _locked; 216 }; 217 218 } // End of namespace Graphics 219 220 #define CursorMan (::Graphics::CursorManager::instance()) 221 222 #endif 223