src/video/cocoa/SDL_cocoamouse.m
author Sam Lantinga <slouken@libsdl.org>
Mon, 19 Nov 2012 20:27:08 -0800
changeset 6676 4ff261ffaa42
parent 6301 e8a69c5378e7
child 6832 156e608ec4ef
permissions -rw-r--r--
Added a Cocoa implementation of SDL_CreateSystemCursor()
slouken@1931
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6138
     3
  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
slouken@1931
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@1931
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@1931
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@1931
    20
*/
slouken@1931
    21
#include "SDL_config.h"
slouken@1931
    22
slouken@6044
    23
#if SDL_VIDEO_DRIVER_COCOA
slouken@6044
    24
slouken@6676
    25
#include "SDL_assert.h"
slouken@3517
    26
#include "SDL_events.h"
slouken@1931
    27
#include "SDL_cocoavideo.h"
slouken@1931
    28
slouken@1931
    29
#include "../../events/SDL_mouse_c.h"
slouken@1931
    30
slouken@5376
    31
slouken@5376
    32
static SDL_Cursor *
slouken@5376
    33
Cocoa_CreateDefaultCursor()
slouken@5376
    34
{
slouken@5376
    35
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@5376
    36
    NSCursor *nscursor;
slouken@5376
    37
    SDL_Cursor *cursor = NULL;
slouken@5376
    38
slouken@5376
    39
    nscursor = [NSCursor arrowCursor];
slouken@5376
    40
slouken@5376
    41
    if (nscursor) {
slouken@5376
    42
        cursor = SDL_calloc(1, sizeof(*cursor));
slouken@5376
    43
        if (cursor) {
slouken@5376
    44
            cursor->driverdata = nscursor;
slouken@5376
    45
            [nscursor retain];
slouken@5376
    46
        }
slouken@5376
    47
    }
slouken@5376
    48
slouken@5376
    49
    [pool release];
slouken@5376
    50
slouken@5376
    51
    return cursor;
slouken@5376
    52
}
slouken@5376
    53
slouken@5376
    54
static SDL_Cursor *
slouken@5376
    55
Cocoa_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
slouken@5376
    56
{
slouken@5376
    57
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@5376
    58
    NSImage *nsimage;
slouken@5376
    59
    NSCursor *nscursor = NULL;
slouken@5376
    60
    SDL_Cursor *cursor = NULL;
slouken@5376
    61
slouken@5376
    62
    nsimage = Cocoa_CreateImage(surface);
slouken@5376
    63
    if (nsimage) {
slouken@5376
    64
        nscursor = [[NSCursor alloc] initWithImage: nsimage hotSpot: NSMakePoint(hot_x, hot_y)];
slouken@5376
    65
    }
slouken@5376
    66
slouken@5376
    67
    if (nscursor) {
slouken@5376
    68
        cursor = SDL_calloc(1, sizeof(*cursor));
slouken@5376
    69
        if (cursor) {
slouken@5376
    70
            cursor->driverdata = nscursor;
slouken@5376
    71
        }
slouken@5376
    72
    }
slouken@5376
    73
slouken@5376
    74
    [pool release];
slouken@5376
    75
slouken@5376
    76
    return cursor;
slouken@5376
    77
}
slouken@5376
    78
slouken@6676
    79
static SDL_Cursor *
slouken@6676
    80
