zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_windowsmouse.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22 
23 #if SDL_VIDEO_DRIVER_WINDOWS
24 
25 #include "SDL_assert.h"
26 #include "SDL_windowsvideo.h"
27 
28 #include "../../events/SDL_mouse_c.h"
29 
30 
31 HCURSOR SDL_cursor = NULL;
32 
33 
34 static SDL_Cursor *
35 WIN_CreateDefaultCursor()
36 {
37  SDL_Cursor *cursor;
38 
39  cursor = SDL_calloc(1, sizeof(*cursor));
40  if (cursor) {
41  cursor->driverdata = LoadCursor(NULL, IDC_ARROW);
42  } else {
44  }
45 
46  return cursor;
47 }
48 
49 static SDL_Cursor *
50 WIN_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
51 {
52  /* msdn says cursor mask has to be padded out to word alignment. Not sure
53  if that means machine word or WORD, but this handles either case. */
54  const size_t pad = (sizeof (size_t) * 8); /* 32 or 64, or whatever. */
55  SDL_Cursor *cursor;
56  HICON hicon;
57  HDC hdc;
58  BITMAPV4HEADER bmh;
59  LPVOID pixels;
60  LPVOID maskbits;
61  size_t maskbitslen;
62  ICONINFO ii;
63 
64  SDL_zero(bmh);
65  bmh.bV4Size = sizeof(bmh);
66  bmh.bV4Width = surface->w;
67  bmh.bV4Height = -surface->h; /* Invert the image */
68  bmh.bV4Planes = 1;
69  bmh.bV4BitCount = 32;
70  bmh.bV4V4Compression = BI_BITFIELDS;
71  bmh.bV4AlphaMask = 0xFF000000;
72  bmh.bV4RedMask = 0x00FF0000;
73  bmh.bV4GreenMask = 0x0000FF00;
74  bmh.bV4BlueMask = 0x000000FF;
75 
76  maskbitslen = ((surface->w + (pad - (surface->w % pad))) / 8) * surface->h;
77  maskbits = SDL_stack_alloc(Uint8,maskbitslen);
78  if (maskbits == NULL) {
80  return NULL;
81  }
82 
83  /* AND the cursor against full bits: no change. We already have alpha. */
84  SDL_memset(maskbits, 0xFF, maskbitslen);
85 
86  hdc = GetDC(NULL);
87  SDL_zero(ii);
88  ii.fIcon = FALSE;
89  ii.xHotspot = (DWORD)hot_x;
90  ii.yHotspot = (DWORD)hot_y;
91  ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO*)&bmh, DIB_RGB_COLORS, &pixels, NULL, 0);
92  ii.hbmMask = CreateBitmap(surface->w, surface->h, 1, 1, maskbits);
93  ReleaseDC(NULL, hdc);
94  SDL_stack_free(maskbits);
95 
97  SDL_assert(surface->pitch == surface->w * 4);
98  SDL_memcpy(pixels, surface->pixels, surface->h * surface->pitch);
99 
100  hicon = CreateIconIndirect(&ii);
101 
102  DeleteObject(ii.hbmColor);
103  DeleteObject(ii.hbmMask);
104 
105  if (!hicon) {
106  WIN_SetError("CreateIconIndirect()");
107  return NULL;
108  }
109 
110  cursor = SDL_calloc(1, sizeof(*cursor));
111  if (cursor) {
112  cursor->driverdata = hicon;
113  } else {
114  DestroyIcon(hicon);
115  SDL_OutOfMemory();
116  }
117 
118  return cursor;
119 }
120 
121 static SDL_Cursor *
122 WIN_CreateSystemCursor(SDL_SystemCursor id)
123 {
124  SDL_Cursor *cursor;
125  LPCTSTR name;
126 
127  switch(id)
128  {
129  default:
130  SDL_assert(0);
131  return NULL;
132  case SDL_SYSTEM_CURSOR_ARROW: name = IDC_ARROW; break;
133  case SDL_SYSTEM_CURSOR_IBEAM: name = IDC_IBEAM; break;
134  case SDL_SYSTEM_CURSOR_WAIT: name = IDC_WAIT; break;
135  case SDL_SYSTEM_CURSOR_CROSSHAIR: name = IDC_CROSS; break;
136  case SDL_SYSTEM_CURSOR_WAITARROW: name = IDC_WAIT; break;
137  case SDL_SYSTEM_CURSOR_SIZENWSE: name = IDC_SIZENWSE; break;
138  case SDL_SYSTEM_CURSOR_SIZENESW: name = IDC_SIZENESW; break;
139  case SDL_SYSTEM_CURSOR_SIZEWE: name = IDC_SIZEWE; break;
140  case SDL_SYSTEM_CURSOR_SIZENS: name = IDC_SIZENS; break;
141  case SDL_SYSTEM_CURSOR_SIZEALL: name = IDC_SIZEALL; break;
142  case SDL_SYSTEM_CURSOR_NO: name = IDC_NO; break;
143  case SDL_SYSTEM_CURSOR_HAND: name = IDC_HAND; break;
144  }
145 
146  cursor = SDL_calloc(1, sizeof(*cursor));
147  if (cursor) {
148  HICON hicon;
149 
150  hicon = LoadCursor(NULL, name);
151 
152  cursor->driverdata = hicon;
153  } else {
154  SDL_OutOfMemory();
155  }
156 
157  return cursor;
158 }
159 
160 static void
161 WIN_FreeCursor(SDL_Cursor * cursor)
162 {
163  HICON hicon = (HICON)cursor->driverdata;
164 
165  DestroyIcon(hicon);
166  SDL_free(cursor);
167 }
168 
169 static int
170 WIN_ShowCursor(SDL_Cursor * cursor)
171 {
172  if (cursor) {
173  SDL_cursor = (HCURSOR)cursor->driverdata;
174  } else {
175  SDL_cursor = NULL;
176  }
177  if (SDL_GetMouseFocus() != NULL) {
178  SetCursor(SDL_cursor);
179  }
180  return 0;
181 }
182 
183 static void
184 WIN_WarpMouse(SDL_Window * window, int x, int y)
185 {
186  HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
187  POINT pt;
188 
189  pt.x = x;
190  pt.y = y;
191  ClientToScreen(hwnd, &pt);
192  SetCursorPos(pt.x, pt.y);
193 }
194 
195 static int
196 WIN_SetRelativeMouseMode(SDL_bool enabled)
197 {
198  RAWINPUTDEVICE rawMouse = { 0x01, 0x02, 0, NULL }; /* Mouse: UsagePage = 1, Usage = 2 */
199  HWND hWnd;
200  hWnd = GetActiveWindow();
201 
202  rawMouse.hwndTarget = hWnd;
203  if(!enabled) {
204  rawMouse.dwFlags |= RIDEV_REMOVE;
205  rawMouse.hwndTarget = NULL;
206  }
207 
208 
209  /* (Un)register raw input for mice */
210  if(RegisterRawInputDevices(&rawMouse, 1, sizeof(RAWINPUTDEVICE)) == FALSE) {
211 
212  /* Only return an error when registering. If we unregister and fail, then
213  it's probably that we unregistered twice. That's OK. */
214  if(enabled) {
215  return SDL_Unsupported();
216  }
217  }
218 
219  if(enabled) {
220  LONG cx, cy;
221  RECT rect;
222  GetWindowRect(hWnd, &rect);
223 
224  cx = (rect.left + rect.right) / 2;
225  cy = (rect.top + rect.bottom) / 2;
226 
227  /* Make an absurdly small clip rect */
228  rect.left = cx-1;
229  rect.right = cx+1;
230  rect.top = cy-1;
231  rect.bottom = cy+1;
232 
233  ClipCursor(&rect);
234  }
235  else
236  ClipCursor(NULL);
237 
238  return 0;
239 }
240 
241 void
243 {
244  SDL_Mouse *mouse = SDL_GetMouse();
245 
246  mouse->CreateCursor = WIN_CreateCursor;
247  mouse->CreateSystemCursor = WIN_CreateSystemCursor;
248  mouse->ShowCursor = WIN_ShowCursor;
249  mouse->FreeCursor = WIN_FreeCursor;
250  mouse->WarpMouse = WIN_WarpMouse;
251  mouse->SetRelativeMouseMode = WIN_SetRelativeMouseMode;
252 
253  SDL_SetDefaultCursor(WIN_CreateDefaultCursor());
254 }
255 
256 void
258 {
259  SDL_Mouse *mouse = SDL_GetMouse();
260  if ( mouse->def_cursor ) {
261  SDL_free(mouse->def_cursor);
262  mouse->def_cursor = NULL;
263  mouse->cur_cursor = NULL;
264  }
265 }
266 
267 #endif /* SDL_VIDEO_DRIVER_WINDOWS */
268 
269 /* vi: set ts=4 sw=4 expandtab: */
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:62
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
#define NULL
Definition: ftobjs.h:61
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:227
SDL_bool
Definition: SDL_stdinc.h:116
GLenum GLsizei const GLuint GLboolean enabled
Definition: glew.h:2538
DECLSPEC SDL_Window *SDLCALL SDL_GetMouseFocus(void)
Get the window which currently has mouse focus.
Definition: SDL_mouse.c:68
EGLSurface EGLint x
Definition: eglext.h:293
EGLSurface surface
Definition: eglext.h:74
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
DECLSPEC void SDLCALL SDL_free(void *mem)
EGLImageKHR EGLint * name
Definition: eglext.h:284
typedef HDC(WINAPI *PFNWGLGETCURRENTREADDCARBPROC)(VOID)
void WIN_InitMouse(_THIS)
void(* FreeCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:51
SDL_Cursor *(* CreateCursor)(SDL_Surface *surface, int hot_x, int hot_y)
Definition: SDL_mouse_c.h:39
void * pixels
Definition: SDL_surface.h:75
#define _THIS
int(* ShowCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:45
DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len)
Definition: SDL_string.c:261
SDL_SystemCursor
Cursor types for SDL_CreateSystemCursor.
Definition: SDL_mouse.h:46
int(* SetRelativeMouseMode)(SDL_bool enabled)
Definition: SDL_mouse_c.h:57
void SDL_SetDefaultCursor(SDL_Cursor *cursor)
Definition: SDL_mouse.c:51
#define FALSE
Definition: ftobjs.h:57
void WIN_QuitMouse(_THIS)
#define BI_BITFIELDS
Definition: SDL_bmp.c:46
typedef LPVOID(WINAPI *PFNWGLCREATEIMAGEBUFFERI3DPROC)(HDC hDC
#define SDL_assert(condition)
Definition: SDL_assert.h:159
EGLSurface EGLint EGLint y
Definition: eglext.h:293
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_PixelFormat * format
Definition: SDL_surface.h:72
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl2ext.h:845
int WIN_SetError(const char *prefix)
DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len)
Definition: SDL_string.c:293
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:226
#define SDL_zero(x)
Definition: SDL_stdinc.h:254
void * driverdata
Definition: SDL_sysvideo.h:99
static SceCtrlData pad
SDL_Cursor * cur_cursor
Definition: SDL_mouse_c.h:74
HCURSOR SDL_cursor
void * driverdata
Definition: SDL_mouse_c.h:33
#define SDL_Unsupported()
Definition: SDL_error.h:53
SDL_Cursor *(* CreateSystemCursor)(SDL_SystemCursor id)
Definition: SDL_mouse_c.h:42
void(* WarpMouse)(SDL_Window *window, int x, int y)
Definition: SDL_mouse_c.h:54
unsigned int size_t
SDL_Cursor * def_cursor
Definition: SDL_mouse_c.h:73