src/video/cocoa/SDL_cocoawindow.m
author Sam Lantinga <slouken@libsdl.org>
Thu, 08 Nov 2012 02:26:40 -0800
changeset 6666 018f8019ce36
parent 6662 698c2e533a7e
child 6681 5a0396a933b5
permissions -rw-r--r--
Reset the mouse button state when losing mouse focus.
Implemented mouse focus handling entirely using mouse motion events, with SetCapture() semantics, as long as the windowing system continues to provide mouse events.
slouken@1933
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6138
     3
  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
slouken@1933
     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@1933
     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@1933
    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@1933
    20
*/
slouken@1933
    21
#include "SDL_config.h"
slouken@1933
    22
slouken@6044
    23
#if SDL_VIDEO_DRIVER_COCOA
slouken@6044
    24
slouken@1933
    25
#include "SDL_syswm.h"
slouken@5398
    26
#include "SDL_timer.h"  /* For SDL_GetTicks() */
slouken@1933
    27
#include "../SDL_sysvideo.h"
slouken@1933
    28
#include "../../events/SDL_keyboard_c.h"
slouken@1933
    29
#include "../../events/SDL_mouse_c.h"
slouken@4673
    30
#include "../../events/SDL_touch_c.h"
slouken@1933
    31
#include "../../events/SDL_windowevents_c.h"
slouken@1933
    32
#include "SDL_cocoavideo.h"
eligottlieb@4811
    33
#include "SDL_cocoashape.h"
gzjjgod@5057
    34
#include "SDL_cocoamouse.h"
slouken@1933
    35
slouken@5398
    36
slouken@5398
    37
static Uint32 s_moveHack;
slouken@5398
    38
slouken@1933
    39
static __inline__ void ConvertNSRect(NSRect *r)
slouken@1933
    40
{
slouken@1933
    41
    r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
slouken@1933
    42
}
slouken@1933
    43
slouken@1933
    44
@implementation Cocoa_WindowListener
slouken@1933
    45
slouken@1933
    46
- (void)listen:(SDL_WindowData *)data
slouken@1933
    47
{
slouken@1933
    48
    NSNotificationCenter *center;
slouken@5371
    49
    NSWindow *window = data->nswindow;
slouken@5371
    50
    NSView *view = [window contentView];
slouken@1933
    51
slouken@1933
    52
    _data = data;
slouken@1933
    53
slouken@1933
    54
    center = [NSNotificationCenter defaultCenter];
slouken@1933
    55
slouken@5374
    56
    if ([window delegate] != nil) {
slouken@5374
    57
        [center addObserver:self selector:@selector(windowDidExpose:) name:NSWindowDidExposeNotification object:window];
slouken@5374
    58
        [center addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:window];
slouken@5374
    59
        [center addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:window];
slouken@5374
    60
        [center addObserver:self selector:@selector(windowDidMiniaturize:) name:NSWindowDidMiniaturizeNotification object:window];
slouken@5374
    61
        [center addObserver:self selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification object:window];
slouken@5374
    62
        [center addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:window];
slouken@5374
    63
        [center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:window];
slouken@5374
    64
    } else {
slouken@5374
    65
        [window setDelegate:self];
slouken@5374
    66
    }
slouken@1933
    67
slouken@5371
    68
    [window setNextResponder:self];
slouken@5371
    69
    [window setAcceptsMouseMovedEvents:YES];
slouken@5371
    70
slouken@5371
    71
    [view setNextResponder:self];
icculus@6108
    72
icculus@5646
    73
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
icculus@6108
    74
    if ([view respondsToSelector:@selector(setAcceptsTouchEvents:)]) {
icculus@6108
    75
        [view setAcceptsTouchEvents:YES];
icculus@6108
    76
    }
slouken@4925
    77
#endif
slouken@1933
    78
}
slouken@1933
    79
slouken@1933
    80
- (void)close
slouken@1933
    81
{
slouken@1933
    82
    NSNotificationCenter *center;
slouken@5371
    83
    NSWindow *window = _data->nswindow;
slouken@5371
    84
    NSView *view = [window contentView];
slouken@1933
    85
slouken@1933
    86
    center = [NSNotificationCenter defaultCenter];
slouken@1933
    87
slouken@5374
    88
    if ([window delegate] != self) {
slouken@5374
    89
        [center removeObserver:self name:NSWindowDidExposeNotification object:window];
slouken@5374
    90
        [center removeObserver:self name:NSWindowDidMoveNotification object:window];
slouken@5374
    91
        [center removeObserver:self name:NSWindowDidResizeNotification object:window];
slouken@5374
    92
        [center removeObserver:self name:NSWindowDidMiniaturizeNotification object:window];
slouken@5374
    93
        [center removeObserver:self name:NSWindowDidDeminiaturizeNotification object:window];
slouken@5374
    94
        [center removeObserver:self name:NSWindowDidBecomeKeyNotification object:window];
slouken@5374
    95
        [center removeObserver:self name:NSWindowDidResignKeyNotification object:window];
slouken@5374
    96
    } else {
slouken@5374
    97
        [window setDelegate:nil];
slouken@5374
    98
    }
slouken@5371
    99
slouken@5374
   100
    if ([window nextResponder] == self) {
slouken@5374
   101
        [window setNextResponder:nil];
slouken@5374
   102
    }
slouken@5374
   103
    if ([view nextResponder] == self) {
slouken@5374
   104
        [view setNextResponder:nil];
slouken@5374
   105
    }
slouken@1933
   106
}
slouken@1933
   107
slouken@1933
   108
- (BOOL)windowShouldClose:(id)sender
slouken@1933
   109
{
slouken@3685
   110
    SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
slouken@1933
   111
    return NO;
slouken@1933
   112
}
slouken@1933
   113
slouken@1933
   114
- (void)windowDidExpose:(NSNotification *)aNotification
slouken@1933
   115
{
slouken@3685
   116
    SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0);
slouken@1933
   117
}
slouken@1933
   118
slouken@1933
   119
