zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_cocoawindow.m
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22 
23 #if SDL_VIDEO_DRIVER_COCOA
24 
25 #include "SDL_syswm.h"
26 #include "SDL_timer.h" /* For SDL_GetTicks() */
27 #include "../SDL_sysvideo.h"
28 #include "../../events/SDL_keyboard_c.h"
29 #include "../../events/SDL_mouse_c.h"
30 #include "../../events/SDL_touch_c.h"
31 #include "../../events/SDL_windowevents_c.h"
32 #include "SDL_cocoavideo.h"
33 #include "SDL_cocoashape.h"
34 #include "SDL_cocoamouse.h"
35 #include "SDL_cocoaopengl.h"
36 
37 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
38 /* Taken from AppKit/NSOpenGLView.h in 10.8 SDK. */
39 @interface NSView (NSOpenGLSurfaceResolution)
40 - (BOOL)wantsBestResolutionOpenGLSurface;
41 - (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag;
42 @end
43 #endif
44 
45 static Uint32 s_moveHack;
46 
47 static __inline__ void ConvertNSRect(NSRect *r)
48 {
49  r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
50 }
51 
52 static void ScheduleContextUpdates(SDL_WindowData *data)
53 {
54  NSMutableArray *contexts = data->nscontexts;
55  @synchronized (contexts) {
56  for (SDLOpenGLContext *context in contexts) {
57  [context scheduleUpdate];
58  }
59  }
60 }
61 
62 @implementation Cocoa_WindowListener
63 
64 - (void)listen:(SDL_WindowData *)data
65 {
66  NSNotificationCenter *center;
67  NSWindow *window = data->nswindow;
68  NSView *view = [window contentView];
69 
70  _data = data;
71  observingVisible = YES;
72  wasCtrlLeft = NO;
73  wasVisible = [window isVisible];
74 
75  center = [NSNotificationCenter defaultCenter];
76 
77  if ([window delegate] != nil) {
78  [center addObserver:self selector:@selector(windowDidExpose:) name:NSWindowDidExposeNotification object:window];
79  [center addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:window];
80  [center addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:window];
81  [center addObserver:self selector:@selector(windowDidMiniaturize:) name:NSWindowDidMiniaturizeNotification object:window];
82  [center addObserver:self selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification object:window];
83  [center addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:window];
84  [center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:window];
85  } else {
86  [window setDelegate:self];
87  }
88 
89  /* Haven't found a delegate / notification that triggers when the window is
90  * ordered out (is not visible any more). You can be ordered out without
91  * minimizing, so DidMiniaturize doesn't work. (e.g. -[NSWindow orderOut:])
92  */
93  [window addObserver:self
94  forKeyPath:@"visible"
95  options:NSKeyValueObservingOptionNew
96  context:NULL];
97 
98  [window setNextResponder:self];
99  [window setAcceptsMouseMovedEvents:YES];
100 
101  [view setNextResponder:self];
102 
103  if ([view respondsToSelector:@selector(setAcceptsTouchEvents:)]) {
104  [view setAcceptsTouchEvents:YES];
105  }
106 }
107 
108 - (void)observeValueForKeyPath:(NSString *)keyPath
109  ofObject:(id)object
110  change:(NSDictionary *)change
111  context:(void *)context
112 {
113  if (!observingVisible) {
114  return;
115  }
116 
117  if (object == _data->nswindow && [keyPath isEqualToString:@"visible"]) {
118  int newVisibility = [[change objectForKey:@"new"] intValue];
119  if (newVisibility) {
121  } else {
123  }
124  }
125 }
126 
128 {
129  observingVisible = NO;
130  wasVisible = [_data->nswindow isVisible];
131 }
132 
134 {
135  BOOL isVisible = [_data->nswindow isVisible];
136  observingVisible = YES;
137  if (wasVisible != isVisible) {
138  if (isVisible) {
140  } else {
142  }
143 
144  wasVisible = isVisible;
145  }
146 }
147 
148 - (void)close
149 {
150  NSNotificationCenter *center;
151  NSWindow *window = _data->nswindow;
152  NSView *view = [window contentView];
153  NSArray *windows = nil;
154 
155  center = [NSNotificationCenter defaultCenter];
156 
157  if ([window delegate] != self) {
158  [center removeObserver:self name:NSWindowDidExposeNotification object:window];
159  [center removeObserver:self name:NSWindowDidMoveNotification object:window];
160  [center removeObserver:self name:NSWindowDidResizeNotification object:window];
161  [center removeObserver:self name:NSWindowDidMiniaturizeNotification object:window];
162  [center removeObserver:self name:NSWindowDidDeminiaturizeNotification object:window];
163  [center removeObserver:self name:NSWindowDidBecomeKeyNotification object:window];
164  [center removeObserver:self name:NSWindowDidResignKeyNotification object:window];
165  } else {
166  [window setDelegate:nil];
167  }
168 
169  [window removeObserver:self
170  forKeyPath:@"visible"];
171 
172  if ([window nextResponder] == self) {
173  [window setNextResponder:nil];
174  }
175  if ([view nextResponder] == self) {
176  [view setNextResponder:nil];
177  }
178 
179  /* Make the next window in the z-order Key. If we weren't the foreground
180  when closed, this is a no-op.
181  !!! FIXME: Note that this is a hack, and there are corner cases where
182  !!! FIXME: this fails (such as the About box). The typical nib+RunLoop
183  !!! FIXME: handles this for Cocoa apps, but we bypass all that in SDL.
184  !!! FIXME: We should remove this code when we find a better way to
185  !!! FIXME: have the system do this for us. See discussion in
186  !!! FIXME: http://bugzilla.libsdl.org/show_bug.cgi?id=1825
187  */
188  windows = [NSApp orderedWindows];
189  if ([windows count] > 0) {
190  NSWindow *win = (NSWindow *) [windows objectAtIndex:0];
191  [win makeKeyAndOrderFront:self];
192  }
193 }
194 
195 - (BOOL)windowShouldClose:(id)sender
196 {
198  return NO;
199 }
200 
201 - (void)windowDidExpose:(NSNotification *)aNotification
202 {
204 }
205 
206 - (void)windowDidMove:(NSNotification *)aNotification
207 {
208  int x, y;
209  SDL_Window *window = _data->window;
210  NSWindow *nswindow = _data->nswindow;
211  NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
212  ConvertNSRect(&rect);
213 
214  if (s_moveHack) {
215  SDL_bool blockMove = ((SDL_GetTicks() - s_moveHack) < 500);
216 
217  s_moveHack = 0;
218 
219  if (blockMove) {
220  /* Cocoa is adjusting the window in response to a mode change */
221  rect.origin.x = window->x;
222  rect.origin.y = window->y;
223  ConvertNSRect(&rect);
224  [nswindow setFrameOrigin:rect.origin];
225  return;
226  }
227  }
228 
229  x = (int)rect.origin.x;
230  y = (int)rect.origin.y;
231 
232  ScheduleContextUpdates(_data);
233 
235 }
236 
237 - (void)windowDidResize:(NSNotification *)aNotification
238 {
239  int x, y, w, h;
240  NSRect rect = [_data->nswindow contentRectForFrameRect:[_data->nswindow frame]];
241  ConvertNSRect(&rect);
242  x = (int)rect.origin.x;
243  y = (int)rect.origin.y;
244  w = (int)rect.size.width;
245  h = (int)rect.size.height;
248 
249  ScheduleContextUpdates(_data);
250 
251  /* The window can move during a resize event, such as when maximizing
252  or resizing from a corner */
255 
256  const BOOL zoomed = [_data->nswindow isZoomed];
257  if (!zoomed) {
259  } else if (zoomed) {
261  }
262 }
263 
264 - (void)windowDidMiniaturize:(NSNotification *)aNotification
265 {
267 }
268 
269 - (void)windowDidDeminiaturize:(NSNotification *)aNotification
270 {
272 }
273 
274 - (void)windowDidBecomeKey:(NSNotification *)aNotification
275 {
276  SDL_Window *window = _data->window;
277  SDL_Mouse *mouse = SDL_GetMouse();
278 
279  /* We're going to get keyboard events, since we're key. */
280  SDL_SetKeyboardFocus(window);
281 
282  /* If we just gained focus we need the updated mouse position */
283  if (!mouse->relative_mode) {
284  NSPoint point;
285  int x, y;
286 
287  point = [_data->nswindow mouseLocationOutsideOfEventStream];
288  x = (int)point.x;
289  y = (int)(window->h - point.y);
290 
291  if (x >= 0 && x < window->w && y >= 0 && y < window->h) {
292  SDL_SendMouseMotion(window, 0, 0, x, y);
293  }
294  }
295 
296  /* Check to see if someone updated the clipboard */
298 }
299 
300 - (void)windowDidResignKey:(NSNotification *)aNotification
301 {
302  /* Some other window will get mouse events, since we're not key. */
303  if (SDL_GetMouseFocus() == _data->window) {
305  }
306 
307  /* Some other window will get keyboard events, since we're not key. */
308  if (SDL_GetKeyboardFocus() == _data->window) {
310  }
311 }
312 
313 /* We'll respond to key events by doing nothing so we don't beep.
314  * We could handle key messages here, but we lose some in the NSApp dispatch,
315  * where they get converted to action messages, etc.
316  */
317 - (void)flagsChanged:(NSEvent *)theEvent
318 {
319  /*Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);*/
320 }
321 - (void)keyDown:(NSEvent *)theEvent
322 {
323  /*Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);*/
324 }
325 - (void)keyUp:(NSEvent *)theEvent
326 {
327  /*Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);*/
328 }
329 
330 /* We'll respond to selectors by doing nothing so we don't beep.
331  * The escape key gets converted to a "cancel" selector, etc.
332  */
333 - (void)doCommandBySelector:(SEL)aSelector
334 {
335  /*NSLog(@"doCommandBySelector: %@\n", NSStringFromSelector(aSelector));*/
336 }
337 
338 - (void)mouseDown:(NSEvent *)theEvent
339 {
340  int button;
341 
342  switch ([theEvent buttonNumber]) {
343  case 0:
344  if ([theEvent modifierFlags] & NSControlKeyMask) {
345  wasCtrlLeft = YES;
346  button = SDL_BUTTON_RIGHT;
347  } else {
348  wasCtrlLeft = NO;
349  button = SDL_BUTTON_LEFT;
350  }
351  break;
352  case 1:
353  button = SDL_BUTTON_RIGHT;
354  break;
355  case 2:
356  button = SDL_BUTTON_MIDDLE;
357  break;
358  default:
359  button = [theEvent buttonNumber] + 1;
360  break;
361  }
363 }
364 
365 - (void)rightMouseDown:(NSEvent *)theEvent
366 {
367  [self mouseDown:theEvent];
368 }
369 
370 - (void)otherMouseDown:(NSEvent *)theEvent
371 {
372  [self mouseDown:theEvent];
373 }
374 
375 - (void)mouseUp:(NSEvent *)theEvent
376 {
377  int button;
378 
379  switch ([theEvent buttonNumber]) {
380  case 0:
381  if (wasCtrlLeft) {
382  button = SDL_BUTTON_RIGHT;
383  wasCtrlLeft = NO;
384  } else {
385  button = SDL_BUTTON_LEFT;
386  }
387  break;
388  case 1:
389  button = SDL_BUTTON_RIGHT;
390  break;
391  case 2:
392  button = SDL_BUTTON_MIDDLE;
393  break;
394  default:
395  button = [theEvent buttonNumber] + 1;
396  break;
397  }
399 }
400 
401 - (void)rightMouseUp:(NSEvent *)theEvent
402 {
403  [self mouseUp:theEvent];
404 }
405 
406 - (void)otherMouseUp:(NSEvent *)theEvent
407 {
408  [self mouseUp:theEvent];
409 }
410 
411 - (void)mouseMoved:(NSEvent *)theEvent
412 {
413  SDL_Mouse *mouse = SDL_GetMouse();
414  SDL_Window *window = _data->window;
415  NSPoint point;
416  int x, y;
417 
418  if (mouse->relative_mode) {
419  return;
420  }
421 
422  point = [theEvent locationInWindow];
423  x = (int)point.x;
424  y = (int)(window->h - point.y);
425 
426  if (x < 0 || x >= window->w || y < 0 || y >= window->h) {
427  if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
428  CGPoint cgpoint;
429 
430  if (x < 0) {
431  x = 0;
432  } else if (x >= window->w) {
433  x = window->w - 1;
434  }
435  if (y < 0) {
436  y = 0;
437  } else if (y >= window->h) {
438  y = window->h - 1;
439  }
440 
441 #if !SDL_MAC_NO_SANDBOX
442  /* When SDL_MAC_NO_SANDBOX is set, this is handled by
443  * SDL_cocoamousetap.m.
444  */
445 
446  cgpoint.x = window->x + x;
447  cgpoint.y = window->y + y;
448 
449  /* According to the docs, this was deprecated in 10.6, but it's still
450  * around. The substitute requires a CGEventSource, but I'm not entirely
451  * sure how we'd procure the right one for this event.
452  */
453  CGSetLocalEventsSuppressionInterval(0.0);
454  CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
455  CGSetLocalEventsSuppressionInterval(0.25);
456 #endif
457  }
458  }
459  SDL_SendMouseMotion(window, 0, 0, x, y);
460 }
461 
462 - (void)mouseDragged:(NSEvent *)theEvent
463 {
464  [self mouseMoved:theEvent];
465 }
466 
467 - (void)rightMouseDragged:(NSEvent *)theEvent
468 {
469  [self mouseMoved:theEvent];
470 }
471 
472 - (void)otherMouseDragged:(NSEvent *)theEvent
473 {
474  [self mouseMoved:theEvent];
475 }
476 
477 - (void)scrollWheel:(NSEvent *)theEvent
478 {
479  Cocoa_HandleMouseWheel(_data->window, theEvent);
480 }
481 
482 - (void)touchesBeganWithEvent:(NSEvent *) theEvent
483 {
484  [self handleTouches:COCOA_TOUCH_DOWN withEvent:theEvent];
485 }
486 
487 - (void)touchesMovedWithEvent:(NSEvent *) theEvent
488 {
489  [self handleTouches:COCOA_TOUCH_MOVE withEvent:theEvent];
490 }
491 
492 - (void)touchesEndedWithEvent:(NSEvent *) theEvent
493 {
494  [self handleTouches:COCOA_TOUCH_UP withEvent:theEvent];
495 }
496 
497 - (void)touchesCancelledWithEvent:(NSEvent *) theEvent
498 {
499  [self handleTouches:COCOA_TOUCH_CANCELLED withEvent:theEvent];
500 }
501 
502 - (void)handleTouches:(cocoaTouchType)type withEvent:(NSEvent *)event
503 {
504  NSSet *touches = 0;
505  NSEnumerator *enumerator;
506  NSTouch *touch;
507 
508  switch (type) {
509  case COCOA_TOUCH_DOWN:
510  touches = [event touchesMatchingPhase:NSTouchPhaseBegan inView:nil];
511  break;
512  case COCOA_TOUCH_UP:
514  touches = [event touchesMatchingPhase:NSTouchPhaseEnded inView:nil];
515  break;
516  case COCOA_TOUCH_MOVE:
517  touches = [event touchesMatchingPhase:NSTouchPhaseMoved inView:nil];
518  break;
519  }
520 
521  enumerator = [touches objectEnumerator];
522  touch = (NSTouch*)[enumerator nextObject];
523  while (touch) {
524  const SDL_TouchID touchId = (SDL_TouchID)(intptr_t)[touch device];
525  if (!SDL_GetTouch(touchId)) {
526  if (SDL_AddTouch(touchId, "") < 0) {
527  return;
528  }
529  }
530 
531  const SDL_FingerID fingerId = (SDL_FingerID)(intptr_t)[touch identity];
532  float x = [touch normalizedPosition].x;
533  float y = [touch normalizedPosition].y;
534  /* Make the origin the upper left instead of the lower left */
535  y = 1.0f - y;
536 
537  switch (type) {
538  case COCOA_TOUCH_DOWN:
539  SDL_SendTouch(touchId, fingerId, SDL_TRUE, x, y, 1.0f);
540  break;
541  case COCOA_TOUCH_UP:
543  SDL_SendTouch(touchId, fingerId, SDL_FALSE, x, y, 1.0f);
544  break;
545  case COCOA_TOUCH_MOVE:
546  SDL_SendTouchMotion(touchId, fingerId, x, y, 1.0f);
547  break;
548  }
549 
550  touch = (NSTouch*)[enumerator nextObject];
551  }
552 }
553 
554 @end
555 
556 @interface SDLWindow : NSWindow
557 /* These are needed for borderless/fullscreen windows */
558 - (BOOL)canBecomeKeyWindow;
559 - (BOOL)canBecomeMainWindow;
560 @end
561 
562 @implementation SDLWindow
563 - (BOOL)canBecomeKeyWindow
564 {
565  return YES;
566 }
567 
568 - (BOOL)canBecomeMainWindow
569 {
570  return YES;
571 }
572 @end
573 
574 @interface SDLView : NSView
575 
576 /* The default implementation doesn't pass rightMouseDown to responder chain */
577 - (void)rightMouseDown:(NSEvent *)theEvent;
578 @end
579 
580 @implementation SDLView
581 - (void)rightMouseDown:(NSEvent *)theEvent
582 {
583  [[self nextResponder] rightMouseDown:theEvent];
584 }
585 
586 - (void)resetCursorRects
587 {
588  [super resetCursorRects];
589  SDL_Mouse *mouse = SDL_GetMouse();
590 
591  if (mouse->cursor_shown && mouse->cur_cursor && !mouse->relative_mode) {
592  [self addCursorRect:[self bounds]
593  cursor:mouse->cur_cursor->driverdata];
594  } else {
595  [self addCursorRect:[self bounds]
596  cursor:[NSCursor invisibleCursor]];
597  }
598 }
599 @end
600 
601 static unsigned int
602 GetWindowStyle(SDL_Window * window)
603 {
604  unsigned int style;
605 
606  if (window->flags & SDL_WINDOW_FULLSCREEN) {
607  style = NSBorderlessWindowMask;
608  } else {
609  if (window->flags & SDL_WINDOW_BORDERLESS) {
610  style = NSBorderlessWindowMask;
611  } else {
612  style = (NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask);
613  }
614  if (window->flags & SDL_WINDOW_RESIZABLE) {
615  style |= NSResizableWindowMask;
616  }
617  }
618  return style;
619 }
620 
621 static int
622 SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created)
623 {
624  NSAutoreleasePool *pool;
625  SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
626  SDL_WindowData *data;
627 
628  /* Allocate the window data */
629  data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
630  if (!data) {
631  return SDL_OutOfMemory();
632  }
633  data->window = window;
634  data->nswindow = nswindow;
635  data->created = created;
636  data->videodata = videodata;
637  data->nscontexts = [[NSMutableArray alloc] init];
638 
639  pool = [[NSAutoreleasePool alloc] init];
640 
641  /* Create an event listener for the window */
642  data->listener = [[Cocoa_WindowListener alloc] init];
643 
644  /* Fill in the SDL window with the window data */
645  {
646  NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
647  ConvertNSRect(&rect);
648  window->x = (int)rect.origin.x;
649  window->y = (int)rect.origin.y;
650  window->w = (int)rect.size.width;
651  window->h = (int)rect.size.height;
652  }
653 
654  /* Set up the listener after we create the view */
655  [data->listener listen:data];
656 
657  if ([nswindow isVisible]) {
658  window->flags |= SDL_WINDOW_SHOWN;
659  } else {
660  window->flags &= ~SDL_WINDOW_SHOWN;
661  }
662 
663  {
664  unsigned int style = [nswindow styleMask];
665 
666  if (style == NSBorderlessWindowMask) {
667  window->flags |= SDL_WINDOW_BORDERLESS;
668  } else {
669  window->flags &= ~SDL_WINDOW_BORDERLESS;
670  }
671  if (style & NSResizableWindowMask) {
672  window->flags |= SDL_WINDOW_RESIZABLE;
673  } else {
674  window->flags &= ~SDL_WINDOW_RESIZABLE;
675  }
676  }
677 
678  /* isZoomed always returns true if the window is not resizable */
679  if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed]) {
680  window->flags |= SDL_WINDOW_MAXIMIZED;
681  } else {
682  window->flags &= ~SDL_WINDOW_MAXIMIZED;
683  }
684 
685  if ([nswindow isMiniaturized]) {
686  window->flags |= SDL_WINDOW_MINIMIZED;
687  } else {
688  window->flags &= ~SDL_WINDOW_MINIMIZED;
689  }
690 
691  if ([nswindow isKeyWindow]) {
692  window->flags |= SDL_WINDOW_INPUT_FOCUS;
694  }
695 
696  /* Prevents the window's "window device" from being destroyed when it is
697  * hidden. See http://www.mikeash.com/pyblog/nsopenglcontext-and-one-shot.html
698  */
699  [nswindow setOneShot:NO];
700 
701  /* All done! */
702  [pool release];
703  window->driverdata = data;
704  return 0;
705 }
706 
707 int
709 {
710  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
711  NSWindow *nswindow;
713  NSRect rect;
714  SDL_Rect bounds;
715  unsigned int style;
716 
717  Cocoa_GetDisplayBounds(_this, display, &bounds);
718  rect.origin.x = window->x;
719  rect.origin.y = window->y;
720  rect.size.width = window->w;
721  rect.size.height = window->h;
722  ConvertNSRect(&rect);
723 
724  style = GetWindowStyle(window);
725 
726  /* Figure out which screen to place this window */
727  NSArray *screens = [NSScreen screens];
728  NSScreen *screen = nil;
729  NSScreen *candidate;
730  int i, count = [screens count];
731  for (i = 0; i < count; ++i) {
732  candidate = [screens objectAtIndex:i];
733  NSRect screenRect = [candidate frame];
734  if (rect.origin.x >= screenRect.origin.x &&
735  rect.origin.x < screenRect.origin.x + screenRect.size.width &&
736  rect.origin.y >= screenRect.origin.y &&
737  rect.origin.y < screenRect.origin.y + screenRect.size.height) {
738  screen = candidate;
739  rect.origin.x -= screenRect.origin.x;
740  rect.origin.y -= screenRect.origin.y;
741  }
742  }
743  nswindow = [[SDLWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:NO screen:screen];
744  [nswindow setBackgroundColor:[NSColor blackColor]];
745 
746  /* Create a default view for this window */
747  rect = [nswindow contentRectForFrameRect:[nswindow frame]];
748  NSView *contentView = [[SDLView alloc] initWithFrame:rect];
749 
750  if ((window->flags & SDL_WINDOW_ALLOW_HIGHDPI) > 0) {
751  if ([contentView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
752  [contentView setWantsBestResolutionOpenGLSurface:YES];
753  }
754  }
755 
756  [nswindow setContentView: contentView];
757  [contentView release];
758 
759  [pool release];
760 
761  if (SetupWindowData(_this, window, nswindow, SDL_TRUE) < 0) {
762  [nswindow release];
763  return -1;
764  }
765  return 0;
766 }
767 
768 int
769 Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
770 {
771  NSAutoreleasePool *pool;
772  NSWindow *nswindow = (NSWindow *) data;
773  NSString *title;
774 
775  pool = [[NSAutoreleasePool alloc] init];
776 
777  /* Query the title from the existing window */
778  title = [nswindow title];
779  if (title) {
780  window->title = SDL_strdup([title UTF8String]);
781  }
782 
783  [pool release];
784 
785  return SetupWindowData(_this, window, nswindow, SDL_FALSE);
786 }
787 
788 void
790 {
791  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
792  NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
793  NSString *string;
794 
795  if(window->title) {
796  string = [[NSString alloc] initWithUTF8String:window->title];
797  } else {
798  string = [[NSString alloc] init];
799  }
800  [nswindow setTitle:string];
801  [string release];
802 
803  [pool release];
804 }
805 
806 void
808 {
809  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
810  NSImage *nsimage = Cocoa_CreateImage(icon);
811 
812  if (nsimage) {
813  [NSApp setApplicationIconImage:nsimage];
814  }
815 
816  [pool release];
817 }
818 
819 void
821 {
822  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
823  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
824  NSWindow *nswindow = windata->nswindow;
825  NSRect rect;
826  Uint32 moveHack;
827 
828  rect.origin.x = window->x;
829  rect.origin.y = window->y;
830  rect.size.width = window->w;
831  rect.size.height = window->h;
832  ConvertNSRect(&rect);
833 
834  moveHack = s_moveHack;
835  s_moveHack = 0;
836  [nswindow setFrameOrigin:rect.origin];
837  s_moveHack = moveHack;
838 
839  ScheduleContextUpdates(windata);
840 
841  [pool release];
842 }
843 
844 void
846 {
847  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
848  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
849  NSWindow *nswindow = windata->nswindow;
850  NSSize size;
851 
852  size.width = window->w;
853  size.height = window->h;
854  [nswindow setContentSize:size];
855 
856  ScheduleContextUpdates(windata);
857 
858  [pool release];
859 }
860 
861 void
863 {
864  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
865  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
866 
867  NSSize minSize;
868  minSize.width = window->min_w;
869  minSize.height = window->min_h;
870 
871  [windata->nswindow setContentMinSize:minSize];
872 
873  [pool release];
874 }
875 
876 void
878 {
879  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
880  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
881 
882  NSSize maxSize;
883  maxSize.width = window->max_w;
884  maxSize.height = window->max_h;
885 
886  [windata->nswindow setContentMaxSize:maxSize];
887 
888  [pool release];
889 }
890 
891 void
893 {
894  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
895  SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata);
896  NSWindow *nswindow = windowData->nswindow;
897 
898  if (![nswindow isMiniaturized]) {
899  [windowData->listener pauseVisibleObservation];
900  [nswindow makeKeyAndOrderFront:nil];
901  [windowData->listener resumeVisibleObservation];
902  }
903  [pool release];
904 }
905 
906 void
908 {
909  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
910  NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
911 
912  [nswindow orderOut:nil];
913  [pool release];
914 }
915 
916 void
918 {
919  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
920  SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata);
921  NSWindow *nswindow = windowData->nswindow;
922 
923  // makeKeyAndOrderFront: has the side-effect of deminiaturizing and showing
924  // a minimized or hidden window, so check for that before showing it.
925  [windowData->listener pauseVisibleObservation];
926  if (![nswindow isMiniaturized] && [nswindow isVisible]) {
927  [nswindow makeKeyAndOrderFront:nil];
928  }
929  [windowData->listener resumeVisibleObservation];
930 
931  [pool release];
932 }
933 
934 void
936 {
937  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
938  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
939  NSWindow *nswindow = windata->nswindow;
940 
941  [nswindow zoom:nil];
942 
943  ScheduleContextUpdates(windata);
944 
945  [pool release];
946 }
947 
948 void
950 {
951  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
952  NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
953 
954  [nswindow miniaturize:nil];
955  [pool release];
956 }
957 
958 void
960 {
961  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
962  NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
963 
964  if ([nswindow isMiniaturized]) {
965  [nswindow deminiaturize:nil];
966  } else if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed]) {
967  [nswindow zoom:nil];
968  }
969  [pool release];
970 }
971 
972 static NSWindow *
973 Cocoa_RebuildWindow(SDL_WindowData * data, NSWindow * nswindow, unsigned style)
974 {
975  if (!data->created) {
976  /* Don't mess with other people's windows... */
977  return nswindow;
978  }
979 
980  [data->listener close];
981  data->nswindow = [[SDLWindow alloc] initWithContentRect:[[nswindow contentView] frame] styleMask:style backing:NSBackingStoreBuffered defer:NO screen:[nswindow screen]];
982  [data->nswindow setContentView:[nswindow contentView]];
983  /* See comment in SetupWindowData. */
984  [data->nswindow setOneShot:NO];
985  [data->listener listen:data];
986 
987  [nswindow close];
988 
989  return data->nswindow;
990 }
991 
992 void
994 {
995  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
996  NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
997  if ([nswindow respondsToSelector:@selector(setStyleMask:)]) {
998  [nswindow setStyleMask:GetWindowStyle(window)];
999  if (bordered) {
1000  Cocoa_SetWindowTitle(_this, window); /* this got blanked out. */
1001  }
1002  }
1003  [pool release];
1004 }
1005 
1006 void
1007 Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
1008 {
1009  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1010  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1011  NSWindow *nswindow = data->nswindow;
1012  NSRect rect;
1013 
1014  /* The view responder chain gets messed with during setStyleMask */
1015  if ([[nswindow contentView] nextResponder] == data->listener) {
1016  [[nswindow contentView] setNextResponder:nil];
1017  }
1018 
1019  if (fullscreen) {
1020  SDL_Rect bounds;
1021 
1022  Cocoa_GetDisplayBounds(_this, display, &bounds);
1023  rect.origin.x = bounds.x;
1024  rect.origin.y = bounds.y;
1025  rect.size.width = bounds.w;
1026  rect.size.height = bounds.h;
1027  ConvertNSRect(&rect);
1028 
1029  /* Hack to fix origin on Mac OS X 10.4 */
1030  NSRect screenRect = [[nswindow screen] frame];
1031  if (screenRect.size.height >= 1.0f) {
1032  rect.origin.y += (screenRect.size.height - rect.size.height);
1033  }
1034 
1035  if ([nswindow respondsToSelector: @selector(setStyleMask:)]) {
1036  [nswindow performSelector: @selector(setStyleMask:) withObject: (id)NSBorderlessWindowMask];
1037  } else {
1038  nswindow = Cocoa_RebuildWindow(data, nswindow, NSBorderlessWindowMask);
1039  }
1040  } else {
1041  rect.origin.x = window->windowed.x;
1042  rect.origin.y = window->windowed.y;
1043  rect.size.width = window->windowed.w;
1044  rect.size.height = window->windowed.h;
1045  ConvertNSRect(&rect);
1046 
1047  if ([nswindow respondsToSelector: @selector(setStyleMask:)]) {
1048  [nswindow performSelector: @selector(setStyleMask:) withObject: (id)(uintptr_t)GetWindowStyle(window)];
1049  } else {
1050  nswindow = Cocoa_RebuildWindow(data, nswindow, GetWindowStyle(window));
1051  }
1052  }
1053 
1054  /* The view responder chain gets messed with during setStyleMask */
1055  if ([[nswindow contentView] nextResponder] != data->listener) {
1056  [[nswindow contentView] setNextResponder:data->listener];
1057  }
1058 
1059  s_moveHack = 0;
1060  [nswindow setFrameOrigin:rect.origin];
1061  [nswindow setContentSize:rect.size];
1062  s_moveHack = SDL_GetTicks();
1063 
1064  /* When the window style changes the title is cleared */
1065  if (!fullscreen) {
1066  Cocoa_SetWindowTitle(_this, window);
1067  }
1068 
1069  if (SDL_ShouldAllowTopmost() && fullscreen) {
1070  /* OpenGL is rendering to the window, so make it visible! */
1071  [nswindow setLevel:CGShieldingWindowLevel()];
1072  } else {
1073  [nswindow setLevel:kCGNormalWindowLevel];
1074  }
1075 
1076  if ([nswindow isVisible] || fullscreen) {
1077  [data->listener pauseVisibleObservation];
1078  [nswindow makeKeyAndOrderFront:nil];
1079  [data->listener resumeVisibleObservation];
1080  }
1081 
1082  ScheduleContextUpdates(data);
1083 
1084  [pool release];
1085 }
1086 
1087 int
1088 Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
1089 {
1090  SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
1091  CGDirectDisplayID display_id = ((SDL_DisplayData *)display->driverdata)->display;
1092  const uint32_t tableSize = 256;
1093  CGGammaValue redTable[tableSize];
1094  CGGammaValue greenTable[tableSize];
1095  CGGammaValue blueTable[tableSize];
1096  uint32_t i;
1097  float inv65535 = 1.0f / 65535.0f;
1098 
1099  /* Extract gamma values into separate tables, convert to floats between 0.0 and 1.0 */
1100  for (i = 0; i < 256; i++) {
1101  redTable[i] = ramp[0*256+i] * inv65535;
1102  greenTable[i] = ramp[1*256+i] * inv65535;
1103  blueTable[i] = ramp[2*256+i] * inv65535;
1104  }
1105 
1106  if (CGSetDisplayTransferByTable(display_id, tableSize,
1107  redTable, greenTable, blueTable) != CGDisplayNoErr) {
1108  return SDL_SetError("CGSetDisplayTransferByTable()");
1109  }
1110  return 0;
1111 }
1112 
1113 int
1115 {
1116  SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
1117  CGDirectDisplayID display_id = ((SDL_DisplayData *)display->driverdata)->display;
1118  const uint32_t tableSize = 256;
1119  CGGammaValue redTable[tableSize];
1120  CGGammaValue greenTable[tableSize];
1121  CGGammaValue blueTable[tableSize];
1122  uint32_t i, tableCopied;
1123 
1124  if (CGGetDisplayTransferByTable(display_id, tableSize,
1125  redTable, greenTable, blueTable, &tableCopied) != CGDisplayNoErr) {
1126  return SDL_SetError("CGGetDisplayTransferByTable()");
1127  }
1128 
1129  for (i = 0; i < tableCopied; i++) {
1130  ramp[0*256+i] = (Uint16)(redTable[i] * 65535.0f);
1131  ramp[1*256+i] = (Uint16)(greenTable[i] * 65535.0f);
1132  ramp[2*256+i] = (Uint16)(blueTable[i] * 65535.0f);
1133  }
1134  return 0;
1135 }
1136 
1137 void
1138 Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
1139 {
1140  /* Move the cursor to the nearest point in the window */
1141  if (grabbed) {
1142  int x, y;
1143  CGPoint cgpoint;
1144 
1145  SDL_GetMouseState(&x, &y);
1146  cgpoint.x = window->x + x;
1147  cgpoint.y = window->y + y;
1148  CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
1149  }
1150 
1151  if ( window->flags & SDL_WINDOW_FULLSCREEN ) {
1152  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1153 
1155  /* OpenGL is rendering to the window, so make it visible! */
1156  [data->nswindow setLevel:CGShieldingWindowLevel()];
1157  } else {
1158  [data->nswindow setLevel:kCGNormalWindowLevel];
1159  }
1160  }
1161 }
1162 
1163 void
1165 {
1166  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1167  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1168 
1169  if (data) {
1170  [data->listener close];
1171  [data->listener release];
1172  if (data->created) {
1173  [data->nswindow close];
1174  }
1175 
1176  NSArray *contexts = [[data->nscontexts copy] autorelease];
1177  for (SDLOpenGLContext *context in contexts) {
1178  /* Calling setWindow:NULL causes the context to remove itself from the context list. */
1179  [context setWindow:NULL];
1180  }
1181  [data->nscontexts release];
1182 
1183  SDL_free(data);
1184  }
1185  [pool release];
1186 }
1187 
1188 SDL_bool
1190 {
1191  NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
1192 
1193  if (info->version.major <= SDL_MAJOR_VERSION) {
1194  info->subsystem = SDL_SYSWM_COCOA;
1195  info->info.cocoa.window = nswindow;
1196  return SDL_TRUE;
1197  } else {
1198  SDL_SetError("Application not compiled with SDL %d.%d\n",
1200  return SDL_FALSE;
1201  }
1202 }
1203 
1204 #endif /* SDL_VIDEO_DRIVER_COCOA */
1205 
1206 /* vi: set ts=4 sw=4 expandtab: */
int Cocoa_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
#define __inline__
Definition: begin_code.h:119
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:62
NSMutableArray * nscontexts
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:7294
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:611
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1824
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
void Cocoa_MinimizeWindow(_THIS, SDL_Window *window)
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
#define NULL
Definition: ftobjs.h:61
GLclampf f
Definition: glew.h:3390
void Cocoa_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
void Cocoa_SetWindowMaximumSize(_THIS, SDL_Window *window)
Sint64 SDL_FingerID
Definition: SDL_touch.h:42
SDL_bool
Definition: SDL_stdinc.h:116
void Cocoa_SetWindowBordered(_THIS, SDL_Window *window, SDL_bool bordered)
DECLSPEC SDL_Window *SDLCALL SDL_GetMouseFocus(void)
Get the window which currently has mouse focus.
Definition: SDL_mouse.c:68
#define SDL_BUTTON_RIGHT
Definition: SDL_mouse.h:206
EGLSurface EGLint x
Definition: eglext.h:293
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
GLuint in
Definition: glew.h:10672
DECLSPEC void SDLCALL SDL_free(void *mem)
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_bool down, float x, float y, float pressure)
Definition: SDL_touch.c:213
SDL_version version
Definition: SDL_syswm.h:161
Uint8 major
Definition: SDL_version.h:53
EGLSurface EGLint EGLint EGLint EGLint height
Definition: eglext.h:293
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:162
void Cocoa_SetWindowTitle(_THIS, SDL_Window *window)
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
SDL_Window * window
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:93
char * display
Definition: visualinfo.c:85
void Cocoa_SetWindowPosition(_THIS, SDL_Window *window)
if(!yyg->yy_init)
SDL_Rect windowed
Definition: SDL_sysvideo.h:84
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, float x, float y, float pressure)
Definition: SDL_touch.c:275
static SDL_VideoDevice * _this
Definition: SDL_video.c:92
void Cocoa_RestoreWindow(_THIS, SDL_Window *window)
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
DECLSPEC Uint32 SDLCALL SDL_GetMouseState(int *x, int *y)
Retrieve the current state of the mouse.
Definition: SDL_mouse.c:382
DECLSPEC Uint32 SDLCALL SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
Definition: SDL_systimer.c:44
void Cocoa_ShowWindow(_THIS, SDL_Window *window)
DECLSPEC SDL_bool SDLCALL SDL_IsShapedWindow(const SDL_Window *window)
Return whether the given window is a shaped window.
Definition: SDL_shape.c:57
NSImage * Cocoa_CreateImage(SDL_Surface *surface)
int
Definition: SDL_systhread.c:37
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
Definition: SDL_mouse.c:178
#define SDL_BUTTON_LEFT
Definition: SDL_mouse.h:204
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
Cocoa_WindowListener * listener
#define _THIS
struct SDL_VideoData * videodata
DECLSPEC char *SDLCALL SDL_strdup(const char *str)
Definition: SDL_string.c:511
int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window *window, const Uint16 *ramp)
void Cocoa_DestroyWindow(_THIS, SDL_Window *window)
GLint GLsizei count
Definition: gl2ext.h:1011
void Cocoa_RaiseWindow(_THIS, SDL_Window *window)
SDL_bool cursor_shown
Definition: SDL_mouse_c.h:75
SDL_bool relative_mode
Definition: SDL_mouse_c.h:68
SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
void Cocoa_CheckClipboardUpdate(struct SDL_VideoData *data)
SDL_WindowData * _data
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
#define SDL_BUTTON_MIDDLE
Definition: SDL_mouse.h:205
char * title
Definition: SDL_sysvideo.h:75
int x
Definition: SDL_rect.h:65
int SDL_AddTouch(SDL_TouchID touchID, const char *name)
Definition: SDL_touch.c:130
int w
Definition: SDL_rect.h:66
void Cocoa_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
union SDL_SysWMinfo::@78 info
NSWindow * nswindow
SDL_bool SDL_ShouldAllowTopmost(void)
Definition: SDL_video.c:3207
EGLSurface EGLint EGLint y
Definition: eglext.h:293
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
unsigned int uint32_t
int Cocoa_CreateWindow(_THIS, SDL_Window *window)
int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window *window, Uint16 *ramp)
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:996
int h
Definition: SDL_rect.h:66
void Cocoa_SetWindowSize(_THIS, SDL_Window *window)
GLsizei const GLcharARB ** string
Definition: glew.h:5638
int Cocoa_ResizeWindowShape(SDL_Window *window)
GLdouble GLdouble GLdouble r
Definition: glew.h:1392
GLint GLint GLint GLint GLint w
Definition: gl2ext.h:1215
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:137
void Cocoa_HideWindow(_THIS, SDL_Window *window)
DECLSPEC SDL_Window *SDLCALL SDL_GetKeyboardFocus(void)
Get the window which currently has keyboard focus.
Definition: SDL_keyboard.c:603
int Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
void * driverdata
Definition: SDL_sysvideo.h:99
void Cocoa_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
TParseContext * context
#define SDL_PRESSED
Definition: SDL_events.h:50
int i
Definition: pngrutil.c:1377
SDL_Cursor * cur_cursor
Definition: SDL_mouse_c.h:74
Uint32 flags
Definition: SDL_sysvideo.h:81
#define SDL_RELEASED
Definition: SDL_events.h:49
SDL_Touch * SDL_GetTouch(SDL_TouchID id)
Definition: SDL_touch.c:73
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
Definition: SDL_mouse.c:276
int y
Definition: SDL_rect.h:65
void Cocoa_MaximizeWindow(_THIS, SDL_Window *window)
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63
void Cocoa_SetWindowMinimumSize(_THIS, SDL_Window *window)
typedef BOOL(WINAPI *PFNWGLSETSTEREOEMITTERSTATE3DLPROC)(HDC hDC
GLsizei size
Definition: gl2ext.h:1467