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

# Content
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