ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/MacOSX/Controller.mm
Revision: 1.2
Committed: 2002-03-16T10:00:18Z (22 years, 6 months ago) by nigel
Branch: MAIN
Log Message:
Initial revision of Mac OS X port code. Uses Objective-C++. Needs Mac OS 10.1

File Contents

# Content
1 /*
2 * Controller.m - Simple application window management.
3 *
4 * $Id$
5 *
6 * Basilisk II (C) 1997-2001 Christian Bauer
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #import "Controller.h"
24 #import "Emulator.h"
25
26 @implementation Controller
27
28 #import "sysdeps.h" // Types used in Basilisk C++ code
29
30 #import <main.h>
31 #import <prefs.h>
32
33 #define DEBUG 0
34 #import <debug.h>
35
36 #import "video_macosx.h"
37
38 //
39 // Standard NSApplication methods that we override
40 //
41
42 - (id) init
43 {
44 #ifdef ENABLE_MULTIPLE
45 emulators = [[NSMutableArray alloc] init];
46 #endif
47 return [super init];
48 }
49
50 - (void) dealloc
51 {
52 #ifdef ENABLE_MULTIPLE
53 [emulators dealloc];
54 #endif
55 [super dealloc];
56 }
57
58 - (void) awakeFromNib
59 {
60 #ifdef ENABLE_MULTIPLE
61 [self NewEmulator: self]; // So the user gets something on screen
62 #endif
63 [[NSApplication sharedApplication]
64 setDelegate: self]; // Enable applicationShouldTerminate
65 }
66
67 - (void) sendEvent: (NSEvent *)event;
68 {
69 NSEventType type = [event type];
70
71 if ( type == NSKeyUp || type == NSKeyDown || type == NSFlagsChanged )
72 [self dispatchKeyEvent: event
73 type: type];
74 else
75 [self dispatchEvent: event
76 type: type];
77 }
78
79 // NSApplication methods which are invoked through delegation
80
81 - (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication *)app
82 { return YES; }
83
84 - (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *)app
85 {
86 short count;
87 char *stillRunningMessage;
88
89 if ( [thePrefsEditor hasEdited] )
90 if ( ChoiceAlert("Preferences have been edited",
91 "Save changes", "Quit") )
92 SavePrefs();
93
94 // if ( edited )
95 // {
96 // NSString *title = [NSString stringWithCString: getString(STR_WARNING_ALERT_TITLE)],
97 // *msg = @"Preferences have been edited",
98 // *def = @"Save changes",
99 // *alt = @"Quit Application",
100 // *other = @"Continue";
101 //
102 // switch ( NSRunAlertPanel(title, msg, def, alt, other, nil) )
103 // {
104 // case NSAlertDefault: savePrefs();
105 // case NSAlertAlternate: return NSTerminateNow;
106 // case NSAlertOther: return NSTerminateCancel;
107 // }
108 // }
109
110
111 if ( [[thePrefsEditor window] isVisible] )
112 [[thePrefsEditor window] performClose: self];
113
114
115 count = [self emulatorCreatedCount];
116
117 if ( count > 0 )
118 {
119 if ( count > 1 )
120 stillRunningMessage = "Emulators are still running\nExiting Basilisk may lose data";
121 else
122 stillRunningMessage = "Emulator is still running\nExiting Basilisk may lose data";
123 if ( ! ChoiceAlert(stillRunningMessage, "Exit", "Continue") )
124 return NSTerminateCancel; // NSTerminateLater?
125 }
126
127 return NSTerminateNow;
128 }
129
130
131 // Event dispatching, called by sendEvent
132
133 - (void) dispatchKeyEvent: (NSEvent *)event
134 type: (NSEventType)type
135 {
136 EmulatorView *view;
137
138 #ifdef ENABLE_MULTIPLE
139 // We need to work out what window's Emulator should receive these messages
140
141
142 int tmp;
143
144 for ( tmp = 0; tmp < [emulators count], ++tmp )
145 {
146 theEmulator = [emulators objectAtIndex: tmp];
147 if ( [ theEmulator isRunning ] && [[theEmulator window] isKeyWindow ] )
148 break;
149 }
150
151 if ( tmp < [emulators count] ) // i.e. if we exited the for loop
152 #else
153 if ( [theEmulator isRunning] && [[theEmulator window] isKeyWindow ] )
154 #endif
155 {
156 view = [theEmulator screen];
157
158 switch ( type )
159 {
160 case NSKeyUp:
161 [view keyUp: event];
162 break;
163 case NSKeyDown:
164 D(NSLog(@"%s - NSKeyDown - %@", __PRETTY_FUNCTION__, event));
165 [view keyDown: event];
166 break;
167 case NSFlagsChanged:
168 [view flagsChanged: event];
169 break;
170 default:
171 NSLog(@"%s - Sent a non-key event (logic error)",
172 __PRETTY_FUNCTION__);
173 [super sendEvent: event];
174 }
175 }
176 else // No Basilisk window is key (maybe a panel or pane).
177 [super sendEvent: event]; // Call NSApplication default
178
179 }
180
181 - (void) dispatchEvent: (NSEvent *)event
182 type: (NSEventType)type
183 {
184 #ifdef ENABLE_MULTIPLE
185 // We need to work out what window's Emulator should receive these messages
186
187
188 int tmp;
189
190 for ( tmp = 0; tmp < [emulators count], ++tmp )
191 {
192 theEmulator = [emulators objectAtIndex: tmp];
193 if ( [ theEmulator isRunning ] && [[theEmulator window] isMainWindow ] )
194 break;
195 }
196
197 if ( tmp < [emulators count] ) // i.e. if we exited the for loop
198 #else
199 if ( FULLSCREEN ||
200 ( [theEmulator isRunning] && [[theEmulator window] isMainWindow ] ) )
201 #endif
202 {
203 EmulatorView *view = [theEmulator screen];
204
205 // if ( [view mouseInView] )
206 if ( [view mouseInView: event] || FULLSCREEN )
207 {
208 switch ( type )
209 {
210 case NSLeftMouseDown:
211 [view mouseDown: event];
212 break;
213 case NSLeftMouseUp:
214 [view mouseUp: event];
215 break;
216 case NSLeftMouseDragged:
217 case NSMouseMoved:
218 [view processMouseMove: event];
219 break;
220 default:
221 [super sendEvent: event]; // NSApplication default
222 }
223 return;
224 }
225 }
226
227 // Either the pointer is not in the Emulator's screen, no Basilisk window is running,
228 // or no Basilisk window is main (e.g. there might be a panel or pane up).
229 //
230 // We should just be calling NSApp's default sendEvent, but then for some reason
231 // mouseMoved events are still passed to our EmulatorView, so we filter them out.
232
233 if ( type != NSMouseMoved )
234 [super sendEvent: event];
235 }
236
237 #ifdef ENABLE_MULTIPLE
238
239 - (IBAction) NewEmulator: (id)sender
240 {
241 NSString *title;
242
243 if ( ! [NSBundle loadNibNamed:@"Win512x342" owner:self] )
244 {
245 NSLog(@"%s - LoadNibNamed@Win512x342 failed", __PRETTY_FUNCTION__);
246 return;
247 }
248
249 if ( theEmulator == nil)
250 {
251 NSLog(@"%s - Newly created emulator's NIB stuff not fully linked?", __PRETTY_FUNCTION__);
252 return;
253 }
254
255 [emulators addObject: theEmulator];
256 title = [NSString localizedStringWithFormat:@"BasiliskII Emulator %d", [emulators count]];
257 [theEmulator -> win setTitle: title];
258 }
259
260 - (IBAction) PauseAll: (id)sender
261 {
262 [emulators makeObjectsPerformSelector:@selector(Suspend:)
263 withObject:self];
264 }
265
266 - (IBAction) RunAll: (id)sender
267 {
268 [emulators makeObjectsPerformSelector:@selector(Resume:)
269 withObject:self];
270 }
271
272 - (IBAction) TerminateAll: (id)sender
273 {
274 [emulators makeObjectsPerformSelector:@selector(Terminate:)
275 withObject:self];
276 }
277
278 #endif
279
280 - (BOOL) isAnyEmulatorRunning
281 {
282 #ifdef ENABLE_MULTIPLE
283 int tmp;
284
285 for ( tmp = 0; tmp < [emulators count], ++tmp )
286 if ( [[emulators objectAtIndex: tmp] isRunning] )
287 break;
288
289 if ( tmp < [emulators count] ) // i.e. if we exited the for loop
290 #else
291 if ( [theEmulator isRunning] )
292 #endif
293 return TRUE;
294
295 return FALSE;
296 }
297
298 - (short) emulatorCreatedCount
299 {
300 short count = 0;
301 #ifdef ENABLE_MULTIPLE
302 int tmp;
303
304 for ( tmp = 0; tmp < [emulators count], ++tmp )
305 if ( [[emulators objectAtIndex: tmp] uaeCreated] )
306 ++count;
307 #else
308 if ( [theEmulator uaeCreated] )
309 ++count;
310 #endif
311
312 return count;
313 }
314
315 @end