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

# User Rev Content
1 nigel 1.2 /*
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