- (void)windowDidMove:(NSNotification *)aNotification
slouken@1933
   120
{
slouken@1933
   121
    int x, y;
icculus@5564
   122
    SDL_VideoDevice *device = SDL_GetVideoDevice();
slouken@5398
   123
    SDL_Window *window = _data->window;
slouken@5398
   124
    NSWindow *nswindow = _data->nswindow;
slouken@5398
   125
    NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
slouken@1933
   126
    ConvertNSRect(&rect);
slouken@5398
   127
slouken@5398
   128
    if (s_moveHack) {
slouken@5398
   129
        SDL_bool blockMove = ((SDL_GetTicks() - s_moveHack) < 500);
slouken@5398
   130
slouken@5398
   131
        s_moveHack = 0;
slouken@5398
   132
slouken@5398
   133
        if (blockMove) {
slouken@5398
   134
            /* Cocoa is adjusting the window in response to a mode change */
slouken@5398
   135
            rect.origin.x = window->x;
slouken@5398
   136
            rect.origin.y = window->y;
slouken@5398
   137
            ConvertNSRect(&rect);
slouken@5398
   138
            [nswindow setFrameOrigin:rect.origin];
slouken@5398
   139
            return;
slouken@5398
   140
        }
slouken@5398
   141
    }
slouken@5398
   142
slouken@3507
   143
    x = (int)rect.origin.x;
slouken@3507
   144
    y = (int)rect.origin.y;
icculus@5564
   145
icculus@5564
   146
    if (window == device->current_glwin) {
icculus@5564
   147
        [((NSOpenGLContext *) device->current_glctx) update];
icculus@5564
   148
    }
icculus@5564
   149
slouken@5398
   150
    SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y);
slouken@1933
   151
}
slouken@1933
   152
slouken@1933
   153
- (void)windowDidResize:(NSNotification *)aNotification
slouken@1933
   154
{
icculus@5564
   155
    SDL_VideoDevice *device = SDL_GetVideoDevice();
slouken@6231
   156
    int x, y, w, h;
slouken@3688
   157
    NSRect rect = [_data->nswindow contentRectForFrameRect:[_data->nswindow frame]];
slouken@6231
   158
    ConvertNSRect(&rect);
slouken@6231
   159
    x = (int)rect.origin.x;
slouken@6231
   160
    y = (int)rect.origin.y;
slouken@1933
   161
    w = (int)rect.size.width;
slouken@1933
   162
    h = (int)rect.size.height;
slouken@4937
   163
    if (SDL_IsShapedWindow(_data->window))
slouken@4937
   164
        Cocoa_ResizeWindowShape(_data->window);
icculus@5564
   165
icculus@5564
   166
    if (_data->window == device->current_glwin) {
icculus@5564
   167
        [((NSOpenGLContext *) device->current_glctx) update];
icculus@5564
   168
    }
icculus@5564
   169
slouken@6231
   170
    /* The window can move during a resize event, such as when maximizing
slouken@6231
   171
       or resizing from a corner */
slouken@6231
   172
    SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_MOVED, x, y);
slouken@3685
   173
    SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_RESIZED, w, h);
slouken@1933
   174
}
slouken@1933
   175
slouken@1933
   176
- (void)windowDidMiniaturize:(NSNotification *)aNotification
slouken@1933
   177
{
slouken@3685
   178
    SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
slouken@1933
   179
}
slouken@1933
   180
slouken@1933
   181
- (void)windowDidDeminiaturize:(NSNotification *)aNotification
slouken@1933
   182
{
slouken@3685
   183
    SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
slouken@1933
   184
}
slouken@1933
   185
slouken@1933
   186
- (void)windowDidBecomeKey:(NSNotification *)aNotification
slouken@1933
   187
{
slouken@5367
   188
    SDL_Window *window = _data->window;
slouken@5367
   189
slouken@3688
   190
    /* We're going to get keyboard events, since we're key. */
slouken@5367
   191
    SDL_SetKeyboardFocus(window);
slouken@5367
   192
slouken@5367
   193
    /* If we just gained focus we need the updated mouse position */
slouken@5396
   194
    {
slouken@5367
   195
        NSPoint point;
slouken@5396
   196
        int x, y;
slouken@5396
   197
slouken@5396
   198
        point = [_data->nswindow mouseLocationOutsideOfEventStream];
slouken@5396
   199
        x = (int)point.x;
slouken@5396
   200
        y = (int)(window->h - point.y);
slouken@5396
   201
slouken@5396
   202
        if (x >= 0 && x < window->w && y >= 0 && y < window->h) {
slouken@5396
   203
            SDL_SendMouseMotion(window, 0, x, y);
slouken@6666
   204
            SDL_SetCursor(NULL);
slouken@5396
   205
        }
slouken@5367
   206
    }
slouken@1962
   207
slouken@4503
   208
    /* Check to see if someone updated the clipboard */
slouken@4503
   209
    Cocoa_CheckClipboardUpdate(_data->videodata);
slouken@1933
   210
}
slouken@1933
   211
slouken@1933
   212
- (void)windowDidResignKey:(NSNotification *)aNotification
slouken@1933
   213
{
slouken@2059
   214
    /* Some other window will get mouse events, since we're not key. */
slouken@4465
   215
    if (SDL_GetMouseFocus() == _data->window) {
slouken@4465
   216
        SDL_SetMouseFocus(NULL);
slouken@2059
   217
    }
slouken@2059
   218
slouken@2059
   219
    /* Some other window will get keyboard events, since we're not key. */
slouken@4465
   220
    if (SDL_GetKeyboardFocus() == _data->window) {
slouken@4465
   221
        SDL_SetKeyboardFocus(NULL);
slouken@4465
   222
    }
slouken@1933
   223
}
slouken@1933
   224
slouken@6514
   225
// We'll respond to key events by doing nothing so we don't beep.
slouken@6514
   226
// We could handle key messages here, but we lose some in the NSApp dispatch,
slouken@6514
   227
// where they get converted to action messages, etc.
slouken@6514
   228
- (void)flagsChanged:(NSEvent *)theEvent
slouken@6514
   229
{
slouken@6514
   230
    //Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);
slouken@6514
   231
}
slouken@6514
   232
- (void)keyDown:(NSEvent *)theEvent
slouken@6514
   233
{
slouken@6514
   234
    //Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);
slouken@6514
   235
}
slouken@6514
   236
- (void)keyUp:(NSEvent *)theEvent
slouken@6514
   237
{
slouken@6514
   238
    //Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);
slouken@6514
   239
}
slouken@6514
   240
slouken@6514
   241
// We'll respond to selectors by doing nothing so we don't beep.
slouken@6514
   242
// The escape key gets converted to a "cancel" selector, etc.
slouken@6514
   243
- (void)doCommandBySelector:(SEL)aSelector
slouken@6514
   244
{
slouken@6514
   245
    //NSLog(@"doCommandBySelector: %@\n", NSStringFromSelector(aSelector));
slouken@6514
   246
}
slouken@6514
   247
slouken@1933
   248
