FIFE
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cursor.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2013 by the FIFE team *
3  * http://www.fifengine.net *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 #if defined( WIN32 )
24 #include <windows.h>
25 #include <sdl.h>
26 #endif
27 
28 #if defined( __unix__ )
29 #include <X11/Xcursor/Xcursor.h>
30 #endif
31 
32 // 3rd party library includes
33 
34 // FIFE includes
35 // These includes are split up in two parts, separated by one empty line
36 // First block: files included from the FIFE root src directory
37 // Second block: files included from the same folder
38 #include "util/structures/rect.h"
39 #include "util/time/timemanager.h"
40 #include "util/log/logger.h"
41 #include "video/imagemanager.h"
42 
43 #include "animation.h"
44 #include "image.h"
45 #include "renderbackend.h"
46 #include "cursor.h"
47 
48 #if defined( WIN32 )
49 
50 // From SDL_sysmouse.c
51 struct WMcursor {
52  HCURSOR curs;
53 #ifndef _WIN32_WCE
54  Uint8 *ands;
55  Uint8 *xors;
56 #endif
57 };
58 
59 #endif
60 
61 #if defined( __unix__ )
62 
63 // Stops the compiler from confusing it with FIFE:Cursor
64 typedef Cursor XCursor;
65 
66 // From SDL_x11mouse.c
67 struct WMcursor {
68  Cursor x_cursor;
69 };
70 
71 #endif
72 
73 namespace FIFE {
77  static Logger _log(LM_GUI); //@todo We should have a log module for cursor
78 
79  Cursor::Cursor(RenderBackend* renderbackend):
80  m_cursor_id(NC_ARROW),
81  m_cursor_type(CURSOR_NATIVE),
82  m_drag_type(CURSOR_NONE),
83  m_native_cursor(NULL),
84  m_renderbackend(renderbackend),
85  m_animtime(0),
86  m_drag_animtime(0),
87  m_drag_offset_x(0),
88  m_drag_offset_y(0),
89  m_mx(0),
90  m_my(0),
91  m_timemanager(TimeManager::instance()),
92  m_invalidated(false) {
93  assert(m_timemanager);
95  }
96 
97  void Cursor::set(uint32_t cursor_id) {
99 
100  if (!SDL_ShowCursor(1)) {
101  SDL_PumpEvents();
102  }
103  setNativeCursor(cursor_id);
104 
107  }
108 
109  void Cursor::set(ImagePtr image) {
110  assert(image != 0);
111 
112  m_cursor_image = image;
114 
115  if (SDL_ShowCursor(0)) {
116  SDL_PumpEvents();
117  }
118 
121  }
122 
124  assert(anim != 0);
125 
126  m_cursor_animation = anim;
128 
129  if (SDL_ShowCursor(0)) {
130  SDL_PumpEvents();
131  }
133 
136  }
137 
138  void Cursor::setDrag(ImagePtr image, int32_t drag_offset_x, int32_t drag_offset_y) {
139  assert(image != 0);
140 
141  m_cursor_drag_image = image;
143  m_drag_offset_x = drag_offset_x;
144  m_drag_offset_y = drag_offset_y;
145 
147  }
148 
149  void Cursor::setDrag(AnimationPtr anim, int32_t drag_offset_x, int32_t drag_offset_y) {
150  assert(anim != 0);
151 
154  m_drag_offset_x = drag_offset_x;
155  m_drag_offset_y = drag_offset_y;
156 
158 
160  }
161 
164 
165  m_drag_animtime = 0;
166  m_drag_offset_x = 0;
167  m_drag_offset_y = 0;
168 
171  }
172 
174  m_mx = x;
175  m_my = y;
176  SDL_WarpMouse(m_mx, m_my);
177  }
178 
179  void Cursor::getPosition(int32_t* x, int32_t* y) {
180  *x = m_mx;
181  *y = m_my;
182  }
183 
185  if (m_native_cursor != NULL) {
186  SDL_free(m_native_cursor->wm_cursor);
187  m_native_cursor->wm_cursor = NULL;
188  SDL_FreeCursor(m_native_cursor);
189  m_native_cursor = NULL;
190 
191  m_invalidated = true;
192  }
193  }
194 
195  void Cursor::draw() {
196  if (m_invalidated) {
198  set(m_cursor_id);
199  }
200 
201  m_invalidated = false;
202  }
203 
204  SDL_GetMouseState(&m_mx, &m_my);
206  return;
207  }
208 
209  // render possible drag image
210  ImagePtr img;
211  if (m_drag_type == CURSOR_IMAGE) {
212  img = m_cursor_drag_image;
213  }
214  else if (m_drag_type == CURSOR_ANIMATION) {
217  }
218 
219  if (img != 0) {
220  Rect area(m_mx + m_drag_offset_x + img->getXShift(), m_my + m_drag_offset_y + img->getYShift(), img->getWidth(), img->getHeight());
221  m_renderbackend->pushClipArea(area, false);
222  img->render(area);
225  }
226 
227  ImagePtr img2;
228  // render possible cursor image
229  if (m_cursor_type == CURSOR_IMAGE) {
230  img2 = m_cursor_image;
231  }
232  else if (m_cursor_type == CURSOR_ANIMATION) {
233  int32_t animtime = (m_timemanager->getTime() - m_animtime) % m_cursor_animation->getDuration();
234  img2 = m_cursor_animation->getFrameByTimestamp(animtime);
235  }
236 
237  if (img2 != 0) {
238  Rect area(m_mx + img2->getXShift(), m_my + img2->getYShift(), img2->getWidth(), img2->getHeight());
239  m_renderbackend->pushClipArea(area, false);
240  img2->render(area);
243  }
244  }
245 
247 #if defined( WIN32 )
248  switch (cursor_id) {
249  case NC_ARROW:
250  return 32512; // IDC_ARROW;
251  case NC_IBEAM:
252  return 32513; // IDC_IBEAM;
253  case NC_WAIT:
254  return 32514; // IDC_WAIT;
255  case NC_CROSS:
256  return 32515; // IDC_CROSS;
257  case NC_UPARROW:
258  return 32516; // IDC_UPARROW;
259  case NC_RESIZESE:
260  return 32642; // IDC_SIZENWSE;
261  case NC_RESIZESW:
262  return 32643; // IDC_SIZENESW;
263  case NC_RESIZEE:
264  return 32644; // IDC_SIZEWE;
265  case NC_RESIZES:
266  return 32645; // IDC_SIZENS;
267  case NC_RESIZENW:
268  return 32642; // IDC_SIZENWSE;
269  case NC_RESIZENE:
270  return 32643; // IDC_SIZENESW;
271  case NC_RESIZEW:
272  return 32644; // IDC_SIZEWE;
273  case NC_RESIZEN:
274  return 32645; // IDC_SIZENS;
275  case NC_RESIZEALL:
276  return 32646; // IDC_SIZEALL;
277  case NC_NO:
278  return 32648; // IDC_NO;
279  case NC_HAND:
280  return 32649; // IDC_HAND;
281  case NC_APPSTARTING:
282  return 32650; // IDC_APPSTARTING;
283  case NC_HELP:
284  return 32651; // IDC_HELP;
285  default:
286  break;
287  }
288 
289 #elif defined( __unix__ )
290  switch (cursor_id) {
291  case NC_ARROW:
292  return 68;
293  case NC_IBEAM:
294  return 152;
295  case NC_WAIT:
296  return 150;
297  case NC_CROSS:
298  return 130;
299  case NC_UPARROW:
300  return 22;
301  case NC_RESIZESE:
302  return 14;
303  case NC_RESIZESW:
304  return 12;
305  case NC_RESIZEE:
306  return 96;
307  case NC_RESIZES:
308  return 16;
309  case NC_RESIZENW:
310  return 134;
311  case NC_RESIZENE:
312  return 136;
313  case NC_RESIZEW:
314  return 70;
315  case NC_RESIZEN:
316  return 138;
317  case NC_RESIZEALL:
318  return 52;
319  case NC_NO:
320  return 0;
321  case NC_HAND:
322  return 60;
323  case NC_APPSTARTING:
324  return 150;
325  case NC_HELP:
326  return 92;
327  default:
328  break;
329  }
330 #endif
331  return cursor_id;
332  }
333 
335 #if defined( WIN32 ) || defined(__unix__)
336  // Check if a value in NativeCursors is requested
337  cursor_id = getNativeId(cursor_id);
338 
339  // Load cursor
340 #if defined( __unix__ )
341  static Display* dsp = XOpenDisplay(NULL);
342  XCursor xCursor = XcursorShapeLoadCursor(dsp, cursor_id);
343  if (xCursor == 0) {
344  if (m_native_cursor != NULL) {
345  SDL_FreeCursor(m_native_cursor);
346  m_native_cursor = NULL;
347  }
348  FL_WARN(_log, "Cursor: No cursor matching cursor_id was found.");
349  return;
350  }
351 #elif defined( WIN32 )
352  // Load native cursor
353  HCURSOR hIcon = LoadCursor(NULL, MAKEINTRESOURCE(cursor_id));
354  if (hIcon == static_cast<HCURSOR>(0)) {
355  if (m_native_cursor != NULL) {
356  SDL_FreeCursor(m_native_cursor);
357  m_native_cursor = NULL;
358  }
359  FL_WARN(_log, "Cursor: No cursor matching cursor_id was found.");
360  return;
361  }
362 #endif
363 
364  WMcursor *cursor;
365  SDL_Cursor *curs2;
366 
367  // Allocate memory. Use SDL_FreeCursor to free cursor memory
368  cursor = (WMcursor *)SDL_malloc(sizeof(*cursor));
369  curs2 = (SDL_Cursor *)SDL_malloc(sizeof *curs2);
370 
371  //-- Set up some default values --
372  curs2->wm_cursor = cursor;
373  curs2->data = NULL;
374  curs2->mask = NULL;
375  curs2->save[0] = NULL;
376  curs2->save[1] = NULL;
377  curs2->area.x = 0;
378  curs2->area.y = 0;
379  curs2->area.w = 32;
380  curs2->area.h = 32;
381  curs2->hot_x = 0;
382  curs2->hot_y = 0;
383 
384 #if defined(WIN32)
385  cursor->curs = hIcon;
386 #ifndef _WIN32_WCE
387  cursor->ands = NULL;
388  cursor->xors = NULL;
389 #endif
390 
391  // Get hot spot
392  ICONINFO iconinfo;
393  if (GetIconInfo(hIcon, &iconinfo)) {
394  curs2->hot_x = static_cast<Sint16>(iconinfo.xHotspot);
395  curs2->hot_y = static_cast<Sint16>(iconinfo.yHotspot);
396  }
397 
398 #elif defined(__unix__)
399  cursor->x_cursor = xCursor;
400  XSync(dsp, false);
401 #endif
402 
403  m_native_cursor = curs2;
404  SDL_SetCursor(curs2);
405 
406 #endif // WIN32 || __unix__
407  }
408 }
Definition: modules.h:41
#define FL_WARN(logger, msg)
Definition: logger.h:72
uint32_t m_animtime
Definition: cursor.h:210
Abstract interface for all the renderbackends.
Definition: renderbackend.h:92
MouseCursorType m_cursor_type
Definition: cursor.h:197
MouseCursorType m_drag_type
Definition: cursor.h:198
TimeManager * m_timemanager
Definition: cursor.h:217
int32_t m_drag_offset_x
Definition: cursor.h:213
int32_t getXShift() const
Definition: image.h:117
void reset(T *ptr=0)
reset this pointer to a null shared pointer this can be used to lower the reference count of the shar...
Definition: sharedptr.h:164
ImagePtr m_cursor_image
Definition: cursor.h:202
uint32_t getDuration() const
Gets the total duration for the whole animation.
Definition: animation.h:129
int32_t getYShift() const
Definition: image.h:123
static Logger _log(LM_AUDIO)
int32_t m_my
Definition: cursor.h:216
ImagePtr m_cursor_drag_image
Definition: cursor.h:203
void setDrag(ImagePtr image, int32_t drag_offset_x=0, int32_t drag_offset_y=0)
Sets the current drag image cursor.
Definition: cursor.cpp:138
uint32_t getHeight() const
Definition: image.cpp:155
AnimationPtr m_cursor_animation
Definition: cursor.h:205
bool m_invalidated
Definition: cursor.h:219
void setNativeCursor(uint32_t cursor_id)
Sets the cursor to a native type.
Definition: cursor.cpp:334
void invalidate()
Definition: cursor.cpp:184
uint32_t getTime() const
Get the time.
ImagePtr getFrameByTimestamp(uint32_t timestamp)
Gets the frame image that matches the given timestamp.
Definition: animation.cpp:99
virtual void draw()
draws cursor on screen
Definition: cursor.cpp:195
void pushClipArea(const Rect &cliparea, bool clear=true)
Pushes clip area to clip stack Clip areas define which area is drawn on screen.
int32_t m_drag_offset_y
Definition: cursor.h:214
uint32_t m_drag_animtime
Definition: cursor.h:211
void popClipArea()
Pops clip area from clip stack.
uint32_t getWidth() const
Definition: image.cpp:146
uint32_t m_cursor_id
Definition: cursor.h:196
Time Manager.
Definition: timemanager.h:50
void set(uint32_t cursor_id=0)
Sets the current mouse cursor.
Definition: cursor.cpp:97
void resetDrag()
Resets the cursor drag type to CURSOR_NONE.
Definition: cursor.cpp:162
uint32_t getNativeId(uint32_t cursor_id)
To get some consistancy between platforms, this function checks if cursor_id matches any of the value...
Definition: cursor.cpp:246
AnimationPtr m_cursor_drag_animation
Definition: cursor.h:206
virtual void render(const Rect &rect, uint8_t alpha=255, uint8_t const *rgb=0)=0
Renders itself to the current render target (main screen or attached destination image) at the rectan...
Cursor(RenderBackend *renderbackend)
Constructor.
Definition: cursor.cpp:79
void getPosition(int32_t *x, int32_t *y)
Get the current mouse position.
Definition: cursor.cpp:179
virtual void renderVertexArrays()=0
Render the Vertex Arrays, only for primitives (points, lines,...)
int32_t m_mx
Definition: cursor.h:215
RenderBackend * m_renderbackend
Definition: cursor.h:208
unsigned int uint32_t
Definition: core.h:40
SDL_Cursor * m_native_cursor
Definition: cursor.h:200
void setPosition(uint32_t x, uint32_t y)
Set the mouse position.
Definition: cursor.cpp:173