winemac: Implement MsgWaitForMultipleObjectsEx and infrastructure for processing...
[wine] / dlls / winemac.drv / cocoa_app.m
1 /*
2  * MACDRV Cocoa application class
3  *
4  * Copyright 2011, 2012, 2013 Ken Thomases for CodeWeavers Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #import "cocoa_app.h"
22
23
24 int macdrv_err_on;
25
26
27 @implementation WineApplication
28
29     - (id) init
30     {
31         self = [super init];
32         if (self != nil)
33         {
34             eventQueues = [[NSMutableArray alloc] init];
35             eventQueuesLock = [[NSLock alloc] init];
36
37             if (!eventQueues || !eventQueuesLock)
38             {
39                 [self release];
40                 return nil;
41             }
42         }
43         return self;
44     }
45
46     - (void) dealloc
47     {
48         [eventQueues release];
49         [eventQueuesLock release];
50         [super dealloc];
51     }
52
53     - (void) transformProcessToForeground
54     {
55         if ([self activationPolicy] != NSApplicationActivationPolicyRegular)
56         {
57             NSMenu* mainMenu;
58             NSMenu* submenu;
59             NSString* bundleName;
60             NSString* title;
61             NSMenuItem* item;
62
63             [self setActivationPolicy:NSApplicationActivationPolicyRegular];
64             [self activateIgnoringOtherApps:YES];
65
66             mainMenu = [[[NSMenu alloc] init] autorelease];
67
68             submenu = [[[NSMenu alloc] initWithTitle:@"Wine"] autorelease];
69             bundleName = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString*)kCFBundleNameKey];
70             if ([bundleName length])
71                 title = [NSString stringWithFormat:@"Quit %@", bundleName];
72             else
73                 title = @"Quit";
74             item = [submenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
75             [item setKeyEquivalentModifierMask:NSCommandKeyMask | NSAlternateKeyMask];
76             item = [[[NSMenuItem alloc] init] autorelease];
77             [item setTitle:@"Wine"];
78             [item setSubmenu:submenu];
79             [mainMenu addItem:item];
80
81             submenu = [[[NSMenu alloc] initWithTitle:@"Window"] autorelease];
82             [submenu addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@""];
83             [submenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""];
84             [submenu addItem:[NSMenuItem separatorItem]];
85             [submenu addItemWithTitle:@"Bring All to Front" action:@selector(arrangeInFront:) keyEquivalent:@""];
86             item = [[[NSMenuItem alloc] init] autorelease];
87             [item setTitle:@"Window"];
88             [item setSubmenu:submenu];
89             [mainMenu addItem:item];
90
91             [self setMainMenu:mainMenu];
92             [self setWindowsMenu:submenu];
93         }
94     }
95
96     - (BOOL) registerEventQueue:(WineEventQueue*)queue
97     {
98         [eventQueuesLock lock];
99         [eventQueues addObject:queue];
100         [eventQueuesLock unlock];
101         return TRUE;
102     }
103
104     - (void) unregisterEventQueue:(WineEventQueue*)queue
105     {
106         [eventQueuesLock lock];
107         [eventQueues removeObjectIdenticalTo:queue];
108         [eventQueuesLock unlock];
109     }
110
111 @end
112
113 /***********************************************************************
114  *              OnMainThread
115  *
116  * Run a block on the main thread synchronously.
117  */
118 void OnMainThread(dispatch_block_t block)
119 {
120     dispatch_sync(dispatch_get_main_queue(), block);
121 }
122
123 /***********************************************************************
124  *              OnMainThreadAsync
125  *
126  * Run a block on the main thread asynchronously.
127  */
128 void OnMainThreadAsync(dispatch_block_t block)
129 {
130     dispatch_async(dispatch_get_main_queue(), block);
131 }
132
133 /***********************************************************************
134  *              LogError
135  */
136 void LogError(const char* func, NSString* format, ...)
137 {
138     va_list args;
139     va_start(args, format);
140     LogErrorv(func, format, args);
141     va_end(args);
142 }
143
144 /***********************************************************************
145  *              LogErrorv
146  */
147 void LogErrorv(const char* func, NSString* format, va_list args)
148 {
149     NSString* message = [[NSString alloc] initWithFormat:format arguments:args];
150     fprintf(stderr, "err:%s:%s", func, [message UTF8String]);
151     [message release];
152 }