- (void)mouseDown:(NSEvent *)theEvent
slouken@1933
   249
{
slouken@1959
   250
    int button;
slouken@1933
   251
slouken@1959
   252
    switch ([theEvent buttonNumber]) {
slouken@1959
   253
    case 0:
slouken@1959
   254
        button = SDL_BUTTON_LEFT;
slouken@1959
   255
        break;
slouken@1959
   256
    case 1:
slouken@1959
   257
        button = SDL_BUTTON_RIGHT;
slouken@1959
   258
        break;
slouken@1959
   259
    case 2:
slouken@1959
   260
        button = SDL_BUTTON_MIDDLE;
slouken@1959
   261
        break;
slouken@1959
   262
    default:
slouken@5061
   263
        button = [theEvent buttonNumber] + 1;
slouken@1959
   264
        break;
slouken@1959
   265
    }
slouken@4484
   266
    SDL_SendMouseButton(_data->window, SDL_PRESSED, button);
slouken@1933
   267
}
slouken@1933
   268
slouken@1933
   269
- (void)rightMouseDown:(NSEvent *)theEvent
slouken@1933
   270
{
slouken@1959
   271
    [self mouseDown:theEvent];
slouken@1933
   272
}
slouken@1933
   273
slouken@1933
   274
- (void)otherMouseDown:(NSEvent *)theEvent
slouken@1933
   275
{
slouken@1959
   276
    [self mouseDown:theEvent];
slouken@1933
   277
}
slouken@1933
   278
slouken@1933
   279
- (void)mouseUp:(NSEvent *)theEvent
slouken@1933
   280
{
slouken@1959
   281
    int button;
slouken@1933
   282
slouken@1959
   283
    switch ([theEvent buttonNumber]) {
slouken@1959
   284
    case 0:
slouken@1959
   285
        button = SDL_BUTTON_LEFT;
slouken@1959
   286
        break;
slouken@1959
   287
    case 1:
slouken@1959
   288
        button = SDL_BUTTON_RIGHT;
slouken@1959
   289
        break;
slouken@1959
   290
    case 2:
slouken@1959
   291
        button = SDL_BUTTON_MIDDLE;
slouken@1959
   292
        break;
slouken@1959
   293
    default:
slouken@5061
   294
        button = [theEvent buttonNumber] + 1;
slouken@1959
   295
        break;
slouken@1959
   296
    }
slouken@4484
   297
    SDL_SendMouseButton(_data->window, SDL_RELEASED, button);
slouken@1933
   298
}
slouken@1933
   299
slouken@1933
   300
- (void)rightMouseUp:(NSEvent *)theEvent
slouken@1933
   301
{
slouken@1959
   302
    [self mouseUp:theEvent];
slouken@1933
   303
}
slouken@1933
   304
slouken@1933
   305
- (void)otherMouseUp:(NSEvent *)theEvent
slouken@1933
   306
{
slouken@1959
   307
    [self mouseUp:theEvent];
slouken@1933
   308
}
slouken@1933
   309
slouken@1933
   310
- (void)mouseMoved:(NSEvent *)theEvent
slouken@1933
   311
{
slouken@5406
   312
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@3685
   313
    SDL_Window *window = _data->window;
slouken@5396
   314
    NSPoint point;
slouken@5396
   315
    int x, y;
slouken@1933
   316
slouken@5406
   317
    if (mouse->relative_mode) {
gzjjgod@5059
   318
        return;
slouken@5371
   319
    }
gzjjgod@5059
   320
slouken@5396
   321
    point = [theEvent locationInWindow];
slouken@5396
   322
    x = (int)point.x;
slouken@5396
   323
    y = (int)(window->h - point.y);
slouken@5371
   324
slouken@5396
   325
    if (x < 0 || x >= window->w || y < 0 || y >= window->h) {
slouken@6666
   326
        if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
slouken@6666
   327
            CGPoint cgpoint;
slouken@6666
   328
slouken@6666
   329
            if (x < 0) {
slouken@6666
   330
                x = 0;
slouken@6666
   331
            } else if (x >= window->w) {
slouken@6666
   332
                x = window->w - 1;
slouken@6666
   333
            }
slouken@6666
   334
            if (y < 0) {
slouken@6666
   335
                y = 0;
slouken@6666
   336
            } else if (y >= window->h) {
slouken@6666
   337
                y = window->h - 1;
slouken@6666
   338
            }
slouken@6666
   339
slouken@6666
   340
            cgpoint.x = window->x + x;
slouken@6666
   341
            cgpoint.y = window->y + y;
slouken@6666
   342
            CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
slouken@5396
   343
        }
slouken@2059
   344
    }
slouken@6666
   345
    SDL_SendMouseMotion(window, 0, x, y);
slouken@1933
   346
}
slouken@1933
   347
slouken@1957
   348
- (void)mouseDragged:(NSEvent *)theEvent
slouken@1957
   349
{
slouken@1957
   350
    [self mouseMoved:theEvent];
slouken@1957
   351
}
slouken@1957
   352
slouken@1958
   353
- (void)rightMouseDragged:(NSEvent *)theEvent
slouken@1958
   354
{
slouken@1958
   355
    [self mouseMoved:theEvent];
slouken@1958
   356
}
slouken@1958
   357
slouken@1958
   358
- (void)otherMouseDragged:(NSEvent *)theEvent
slouken@1958
   359
{
slouken@1958
   360
    [self mouseMoved:theEvent];
slouken@1958
   361
}
slouken@1958
   362
slouken@1933
   363
- (void)scrollWheel:(NSEvent *)theEvent
slouken@1933
   364
{
gzjjgod@5057
   365
    Cocoa_HandleMouseWheel(_data->window, theEvent);
slouken@3688
   366
}
slouken@3688
   367
slouken@4673
   368
- (void)touchesBeganWithEvent:(NSEvent *) theEvent
slouken@4673
   369
{
slouken@4673
   370
    [self handleTouches:COCOA_TOUCH_DOWN withEvent:theEvent];
slouken@4673
   371
}
slouken@4673
   372
slouken@4673
   373
- (void)touchesMovedWithEvent:(NSEvent *) theEvent
slouken@4673
   374
{
slouken@4673
   375
    [self handleTouches:COCOA_TOUCH_MOVE withEvent:theEvent];
slouken@4673
   376
}
slouken@4673
   377
slouken@4673
   378
- (void)touchesEndedWithEvent:(NSEvent *) theEvent
slouken@4673
   379
{
slouken@4673
   380
    [self handleTouches:COCOA_TOUCH_UP withEvent:theEvent];
slouken@4673
   381
}
slouken@4673
   382
slouken@4673
   383
- (void)touchesCancelledWithEvent:(NSEvent *) theEvent
slouken@4673
   384
{
slouken@4673
   385
    [self handleTouches:COCOA_TOUCH_CANCELLED withEvent:theEvent];
slouken@4673
   386
}
slouken@4673
   387
