ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/MacOSX/Controller.mm
Revision: 1.3
Committed: 2002-03-18T10:48:25Z (22 years, 3 months ago) by nigel
Branch: MAIN
CVS Tags: nigel-build-10
Changes since 1.2: +4 -3 lines
Log Message:
Bug fix. Key events were not being passed in full screen mode,
because the window, having been minimised, is no longer 'Key.'

File Contents

# Content
1 /*
2 * Controller.m - Simple application window management.
3 *
4 * $Id: Controller.mm,v 1.2 2002/03/16 10:00:18 nigel Exp $
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 ( FULLSCREEN ||
154 [theEmulator isRunning] && [[theEmulator window] isKeyWindow ] )
155 #endif
156 {
157 view = [theEmulator screen];
158 NSLog(@"Got a key event - %d\n", [event keyCode]);
159 switch ( type )
160 {
161 case NSKeyUp:
162 [view keyUp: event];
163 break;
164 case NSKeyDown:
165 D(NSLog(@"%s - NSKeyDown - %@", __PRETTY_FUNCTION__, event));
166 [view keyDown: event];
167 break;
168 case NSFlagsChanged:
169 [view flagsChanged: event];
170 break;
171 default:
172 NSLog(@"%s - Sent a non-key event (logic error)",
173 __PRETTY_FUNCTION__);
174 [super sendEvent: event];
175 }
176 }
177 else // No Basilisk window is key (maybe a panel or pane).
178 [super sendEvent: event]; // Call NSApplication default
179
180 }
181
182 - (void) dispatchEvent: (NSEvent *)event
183 type: (NSEventType)type
184 {
185 #ifdef ENABLE_MULTIPLE
186 // We need to work out what window's Emulator should receive these messages
187
188
189 int tmp;
190
191 for ( tmp = 0; tmp < [emulators count], ++tmp )
192 {
193 theEmulator = [emulators objectAtIndex: tmp];
194 if ( [ theEmulator isRunning ] && [[theEmulator window] isMainWindow ] )
195 break;
196 }
197
198 if ( tmp < [emulators count] ) // i.e. if we exited the for loop
199 #else
200 if ( FULLSCREEN ||
201 ( [theEmulator isRunning] && [[theEmulator window] isMainWindow ] ) )
202 #endif
203 {
204 EmulatorView *view = [theEmulator screen];
205
206 // if ( [view mouseInView] )
207 if ( [view mouseInView: event] || FULLSCREEN )
208 {
209 switch ( type )
210 {
211 case NSLeftMouseDown:
212 [view mouseDown: event];
213 break;
214 case NSLeftMouseUp:
215 [view mouseUp: event];
216 break;
217 case NSLeftMouseDragged:
218 case NSMouseMoved:
219 [view processMouseMove: event];
220 break;
221 default:
222 [super sendEvent: event]; // NSApplication default
223 }
224 return;
225 }
226 }
227
228 // Either the pointer is not in the Emulator's screen, no Basilisk window is running,
229 // or no Basilisk window is main (e.g. there might be a panel or pane up).
230 //
231 // We should just be calling NSApp's default sendEvent, but then for some reason
232 // mouseMoved events are still passed to our EmulatorView, so we filter them out.
233
234 if ( type != NSMouseMoved )
235 [super sendEvent: event];
236 }
237
238 #ifdef ENABLE_MULTIPLE
239
240 - (IBAction) NewEmulator: (id)sender
241 {
242 NSString *title;
243
244 if ( ! [NSBundle loadNibNamed:@"Win512x342" owner:self] )
245 {
246 NSLog(@"%s - LoadNibNamed@Win512x342 failed", __PRETTY_FUNCTION__);
247 return;
248 }
249
250 if ( theEmulator == nil)
251 {
252 NSLog(@"%s - Newly created emulator's NIB stuff not fully linked?", __PRETTY_FUNCTION__);
253 return;
254 }
255
256 [emulators addObject: theEmulator];
257 title = [NSString localizedStringWithFormat:@"BasiliskII Emulator %d", [emulators count]];
258 [theEmulator -> win setTitle: title];
259 }
260
261 - (IBAction) PauseAll: (id)sender
262 {
263 [emulators makeObjectsPerformSelector:@selector(Suspend:)
264 withObject:self];
265 }
266
267 - (IBAction) RunAll: (id)sender
268 {
269 [emulators makeObjectsPerformSelector:@selector(Resume:)
270 withObject:self];
271 }
272
273 - (IBAction) TerminateAll: (id)sender
274 {
275 [emulators makeObjectsPerformSelector:@selector(Terminate:)
276 withObject:self];
277 }
278
279 #endif
280
281 - (BOOL) isAnyEmulatorRunning
282 {
283 #ifdef ENABLE_MULTIPLE
284 int tmp;
285
286 for ( tmp = 0; tmp < [emulators count], ++tmp )
287 if ( [[emulators objectAtIndex: tmp] isRunning] )
288 break;
289
290 if ( tmp < [emulators count] ) // i.e. if we exited the for loop
291 #else
292 if ( [theEmulator isRunning] )
293 #endif
294 return TRUE;
295
296 return FALSE;
297 }
298
299 - (short) emulatorCreatedCount
300 {
301 short count = 0;
302 #ifdef ENABLE_MULTIPLE
303 int tmp;
304
305 for ( tmp = 0; tmp < [emulators count], ++tmp )
306 if ( [[emulators objectAtIndex: tmp] uaeCreated] )
307 ++count;
308 #else
309 if ( [theEmulator uaeCreated] )
310 ++count;
311 #endif
312
313 return count;
314 }
315
316 @end