src/video/cocoa/SDL_cocoawindow.m
author Ryan C. Gordon <icculus@icculus.org>
Sat, 16 Jul 2011 11:52:09 -0700
changeset 5564 7ed38a8ad304
parent 5535 96594ac5fd1a
child 5646 fe1df351ca3d
permissions -rw-r--r--
Cocoa: Update the current GL context when its window moves or resizes.

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