src/video/cocoa/SDL_cocoaevents.m
author Ryan C. Gordon <icculus@icculus.org>
Fri, 02 Nov 2012 16:48:47 -0400
changeset 6639 c7e81fae23c4
parent 6515 f750d9ecae1e
child 6832 156e608ec4ef
permissions -rw-r--r--
Cocoa_ShowMessageBox() should call Cocoa_RegisterApp().

Otherwise, message boxes can fail if SDL_Init(SDL_INIT_VIDEO) wasn't completed.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "SDL_config.h"
    22 
    23 #if SDL_VIDEO_DRIVER_COCOA
    24 #include "SDL_timer.h"
    25 
    26 #include "SDL_cocoavideo.h"
    27 #include "../../events/SDL_events_c.h"
    28 
    29 #if !defined(UsrActivity) && defined(__LP64__) && !defined(__POWER__)
    30 /*
    31  * Workaround for a bug in the 10.5 SDK: By accident, OSService.h does
    32  * not include Power.h at all when compiling in 64bit mode. This has
    33  * been fixed in 10.6, but for 10.5, we manually define UsrActivity
    34  * to ensure compilation works.
    35  */
    36 #define UsrActivity 1
    37 #endif
    38 
    39 /* setAppleMenu disappeared from the headers in 10.4 */
    40 @interface NSApplication(NSAppleMenu)
    41 - (void)setAppleMenu:(NSMenu *)menu;
    42 @end
    43 
    44 @interface SDLAppDelegate : NSObject
    45 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
    46 @end
    47 
    48 @implementation SDLAppDelegate : NSObject
    49 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
    50 {
    51     SDL_SendQuit();
    52     return NSTerminateCancel;
    53 }
    54 
    55 - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
    56 {
    57     return (BOOL)SDL_SendDropFile([filename UTF8String]);
    58 }
    59 @end
    60 
    61 static NSString *
    62 GetApplicationName(void)
    63 {
    64     NSDictionary *dict;
    65     NSString *appName = 0;
    66 
    67     /* Determine the application name */
    68     dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
    69     if (dict)
    70         appName = [dict objectForKey: @"CFBundleName"];
    71     
    72     if (![appName length])
    73         appName = [[NSProcessInfo processInfo] processName];
    74 
    75     return appName;
    76 }
    77 
    78 static void
    79 CreateApplicationMenus(void)
    80 {
    81     NSString *appName;
    82     NSString *title;
    83     NSMenu *appleMenu;
    84     NSMenu *serviceMenu;
    85     NSMenu *windowMenu;
    86     NSMenuItem *menuItem;
    87     
    88     /* Create the main menu bar */
    89     [NSApp setMainMenu:[[NSMenu alloc] init]];
    90 
    91     /* Create the application menu */
    92     appName = GetApplicationName();
    93     appleMenu = [[NSMenu alloc] initWithTitle:@""];
    94     
    95     /* Add menu items */
    96     title = [@"About " stringByAppendingString:appName];
    97     [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
    98 
    99     [appleMenu addItem:[NSMenuItem separatorItem]];
   100 
   101     [appleMenu addItemWithTitle:@"Preferences…" action:nil keyEquivalent:@","];
   102 
   103     [appleMenu addItem:[NSMenuItem separatorItem]];
   104 
   105     serviceMenu = [[NSMenu alloc] initWithTitle:@""];
   106     menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Services" action:nil keyEquivalent:@""];
   107     [menuItem setSubmenu:serviceMenu];
   108 
   109     [NSApp setServicesMenu:serviceMenu];
   110 
   111     [appleMenu addItem:[NSMenuItem separatorItem]];
   112 
   113     title = [@"Hide " stringByAppendingString:appName];
   114     [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
   115 
   116     menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
   117     [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
   118 
   119     [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
   120 
   121     [appleMenu addItem:[NSMenuItem separatorItem]];
   122 
   123     title = [@"Quit " stringByAppendingString:appName];
   124     [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
   125     
   126     /* Put menu into the menubar */
   127     menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
   128     [menuItem setSubmenu:appleMenu];
   129     [[NSApp mainMenu] addItem:menuItem];
   130     [menuItem release];
   131 
   132     /* Tell the application object that this is now the application menu */
   133     [NSApp setAppleMenu:appleMenu];
   134     [appleMenu release];
   135 
   136 
   137     /* Create the window menu */
   138     windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
   139     
   140     /* Add menu items */
   141     [windowMenu addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
   142     
   143     [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""];
   144 
   145     /* Put menu into the menubar */
   146     menuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
   147     [menuItem setSubmenu:windowMenu];
   148     [[NSApp mainMenu] addItem:menuItem];
   149     [menuItem release];
   150     
   151     /* Tell the application object that this is now the window menu */
   152     [NSApp setWindowsMenu:windowMenu];
   153     [windowMenu release];
   154 }
   155 
   156 void
   157 Cocoa_RegisterApp(void)
   158 {
   159     /* This can get called more than once! Be careful what you initialize! */
   160     ProcessSerialNumber psn;
   161     NSAutoreleasePool *pool;
   162 
   163     if (!GetCurrentProcess(&psn)) {
   164         TransformProcessType(&psn, kProcessTransformToForegroundApplication);
   165         SetFrontProcess(&psn);
   166     }
   167 
   168     pool = [[NSAutoreleasePool alloc] init];
   169     if (NSApp == nil) {
   170         [NSApplication sharedApplication];
   171 
   172         if ([NSApp mainMenu] == nil) {
   173             CreateApplicationMenus();
   174         }
   175         [NSApp finishLaunching];
   176     }
   177     if ([NSApp delegate] == nil) {
   178         [NSApp setDelegate:[[SDLAppDelegate alloc] init]];
   179     }
   180     [pool release];
   181 }
   182 
   183 void
   184 Cocoa_PumpEvents(_THIS)
   185 {
   186     NSAutoreleasePool *pool;
   187 
   188     /* Update activity every 30 seconds to prevent screensaver */
   189     if (_this->suspend_screensaver) {
   190         SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
   191         Uint32 now = SDL_GetTicks();
   192         if (!data->screensaver_activity ||
   193             (int)(now-data->screensaver_activity) >= 30000) {
   194             UpdateSystemActivity(UsrActivity);
   195             data->screensaver_activity = now;
   196         }
   197     }
   198 
   199     pool = [[NSAutoreleasePool alloc] init];
   200     for ( ; ; ) {
   201         NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ];
   202         if ( event == nil ) {
   203             break;
   204         }
   205 		
   206         switch ([event type]) {
   207         case NSLeftMouseDown:
   208         case NSOtherMouseDown:
   209         case NSRightMouseDown:
   210         case NSLeftMouseUp:
   211         case NSOtherMouseUp:
   212         case NSRightMouseUp:
   213         case NSLeftMouseDragged:
   214         case NSRightMouseDragged:
   215         case NSOtherMouseDragged: /* usually middle mouse dragged */
   216         case NSMouseMoved:
   217         case NSScrollWheel:
   218             Cocoa_HandleMouseEvent(_this, event);
   219             break;
   220         case NSKeyDown:
   221         case NSKeyUp:
   222         case NSFlagsChanged:
   223             Cocoa_HandleKeyEvent(_this, event);
   224             break;
   225         default:
   226             break;
   227         }
   228         /* Pass through to NSApp to make sure everything stays in sync */
   229         [NSApp sendEvent:event];
   230     }
   231     [pool release];
   232 }
   233 
   234 #endif /* SDL_VIDEO_DRIVER_COCOA */
   235 
   236 /* vi: set ts=4 sw=4 expandtab: */