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