slouken@4673
   388
- (void)handleTouches:(cocoaTouchType)type withEvent:(NSEvent *)event
slouken@4673
   389
{
icculus@5646
   390
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
slouken@4680
   391
    NSSet *touches = 0;
slouken@4680
   392
    NSEnumerator *enumerator;
slouken@4680
   393
    NSTouch *touch;
slouken@4673
   394
slouken@4680
   395
    switch (type) {
slouken@4680
   396
        case COCOA_TOUCH_DOWN:
slouken@4680
   397
            touches = [event touchesMatchingPhase:NSTouchPhaseBegan inView:nil];
slouken@4680
   398
            break;
slouken@4680
   399
        case COCOA_TOUCH_UP:
slouken@4680
   400
        case COCOA_TOUCH_CANCELLED:
slouken@4680
   401
            touches = [event touchesMatchingPhase:NSTouchPhaseEnded inView:nil];
slouken@4680
   402
            break;
slouken@4680
   403
        case COCOA_TOUCH_MOVE:
slouken@4680
   404
            touches = [event touchesMatchingPhase:NSTouchPhaseMoved inView:nil];
slouken@4680
   405
            break;
slouken@4680
   406
    }
slouken@4680
   407
slouken@4680
   408
    enumerator = [touches objectEnumerator];
slouken@4680
   409
    touch = (NSTouch*)[enumerator nextObject];
slouken@4673
   410
    while (touch) {
icculus@5873
   411
        const SDL_TouchID touchId = (SDL_TouchID) ((size_t) [touch device]);
slouken@4673
   412
        if (!SDL_GetTouch(touchId)) {
slouken@4673
   413
            SDL_Touch touch;
slouken@4673
   414
slouken@4673
   415
            touch.id = touchId;
slouken@4673
   416
            touch.x_min = 0;
slouken@4673
   417
            touch.x_max = 1;
jimtla@4678
   418
            touch.native_xres = touch.x_max - touch.x_min;
slouken@4673
   419
            touch.y_min = 0;
slouken@4673
   420
            touch.y_max = 1;
jimtla@4678
   421
            touch.native_yres = touch.y_max - touch.y_min;
slouken@4673
   422
            touch.pressure_min = 0;
slouken@4673
   423
            touch.pressure_max = 1;
jimtla@4678
   424
            touch.native_pressureres = touch.pressure_max - touch.pressure_min;
slouken@4673
   425
            
slouken@4673
   426
            if (SDL_AddTouch(&touch, "") < 0) {
slouken@4680
   427
                return;
slouken@4673
   428
            }
slouken@4673
   429
        } 
slouken@4687
   430
icculus@5873
   431
        const SDL_FingerID fingerId = (SDL_FingerID) ((size_t) [touch identity]);
slouken@4673
   432
        float x = [touch normalizedPosition].x;
slouken@4673
   433
        float y = [touch normalizedPosition].y;
slouken@5261
   434
        /* Make the origin the upper left instead of the lower left */
slouken@5261
   435
        y = 1.0f - y;
slouken@4687
   436
slouken@4673
   437
        switch (type) {
slouken@4673
   438
        case COCOA_TOUCH_DOWN:
slouken@4673
   439
            SDL_SendFingerDown(touchId, fingerId, SDL_TRUE, x, y, 1);
slouken@4673
   440
            break;
slouken@4673
   441
        case COCOA_TOUCH_UP:
slouken@4673
   442
        case COCOA_TOUCH_CANCELLED:
slouken@4673
   443
            SDL_SendFingerDown(touchId, fingerId, SDL_FALSE, x, y, 1);
slouken@4673
   444
            break;
slouken@4673
   445
        case COCOA_TOUCH_MOVE:
slouken@4673
   446
            SDL_SendTouchMotion(touchId, fingerId, SDL_FALSE, x, y, 1);
slouken@4673
   447
            break;
slouken@4673
   448
        }
slouken@4673
   449
        
slouken@4673
   450
        touch = (NSTouch*)[enumerator nextObject];
slouken@4673
   451
    }
icculus@5646
   452
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 */
slouken@1933
   453
}
slouken@1933
   454
slouken@1933
   455
@end
slouken@1933
   456
slouken@1973
   457
@interface SDLWindow : NSWindow
slouken@1973
   458
/* These are needed for borderless/fullscreen windows */
slouken@1973
   459
- (BOOL)canBecomeKeyWindow;
slouken@1973
   460
- (BOOL)canBecomeMainWindow;
slouken@1973
   461
@end
slouken@1973
   462
slouken@1973
   463
@implementation SDLWindow
slouken@1973
   464
- (BOOL)canBecomeKeyWindow
slouken@1973
   465
{
slouken@1973
   466
    return YES;
slouken@1973
   467
}
slouken@1973
   468
slouken@1973
   469
- (BOOL)canBecomeMainWindow
slouken@1973
   470
{
slouken@1973
   471
    return YES;
slouken@1973
   472
}
slouken@1973
   473
@end
slouken@1973
   474
slouken@5379
   475
@interface SDLView : NSView
slouken@5379
   476
/* The default implementation doesn't pass rightMouseDown to responder chain */
slouken@5379
   477
- (void)rightMouseDown:(NSEvent *)theEvent;
gzjjgod@4915
   478
@end
gzjjgod@4915
   479
gzjjgod@4915
   480
@implementation SDLView
gzjjgod@4915
   481
- (void)rightMouseDown:(NSEvent *)theEvent
gzjjgod@4915
   482
{
slouken@5371
   483
    [[self nextResponder] rightMouseDown:theEvent];
gzjjgod@4915
   484
}
gzjjgod@4915
   485
@end
gzjjgod@4915
   486
slouken@5249
   487
static unsigned int
slouken@5305
   488
GetWindowStyle(SDL_Window * window)
slouken@5249
   489
{
slouken@5249
   490
    unsigned int style;
slouken@5249
   491
slouken@5305
   492
	if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@5249
   493
        style = NSBorderlessWindowMask;
slouken@5305
   494
	} else {
slouken@5305
   495
		if (window->flags & SDL_WINDOW_BORDERLESS) {
slouken@5305
   496
			style = NSBorderlessWindowMask;
slouken@5305
   497
		} else {
slouken@5305
   498
			style = (NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask);
slouken@5305
   499
		}
slouken@5305
   500
		if (window->flags & SDL_WINDOW_RESIZABLE) {
slouken@5305
   501
			style |= NSResizableWindowMask;
slouken@5305
   502
		}
slouken@5305
   503
	}
slouken@5249
   504
    return style;
slouken@5249
   505
}
slouken@5249
   506
