1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci* Copyright 2019 Google Inc.
3cb93a386Sopenharmony_ci*
4cb93a386Sopenharmony_ci* Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci* found in the LICENSE file.
6cb93a386Sopenharmony_ci*/
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#import <Cocoa/Cocoa.h>
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "tools/sk_app/Application.h"
11cb93a386Sopenharmony_ci#include "tools/sk_app/mac/Window_mac.h"
12cb93a386Sopenharmony_ci
13cb93a386Sopenharmony_ci@interface AppDelegate : NSObject<NSApplicationDelegate, NSWindowDelegate>
14cb93a386Sopenharmony_ci
15cb93a386Sopenharmony_ci@property (nonatomic, assign) BOOL done;
16cb93a386Sopenharmony_ci
17cb93a386Sopenharmony_ci@end
18cb93a386Sopenharmony_ci
19cb93a386Sopenharmony_ci@implementation AppDelegate : NSObject
20cb93a386Sopenharmony_ci
21cb93a386Sopenharmony_ci@synthesize done = _done;
22cb93a386Sopenharmony_ci
23cb93a386Sopenharmony_ci- (id)init {
24cb93a386Sopenharmony_ci    self = [super init];
25cb93a386Sopenharmony_ci    _done = FALSE;
26cb93a386Sopenharmony_ci    return self;
27cb93a386Sopenharmony_ci}
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_ci- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
30cb93a386Sopenharmony_ci    _done = TRUE;
31cb93a386Sopenharmony_ci    return NSTerminateCancel;
32cb93a386Sopenharmony_ci}
33cb93a386Sopenharmony_ci
34cb93a386Sopenharmony_ci- (void)applicationDidFinishLaunching:(NSNotification *)notification {
35cb93a386Sopenharmony_ci    [NSApp stop:nil];
36cb93a386Sopenharmony_ci}
37cb93a386Sopenharmony_ci
38cb93a386Sopenharmony_ci@end
39cb93a386Sopenharmony_ci
40cb93a386Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////////////////
41cb93a386Sopenharmony_ci
42cb93a386Sopenharmony_ciusing sk_app::Application;
43cb93a386Sopenharmony_ciusing sk_app::Window_mac;
44cb93a386Sopenharmony_ci
45cb93a386Sopenharmony_ciint main(int argc, char * argv[]) {
46cb93a386Sopenharmony_ci#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
47cb93a386Sopenharmony_ci    // we only run on systems that support at least Core Profile 3.2
48cb93a386Sopenharmony_ci    return EXIT_FAILURE;
49cb93a386Sopenharmony_ci#endif
50cb93a386Sopenharmony_ci
51cb93a386Sopenharmony_ci    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
52cb93a386Sopenharmony_ci    [NSApplication sharedApplication];
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_ci    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
55cb93a386Sopenharmony_ci
56cb93a386Sopenharmony_ci    //Create the application menu.
57cb93a386Sopenharmony_ci    NSMenu* menuBar=[[NSMenu alloc] initWithTitle:@"AMainMenu"];
58cb93a386Sopenharmony_ci    [NSApp setMainMenu:menuBar];
59cb93a386Sopenharmony_ci
60cb93a386Sopenharmony_ci    NSMenuItem* item;
61cb93a386Sopenharmony_ci    NSMenu* subMenu;
62cb93a386Sopenharmony_ci
63cb93a386Sopenharmony_ci    item=[[NSMenuItem alloc] initWithTitle:@"Apple" action:nil keyEquivalent:@""];
64cb93a386Sopenharmony_ci    [menuBar addItem:item];
65cb93a386Sopenharmony_ci    subMenu=[[NSMenu alloc] initWithTitle:@"Apple"];
66cb93a386Sopenharmony_ci    [menuBar setSubmenu:subMenu forItem:item];
67cb93a386Sopenharmony_ci    [item release];
68cb93a386Sopenharmony_ci    item=[[NSMenuItem alloc] initWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"];
69cb93a386Sopenharmony_ci    [subMenu addItem:item];
70cb93a386Sopenharmony_ci    [item release];
71cb93a386Sopenharmony_ci    [subMenu release];
72cb93a386Sopenharmony_ci
73cb93a386Sopenharmony_ci    // Set AppDelegate to catch certain global events
74cb93a386Sopenharmony_ci    AppDelegate* appDelegate = [[AppDelegate alloc] init];
75cb93a386Sopenharmony_ci    [NSApp setDelegate:appDelegate];
76cb93a386Sopenharmony_ci
77cb93a386Sopenharmony_ci    Application* app = Application::Create(argc, argv, nullptr);
78cb93a386Sopenharmony_ci
79cb93a386Sopenharmony_ci    // This will run until the application finishes launching, then lets us take over
80cb93a386Sopenharmony_ci    [NSApp run];
81cb93a386Sopenharmony_ci
82cb93a386Sopenharmony_ci    // Now we process the events
83cb93a386Sopenharmony_ci    while (![appDelegate done]) {
84cb93a386Sopenharmony_ci        NSEvent* event;
85cb93a386Sopenharmony_ci        do {
86cb93a386Sopenharmony_ci            event = [NSApp nextEventMatchingMask:NSAnyEventMask
87cb93a386Sopenharmony_ci                                       untilDate:[NSDate distantPast]
88cb93a386Sopenharmony_ci                                          inMode:NSDefaultRunLoopMode
89cb93a386Sopenharmony_ci                                         dequeue:YES];
90cb93a386Sopenharmony_ci            [NSApp sendEvent:event];
91cb93a386Sopenharmony_ci        } while (event != nil);
92cb93a386Sopenharmony_ci
93cb93a386Sopenharmony_ci        [pool drain];
94cb93a386Sopenharmony_ci        pool = [[NSAutoreleasePool alloc] init];
95cb93a386Sopenharmony_ci
96cb93a386Sopenharmony_ci        // Rather than depending on a Mac event to drive this, we treat our window
97cb93a386Sopenharmony_ci        // invalidation flag as a separate event stream. Window::onPaint() will clear
98cb93a386Sopenharmony_ci        // the invalidation flag, effectively removing it from the stream.
99cb93a386Sopenharmony_ci        Window_mac::PaintWindows();
100cb93a386Sopenharmony_ci
101cb93a386Sopenharmony_ci        app->onIdle();
102cb93a386Sopenharmony_ci    }
103cb93a386Sopenharmony_ci
104cb93a386Sopenharmony_ci    delete app;
105cb93a386Sopenharmony_ci
106cb93a386Sopenharmony_ci    [NSApp setDelegate:nil];
107cb93a386Sopenharmony_ci    [appDelegate release];
108cb93a386Sopenharmony_ci
109cb93a386Sopenharmony_ci    [menuBar release];
110cb93a386Sopenharmony_ci    [pool release];
111cb93a386Sopenharmony_ci
112cb93a386Sopenharmony_ci    return EXIT_SUCCESS;
113cb93a386Sopenharmony_ci}
114