SDL  2.0
SDL_cocoawindow.m
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 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_internal.h"
22 
23 #if SDL_VIDEO_DRIVER_COCOA
24 
25 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
26 # error SDL for Mac OS X must be built with a 10.7 SDK or above.
27 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1070 */
28 
29 #include "SDL_syswm.h"
30 #include "SDL_timer.h" /* For SDL_GetTicks() */
31 #include "SDL_hints.h"
32 #include "../SDL_sysvideo.h"
33 #include "../../events/SDL_keyboard_c.h"
34 #include "../../events/SDL_mouse_c.h"
35 #include "../../events/SDL_touch_c.h"
36 #include "../../events/SDL_windowevents_c.h"
37 #include "../../events/SDL_dropevents_c.h"
38 #include "SDL_cocoavideo.h"
39 #include "SDL_cocoashape.h"
40 #include "SDL_cocoamouse.h"
41 #include "SDL_cocoamousetap.h"
42 #include "SDL_cocoaopengl.h"
43 #include "SDL_cocoaopengles.h"
44 #include "SDL_assert.h"
45 
46 /* #define DEBUG_COCOAWINDOW */
47 
48 #ifdef DEBUG_COCOAWINDOW
49 #define DLog(fmt, ...) printf("%s: " fmt "\n", __func__, ##__VA_ARGS__)
50 #else
51 #define DLog(...) do { } while (0)
52 #endif
53 
54 
55 #define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN)
56 
57 #ifndef MAC_OS_X_VERSION_10_12
58 #define NSEventModifierFlagCapsLock NSAlphaShiftKeyMask
59 #endif
60 
61 @interface SDLWindow : NSWindow <NSDraggingDestination>
62 /* These are needed for borderless/fullscreen windows */
63 - (BOOL)canBecomeKeyWindow;
64 - (BOOL)canBecomeMainWindow;
65 - (void)sendEvent:(NSEvent *)event;
66 - (void)doCommandBySelector:(SEL)aSelector;
67 
68 /* Handle drag-and-drop of files onto the SDL window. */
69 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender;
70 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender;
71 - (BOOL)wantsPeriodicDraggingUpdates;
72 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem;
73 
74 - (SDL_Window*)findSDLWindow;
75 @end
76 
77 @implementation SDLWindow
78 
79 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
80 {
81  /* Only allow using the macOS native fullscreen toggle menubar item if the
82  * window is resizable and not in a SDL fullscreen mode.
83  */
84  if ([menuItem action] == @selector(toggleFullScreen:)) {
85  SDL_Window *window = [self findSDLWindow];
86  if (window == NULL) {
87  return NO;
88  } else if ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_FULLSCREEN_DESKTOP)) != 0) {
89  return NO;
90  } else if ((window->flags & SDL_WINDOW_RESIZABLE) == 0) {
91  return NO;
92  }
93  }
94  return [super validateMenuItem:menuItem];
95 }
96 
97 - (BOOL)canBecomeKeyWindow
98 {
99  return YES;
100 }
101 
102 - (BOOL)canBecomeMainWindow
103 {
104  return YES;
105 }
106 
107 - (void)sendEvent:(NSEvent *)event
108 {
109  [super sendEvent:event];
110 
111  if ([event type] != NSEventTypeLeftMouseUp) {
112  return;
113  }
114 
115  id delegate = [self delegate];
116  if (![delegate isKindOfClass:[Cocoa_WindowListener class]]) {
117  return;
118  }
119 
120  if ([delegate isMoving]) {
121  [delegate windowDidFinishMoving];
122  }
123 }
124 
125 /* We'll respond to selectors by doing nothing so we don't beep.
126  * The escape key gets converted to a "cancel" selector, etc.
127  */
128 - (void)doCommandBySelector:(SEL)aSelector
129 {
130  /*NSLog(@"doCommandBySelector: %@\n", NSStringFromSelector(aSelector));*/
131 }
132 
133 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
134 {
135  if (([sender draggingSourceOperationMask] & NSDragOperationGeneric) == NSDragOperationGeneric) {
136  return NSDragOperationGeneric;
137  }
138 
139  return NSDragOperationNone; /* no idea what to do with this, reject it. */
140 }
141 
142 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
143 { @autoreleasepool
144 {
145  NSPasteboard *pasteboard = [sender draggingPasteboard];
146  NSArray *types = [NSArray arrayWithObject:NSFilenamesPboardType];
147  NSString *desiredType = [pasteboard availableTypeFromArray:types];
148  SDL_Window *sdlwindow = [self findSDLWindow];
149 
150  if (desiredType == nil) {
151  return NO; /* can't accept anything that's being dropped here. */
152  }
153 
154  NSData *data = [pasteboard dataForType:desiredType];
155  if (data == nil) {
156  return NO;
157  }
158 
159  SDL_assert([desiredType isEqualToString:NSFilenamesPboardType]);
160  NSArray *array = [pasteboard propertyListForType:@"NSFilenamesPboardType"];
161 
162  for (NSString *path in array) {
163  NSURL *fileURL = [NSURL fileURLWithPath:path];
164  NSNumber *isAlias = nil;
165 
166  [fileURL getResourceValue:&isAlias forKey:NSURLIsAliasFileKey error:nil];
167 
168  /* If the URL is an alias, resolve it. */
169  if ([isAlias boolValue]) {
170  NSURLBookmarkResolutionOptions opts = NSURLBookmarkResolutionWithoutMounting | NSURLBookmarkResolutionWithoutUI;
171  NSData *bookmark = [NSURL bookmarkDataWithContentsOfURL:fileURL error:nil];
172  if (bookmark != nil) {
173  NSURL *resolvedURL = [NSURL URLByResolvingBookmarkData:bookmark
174  options:opts
175  relativeToURL:nil
176  bookmarkDataIsStale:nil
177  error:nil];
178 
179  if (resolvedURL != nil) {
180  fileURL = resolvedURL;
181  }
182  }
183  }
184 
185  if (!SDL_SendDropFile(sdlwindow, [[fileURL path] UTF8String])) {
186  return NO;
187  }
188  }
189 
190  SDL_SendDropComplete(sdlwindow);
191  return YES;
192 }}
193 
194 - (BOOL)wantsPeriodicDraggingUpdates
195 {
196  return NO;
197 }
198 
199 - (SDL_Window*)findSDLWindow
200 {
201  SDL_Window *sdlwindow = NULL;
203 
204  /* !!! FIXME: is there a better way to do this? */
205  if (_this) {
206  for (sdlwindow = _this->windows; sdlwindow; sdlwindow = sdlwindow->next) {
207  NSWindow *nswindow = ((SDL_WindowData *) sdlwindow->driverdata)->nswindow;
208  if (nswindow == self) {
209  break;
210  }
211  }
212  }
213 
214  return sdlwindow;
215 }
216 
217 @end
218 
219 
220 static Uint32 s_moveHack;
221 
222 static void ConvertNSRect(NSScreen *screen, BOOL fullscreen, NSRect *r)
223 {
224  r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
225 }
226 
227 static void
228 ScheduleContextUpdates(SDL_WindowData *data)
229 {
230  if (!data || !data->nscontexts) {
231  return;
232  }
233 
234  /* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */
235  #ifdef __clang__
236  #pragma clang diagnostic push
237  #pragma clang diagnostic ignored "-Wdeprecated-declarations"
238  #endif
239 
240  NSOpenGLContext *currentContext = [NSOpenGLContext currentContext];
241  NSMutableArray *contexts = data->nscontexts;
242  @synchronized (contexts) {
243  for (SDLOpenGLContext *context in contexts) {
244  if (context == currentContext) {
245  [context update];
246  } else {
247  [context scheduleUpdate];
248  }
249  }
250  }
251 
252  #ifdef __clang__
253  #pragma clang diagnostic pop
254  #endif
255 }
256 
257 /* !!! FIXME: this should use a hint callback. */
258 static int
259 GetHintCtrlClickEmulateRightClick()
260 {
262 }
263 
264 static NSUInteger
265 GetWindowWindowedStyle(SDL_Window * window)
266 {
267  NSUInteger style = 0;
268 
269  if (window->flags & SDL_WINDOW_BORDERLESS) {
270  style = NSWindowStyleMaskBorderless;
271  } else {
272  style = (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable);
273  }
274  if (window->flags & SDL_WINDOW_RESIZABLE) {
275  style |= NSWindowStyleMaskResizable;
276  }
277  return style;
278 }
279 
280 static NSUInteger
281 GetWindowStyle(SDL_Window * window)
282 {
283  NSUInteger style = 0;
284 
285  if (window->flags & SDL_WINDOW_FULLSCREEN) {
286  style = NSWindowStyleMaskBorderless;
287  } else {
288  style = GetWindowWindowedStyle(window);
289  }
290  return style;
291 }
292 
293 static SDL_bool
294 SetWindowStyle(SDL_Window * window, NSUInteger style)
295 {
296  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
297  NSWindow *nswindow = data->nswindow;
298 
299  /* The view responder chain gets messed with during setStyleMask */
300  if ([[nswindow contentView] nextResponder] == data->listener) {
301  [[nswindow contentView] setNextResponder:nil];
302  }
303 
304  [nswindow setStyleMask:style];
305 
306  /* The view responder chain gets messed with during setStyleMask */
307  if ([[nswindow contentView] nextResponder] != data->listener) {
308  [[nswindow contentView] setNextResponder:data->listener];
309  }
310 
311  return SDL_TRUE;
312 }
313 
314 
315 @implementation Cocoa_WindowListener
316 
317 - (void)listen:(SDL_WindowData *)data
318 {
319  NSNotificationCenter *center;
320  NSWindow *window = data->nswindow;
321  NSView *view = [window contentView];
322 
323  _data = data;
324  observingVisible = YES;
325  wasCtrlLeft = NO;
326  wasVisible = [window isVisible];
327  isFullscreenSpace = NO;
330  isMoving = NO;
331  isDragAreaRunning = NO;
332 
333  center = [NSNotificationCenter defaultCenter];
334 
335  if ([window delegate] != nil) {
336  [center addObserver:self selector:@selector(windowDidExpose:) name:NSWindowDidExposeNotification object:window];
337  [center addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:window];
338  [center addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:window];
339  [center addObserver:self selector:@selector(windowDidMiniaturize:) name:NSWindowDidMiniaturizeNotification object:window];
340  [center addObserver:self selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification object:window];
341  [center addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:window];
342  [center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:window];
343  [center addObserver:self selector:@selector(windowDidChangeBackingProperties:) name:NSWindowDidChangeBackingPropertiesNotification object:window];
344  [center addObserver:self selector:@selector(windowWillEnterFullScreen:) name:NSWindowWillEnterFullScreenNotification object:window];
345  [center addObserver:self selector:@selector(windowDidEnterFullScreen:) name:NSWindowDidEnterFullScreenNotification object:window];
346  [center addObserver:self selector:@selector(windowWillExitFullScreen:) name:NSWindowWillExitFullScreenNotification object:window];
347  [center addObserver:self selector:@selector(windowDidExitFullScreen:) name:NSWindowDidExitFullScreenNotification object:window];
348  [center addObserver:self selector:@selector(windowDidFailToEnterFullScreen:) name:@"NSWindowDidFailToEnterFullScreenNotification" object:window];
349  [center addObserver:self selector:@selector(windowDidFailToExitFullScreen:) name:@"NSWindowDidFailToExitFullScreenNotification" object:window];
350  } else {
351  [window setDelegate:self];
352  }
353 
354  /* Haven't found a delegate / notification that triggers when the window is
355  * ordered out (is not visible any more). You can be ordered out without
356  * minimizing, so DidMiniaturize doesn't work. (e.g. -[NSWindow orderOut:])
357  */
358  [window addObserver:self
359  forKeyPath:@"visible"
360  options:NSKeyValueObservingOptionNew
361  context:NULL];
362 
363  [window setNextResponder:self];
364  [window setAcceptsMouseMovedEvents:YES];
365 
366  [view setNextResponder:self];
367 
368  [view setAcceptsTouchEvents:YES];
369 }
370 
371 - (void)observeValueForKeyPath:(NSString *)keyPath
372  ofObject:(id)object
373  change:(NSDictionary *)change
374  context:(void *)context
375 {
376  if (!observingVisible) {
377  return;
378  }
379 
380  if (object == _data->nswindow && [keyPath isEqualToString:@"visible"]) {
381  int newVisibility = [[change objectForKey:@"new"] intValue];
382  if (newVisibility) {
384  } else {
386  }
387  }
388 }
389 
391 {
392  observingVisible = NO;
393  wasVisible = [_data->nswindow isVisible];
394 }
395 
397 {
398  BOOL isVisible = [_data->nswindow isVisible];
399  observingVisible = YES;
400  if (wasVisible != isVisible) {
401  if (isVisible) {
403  } else {
405  }
406 
407  wasVisible = isVisible;
408  }
409 }
410 
411 -(BOOL) setFullscreenSpace:(BOOL) state
412 {
414  NSWindow *nswindow = _data->nswindow;
415  SDL_VideoData *videodata = ((SDL_WindowData *) window->driverdata)->videodata;
416 
417  if (!videodata->allow_spaces) {
418  return NO; /* Spaces are forcibly disabled. */
420  return NO; /* we only allow you to make a Space on FULLSCREEN_DESKTOP windows. */
421  } else if (!state && ((window->last_fullscreen_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP)) {
422  return NO; /* we only handle leaving the Space on windows that were previously FULLSCREEN_DESKTOP. */
423  } else if (state == isFullscreenSpace) {
424  return YES; /* already there. */
425  }
426 
428  if (state) {
429  [self addPendingWindowOperation:PENDING_OPERATION_ENTER_FULLSCREEN];
430  } else {
431  [self addPendingWindowOperation:PENDING_OPERATION_LEAVE_FULLSCREEN];
432  }
433  return YES;
434  }
436 
437  /* you need to be FullScreenPrimary, or toggleFullScreen doesn't work. Unset it again in windowDidExitFullScreen. */
438  [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
439  [nswindow performSelectorOnMainThread: @selector(toggleFullScreen:) withObject:nswindow waitUntilDone:NO];
440  return YES;
441 }
442 
443 -(BOOL) isInFullscreenSpace
444 {
445  return isFullscreenSpace;
446 }
447 
449 {
450  return inFullscreenTransition;
451 }
452 
453 -(void) addPendingWindowOperation:(PendingWindowOperation) operation
454 {
455  pendingWindowOperation = operation;
456 }
457 
458 - (void)close
459 {
460  NSNotificationCenter *center;
461  NSWindow *window = _data->nswindow;
462  NSView *view = [window contentView];
463 
464  center = [NSNotificationCenter defaultCenter];
465 
466  if ([window delegate] != self) {
467  [center removeObserver:self name:NSWindowDidExposeNotification object:window];
468  [center removeObserver:self name:NSWindowDidMoveNotification object:window];
469  [center removeObserver:self name:NSWindowDidResizeNotification object:window];
470  [center removeObserver:self name:NSWindowDidMiniaturizeNotification object:window];
471  [center removeObserver:self name:NSWindowDidDeminiaturizeNotification object:window];
472  [center removeObserver:self name:NSWindowDidBecomeKeyNotification object:window];
473  [center removeObserver:self name:NSWindowDidResignKeyNotification object:window];
474  [center removeObserver:self name:NSWindowDidChangeBackingPropertiesNotification object:window];
475  [center removeObserver:self name:NSWindowWillEnterFullScreenNotification object:window];
476  [center removeObserver:self name:NSWindowDidEnterFullScreenNotification object:window];
477  [center removeObserver:self name:NSWindowWillExitFullScreenNotification object:window];
478  [center removeObserver:self name:NSWindowDidExitFullScreenNotification object:window];
479  [center removeObserver:self name:@"NSWindowDidFailToEnterFullScreenNotification" object:window];
480  [center removeObserver:self name:@"NSWindowDidFailToExitFullScreenNotification" object:window];
481  } else {
482  [window setDelegate:nil];
483  }
484 
485  [window removeObserver:self forKeyPath:@"visible"];
486 
487  if ([window nextResponder] == self) {
488  [window setNextResponder:nil];
489  }
490  if ([view nextResponder] == self) {
491  [view setNextResponder:nil];
492  }
493 }
494 
495 - (BOOL)isMoving
496 {
497  return isMoving;
498 }
499 
500 -(void) setPendingMoveX:(int)x Y:(int)y
501 {
504 }
505 
507 {
508  if ([self isMoving]) {
509  isMoving = NO;
510 
511  SDL_Mouse *mouse = SDL_GetMouse();
515  }
516  if (mouse->relative_mode && !mouse->relative_mode_warp && mouse->focus == _data->window) {
518  }
519  }
520 }
521 
522 - (BOOL)windowShouldClose:(id)sender
523 {
525  return NO;
526 }
527 
528 - (void)windowDidExpose:(NSNotification *)aNotification
529 {
531 }
532 
533 - (void)windowWillMove:(NSNotification *)aNotification
534 {
535  if ([_data->nswindow isKindOfClass:[SDLWindow class]]) {
537  isMoving = YES;
538  }
539 }
540 
541 - (void)windowDidMove:(NSNotification *)aNotification
542 {
543  int x, y;
545  NSWindow *nswindow = _data->nswindow;
546  BOOL fullscreen = window->flags & FULLSCREEN_MASK;
547  NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
548  ConvertNSRect([nswindow screen], fullscreen, &rect);
549 
551  /* We'll take care of this at the end of the transition */
552  return;
553  }
554 
555  if (s_moveHack) {
556  SDL_bool blockMove = ((SDL_GetTicks() - s_moveHack) < 500);
557 
558  s_moveHack = 0;
559 
560  if (blockMove) {
561  /* Cocoa is adjusting the window in response to a mode change */
562  rect.origin.x = window->x;
563  rect.origin.y = window->y;
564  ConvertNSRect([nswindow screen], fullscreen, &rect);
565  [nswindow setFrameOrigin:rect.origin];
566  return;
567  }
568  }
569 
570  x = (int)rect.origin.x;
571  y = (int)rect.origin.y;
572 
573  ScheduleContextUpdates(_data);
574 
576 }
577 
578 - (void)windowDidResize:(NSNotification *)aNotification
579 {
581  /* We'll take care of this at the end of the transition */
582  return;
583  }
584 
586  NSWindow *nswindow = _data->nswindow;
587  int x, y, w, h;
588  NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
589  ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect);
590  x = (int)rect.origin.x;
591  y = (int)rect.origin.y;
592  w = (int)rect.size.width;
593  h = (int)rect.size.height;
594 
595  if (SDL_IsShapedWindow(window)) {
597  }
598 
599  ScheduleContextUpdates(_data);
600 
601  /* The window can move during a resize event, such as when maximizing
602  or resizing from a corner */
605 
606  const BOOL zoomed = [nswindow isZoomed];
607  if (!zoomed) {
609  } else if (zoomed) {
611  }
612 }
613 
614 - (void)windowDidMiniaturize:(NSNotification *)aNotification
615 {
617 }
618 
619 - (void)windowDidDeminiaturize:(NSNotification *)aNotification
620 {
622 }
623 
624 - (void)windowDidBecomeKey:(NSNotification *)aNotification
625 {
627  SDL_Mouse *mouse = SDL_GetMouse();
628 
629  /* We're going to get keyboard events, since we're key. */
630  /* This needs to be done before restoring the relative mouse mode. */
632 
633  if (mouse->relative_mode && !mouse->relative_mode_warp && ![self isMoving]) {
635  }
636 
637  /* If we just gained focus we need the updated mouse position */
638  if (!mouse->relative_mode) {
639  NSPoint point;
640  int x, y;
641 
642  point = [_data->nswindow mouseLocationOutsideOfEventStream];
643  x = (int)point.x;
644  y = (int)(window->h - point.y);
645 
646  if (x >= 0 && x < window->w && y >= 0 && y < window->h) {
647  SDL_SendMouseMotion(window, mouse->mouseID, 0, x, y);
648  }
649  }
650 
651  /* Check to see if someone updated the clipboard */
653 
655  [NSMenu setMenuBarVisible:NO];
656  }
657 
658  const unsigned int newflags = [NSEvent modifierFlags] & NSEventModifierFlagCapsLock;
660  SDL_ToggleModState(KMOD_CAPS, newflags != 0);
661 }
662 
663 - (void)windowDidResignKey:(NSNotification *)aNotification
664 {
665  SDL_Mouse *mouse = SDL_GetMouse();
666  if (mouse->relative_mode && !mouse->relative_mode_warp) {
668  }
669 
670  /* Some other window will get mouse events, since we're not key. */
671  if (SDL_GetMouseFocus() == _data->window) {
673  }
674 
675  /* Some other window will get keyboard events, since we're not key. */
676  if (SDL_GetKeyboardFocus() == _data->window) {
678  }
679 
680  if (isFullscreenSpace) {
681  [NSMenu setMenuBarVisible:YES];
682  }
683 }
684 
685 - (void)windowDidChangeBackingProperties:(NSNotification *)aNotification
686 {
687  NSNumber *oldscale = [[aNotification userInfo] objectForKey:NSBackingPropertyOldScaleFactorKey];
688 
690  return;
691  }
692 
693  if ([oldscale doubleValue] != [_data->nswindow backingScaleFactor]) {
694  /* Force a resize event when the backing scale factor changes. */
695  _data->window->w = 0;
696  _data->window->h = 0;
697  [self windowDidResize:aNotification];
698  }
699 }
700 
701 - (void)windowWillEnterFullScreen:(NSNotification *)aNotification
702 {
704 
705  SetWindowStyle(window, (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable));
706 
707  isFullscreenSpace = YES;
709 }
710 
711 - (void)windowDidFailToEnterFullScreen:(NSNotification *)aNotification
712 {
714 
715  if (window->is_destroying) {
716  return;
717  }
718 
719  SetWindowStyle(window, GetWindowStyle(window));
720 
721  isFullscreenSpace = NO;
723 
724  [self windowDidExitFullScreen:nil];
725 }
726 
727 - (void)windowDidEnterFullScreen:(NSNotification *)aNotification
728 {
730  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
731  NSWindow *nswindow = data->nswindow;
732 
734 
737  [self setFullscreenSpace:NO];
738  } else {
739  /* Unset the resizable flag.
740  This is a workaround for https://bugzilla.libsdl.org/show_bug.cgi?id=3697
741  */
742  SetWindowStyle(window, [nswindow styleMask] & (~NSWindowStyleMaskResizable));
743 
745  [NSMenu setMenuBarVisible:NO];
746  }
747 
749  /* Force the size change event in case it was delivered earlier
750  while the window was still animating into place.
751  */
752  window->w = 0;
753  window->h = 0;
754  [self windowDidMove:aNotification];
755  [self windowDidResize:aNotification];
756  }
757 }
758 
759 - (void)windowWillExitFullScreen:(NSNotification *)aNotification
760 {
762 
763  isFullscreenSpace = NO;
765 
766  /* As of macOS 10.11, the window seems to need to be resizable when exiting
767  a Space, in order for it to resize back to its windowed-mode size.
768  As of macOS 10.15, the window decorations can go missing sometimes after
769  certain fullscreen-desktop->exlusive-fullscreen->windowed mode flows
770  sometimes. Making sure the style mask always uses the windowed mode style
771  when returning to windowed mode from a space (instead of using a pending
772  fullscreen mode style mask) seems to work around that issue.
773  */
774  SetWindowStyle(window, GetWindowWindowedStyle(window) | NSWindowStyleMaskResizable);
775 }
776 
777 - (void)windowDidFailToExitFullScreen:(NSNotification *)aNotification
778 {
780 
781  if (window->is_destroying) {
782  return;
783  }
784 
785  SetWindowStyle(window, (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable));
786 
787  isFullscreenSpace = YES;
789 
790  [self windowDidEnterFullScreen:nil];
791 }
792 
793 - (void)windowDidExitFullScreen:(NSNotification *)aNotification
794 {
796  NSWindow *nswindow = _data->nswindow;
797  NSButton *button = nil;
798 
800 
801  /* As of macOS 10.15, the window decorations can go missing sometimes after
802  certain fullscreen-desktop->exlusive-fullscreen->windowed mode flows
803  sometimes. Making sure the style mask always uses the windowed mode style
804  when returning to windowed mode from a space (instead of using a pending
805  fullscreen mode style mask) seems to work around that issue.
806  */
807  SetWindowStyle(window, GetWindowWindowedStyle(window));
808 
809  if (window->flags & SDL_WINDOW_ALWAYS_ON_TOP) {
810  [nswindow setLevel:NSFloatingWindowLevel];
811  } else {
812  [nswindow setLevel:kCGNormalWindowLevel];
813  }
814 
817  [self setFullscreenSpace:YES];
820  [nswindow miniaturize:nil];
821  } else {
822  /* Adjust the fullscreen toggle button and readd menu now that we're here. */
823  if (window->flags & SDL_WINDOW_RESIZABLE) {
824  /* resizable windows are Spaces-friendly: they get the "go fullscreen" toggle button on their titlebar. */
825  [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
826  } else {
827  [nswindow setCollectionBehavior:NSWindowCollectionBehaviorManaged];
828  }
829  [NSMenu setMenuBarVisible:YES];
830 
832 
833 #if 0
834 /* This fixed bug 3719, which is that changing window size while fullscreen
835  doesn't take effect when leaving fullscreen, but introduces bug 3809,
836  which is that a maximized window doesn't go back to normal size when
837  restored, so this code is disabled until we can properly handle the
838  beginning and end of maximize and restore.
839  */
840  /* Restore windowed size and position in case it changed while fullscreen */
841  {
842  NSRect rect;
843  rect.origin.x = window->windowed.x;
844  rect.origin.y = window->windowed.y;
845  rect.size.width = window->windowed.w;
846  rect.size.height = window->windowed.h;
847  ConvertNSRect([nswindow screen], NO, &rect);
848 
849  s_moveHack = 0;
850  [nswindow setContentSize:rect.size];
851  [nswindow setFrameOrigin:rect.origin];
852  s_moveHack = SDL_GetTicks();
853  }
854 #endif /* 0 */
855 
856  /* Force the size change event in case it was delivered earlier
857  while the window was still animating into place.
858  */
859  window->w = 0;
860  window->h = 0;
861  [self windowDidMove:aNotification];
862  [self windowDidResize:aNotification];
863 
864  /* FIXME: Why does the window get hidden? */
865  if (window->flags & SDL_WINDOW_SHOWN) {
867  }
868  }
869 
870  /* There's some state that isn't quite back to normal when
871  windowDidExitFullScreen triggers. For example, the minimize button on
872  the titlebar doesn't actually enable for another 200 milliseconds or
873  so on this MacBook. Camp here and wait for that to happen before
874  going on, in case we're exiting fullscreen to minimize, which need
875  that window state to be normal before it will work. */
876  button = [nswindow standardWindowButton:NSWindowMiniaturizeButton];
877  if (button) {
878  int iterations = 0;
879  while (![button isEnabled] && (iterations < 100)) {
880  SDL_Delay(10);
881  SDL_PumpEvents();
882  iterations++;
883  }
884  }
885 }
886 
887 -(NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions
888 {
890  return NSApplicationPresentationFullScreen | NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar;
891  } else {
892  return proposedOptions;
893  }
894 }
895 
896 /* We'll respond to key events by mostly doing nothing so we don't beep.
897  * We could handle key messages here, but we lose some in the NSApp dispatch,
898  * where they get converted to action messages, etc.
899  */
900 - (void)flagsChanged:(NSEvent *)theEvent
901 {
902  /*Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);*/
903 
904  /* Catch capslock in here as a special case:
905  https://developer.apple.com/library/archive/qa/qa1519/_index.html
906  Note that technote's check of keyCode doesn't work. At least on the
907  10.15 beta, capslock comes through here as keycode 255, but it's safe
908  to send duplicate key events; SDL filters them out quickly in
909  SDL_SendKeyboardKey(). */
910 
911  /* Also note that SDL_SendKeyboardKey expects all capslock events to be
912  keypresses; it won't toggle the mod state if you send a keyrelease. */
913  const SDL_bool osenabled = ([theEvent modifierFlags] & NSEventModifierFlagCapsLock) ? SDL_TRUE : SDL_FALSE;
914  const SDL_bool sdlenabled = (SDL_GetModState() & KMOD_CAPS) ? SDL_TRUE : SDL_FALSE;
915  if (!osenabled && sdlenabled) {
918  } else if (osenabled && !sdlenabled) {
920  }
921 }
922 - (void)keyDown:(NSEvent *)theEvent
923 {
924  /*Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);*/
925 }
926 - (void)keyUp:(NSEvent *)theEvent
927 {
928  /*Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);*/
929 }
930 
931 /* We'll respond to selectors by doing nothing so we don't beep.
932  * The escape key gets converted to a "cancel" selector, etc.
933  */
934 - (void)doCommandBySelector:(SEL)aSelector
935 {
936  /*NSLog(@"doCommandBySelector: %@\n", NSStringFromSelector(aSelector));*/
937 }
938 
939 - (BOOL)processHitTest:(NSEvent *)theEvent
940 {
941  SDL_assert(isDragAreaRunning == [_data->nswindow isMovableByWindowBackground]);
942 
943  if (_data->window->hit_test) { /* if no hit-test, skip this. */
944  const NSPoint location = [theEvent locationInWindow];
945  const SDL_Point point = { (int) location.x, _data->window->h - (((int) location.y)-1) };
947  if (rc == SDL_HITTEST_DRAGGABLE) {
948  if (!isDragAreaRunning) {
949  isDragAreaRunning = YES;
950  [_data->nswindow setMovableByWindowBackground:YES];
951  }
952  return YES; /* dragging! */
953  }
954  }
955 
956  if (isDragAreaRunning) {
957  isDragAreaRunning = NO;
958  [_data->nswindow setMovableByWindowBackground:NO];
959  return YES; /* was dragging, drop event. */
960  }
961 
962  return NO; /* not a special area, carry on. */
963 }
964 
965 - (void)mouseDown:(NSEvent *)theEvent
966 {
967  const SDL_Mouse *mouse = SDL_GetMouse();
968  if (!mouse) {
969  return;
970  }
971 
972  const SDL_MouseID mouseID = mouse->mouseID;
973  int button;
974  int clicks;
975 
976  /* Ignore events that aren't inside the client area (i.e. title bar.) */
977  if ([theEvent window]) {
978  NSRect windowRect = [[[theEvent window] contentView] frame];
979  if (!NSMouseInRect([theEvent locationInWindow], windowRect, NO)) {
980  return;
981  }
982  }
983 
984  if ([self processHitTest:theEvent]) {
986  return; /* dragging, drop event. */
987  }
988 
989  switch ([theEvent buttonNumber]) {
990  case 0:
991  if (([theEvent modifierFlags] & NSEventModifierFlagControl) &&
992  GetHintCtrlClickEmulateRightClick()) {
993  wasCtrlLeft = YES;
995  } else {
996  wasCtrlLeft = NO;
998  }
999  break;
1000  case 1:
1002  break;
1003  case 2:
1005  break;
1006  default:
1007  button = (int) [theEvent buttonNumber] + 1;
1008  break;
1009  }
1010 
1011  clicks = (int) [theEvent clickCount];
1012 
1014 }
1015 
1016 - (void)rightMouseDown:(NSEvent *)theEvent
1017 {
1018  [self mouseDown:theEvent];
1019 }
1020 
1021 - (void)otherMouseDown:(NSEvent *)theEvent
1022 {
1023  [self mouseDown:theEvent];
1024 }
1025 
1026 - (void)mouseUp:(NSEvent *)theEvent
1027 {
1028  const SDL_Mouse *mouse = SDL_GetMouse();
1029  if (!mouse) {
1030  return;
1031  }
1032 
1033  const SDL_MouseID mouseID = mouse->mouseID;
1034  int button;
1035  int clicks;
1036 
1037  if ([self processHitTest:theEvent]) {
1039  return; /* stopped dragging, drop event. */
1040  }
1041 
1042  switch ([theEvent buttonNumber]) {
1043  case 0:
1044  if (wasCtrlLeft) {
1046  wasCtrlLeft = NO;
1047  } else {
1049  }
1050  break;
1051  case 1:
1053  break;
1054  case 2:
1056  break;
1057  default:
1058  button = (int) [theEvent buttonNumber] + 1;
1059  break;
1060  }
1061 
1062  clicks = (int) [theEvent clickCount];
1063 
1065 }
1066 
1067 - (void)rightMouseUp:(NSEvent *)theEvent
1068 {
1069  [self mouseUp:theEvent];
1070 }
1071 
1072 - (void)otherMouseUp:(NSEvent *)theEvent
1073 {
1074  [self mouseUp:theEvent];
1075 }
1076 
1077 - (void)mouseMoved:(NSEvent *)theEvent
1078 {
1079  SDL_Mouse *mouse = SDL_GetMouse();
1080  if (!mouse) {
1081  return;
1082  }
1083 
1084  const SDL_MouseID mouseID = mouse->mouseID;
1086  NSPoint point;
1087  int x, y;
1088 
1089  if ([self processHitTest:theEvent]) {
1091  return; /* dragging, drop event. */
1092  }
1093 
1094  if (mouse->relative_mode) {
1095  return;
1096  }
1097 
1098  point = [theEvent locationInWindow];
1099  x = (int)point.x;
1100  y = (int)(window->h - point.y);
1101 
1102  if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
1103  if (x < 0 || x >= window->w || y < 0 || y >= window->h) {
1104  if (x < 0) {
1105  x = 0;
1106  } else if (x >= window->w) {
1107  x = window->w - 1;
1108  }
1109  if (y < 0) {
1110  y = 0;
1111  } else if (y >= window->h) {
1112  y = window->h - 1;
1113  }
1114 
1115 #if !SDL_MAC_NO_SANDBOX
1116  CGPoint cgpoint;
1117 
1118  /* When SDL_MAC_NO_SANDBOX is set, this is handled by
1119  * SDL_cocoamousetap.m.
1120  */
1121 
1122  cgpoint.x = window->x + x;
1123  cgpoint.y = window->y + y;
1124 
1125  CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
1126  CGAssociateMouseAndMouseCursorPosition(YES);
1127 
1128  Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
1129 #endif
1130  }
1131  }
1132 
1133  SDL_SendMouseMotion(window, mouseID, 0, x, y);
1134 }
1135 
1136 - (void)mouseDragged:(NSEvent *)theEvent
1137 {
1138  [self mouseMoved:theEvent];
1139 }
1140 
1141 - (void)rightMouseDragged:(NSEvent *)theEvent
1142 {
1143  [self mouseMoved:theEvent];
1144 }
1145 
1146 - (void)otherMouseDragged:(NSEvent *)theEvent
1147 {
1148  [self mouseMoved:theEvent];
1149 }
1150 
1151 - (void)scrollWheel:(NSEvent *)theEvent
1152 {
1153  Cocoa_HandleMouseWheel(_data->window, theEvent);
1154 }
1155 
1156 - (void)touchesBeganWithEvent:(NSEvent *) theEvent
1157 {
1158  /* probably a MacBook trackpad; make this look like a synthesized event.
1159  This is backwards from reality, but better matches user expectations. */
1160  const BOOL istrackpad = ([theEvent subtype] == NSEventSubtypeMouseEvent);
1161 
1162  NSSet *touches = [theEvent touchesMatchingPhase:NSTouchPhaseAny inView:nil];
1163  const SDL_TouchID touchID = istrackpad ? SDL_MOUSE_TOUCHID : (SDL_TouchID)(intptr_t)[[touches anyObject] device];
1164  int existingTouchCount = 0;
1165 
1166  for (NSTouch* touch in touches) {
1167  if ([touch phase] != NSTouchPhaseBegan) {
1168  existingTouchCount++;
1169  }
1170  }
1171  if (existingTouchCount == 0) {
1172  int numFingers = SDL_GetNumTouchFingers(touchID);
1173  DLog("Reset Lost Fingers: %d", numFingers);
1174  for (--numFingers; numFingers >= 0; --numFingers) {
1175  SDL_Finger* finger = SDL_GetTouchFinger(touchID, numFingers);
1176  /* trackpad touches have no window. If we really wanted one we could
1177  * use the window that has mouse or keyboard focus.
1178  * Sending a null window currently also prevents synthetic mouse
1179  * events from being generated from touch events.
1180  */
1181  SDL_Window *window = NULL;
1182  SDL_SendTouch(touchID, finger->id, window, SDL_FALSE, 0, 0, 0);
1183  }
1184  }
1185 
1186  DLog("Began Fingers: %lu .. existing: %d", (unsigned long)[touches count], existingTouchCount);
1187  [self handleTouches:NSTouchPhaseBegan withEvent:theEvent];
1188 }
1189 
1190 - (void)touchesMovedWithEvent:(NSEvent *) theEvent
1191 {
1192  [self handleTouches:NSTouchPhaseMoved withEvent:theEvent];
1193 }
1194 
1195 - (void)touchesEndedWithEvent:(NSEvent *) theEvent
1196 {
1197  [self handleTouches:NSTouchPhaseEnded withEvent:theEvent];
1198 }
1199 
1200 - (void)touchesCancelledWithEvent:(NSEvent *) theEvent
1201 {
1202  [self handleTouches:NSTouchPhaseCancelled withEvent:theEvent];
1203 }
1204 
1205 - (void)handleTouches:(NSTouchPhase) phase withEvent:(NSEvent *) theEvent
1206 {
1207  NSSet *touches = [theEvent touchesMatchingPhase:phase inView:nil];
1208 
1209  /* probably a MacBook trackpad; make this look like a synthesized event.
1210  This is backwards from reality, but better matches user expectations. */
1211  const BOOL istrackpad = ([theEvent subtype] == NSEventSubtypeMouseEvent);
1212 
1213  for (NSTouch *touch in touches) {
1214  const SDL_TouchID touchId = istrackpad ? SDL_MOUSE_TOUCHID : (SDL_TouchID)(intptr_t)[touch device];
1216 
1217  /* trackpad touches have no window. If we really wanted one we could
1218  * use the window that has mouse or keyboard focus.
1219  * Sending a null window currently also prevents synthetic mouse events
1220  * from being generated from touch events.
1221  */
1222  SDL_Window *window = NULL;
1223 
1224 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101202 /* Added in the 10.12.2 SDK. */
1225  if ([touch respondsToSelector:@selector(type)]) {
1226  /* TODO: Before implementing direct touch support here, we need to
1227  * figure out whether the OS generates mouse events from them on its
1228  * own. If it does, we should prevent SendTouch from generating
1229  * synthetic mouse events for these touches itself (while also
1230  * sending a window.) It will also need to use normalized window-
1231  * relative coordinates via [touch locationInView:].
1232  */
1233  if ([touch type] == NSTouchTypeDirect) {
1234  continue;
1235  }
1236  }
1237 #endif
1238 
1239  if (SDL_AddTouch(touchId, devtype, "") < 0) {
1240  return;
1241  }
1242 
1243  const SDL_FingerID fingerId = (SDL_FingerID)(intptr_t)[touch identity];
1244  float x = [touch normalizedPosition].x;
1245  float y = [touch normalizedPosition].y;
1246  /* Make the origin the upper left instead of the lower left */
1247  y = 1.0f - y;
1248 
1249  switch (phase) {
1250  case NSTouchPhaseBegan:
1251  SDL_SendTouch(touchId, fingerId, window, SDL_TRUE, x, y, 1.0f);
1252  break;
1253  case NSTouchPhaseEnded:
1254  case NSTouchPhaseCancelled:
1255  SDL_SendTouch(touchId, fingerId, window, SDL_FALSE, x, y, 1.0f);
1256  break;
1257  case NSTouchPhaseMoved:
1258  SDL_SendTouchMotion(touchId, fingerId, window, x, y, 1.0f);
1259  break;
1260  default:
1261  break;
1262  }
1263  }
1264 }
1265 
1266 @end
1267 
1268 @interface SDLView : NSView {
1269  SDL_Window *_sdlWindow;
1270 }
1271 
1272 - (void)setSDLWindow:(SDL_Window*)window;
1273 
1274 /* The default implementation doesn't pass rightMouseDown to responder chain */
1275 - (void)rightMouseDown:(NSEvent *)theEvent;
1276 - (BOOL)mouseDownCanMoveWindow;
1277 - (void)drawRect:(NSRect)dirtyRect;
1278 - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent;
1279 - (BOOL)wantsUpdateLayer;
1280 - (void)updateLayer;
1281 @end
1282 
1283 @implementation SDLView
1284 
1285 - (void)setSDLWindow:(SDL_Window*)window
1286 {
1287  _sdlWindow = window;
1288 }
1289 
1290 /* this is used on older macOS revisions, and newer ones which emulate old
1291  NSOpenGLContext behaviour while still using a layer under the hood. 10.8 and
1292  later use updateLayer, up until 10.14.2 or so, which uses drawRect without
1293  a GraphicsContext and with a layer active instead (for OpenGL contexts). */
1294 - (void)drawRect:(NSRect)dirtyRect
1295 {
1296  /* Force the graphics context to clear to black so we don't get a flash of
1297  white until the app is ready to draw. In practice on modern macOS, this
1298  only gets called for window creation and other extraordinary events. */
1299  if ([NSGraphicsContext currentContext]) {
1300  [[NSColor blackColor] setFill];
1301  NSRectFill(dirtyRect);
1302  } else if (self.layer) {
1303  self.layer.backgroundColor = CGColorGetConstantColor(kCGColorBlack);
1304  }
1305 
1306  SDL_SendWindowEvent(_sdlWindow, SDL_WINDOWEVENT_EXPOSED, 0, 0);
1307 }
1308 
1309 - (BOOL)wantsUpdateLayer
1310 {
1311  return YES;
1312 }
1313 
1314 /* This is also called when a Metal layer is active. */
1315 - (void)updateLayer
1316 {
1317  /* Force the graphics context to clear to black so we don't get a flash of
1318  white until the app is ready to draw. In practice on modern macOS, this
1319  only gets called for window creation and other extraordinary events. */
1320  self.layer.backgroundColor = CGColorGetConstantColor(kCGColorBlack);
1321  ScheduleContextUpdates((SDL_WindowData *) _sdlWindow->driverdata);
1322  SDL_SendWindowEvent(_sdlWindow, SDL_WINDOWEVENT_EXPOSED, 0, 0);
1323 }
1324 
1325 - (void)rightMouseDown:(NSEvent *)theEvent
1326 {
1327  [[self nextResponder] rightMouseDown:theEvent];
1328 }
1329 
1330 - (BOOL)mouseDownCanMoveWindow
1331 {
1332  /* Always say YES, but this doesn't do anything until we call
1333  -[NSWindow setMovableByWindowBackground:YES], which we ninja-toggle
1334  during mouse events when we're using a drag area. */
1335  return YES;
1336 }
1337 
1338 - (void)resetCursorRects
1339 {
1340  [super resetCursorRects];
1341  SDL_Mouse *mouse = SDL_GetMouse();
1342 
1343  if (mouse->cursor_shown && mouse->cur_cursor && !mouse->relative_mode) {
1344  [self addCursorRect:[self bounds]
1345  cursor:mouse->cur_cursor->driverdata];
1346  } else {
1347  [self addCursorRect:[self bounds]
1348  cursor:[NSCursor invisibleCursor]];
1349  }
1350 }
1351 
1352 - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
1353 {
1356  } else {
1357  return SDL_GetHintBoolean("SDL_MAC_MOUSE_FOCUS_CLICKTHROUGH", SDL_FALSE);
1358  }
1359 }
1360 @end
1361 
1362 static int
1363 SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created)
1364 { @autoreleasepool
1365 {
1366  SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
1368 
1369  /* Allocate the window data */
1370  window->driverdata = data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
1371  if (!data) {
1372  return SDL_OutOfMemory();
1373  }
1374  data->window = window;
1375  data->nswindow = nswindow;
1376  data->created = created;
1377  data->videodata = videodata;
1378  data->nscontexts = [[NSMutableArray alloc] init];
1379 
1380  /* Only store this for windows created by us since the content view might
1381  * get replaced from under us otherwise, and we only need it when the
1382  * window is guaranteed to be created by us (OpenGL contexts). */
1383  data->sdlContentView = created ? [nswindow contentView] : nil;
1384 
1385  /* Create an event listener for the window */
1386  data->listener = [[Cocoa_WindowListener alloc] init];
1387 
1388  /* Fill in the SDL window with the window data */
1389  {
1390  NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
1391  ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect);
1392  window->x = (int)rect.origin.x;
1393  window->y = (int)rect.origin.y;
1394  window->w = (int)rect.size.width;
1395  window->h = (int)rect.size.height;
1396  }
1397 
1398  /* Set up the listener after we create the view */
1399  [data->listener listen:data];
1400 
1401  if ([nswindow isVisible]) {
1402  window->flags |= SDL_WINDOW_SHOWN;
1403  } else {
1404  window->flags &= ~SDL_WINDOW_SHOWN;
1405  }
1406 
1407  {
1408  unsigned long style = [nswindow styleMask];
1409 
1410  if (style == NSWindowStyleMaskBorderless) {
1411  window->flags |= SDL_WINDOW_BORDERLESS;
1412  } else {
1413  window->flags &= ~SDL_WINDOW_BORDERLESS;
1414  }
1415  if (style & NSWindowStyleMaskResizable) {
1416  window->flags |= SDL_WINDOW_RESIZABLE;
1417  } else {
1418  window->flags &= ~SDL_WINDOW_RESIZABLE;
1419  }
1420  }
1421 
1422  /* isZoomed always returns true if the window is not resizable */
1423  if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed]) {
1424  window->flags |= SDL_WINDOW_MAXIMIZED;
1425  } else {
1426  window->flags &= ~SDL_WINDOW_MAXIMIZED;
1427  }
1428 
1429  if ([nswindow isMiniaturized]) {
1430  window->flags |= SDL_WINDOW_MINIMIZED;
1431  } else {
1432  window->flags &= ~SDL_WINDOW_MINIMIZED;
1433  }
1434 
1435  if ([nswindow isKeyWindow]) {
1436  window->flags |= SDL_WINDOW_INPUT_FOCUS;
1437  SDL_SetKeyboardFocus(data->window);
1438  }
1439 
1440  /* Prevents the window's "window device" from being destroyed when it is
1441  * hidden. See http://www.mikeash.com/pyblog/nsopenglcontext-and-one-shot.html
1442  */
1443  [nswindow setOneShot:NO];
1444 
1445  /* All done! */
1446  window->driverdata = data;
1447  return 0;
1448 }}
1449 
1450 int
1452 { @autoreleasepool
1453 {
1454  SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
1455  NSWindow *nswindow;
1457  NSRect rect;
1458  SDL_Rect bounds;
1459  NSUInteger style;
1460  NSArray *screens = [NSScreen screens];
1461 
1462  Cocoa_GetDisplayBounds(_this, display, &bounds);
1463  rect.origin.x = window->x;
1464  rect.origin.y = window->y;
1465  rect.size.width = window->w;
1466  rect.size.height = window->h;
1467  ConvertNSRect([screens objectAtIndex:0], (window->flags & FULLSCREEN_MASK), &rect);
1468 
1469  style = GetWindowStyle(window);
1470 
1471  /* Figure out which screen to place this window */
1472  NSScreen *screen = nil;
1473  for (NSScreen *candidate in screens) {
1474  NSRect screenRect = [candidate frame];
1475  if (rect.origin.x >= screenRect.origin.x &&
1476  rect.origin.x < screenRect.origin.x + screenRect.size.width &&
1477  rect.origin.y >= screenRect.origin.y &&
1478  rect.origin.y < screenRect.origin.y + screenRect.size.height) {
1479  screen = candidate;
1480  rect.origin.x -= screenRect.origin.x;
1481  rect.origin.y -= screenRect.origin.y;
1482  }
1483  }
1484 
1485  @try {
1486  nswindow = [[SDLWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:NO screen:screen];
1487  }
1488  @catch (NSException *e) {
1489  return SDL_SetError("%s", [[e reason] UTF8String]);
1490  }
1491 
1492 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 /* Added in the 10.12.0 SDK. */
1493  /* By default, don't allow users to make our window tabbed in 10.12 or later */
1494  if ([nswindow respondsToSelector:@selector(setTabbingMode:)]) {
1495  [nswindow setTabbingMode:NSWindowTabbingModeDisallowed];
1496  }
1497 #endif
1498 
1499  if (videodata->allow_spaces) {
1500  SDL_assert(floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6);
1501  SDL_assert([nswindow respondsToSelector:@selector(toggleFullScreen:)]);
1502  /* we put FULLSCREEN_DESKTOP windows in their own Space, without a toggle button or menubar, later */
1503  if (window->flags & SDL_WINDOW_RESIZABLE) {
1504  /* resizable windows are Spaces-friendly: they get the "go fullscreen" toggle button on their titlebar. */
1505  [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
1506  }
1507  }
1508 
1509  if (window->flags & SDL_WINDOW_ALWAYS_ON_TOP) {
1510  [nswindow setLevel:NSFloatingWindowLevel];
1511  }
1512 
1513  /* Create a default view for this window */
1514  rect = [nswindow contentRectForFrameRect:[nswindow frame]];
1515  SDLView *contentView = [[SDLView alloc] initWithFrame:rect];
1516  [contentView setSDLWindow:window];
1517 
1518  /* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */
1519  #ifdef __clang__
1520  #pragma clang diagnostic push
1521  #pragma clang diagnostic ignored "-Wdeprecated-declarations"
1522  #endif
1523  /* Note: as of the macOS 10.15 SDK, this defaults to YES instead of NO when
1524  * the NSHighResolutionCapable boolean is set in Info.plist. */
1525  if ([contentView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
1526  BOOL highdpi = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0;
1527  [contentView setWantsBestResolutionOpenGLSurface:highdpi];
1528  }
1529  #ifdef __clang__
1530  #pragma clang diagnostic pop
1531  #endif
1532 
1533 #if SDL_VIDEO_OPENGL_ES2
1534 #if SDL_VIDEO_OPENGL_EGL
1535  if ((window->flags & SDL_WINDOW_OPENGL) &&
1537  [contentView setWantsLayer:TRUE];
1538  }
1539 #endif /* SDL_VIDEO_OPENGL_EGL */
1540 #endif /* SDL_VIDEO_OPENGL_ES2 */
1541  [nswindow setContentView:contentView];
1542  [contentView release];
1543 
1544  if (SetupWindowData(_this, window, nswindow, SDL_TRUE) < 0) {
1545  [nswindow release];
1546  return -1;
1547  }
1548 
1549  if (!(window->flags & SDL_WINDOW_OPENGL)) {
1550  return 0;
1551  }
1552 
1553  /* The rest of this macro mess is for OpenGL or OpenGL ES windows */
1554 #if SDL_VIDEO_OPENGL_ES2
1556 #if SDL_VIDEO_OPENGL_EGL
1557  if (Cocoa_GLES_SetupWindow(_this, window) < 0) {
1559  return -1;
1560  }
1561  return 0;
1562 #else
1563  return SDL_SetError("Could not create GLES window surface (EGL support not configured)");
1564 #endif /* SDL_VIDEO_OPENGL_EGL */
1565  }
1566 #endif /* SDL_VIDEO_OPENGL_ES2 */
1567  return 0;
1568 }}
1569 
1570 int
1572 { @autoreleasepool
1573 {
1574  NSWindow *nswindow = (NSWindow *) data;
1575  NSString *title;
1576 
1577  /* Query the title from the existing window */
1578  title = [nswindow title];
1579  if (title) {
1580  window->title = SDL_strdup([title UTF8String]);
1581  }
1582 
1583  return SetupWindowData(_this, window, nswindow, SDL_FALSE);
1584 }}
1585 
1586 void
1588 { @autoreleasepool
1589 {
1590  const char *title = window->title ? window->title : "";
1591  NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
1592  NSString *string = [[NSString alloc] initWithUTF8String:title];
1593  [nswindow setTitle:string];
1594  [string release];
1595 }}
1596 
1597 void
1599 { @autoreleasepool
1600 {
1601  NSImage *nsimage = Cocoa_CreateImage(icon);
1602 
1603  if (nsimage) {
1604  [NSApp setApplicationIconImage:nsimage];
1605  }
1606 }}
1607 
1608 void
1610 { @autoreleasepool
1611 {
1612  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
1613  NSWindow *nswindow = windata->nswindow;
1614  NSRect rect;
1615  Uint32 moveHack;
1616 
1617  rect.origin.x = window->x;
1618  rect.origin.y = window->y;
1619  rect.size.width = window->w;
1620  rect.size.height = window->h;
1621  ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect);
1622 
1623  moveHack = s_moveHack;
1624  s_moveHack = 0;
1625  [nswindow setFrameOrigin:rect.origin];
1626  s_moveHack = moveHack;
1627 
1628  ScheduleContextUpdates(windata);
1629 }}
1630 
1631 void
1633 { @autoreleasepool
1634 {
1635  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
1636  NSWindow *nswindow = windata->nswindow;
1637  NSRect rect;
1638  Uint32 moveHack;
1639 
1640  /* Cocoa will resize the window from the bottom-left rather than the
1641  * top-left when -[nswindow setContentSize:] is used, so we must set the
1642  * entire frame based on the new size, in order to preserve the position.
1643  */
1644  rect.origin.x = window->x;
1645  rect.origin.y = window->y;
1646  rect.size.width = window->w;
1647  rect.size.height = window->h;
1648  ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect);
1649 
1650  moveHack = s_moveHack;
1651  s_moveHack = 0;
1652  [nswindow setFrame:[nswindow frameRectForContentRect:rect] display:YES];
1653  s_moveHack = moveHack;
1654 
1655  ScheduleContextUpdates(windata);
1656 }}
1657 
1658 void
1660 { @autoreleasepool
1661 {
1662  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
1663 
1664  NSSize minSize;
1665  minSize.width = window->min_w;
1666  minSize.height = window->min_h;
1667 
1668  [windata->nswindow setContentMinSize:minSize];
1669 }}
1670 
1671 void
1673 { @autoreleasepool
1674 {
1675  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
1676 
1677  NSSize maxSize;
1678  maxSize.width = window->max_w;
1679  maxSize.height = window->max_h;
1680 
1681  [windata->nswindow setContentMaxSize:maxSize];
1682 }}
1683 
1684 void
1686 { @autoreleasepool
1687 {
1688  SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata);
1689  NSWindow *nswindow = windowData->nswindow;
1690 
1691  if (![nswindow isMiniaturized]) {
1692  [windowData->listener pauseVisibleObservation];
1693  [nswindow makeKeyAndOrderFront:nil];
1694  [windowData->listener resumeVisibleObservation];
1695  }
1696 }}
1697 
1698 void
1700 { @autoreleasepool
1701 {
1702  NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
1703 
1704  [nswindow orderOut:nil];
1705 }}
1706 
1707 void
1709 { @autoreleasepool
1710 {
1711  SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata);
1712  NSWindow *nswindow = windowData->nswindow;
1713 
1714  /* makeKeyAndOrderFront: has the side-effect of deminiaturizing and showing
1715  a minimized or hidden window, so check for that before showing it.
1716  */
1717  [windowData->listener pauseVisibleObservation];
1718  if (![nswindow isMiniaturized] && [nswindow isVisible]) {
1719  [NSApp activateIgnoringOtherApps:YES];
1720  [nswindow makeKeyAndOrderFront:nil];
1721  }
1722  [windowData->listener resumeVisibleObservation];
1723 }}
1724 
1725 void
1727 { @autoreleasepool
1728 {
1729  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
1730  NSWindow *nswindow = windata->nswindow;
1731 
1732  [nswindow zoom:nil];
1733 
1734  ScheduleContextUpdates(windata);
1735 }}
1736 
1737 void
1739 { @autoreleasepool
1740 {
1741  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1742  NSWindow *nswindow = data->nswindow;
1743  if ([data->listener isInFullscreenSpaceTransition]) {
1744  [data->listener addPendingWindowOperation:PENDING_OPERATION_MINIMIZE];
1745  } else {
1746  [nswindow miniaturize:nil];
1747  }
1748 }}
1749 
1750 void
1752 { @autoreleasepool
1753 {
1754  NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
1755 
1756  if ([nswindow isMiniaturized]) {
1757  [nswindow deminiaturize:nil];
1758  } else if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed]) {
1759  [nswindow zoom:nil];
1760  }
1761 }}
1762 
1763 void
1765 { @autoreleasepool
1766 {
1767  if (SetWindowStyle(window, GetWindowStyle(window))) {
1768  if (bordered) {
1769  Cocoa_SetWindowTitle(_this, window); /* this got blanked out. */
1770  }
1771  }
1772 }}
1773 
1774 void
1776 { @autoreleasepool
1777 {
1778  /* Don't set this if we're in a space!
1779  * The window will get permanently stuck if resizable is false.
1780  * -flibit
1781  */
1782  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1783  Cocoa_WindowListener *listener = data->listener;
1784  if (![listener isInFullscreenSpace]) {
1785  SetWindowStyle(window, GetWindowStyle(window));
1786  }
1787 }}
1788 
1789 void
1791 { @autoreleasepool
1792 {
1793  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1794  NSWindow *nswindow = data->nswindow;
1795  NSRect rect;
1796 
1797  /* The view responder chain gets messed with during setStyleMask */
1798  if ([[nswindow contentView] nextResponder] == data->listener) {
1799  [[nswindow contentView] setNextResponder:nil];
1800  }
1801 
1802  if (fullscreen) {
1803  SDL_Rect bounds;
1804 
1805  Cocoa_GetDisplayBounds(_this, display, &bounds);
1806  rect.origin.x = bounds.x;
1807  rect.origin.y = bounds.y;
1808  rect.size.width = bounds.w;
1809  rect.size.height = bounds.h;
1810  ConvertNSRect([nswindow screen], fullscreen, &rect);
1811 
1812  /* Hack to fix origin on Mac OS X 10.4
1813  This is no longer needed as of Mac OS X 10.15, according to bug 4822.
1814  */
1815  NSProcessInfo *processInfo = [NSProcessInfo processInfo];
1816  NSOperatingSystemVersion version = { 10, 15, 0 };
1817  if (![processInfo respondsToSelector:@selector(isOperatingSystemAtLeastVersion:)] ||
1818  ![processInfo isOperatingSystemAtLeastVersion:version]) {
1819  NSRect screenRect = [[nswindow screen] frame];
1820  if (screenRect.size.height >= 1.0f) {
1821  rect.origin.y += (screenRect.size.height - rect.size.height);
1822  }
1823  }
1824 
1825  [nswindow setStyleMask:NSWindowStyleMaskBorderless];
1826  } else {
1827  rect.origin.x = window->windowed.x;
1828  rect.origin.y = window->windowed.y;
1829  rect.size.width = window->windowed.w;
1830  rect.size.height = window->windowed.h;
1831  ConvertNSRect([nswindow screen], fullscreen, &rect);
1832 
1833  /* The window is not meant to be fullscreen, but its flags might have a
1834  * fullscreen bit set if it's scheduled to go fullscreen immediately
1835  * after. Always using the windowed mode style here works around bugs in
1836  * macOS 10.15 where the window doesn't properly restore the windowed
1837  * mode decorations after exiting fullscreen-desktop, when the window
1838  * was created as fullscreen-desktop. */
1839  [nswindow setStyleMask:GetWindowWindowedStyle(window)];
1840 
1841  /* Hack to restore window decorations on Mac OS X 10.10 */
1842  NSRect frameRect = [nswindow frame];
1843  [nswindow setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO];
1844  [nswindow setFrame:frameRect display:NO];
1845  }
1846 
1847  /* The view responder chain gets messed with during setStyleMask */
1848  if ([[nswindow contentView] nextResponder] != data->listener) {
1849  [[nswindow contentView] setNextResponder:data->listener];
1850  }
1851 
1852  s_moveHack = 0;
1853  [nswindow setContentSize:rect.size];
1854  [nswindow setFrameOrigin:rect.origin];
1855  s_moveHack = SDL_GetTicks();
1856 
1857  /* When the window style changes the title is cleared */
1858  if (!fullscreen) {
1860  }
1861 
1862  if (SDL_ShouldAllowTopmost() && fullscreen) {
1863  /* OpenGL is rendering to the window, so make it visible! */
1864  [nswindow setLevel:CGShieldingWindowLevel()];
1865  } else if (window->flags & SDL_WINDOW_ALWAYS_ON_TOP) {
1866  [nswindow setLevel:NSFloatingWindowLevel];
1867  } else {
1868  [nswindow setLevel:kCGNormalWindowLevel];
1869  }
1870 
1871  if ([nswindow isVisible] || fullscreen) {
1872  [data->listener pauseVisibleObservation];
1873  [nswindow makeKeyAndOrderFront:nil];
1874  [data->listener resumeVisibleObservation];
1875  }
1876 
1877  ScheduleContextUpdates(data);
1878 }}
1879 
1880 int
1882 {
1884  CGDirectDisplayID display_id = ((SDL_DisplayData *)display->driverdata)->display;
1885  const uint32_t tableSize = 256;
1886  CGGammaValue redTable[tableSize];
1887  CGGammaValue greenTable[tableSize];
1888  CGGammaValue blueTable[tableSize];
1889  uint32_t i;
1890  float inv65535 = 1.0f / 65535.0f;
1891 
1892  /* Extract gamma values into separate tables, convert to floats between 0.0 and 1.0 */
1893  for (i = 0; i < 256; i++) {
1894  redTable[i] = ramp[0*256+i] * inv65535;
1895  greenTable[i] = ramp[1*256+i] * inv65535;
1896  blueTable[i] = ramp[2*256+i] * inv65535;
1897  }
1898 
1899  if (CGSetDisplayTransferByTable(display_id, tableSize,
1900  redTable, greenTable, blueTable) != CGDisplayNoErr) {
1901  return SDL_SetError("CGSetDisplayTransferByTable()");
1902  }
1903  return 0;
1904 }
1905 
1906 int
1908 {
1910  CGDirectDisplayID display_id = ((SDL_DisplayData *)display->driverdata)->display;
1911  const uint32_t tableSize = 256;
1912  CGGammaValue redTable[tableSize];
1913  CGGammaValue greenTable[tableSize];
1914  CGGammaValue blueTable[tableSize];
1915  uint32_t i, tableCopied;
1916 
1917  if (CGGetDisplayTransferByTable(display_id, tableSize,
1918  redTable, greenTable, blueTable, &tableCopied) != CGDisplayNoErr) {
1919  return SDL_SetError("CGGetDisplayTransferByTable()");
1920  }
1921 
1922  for (i = 0; i < tableCopied; i++) {
1923  ramp[0*256+i] = (Uint16)(redTable[i] * 65535.0f);
1924  ramp[1*256+i] = (Uint16)(greenTable[i] * 65535.0f);
1925  ramp[2*256+i] = (Uint16)(blueTable[i] * 65535.0f);
1926  }
1927  return 0;
1928 }
1929 
1930 void
1932 {
1933  SDL_Mouse *mouse = SDL_GetMouse();
1934  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1935 
1936  /* Enable or disable the event tap as necessary */
1937  Cocoa_EnableMouseEventTap(mouse->driverdata, grabbed);
1938 
1939  /* Move the cursor to the nearest point in the window */
1940  if (grabbed && data && ![data->listener isMoving]) {
1941  int x, y;
1942  CGPoint cgpoint;
1943 
1944  SDL_GetMouseState(&x, &y);
1945  cgpoint.x = window->x + x;
1946  cgpoint.y = window->y + y;
1947 
1948  Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
1949 
1950  DLog("Returning cursor to (%g, %g)", cgpoint.x, cgpoint.y);
1951  CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
1952  }
1953 
1954  if ( data && (window->flags & SDL_WINDOW_FULLSCREEN) ) {
1956  && ![data->listener isInFullscreenSpace]) {
1957  /* OpenGL is rendering to the window, so make it visible! */
1958  /* Doing this in 10.11 while in a Space breaks things (bug #3152) */
1959  [data->nswindow setLevel:CGShieldingWindowLevel()];
1960  } else if (window->flags & SDL_WINDOW_ALWAYS_ON_TOP) {
1961  [data->nswindow setLevel:NSFloatingWindowLevel];
1962  } else {
1963  [data->nswindow setLevel:kCGNormalWindowLevel];
1964  }
1965  }
1966 }
1967 
1968 void
1970 { @autoreleasepool
1971 {
1972  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1973 
1974  if (data) {
1975  if ([data->listener isInFullscreenSpace]) {
1976  [NSMenu setMenuBarVisible:YES];
1977  }
1978  [data->listener close];
1979  [data->listener release];
1980  if (data->created) {
1981  /* Release the content view to avoid further updateLayer callbacks */
1982  [data->nswindow setContentView:nil];
1983  [data->nswindow close];
1984  }
1985 
1986  NSArray *contexts = [[data->nscontexts copy] autorelease];
1987  for (SDLOpenGLContext *context in contexts) {
1988  /* Calling setWindow:NULL causes the context to remove itself from the context list. */
1989  [context setWindow:NULL];
1990  }
1991  [data->nscontexts release];
1992 
1993  SDL_free(data);
1994  }
1995  window->driverdata = NULL;
1996 }}
1997 
1998 SDL_bool
2000 {
2001  NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
2002 
2003  if (info->version.major <= SDL_MAJOR_VERSION) {
2004  info->subsystem = SDL_SYSWM_COCOA;
2005  info->info.cocoa.window = nswindow;
2006  return SDL_TRUE;
2007  } else {
2008  SDL_SetError("Application not compiled with SDL %d.%d",
2010  return SDL_FALSE;
2011  }
2012 }
2013 
2014 SDL_bool
2015 Cocoa_IsWindowInFullscreenSpace(SDL_Window * window)
2016 {
2017  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
2018 
2019  if ([data->listener isInFullscreenSpace]) {
2020  return SDL_TRUE;
2021  } else {
2022  return SDL_FALSE;
2023  }
2024 }
2025 
2026 SDL_bool
2027 Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state)
2028 { @autoreleasepool
2029 {
2030  SDL_bool succeeded = SDL_FALSE;
2031  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
2032 
2033  if (data->inWindowFullscreenTransition) {
2034  return SDL_FALSE;
2035  }
2036 
2037  data->inWindowFullscreenTransition = SDL_TRUE;
2038  if ([data->listener setFullscreenSpace:(state ? YES : NO)]) {
2039  const int maxattempts = 3;
2040  int attempt = 0;
2041  while (++attempt <= maxattempts) {
2042  /* Wait for the transition to complete, so application changes
2043  take effect properly (e.g. setting the window size, etc.)
2044  */
2045  const int limit = 10000;
2046  int count = 0;
2047  while ([data->listener isInFullscreenSpaceTransition]) {
2048  if ( ++count == limit ) {
2049  /* Uh oh, transition isn't completing. Should we assert? */
2050  break;
2051  }
2052  SDL_Delay(1);
2053  SDL_PumpEvents();
2054  }
2055  if ([data->listener isInFullscreenSpace] == (state ? YES : NO))
2056  break;
2057  /* Try again, the last attempt was interrupted by user gestures */
2058  if (![data->listener setFullscreenSpace:(state ? YES : NO)])
2059  break; /* ??? */
2060  }
2061  /* Return TRUE to prevent non-space fullscreen logic from running */
2062  succeeded = SDL_TRUE;
2063  }
2064  data->inWindowFullscreenTransition = SDL_FALSE;
2065 
2066  return succeeded;
2067 }}
2068 
2069 int
2071 {
2072  return 0; /* just succeed, the real work is done elsewhere. */
2073 }
2074 
2075 void
2077 {
2078  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
2079  if (accept) {
2080  [data->nswindow registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]];
2081  } else {
2082  [data->nswindow unregisterDraggedTypes];
2083  }
2084 }
2085 
2086 int
2087 Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
2088 {
2089  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
2090  [data->nswindow setAlphaValue:opacity];
2091  return 0;
2092 }
2093 
2094 #endif /* SDL_VIDEO_DRIVER_COCOA */
2095 
2096 /* vi: set ts=4 sw=4 expandtab: */
SDL_HITTEST_DRAGGABLE
@ SDL_HITTEST_DRAGGABLE
Definition: SDL_video.h:1022
SDL_GetMouse
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:170
SDL_GetMouseState
#define SDL_GetMouseState
Definition: SDL_dynapi_overrides.h:246
SDL_Point::x
int x
Definition: SDL_rect.h:50
SDL_Mouse::WarpMouseGlobal
int(* WarpMouseGlobal)(int x, int y)
Definition: SDL_mouse_c.h:64
SDL_cocoamousetap.h
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
NSEventModifierFlagCapsLock
static const NSUInteger NSEventModifierFlagCapsLock
Definition: SDL_cocoavideo.h:71
SDL_WINDOW_ALLOW_HIGHDPI
@ SDL_WINDOW_ALLOW_HIGHDPI
Definition: SDL_video.h:112
screen
SDL_Renderer * screen
Definition: testgamecontroller.c:64
SDL_cocoaopengl.h
SDL_VideoDevice::driverdata
void * driverdata
Definition: SDL_sysvideo.h:389
-[Cocoa_WindowListener resumeVisibleObservation]
void resumeVisibleObservation()
SDL_VideoData::allow_spaces
int allow_spaces
Definition: SDL_cocoavideo.h:102
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:70
SDL_WINDOW_ALWAYS_ON_TOP
@ SDL_WINDOW_ALWAYS_ON_TOP
Definition: SDL_video.h:116
SDL_WINDOW_MINIMIZED
@ SDL_WINDOW_MINIMIZED
Definition: SDL_video.h:105
in
GLuint in
Definition: SDL_opengl_glext.h:7943
Cocoa_WindowListener::_data
SDL_WindowData * _data
Definition: SDL_cocoawindow.h:43
if
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
Definition: pixman-arm-neon-asm.h:469
Cocoa_WindowListener::pendingWindowWarpX
int pendingWindowWarpX
Definition: SDL_cocoawindow.h:51
location
GLint location
Definition: SDL_opengl_glext.h:682
PENDING_OPERATION_ENTER_FULLSCREEN
@ PENDING_OPERATION_ENTER_FULLSCREEN
Definition: SDL_cocoawindow.h:37
limit
GLint limit
Definition: SDL_opengl_glext.h:8769
SDL_IsShapedWindow
#define SDL_IsShapedWindow
Definition: SDL_dynapi_overrides.h:371
Cocoa_SetWindowTitle
void Cocoa_SetWindowTitle(_THIS, SDL_Window *window)
NULL
#define NULL
Definition: begin_code.h:167
layer
GLenum GLuint GLint GLint layer
Definition: SDL_opengl_glext.h:1189
SDL_timer.h
SDL_WINDOWEVENT_CLOSE
@ SDL_WINDOWEVENT_CLOSE
Definition: SDL_video.h:166
SDL_BUTTON_RIGHT
#define SDL_BUTTON_RIGHT
Definition: SDL_mouse.h:284
SDL_SysWMinfo
Definition: SDL_syswm.h:201
SDL_WindowData
Definition: SDL_androidwindow.h:38
Cocoa_SetWindowIcon
void Cocoa_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
Cocoa_WindowListener::wasVisible
BOOL wasVisible
Definition: SDL_cocoawindow.h:46
Cocoa_HandleMouseWarp
void Cocoa_HandleMouseWarp(CGFloat x, CGFloat y)
iterations
static int iterations
Definition: testsprite2.c:45
SDL_FingerID
Sint64 SDL_FingerID
Definition: SDL_touch.h:42
count
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
SDL_GetDisplayForWindow
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1110
SDL_WINDOW_FULLSCREEN
@ SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:99
SDL_SendTouch
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, SDL_bool down, float x, float y, float pressure)
Definition: SDL_touch.c:242
Cocoa_WindowListener::inFullscreenTransition
BOOL inFullscreenTransition
Definition: SDL_cocoawindow.h:48
SDL_SysWMinfo::window
Window window
Definition: SDL_syswm.h:225
Cocoa_MaximizeWindow
void Cocoa_MaximizeWindow(_THIS, SDL_Window *window)
r
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
SDL_WINDOW_OPENGL
@ SDL_WINDOW_OPENGL
Definition: SDL_video.h:100
Cocoa_WindowListener
Definition: SDL_cocoawindow.h:42
SDL_TouchID
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
SDL_WINDOWEVENT_RESIZED
@ SDL_WINDOWEVENT_RESIZED
Definition: SDL_video.h:154
Cocoa_SetWindowPosition
void Cocoa_SetWindowPosition(_THIS, SDL_Window *window)
Cocoa_CreateImage
NSImage * Cocoa_CreateImage(SDL_Surface *surface)
Cocoa_WindowListener::pendingWindowOperation
PendingWindowOperation pendingWindowOperation
Definition: SDL_cocoawindow.h:49
SDL_WINDOW_FULLSCREEN_DESKTOP
@ SDL_WINDOW_FULLSCREEN_DESKTOP
Definition: SDL_video.h:110
SDL_SetKeyboardFocus
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:630
SDL_GetTouchFinger
#define SDL_GetTouchFinger
Definition: SDL_dynapi_overrides.h:492
SDL_Mouse::driverdata
void * driverdata
Definition: SDL_mouse_c.h:109
SDL_SendMouseButtonClicks
int SDL_SendMouseButtonClicks(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks)
Definition: SDL_mouse.c:587
SDL_VideoData::modifierFlags
unsigned int modifierFlags
Definition: SDL_cocoavideo.h:103
SDL_Mouse::SetRelativeMouseMode
int(* SetRelativeMouseMode)(SDL_bool enabled)
Definition: SDL_mouse_c.h:67
SDL_VideoDevice::profile_mask
int profile_mask
Definition: SDL_sysvideo.h:354
Cocoa_CreateWindow
int Cocoa_CreateWindow(_THIS, SDL_Window *window)
Cocoa_RestoreWindow
void Cocoa_RestoreWindow(_THIS, SDL_Window *window)
Cocoa_SetWindowGammaRamp
int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window *window, const Uint16 *ramp)
path
GLsizei const GLchar *const * path
Definition: SDL_opengl_glext.h:3733
SDL_WINDOW_MAXIMIZED
@ SDL_WINDOW_MAXIMIZED
Definition: SDL_video.h:106
SDL_cocoavideo.h
SDL_WINDOWEVENT_MOVED
@ SDL_WINDOWEVENT_MOVED
Definition: SDL_video.h:152
Cocoa_GetDisplayBounds
int Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
-[Cocoa_WindowListener pauseVisibleObservation]
void pauseVisibleObservation()
SDL_GetHint
#define SDL_GetHint
Definition: SDL_dynapi_overrides.h:191
SDL_RELEASED
#define SDL_RELEASED
Definition: SDL_events.h:49
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1949
SDL_Rect::x
int x
Definition: SDL_rect.h:79
SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK
#define SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK
A variable that determines whether ctrl+click should generate a right-click event on Mac.
Definition: SDL_hints.h:744
SDL_SetMouseFocus
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:203
SDL_MouseID
Uint32 SDL_MouseID
Definition: SDL_mouse_c.h:28
SDL_SendKeyboardKey
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
Definition: SDL_keyboard.c:679
SDL_WINDOW_INPUT_FOCUS
@ SDL_WINDOW_INPUT_FOCUS
Definition: SDL_video.h:108
SDL_WINDOW_RESIZABLE
@ SDL_WINDOW_RESIZABLE
Definition: SDL_video.h:104
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
SDL_Rect::w
int w
Definition: SDL_rect.h:80
Cocoa_MinimizeWindow
void Cocoa_MinimizeWindow(_THIS, SDL_Window *window)
SDL_PumpEvents
#define SDL_PumpEvents
Definition: SDL_dynapi_overrides.h:116
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:74
SDL_GetKeyboardFocus
#define SDL_GetKeyboardFocus
Definition: SDL_dynapi_overrides.h:216
Cocoa_AcceptDragAndDrop
void Cocoa_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept)
SDL_Finger
Definition: SDL_touch.h:52
Cocoa_SetWindowMaximumSize
void Cocoa_SetWindowMaximumSize(_THIS, SDL_Window *window)
SDL_TouchDeviceType
SDL_TouchDeviceType
Definition: SDL_touch.h:44
SDL_WINDOWEVENT_SHOWN
@ SDL_WINDOWEVENT_SHOWN
Definition: SDL_video.h:148
SDL_SCANCODE_CAPSLOCK
@ SDL_SCANCODE_CAPSLOCK
Definition: SDL_scancode.h:151
Cocoa_WindowListener::isMoving
BOOL isMoving
Definition: SDL_cocoawindow.h:50
SDL_Window::w
int w
Definition: SDL_sysvideo.h:81
SDL_VideoDevice::gl_config
struct SDL_VideoDevice::@255 gl_config
SDL_PRESSED
#define SDL_PRESSED
Definition: SDL_events.h:50
Cocoa_EnableMouseEventTap
void Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled)
SDL_GetHintBoolean
#define SDL_GetHintBoolean
Definition: SDL_dynapi_overrides.h:608
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2652
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_ToggleModState
void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle)
Definition: SDL_keyboard.c:865
SDL_AddTouch
int SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name)
Definition: SDL_touch.c:155
SDL_Mouse::relative_mode
SDL_bool relative_mode
Definition: SDL_mouse_c.h:87
context
static screen_context_t context
Definition: video.c:25
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:121
SDL_BUTTON_LEFT
#define SDL_BUTTON_LEFT
Definition: SDL_mouse.h:282
SDL_HitTestResult
SDL_HitTestResult
Possible return values from the SDL_HitTest callback.
Definition: SDL_video.h:1019
array
GLenum array
Definition: SDL_opengl_glext.h:6303
SDL_SYSWM_COCOA
@ SDL_SYSWM_COCOA
Definition: SDL_syswm.h:128
SDL_MINOR_VERSION
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
PENDING_OPERATION_NONE
@ PENDING_OPERATION_NONE
Definition: SDL_cocoawindow.h:36
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
SDL_SysWMinfo::subsystem
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:204
window
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
SDL_WindowData::width
int width
Definition: SDL_waylandwindow.h:76
SDL_Rect::y
int y
Definition: SDL_rect.h:79
SDL_Rect::h
int h
Definition: SDL_rect.h:80
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
f
GLfloat f
Definition: SDL_opengl_glext.h:1873
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
Cocoa_SetWindowSize
void Cocoa_SetWindowSize(_THIS, SDL_Window *window)
Cocoa_RaiseWindow
void Cocoa_RaiseWindow(_THIS, SDL_Window *window)
Cocoa_ResizeWindowShape
int Cocoa_ResizeWindowShape(SDL_Window *window)
Cocoa_CreateWindowFrom
int Cocoa_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
Cocoa_WindowListener::isDragAreaRunning
BOOL isDragAreaRunning
Definition: SDL_cocoawindow.h:52
Cocoa_WindowListener::isFullscreenSpace
BOOL isFullscreenSpace
Definition: SDL_cocoawindow.h:47
SDL_SendDropFile
int SDL_SendDropFile(SDL_Window *window, const char *file)
Definition: SDL_dropevents.c:80
rect
SDL_Rect rect
Definition: testrelative.c:27
SDL_SendMouseMotion
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
Definition: SDL_mouse.c:293
SDL_WINDOWEVENT_EXPOSED
@ SDL_WINDOWEVENT_EXPOSED
Definition: SDL_video.h:150
SDL_GL_CONTEXT_PROFILE_ES
@ SDL_GL_CONTEXT_PROFILE_ES
Definition: SDL_video.h:232
SDL_BUTTON_MIDDLE
#define SDL_BUTTON_MIDDLE
Definition: SDL_mouse.h:283
Uint16
uint16_t Uint16
Definition: SDL_stdinc.h:191
SDL_assert.h
SDL_GetTicks
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
SDL_GetNumTouchFingers
#define SDL_GetNumTouchFingers
Definition: SDL_dynapi_overrides.h:491
Cocoa_SetWindowFullscreen
void Cocoa_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
Cocoa_HideWindow
void Cocoa_HideWindow(_THIS, SDL_Window *window)
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
SDL_WINDOWEVENT_HIT_TEST
@ SDL_WINDOWEVENT_HIT_TEST
Definition: SDL_video.h:168
SDL_WINDOW_INPUT_GRABBED
@ SDL_WINDOW_INPUT_GRABBED
Definition: SDL_video.h:107
Cocoa_DestroyWindow
void Cocoa_DestroyWindow(_THIS, SDL_Window *window)
SDL_Mouse
Definition: SDL_mouse_c.h:43
PendingWindowOperation
PendingWindowOperation
Definition: SDL_cocoawindow.h:34
SDL_Delay
#define SDL_Delay
Definition: SDL_dynapi_overrides.h:486
SDL_SendDropComplete
int SDL_SendDropComplete(SDL_Window *window)
Definition: SDL_dropevents.c:92
-[Cocoa_WindowListener close]
void close()
SDL_Mouse::relative_mode_warp
SDL_bool relative_mode_warp
Definition: SDL_mouse_c.h:88
SDL_WindowData::window
SDL_Window * window
Definition: SDL_cocoawindow.h:114
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:169
SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE
@ SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE
Definition: SDL_touch.h:48
SDL_Mouse::focus
SDL_Window * focus
Definition: SDL_mouse_c.h:77
SDL_WINDOWEVENT_MINIMIZED
@ SDL_WINDOWEVENT_MINIMIZED
Definition: SDL_video.h:158
SDL_WINDOW_SHOWN
@ SDL_WINDOW_SHOWN
Definition: SDL_video.h:101
SDL_VideoDisplay::driverdata
void * driverdata
Definition: SDL_sysvideo.h:140
SDL_Window::h
int h
Definition: SDL_sysvideo.h:81
SDL_ShouldAllowTopmost
SDL_bool SDL_ShouldAllowTopmost(void)
Definition: SDL_video.c:4023
SDL_DisplayData
Definition: SDL_cocoamodes.h:26
SDL_VideoDevice
Definition: SDL_sysvideo.h:149
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:540
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
SDL_Window::y
int y
Definition: SDL_sysvideo.h:80
Cocoa_SetWindowBordered
void Cocoa_SetWindowBordered(_THIS, SDL_Window *window, SDL_bool bordered)
SDL_MOUSE_TOUCHID
#define SDL_MOUSE_TOUCHID
Definition: SDL_touch.h:64
Cocoa_SetWindowGrab
void Cocoa_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
action
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF base if bpp PF set rept prefetch_distance PF set OFFSET endr endif endm macro preload_leading_step2 base if bpp ifc DST PF PF else if bpp lsl PF PF lsl PF PF lsl PF PF PF else PF lsl PF lsl PF lsl PF endif SIZE macro preload_middle scratch_holds_offset if bpp if else PF PF endif endif endif endm macro preload_trailing base if bpp if bpp *pix_per_block PF PF lsl PF PF PF PF PF else PF lsl PF lsl PF PF PF PF PF base if bpp if narrow_case &&bpp<=dst_w_bpp) PF bic, WK0, base, #31 PF pld,[WK0] PF add, WK1, base, X, LSL #bpp_shift PF sub, WK1, WK1, #1 PF bic, WK1, WK1, #31 PF cmp, WK1, WK0 PF beq, 90f PF pld,[WK1]90:.else PF bic, WK0, base, #31 PF pld,[WK0] PF add, WK1, base, X, lsl #bpp_shift PF sub, WK1, WK1, #1 PF bic, WK1, WK1, #31 PF cmp, WK1, WK0 PF beq, 92f91:PF add, WK0, WK0, #32 PF cmp, WK0, WK1 PF pld,[WK0] PF bne, 91b92:.endif .endif.endm.macro conditional_process1_helper cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, 0 .if decrementx sub &cond X, X, #8 *numbytes/dst_w_bpp .endif process_tail cond, numbytes, firstreg .if !((flags) &FLAG_PROCESS_DOES_STORE) pixst cond, numbytes, firstreg, DST .endif.endm.macro conditional_process1 cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx .if(flags) &FLAG_BRANCH_OVER .ifc cond, mi bpl 100f .endif .ifc cond, cs bcc 100f .endif .ifc cond, ne beq 100f .endif conditional_process1_helper, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx100:.else conditional_process1_helper cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx .endif.endm.macro conditional_process2 test, cond1, cond2, process_head, process_tail, numbytes1, numbytes2, firstreg1, firstreg2, unaligned_src, unaligned_mask, decrementx .if(flags) &(FLAG_DST_READWRITE|FLAG_BRANCH_OVER|FLAG_PROCESS_CORRUPTS_PSR|FLAG_PROCESS_DOES_STORE) test conditional_process1 cond1, process_head, process_tail, numbytes1, firstreg1, unaligned_src, unaligned_mask, decrementx .if(flags) &FLAG_PROCESS_CORRUPTS_PSR test .endif conditional_process1 cond2, process_head, process_tail, numbytes2, firstreg2, unaligned_src, unaligned_mask, decrementx .else test process_head cond1, numbytes1, firstreg1, unaligned_src, unaligned_mask, 0 process_head cond2, numbytes2, firstreg2, unaligned_src, unaligned_mask, 0 .if decrementx sub &cond1 X, X, #8 *numbytes1/dst_w_bpp sub &cond2 X, X, #8 *numbytes2/dst_w_bpp .endif process_tail cond1, numbytes1, firstreg1 process_tail cond2, numbytes2, firstreg2 pixst cond1, numbytes1, firstreg1, DST pixst cond2, numbytes2, firstreg2, DST .endif.endm.macro test_bits_1_0_ptr .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 movs SCRATCH, X, lsl #32-1 .else movs SCRATCH, WK0, lsl #32-1 .endif.endm.macro test_bits_3_2_ptr .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 movs SCRATCH, X, lsl #32-3 .else movs SCRATCH, WK0, lsl #32-3 .endif.endm.macro leading_15bytes process_head, process_tail .set DECREMENT_X, 1 .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 .set DECREMENT_X, 0 sub X, X, WK0, lsr #dst_bpp_shift str X,[sp, #LINE_SAVED_REG_COUNT *4] mov X, WK0 .endif .if dst_w_bpp==8 conditional_process2 test_bits_1_0_ptr, mi, cs, process_head, process_tail, 1, 2, 1, 2, 1, 1, DECREMENT_X .elseif dst_w_bpp==16 test_bits_1_0_ptr conditional_process1 cs, process_head, process_tail, 2, 2, 1, 1, DECREMENT_X .endif conditional_process2 test_bits_3_2_ptr, mi, cs, process_head, process_tail, 4, 8, 1, 2, 1, 1, DECREMENT_X .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 ldr X,[sp, #LINE_SAVED_REG_COUNT *4] .endif.endm.macro test_bits_3_2_pix movs SCRATCH, X, lsl #dst_bpp_shift+32-3.endm.macro test_bits_1_0_pix .if dst_w_bpp==8 movs SCRATCH, X, lsl #dst_bpp_shift+32-1 .else movs SCRATCH, X, lsr #1 .endif.endm.macro trailing_15bytes process_head, process_tail, unaligned_src, unaligned_mask conditional_process2 test_bits_3_2_pix, cs, mi, process_head, process_tail, 8, 4, 0, 2, unaligned_src, unaligned_mask, 0 .if dst_w_bpp==16 test_bits_1_0_pix conditional_process1 cs, process_head, process_tail, 2, 0, unaligned_src, unaligned_mask, 0 .elseif dst_w_bpp==8 conditional_process2 test_bits_1_0_pix, cs, mi, process_head, process_tail, 2, 1, 0, 1, unaligned_src, unaligned_mask, 0 .endif.endm.macro wide_case_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, dst_alignment110:.set SUBBLOCK, 0 .rept pix_per_block *dst_w_bpp/128 process_head, 16, 0, unaligned_src, unaligned_mask, 1 .if(src_bpp > 0) &&(mask_bpp==0) &&((flags) &FLAG_PROCESS_PRESERVES_SCRATCH) preload_middle src_bpp, SRC, 1 .elseif(src_bpp==0) &&(mask_bpp > 0) &&((flags) &FLAG_PROCESS_PRESERVES_SCRATCH) preload_middle mask_bpp, MASK, 1 .else preload_middle src_bpp, SRC, 0 preload_middle mask_bpp, MASK, 0 .endif .if(dst_r_bpp > 0) &&((SUBBLOCK % 2)==0) &&(((flags) &FLAG_NO_PRELOAD_DST)==0) PF pld,[DST, #32 *prefetch_distance - dst_alignment] .endif process_tail, 16, 0 .if !((flags) &FLAG_PROCESS_DOES_STORE) pixst, 16, 0, DST .endif .set SUBBLOCK, SUBBLOCK+1 .endr subs X, X, #pix_per_block bhs 110b.endm.macro wide_case_inner_loop_and_trailing_pixels process_head, process_tail, process_inner_loop, exit_label, unaligned_src, unaligned_mask .if dst_r_bpp > tst bne process_inner_loop DST_PRELOAD_BIAS endif preload_trailing SRC preload_trailing MASK DST endif add medium_case_inner_loop_and_trailing_pixels unaligned_mask endm macro medium_case_inner_loop_and_trailing_pixels DST endif subs bhs tst beq exit_label trailing_15bytes unaligned_mask endm macro narrow_case_inner_loop_and_trailing_pixels unaligned_mask tst conditional_process1 trailing_15bytes unaligned_mask endm macro switch_on_alignment action
Definition: pixman-arm-simd-asm.h:510
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
Cocoa_SetWindowMinimumSize
void Cocoa_SetWindowMinimumSize(_THIS, SDL_Window *window)
-[Cocoa_WindowListener isInFullscreenSpace]
BOOL isInFullscreenSpace()
Cocoa_WindowListener::wasCtrlLeft
BOOL wasCtrlLeft
Definition: SDL_cocoawindow.h:45
SDL_Window::driverdata
void * driverdata
Definition: SDL_sysvideo.h:112
uint32_t
unsigned int uint32_t
Definition: SDL_config_windows.h:63
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
NSEventSubtypeMouseEvent
#define NSEventSubtypeMouseEvent
Definition: SDL_cocoavideo.h:118
SDL_Point
The structure that defines a point (integer)
Definition: SDL_rect.h:48
SDL_SysWMinfo::version
SDL_version version
Definition: SDL_syswm.h:203
INT_MAX
#define INT_MAX
Definition: SDL_wave.c:31
PENDING_OPERATION_MINIMIZE
@ PENDING_OPERATION_MINIMIZE
Definition: SDL_cocoawindow.h:39
SDL_Window::next
SDL_Window * next
Definition: SDL_sysvideo.h:115
SDL_VideoDisplay
Definition: SDL_sysvideo.h:126
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
-[Cocoa_WindowListener windowDidFinishMoving]
void windowDidFinishMoving()
SDL_Rect
A rectangle, with the origin at the upper left (integer).
Definition: SDL_rect.h:77
SDL_GetMouseFocus
#define SDL_GetMouseFocus
Definition: SDL_dynapi_overrides.h:245
display_id
EGLNativeDisplayType * display_id
Definition: eglext.h:1024
SDL_Window::hit_test
SDL_HitTest hit_test
Definition: SDL_sysvideo.h:107
SDL_hints.h
e
const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char const char const SDL_SCANF_FORMAT_STRING char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 Uint32 * e
Definition: SDL_dynapi_procs.h:117
SDL_SendTouchMotion
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, float x, float y, float pressure)
Definition: SDL_touch.c:356
Cocoa_SetWindowOpacity
int Cocoa_SetWindowOpacity(_THIS, SDL_Window *window, float opacity)
Cocoa_GetWindowGammaRamp
int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window *window, Uint16 *ramp)
SDL_SendWindowEvent
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
Definition: SDL_windowevents.c:74
Cocoa_WindowListener::observingVisible
BOOL observingVisible
Definition: SDL_cocoawindow.h:44
SDL_strdup
#define SDL_strdup
Definition: SDL_dynapi_overrides.h:397
SDL_Mouse::mouseID
SDL_MouseID mouseID
Definition: SDL_mouse_c.h:76
SDL_SysWMinfo::info
union SDL_SysWMinfo::@10 info
enabled
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: SDL_opengl_glext.h:2482
PENDING_OPERATION_LEAVE_FULLSCREEN
@ PENDING_OPERATION_LEAVE_FULLSCREEN
Definition: SDL_cocoawindow.h:38
Cocoa_CheckClipboardUpdate
void Cocoa_CheckClipboardUpdate(struct SDL_VideoData *data)
SDL_Finger::id
SDL_FingerID id
Definition: SDL_touch.h:54
SDL_cocoamouse.h
Cocoa_SetWindowHitTest
int Cocoa_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
SDL_WindowData::videodata
struct SDL_VideoData * videodata
Definition: SDL_cocoawindow.h:121
SDL_WINDOWEVENT_HIDDEN
@ SDL_WINDOWEVENT_HIDDEN
Definition: SDL_video.h:149
types
GLsizei GLenum GLenum * types
Definition: SDL_opengl_glext.h:2485
SDL_GetVideoDevice
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:586
Cocoa_WindowListener::pendingWindowWarpY
int pendingWindowWarpY
Definition: SDL_cocoawindow.h:51
SDL_WINDOWEVENT_RESTORED
@ SDL_WINDOWEVENT_RESTORED
Definition: SDL_video.h:160
SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH
#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH
Allow mouse click events when clicking to focus an SDL window.
Definition: SDL_hints.h:337
SDL_Window::hit_test_data
void * hit_test_data
Definition: SDL_sysvideo.h:108
SDL_cocoashape.h
SDL_cocoaopengles.h
void
const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char const char const SDL_SCANF_FORMAT_STRING char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
Definition: SDL_dynapi_procs.h:89
SDL_version::major
Uint8 major
Definition: SDL_version.h:53
FULLSCREEN_MASK
#define FULLSCREEN_MASK
Definition: SDL_video.c:147
SDL_GetModState
#define SDL_GetModState
Definition: SDL_dynapi_overrides.h:218
SDL_MAJOR_VERSION
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
Cocoa_HandleMouseWheel
void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
floor
double floor(double x)
Definition: s_floor.c:33
SDL_Window::flags
Uint32 flags
Definition: SDL_sysvideo.h:84
Cocoa_GetWindowWMInfo
SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
type
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
state
struct xkb_state * state
Definition: SDL_waylandsym.h:114
KMOD_CAPS
@ KMOD_CAPS
Definition: SDL_keycode.h:337
button
SDL_Texture * button
Definition: testgamecontroller.c:67
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SDL_Mouse::cur_cursor
SDL_Cursor * cur_cursor
Definition: SDL_mouse_c.h:105
SDL_WINDOWEVENT_MAXIMIZED
@ SDL_WINDOWEVENT_MAXIMIZED
Definition: SDL_video.h:159
Cocoa_ShowWindow
void Cocoa_ShowWindow(_THIS, SDL_Window *window)
-[Cocoa_WindowListener isInFullscreenSpaceTransition]
BOOL isInFullscreenSpaceTransition()
SDL_VideoData
Definition: SDL_androidvideo.h:36
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:161
Cocoa_SetWindowResizable
void Cocoa_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable)
SDL_Mouse::cursor_shown
SDL_bool cursor_shown
Definition: SDL_mouse_c.h:106
SDL_WindowData::nswindow
NSWindow * nswindow
Definition: SDL_cocoawindow.h:115
SDL_syswm.h
SDL_WINDOW_BORDERLESS
@ SDL_WINDOW_BORDERLESS
Definition: SDL_video.h:103
SDL_VideoDevice::windows
SDL_Window * windows
Definition: SDL_sysvideo.h:325
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:734