slouken@1933
   507
static int
slouken@1951
   508
SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created)
slouken@1933
   509
{
slouken@1933
   510
    NSAutoreleasePool *pool;
slouken@1951
   511
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
slouken@1933
   512
    SDL_WindowData *data;
slouken@1933
   513
slouken@1933
   514
    /* Allocate the window data */
slouken@5249
   515
    data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
slouken@1933
   516
    if (!data) {
slouken@1933
   517
        SDL_OutOfMemory();
slouken@1933
   518
        return -1;
slouken@1933
   519
    }
slouken@3685
   520
    data->window = window;
slouken@3688
   521
    data->nswindow = nswindow;
slouken@1933
   522
    data->created = created;
slouken@1951
   523
    data->videodata = videodata;
slouken@1933
   524
slouken@1933
   525
    pool = [[NSAutoreleasePool alloc] init];
slouken@1933
   526
slouken@1933
   527
    /* Create an event listener for the window */
slouken@1933
   528
    data->listener = [[Cocoa_WindowListener alloc] init];
slouken@1933
   529
slouken@1933
   530
    /* Fill in the SDL window with the window data */
slouken@1933
   531
    {
slouken@1933
   532
        NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
slouken@1933
   533
        ConvertNSRect(&rect);
slouken@5261
   534
        window->x = (int)rect.origin.x;
slouken@5261
   535
        window->y = (int)rect.origin.y;
slouken@5261
   536
        window->w = (int)rect.size.width;
slouken@5261
   537
        window->h = (int)rect.size.height;
slouken@1933
   538
    }
slouken@5371
   539
slouken@5371
   540
    /* Set up the listener after we create the view */
slouken@5371
   541
    [data->listener listen:data];
slouken@5371
   542
slouken@1933
   543
    if ([nswindow isVisible]) {
slouken@1933
   544
        window->flags |= SDL_WINDOW_SHOWN;
slouken@1933
   545
    } else {
slouken@1933
   546
        window->flags &= ~SDL_WINDOW_SHOWN;
slouken@1933
   547
    }
slouken@1933
   548
    {
slouken@1933
   549
        unsigned int style = [nswindow styleMask];
slouken@1933
   550
slouken@5380
   551
        if (style == NSBorderlessWindowMask) {
slouken@1933
   552
            window->flags |= SDL_WINDOW_BORDERLESS;
slouken@1933
   553
        } else {
slouken@1933
   554
            window->flags &= ~SDL_WINDOW_BORDERLESS;
slouken@1933
   555
        }
slouken@1933
   556
        if (style & NSResizableWindowMask) {
slouken@1933
   557
            window->flags |= SDL_WINDOW_RESIZABLE;
slouken@1933
   558
        } else {
slouken@1933
   559
            window->flags &= ~SDL_WINDOW_RESIZABLE;
slouken@1933
   560
        }
slouken@1933
   561
    }
slouken@5380
   562
    /* isZoomed always returns true if the window is not resizable */
slouken@5380
   563
    if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed]) {
slouken@1933
   564
        window->flags |= SDL_WINDOW_MAXIMIZED;
slouken@1933
   565
    } else {
slouken@1933
   566
        window->flags &= ~SDL_WINDOW_MAXIMIZED;
slouken@1933
   567
    }
slouken@1933
   568
    if ([nswindow isMiniaturized]) {
slouken@1933
   569
        window->flags |= SDL_WINDOW_MINIMIZED;
slouken@1933
   570
    } else {
slouken@1933
   571
        window->flags &= ~SDL_WINDOW_MINIMIZED;
slouken@1933
   572
    }
slouken@1933
   573
    if ([nswindow isKeyWindow]) {
slouken@1933
   574
        window->flags |= SDL_WINDOW_INPUT_FOCUS;
slouken@4465
   575
        SDL_SetKeyboardFocus(data->window);
slouken@1933
   576
    }
slouken@1933
   577
slouken@1933
   578
    /* All done! */
slouken@1933
   579
    [pool release];
slouken@1933
   580
    window->driverdata = data;
slouken@1933
   581
    return 0;
slouken@1933
   582
}
slouken@1933
   583
slouken@1933
   584
int
slouken@1933
   585