Cocoa_CreateSystemCursor(SDL_SystemCursor id)
slouken@6676
    81
{
slouken@6676
    82
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@6676
    83
    NSCursor *nscursor = NULL;
slouken@6676
    84
    SDL_Cursor *cursor = NULL;
slouken@6676
    85
slouken@6676
    86
    switch(id)
slouken@6676
    87
    {
slouken@6676
    88
    case SDL_SYSTEM_CURSOR_ARROW:
slouken@6676
    89
        nscursor = [NSCursor arrowCursor];
slouken@6676
    90
        break;
slouken@6676
    91
    case SDL_SYSTEM_CURSOR_IBEAM:
slouken@6676
    92
        nscursor = [NSCursor IBeamCursor];
slouken@6676
    93
        break;
slouken@6676
    94
    case SDL_SYSTEM_CURSOR_WAIT:
slouken@6676
    95
        nscursor = [NSCursor arrowCursor];
slouken@6676
    96
        break;
slouken@6676
    97
    case SDL_SYSTEM_CURSOR_CROSSHAIR:
slouken@6676
    98
        nscursor = [NSCursor crosshairCursor];
slouken@6676
    99
        break;
slouken@6676
   100
    case SDL_SYSTEM_CURSOR_WAITARROW:
slouken@6676
   101
        nscursor = [NSCursor arrowCursor];
slouken@6676
   102
        break;
slouken@6676
   103
    case SDL_SYSTEM_CURSOR_SIZENWSE:
slouken@6676
   104
    case SDL_SYSTEM_CURSOR_SIZENESW:
slouken@6676
   105
        nscursor = [NSCursor closedHandCursor];
slouken@6676
   106
        break;
slouken@6676
   107
    case SDL_SYSTEM_CURSOR_SIZEWE:
slouken@6676
   108
        nscursor = [NSCursor resizeLeftRightCursor];
slouken@6676
   109
        break;
slouken@6676
   110
    case SDL_SYSTEM_CURSOR_SIZENS:
slouken@6676
   111
        nscursor = [NSCursor resizeUpDownCursor];
slouken@6676
   112
        break;
slouken@6676
   113
    case SDL_SYSTEM_CURSOR_SIZEALL:
slouken@6676
   114
        nscursor = [NSCursor closedHandCursor];
slouken@6676
   115
        break;
slouken@6676
   116
    case SDL_SYSTEM_CURSOR_NO:
slouken@6676
   117
        nscursor = [NSCursor operationNotAllowedCursor];
slouken@6676
   118
        break;
slouken@6676
   119
    case SDL_SYSTEM_CURSOR_HAND:
slouken@6676
   120
        nscursor = [NSCursor pointingHandCursor];
slouken@6676
   121
        break;
slouken@6676
   122
    default:
slouken@6676
   123
        SDL_assert(!"Unknown system cursor");
slouken@6676
   124
        return NULL;
slouken@6676
   125
    }
slouken@6676
   126
slouken@6676
   127
    if (nscursor) {
slouken@6676
   128
        cursor = SDL_calloc(1, sizeof(*cursor));
slouken@6676
   129
        if (cursor) {
slouken@6676
   130
            // We'll free it later, so retain it here
slouken@6676
   131
            [nscursor retain];
slouken@6676
   132
            cursor->driverdata = nscursor;
slouken@6676
   133
        }
slouken@6676
   134
    }
slouken@6676
   135
slouken@6676
   136
    [pool release];
slouken@6676
   137
slouken@6676
   138
    return cursor;
slouken@6676
   139
}
slouken@6676
   140
slouken@5376
   141
static void
slouken@5376
   142
Cocoa_FreeCursor(SDL_Cursor * cursor)
slouken@5376
   143
{
slouken@5376
   144
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@5376
   145
    NSCursor *nscursor = (NSCursor *)cursor->driverdata;
slouken@5376
   146
slouken@5376
   147
    [nscursor release];
slouken@5419
   148
    SDL_free(cursor);
slouken@5376
   149
slouken@5376
   150
    [pool release];
slouken@5376
   151
}
slouken@5376
   152
slouken@5376
   153
static int
slouken@5376
   154
Cocoa_ShowCursor(SDL_Cursor * cursor)
slouken@5376
   155
{
slouken@5376
   156
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@5376
   157
ghostunderscore@6301
   158
    if (cursor) {
ghostunderscore@6301
   159
        NSCursor *nscursor = (NSCursor *)cursor->driverdata;
slouken@5387
   160
ghostunderscore@6301
   161
        [nscursor set];
ghostunderscore@6301
   162
        [NSCursor unhide];
ghostunderscore@6301
   163
    } else {
ghostunderscore@6301
   164
        [NSCursor hide];
slouken@5376
   165
    }
slouken@5376
   166
slouken@5376
   167
    [pool release];
slouken@5376
   168
slouken@5376
   169
    return 0;
slouken@5376
   170
}
slouken@5376
   171
slouken@5376
   172
static void
slouken@5376
   173
