zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_cocoamouse.m
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_COCOA
24 
25 #include "SDL_assert.h"
26 #include "SDL_events.h"
27 #include "SDL_cocoamouse.h"
28 #include "SDL_cocoamousetap.h"
29 
30 #include "../../events/SDL_mouse_c.h"
31 
32 @implementation NSCursor (InvisibleCursor)
33 + (NSCursor *)invisibleCursor
34 {
35  static NSCursor *invisibleCursor = NULL;
36  if (!invisibleCursor) {
37  /* RAW 16x16 transparent GIF */
38  static unsigned char cursorBytes[] = {
39  0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80,
40  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xF9, 0x04,
41  0x01, 0x00, 0x00, 0x01, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x10,
42  0x00, 0x10, 0x00, 0x00, 0x02, 0x0E, 0x8C, 0x8F, 0xA9, 0xCB, 0xED,
43  0x0F, 0xA3, 0x9C, 0xB4, 0xDA, 0x8B, 0xB3, 0x3E, 0x05, 0x00, 0x3B
44  };
45 
46  NSData *cursorData = [NSData dataWithBytesNoCopy:&cursorBytes[0]
47  length:sizeof(cursorBytes)
48  freeWhenDone:NO];
49  NSImage *cursorImage = [[[NSImage alloc] initWithData:cursorData] autorelease];
50  invisibleCursor = [[NSCursor alloc] initWithImage:cursorImage
51  hotSpot:NSZeroPoint];
52  }
53 
54  return invisibleCursor;
55 }
56 @end
57 
58 
59 static SDL_Cursor *
60 Cocoa_CreateDefaultCursor()
61 {
62  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
63  NSCursor *nscursor;
64  SDL_Cursor *cursor = NULL;
65 
66  nscursor = [NSCursor arrowCursor];
67 
68  if (nscursor) {
69  cursor = SDL_calloc(1, sizeof(*cursor));
70  if (cursor) {
71  cursor->driverdata = nscursor;
72  [nscursor retain];
73  }
74  }
75 
76  [pool release];
77 
78  return cursor;
79 }
80 
81 static SDL_Cursor *
82 Cocoa_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
83 {
84  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
85  NSImage *nsimage;
86  NSCursor *nscursor = NULL;
87  SDL_Cursor *cursor = NULL;
88 
89  nsimage = Cocoa_CreateImage(surface);
90  if (nsimage) {
91  nscursor = [[NSCursor alloc] initWithImage: nsimage hotSpot: NSMakePoint(hot_x, hot_y)];
92  }
93 
94  if (nscursor) {
95  cursor = SDL_calloc(1, sizeof(*cursor));
96  if (cursor) {
97  cursor->driverdata = nscursor;
98  } else {
99  [nscursor release];
100  }
101  }
102 
103  [pool release];
104 
105  return cursor;
106 }
107 
108 static SDL_Cursor *
109 Cocoa_CreateSystemCursor(SDL_SystemCursor id)
110 {
111  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
112  NSCursor *nscursor = NULL;
113  SDL_Cursor *cursor = NULL;
114 
115  switch(id)
116  {
118  nscursor = [NSCursor arrowCursor];
119  break;
121  nscursor = [NSCursor IBeamCursor];
122  break;
124  nscursor = [NSCursor arrowCursor];
125  break;
127  nscursor = [NSCursor crosshairCursor];
128  break;
130  nscursor = [NSCursor arrowCursor];
131  break;
134  nscursor = [NSCursor closedHandCursor];
135  break;
137  nscursor = [NSCursor resizeLeftRightCursor];
138  break;
140  nscursor = [NSCursor resizeUpDownCursor];
141  break;
143  nscursor = [NSCursor closedHandCursor];
144  break;
146  nscursor = [NSCursor operationNotAllowedCursor];
147  break;
149  nscursor = [NSCursor pointingHandCursor];
150  break;
151  default:
152  SDL_assert(!"Unknown system cursor");
153  return NULL;
154  }
155 
156  if (nscursor) {
157  cursor = SDL_calloc(1, sizeof(*cursor));
158  if (cursor) {
159  /* We'll free it later, so retain it here */
160  [nscursor retain];
161  cursor->driverdata = nscursor;
162  }
163  }
164 
165  [pool release];
166 
167  return cursor;
168 }
169 
170 static void
171 Cocoa_FreeCursor(SDL_Cursor * cursor)
172 {
173  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
174  NSCursor *nscursor = (NSCursor *)cursor->driverdata;
175 
176  [nscursor release];
177  SDL_free(cursor);
178 
179  [pool release];
180 }
181 
182 static int
183 Cocoa_ShowCursor(SDL_Cursor * cursor)
184 {
185  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
186 
188  SDL_Window *window = (device ? device->windows : NULL);
189  for (; window != NULL; window = window->next) {
190  SDL_WindowData *driverdata = (SDL_WindowData *)window->driverdata;
191  if (driverdata) {
192  [driverdata->nswindow performSelectorOnMainThread:@selector(invalidateCursorRectsForView:)
193  withObject:[driverdata->nswindow contentView]
194  waitUntilDone:NO];
195  }
196  }
197 
198  [pool release];
199 
200  return 0;
201 }
202 
203 static void
204 Cocoa_WarpMouse(SDL_Window * window, int x, int y)
205 {
206  SDL_Mouse *mouse = SDL_GetMouse();
207  CGPoint point = CGPointMake(x, y);
208 
209  if (!(window->flags & SDL_WINDOW_FULLSCREEN))
210  {
211  point.x += window->x;
212  point.y += window->y;
213  }
214 
215  {
216  /* This makes Cocoa_HandleMouseEvent ignore this delta in the next
217  * movement event.
218  */
219  SDL_MouseData *driverdata = (SDL_MouseData*)mouse->driverdata;
220  NSPoint location = [NSEvent mouseLocation];
221  driverdata->deltaXOffset = location.x - point.x;
222  driverdata->deltaYOffset = point.y - location.y;
223  }
224 
225  /* According to the docs, this was deprecated in 10.6, but it's still
226  * around. The substitute requires a CGEventSource, but I'm not entirely
227  * sure how we'd procure the right one for this event.
228  */
229  CGSetLocalEventsSuppressionInterval(0.0);
230  CGWarpMouseCursorPosition(point);
231  CGSetLocalEventsSuppressionInterval(0.25);
232 
233  if (!mouse->relative_mode) {
234  /* CGWarpMouseCursorPosition doesn't generate a window event, unlike our
235  * other implementations' APIs.
236  */
237  SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
238  }
239 }
240 
241 static int
242 Cocoa_SetRelativeMouseMode(SDL_bool enabled)
243 {
244  CGError result;
245 
246  if (enabled) {
247  result = CGAssociateMouseAndMouseCursorPosition(NO);
248  } else {
249  result = CGAssociateMouseAndMouseCursorPosition(YES);
250  }
251  if (result != kCGErrorSuccess) {
252  return SDL_SetError("CGAssociateMouseAndMouseCursorPosition() failed");
253  }
254  return 0;
255 }
256 
257 void
259 {
260  SDL_Mouse *mouse = SDL_GetMouse();
261 
262  mouse->driverdata = SDL_calloc(1, sizeof(SDL_MouseData));
263 
264  mouse->CreateCursor = Cocoa_CreateCursor;
265  mouse->CreateSystemCursor = Cocoa_CreateSystemCursor;
266  mouse->ShowCursor = Cocoa_ShowCursor;
267  mouse->FreeCursor = Cocoa_FreeCursor;
268  mouse->WarpMouse = Cocoa_WarpMouse;
269  mouse->SetRelativeMouseMode = Cocoa_SetRelativeMouseMode;
270 
271  SDL_SetDefaultCursor(Cocoa_CreateDefaultCursor());
272 
274 }
275 
276 void
278 {
279  SDL_Mouse *mouse = SDL_GetMouse();
280 
281  if (mouse->relative_mode &&
282  ([event type] == NSMouseMoved ||
283  [event type] == NSLeftMouseDragged ||
284  [event type] == NSRightMouseDragged ||
285  [event type] == NSOtherMouseDragged)) {
286  SDL_MouseData *driverdata = (SDL_MouseData*)mouse->driverdata;
287  float x = [event deltaX] + driverdata->deltaXOffset;
288  float y = [event deltaY] + driverdata->deltaYOffset;
289  driverdata->deltaXOffset = driverdata->deltaYOffset = 0;
290 
291  SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, (int)x, (int)y);
292  }
293 }
294 
295 void
296 Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
297 {
298  SDL_Mouse *mouse = SDL_GetMouse();
299 
300  float x = [event deltaX];
301  float y = [event deltaY];
302 
303  if (x > 0) {
304  x += 0.9f;
305  } else if (x < 0) {
306  x -= 0.9f;
307  }
308  if (y > 0) {
309  y += 0.9f;
310  } else if (y < 0) {
311  y -= 0.9f;
312  }
313  SDL_SendMouseWheel(window, mouse->mouseID, (int)x, (int)y);
314 }
315 
316 void
318 {
319  SDL_Mouse *mouse = SDL_GetMouse();
320  if (mouse) {
321  if (mouse->driverdata) {
323  }
324 
325  SDL_free(mouse->driverdata);
326  }
327 }
328 
329 #endif /* SDL_VIDEO_DRIVER_COCOA */
330 
331 /* vi: set ts=4 sw=4 expandtab: */
SDL_Window * next
Definition: SDL_sysvideo.h:102
void Cocoa_InitMouse(_THIS)
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:62
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
#define NULL
Definition: ftobjs.h:61
GLclampf f
Definition: glew.h:3390
GLint location
Definition: gl2ext.h:1164
SDL_Window * focus
Definition: SDL_mouse_c.h:61
SDL_bool
Definition: SDL_stdinc.h:116
GLenum GLsizei const GLuint GLboolean enabled
Definition: glew.h:2538
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)
if(!yyg->yy_init)
SDL_MouseID mouseID
Definition: SDL_mouse_c.h:60
void(* FreeCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:51
void Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata)
GLuint64EXT * result
Definition: glew.h:12708
NSImage * Cocoa_CreateImage(SDL_Surface *surface)
SDL_Cursor *(* CreateCursor)(SDL_Surface *surface, int hot_x, int hot_y)
Definition: SDL_mouse_c.h:39
int
Definition: SDL_systhread.c:37
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
Definition: SDL_mouse.c:178
void Cocoa_QuitMouse(_THIS)
#define _THIS
int(* ShowCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:45
SDL_bool relative_mode
Definition: SDL_mouse_c.h:68
SDL_SystemCursor
Cursor types for SDL_CreateSystemCursor.
Definition: SDL_mouse.h:46
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
int(* SetRelativeMouseMode)(SDL_bool enabled)
Definition: SDL_mouse_c.h:57
void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
SDL_Window * windows
Definition: SDL_sysvideo.h:266
void Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
void SDL_SetDefaultCursor(SDL_Cursor *cursor)
Definition: SDL_mouse.c:51
#define SDL_assert(condition)
Definition: SDL_assert.h:159
EGLSurface EGLint EGLint y
Definition: eglext.h:293
int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, int x, int y)
Definition: SDL_mouse.c:332
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:548
void * driverdata
Definition: SDL_sysvideo.h:99
void * driverdata
Definition: SDL_mouse_c.h:78
Uint32 flags
Definition: SDL_sysvideo.h:81
void * driverdata
Definition: SDL_mouse_c.h:33
SDL_Cursor *(* CreateSystemCursor)(SDL_SystemCursor id)
Definition: SDL_mouse_c.h:42
void Cocoa_InitMouseEventTap(SDL_MouseData *driverdata)
void(* WarpMouse)(SDL_Window *window, int x, int y)
Definition: SDL_mouse_c.h:54
cl_event event
Definition: glew.h:3556