ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/MacOSX/PrefsEditor.mm
Revision: 1.4
Committed: 2002-06-05T09:41:27Z (22 years ago) by nigel
Branch: MAIN
Changes since 1.3: +9 -6 lines
Log Message:
Debug statements were not in D() macros

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: PrefsEditor.mm,v 1.3 2002/05/26 00:12:32 nigel Exp $
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 BOOL noSound = [disableSound state];
264
265 if ( ! noSound )
266 WarningSheet(@"Sound is currently unimplemented", panel);
267
268 PrefsReplaceBool("nosound", noSound);
269 edited = YES;
270 }
271
272 - (IBAction) ChangeFPU: (NSButton *)sender
273 {
274 PrefsReplaceBool("fpu", [FPU state]);
275 edited = YES;
276 }
277
278 - (IBAction) ChangeModel: (NSMatrix *)sender
279 {
280 PrefsReplaceInt32("modelid", [[sender selectedCell] tag]);
281 edited = YES;
282 }
283
284 // This is called when any of the screen/openGL/window,
285 // width, height or depth is clicked.
286 //
287 // Note that sender may not actually be an NSMatrix.
288
289 - (IBAction) ChangeScreen: (NSMatrix *)sender
290 {
291 NSButton *cell = [sender selectedCell];
292
293 short newx = [width intValue];
294 short newy = [height intValue];
295 short newbpp = [depth intValue];
296 short newtype;
297 char str[20];
298
299 if ( cell == openGL )
300 newtype = DISPLAY_OPENGL;
301 else if ( cell == screen )
302 newtype = DISPLAY_SCREEN;
303 else if ( cell == window )
304 newtype = DISPLAY_WINDOW;
305 else
306 newtype = display_type;
307
308 // Check that a field actually changed
309 if ( newbpp == init_depth && newx == init_width &&
310 newy == init_height && newtype == display_type )
311 {
312 D(NSLog(@"No changed GUI items in ChangeScreen"));
313 return;
314 }
315
316 // If we are changing type, supply some sensible defaults
317 if ( newtype != display_type )
318 {
319 D(NSLog(@"Changing display type in ChangeScreen"));
320 if ( newtype == DISPLAY_SCREEN ) // If changing to full screen
321 {
322 // supply main screen dimensions as a default
323 newx = CGDisplayPixelsWide (kCGDirectMainDisplay);
324 newy = CGDisplayPixelsHigh (kCGDirectMainDisplay);
325 newbpp = CGDisplayBitsPerPixel(kCGDirectMainDisplay);
326 }
327
328 if ( display_type == DISPLAY_SCREEN ) // If changing from full screen
329 newx = MIN_WIDTH, newy = MIN_HEIGHT;
330
331 [width setIntValue: newx];
332 [height setIntValue: newy];
333 [depth setIntValue: newbpp];
334 }
335 else
336 {
337 // Check size is within ranges of MIN_WIDTH ... MAX_WIDTH
338 // and MIN_HEIGHT ... MAX_HEIGHT
339 // ???
340 }
341
342
343 // Store new prefs
344 *str = '\0';
345 switch ( newtype )
346 {
347 case DISPLAY_WINDOW:
348 if ( newbpp )
349 sprintf(str, "win/%hd/%hd/%hd", newx, newy, newbpp);
350 else
351 sprintf(str, "win/%hd/%hd", newx, newy);
352 break;
353 case DISPLAY_OPENGL:
354 if ( newbpp )
355 sprintf(str, "opengl/%hd/%hd/%hd", newx, newy, newbpp);
356 else
357 sprintf(str, "opengl/%hd/%hd", newx, newy);
358 break;
359 case DISPLAY_SCREEN:
360 if ( newbpp )
361 sprintf(str, "full/%hd/%hd/%hd", newx, newy, newbpp);
362 else
363 sprintf(str, "full/%hd/%hd", newx, newy);
364 break;
365 };
366 PrefsReplaceString("screen", str);
367
368 parse_screen_prefs(str);
369
370 edited = YES;
371
372 if ( display_type != DISPLAY_SCREEN )
373 {
374 D(NSLog(@"Display type is not SCREEN (%d), resizing window",
375 display_type));
376 resizeWinTo(newx, newy);
377 }
378 }
379
380 - (IBAction) CreateVolume: (id)sender
381 {
382 NSSavePanel *sP = [NSSavePanel savePanel];
383
384 [sP setAccessoryView: newVolumeView];
385 [sP setPrompt: @"Create"];
386 [sP setTitle: @"Create new volume as"];
387
388 if ( [sP runModalForDirectory:NSHomeDirectory() file:@"basilisk-II.vol"] == NSOKButton )
389 {
390 char cmd[1024];
391 const char *filename = [[sP filename] cString];
392 int retVal,
393 size = [newVolumeSize intValue];
394
395 sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", filename, size);
396 retVal = system(cmd);
397 if (retVal != 0)
398 {
399 NSString *details = [NSString stringWithFormat:
400 @"The dd command failed.\nReturn status %d (%s)",
401 retVal, strerror(errno)];
402 WarningSheet(@"Unable to create volume", details, nil, panel);
403 }
404 else
405 {
406 [volsDS addObject: (NSObject *) blank
407 withPath: [sP filename] ];
408 PrefsAddString("disk", filename);
409 [diskImages reloadData];
410 }
411 }
412 }
413
414 - (IBAction) DeleteVolume: (id)sender
415 {
416 const char *path = [self RemoveVolumeEntry];
417 if ( unlink(path) == -1 )
418 {
419 NSLog(@"%s unlink(%s) failed", __PRETTY_FUNCTION__, path, strerror(errno));
420 }
421 }
422
423 - (IBAction) EditDelay: (NSTextField *)sender
424 {
425 int ticks = [delay intValue];
426 float freq;
427
428 if ( ticks )
429 freq = 60.0 / ticks;
430 else
431 freq = 60.0;
432
433 [frequency setFloatValue: freq];
434 [emuFreq setFloatValue: freq];
435 PrefsReplaceInt32("frameskip", ticks);
436 edited = YES;
437 }
438
439 - (IBAction) EditBytes: (NSTextField *)sender
440 {
441 int B = (int) [bytes floatValue];
442 float M = B / 1024 / 1024;
443
444 D(NSLog(@"%s = %f %d", __PRETTY_FUNCTION__, M, B));
445 PrefsReplaceInt32("ramsize", B);
446 [MB setFloatValue: M];
447 edited = YES;
448 }
449
450 - (IBAction) EditEtherNetDevice: (NSTextField *)sender
451 {
452 NSString *path = [etherNet stringValue];
453
454 PrefsReplaceString("ether", [path cString]);
455 edited = YES;
456 }
457
458 - (IBAction) EditExtFS: (NSTextField *)sender
459 {
460 NSString *path = [extFS stringValue];
461
462 PrefsReplaceString("extfs", [path cString]);
463 edited = YES;
464 }
465
466 - (IBAction) EditFrequency: (NSTextField *)sender
467 {
468 float freq = [frequency floatValue];
469
470 [delay setIntValue: frequencyToTickDelay(freq)];
471 [emuFreq setFloatValue: freq];
472 edited = YES;
473 }
474
475 - (IBAction) EditModemDevice: (NSTextField *)sender
476 {
477 NSString *path = [modem stringValue];
478
479 PrefsReplaceString("seriala", [path cString]);
480 edited = YES;
481 }
482
483 - (IBAction) EditMB: (NSTextField *)sender
484 {
485 float M = [MB floatValue];
486 int B = (int) (M * 1024 * 1024);
487
488 D(NSLog(@"%s = %f %d", __PRETTY_FUNCTION__, M, B));
489 PrefsReplaceInt32("ramsize", B);
490 [bytes setIntValue: B];
491 edited = YES;
492 }
493
494 - (IBAction) EditPrinterDevice: (NSTextField *)sender
495 {
496 NSString *path = [printer stringValue];
497
498 PrefsReplaceString("serialb", [path cString]);
499 edited = YES;
500 }
501
502 - (IBAction) EditROMpath: (NSTextField *)sender
503 {
504 NSString *path = [ROMfile stringValue];
505
506 PrefsReplaceString("rom", [path cString]);
507 }
508
509 - (IBAction) RemoveSCSI: (id)sender
510 {
511 char pref[6];
512 int row = [SCSIdisks selectedRow],
513 SCSIid = [SCSIds intAtRow: row];
514
515 if ( ! [SCSIds deleteRow: row] )
516 NSLog (@"%s - [SCSIds deleteRow: %d] failed", __PRETTY_FUNCTION__, row);
517 [SCSIdisks reloadData];
518 sprintf(pref, "scsi%d", SCSIid);
519 PrefsRemoveItem(pref,0);
520 }
521
522 - (const char *) RemoveVolumeEntry
523 {
524 int row = [diskImages selectedRow];
525
526 if ( row != -1 )
527 {
528 const char *path = [[volsDS pathAtRow: row] cString],
529 *str;
530 int tmp = 0;
531
532 while ( (str = PrefsFindString("disk", tmp) ) != NULL )
533 {
534 if ( strcmp(str, path) == 0 )
535 {
536 PrefsRemoveItem("disk", tmp);
537 D(NSLog(@"%s - Deleted prefs entry \"disk\", %d",
538 __PRETTY_FUNCTION__, tmp));
539 edited = YES;
540 break;
541 }
542 ++tmp;
543 }
544
545 if ( str == NULL )
546 {
547 NSLog(@"%s - Couldn't find any disk preference to match %s",
548 __PRETTY_FUNCTION__, path);
549 return NULL;
550 }
551
552 if ( ! [volsDS deleteRow: row] )
553 NSLog (@"%s - RemoveVolume %d failed", __PRETTY_FUNCTION__, tmp);
554 [diskImages reloadData];
555 return path;
556 }
557 else
558 {
559 WarningSheet(@"Please select a volume first", panel);
560 return NULL;
561 }
562 }
563
564 - (IBAction) RemoveVolume: (id)sender
565 {
566 [self RemoveVolumeEntry];
567 }
568
569 - (IBAction) ResetPrefs: (id)sender
570 {
571 int argc = 0;
572 char **argv = NULL;
573
574 [panel close]; // Temporarily hide preferences panel
575
576 PrefsExit(); // Purge all the old pref values
577
578 PrefsInit(argc, argv);
579 AddPrefsDefaults();
580 AddPlatformPrefsDefaults(); // and only create basic ones
581
582 [SCSIds deleteAll]; // Clear out datasources for the tables
583 [volsDS deleteAll];
584
585 [self ShowPrefs: self]; // Reset items in panel, and redisplay
586 edited = NO;
587 }
588
589 - (void) setStringOf: (NSTextField *) field
590 fromPref: (const char *) prefName
591 {
592 const char *value = PrefsFindString(prefName, 0);
593
594 if ( value )
595 [field setStringValue: [NSString stringWithCString: value] ];
596 }
597
598 - (IBAction) SavePrefs: (id)sender
599 {
600 SavePrefs();
601 edited = NO;
602 }
603
604 - (IBAction) ShowPrefs: (id)sender
605 {
606 NSTableColumn *locks;
607 const char *str;
608 int cpu, tmp;
609
610
611 // Set simple single field items
612
613 tmp = PrefsFindInt32("frameskip");
614 [delay setIntValue: tmp];
615 if ( tmp )
616 [frequency setFloatValue: 60.0 / tmp];
617 else
618 [frequency setFloatValue: 60.0];
619
620 tmp = PrefsFindInt32("ramsize");
621 [bytes setIntValue: tmp];
622 [MB setFloatValue: tmp / (1024.0 * 1024.0)];
623
624 [disableCD setState: PrefsFindBool("nocdrom")];
625 [disableSound setState: PrefsFindBool("nosound")];
626 [FPU setState: PrefsFindBool("fpu") ];
627
628 [self setStringOf: etherNet fromPref: "ether" ];
629 [self setStringOf: extFS fromPref: "extfs" ];
630 [self setStringOf: modem fromPref: "seriala"];
631 [self setStringOf: printer fromPref: "serialb"];
632 [self setStringOf: ROMfile fromPref: "rom" ];
633
634
635 parse_screen_prefs(PrefsFindString("screen"));
636
637 [width setIntValue: init_width];
638 [height setIntValue: init_height];
639 [depth setIntValue: init_depth];
640
641 [window setState: NO];
642 switch ( display_type )
643 {
644 case DISPLAY_WINDOW: [window setState: YES]; break;
645 case DISPLAY_OPENGL: [openGL setState: YES]; break;
646 case DISPLAY_SCREEN: [screen setState: YES]; break;
647 }
648
649 [newVolumeSize setIntValue: 10];
650
651 // Radio button groups:
652
653 tmp = PrefsFindInt32("bootdriver");
654 [bootFromAny setState: tmp != CDROMRefNum];
655 [bootFromCD setState: tmp == CDROMRefNum];
656
657 cpu = PrefsFindInt32("cpu");
658 tmp = PrefsFindInt32("modelid");
659
660 #if REAL_ADDRESSING || DIRECT_ADDRESSING
661 puts("Current memory model does not support 24bit addressing");
662 if ( tmp == [classic tag] )
663 {
664 // Window already created by NIB file, just display
665 [panel makeKeyAndOrderFront:self];
666 WarningSheet(@"Compiled-in memory model does not support 24bit",
667 @"Disabling Mac Classic emulation", nil, panel);
668 cpu = [CPU68030 tag];
669 PrefsReplaceInt32("cpu", cpu);
670 tmp = [IIci tag];
671 PrefsReplaceInt32("modelid", tmp);
672 }
673
674 puts("Disabling 68000 & Mac Classic buttons");
675 [CPU68000 setEnabled:FALSE];
676 [classic setEnabled:FALSE];
677 #endif
678
679 [CPU68000 setState: [CPU68000 tag] == cpu];
680 [CPU68020 setState: [CPU68020 tag] == cpu];
681 [CPU68030 setState: [CPU68030 tag] == cpu];
682 [CPU68040 setState: [CPU68040 tag] == cpu];
683
684 [classic setState: [classic tag] == tmp];
685 [IIci setState: [IIci tag] == tmp];
686 [quadra900 setState: [quadra900 tag] == tmp];
687
688
689 // Lists of thingies:
690
691 for ( tmp = 0; tmp < 7; ++tmp)
692 {
693 char pref[6];
694
695 pref[0] = '\0';
696
697 sprintf (pref, "scsi%d", tmp);
698 if ( (str = PrefsFindString(pref, 0) ) )
699 [SCSIds addInt: tmp
700 withPath: [NSString stringWithCString: str] ];
701 }
702
703 [SCSIdisks setDataSource: SCSIds];
704
705 locks = [diskImages tableColumnWithIdentifier: @"locked"];
706 if ( locks == nil )
707 NSLog (@"%s - Can't find column for lock images", __PRETTY_FUNCTION__);
708 [locks setDataCell: lockCell];
709
710 tmp = 0;
711 while ( (str = PrefsFindString("disk", tmp++) ) != NULL )
712 {
713 if ( *str == '*' )
714 [volsDS addObject: (NSObject *) locked
715 withPath: [NSString stringWithCString: str+1]];
716 else
717 [volsDS addObject: (NSObject *) blank
718 withPath: [NSString stringWithCString: str]];
719 }
720
721 [diskImages setDataSource: volsDS];
722
723
724 [panel makeKeyAndOrderFront:self]; // Window already created by NIB file, just display
725 }
726
727 @end