ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/MacOSX/PrefsEditor.mm
Revision: 1.3
Committed: 2002-05-26T00:12:32Z (22 years, 6 months ago) by nigel
Branch: MAIN
Changes since 1.2: +13 -15 lines
Log Message:
A better screens prefs change

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.1 2002/03/16 04:00:30 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 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 NSLog(@"Changing disylay 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 NSLog(@"Display type is not SCREEN (%d), resizing window", display_type);
375 resizeWinTo(newx, newy);
376 }
377 }
378
379 - (IBAction) CreateVolume: (id)sender
380 {
381 NSSavePanel *sP = [NSSavePanel savePanel];
382
383 [sP setAccessoryView: newVolumeView];
384 [sP setPrompt: @"Create"];
385 [sP setTitle: @"Create new volume as"];
386
387 if ( [sP runModalForDirectory:NSHomeDirectory() file:@"basilisk-II.vol"] == NSOKButton )
388 {
389 char cmd[1024];
390 const char *filename = [[sP filename] cString];
391 int retVal,
392 size = [newVolumeSize intValue];
393
394 sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", filename, size);
395 retVal = system(cmd);
396 if (retVal != 0)
397 {
398 NSString *details = [NSString stringWithFormat:
399 @"The dd command failed.\nReturn status %d (%s)",
400 retVal, strerror(errno)];
401 WarningSheet(@"Unable to create volume", details, nil, panel);
402 }
403 else
404 {
405 [volsDS addObject: (NSObject *) blank
406 withPath: [sP filename] ];
407 PrefsAddString("disk", filename);
408 [diskImages reloadData];
409 }
410 }
411 }
412
413 - (IBAction) DeleteVolume: (id)sender
414 {
415 const char *path = [self RemoveVolumeEntry];
416 if ( unlink(path) == -1 )
417 {
418 NSLog(@"%s unlink(%s) failed", __PRETTY_FUNCTION__, path, strerror(errno));
419 }
420 }
421
422 - (IBAction) EditDelay: (NSTextField *)sender
423 {
424 int ticks = [delay intValue];
425 float freq;
426
427 if ( ticks )
428 freq = 60.0 / ticks;
429 else
430 freq = 60.0;
431
432 [frequency setFloatValue: freq];
433 [emuFreq setFloatValue: freq];
434 PrefsReplaceInt32("frameskip", ticks);
435 edited = YES;
436 }
437
438 - (IBAction) EditBytes: (NSTextField *)sender
439 {
440 int B = (int) [bytes floatValue];
441 float M = B / 1024 / 1024;
442
443 D(NSLog(@"%s = %f %d", __PRETTY_FUNCTION__, M, B));
444 PrefsReplaceInt32("ramsize", B);
445 [MB setFloatValue: M];
446 edited = YES;
447 }
448
449 - (IBAction) EditEtherNetDevice: (NSTextField *)sender
450 {
451 NSString *path = [etherNet stringValue];
452
453 PrefsReplaceString("ether", [path cString]);
454 edited = YES;
455 }
456
457 - (IBAction) EditExtFS: (NSTextField *)sender
458 {
459 NSString *path = [extFS stringValue];
460
461 PrefsReplaceString("extfs", [path cString]);
462 edited = YES;
463 }
464
465 - (IBAction) EditFrequency: (NSTextField *)sender
466 {
467 float freq = [frequency floatValue];
468
469 [delay setIntValue: frequencyToTickDelay(freq)];
470 [emuFreq setFloatValue: freq];
471 edited = YES;
472 }
473
474 - (IBAction) EditModemDevice: (NSTextField *)sender
475 {
476 NSString *path = [modem stringValue];
477
478 PrefsReplaceString("seriala", [path cString]);
479 edited = YES;
480 }
481
482 - (IBAction) EditMB: (NSTextField *)sender
483 {
484 float M = [MB floatValue];
485 int B = (int) (M * 1024 * 1024);
486
487 D(NSLog(@"%s = %f %d", __PRETTY_FUNCTION__, M, B));
488 PrefsReplaceInt32("ramsize", B);
489 [bytes setIntValue: B];
490 edited = YES;
491 }
492
493 - (IBAction) EditPrinterDevice: (NSTextField *)sender
494 {
495 NSString *path = [printer stringValue];
496
497 PrefsReplaceString("serialb", [path cString]);
498 edited = YES;
499 }
500
501 - (IBAction) EditROMpath: (NSTextField *)sender
502 {
503 NSString *path = [ROMfile stringValue];
504
505 PrefsReplaceString("rom", [path cString]);
506 }
507
508 - (IBAction) RemoveSCSI: (id)sender
509 {
510 char pref[6];
511 int row = [SCSIdisks selectedRow],
512 SCSIid = [SCSIds intAtRow: row];
513
514 if ( ! [SCSIds deleteRow: row] )
515 NSLog (@"%s - [SCSIds deleteRow: %d] failed", __PRETTY_FUNCTION__, row);
516 [SCSIdisks reloadData];
517 sprintf(pref, "scsi%d", SCSIid);
518 PrefsRemoveItem(pref,0);
519 }
520
521 - (const char *) RemoveVolumeEntry
522 {
523 int row = [diskImages selectedRow];
524
525 if ( row != -1 )
526 {
527 const char *path = [[volsDS pathAtRow: row] cString],
528 *str;
529 int tmp = 0;
530
531 while ( (str = PrefsFindString("disk", tmp) ) != NULL )
532 {
533 if ( strcmp(str, path) == 0 )
534 {
535 PrefsRemoveItem("disk", tmp);
536 D(NSLog(@"%s - Deleted prefs entry \"disk\", %d", __PRETTY_FUNCTION__, tmp));
537 edited = YES;
538 break;
539 }
540 ++tmp;
541 }
542
543 if ( str == NULL )
544 {
545 NSLog(@"%s - Couldn't find any disk preference to match %s", __PRETTY_FUNCTION__, path);
546 return NULL;
547 }
548
549 if ( ! [volsDS deleteRow: row] )
550 NSLog (@"%s - RemoveVolume %d failed", __PRETTY_FUNCTION__, tmp);
551 [diskImages reloadData];
552 return path;
553 }
554 else
555 {
556 WarningSheet(@"Please select a volume first", panel);
557 return NULL;
558 }
559 }
560
561 - (IBAction) RemoveVolume: (id)sender
562 {
563 [self RemoveVolumeEntry];
564 }
565
566 - (IBAction) ResetPrefs: (id)sender
567 {
568 int argc = 0;
569 char **argv = NULL;
570
571 [panel close]; // Temporarily hide preferences panel
572
573 PrefsExit(); // Purge all the old pref values
574
575 PrefsInit(argc, argv);
576 AddPrefsDefaults();
577 AddPlatformPrefsDefaults(); // and only create basic ones
578
579 [SCSIds deleteAll]; // Clear out datasources for the tables
580 [volsDS deleteAll];
581
582 [self ShowPrefs: self]; // Reset items in panel, and redisplay
583 edited = NO;
584 }
585
586 - (void) setStringOf: (NSTextField *) field
587 fromPref: (const char *) prefName
588 {
589 const char *value = PrefsFindString(prefName, 0);
590
591 if ( value )
592 [field setStringValue: [NSString stringWithCString: value] ];
593 }
594
595 - (IBAction) SavePrefs: (id)sender
596 {
597 SavePrefs();
598 edited = NO;
599 }
600
601 - (IBAction) ShowPrefs: (id)sender
602 {
603 NSTableColumn *locks;
604 const char *str;
605 int cpu, tmp;
606
607
608 // Set simple single field items
609
610 tmp = PrefsFindInt32("frameskip");
611 [delay setIntValue: tmp];
612 if ( tmp )
613 [frequency setFloatValue: 60.0 / tmp];
614 else
615 [frequency setFloatValue: 60.0];
616
617 tmp = PrefsFindInt32("ramsize");
618 [bytes setIntValue: tmp];
619 [MB setFloatValue: tmp / (1024.0 * 1024.0)];
620
621 [disableCD setState: PrefsFindBool("nocdrom")];
622 [disableSound setState: PrefsFindBool("nosound")];
623 [FPU setState: PrefsFindBool("fpu") ];
624
625 [self setStringOf: etherNet fromPref: "ether" ];
626 [self setStringOf: extFS fromPref: "extfs" ];
627 [self setStringOf: modem fromPref: "seriala"];
628 [self setStringOf: printer fromPref: "serialb"];
629 [self setStringOf: ROMfile fromPref: "rom" ];
630
631
632 parse_screen_prefs(PrefsFindString("screen"));
633
634 [width setIntValue: init_width];
635 [height setIntValue: init_height];
636 [depth setIntValue: init_depth];
637
638 [window setState: NO];
639 switch ( display_type )
640 {
641 case DISPLAY_WINDOW: [window setState: YES]; break;
642 case DISPLAY_OPENGL: [openGL setState: YES]; break;
643 case DISPLAY_SCREEN: [screen setState: YES]; break;
644 }
645
646 [newVolumeSize setIntValue: 10];
647
648 // Radio button groups:
649
650 tmp = PrefsFindInt32("bootdriver");
651 [bootFromAny setState: tmp != CDROMRefNum];
652 [bootFromCD setState: tmp == CDROMRefNum];
653
654 cpu = PrefsFindInt32("cpu");
655 tmp = PrefsFindInt32("modelid");
656
657 #if REAL_ADDRESSING || DIRECT_ADDRESSING
658 puts("Current memory model does not support 24bit addressing");
659 if ( tmp == [classic tag] )
660 {
661 // Window already created by NIB file, just display
662 [panel makeKeyAndOrderFront:self];
663 WarningSheet(@"Compiled-in memory model does not support 24bit",
664 @"Disabling Mac Classic emulation", nil, panel);
665 cpu = [CPU68030 tag];
666 PrefsReplaceInt32("cpu", cpu);
667 tmp = [IIci tag];
668 PrefsReplaceInt32("modelid", tmp);
669 }
670
671 puts("Disabling 68000 & Mac Classic buttons");
672 [CPU68000 setEnabled:FALSE];
673 [classic setEnabled:FALSE];
674 #endif
675
676 [CPU68000 setState: [CPU68000 tag] == cpu];
677 [CPU68020 setState: [CPU68020 tag] == cpu];
678 [CPU68030 setState: [CPU68030 tag] == cpu];
679 [CPU68040 setState: [CPU68040 tag] == cpu];
680
681 [classic setState: [classic tag] == tmp];
682 [IIci setState: [IIci tag] == tmp];
683 [quadra900 setState: [quadra900 tag] == tmp];
684
685
686 // Lists of thingies:
687
688 for ( tmp = 0; tmp < 7; ++tmp)
689 {
690 char pref[6];
691
692 pref[0] = '\0';
693
694 sprintf (pref, "scsi%d", tmp);
695 if ( (str = PrefsFindString(pref, 0) ) )
696 [SCSIds addInt: tmp
697 withPath: [NSString stringWithCString: str] ];
698 }
699
700 [SCSIdisks setDataSource: SCSIds];
701
702 locks = [diskImages tableColumnWithIdentifier: @"locked"];
703 if ( locks == nil )
704 NSLog (@"%s - Can't find column for lock images", __PRETTY_FUNCTION__);
705 [locks setDataCell: lockCell];
706
707 tmp = 0;
708 while ( (str = PrefsFindString("disk", tmp++) ) != NULL )
709 {
710 if ( *str == '*' )
711 [volsDS addObject: (NSObject *) locked
712 withPath: [NSString stringWithCString: str+1]];
713 else
714 [volsDS addObject: (NSObject *) blank
715 withPath: [NSString stringWithCString: str]];
716 }
717
718 [diskImages setDataSource: volsDS];
719
720
721 [panel makeKeyAndOrderFront:self]; // Window already created by NIB file, just display
722 }
723
724 @end