src/video/cocoa/SDL_cocoaevents.m
author Sam Lantinga
Sat, 19 Sep 2009 13:29:40 +0000
changeset 3280 00cace2d9080
parent 3120 1282a042d530
child 3517 e7eec78e4b92
permissions -rw-r--r--
Merged a cleaned up version of Jiang's code changes from Google Summer of Code 2009
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2009 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 #include "SDL_timer.h"
    24 
    25 #include "SDL_cocoavideo.h"
    26 #include "../../events/SDL_events_c.h"
    27 
    28 
    29 /* setAppleMenu disappeared from the headers in 10.4 */
    30 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
    31 @interface NSApplication(NSAppleMenu)
    32 - (void)setAppleMenu:(NSMenu *)menu;
    33 @end
    34 #endif
    35 
    36 @implementation NSApplication(SDL)
    37 - (void)setRunning
    38 {
    39     _running = 1;
    40 }
    41 @end
    42 
    43 @interface SDLAppDelegate : NSObject
    44 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
    45 @end
    46 
    47 @implementation SDLAppDelegate : NSObject
    48 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
    49 {
    50     SDL_SendQuit();
    51     return NSTerminateCancel;
    52 }
    53 @end
    54 
    55 static NSString *
    56 GetApplicationName(void)
    57 {
    58     NSDictionary *dict;
    59     NSString *appName = 0;
    60 
    61     /* Determine the application name */
    62     dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
    63     if (dict)
    64         appName = [dict objectForKey: @"CFBundleName"];
    65     
    66     if (![appName length])
    67         appName = [[NSProcessInfo processInfo] processName];
    68 
    69     return appName;
    70 }
    71 
    72 static void
    73 CreateApplicationMenus(void)
    74 {
    75     NSString *appName;
    76     NSString *title;
    77     NSMenu *appleMenu;
    78     NSMenu *windowMenu;
    79     NSMenuItem *menuItem;
    80     
    81     /* Create the main menu bar */
    82     [NSApp setMainMenu:[[NSMenu alloc] init]];
    83 
    84     /* Create the application menu */
    85     appName = GetApplicationName();
    86     appleMenu = [[NSMenu alloc] initWithTitle:@""];
    87     
    88     /* Add menu items */
    89     title = [@"About " stringByAppendingString:appName];
    90     [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
    91 
    92     [appleMenu addItem:[NSMenuItem separatorItem]];
    93 
    94     title = [@"Hide " stringByAppendingString:appName];
    95     [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@/*"h"*/""];
    96 
    97     menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@/*"h"*/""];
    98     [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
    99 
   100     [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
   101 
   102     [appleMenu addItem:[NSMenuItem separatorItem]];
   103 
   104     title = [@"Quit " stringByAppendingString:appName];
   105     [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@/*"q"*/""];
   106     
   107     /* Put menu into the menubar */
   108     menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
   109     [menuItem setSubmenu:appleMenu];
   110     [[NSApp mainMenu] addItem:menuItem];
   111     [menuItem release];
   112 
   113     /* Tell the application object that this is now the application menu */
   114     [NSApp setAppleMenu:appleMenu];
   115     [appleMenu release];
   116 
   117 
   118     /* Create the window menu */
   119     windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
   120     
   121     /* "Minimize" item */
   122     menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@/*"m"*/""];
   123     [windowMenu addItem:menuItem];
   124     [menuItem release];
   125     
   126     /* Put menu into the menubar */
   127     menuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
   128     [menuItem setSubmenu:windowMenu];
   129     [[NSApp mainMenu] addItem:menuItem];
   130     [menuItem release];
   131     
   132     /* Tell the application object that this is now the window menu */
   133     [NSApp setWindowsMenu:windowMenu];
   134     [windowMenu release];
   135 }
   136 
   137 void
   138 Cocoa_RegisterApp(void)
   139 {
   140     ProcessSerialNumber psn;
   141     NSAutoreleasePool *pool;
   142 
   143     if (!GetCurrentProcess(&psn)) {
   144         TransformProcessType(&psn, kProcessTransformToForegroundApplication);
   145         SetFrontProcess(&psn);
   146     }
   147 
   148     pool = [[NSAutoreleasePool alloc] init];
   149     if (NSApp == nil) {
   150         [NSApplication sharedApplication];
   151 
   152         if ([NSApp mainMenu] == nil) {
   153             CreateApplicationMenus();
   154         }
   155         [NSApp finishLaunching];
   156     }
   157     if ([NSApp delegate] == nil) {
   158         [NSApp setDelegate:[[SDLAppDelegate alloc] init]];
   159     }
   160     [NSApp setRunning];
   161     [pool release];
   162 }
   163 
   164 void
   165 Cocoa_PumpEvents(_THIS)
   166 {
   167     NSAutoreleasePool *pool;
   168 
   169     /* Update activity every 30 seconds to prevent screensaver */
   170     /* FIXME: This define isn't available with 64-bit Mac OS X? */
   171 #ifdef UsrActivity
   172     if (_this->suspend_screensaver) {
   173         SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
   174         Uint32 now = SDL_GetTicks();
   175         if (!data->screensaver_activity ||
   176             (int)(now-data->screensaver_activity) >= 30000) {
   177             UpdateSystemActivity(UsrActivity);
   178             data->screensaver_activity = now;
   179         }
   180     }
   181 #endif
   182 
   183     pool = [[NSAutoreleasePool alloc] init];
   184     while ([NSApp isRunning]) {
   185         NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ];
   186         if ( event == nil ) {
   187             break;
   188         }
   189         switch ([event type]) {
   190         case NSKeyDown:
   191         case NSKeyUp:
   192         case NSFlagsChanged:
   193             Cocoa_HandleKeyEvent(_this, event);
   194             /* Fall through to pass event to NSApp; er, nevermind... */
   195             /* FIXME: Find a way to stop the beeping, using delegate */
   196 
   197             /* Add to support system-wide keyboard shortcuts like CMD+Space */
   198             if (([event modifierFlags] & NSCommandKeyMask) || [event type] == NSFlagsChanged)
   199                [NSApp sendEvent: event];
   200             break;
   201         default:
   202             [NSApp sendEvent:event];
   203             break;
   204         }
   205     }
   206     [pool release];
   207 }
   208 
   209 /* vi: set ts=4 sw=4 expandtab: */