Cocoa_WarpMouse(SDL_Window * window, int x, int y)
slouken@5376
   174
{
slouken@5376
   175
    CGPoint point;
slouken@5376
   176
slouken@5391
   177
    point.x = (float)window->x + x;
slouken@5391
   178
    point.y = (float)window->y + y;
slouken@5376
   179
    CGWarpMouseCursorPosition(point);
slouken@5376
   180
}
slouken@5376
   181
slouken@5406
   182
static int
slouken@5406
   183
Cocoa_SetRelativeMouseMode(SDL_bool enabled)
slouken@5406
   184
{
slouken@5406
   185
    CGError result;
slouken@5406
   186
slouken@5406
   187
    if (enabled) {
slouken@5406
   188
        result = CGAssociateMouseAndMouseCursorPosition(NO);
slouken@5406
   189
    } else {
slouken@5406
   190
        result = CGAssociateMouseAndMouseCursorPosition(YES);
slouken@5406
   191
    }
slouken@5406
   192
    if (result != kCGErrorSuccess) {
slouken@5406
   193
        SDL_SetError("CGAssociateMouseAndMouseCursorPosition() failed");
slouken@5406
   194
        return -1;
slouken@5406
   195
    }
slouken@5406
   196
    return 0;
slouken@5406
   197
}
slouken@5406
   198
slouken@1931
   199
void
slouken@1931
   200
Cocoa_InitMouse(_THIS)
slouken@1931
   201
{
slouken@5376
   202
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@5376
   203
slouken@5376
   204
    mouse->CreateCursor = Cocoa_CreateCursor;
slouken@6676
   205
    mouse->CreateSystemCursor = Cocoa_CreateSystemCursor;
slouken@5376
   206
    mouse->ShowCursor = Cocoa_ShowCursor;
slouken@5406
   207
    mouse->FreeCursor = Cocoa_FreeCursor;
slouken@5376
   208
    mouse->WarpMouse = Cocoa_WarpMouse;
slouken@5406
   209
    mouse->SetRelativeMouseMode = Cocoa_SetRelativeMouseMode;
slouken@5376
   210
slouken@5405
   211
    SDL_SetDefaultCursor(Cocoa_CreateDefaultCursor());
slouken@1931
   212
}
slouken@1931
   213
slouken@3517
   214
void
slouken@3517
   215
Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
slouken@3517
   216
{
slouken@5406
   217
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@5406
   218
slouken@5477
   219
    if (mouse->relative_mode &&
slouken@5477
   220
        ([event type] == NSMouseMoved ||
slouken@5477
   221
         [event type] == NSLeftMouseDragged ||
slouken@5477
   222
         [event type] == NSRightMouseDragged ||
slouken@5477
   223
         [event type] == NSOtherMouseDragged)) {
slouken@5406
   224
        float x = [event deltaX];
slouken@5406
   225
        float y = [event deltaY];
slouken@5406
   226
        SDL_SendMouseMotion(mouse->focus, 1, (int)x, (int)y);
slouken@5406
   227
    }
slouken@3517
   228
}
slouken@3517
   229
slouken@1931
   230
void
gzjjgod@5057
   231
Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
gzjjgod@5057
   232
{
gzjjgod@5057
   233
    float x = [event deltaX];
gzjjgod@5057
   234
    float y = [event deltaY];
gzjjgod@5057
   235
gzjjgod@5057
   236
    if (x > 0) {
gzjjgod@5057
   237
        x += 0.9f;
gzjjgod@5057
   238
    } else if (x < 0) {
gzjjgod@5057
   239
        x -= 0.9f;
gzjjgod@5057
   240
    }
gzjjgod@5057
   241
    if (y > 0) {
gzjjgod@5057
   242
        y += 0.9f;
gzjjgod@5057
   243
    } else if (y < 0) {
gzjjgod@5057
   244
        y -= 0.9f;
gzjjgod@5057
   245
    }
gzjjgod@5057
   246
    SDL_SendMouseWheel(window, (int)x, (int)y);
gzjjgod@5057
   247
}
gzjjgod@5057
   248
slouken@5058
   249
void
slouken@5058
   250
Cocoa_QuitMouse(_THIS)
slouken@5058
   251
{
slouken@5058
   252
}
slouken@5058
   253
slouken@6044
   254
#endif /* SDL_VIDEO_DRIVER_COCOA */
slouken@6044
   255
slouken@1931
   256
/* vi: set ts=4 sw=4 expandtab: */