src/video/cocoa/SDL_cocoamouse.m
author Sam Lantinga <slouken@libsdl.org>
Sat, 02 Mar 2013 20:44:16 -0800
changeset 6950 1ddb72193079
parent 6885 700f1b25f77f
child 7037 3fedf1f25b94
permissions -rw-r--r--
Added a mouse ID to the mouse events, which set to the special value SDL_TOUCH_MOUSEID for mouse events simulated by touch input.
     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_cocoavideo.h"
    28 
    29 #include "../../events/SDL_mouse_c.h"
    30 
    31 
    32 static SDL_Cursor *
    33 Cocoa_CreateDefaultCursor()
    34 {
    35     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    36     NSCursor *nscursor;
    37     SDL_Cursor *cursor = NULL;
    38 
    39     nscursor = [NSCursor arrowCursor];
    40 
    41     if (nscursor) {
    42         cursor = SDL_calloc(1, sizeof(*cursor));
    43         if (cursor) {
    44             cursor->driverdata = nscursor;
    45             [nscursor retain];
    46         }
    47     }
    48 
    49     [pool release];
    50 
    51     return cursor;
    52 }
    53 
    54 static SDL_Cursor *
    55 Cocoa_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
    56 {
    57     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    58     NSImage *nsimage;
    59     NSCursor *nscursor = NULL;
    60     SDL_Cursor *cursor = NULL;
    61 
    62     nsimage = Cocoa_CreateImage(surface);
    63     if (nsimage) {
    64         nscursor = [[NSCursor alloc] initWithImage: nsimage hotSpot: NSMakePoint(hot_x, hot_y)];
    65     }
    66 
    67     if (nscursor) {
    68         cursor = SDL_calloc(1, sizeof(*cursor));
    69         if (cursor) {
    70             cursor->driverdata = nscursor;
    71         }
    72     }
    73 
    74     [pool release];
    75 
    76     return cursor;
    77 }
    78 
    79 static SDL_Cursor *
    80 Cocoa_CreateSystemCursor(SDL_SystemCursor id)
    81 {
    82     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    83     NSCursor *nscursor = NULL;
    84     SDL_Cursor *cursor = NULL;
    85 
    86     switch(id)
    87     {
    88     case SDL_SYSTEM_CURSOR_ARROW:
    89         nscursor = [NSCursor arrowCursor];
    90         break;
    91     case SDL_SYSTEM_CURSOR_IBEAM:
    92         nscursor = [NSCursor IBeamCursor];
    93         break;
    94     case SDL_SYSTEM_CURSOR_WAIT:
    95         nscursor = [NSCursor arrowCursor];
    96         break;
    97     case SDL_SYSTEM_CURSOR_CROSSHAIR:
    98         nscursor = [NSCursor crosshairCursor];
    99         break;
   100     case SDL_SYSTEM_CURSOR_WAITARROW:
   101         nscursor = [NSCursor arrowCursor];
   102         break;
   103     case SDL_SYSTEM_CURSOR_SIZENWSE:
   104     case SDL_SYSTEM_CURSOR_SIZENESW:
   105         nscursor = [NSCursor closedHandCursor];
   106         break;
   107     case SDL_SYSTEM_CURSOR_SIZEWE:
   108         nscursor = [NSCursor resizeLeftRightCursor];
   109         break;
   110     case SDL_SYSTEM_CURSOR_SIZENS:
   111         nscursor = [NSCursor resizeUpDownCursor];
   112         break;
   113     case SDL_SYSTEM_CURSOR_SIZEALL:
   114         nscursor = [NSCursor closedHandCursor];
   115         break;
   116     case SDL_SYSTEM_CURSOR_NO:
   117         nscursor = [NSCursor operationNotAllowedCursor];
   118         break;
   119     case SDL_SYSTEM_CURSOR_HAND:
   120         nscursor = [NSCursor pointingHandCursor];
   121         break;
   122     default:
   123         SDL_assert(!"Unknown system cursor");
   124         return NULL;
   125     }
   126 
   127     if (nscursor) {
   128         cursor = SDL_calloc(1, sizeof(*cursor));
   129         if (cursor) {
   130             // We'll free it later, so retain it here
   131             [nscursor retain];
   132             cursor->driverdata = nscursor;
   133         }
   134     }
   135 
   136     [pool release];
   137 
   138     return cursor;
   139 }
   140 
   141 static void
   142 Cocoa_FreeCursor(SDL_Cursor * cursor)
   143 {
   144     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   145     NSCursor *nscursor = (NSCursor *)cursor->driverdata;
   146 
   147     [nscursor release];
   148     SDL_free(cursor);
   149 
   150     [pool release];
   151 }
   152 
   153 static int
   154 Cocoa_ShowCursor(SDL_Cursor * cursor)
   155 {
   156     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   157 
   158     if (cursor) {
   159         NSCursor *nscursor = (NSCursor *)cursor->driverdata;
   160 
   161         [nscursor set];
   162         [NSCursor unhide];
   163     } else {
   164         [NSCursor hide];
   165     }
   166 
   167     [pool release];
   168 
   169     return 0;
   170 }
   171 
   172 static void
   173 Cocoa_WarpMouse(SDL_Window * window, int x, int y)
   174 {
   175     CGPoint point;
   176 
   177     point.x = (float)window->x + x;
   178     point.y = (float)window->y + y;
   179     CGWarpMouseCursorPosition(point);
   180 }
   181 
   182 static int
   183 Cocoa_SetRelativeMouseMode(SDL_bool enabled)
   184 {
   185     CGError result;
   186 
   187     if (enabled) {
   188         result = CGAssociateMouseAndMouseCursorPosition(NO);
   189     } else {
   190         result = CGAssociateMouseAndMouseCursorPosition(YES);
   191     }
   192     if (result != kCGErrorSuccess) {
   193         SDL_SetError("CGAssociateMouseAndMouseCursorPosition() failed");
   194         return -1;
   195     }
   196     return 0;
   197 }
   198 
   199 void
   200 Cocoa_InitMouse(_THIS)
   201 {
   202     SDL_Mouse *mouse = SDL_GetMouse();
   203 
   204     mouse->CreateCursor = Cocoa_CreateCursor;
   205     mouse->CreateSystemCursor = Cocoa_CreateSystemCursor;
   206     mouse->ShowCursor = Cocoa_ShowCursor;
   207     mouse->FreeCursor = Cocoa_FreeCursor;
   208     mouse->WarpMouse = Cocoa_WarpMouse;
   209     mouse->SetRelativeMouseMode = Cocoa_SetRelativeMouseMode;
   210 
   211     SDL_SetDefaultCursor(Cocoa_CreateDefaultCursor());
   212 }
   213 
   214 void
   215 Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
   216 {
   217     SDL_Mouse *mouse = SDL_GetMouse();
   218 
   219     if (mouse->relative_mode &&
   220         ([event type] == NSMouseMoved ||
   221          [event type] == NSLeftMouseDragged ||
   222          [event type] == NSRightMouseDragged ||
   223          [event type] == NSOtherMouseDragged)) {
   224         float x = [event deltaX];
   225         float y = [event deltaY];
   226         SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, (int)x, (int)y);
   227     }
   228 }
   229 
   230 void
   231 Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
   232 {
   233     SDL_Mouse *mouse = SDL_GetMouse();
   234 
   235     float x = [event deltaX];
   236     float y = [event deltaY];
   237 
   238     if (x > 0) {
   239         x += 0.9f;
   240     } else if (x < 0) {
   241         x -= 0.9f;
   242     }
   243     if (y > 0) {
   244         y += 0.9f;
   245     } else if (y < 0) {
   246         y -= 0.9f;
   247     }
   248     SDL_SendMouseWheel(window, mouse->mouseID, (int)x, (int)y);
   249 }
   250 
   251 void
   252 Cocoa_QuitMouse(_THIS)
   253 {
   254 }
   255 
   256 #endif /* SDL_VIDEO_DRIVER_COCOA */
   257 
   258 /* vi: set ts=4 sw=4 expandtab: */