Cocoa_CreateWindow(_THIS, SDL_Window * window)
slouken@1933
   586
{
slouken@3506
   587
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@1933
   588
    NSWindow *nswindow;
slouken@5246
   589
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
slouken@1933
   590
    NSRect rect;
slouken@3528
   591
    SDL_Rect bounds;
slouken@1933
   592
    unsigned int style;
slouken@1933
   593
slouken@3528
   594
    Cocoa_GetDisplayBounds(_this, display, &bounds);
slouken@5380
   595
    rect.origin.x = window->x;
slouken@5380
   596
    rect.origin.y = window->y;
slouken@1933
   597
    rect.size.width = window->w;
slouken@1933
   598
    rect.size.height = window->h;
slouken@1933
   599
    ConvertNSRect(&rect);
slouken@1933
   600
slouken@5305
   601
    style = GetWindowStyle(window);
slouken@1933
   602
slouken@3506
   603
    /* Figure out which screen to place this window */
slouken@3506
   604
    NSArray *screens = [NSScreen screens];
slouken@3506
   605
    NSScreen *screen = nil;
slouken@3506
   606
    NSScreen *candidate;
slouken@3525
   607
    int i, count = [screens count];
slouken@3525
   608
    for (i = 0; i < count; ++i) {
slouken@3529
   609
        candidate = [screens objectAtIndex:i];
slouken@3506
   610
        NSRect screenRect = [candidate frame];
slouken@3506
   611
        if (rect.origin.x >= screenRect.origin.x &&
slouken@3506
   612
            rect.origin.x < screenRect.origin.x + screenRect.size.width &&
slouken@3506
   613
            rect.origin.y >= screenRect.origin.y &&
slouken@3506
   614
            rect.origin.y < screenRect.origin.y + screenRect.size.height) {
slouken@3506
   615
            screen = candidate;
slouken@3506
   616
            rect.origin.x -= screenRect.origin.x;
slouken@3506
   617
            rect.origin.y -= screenRect.origin.y;
slouken@3506
   618
        }
slouken@3506
   619
    }
slouken@5379
   620
    nswindow = [[SDLWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:YES screen:screen];
slouken@1933
   621
slouken@6489
   622
    // Create a default view for this window
slouken@6489
   623
    rect = [nswindow contentRectForFrameRect:[nswindow frame]];
slouken@6489
   624
    NSView *contentView = [[SDLView alloc] initWithFrame:rect];
slouken@6489
   625
    [nswindow setContentView: contentView];
slouken@6489
   626
    [contentView release];
slouken@6489
   627
slouken@1933
   628
    [pool release];
slouken@1933
   629
slouken@1951
   630
    if (SetupWindowData(_this, window, nswindow, SDL_TRUE) < 0) {
slouken@1933
   631
        [nswindow release];
slouken@1933
   632
        return -1;
slouken@1933
   633
    }
slouken@1933
   634
    return 0;
slouken@1933
   635
}
slouken@1933
   636
slouken@1933
   637
int
slouken@1933
   638
Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
slouken@1933
   639
{
slouken@1933
   640
    NSAutoreleasePool *pool;
slouken@1933
   641
    NSWindow *nswindow = (NSWindow *) data;
slouken@1933
   642
    NSString *title;
slouken@1933
   643
slouken@1933
   644
    pool = [[NSAutoreleasePool alloc] init];
slouken@1933
   645
slouken@1933
   646
    /* Query the title from the existing window */
slouken@1933
   647
    title = [nswindow title];
slouken@1933
   648
    if (title) {
slouken@1933
   649
        window->title = SDL_strdup([title UTF8String]);
slouken@1933
   650
    }
slouken@1933
   651
slouken@1933
   652
    [pool release];
slouken@1933
   653
slouken@1951
   654
    return SetupWindowData(_this, window, nswindow, SDL_FALSE);
slouken@1933
   655
}
slouken@1933
   656
slouken@1933
   657
void
slouken@1933
   658
Cocoa_SetWindowTitle(_THIS, SDL_Window * window)
slouken@1933
   659
{
slouken@1937
   660
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@3688
   661
    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
slouken@1933
   662
    NSString *string;
slouken@1933
   663
slouken@1956
   664
    if(window->title) {
slouken@1956
   665
        string = [[NSString alloc] initWithUTF8String:window->title];
slouken@1956
   666
    } else {
slouken@1956
   667
        string = [[NSString alloc] init];
slouken@1956
   668
    }
slouken@1933
   669
    [nswindow setTitle:string];
slouken@1933
   670
    [string release];
slouken@1956
   671
slouken@1937
   672
    [pool release];
slouken@1933
   673
}
slouken@1933
   674
slouken@1933
   675
void
slouken@5375
   676
Cocoa_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
slouken@5375
   677
{
slouken@5375
   678
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@5375
   679
    NSImage *nsimage = Cocoa_CreateImage(icon);
slouken@5375
   680
slouken@5375
   681
    if (nsimage) {
slouken@5375
   682
        [NSApp setApplicationIconImage:nsimage];
slouken@5375
   683
    }
slouken@5375
   684
slouken@5375
   685
    [pool release];
slouken@5375
   686
}
slouken@5375
   687
slouken@5375
   688
void
slouken@1933
   689
Cocoa_SetWindowPosition(_THIS, SDL_Window * window)
slouken@1933
   690
{
slouken@1937
   691
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@3688
   692
    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
slouken@1933
   693
    NSRect rect;
slouken@5478
   694
    Uint32 moveHack;
slouken@1933
   695
slouken@5478
   696
    rect.origin.x = window->x;
slouken@5478
   697
    rect.origin.y = window->y;
slouken@1933
   698
    rect.size.width = window->w;
slouken@1933
   699
    rect.size.height = window->h;
slouken@1933
   700
    ConvertNSRect(&rect);
slouken@5478
   701
slouken@5478
   702
    moveHack = s_moveHack;
slouken@5478
   703
    s_moveHack = 0;
slouken@1933
   704
    [nswindow setFrameOrigin:rect.origin];
slouken@5478
   705
    s_moveHack = moveHack;
slouken@5478
   706
icculus@5564
   707
    if (window == _this->current_glwin) {
icculus@5564
   708
        [((NSOpenGLContext *) _this->current_glctx) update];
icculus@5564
   709
    }
icculus@5564
   710
slouken@1937
   711
    [pool release];
slouken@1933
   712
}
slouken@1933
   713
slouken@1933
   714
void
slouken@1933
   715
Cocoa_SetWindowSize(_THIS, SDL_Window * window)
slouken@1933
   716
{
slouken@1937
   717
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
icculus@5564
   718
    SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
icculus@5564
   719
    NSWindow *nswindow = windata->nswindow;
slouken@1933
   720
    NSSize size;
slouken@1933
   721
slouken@1933
   722
    size.width = window->w;
slouken@1933
   723
    size.height = window->h;
slouken@1933
   724
    [nswindow setContentSize:size];
icculus@5564
   725
icculus@5564
   726
    if (window == _this->current_glwin) {
icculus@5564
   727
        [((NSOpenGLContext *) _this->current_glctx) update];
icculus@5564
   728
    }
icculus@5564
   729
slouken@1937
   730
    [pool release];
slouken@1933
   731
}
slouken@1933
   732
slouken@1933
   733
void
slouken@1933
   734
Cocoa_ShowWindow(_THIS, SDL_Window * window)
slouken@1933
   735
{
slouken@1937
   736
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@3688
   737
    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
slouken@1933
   738
slouken@1956
   739
    if (![nswindow isMiniaturized]) {
slouken@1956
   740
        [nswindow makeKeyAndOrderFront:nil];
slouken@1956
   741
    }
slouken@1937
   742
    [pool release];
slouken@1933
   743
}
slouken@1933
   744
slouken@1933
   745
void
slouken@1933
   746
Cocoa_HideWindow(_THIS, SDL_Window * window)
slouken@1933
   747
{
slouken@1956
   748
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@3688
   749
    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
slouken@1933
   750
slouken@1956
   751
    [nswindow orderOut:nil];
slouken@1956
   752
    [pool release];
slouken@1933
   753
}
slouken@1933
   754
slouken@1933
   755
void
slouken@1933
   756
Cocoa_RaiseWindow(_THIS, SDL_Window * window)
slouken@1933
   757
{
slouken@1937
   758
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@3688
   759
    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
slouken@1933
   760
slouken@1933
   761
    [nswindow makeKeyAndOrderFront:nil];
slouken@1937
   762
    [pool release];
slouken@1933
   763
}
slouken@1933
   764
slouken@1933
   765
void
slouken@1933
   766
Cocoa_MaximizeWindow(_THIS, SDL_Window * window)
slouken@1933
   767
{
slouken@1937
   768
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@3688
   769
    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
slouken@1933
   770
slouken@1956
   771
    [nswindow zoom:nil];
icculus@5564
   772
icculus@5564
   773
    if (window == _this->current_glwin) {
icculus@5564
   774
        [((NSOpenGLContext *) _this->current_glctx) update];
icculus@5564
   775
    }
icculus@5564
   776
slouken@1937
   777
    [pool release];
slouken@1933
   778
}
slouken@1933
   779
slouken@1933
   780
void
slouken@1933
   781
Cocoa_MinimizeWindow(_THIS, SDL_Window * window)
slouken@1933
   782
{
slouken@1937
   783
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@3688
   784
    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
slouken@1933
   785
slouken@1956
   786
    [nswindow miniaturize:nil];
slouken@1937
   787
    [pool release];
slouken@1933
   788
}
slouken@1933
   789
slouken@1933
   790
void
slouken@1933
   791
Cocoa_RestoreWindow(_THIS, SDL_Window * window)
slouken@1933
   792
{
slouken@1956
   793
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@3688
   794
    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
slouken@1933
   795
slouken@1956
   796
    if ([nswindow isMiniaturized]) {
slouken@1956
   797
        [nswindow deminiaturize:nil];
slouken@5380
   798
    } else if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed]) {
slouken@1956
   799
        [nswindow zoom:nil];
slouken@1956
   800
    }
