ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/MacOSX/Controller.mm
Revision: 1.4
Committed: 2002-05-30T12:50:21Z (22 years ago) by nigel
Branch: MAIN
Changes since 1.3: +51 -20 lines
Log Message:
Sheet and fullscreen-safe input processing, small tidyup

File Contents

# User Rev Content
1 nigel 1.2 /*
2     * Controller.m - Simple application window management.
3     *
4 nigel 1.4 * $Id: Controller.mm,v 1.3 2002/03/18 10:48:25 nigel Exp $
5 nigel 1.2 *
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 nigel 1.4 if ( [self isAnyEmulatorDisplayingSheets] || ! [self isAnyEmulatorRunning] )
70     [super sendEvent: event];
71     else
72     {
73     NSEventType type = [event type];
74 nigel 1.2
75 nigel 1.4 if ( type == NSKeyUp || type == NSKeyDown || type == NSFlagsChanged )
76     [self dispatchKeyEvent: event
77     type: type];
78     else
79     [self dispatchEvent: event
80     type: type];
81     }
82 nigel 1.2 }
83    
84     // NSApplication methods which are invoked through delegation
85    
86     - (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication *)app
87     { return YES; }
88    
89     - (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *)app
90     {
91     short count;
92     char *stillRunningMessage;
93    
94     if ( [thePrefsEditor hasEdited] )
95     if ( ChoiceAlert("Preferences have been edited",
96     "Save changes", "Quit") )
97     SavePrefs();
98    
99     // if ( edited )
100     // {
101     // NSString *title = [NSString stringWithCString: getString(STR_WARNING_ALERT_TITLE)],
102     // *msg = @"Preferences have been edited",
103     // *def = @"Save changes",
104     // *alt = @"Quit Application",
105     // *other = @"Continue";
106     //
107     // switch ( NSRunAlertPanel(title, msg, def, alt, other, nil) )
108     // {
109     // case NSAlertDefault: savePrefs();
110     // case NSAlertAlternate: return NSTerminateNow;
111     // case NSAlertOther: return NSTerminateCancel;
112     // }
113     // }
114    
115    
116     if ( [[thePrefsEditor window] isVisible] )
117     [[thePrefsEditor window] performClose: self];
118    
119    
120     count = [self emulatorCreatedCount];
121    
122     if ( count > 0 )
123     {
124     if ( count > 1 )
125     stillRunningMessage = "Emulators are still running\nExiting Basilisk may lose data";
126     else
127     stillRunningMessage = "Emulator is still running\nExiting Basilisk may lose data";
128     if ( ! ChoiceAlert(stillRunningMessage, "Exit", "Continue") )
129     return NSTerminateCancel; // NSTerminateLater?
130     }
131    
132     return NSTerminateNow;
133     }
134    
135    
136     // Event dispatching, called by sendEvent
137    
138     - (void) dispatchKeyEvent: (NSEvent *)event
139     type: (NSEventType)type
140     {
141     EmulatorView *view;
142    
143     #ifdef ENABLE_MULTIPLE
144     // We need to work out what window's Emulator should receive these messages
145    
146    
147     int tmp;
148    
149     for ( tmp = 0; tmp < [emulators count], ++tmp )
150     {
151     theEmulator = [emulators objectAtIndex: tmp];
152 nigel 1.4 view = [theEmulator screen];
153    
154     if ( [ theEmulator isRunning ] &&
155     ( [[theEmulator window] isKeyWindow] || [view isFullScreen] ) )
156 nigel 1.2 break;
157     }
158    
159     if ( tmp < [emulators count] ) // i.e. if we exited the for loop
160     #else
161 nigel 1.4 view = [theEmulator screen];
162    
163     if ( [theEmulator isRunning] &&
164     ( [[theEmulator window] isKeyWindow] || [view isFullScreen] ) )
165 nigel 1.2 #endif
166     {
167 nigel 1.4 D(NSLog(@"Got a key event - %d\n", [event keyCode]));
168 nigel 1.2 switch ( type )
169     {
170     case NSKeyUp:
171     [view keyUp: event];
172     break;
173     case NSKeyDown:
174     D(NSLog(@"%s - NSKeyDown - %@", __PRETTY_FUNCTION__, event));
175     [view keyDown: event];
176     break;
177     case NSFlagsChanged:
178     [view flagsChanged: event];
179     break;
180     default:
181     NSLog(@"%s - Sent a non-key event (logic error)",
182     __PRETTY_FUNCTION__);
183     [super sendEvent: event];
184     }
185     }
186     else // No Basilisk window is key (maybe a panel or pane).
187     [super sendEvent: event]; // Call NSApplication default
188    
189     }
190    
191     - (void) dispatchEvent: (NSEvent *)event
192     type: (NSEventType)type
193     {
194 nigel 1.4 EmulatorView *view;
195    
196 nigel 1.2 #ifdef ENABLE_MULTIPLE
197     // We need to work out what window's Emulator should receive these messages
198    
199    
200     int tmp;
201    
202     for ( tmp = 0; tmp < [emulators count], ++tmp )
203     {
204     theEmulator = [emulators objectAtIndex: tmp];
205 nigel 1.4 view = [theEmulator screen];
206    
207     if ( [theEmulator isRunning] &&
208     ( [[theEmulator window] isMainWindow] || [view isFullScreen] ) )
209 nigel 1.2 break;
210     }
211    
212     if ( tmp < [emulators count] ) // i.e. if we exited the for loop
213     #else
214 nigel 1.4 view = [theEmulator screen];
215    
216     if ( [theEmulator isRunning] &&
217     ( [[theEmulator window] isMainWindow] || [view isFullScreen] ) )
218 nigel 1.2 #endif
219     {
220 nigel 1.4 if ( [view mouseInView: event] )
221 nigel 1.2 {
222     switch ( type )
223     {
224     case NSLeftMouseDown:
225     [view mouseDown: event];
226     break;
227     case NSLeftMouseUp:
228     [view mouseUp: event];
229     break;
230     case NSLeftMouseDragged:
231     case NSMouseMoved:
232     [view processMouseMove: event];
233     break;
234     default:
235     [super sendEvent: event]; // NSApplication default
236     }
237     return;
238     }
239     }
240    
241     // Either the pointer is not in the Emulator's screen, no Basilisk window is running,
242     // or no Basilisk window is main (e.g. there might be a panel or pane up).
243     //
244     // We should just be calling NSApp's default sendEvent, but then for some reason
245     // mouseMoved events are still passed to our EmulatorView, so we filter them out.
246    
247     if ( type != NSMouseMoved )
248     [super sendEvent: event];
249     }
250    
251     #ifdef ENABLE_MULTIPLE
252    
253     - (IBAction) NewEmulator: (id)sender
254     {
255     NSString *title;
256    
257     if ( ! [NSBundle loadNibNamed:@"Win512x342" owner:self] )
258     {
259     NSLog(@"%s - LoadNibNamed@Win512x342 failed", __PRETTY_FUNCTION__);
260     return;
261     }
262    
263     if ( theEmulator == nil)
264     {
265     NSLog(@"%s - Newly created emulator's NIB stuff not fully linked?", __PRETTY_FUNCTION__);
266     return;
267     }
268    
269     [emulators addObject: theEmulator];
270     title = [NSString localizedStringWithFormat:@"BasiliskII Emulator %d", [emulators count]];
271     [theEmulator -> win setTitle: title];
272     }
273    
274     - (IBAction) PauseAll: (id)sender
275     {
276     [emulators makeObjectsPerformSelector:@selector(Suspend:)
277     withObject:self];
278     }
279    
280     - (IBAction) RunAll: (id)sender
281     {
282     [emulators makeObjectsPerformSelector:@selector(Resume:)
283     withObject:self];
284     }
285    
286     - (IBAction) TerminateAll: (id)sender
287     {
288     [emulators makeObjectsPerformSelector:@selector(Terminate:)
289     withObject:self];
290     }
291    
292     #endif
293 nigel 1.4
294     - (BOOL) isAnyEmulatorDisplayingSheets
295     {
296     #ifdef ENABLE_MULTIPLE
297     int tmp;
298    
299     for ( tmp = 0; tmp < [emulators count], ++tmp )
300     if ( [[[emulators objectAtIndex: tmp] window] attachedSheet] )
301     break;
302    
303     if ( tmp < [emulators count] ) // i.e. if we exited the for loop
304     #else
305     if ( [[theEmulator window] attachedSheet] )
306     #endif
307     return TRUE;
308    
309     return FALSE;
310     }
311 nigel 1.2
312     - (BOOL) isAnyEmulatorRunning
313     {
314     #ifdef ENABLE_MULTIPLE
315     int tmp;
316    
317     for ( tmp = 0; tmp < [emulators count], ++tmp )
318     if ( [[emulators objectAtIndex: tmp] isRunning] )
319     break;
320    
321     if ( tmp < [emulators count] ) // i.e. if we exited the for loop
322     #else
323     if ( [theEmulator isRunning] )
324     #endif
325     return TRUE;
326    
327     return FALSE;
328     }
329    
330     - (short) emulatorCreatedCount
331     {
332     short count = 0;
333     #ifdef ENABLE_MULTIPLE
334     int tmp;
335    
336     for ( tmp = 0; tmp < [emulators count], ++tmp )
337     if ( [[emulators objectAtIndex: tmp] uaeCreated] )
338     ++count;
339     #else
340     if ( [theEmulator uaeCreated] )
341     ++count;
342     #endif
343    
344     return count;
345     }
346    
347     @end