ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/MacOSX/PrefsEditor.mm
Revision: 1.1
Committed: 2002-03-16T04:00:30Z (22 years, 6 months ago) by nigel
Branch: MAIN
CVS Tags: nigel-build-10
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.1 /*
2     * PrefsEditor.m - GUI stuff for Basilisk II preferences
3     * (which is a text file in the user's home directory)
4     *
5     * $Id$
6     *
7     * Basilisk II (C) 1997-2001 Christian Bauer
8     *
9     * This program is free software; you can redistribute it and/or modify
10     * it under the terms of the GNU General Public License as published by
11     * the Free Software Foundation; either version 2 of the License, or
12     * (at your option) any later version.
13     *
14     * This program is distributed in the hope that it will be useful,
15     * but WITHOUT ANY WARRANTY; without even the implied warranty of
16     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17     * GNU General Public License for more details.
18     *
19     * You should have received a copy of the GNU General Public License
20     * along with this program; if not, write to the Free Software
21     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22     */
23    
24     #import "PrefsEditor.h"
25    
26     @implementation TableDS
27    
28     - (TableDS *) init
29     {
30     self = [super init];
31    
32     numItems = 0;
33     col1 = [[NSMutableArray alloc] init];
34     col2 = [[NSMutableArray alloc] init];
35    
36     return self;
37     }
38    
39     - (void) dealloc
40     {
41     [col1 dealloc];
42     [col2 dealloc];
43     [super dealloc];
44     }
45    
46     - (void) addInt: (int)target
47     withPath: (NSString *)path
48     {
49     [col1 addObject: [NSNumber numberWithInt: target]];
50     [col2 addObject: path];
51     ++numItems;
52     }
53    
54     - (void) addObject: (NSObject *)obj
55     withPath: (NSString *)path
56     {
57     [col1 addObject: obj];
58     [col2 addObject: path];
59     ++numItems;
60     }
61    
62     - (void) deleteAll
63     {
64     numItems = 0;
65     [col1 removeAllObjects];
66     [col2 removeAllObjects];
67     }
68    
69     - (BOOL) deleteRow: (int)row
70     {
71     if ( row > numItems )
72     return NO;
73    
74     [col1 removeObjectAtIndex: row];
75     [col2 removeObjectAtIndex: row];
76     -- numItems;
77    
78     return YES;
79     }
80    
81     - (int)intAtRow: (int)row
82     {
83     return [[col1 objectAtIndex: row] intValue];
84     }
85    
86     - (int) numberOfRowsInTableView: (NSTableView *)tView
87     {
88     return numItems;
89     }
90    
91     - (NSString *)pathAtRow: (int)row
92     {
93     return (NSString *) [col2 objectAtIndex: row];
94     }
95    
96     - (id) tableView: (NSTableView *)tView
97     objectValueForTableColumn: (NSTableColumn *)tColumn
98     row: (int)row
99     {
100     if ( [[tColumn identifier] isEqualToString:@"path"] )
101     return [col2 objectAtIndex: row];
102     else
103     return [col1 objectAtIndex: row];
104     }
105    
106     @end
107    
108     @implementation PrefsEditor
109    
110     #import <AppKit/NSImage.h> // For [NSBundle pathForImageResource:] proto
111    
112     #import "sysdeps.h" // Types used in Basilisk C++ code
113     #import "video_macosx.h" // some items that we edit here
114     #import "misc_macosx.h" // WarningSheet() prototype
115    
116     #import <prefs.h>
117    
118     #define DEBUG 0
119     #import <debug.h>
120    
121     - (PrefsEditor *) init
122     {
123     self = [super init];
124    
125     edited = NO;
126    
127     devs = @"/dev";
128     home = NSHomeDirectory();
129     volsDS = [[TableDS alloc] init];
130     SCSIds = [[TableDS alloc] init];
131    
132     lockCell = [[NSImageCell alloc] init];
133     if ( lockCell == nil )
134     NSLog (@"%s - Can't create NSImageCell?", __PRETTY_FUNCTION__);
135    
136     blank = [[NSImage alloc] init];
137     locked = [NSImage alloc];
138     if ( [locked initWithContentsOfFile:
139     [[NSBundle mainBundle]
140     pathForImageResource: @"nowrite.icns"]] == nil )
141     NSLog(@"%s - Couldn't open write protection image", __PRETTY_FUNCTION__);
142    
143     return self;
144     }
145    
146     - (void) dealloc
147     {
148     [volsDS dealloc];
149     [SCSIds dealloc];
150     [lockCell dealloc];
151     [locked dealloc];
152     [blank dealloc];
153     [super dealloc];
154     }
155    
156     - (void) awakeFromNib
157     {
158     emuFreq = [theEmulator speed];
159     #if DEBUG
160     [self ShowPrefs: self]; // For testing
161     #endif
162     }
163    
164     - (BOOL) hasEdited
165     {
166     return edited;
167     }
168    
169     - (NSWindow *) window
170     {
171     return panel;
172     }
173    
174     - (IBAction) AddSCSI: (id)sender
175     {
176     NSOpenPanel *oP = [NSOpenPanel openPanel];
177    
178     if ( [oP runModalForDirectory:home file:nil types:nil] == NSOKButton )
179     {
180     [SCSIds addInt: -1
181     withPath: [oP filename] ];
182     [SCSIdisks reloadData];
183     edited = YES;
184     }
185     }
186    
187     - (IBAction) AddVolume: (id)sender
188     {
189     NSOpenPanel *oP = [NSOpenPanel openPanel];
190    
191     if ( [oP runModalForDirectory:home file:nil types:nil] == NSOKButton )
192     {
193     [volsDS addObject: (NSObject *) locked
194     withPath: [oP filename] ];
195     PrefsAddString("disk", [[oP filename] cString]);
196     [diskImages reloadData];
197     edited = YES;
198     }
199     }
200    
201     - (IBAction) BrowseExtFS: (id)sender
202     {
203     NSOpenPanel *oP = [NSOpenPanel openPanel];
204    
205     [oP setCanChooseDirectories: YES];
206     [oP setCanChooseFiles: NO];
207     [oP setPrompt: @"Select"];
208     [oP setTitle: @"Select a directory to mount"];
209     D(NSLog(@"%s - home = %@, [extFS stringValue] = %@",
210     __PRETTY_FUNCTION__, home, [extFS stringValue]));
211     if ( [oP runModalForDirectory: ([extFS stringValue] ? [extFS stringValue] : home)
212     file:nil
213     types:nil] == NSOKButton )
214     {
215     [extFS setStringValue: [oP directory] ];
216     PrefsReplaceString("extfs", [[oP directory] cString]);
217     edited = YES;
218     }
219     }
220    
221     - (IBAction) BrowseROM: (id)sender
222     {
223     NSOpenPanel *oP = [NSOpenPanel openPanel];
224    
225     [oP setCanChooseFiles: YES];
226     [oP setTitle: @"Open a ROM file"];
227     D(NSLog(@"%s - home = %@", __PRETTY_FUNCTION__, home));
228     if ( [oP runModalForDirectory: ([ROMfile stringValue] ? [ROMfile stringValue] : home)
229     file:nil
230     types:nil] == NSOKButton )
231     {
232     [ROMfile setStringValue: [oP filename] ];
233     PrefsReplaceString("rom", [[oP filename] cString]);
234     edited = YES;
235     }
236     }
237    
238     #include <cdrom.h> // for CDROMRefNum
239    
240     - (IBAction) ChangeBootFrom: (NSMatrix *)sender
241     {
242     if ( [sender selectedCell] == bootFromCD )
243     PrefsReplaceInt32("bootdriver", CDROMRefNum);
244     else
245     PrefsReplaceInt32("bootdriver", 0);
246     edited = YES;
247     }
248    
249     - (IBAction) ChangeCPU: (NSMatrix *)sender
250     {
251     PrefsReplaceInt32("cpu", [[sender selectedCell] tag]);
252     edited = YES;
253     }
254    
255     - (IBAction) ChangeDisableCD: (NSButton *)sender
256     {
257     PrefsReplaceBool("nocdrom", [disableCD state]);
258     edited = YES;
259     }
260    
261     - (IBAction) ChangeDisableSound: (NSButton *)sender
262     {
263     PrefsReplaceBool("nosound", [disableSound state]);
264     edited = YES;
265     }
266    
267     - (IBAction) ChangeFPU: (NSButton *)sender
268     {
269     PrefsReplaceBool("fpu", [FPU state]);
270     edited = YES;
271     }
272    
273     - (IBAction) ChangeModel: (NSMatrix *)sender
274     {
275     PrefsReplaceInt32("modelid", [[sender selectedCell] tag]);
276     edited = YES;
277     }
278    
279     // Screen/window changing stuff
280    
281     // This is called when any of the screen/window, width, height or depth is changed
282    
283     - (IBAction) ChangeScreen: (NSMatrix *)sender
284     {
285     short newx = [width intValue];
286     short newy = [height intValue];
287     short newbpp = [depth intValue];
288     short newtype = DISPLAY_WINDOW;
289     char str[20];
290    
291     if ( [sender selectedCell] == openGL )
292     newtype = DISPLAY_OPENGL;
293     if ( [sender selectedCell] == screen )
294     newtype = DISPLAY_SCREEN;
295    
296     // Check that a field actually changed
297     if ( newbpp == init_depth && newx == init_width &&
298     newy == init_height && newtype == display_type )
299     return;
300    
301    
302     // If we are changing type, supply some sensible defaults
303     if ( newtype != display_type )
304     {
305     if ( newtype == DISPLAY_SCREEN ) // If changing to full screen
306     {
307     // supply main screen dimensions as a default
308     NSScreen *s = [NSScreen mainScreen];
309     NSRect sr = [s frame];
310    
311     newx = (short) sr.size.width;
312     newy = (short) sr.size.height;
313     // This always returns 24, despite the mode
314     //newbpp = NSBitsPerPixelFromDepth([s depth]);
315     newbpp = CGDisplayBitsPerPixel(kCGDirectMainDisplay);
316     }
317    
318     if ( display_type == DISPLAY_SCREEN ) // If changing from full screen
319     newx = MIN_WIDTH, newy = MIN_HEIGHT;
320    
321     [width setIntValue: newx];
322     [height setIntValue: newy];
323     [depth setIntValue: newbpp];
324     }
325     else
326     {
327     // Check size is within ranges of MIN_WIDTH ... MAX_WIDTH
328     // and MIN_HEIGHT ... MAX_HEIGHT
329     // ???
330     }
331    
332    
333     // Store new prefs
334     *str = '\0';
335     switch ( newtype )
336     {
337     case DISPLAY_WINDOW:
338     if ( newbpp )
339     sprintf(str, "win/%hd/%hd/%hd", newx, newy, newbpp);
340     else
341     sprintf(str, "win/%hd/%hd", newx, newy);
342     break;
343     case DISPLAY_OPENGL:
344     if ( newbpp )
345     sprintf(str, "opengl/%hd/%hd/%hd", newx, newy, newbpp);
346     else
347     sprintf(str, "opengl/%hd/%hd", newx, newy);
348     break;
349     case DISPLAY_SCREEN:
350     if ( newbpp )
351     sprintf(str, "full/%hd/%hd/%hd", newx, newy, newbpp);
352     else
353     sprintf(str, "full/%hd/%hd", newx, newy);
354     break;
355     };
356     PrefsReplaceString("screen", str);
357    
358     parse_screen_prefs(str);
359    
360     edited = YES;
361    
362     if ( display_type != DISPLAY_SCREEN )
363     resizeWinTo(newx, newy);
364     }
365    
366     - (IBAction) CreateVolume: (id)sender
367     {
368     NSSavePanel *sP = [NSSavePanel savePanel];
369    
370     [sP setAccessoryView: newVolumeView];
371     [sP setPrompt: @"Create"];
372     [sP setTitle: @"Create new volume as"];
373    
374     if ( [sP runModalForDirectory:NSHomeDirectory() file:@"basilisk-II.vol"] == NSOKButton )
375     {
376     char cmd[1024];
377     const char *filename = [[sP filename] cString];
378     int retVal,
379     size = [newVolumeSize intValue];
380    
381     sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", filename, size);
382     retVal = system(cmd);
383     if (retVal != 0)
384     {
385     NSString *details = [NSString stringWithFormat:
386     @"The dd command failed.\nReturn status %d (%s)",
387     retVal, strerror(errno)];
388     WarningSheet(@"Unable to create volume", details, @"OK", panel);
389     }
390     else
391     {
392     [volsDS addObject: (NSObject *) blank
393     withPath: [sP filename] ];
394     PrefsAddString("disk", filename);
395     [diskImages reloadData];
396     }
397     }
398     }
399    
400     - (IBAction) DeleteVolume: (id)sender
401     {
402     const char *path = [self RemoveVolumeEntry];
403     if ( unlink(path) == -1 )
404     {
405     NSLog(@"%s unlink(%s) failed", __PRETTY_FUNCTION__, path, strerror(errno));
406     }
407     }
408    
409     - (IBAction) EditDelay: (NSTextField *)sender
410     {
411     int ticks = [delay intValue];
412     float freq;
413    
414     if ( ticks )
415     freq = 60.0 / ticks;
416     else
417     freq = 60.0;
418    
419     [frequency setFloatValue: freq];
420     [emuFreq setFloatValue: freq];
421     PrefsReplaceInt32("frameskip", ticks);
422     edited = YES;
423     }
424    
425     - (IBAction) EditBytes: (NSTextField *)sender
426     {
427     int B = (int) [bytes floatValue];
428     float M = B / 1024 / 1024;
429    
430     NSLog(@"%s = %f %d", __PRETTY_FUNCTION__, M, B);
431     PrefsReplaceInt32("ramsize", B);
432     [MB setFloatValue: M];
433     edited = YES;
434     }
435    
436     - (IBAction) EditEtherNetDevice: (NSTextField *)sender
437     {
438     NSString *path = [etherNet stringValue];
439    
440     PrefsReplaceString("ether", [path cString]);
441     edited = YES;
442     }
443    
444     - (IBAction) EditExtFS: (NSTextField *)sender
445     {
446     NSString *path = [extFS stringValue];
447    
448     PrefsReplaceString("extfs", [path cString]);
449     edited = YES;
450     }
451    
452     - (IBAction) EditFrequency: (NSTextField *)sender
453     {
454     float freq = [frequency floatValue];
455    
456     [delay setIntValue: frequencyToTickDelay(freq)];
457     [emuFreq setFloatValue: freq];
458     edited = YES;
459     }
460    
461     - (IBAction) EditModemDevice: (NSTextField *)sender
462     {
463     NSString *path = [modem stringValue];
464    
465     PrefsReplaceString("seriala", [path cString]);
466     edited = YES;
467     }
468    
469     - (IBAction) EditMB: (NSTextField *)sender
470     {
471     float M = [MB floatValue];
472     int B = (int) (M * 1024 * 1024);
473    
474     NSLog(@"%s = %f %d", __PRETTY_FUNCTION__, M, B);
475     PrefsReplaceInt32("ramsize", B);
476     [bytes setIntValue: B];
477     edited = YES;
478     }
479    
480     - (IBAction) EditPrinterDevice: (NSTextField *)sender
481     {
482     NSString *path = [printer stringValue];
483    
484     PrefsReplaceString("serialb", [path cString]);
485     edited = YES;
486     }
487    
488     - (IBAction) EditRAMsize: (NSTextField *)sender
489     {
490     int B = [bytes intValue];
491     float M = B / (1024.0 * 1024.0);
492    
493     NSLog(@"%s = %d %f", __PRETTY_FUNCTION__, B, M);
494     PrefsReplaceInt32("ramsize", B);
495     [MB setFloatValue: M];
496     edited = YES;
497     }
498    
499     - (IBAction) EditROMpath: (NSTextField *)sender
500     {
501     NSString *path = [ROMfile stringValue];
502    
503     PrefsReplaceString("rom", [path cString]);
504     }
505    
506     - (IBAction) RemoveSCSI: (id)sender
507     {
508     char pref[6];
509     int row = [SCSIdisks selectedRow],
510     SCSIid = [SCSIds intAtRow: row];
511    
512     if ( ! [SCSIds deleteRow: row] )
513     NSLog (@"%s - [SCSIds deleteRow: %d] failed", __PRETTY_FUNCTION__, row);
514     [SCSIdisks reloadData];
515     sprintf(pref, "scsi%d", SCSIid);
516     PrefsRemoveItem(pref,0);
517     }
518    
519     - (const char *) RemoveVolumeEntry
520     {
521     int row = [diskImages selectedRow];
522    
523     if ( row != -1 )
524     {
525     const char *path = [[volsDS pathAtRow: row] cString],
526     *str;
527     int tmp = 0;
528    
529     while ( (str = PrefsFindString("disk", tmp) ) != NULL )
530     {
531     if ( strcmp(str, path) == 0 )
532     {
533     PrefsRemoveItem("disk", tmp);
534     D(NSLog(@"%s - Deleted prefs entry \"disk\", %d", __PRETTY_FUNCTION__, tmp));
535     edited = YES;
536     break;
537     }
538     ++tmp;
539     }
540    
541     if ( str == NULL )
542     {
543     NSLog(@"%s - Couldn't find any disk preference to match %s", __PRETTY_FUNCTION__, path);
544     return NULL;
545     }
546    
547     if ( ! [volsDS deleteRow: row] )
548     NSLog (@"%s - RemoveVolume %d failed", __PRETTY_FUNCTION__, tmp);
549     [diskImages reloadData];
550     return path;
551     }
552     else
553     {
554     WarningSheet(@"Please select a volume first", @"", @"OK", panel);
555     return NULL;
556     }
557     }
558    
559     - (IBAction) RemoveVolume: (id)sender
560     {
561     [self RemoveVolumeEntry];
562     }
563    
564     - (IBAction) ResetPrefs: (id)sender
565     {
566     int argc = 0;
567     char **argv = NULL;
568    
569     [panel close]; // Temporarily hide preferences panel
570    
571     PrefsExit(); // Purge all the old pref values
572    
573     PrefsInit(argc, argv);
574     AddPrefsDefaults();
575     AddPlatformPrefsDefaults(); // and only create basic ones
576    
577     [SCSIds deleteAll]; // Clear out datasources for the tables
578     [volsDS deleteAll];
579    
580     [self ShowPrefs: self]; // Reset items in panel, and redisplay
581     edited = NO;
582     }
583    
584     - (void) setStringOf: (NSTextField *) field
585     fromPref: (const char *) prefName
586     {
587     const char *value = PrefsFindString(prefName, 0);
588    
589     if ( value )
590     [field setStringValue: [NSString stringWithCString: value] ];
591     }
592    
593     - (IBAction) SavePrefs: (id)sender
594     {
595     SavePrefs();
596     edited = NO;
597     }
598    
599     - (IBAction) ShowPrefs: (id)sender
600     {
601     NSTableColumn *locks;
602     const char *str;
603     int cpu, tmp;
604    
605    
606     // Set simple single field items
607    
608     tmp = PrefsFindInt32("frameskip");
609     [delay setIntValue: tmp];
610     if ( tmp )
611     [frequency setFloatValue: 60.0 / tmp];
612     else
613     [frequency setFloatValue: 60.0];
614    
615     tmp = PrefsFindInt32("ramsize");
616     [bytes setIntValue: tmp];
617     [MB setFloatValue: tmp / (1024.0 * 1024.0)];
618    
619     [disableCD setState: PrefsFindBool("nocdrom")];
620     [disableSound setState: PrefsFindBool("nosound")];
621     [FPU setState: PrefsFindBool("fpu") ];
622    
623     [self setStringOf: etherNet fromPref: "ether" ];
624     [self setStringOf: extFS fromPref: "extfs" ];
625     [self setStringOf: modem fromPref: "seriala"];
626     [self setStringOf: printer fromPref: "serialb"];
627     [self setStringOf: ROMfile fromPref: "rom" ];
628    
629    
630     parse_screen_prefs(PrefsFindString("screen"));
631    
632     [width setIntValue: init_width];
633     [height setIntValue: init_height];
634     [depth setIntValue: init_depth];
635    
636     [window setState: NO];
637     switch ( display_type )
638     {
639     case DISPLAY_WINDOW: [window setState: YES]; break;
640     case DISPLAY_OPENGL: [openGL setState: YES]; break;
641     case DISPLAY_SCREEN: [screen setState: YES]; break;
642     }
643    
644     [newVolumeSize setIntValue: 10];
645    
646     // Radio button groups:
647    
648     tmp = PrefsFindInt32("bootdriver");
649     [bootFromAny setState: tmp != CDROMRefNum];
650     [bootFromCD setState: tmp == CDROMRefNum];
651    
652     cpu = PrefsFindInt32("cpu");
653     tmp = PrefsFindInt32("modelid");
654    
655     #if REAL_ADDRESSING || DIRECT_ADDRESSING
656     puts("Current memory model does not support 24bit addressing");
657     if ( tmp == [classic tag] )
658     {
659     // Window already created by NIB file, just display
660     [panel makeKeyAndOrderFront:self];
661     WarningSheet(@"Compiled-in memory model does not support 24bit",
662     @"Disabling Mac Classic emulation", @"OK", panel);
663     cpu = [CPU68030 tag];
664     PrefsReplaceInt32("cpu", cpu);
665     tmp = [IIci tag];
666     PrefsReplaceInt32("modelid", tmp);
667     }
668    
669     puts("Disabling 68000 & Mac Classic buttons");
670     [CPU68000 setEnabled:FALSE];
671     [classic setEnabled:FALSE];
672     #endif
673    
674     [CPU68000 setState: [CPU68000 tag] == cpu];
675     [CPU68020 setState: [CPU68020 tag] == cpu];
676     [CPU68030 setState: [CPU68030 tag] == cpu];
677     [CPU68040 setState: [CPU68040 tag] == cpu];
678    
679     [classic setState: [classic tag] == tmp];
680     [IIci setState: [IIci tag] == tmp];
681     [quadra900 setState: [quadra900 tag] == tmp];
682    
683    
684     // Lists of thingies:
685    
686     for ( tmp = 0; tmp < 7; ++tmp)
687     {
688     char pref[6];
689    
690     pref[0] = '\0';
691    
692     sprintf (pref, "scsi%d", tmp);
693     if ( (str = PrefsFindString(pref, 0) ) )
694     [SCSIds addInt: tmp
695     withPath: [NSString stringWithCString: str] ];
696     }
697    
698     [SCSIdisks setDataSource: SCSIds];
699    
700     locks = [diskImages tableColumnWithIdentifier: @"locked"];
701     if ( locks == nil )
702     NSLog (@"%s - Can't find column for lock images", __PRETTY_FUNCTION__);
703     [locks setDataCell: lockCell];
704    
705     tmp = 0;
706     while ( (str = PrefsFindString("disk", tmp++) ) != NULL )
707     {
708     if ( *str == '*' )
709     [volsDS addObject: (NSObject *) locked
710     withPath: [NSString stringWithCString: str+1]];
711     else
712     [volsDS addObject: (NSObject *) blank
713     withPath: [NSString stringWithCString: str]];
714     }
715    
716     [diskImages setDataSource: volsDS];
717    
718    
719     [panel makeKeyAndOrderFront:self]; // Window already created by NIB file, just display
720     }
721    
722     @end