slouken@1956
   801
    [pool release];
slouken@1933
   802
}
slouken@1933
   803
slouken@5400
   804
static NSWindow *
slouken@5400
   805
Cocoa_RebuildWindow(SDL_WindowData * data, NSWindow * nswindow, unsigned style)
slouken@5400
   806
{
slouken@5400
   807
    if (!data->created) {
slouken@5400
   808
        /* Don't mess with other people's windows... */
slouken@5400
   809
        return nswindow;
slouken@5400
   810
    }
slouken@5400
   811
slouken@5400
   812
    [data->listener close];
slouken@5400
   813
    data->nswindow = [[SDLWindow alloc] initWithContentRect:[[nswindow contentView] frame] styleMask:style backing:NSBackingStoreBuffered defer:YES screen:[nswindow screen]];
slouken@5400
   814
    [data->nswindow setContentView:[nswindow contentView]];
slouken@5400
   815
    [data->listener listen:data];
slouken@5400
   816
slouken@5400
   817
    [nswindow close];
slouken@5400
   818
slouken@5400
   819
    return data->nswindow;
slouken@5400
   820
}
slouken@5400
   821
slouken@1933
   822
void
icculus@6422
   823
Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
icculus@6422
   824
{
icculus@6422
   825
    /* this message arrived in 10.6. You're out of luck on older OSes. */
icculus@6422
   826
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
icculus@6422
   827
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
icculus@6422
   828
    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
icculus@6422
   829
    if ([nswindow respondsToSelector:@selector(setStyleMask:)]) {
icculus@6422
   830
        [nswindow setStyleMask:GetWindowStyle(window)];
icculus@6426
   831
        if (bordered) {
icculus@6426
   832
            Cocoa_SetWindowTitle(_this, window);  // this got blanked out.
icculus@6426
   833
        }
icculus@6422
   834
    }
icculus@6422
   835
    [pool release];
icculus@6422
   836
#endif
icculus@6422
   837
}
icculus@6422
   838
icculus@6422
   839
void
slouken@5305
   840
Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
slouken@5249
   841
{
slouken@5249
   842
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@5249
   843
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@5249
   844
    NSWindow *nswindow = data->nswindow;
slouken@5249
   845
    NSRect rect;
slouken@5249
   846
slouken@5502
   847
    /* The view responder chain gets messed with during setStyleMask */
slouken@5502
   848
    if ([[nswindow contentView] nextResponder] == data->listener) {
slouken@5502
   849
        [[nswindow contentView] setNextResponder:nil];
slouken@5502
   850
    }
slouken@5502
   851
slouken@5305
   852
    if (fullscreen) {
slouken@5249
   853
        SDL_Rect bounds;
slouken@5249
   854
slouken@5249
   855
        Cocoa_GetDisplayBounds(_this, display, &bounds);
slouken@5249
   856
        rect.origin.x = bounds.x;
slouken@5249
   857
        rect.origin.y = bounds.y;
slouken@5249
   858
        rect.size.width = bounds.w;
slouken@5249
   859
        rect.size.height = bounds.h;
slouken@5249
   860
        ConvertNSRect(&rect);
slouken@5249
   861
slouken@5401
   862
        /* Hack to fix origin on Mac OS X 10.4 */
slouken@5401
   863
        NSRect screenRect = [[nswindow screen] frame];
slouken@5401
   864
        if (screenRect.size.height >= 1.0f) {
slouken@5401
   865
            rect.origin.y += (screenRect.size.height - rect.size.height);
slouken@5401
   866
        }
slouken@5401
   867
slouken@5361
   868
        if ([nswindow respondsToSelector: @selector(setStyleMask:)]) {
slouken@5361
   869
            [nswindow performSelector: @selector(setStyleMask:) withObject: (id)NSBorderlessWindowMask];
slouken@5400
   870
        } else {
slouken@5400
   871
            nswindow = Cocoa_RebuildWindow(data, nswindow, NSBorderlessWindowMask);
slouken@5361
   872
        }
slouken@5249
   873
    } else {
slouken@5398
   874
        rect.origin.x = window->windowed.x;
slouken@5398
   875
        rect.origin.y = window->windowed.y;
slouken@5398
   876
        rect.size.width = window->windowed.w;
slouken@5398
   877
        rect.size.height = window->windowed.h;
slouken@5398
   878
        ConvertNSRect(&rect);
slouken@5398
   879
slouken@5361
   880
        if ([nswindow respondsToSelector: @selector(setStyleMask:)]) {
slouken@5378
   881
            [nswindow performSelector: @selector(setStyleMask:) withObject: (id)(uintptr_t)GetWindowStyle(window)];
slouken@5400
   882
        } else {
slouken@5400
   883
            nswindow = Cocoa_RebuildWindow(data, nswindow, GetWindowStyle(window));
slouken@5361
   884
        }
slouken@5398
   885
    }
slouken@5249
   886
slouken@5502
   887
    /* The view responder chain gets messed with during setStyleMask */
slouken@5502
   888
    if ([[nswindow contentView] nextResponder] != data->listener) {
slouken@5502
   889
        [[nswindow contentView] setNextResponder:data->listener];
slouken@5502
   890
    }
slouken@5502
   891
slouken@5398
   892
    s_moveHack = 0;
slouken@5398
   893
    [nswindow setFrameOrigin:rect.origin];
slouken@5398
   894
    [nswindow setContentSize:rect.size];
slouken@5398
   895
    s_moveHack = SDL_GetTicks();
slouken@5249
   896
slouken@5399
   897
    /* When the window style changes the title is cleared */
slouken@5399
   898
    if (!fullscreen) {
slouken@5399
   899
        Cocoa_SetWindowTitle(_this, window);
slouken@5399
   900
    }
slouken@5399
   901
slouken@5249
   902
#ifdef FULLSCREEN_TOGGLEABLE
slouken@5305
   903
    if (fullscreen) {
slouken@5249
   904
        /* OpenGL is rendering to the window, so make it visible! */
slouken@5249
   905
        [nswindow setLevel:CGShieldingWindowLevel()];
slouken@5249
   906
    } else {
slouken@5249
   907
        [nswindow setLevel:kCGNormalWindowLevel];
slouken@5249
   908
    }
slouken@5249
   909
#endif
slouken@5249
   910
    [nswindow makeKeyAndOrderFront:nil];
slouken@5249
   911
icculus@5564
   912
    if (window == _this->current_glwin) {
icculus@5564
   913
        [((NSOpenGLContext *) _this->current_glctx) update];
icculus@5564
   914
    }
icculus@5564
   915
slouken@5249
   916
    [pool release];
slouken@5249
   917
}
slouken@5249
   918
