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

# User Rev Content
1 nigel 1.2 /*
2     * Controller.m - Simple application window management.
3     *
4 nigel 1.3 * $Id: Controller.mm,v 1.2 2002/03/16 10:00:18 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     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 nigel 1.3 if ( FULLSCREEN ||
154     [theEmulator isRunning] && [[theEmulator window] isKeyWindow ] )
155 nigel 1.2 #endif
156     {
157     view = [theEmulator screen];
158 nigel 1.3 NSLog(@"Got a key event - %d\n", [event keyCode]);
159 nigel 1.2 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