SDL  2.0
SDL_cocoaevents.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 #include "SDL_timer.h"
26 
27 #include "SDL_cocoavideo.h"
28 #include "../../events/SDL_events_c.h"
29 #include "SDL_hints.h"
30 
31 /* This define was added in the 10.9 SDK. */
32 #ifndef kIOPMAssertPreventUserIdleDisplaySleep
33 #define kIOPMAssertPreventUserIdleDisplaySleep kIOPMAssertionTypePreventUserIdleDisplaySleep
34 #endif
35 #ifndef NSAppKitVersionNumber10_8
36 #define NSAppKitVersionNumber10_8 1187
37 #endif
38 
39 @interface SDLApplication : NSApplication
40 
41 - (void)terminate:(id)sender;
42 - (void)sendEvent:(NSEvent *)theEvent;
43 
44 + (void)registerUserDefaults;
45 
46 @end
47 
48 @implementation SDLApplication
49 
50 // Override terminate to handle Quit and System Shutdown smoothly.
51 - (void)terminate:(id)sender
52 {
53  SDL_SendQuit();
54 }
55 
56 static SDL_bool s_bShouldHandleEventsInSDLApplication = SDL_FALSE;
57 
58 static void Cocoa_DispatchEvent(NSEvent *theEvent)
59 {
61 
62  switch ([theEvent type]) {
63  case NSEventTypeLeftMouseDown:
64  case NSEventTypeOtherMouseDown:
65  case NSEventTypeRightMouseDown:
66  case NSEventTypeLeftMouseUp:
67  case NSEventTypeOtherMouseUp:
68  case NSEventTypeRightMouseUp:
69  case NSEventTypeLeftMouseDragged:
70  case NSEventTypeRightMouseDragged:
71  case NSEventTypeOtherMouseDragged: /* usually middle mouse dragged */
72  case NSEventTypeMouseMoved:
73  case NSEventTypeScrollWheel:
74  Cocoa_HandleMouseEvent(_this, theEvent);
75  break;
76  case NSEventTypeKeyDown:
77  case NSEventTypeKeyUp:
78  case NSEventTypeFlagsChanged:
79  Cocoa_HandleKeyEvent(_this, theEvent);
80  break;
81  default:
82  break;
83  }
84 }
85 
86 // Dispatch events here so that we can handle events caught by
87 // nextEventMatchingMask in SDL, as well as events caught by other
88 // processes (such as CEF) that are passed down to NSApp.
89 - (void)sendEvent:(NSEvent *)theEvent
90 {
91  if (s_bShouldHandleEventsInSDLApplication) {
92  Cocoa_DispatchEvent(theEvent);
93  }
94 
95  [super sendEvent:theEvent];
96 }
97 
98 + (void)registerUserDefaults
99 {
100  NSDictionary *appDefaults = [[NSDictionary alloc] initWithObjectsAndKeys:
101  [NSNumber numberWithBool:NO], @"AppleMomentumScrollSupported",
102  [NSNumber numberWithBool:NO], @"ApplePressAndHoldEnabled",
103  [NSNumber numberWithBool:YES], @"ApplePersistenceIgnoreState",
104  nil];
105  [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
106  [appDefaults release];
107 }
108 
109 @end // SDLApplication
110 
111 /* setAppleMenu disappeared from the headers in 10.4 */
112 @interface NSApplication(NSAppleMenu)
113 - (void)setAppleMenu:(NSMenu *)menu;
114 @end
115 
116 @interface SDLAppDelegate : NSObject <NSApplicationDelegate> {
117 @public
118  BOOL seenFirstActivate;
119 }
120 
121 - (id)init;
122 - (void)localeDidChange:(NSNotification *)notification;
123 @end
124 
125 @implementation SDLAppDelegate : NSObject
126 - (id)init
127 {
128  self = [super init];
129  if (self) {
130  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
131 
132  seenFirstActivate = NO;
133 
134  [center addObserver:self
135  selector:@selector(windowWillClose:)
136  name:NSWindowWillCloseNotification
137  object:nil];
138 
139  [center addObserver:self
140  selector:@selector(focusSomeWindow:)
141  name:NSApplicationDidBecomeActiveNotification
142  object:nil];
143 
144  [center addObserver:self
145  selector:@selector(localeDidChange:)
146  name:NSCurrentLocaleDidChangeNotification
147  object:nil];
148  }
149 
150  return self;
151 }
152 
153 - (void)dealloc
154 {
155  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
156 
157  [center removeObserver:self name:NSWindowWillCloseNotification object:nil];
158  [center removeObserver:self name:NSApplicationDidBecomeActiveNotification object:nil];
159  [center removeObserver:self name:NSCurrentLocaleDidChangeNotification object:nil];
160 
161  [super dealloc];
162 }
163 
164 - (void)windowWillClose:(NSNotification *)notification;
165 {
166  NSWindow *win = (NSWindow*)[notification object];
167 
168  if (![win isKeyWindow]) {
169  return;
170  }
171 
172  /* HACK: Make the next window in the z-order key when the key window is
173  * closed. The custom event loop and/or windowing code we have seems to
174  * prevent the normal behavior: https://bugzilla.libsdl.org/show_bug.cgi?id=1825
175  */
176 
177  /* +[NSApp orderedWindows] never includes the 'About' window, but we still
178  * want to try its list first since the behavior in other apps is to only
179  * make the 'About' window key if no other windows are on-screen.
180  */
181  for (NSWindow *window in [NSApp orderedWindows]) {
182  if (window != win && [window canBecomeKeyWindow]) {
183  if (![window isOnActiveSpace]) {
184  continue;
185  }
186  [window makeKeyAndOrderFront:self];
187  return;
188  }
189  }
190 
191  /* If a window wasn't found above, iterate through all visible windows in
192  * the active Space in z-order (including the 'About' window, if it's shown)
193  * and make the first one key.
194  */
195  for (NSNumber *num in [NSWindow windowNumbersWithOptions:0]) {
196  NSWindow *window = [NSApp windowWithWindowNumber:[num integerValue]];
197  if (window && window != win && [window canBecomeKeyWindow]) {
198  [window makeKeyAndOrderFront:self];
199  return;
200  }
201  }
202 }
203 
204 - (void)focusSomeWindow:(NSNotification *)aNotification
205 {
206  /* HACK: Ignore the first call. The application gets a
207  * applicationDidBecomeActive: a little bit after the first window is
208  * created, and if we don't ignore it, a window that has been created with
209  * SDL_WINDOW_MINIMIZED will ~immediately be restored.
210  */
211  if (!seenFirstActivate) {
212  seenFirstActivate = YES;
213  return;
214  }
215 
217  if (device && device->windows) {
218  SDL_Window *window = device->windows;
219  int i;
220  for (i = 0; i < device->num_displays; ++i) {
221  SDL_Window *fullscreen_window = device->displays[i].fullscreen_window;
222  if (fullscreen_window) {
223  if (fullscreen_window->flags & SDL_WINDOW_MINIMIZED) {
224  SDL_RestoreWindow(fullscreen_window);
225  }
226  return;
227  }
228  }
229 
230  if (window->flags & SDL_WINDOW_MINIMIZED) {
231  SDL_RestoreWindow(window);
232  } else {
233  SDL_RaiseWindow(window);
234  }
235  }
236 }
237 
238 - (void)localeDidChange:(NSNotification *)notification;
239 {
241 }
242 
243 - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
244 {
245  return (BOOL)SDL_SendDropFile(NULL, [filename UTF8String]) && SDL_SendDropComplete(NULL);
246 }
247 
248 - (void)applicationDidFinishLaunching:(NSNotification *)notification
249 {
250  /* The menu bar of SDL apps which don't have the typical .app bundle
251  * structure fails to work the first time a window is created (until it's
252  * de-focused and re-focused), if this call is in Cocoa_RegisterApp instead
253  * of here. https://bugzilla.libsdl.org/show_bug.cgi?id=3051
254  */
256  /* Get more aggressive for Catalina: activate the Dock first so we definitely reset all activation state. */
257  for (NSRunningApplication *i in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"]) {
258  [i activateWithOptions:NSApplicationActivateIgnoringOtherApps];
259  break;
260  }
261  SDL_Delay(300); /* !!! FIXME: this isn't right. */
262  [NSApp activateIgnoringOtherApps:YES];
263  }
264 
265  [[NSAppleEventManager sharedAppleEventManager]
266  setEventHandler:self
267  andSelector:@selector(handleURLEvent:withReplyEvent:)
268  forEventClass:kInternetEventClass
269  andEventID:kAEGetURL];
270 
271  /* If we call this before NSApp activation, macOS might print a complaint
272  * about ApplePersistenceIgnoreState. */
273  [SDLApplication registerUserDefaults];
274 }
275 
276 - (void)handleURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
277 {
278  NSString* path = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
279  SDL_SendDropFile(NULL, [path UTF8String]);
281 }
282 
283 @end
284 
285 static SDLAppDelegate *appDelegate = nil;
286 
287 static NSString *
288 GetApplicationName(void)
289 {
290  NSString *appName;
291 
292  /* Determine the application name */
293  appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
294  if (!appName) {
295  appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
296  }
297 
298  if (![appName length]) {
299  appName = [[NSProcessInfo processInfo] processName];
300  }
301 
302  return appName;
303 }
304 
305 static bool
306 LoadMainMenuNibIfAvailable(void)
307 {
308  NSDictionary *infoDict;
309  NSString *mainNibFileName;
310  bool success = false;
311 
312  if (floor(NSAppKitVersionNumber) < NSAppKitVersionNumber10_8) {
313  return false;
314  }
315  infoDict = [[NSBundle mainBundle] infoDictionary];
316  if (infoDict) {
317  mainNibFileName = [infoDict valueForKey:@"NSMainNibFile"];
318 
319  if (mainNibFileName) {
320  success = [[NSBundle mainBundle] loadNibNamed:mainNibFileName owner:[NSApplication sharedApplication] topLevelObjects:nil];
321  }
322  }
323 
324  return success;
325 }
326 
327 static void
328 CreateApplicationMenus(void)
329 {
330  NSString *appName;
331  NSString *title;
332  NSMenu *appleMenu;
333  NSMenu *serviceMenu;
334  NSMenu *windowMenu;
335  NSMenuItem *menuItem;
336  NSMenu *mainMenu;
337 
338  if (NSApp == nil) {
339  return;
340  }
341 
342  mainMenu = [[NSMenu alloc] init];
343 
344  /* Create the main menu bar */
345  [NSApp setMainMenu:mainMenu];
346 
347  [mainMenu release]; /* we're done with it, let NSApp own it. */
348  mainMenu = nil;
349 
350  /* Create the application menu */
351  appName = GetApplicationName();
352  appleMenu = [[NSMenu alloc] initWithTitle:@""];
353 
354  /* Add menu items */
355  title = [@"About " stringByAppendingString:appName];
356  [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
357 
358  [appleMenu addItem:[NSMenuItem separatorItem]];
359 
360  [appleMenu addItemWithTitle:@"Preferences…" action:nil keyEquivalent:@","];
361 
362  [appleMenu addItem:[NSMenuItem separatorItem]];
363 
364  serviceMenu = [[NSMenu alloc] initWithTitle:@""];
365  menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Services" action:nil keyEquivalent:@""];
366  [menuItem setSubmenu:serviceMenu];
367 
368  [NSApp setServicesMenu:serviceMenu];
369  [serviceMenu release];
370 
371  [appleMenu addItem:[NSMenuItem separatorItem]];
372 
373  title = [@"Hide " stringByAppendingString:appName];
374  [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
375 
376  menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
377  [menuItem setKeyEquivalentModifierMask:(NSEventModifierFlagOption|NSEventModifierFlagCommand)];
378 
379  [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
380 
381  [appleMenu addItem:[NSMenuItem separatorItem]];
382 
383  title = [@"Quit " stringByAppendingString:appName];
384  [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
385 
386  /* Put menu into the menubar */
387  menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
388  [menuItem setSubmenu:appleMenu];
389  [[NSApp mainMenu] addItem:menuItem];
390  [menuItem release];
391 
392  /* Tell the application object that this is now the application menu */
393  [NSApp setAppleMenu:appleMenu];
394  [appleMenu release];
395 
396 
397  /* Create the window menu */
398  windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
399 
400  /* Add menu items */
401  [windowMenu addItemWithTitle:@"Close" action:@selector(performClose:) keyEquivalent:@"w"];
402 
403  [windowMenu addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
404 
405  [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""];
406 
407  /* Add the fullscreen toggle menu option, if supported */
408  if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) {
409  /* Cocoa should update the title to Enter or Exit Full Screen automatically.
410  * But if not, then just fallback to Toggle Full Screen.
411  */
412  menuItem = [[NSMenuItem alloc] initWithTitle:@"Toggle Full Screen" action:@selector(toggleFullScreen:) keyEquivalent:@"f"];
413  [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand];
414  [windowMenu addItem:menuItem];
415  [menuItem release];
416  }
417 
418  /* Put menu into the menubar */
419  menuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
420  [menuItem setSubmenu:windowMenu];
421  [[NSApp mainMenu] addItem:menuItem];
422  [menuItem release];
423 
424  /* Tell the application object that this is now the window menu */
425  [NSApp setWindowsMenu:windowMenu];
426  [windowMenu release];
427 }
428 
429 void
430 Cocoa_RegisterApp(void)
431 { @autoreleasepool
432 {
433  /* This can get called more than once! Be careful what you initialize! */
434 
435  if (NSApp == nil) {
436  [SDLApplication sharedApplication];
437  SDL_assert(NSApp != nil);
438 
439  s_bShouldHandleEventsInSDLApplication = SDL_TRUE;
440 
442  [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
443  }
444 
445  /* If there aren't already menus in place, look to see if there's
446  * a nib we should use. If not, then manually create the basic
447  * menus we meed.
448  */
449  if ([NSApp mainMenu] == nil) {
450  bool nibLoaded;
451 
452  nibLoaded = LoadMainMenuNibIfAvailable();
453  if (!nibLoaded) {
454  CreateApplicationMenus();
455  }
456  }
457  [NSApp finishLaunching];
458  if ([NSApp delegate]) {
459  /* The SDL app delegate calls this in didFinishLaunching if it's
460  * attached to the NSApp, otherwise we need to call it manually.
461  */
462  [SDLApplication registerUserDefaults];
463  }
464  }
465  if (NSApp && !appDelegate) {
466  appDelegate = [[SDLAppDelegate alloc] init];
467 
468  /* If someone else has an app delegate, it means we can't turn a
469  * termination into SDL_Quit, and we can't handle application:openFile:
470  */
471  if (![NSApp delegate]) {
472  [(NSApplication *)NSApp setDelegate:appDelegate];
473  } else {
474  appDelegate->seenFirstActivate = YES;
475  }
476  }
477 }}
478 
479 void
481 { @autoreleasepool
482 {
483 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
484  /* Update activity every 30 seconds to prevent screensaver */
486  if (_this->suspend_screensaver && !data->screensaver_use_iopm) {
487  Uint32 now = SDL_GetTicks();
488  if (!data->screensaver_activity ||
489  SDL_TICKS_PASSED(now, data->screensaver_activity + 30000)) {
490  UpdateSystemActivity(UsrActivity);
491  data->screensaver_activity = now;
492  }
493  }
494 #endif
495 
496  for ( ; ; ) {
497  NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ];
498  if ( event == nil ) {
499  break;
500  }
501 
502  if (!s_bShouldHandleEventsInSDLApplication) {
503  Cocoa_DispatchEvent(event);
504  }
505 
506  // Pass events down to SDLApplication to be handled in sendEvent:
507  [NSApp sendEvent:event];
508  }
509 }}
510 
511 void
513 { @autoreleasepool
514 {
516 
517  if (!data->screensaver_use_iopm) {
518  return;
519  }
520 
521  if (data->screensaver_assertion) {
522  IOPMAssertionRelease(data->screensaver_assertion);
523  data->screensaver_assertion = 0;
524  }
525 
526  if (_this->suspend_screensaver) {
527  /* FIXME: this should ideally describe the real reason why the game
528  * called SDL_DisableScreenSaver. Note that the name is only meant to be
529  * seen by OS X power users. there's an additional optional human-readable
530  * (localized) reason parameter which we don't set.
531  */
532  NSString *name = [GetApplicationName() stringByAppendingString:@" using SDL_DisableScreenSaver"];
533  IOPMAssertionCreateWithDescription(kIOPMAssertPreventUserIdleDisplaySleep,
534  (CFStringRef) name,
535  NULL, NULL, NULL, 0, NULL,
536  &data->screensaver_assertion);
537  }
538 }}
539 
540 #endif /* SDL_VIDEO_DRIVER_COCOA */
541 
542 /* vi: set ts=4 sw=4 expandtab: */
#define _THIS
#define SDL_assert(condition)
Definition: SDL_assert.h:171
void Cocoa_RegisterApp(void)
void Cocoa_SuspendScreenSaver(_THIS)
void Cocoa_PumpEvents(_THIS)
void Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
void Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
int SDL_SendDropFile(SDL_Window *window, const char *file)
int SDL_SendDropComplete(SDL_Window *window)
#define SDL_Delay
#define SDL_GetHintBoolean
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
int SDL_SendLocaleChangedEvent(void)
Definition: SDL_events.c:1072
int SDL_SendQuit(void)
Definition: SDL_quit.c:201
#define SDL_HINT_MAC_BACKGROUND_APP
When set don't force the SDL app to become a foreground process.
Definition: SDL_hints.h:1008
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
struct _cl_event * event
GLuint id
GLuint in
GLuint const GLchar * name
GLsizei const GLchar *const * path
GLuint GLsizei GLsizei * length
GLuint num
SDL_bool
Definition: SDL_stdinc.h:168
@ SDL_TRUE
Definition: SDL_stdinc.h:170
@ SDL_FALSE
Definition: SDL_stdinc.h:169
uint32_t Uint32
Definition: SDL_stdinc.h:209
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:587
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
Definition: SDL_timer.h:56
static SDL_VideoDevice * _this
Definition: SDL_video.c:126
@ SDL_WINDOW_MINIMIZED
Definition: SDL_video.h:105
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
#define NULL
Definition: begin_code.h:163
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
static SDL_AudioDeviceID device
Definition: loopwave.c:37
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 init[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 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld_src SRC pixld MASK if DST_R else pixld DST_R endif if src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head if pixblock_size cache_preload_simple endif process_pixblock_tail pixinterleave dst_w_basereg irp if pixblock_size chunk_size tst beq if DST_W else pixst DST_W else mov ORIG_W endif add lsl if lsl endif if lsl endif lsl endif lsl endif lsl endif subs mov DST_W if regs_shortage str endif bge start_of_loop_label endm macro generate_composite_function
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
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
double floor(double x)
Definition: s_floor.c:33
SDL_bool suspend_screensaver
Definition: SDL_sysvideo.h:324
The type used to identify a window.
Definition: SDL_sysvideo.h:75
Uint32 flags
Definition: SDL_sysvideo.h:84
void terminate(int sig)
Definition: testlock.c:45