slouken@5466
   919
int
slouken@5466
   920
Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
slouken@5466
   921
{
slouken@5466
   922
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
slouken@5466
   923
    CGDirectDisplayID display_id = ((SDL_DisplayData *)display->driverdata)->display;
slouken@5466
   924
    const uint32_t tableSize = 256;
slouken@5466
   925
    CGGammaValue redTable[tableSize];
slouken@5466
   926
    CGGammaValue greenTable[tableSize];
slouken@5466
   927
    CGGammaValue blueTable[tableSize];
slouken@5466
   928
    uint32_t i;
slouken@5466
   929
    float inv65535 = 1.0f / 65535.0f;
slouken@5466
   930
slouken@5466
   931
    /* Extract gamma values into separate tables, convert to floats between 0.0 and 1.0 */
slouken@5466
   932
    for (i = 0; i < 256; i++) {
slouken@5466
   933
        redTable[i] = ramp[0*256+i] * inv65535;
slouken@5466
   934
        greenTable[i] = ramp[1*256+i] * inv65535;
slouken@5466
   935
        blueTable[i] = ramp[2*256+i] * inv65535;
slouken@5466
   936
    }
slouken@5466
   937
slouken@5466
   938
    if (CGSetDisplayTransferByTable(display_id, tableSize,
slouken@5466
   939
                                    redTable, greenTable, blueTable) != CGDisplayNoErr) {
slouken@5466
   940
        SDL_SetError("CGSetDisplayTransferByTable()");
slouken@5466
   941
        return -1;
slouken@5466
   942
    }
slouken@5466
   943
    return 0;
slouken@5466
   944
}
slouken@5466
   945
slouken@5466
   946
int
slouken@5466
   947
Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp)
slouken@5466
   948
{
slouken@5466
   949
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
slouken@5466
   950
    CGDirectDisplayID display_id = ((SDL_DisplayData *)display->driverdata)->display;
slouken@5466
   951
    const uint32_t tableSize = 256;
slouken@5466
   952
    CGGammaValue redTable[tableSize];
slouken@5466
   953
    CGGammaValue greenTable[tableSize];
slouken@5466
   954
    CGGammaValue blueTable[tableSize];
slouken@5466
   955
    uint32_t i, tableCopied;
slouken@5466
   956
slouken@5466
   957
    if (CGGetDisplayTransferByTable(display_id, tableSize,
slouken@5466
   958
                                    redTable, greenTable, blueTable, &tableCopied) != CGDisplayNoErr) {
slouken@5466
   959
        SDL_SetError("CGGetDisplayTransferByTable()");
slouken@5466
   960
        return -1;
slouken@5466
   961
    }
slouken@5466
   962
slouken@5466
   963
    for (i = 0; i < tableCopied; i++) {
slouken@5466
   964
        ramp[0*256+i] = (Uint16)(redTable[i] * 65535.0f);
slouken@5466
   965
        ramp[1*256+i] = (Uint16)(greenTable[i] * 65535.0f);
slouken@5466
   966
        ramp[2*256+i] = (Uint16)(blueTable[i] * 65535.0f);
slouken@5466
   967
    }
slouken@5466
   968
    return 0;
slouken@5466
   969
}
slouken@5466
   970
slouken@5249
   971
void
slouken@6662
   972
Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
slouken@1933
   973
{
slouken@5371
   974
    /* Move the cursor to the nearest point in the window */
slouken@6662
   975
    if (grabbed) {
slouken@5371
   976
        int x, y;
slouken@5371
   977
        CGPoint cgpoint;
slouken@5371
   978
slouken@5371
   979
        SDL_GetMouseState(&x, &y);
slouken@5371
   980
        cgpoint.x = window->x + x;
slouken@5371
   981
        cgpoint.y = window->y + y;
slouken@5371
   982
        CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
slouken@5371
   983
    }
slouken@1933
   984
}
slouken@1933
   985
slouken@1933
   986
void
slouken@1933
   987
Cocoa_DestroyWindow(_THIS, SDL_Window * window)
slouken@1933
   988
{
slouken@1937
   989
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
slouken@1933
   990
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1933
   991
slouken@1933
   992
    if (data) {
slouken@1933
   993
        [data->listener close];
slouken@1933
   994
        [data->listener release];
slouken@1933
   995
        if (data->created) {
slouken@3688
   996
            [data->nswindow close];
slouken@1933
   997
        }
slouken@1933
   998
        SDL_free(data);
slouken@1933
   999
    }
slouken@1937
  1000
    [pool release];
slouken@1933
  1001
}
slouken@1933
  1002
slouken@1933
  1003
SDL_bool
slouken@1933
  1004
Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
slouken@1933
  1005
{
slouken@4900
  1006
    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
slouken@1933
  1007
slouken@1933
  1008
    if (info->version.major <= SDL_MAJOR_VERSION) {
slouken@4900
  1009
        info->subsystem = SDL_SYSWM_COCOA;
slouken@5056
  1010
        info->info.cocoa.window = nswindow;
slouken@1933
  1011
        return SDL_TRUE;
slouken@1933
  1012
    } else {
slouken@1933
  1013
        SDL_SetError("Application not compiled with SDL %d.%d\n",
slouken@1933
  1014
                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
slouken@1933
  1015
        return SDL_FALSE;
slouken@1933
  1016
    }
slouken@1933
  1017
}
slouken@1933
  1018
slouken@6044
  1019
#endif /* SDL_VIDEO_DRIVER_COCOA */
slouken@6044
  1020
slouken@1933
  1021
/* vi: set ts=4 sw=4 expandtab: */