ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/BeOS/prefs_editor_beos.cpp
Revision: 1.9
Committed: 2001-02-02T20:52:57Z (23 years, 5 months ago) by cebix
Branch: MAIN
CVS Tags: snapshot-17022001
Changes since 1.8: +1 -1 lines
Log Message:
- bumped version number to 0.9
- updated copyright dates

File Contents

# Content
1 /*
2 * prefs_editor_beos.cpp - Preferences editor, BeOS implementation
3 *
4 * Basilisk II (C) 1997-2001 Christian Bauer
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include <AppKit.h>
22 #include <InterfaceKit.h>
23 #include <StorageKit.h>
24 #include <SerialPort.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <ctype.h>
29 #include <fs_info.h>
30
31 #include "sysdeps.h"
32 #include "main.h"
33 #include "cdrom.h"
34 #include "xpram.h"
35 #include "prefs.h"
36 #include "version.h"
37 #include "user_strings.h"
38 #include "prefs_editor.h"
39
40
41 // Special colors
42 const rgb_color fill_color = {216, 216, 216, 0};
43 const rgb_color slider_fill_color = {102, 152, 255, 0};
44
45 // Display types
46 enum {
47 DISPLAY_WINDOW,
48 DISPLAY_SCREEN
49 };
50
51 // Window messages
52 const uint32 MSG_OK = 'okok'; // "Start" clicked
53 const uint32 MSG_CANCEL = 'cncl'; // "Quit" clicked
54 const uint32 MSG_ZAP_PRAM = 'zprm';
55
56 const int NUM_PANES = 4;
57
58 const uint32 MSG_VOLUME_SELECTED = 'volu'; // "Volumes" pane
59 const uint32 MSG_VOLUME_INVOKED = 'voli';
60 const uint32 MSG_ADD_VOLUME = 'addv';
61 const uint32 MSG_CREATE_VOLUME = 'crev';
62 const uint32 MSG_REMOVE_VOLUME = 'remv';
63 const uint32 MSG_ADD_VOLUME_PANEL = 'advp';
64 const uint32 MSG_CREATE_VOLUME_PANEL = 'crvp';
65 const uint32 MSG_DEVICE_NAME = 'devn';
66 const uint32 MSG_BOOT_ANY = 'bany';
67 const uint32 MSG_BOOT_CDROM = 'bcdr';
68 const uint32 MSG_NOCDROM = 'nocd';
69
70 const uint32 MSG_REF_5HZ = ' 5Hz'; // "Graphics/Sound" pane
71 const uint32 MSG_REF_7_5HZ = ' 7Hz';
72 const uint32 MSG_REF_10HZ = '10Hz';
73 const uint32 MSG_REF_15HZ = '15Hz';
74 const uint32 MSG_REF_30HZ = '30Hz';
75 const uint32 MSG_VIDEO_WINDOW = 'vtyw';
76 const uint32 MSG_VIDEO_SCREEN = 'vtys';
77 const uint32 MSG_SCREEN_MODE = 'sm\0\0';
78 const uint32 MSG_NOSOUND = 'nosn';
79
80 const uint32 MSG_SER_A = 'sera'; // "Serial/Network" pane
81 const uint32 MSG_SER_B = 'serb';
82 const uint32 MSG_ETHER = 'ethr';
83
84 const uint32 MSG_RAMSIZE = 'rmsz'; // "Memory/Misc" pane
85 const uint32 MSG_MODELID_5 = 'mi05';
86 const uint32 MSG_MODELID_14 = 'mi14';
87 const uint32 MSG_CPU_68020 = 'cpu2';
88 const uint32 MSG_CPU_68020_FPU = 'cpf2';
89 const uint32 MSG_CPU_68030 = 'cpu3';
90 const uint32 MSG_CPU_68030_FPU = 'cpf3';
91 const uint32 MSG_CPU_68040 = 'cpu4';
92
93
94 // RAM size slider class
95 class RAMSlider : public BSlider {
96 public:
97 RAMSlider(BRect frame, const char *name, const char *label, BMessage *message,
98 int32 minValue, int32 maxValue, thumb_style thumbType = B_BLOCK_THUMB,
99 uint32 resizingMode = B_FOLLOW_LEFT |
100 B_FOLLOW_TOP,
101 uint32 flags = B_NAVIGABLE | B_WILL_DRAW |
102 B_FRAME_EVENTS) : BSlider(frame, name, label, message, minValue, maxValue, thumbType, resizingMode, flags)
103 {
104 update_text = (char *)malloc(256);
105 }
106
107 virtual ~RAMSlider()
108 {
109 if (update_text)
110 free(update_text);
111 }
112
113 virtual char *UpdateText(void) const
114 {
115 if (update_text) {
116 sprintf(update_text, GetString(STR_RAMSIZE_FMT), Value());
117 }
118 return update_text;
119 }
120
121 private:
122 char *update_text;
123 };
124
125
126 // Volumes list view class
127 class VolumeListView : public BListView {
128 public:
129 VolumeListView(BRect frame, const char *name, list_view_type type = B_SINGLE_SELECTION_LIST, uint32 resizeMask = B_FOLLOW_LEFT | B_FOLLOW_TOP, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE)
130 : BListView(frame, name, type, resizeMask, flags)
131 {}
132
133 // Handle dropped files and volumes
134 virtual void MessageReceived(BMessage *msg)
135 {
136 if (msg->what == B_SIMPLE_DATA) {
137 BMessage msg2(MSG_ADD_VOLUME_PANEL);
138 entry_ref ref;
139 for (int i=0; msg->FindRef("refs", i, &ref) == B_NO_ERROR; i++)
140 msg2.AddRef("refs", &ref);
141 Window()->PostMessage(&msg2);
142 } else
143 BListView::MessageReceived(msg);
144 }
145 };
146
147
148 // Number-entry BTextControl
149 class NumberControl : public BTextControl {
150 public:
151 NumberControl(BRect frame, float divider, const char *name, const char *label, long value, BMessage *message)
152 : BTextControl(frame, name, label, NULL, message, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE)
153 {
154 SetDivider(divider);
155 for (int c=0; c<256; c++)
156 if (!isdigit(c) && c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW)
157 ((BTextView *)ChildAt(0))->DisallowChar(c);
158 SetValue(value);
159 }
160
161 // Set integer value
162 void SetValue(long value)
163 {
164 char str[32];
165 sprintf(str, "%ld", value);
166 SetText(str);
167 }
168
169 // Get integer value
170 long Value(void)
171 {
172 return atol(Text());
173 }
174 };
175
176
177 // Path-entry BTextControl
178 class PathControl : public BTextControl {
179 public:
180 PathControl(bool dir_ctrl_, BRect frame, const char *name, const char *label, const char *text, BMessage *message) : BTextControl(frame, name, label, text, message), dir_ctrl(dir_ctrl_)
181 {
182 for (int c=0; c<' '; c++)
183 if (c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW)
184 ((BTextView *)ChildAt(0))->DisallowChar(c);
185 }
186
187 virtual void MessageReceived(BMessage *msg)
188 {
189 if (msg->what == B_SIMPLE_DATA) {
190 entry_ref the_ref;
191 BEntry the_entry;
192
193 // Look for dropped refs
194 if (msg->FindRef("refs", &the_ref) == B_NO_ERROR) {
195 if (the_entry.SetTo(&the_ref) == B_NO_ERROR && (dir_ctrl&& the_entry.IsDirectory() || !dir_ctrl && the_entry.IsFile())) {
196 BPath the_path;
197 the_entry.GetPath(&the_path);
198 SetText(the_path.Path());
199 }
200 } else
201 BTextControl::MessageReceived(msg);
202
203 MakeFocus();
204 } else
205 BTextControl::MessageReceived(msg);
206 }
207
208 private:
209 bool dir_ctrl;
210 };
211
212
213 // Preferences window class
214 class PrefsWindow : public BWindow {
215 public:
216 PrefsWindow(uint32 msg);
217 virtual ~PrefsWindow();
218 virtual void MessageReceived(BMessage *msg);
219
220 private:
221 void read_volumes_prefs(void);
222 void hide_show_graphics_ctrls(void);
223 void read_graphics_prefs(void);
224 void add_serial_names(BPopUpMenu *menu, uint32 msg);
225 void read_memory_prefs(void);
226
227 BView *create_volumes_pane(void);
228 BView *create_graphics_pane(void);
229 BView *create_serial_pane(void);
230 BView *create_memory_pane(void);
231
232 uint32 ok_message;
233 bool send_quit_on_close;
234
235 system_info sys_info;
236 BMessenger this_messenger;
237 BView *top;
238 BRect top_frame;
239 BTabView *pane_tabs;
240 BView *panes[NUM_PANES];
241 int current_pane;
242
243 VolumeListView *volume_list;
244 BCheckBox *nocdrom_checkbox;
245 BMenuField *frameskip_menu;
246 NumberControl *display_x_ctrl;
247 NumberControl *display_y_ctrl;
248 BMenuField *scr_mode_menu;
249 BCheckBox *nosound_checkbox;
250 BCheckBox *ether_checkbox;
251 RAMSlider *ramsize_slider;
252 PathControl *extfs_control;
253 PathControl *rom_control;
254 BCheckBox *fpu_checkbox;
255
256 BFilePanel *add_volume_panel;
257 BFilePanel *create_volume_panel;
258
259 uint32 max_ramsize; // In MB
260 int display_type;
261 int scr_mode_bit;
262 };
263
264
265 /*
266 * Show preferences editor (asynchronously)
267 * Under BeOS, the return value is ignored. Instead, a message is sent to the
268 * application when the user clicks on "Start" or "Quit"
269 */
270
271 bool PrefsEditor(void)
272 {
273 new PrefsWindow('strt');
274 return true;
275 }
276
277
278 /*
279 * Preferences window constructor
280 */
281
282 PrefsWindow::PrefsWindow(uint32 msg) : BWindow(BRect(0, 0, 400, 289), GetString(STR_PREFS_TITLE), B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS), this_messenger(this)
283 {
284 int i;
285 ok_message = msg;
286 send_quit_on_close = true;
287 get_system_info(&sys_info);
288
289 // Move window to right position
290 Lock();
291 MoveTo(80, 80);
292
293 // Set up menus
294 BMenuBar *bar = new BMenuBar(Bounds(), "menu");
295 BMenu *menu = new BMenu(GetString(STR_PREFS_MENU));
296 menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_ABOUT), new BMessage(B_ABOUT_REQUESTED)));
297 menu->AddItem(new BSeparatorItem);
298 menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_START), new BMessage(MSG_OK)));
299 menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_ZAP_PRAM), new BMessage(MSG_ZAP_PRAM)));
300 menu->AddItem(new BSeparatorItem);
301 menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_QUIT), new BMessage(MSG_CANCEL), 'Q'));
302 bar->AddItem(menu);
303 AddChild(bar);
304 SetKeyMenuBar(bar);
305 int mbar_height = int(bar->Bounds().bottom) + 1;
306
307 // Resize window to fit menu bar
308 ResizeBy(0, mbar_height);
309
310 // Light gray background
311 BRect b = Bounds();
312 top = new BView(BRect(0, mbar_height, b.right, b.bottom), "top", B_FOLLOW_NONE, B_WILL_DRAW);
313 AddChild(top);
314 top->SetViewColor(fill_color);
315 top_frame = top->Bounds();
316
317 // Create panes
318 panes[0] = create_volumes_pane();
319 panes[1] = create_graphics_pane();
320 panes[2] = create_serial_pane();
321 panes[3] = create_memory_pane();
322
323 // Prefs item tab view
324 pane_tabs = new BTabView(BRect(10, 10, top_frame.right-10, top_frame.bottom-50), "items", B_WIDTH_FROM_LABEL);
325 for (i=0; i<NUM_PANES; i++)
326 pane_tabs->AddTab(panes[i]);
327 top->AddChild(pane_tabs);
328
329 volume_list->Select(0);
330
331 // Create volume file panels
332 add_volume_panel = new BFilePanel(B_OPEN_PANEL, &this_messenger, NULL, B_FILE_NODE | B_DIRECTORY_NODE, false, new BMessage(MSG_ADD_VOLUME_PANEL));
333 add_volume_panel->SetButtonLabel(B_DEFAULT_BUTTON, GetString(STR_ADD_VOLUME_PANEL_BUTTON));
334 add_volume_panel->Window()->SetTitle(GetString(STR_ADD_VOLUME_TITLE));
335 create_volume_panel = new BFilePanel(B_SAVE_PANEL, &this_messenger, NULL, B_FILE_NODE | B_DIRECTORY_NODE, false, new BMessage(MSG_CREATE_VOLUME_PANEL));
336 create_volume_panel->SetButtonLabel(B_DEFAULT_BUTTON, GetString(STR_CREATE_VOLUME_PANEL_BUTTON));
337 create_volume_panel->Window()->SetTitle(GetString(STR_CREATE_VOLUME_TITLE));
338
339 create_volume_panel->Window()->Lock();
340 BView *background = create_volume_panel->Window()->ChildAt(0);
341 background->FindView("PoseView")->ResizeBy(0, -30);
342 background->FindView("VScrollBar")->ResizeBy(0, -30);
343 background->FindView("CountVw")->MoveBy(0, -30);
344 BView *v = background->FindView("HScrollBar");
345 if (v)
346 v->MoveBy(0, -30);
347 else {
348 i = 0;
349 while ((v = background->ChildAt(i++)) != NULL) {
350 if (v->Name() == NULL || v->Name()[0] == 0) {
351 v->MoveBy(0, -30); // unnamed horizontal scroll bar
352 break;
353 }
354 }
355 }
356 BView *filename = background->FindView("text view");
357 BRect fnr(filename->Frame());
358 fnr.OffsetBy(0, -30);
359 NumberControl *nc = new NumberControl(fnr, 80, "hardfile_size", GetString(STR_HARDFILE_SIZE_CTRL), 40, NULL);
360 background->AddChild(nc);
361 create_volume_panel->Window()->Unlock();
362
363 // "Start" button
364 BButton *button = new BButton(BRect(20, top_frame.bottom-35, 90, top_frame.bottom-10), "start", GetString(STR_START_BUTTON), new BMessage(MSG_OK));
365 top->AddChild(button);
366 SetDefaultButton(button);
367
368 // "Quit" button
369 top->AddChild(new BButton(BRect(top_frame.right-90, top_frame.bottom-35, top_frame.right-20, top_frame.bottom-10), "cancel", GetString(STR_QUIT_BUTTON), new BMessage(MSG_CANCEL)));
370
371 Unlock();
372 Show();
373 }
374
375
376 /*
377 * Preferences window destructor
378 */
379
380 PrefsWindow::~PrefsWindow()
381 {
382 delete add_volume_panel;
383 delete create_volume_panel;
384 if (send_quit_on_close)
385 be_app->PostMessage(B_QUIT_REQUESTED);
386 }
387
388
389 /*
390 * Create "Volumes" pane
391 */
392
393 void PrefsWindow::read_volumes_prefs(void)
394 {
395 PrefsReplaceString("extfs", extfs_control->Text());
396 }
397
398 BView *PrefsWindow::create_volumes_pane(void)
399 {
400 BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_VOLUMES_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW);
401 pane->SetViewColor(fill_color);
402 float right = pane->Bounds().right-10;
403
404 const char *str;
405 int32 index = 0;
406 volume_list = new VolumeListView(BRect(15, 10, pane->Bounds().right-30, 113), "volumes");
407 while ((str = PrefsFindString("disk", index++)) != NULL)
408 volume_list->AddItem(new BStringItem(str));
409 volume_list->SetSelectionMessage(new BMessage(MSG_VOLUME_SELECTED));
410 volume_list->SetInvocationMessage(new BMessage(MSG_VOLUME_INVOKED));
411 pane->AddChild(new BScrollView("volumes_border", volume_list, B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true));
412
413 pane->AddChild(new BButton(BRect(10, 118, pane->Bounds().right/3, 138), "add_volume", GetString(STR_ADD_VOLUME_BUTTON), new BMessage(MSG_ADD_VOLUME)));
414 pane->AddChild(new BButton(BRect(pane->Bounds().right/3, 118, pane->Bounds().right*2/3, 138), "create_volume", GetString(STR_CREATE_VOLUME_BUTTON), new BMessage(MSG_CREATE_VOLUME)));
415 pane->AddChild(new BButton(BRect(pane->Bounds().right*2/3, 118, pane->Bounds().right-11, 138), "remove_volume", GetString(STR_REMOVE_VOLUME_BUTTON), new BMessage(MSG_REMOVE_VOLUME)));
416
417 extfs_control = new PathControl(true, BRect(10, 145, right, 160), "extfs", GetString(STR_EXTFS_CTRL), PrefsFindString("extfs"), NULL);
418 extfs_control->SetDivider(90);
419 pane->AddChild(extfs_control);
420
421 BMenuField *menu_field;
422 BPopUpMenu *menu = new BPopUpMenu("");
423 menu_field = new BMenuField(BRect(10, 165, right, 180), "bootdriver", GetString(STR_BOOTDRIVER_CTRL), menu);
424 menu_field->SetDivider(90);
425 menu->AddItem(new BMenuItem(GetString(STR_BOOT_ANY_LAB), new BMessage(MSG_BOOT_ANY)));
426 menu->AddItem(new BMenuItem(GetString(STR_BOOT_CDROM_LAB), new BMessage(MSG_BOOT_CDROM)));
427 pane->AddChild(menu_field);
428 int32 i32 = PrefsFindInt32("bootdriver");
429 BMenuItem *item;
430 if (i32 == 0) {
431 if ((item = menu->FindItem(GetString(STR_BOOT_ANY_LAB))) != NULL)
432 item->SetMarked(true);
433 } else if (i32 == CDROMRefNum) {
434 if ((item = menu->FindItem(GetString(STR_BOOT_CDROM_LAB))) != NULL)
435 item->SetMarked(true);
436 }
437
438 nocdrom_checkbox = new BCheckBox(BRect(10, 185, right, 200), "nocdrom", GetString(STR_NOCDROM_CTRL), new BMessage(MSG_NOCDROM));
439 pane->AddChild(nocdrom_checkbox);
440 nocdrom_checkbox->SetValue(PrefsFindBool("nocdrom") ? B_CONTROL_ON : B_CONTROL_OFF);
441
442 return pane;
443 }
444
445
446 /*
447 * Create "Graphics/Sound" pane
448 */
449
450 // Screen mode list
451 struct scr_mode_desc {
452 int mode_mask;
453 int str;
454 };
455
456 static const scr_mode_desc scr_mode[] = {
457 {B_8_BIT_640x480, STR_8_BIT_640x480_LAB},
458 {B_8_BIT_800x600, STR_8_BIT_800x600_LAB},
459 {B_8_BIT_1024x768, STR_8_BIT_1024x768_LAB},
460 {B_8_BIT_1152x900, STR_8_BIT_1152x900_LAB},
461 {B_8_BIT_1280x1024, STR_8_BIT_1280x1024_LAB},
462 {B_8_BIT_1600x1200, STR_8_BIT_1600x1200_LAB},
463 {B_15_BIT_640x480, STR_15_BIT_640x480_LAB},
464 {B_15_BIT_800x600, STR_15_BIT_800x600_LAB},
465 {B_15_BIT_1024x768, STR_15_BIT_1024x768_LAB},
466 {B_15_BIT_1152x900, STR_15_BIT_1152x900_LAB},
467 {B_15_BIT_1280x1024, STR_15_BIT_1280x1024_LAB},
468 {B_15_BIT_1600x1200, STR_15_BIT_1600x1200_LAB},
469 {B_32_BIT_640x480, STR_24_BIT_640x480_LAB},
470 {B_32_BIT_800x600, STR_24_BIT_800x600_LAB},
471 {B_32_BIT_1024x768, STR_24_BIT_1024x768_LAB},
472 {B_32_BIT_1152x900, STR_24_BIT_1152x900_LAB},
473 {B_32_BIT_1280x1024, STR_24_BIT_1280x1024_LAB},
474 {B_32_BIT_1600x1200, STR_24_BIT_1600x1200_LAB},
475 {0, 0} // End marker
476 };
477
478 void PrefsWindow::hide_show_graphics_ctrls(void)
479 {
480 if (display_type == DISPLAY_WINDOW) {
481 if (!scr_mode_menu->IsHidden())
482 scr_mode_menu->Hide();
483 if (frameskip_menu->IsHidden())
484 frameskip_menu->Show();
485 if (display_x_ctrl->IsHidden())
486 display_x_ctrl->Show();
487 if (display_y_ctrl->IsHidden())
488 display_y_ctrl->Show();
489 } else {
490 if (!frameskip_menu->IsHidden())
491 frameskip_menu->Hide();
492 if (!display_x_ctrl->IsHidden())
493 display_x_ctrl->Hide();
494 if (!display_y_ctrl->IsHidden())
495 display_y_ctrl->Hide();
496 if (scr_mode_menu->IsHidden())
497 scr_mode_menu->Show();
498 }
499 }
500
501 void PrefsWindow::read_graphics_prefs(void)
502 {
503 char str[64];
504 if (display_type == DISPLAY_WINDOW) {
505 sprintf(str, "win/%d/%d", display_x_ctrl->Value(), display_y_ctrl->Value());
506 } else {
507 sprintf(str, "scr/%d", scr_mode_bit);
508 }
509 PrefsReplaceString("screen", str);
510 }
511
512 BView *PrefsWindow::create_graphics_pane(void)
513 {
514 BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_GRAPHICS_SOUND_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW);
515 pane->SetViewColor(fill_color);
516 float right = pane->Bounds().right-10;
517
518 const char *mode_str = PrefsFindString("screen");
519 int width = 512, height = 384;
520 scr_mode_bit = 0;
521 display_type = DISPLAY_WINDOW;
522 if (mode_str) {
523 if (sscanf(mode_str, "win/%d/%d", &width, &height) == 2)
524 display_type = DISPLAY_WINDOW;
525 else if (sscanf(mode_str, "scr/%d", &scr_mode_bit) == 1)
526 display_type = DISPLAY_SCREEN;
527 }
528
529 BMenuField *menu_field;
530 BMenuItem *item;
531 BPopUpMenu *menu;
532
533 menu = new BPopUpMenu("");
534 menu_field = new BMenuField(BRect(10, 5, right, 20), "videotype", GetString(STR_VIDEO_TYPE_CTRL), menu);
535 menu_field->SetDivider(120);
536 menu->AddItem(item = new BMenuItem(GetString(STR_WINDOW_LAB), new BMessage(MSG_VIDEO_WINDOW)));
537 if (display_type == DISPLAY_WINDOW)
538 item->SetMarked(true);
539 menu->AddItem(item = new BMenuItem(GetString(STR_FULLSCREEN_LAB), new BMessage(MSG_VIDEO_SCREEN)));
540 if (display_type == DISPLAY_SCREEN)
541 item->SetMarked(true);
542 pane->AddChild(menu_field);
543
544 menu = new BPopUpMenu("");
545 frameskip_menu = new BMenuField(BRect(10, 26, right, 41), "frameskip", GetString(STR_FRAMESKIP_CTRL), menu);
546 frameskip_menu->SetDivider(120);
547 menu->AddItem(new BMenuItem(GetString(STR_REF_5HZ_LAB), new BMessage(MSG_REF_5HZ)));
548 menu->AddItem(new BMenuItem(GetString(STR_REF_7_5HZ_LAB), new BMessage(MSG_REF_7_5HZ)));
549 menu->AddItem(new BMenuItem(GetString(STR_REF_10HZ_LAB), new BMessage(MSG_REF_10HZ)));
550 menu->AddItem(new BMenuItem(GetString(STR_REF_15HZ_LAB), new BMessage(MSG_REF_15HZ)));
551 menu->AddItem(new BMenuItem(GetString(STR_REF_30HZ_LAB), new BMessage(MSG_REF_30HZ)));
552 pane->AddChild(frameskip_menu);
553 int32 i32 = PrefsFindInt32("frameskip");
554 if (i32 == 12) {
555 if ((item = menu->FindItem(GetString(STR_REF_5HZ_LAB))) != NULL)
556 item->SetMarked(true);
557 } else if (i32 == 8) {
558 if ((item = menu->FindItem(GetString(STR_REF_7_5HZ_LAB))) != NULL)
559 item->SetMarked(true);
560 } else if (i32 == 6) {
561 if ((item = menu->FindItem(GetString(STR_REF_10HZ_LAB))) != NULL)
562 item->SetMarked(true);
563 } else if (i32 == 4) {
564 if ((item = menu->FindItem(GetString(STR_REF_15HZ_LAB))) != NULL)
565 item->SetMarked(true);
566 } else if (i32 == 2) {
567 if ((item = menu->FindItem(GetString(STR_REF_30HZ_LAB))) != NULL)
568 item->SetMarked(true);
569 }
570
571 display_x_ctrl = new NumberControl(BRect(10, 48, right / 2, 66), 118, "width", GetString(STR_DISPLAY_X_CTRL), width, NULL);
572 pane->AddChild(display_x_ctrl);
573 display_y_ctrl = new NumberControl(BRect(10, 69, right / 2, 87), 118, "height", GetString(STR_DISPLAY_Y_CTRL), height, NULL);
574 pane->AddChild(display_y_ctrl);
575
576 menu = new BPopUpMenu("");
577 scr_mode_menu = new BMenuField(BRect(10, 26, right, 41), "screenmode", GetString(STR_SCREEN_MODE_CTRL), menu);
578 scr_mode_menu->SetDivider(120);
579 for (int i=0; scr_mode[i].mode_mask; i++) {
580 menu->AddItem(item = new BMenuItem(GetString(scr_mode[i].str), new BMessage(MSG_SCREEN_MODE + i)));
581 if (scr_mode[i].mode_mask & (1 << scr_mode_bit))
582 item->SetMarked(true);
583 }
584 pane->AddChild(scr_mode_menu);
585
586 nosound_checkbox = new BCheckBox(BRect(10, 90, right, 105), "nosound", GetString(STR_NOSOUND_CTRL), new BMessage(MSG_NOSOUND));
587 pane->AddChild(nosound_checkbox);
588 nosound_checkbox->SetValue(PrefsFindBool("nosound") ? B_CONTROL_ON : B_CONTROL_OFF);
589
590 hide_show_graphics_ctrls();
591 return pane;
592 }
593
594
595 /*
596 * Create "Serial Ports" pane
597 */
598
599 void PrefsWindow::add_serial_names(BPopUpMenu *menu, uint32 msg)
600 {
601 BSerialPort *port = new BSerialPort;
602 char name[B_PATH_NAME_LENGTH];
603 for (int i=0; i<port->CountDevices(); i++) {
604 port->GetDeviceName(i, name);
605 menu->AddItem(new BMenuItem(name, new BMessage(msg)));
606 }
607 if (sys_info.platform_type == B_BEBOX_PLATFORM) {
608 BDirectory dir;
609 BEntry entry;
610 dir.SetTo("/dev/parallel");
611 if (dir.InitCheck() == B_NO_ERROR) {
612 dir.Rewind();
613 while (dir.GetNextEntry(&entry) >= 0) {
614 if (!entry.IsDirectory()) {
615 entry.GetName(name);
616 menu->AddItem(new BMenuItem(name, new BMessage(msg)));
617 }
618 }
619 }
620 }
621 delete port;
622 }
623
624 static void set_serial_label(BPopUpMenu *menu, const char *prefs_name)
625 {
626 const char *str;
627 BMenuItem *item;
628 if ((str = PrefsFindString(prefs_name)) != NULL)
629 if ((item = menu->FindItem(str)) != NULL)
630 item->SetMarked(true);
631 }
632
633 BView *PrefsWindow::create_serial_pane(void)
634 {
635 BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_SERIAL_NETWORK_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW);
636 pane->SetViewColor(fill_color);
637 float right = pane->Bounds().right-10;
638
639 BMenuField *menu_field;
640 BPopUpMenu *menu_a = new BPopUpMenu("");
641 add_serial_names(menu_a, MSG_SER_A);
642 menu_field = new BMenuField(BRect(10, 5, right, 20), "seriala", GetString(STR_SERIALA_CTRL), menu_a);
643 menu_field->SetDivider(90);
644 pane->AddChild(menu_field);
645 set_serial_label(menu_a, "seriala");
646
647 BPopUpMenu *menu_b = new BPopUpMenu("");
648 add_serial_names(menu_b, MSG_SER_B);
649 menu_field = new BMenuField(BRect(10, 26, right, 41), "serialb", GetString(STR_SERIALB_CTRL), menu_b);
650 menu_field->SetDivider(90);
651 pane->AddChild(menu_field);
652 set_serial_label(menu_b, "serialb");
653
654 ether_checkbox = new BCheckBox(BRect(10, 47, right, 62), "ether", GetString(STR_ETHER_ENABLE_CTRL), new BMessage(MSG_ETHER));
655 pane->AddChild(ether_checkbox);
656 ether_checkbox->SetValue(PrefsFindString("ether") ? B_CONTROL_ON : B_CONTROL_OFF);
657
658 return pane;
659 }
660
661
662 /*
663 * Create "Memory" pane
664 */
665
666 void PrefsWindow::read_memory_prefs(void)
667 {
668 const char *str = rom_control->Text();
669 if (strlen(str))
670 PrefsReplaceString("rom", str);
671 else
672 PrefsRemoveItem("rom");
673 }
674
675 BView *PrefsWindow::create_memory_pane(void)
676 {
677 char str[256], str2[256];
678 BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_MEMORY_MISC_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW);
679 pane->SetViewColor(fill_color);
680 float right = pane->Bounds().right-10;
681
682 BEntry entry("/boot/var/swap");
683 off_t swap_space;
684 if (entry.GetSize(&swap_space) == B_NO_ERROR)
685 max_ramsize = swap_space / (1024 * 1024) - 8;
686 else
687 max_ramsize = sys_info.max_pages * B_PAGE_SIZE / (1024 * 1024) - 8;
688
689 int32 value = PrefsFindInt32("ramsize") / (1024 * 1024);
690
691 ramsize_slider = new RAMSlider(BRect(10, 5, right, 55), "ramsize", GetString(STR_RAMSIZE_SLIDER), new BMessage(MSG_RAMSIZE), 1, max_ramsize, B_TRIANGLE_THUMB);
692 ramsize_slider->SetValue(value);
693 ramsize_slider->UseFillColor(true, &slider_fill_color);
694 sprintf(str, GetString(STR_RAMSIZE_FMT), 1);
695 sprintf(str2, GetString(STR_RAMSIZE_FMT), max_ramsize);
696 ramsize_slider->SetLimitLabels(str, str2);
697 pane->AddChild(ramsize_slider);
698
699 BMenuField *menu_field;
700 BMenuItem *item;
701 BPopUpMenu *menu;
702
703 int id = PrefsFindInt32("modelid");
704 menu = new BPopUpMenu("");
705 menu_field = new BMenuField(BRect(10, 60, right, 75), "modelid", GetString(STR_MODELID_CTRL), menu);
706 menu_field->SetDivider(120);
707 menu->AddItem(item = new BMenuItem(GetString(STR_MODELID_5_LAB), new BMessage(MSG_MODELID_5)));
708 if (id == 5)
709 item->SetMarked(true);
710 menu->AddItem(item = new BMenuItem(GetString(STR_MODELID_14_LAB), new BMessage(MSG_MODELID_14)));
711 if (id == 14)
712 item->SetMarked(true);
713 pane->AddChild(menu_field);
714
715 int cpu = PrefsFindInt32("cpu");
716 bool fpu = PrefsFindBool("fpu");
717 menu = new BPopUpMenu("");
718 menu_field = new BMenuField(BRect(10, 82, right, 97), "cpu", GetString(STR_CPU_CTRL), menu);
719 menu_field->SetDivider(120);
720 menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68020_LAB), new BMessage(MSG_CPU_68020)));
721 if (cpu == 2 && !fpu)
722 item->SetMarked(true);
723 menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68020_FPU_LAB), new BMessage(MSG_CPU_68020_FPU)));
724 if (cpu == 2 && fpu)
725 item->SetMarked(true);
726 menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68030_LAB), new BMessage(MSG_CPU_68030)));
727 if (cpu == 3 && !fpu)
728 item->SetMarked(true);
729 menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68030_FPU_LAB), new BMessage(MSG_CPU_68030_FPU)));
730 if (cpu == 3 && fpu)
731 item->SetMarked(true);
732 menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68040_LAB), new BMessage(MSG_CPU_68040)));
733 if (cpu == 4)
734 item->SetMarked(true);
735 pane->AddChild(menu_field);
736
737 rom_control = new PathControl(false, BRect(10, 104, right, 119), "rom", GetString(STR_ROM_FILE_CTRL), PrefsFindString("rom"), NULL);
738 rom_control->SetDivider(117);
739 pane->AddChild(rom_control);
740
741 return pane;
742 }
743
744
745 /*
746 * Message from controls/menus received
747 */
748
749 void PrefsWindow::MessageReceived(BMessage *msg)
750 {
751 switch (msg->what) {
752 case MSG_OK: { // "Start" button clicked
753 read_volumes_prefs();
754 read_memory_prefs();
755 read_graphics_prefs();
756 SavePrefs();
757 send_quit_on_close = false;
758 PostMessage(B_QUIT_REQUESTED);
759 be_app->PostMessage(ok_message);
760 break;
761 }
762
763 case MSG_CANCEL: // "Quit" button clicked
764 send_quit_on_close = false;
765 PostMessage(B_QUIT_REQUESTED);
766 be_app->PostMessage(B_QUIT_REQUESTED);
767 break;
768
769 case B_ABOUT_REQUESTED: { // "About" menu item selected
770 char str[256];
771 sprintf(str, GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR);
772 strcat(str, " ");
773 strcat(str, GetString(STR_ABOUT_TEXT2));
774 BAlert *about = new BAlert(GetString(STR_WINDOW_TITLE), str, GetString(STR_OK_BUTTON));
775 about->Go();
776 break;
777 }
778
779 case MSG_ZAP_PRAM: // "Zap PRAM File" menu item selected
780 ZapPRAM();
781 break;
782
783 case MSG_VOLUME_INVOKED: { // Double-clicked on volume name, toggle read-only flag
784 int selected = volume_list->CurrentSelection();
785 if (selected >= 0) {
786 const char *str = PrefsFindString("disk", selected);
787 BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected);
788 delete item;
789 char newstr[256];
790 if (str[0] == '*')
791 strcpy(newstr, str+1);
792 else {
793 strcpy(newstr, "*");
794 strcat(newstr, str);
795 }
796 PrefsReplaceString("disk", newstr, selected);
797 volume_list->AddItem(new BStringItem(newstr), selected);
798 volume_list->Select(selected);
799 }
800 break;
801 }
802
803 case MSG_ADD_VOLUME:
804 add_volume_panel->Show();
805 break;
806
807 case MSG_CREATE_VOLUME:
808 create_volume_panel->Show();
809 break;
810
811 case MSG_ADD_VOLUME_PANEL: {
812 entry_ref ref;
813 if (msg->FindRef("refs", &ref) == B_NO_ERROR) {
814 BEntry entry(&ref, true);
815 BPath path;
816 entry.GetPath(&path);
817 if (entry.IsFile()) {
818 PrefsAddString("disk", path.Path());
819 volume_list->AddItem(new BStringItem(path.Path()));
820 } else if (entry.IsDirectory()) {
821 BVolume volume;
822 if (path.Path()[0] == '/' && strchr(path.Path()+1, '/') == NULL && entry.GetVolume(&volume) == B_NO_ERROR) {
823 int32 i = 0;
824 dev_t d;
825 fs_info info;
826 while ((d = next_dev(&i)) >= 0) {
827 fs_stat_dev(d, &info);
828 if (volume.Device() == info.dev) {
829 PrefsAddString("disk", info.device_name);
830 volume_list->AddItem(new BStringItem(info.device_name));
831 }
832 }
833 }
834 }
835 }
836 break;
837 }
838
839 case MSG_CREATE_VOLUME_PANEL: {
840 entry_ref dir;
841 if (msg->FindRef("directory", &dir) == B_NO_ERROR) {
842 BEntry entry(&dir, true);
843 BPath path;
844 entry.GetPath(&path);
845 path.Append(msg->FindString("name"));
846
847 create_volume_panel->Window()->Lock();
848 BView *background = create_volume_panel->Window()->ChildAt(0);
849 NumberControl *v = (NumberControl *)background->FindView("hardfile_size");
850 int size = v->Value();
851
852 char cmd[1024];
853 sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", path.Path(), size);
854 int ret = system(cmd);
855 if (ret == 0) {
856 PrefsAddString("disk", path.Path());
857 volume_list->AddItem(new BStringItem(path.Path()));
858 } else {
859 sprintf(cmd, GetString(STR_CREATE_VOLUME_WARN), strerror(ret));
860 WarningAlert(cmd);
861 }
862 }
863 break;
864 }
865
866 case MSG_REMOVE_VOLUME: {
867 int selected = volume_list->CurrentSelection();
868 if (selected >= 0) {
869 PrefsRemoveItem("disk", selected);
870 BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected);
871 delete item;
872 volume_list->Select(selected);
873 }
874 break;
875 }
876
877 case MSG_BOOT_ANY:
878 PrefsReplaceInt32("bootdriver", 0);
879 break;
880
881 case MSG_BOOT_CDROM:
882 PrefsReplaceInt32("bootdriver", CDROMRefNum);
883 break;
884
885 case MSG_NOCDROM:
886 PrefsReplaceBool("nocdrom", nocdrom_checkbox->Value() == B_CONTROL_ON);
887 break;
888
889 case MSG_VIDEO_WINDOW:
890 display_type = DISPLAY_WINDOW;
891 hide_show_graphics_ctrls();
892 break;
893
894 case MSG_VIDEO_SCREEN:
895 display_type = DISPLAY_SCREEN;
896 hide_show_graphics_ctrls();
897 break;
898
899 case MSG_REF_5HZ:
900 PrefsReplaceInt32("frameskip", 12);
901 break;
902
903 case MSG_REF_7_5HZ:
904 PrefsReplaceInt32("frameskip", 8);
905 break;
906
907 case MSG_REF_10HZ:
908 PrefsReplaceInt32("frameskip", 6);
909 break;
910
911 case MSG_REF_15HZ:
912 PrefsReplaceInt32("frameskip", 4);
913 break;
914
915 case MSG_REF_30HZ:
916 PrefsReplaceInt32("frameskip", 2);
917 break;
918
919 case MSG_NOSOUND:
920 PrefsReplaceBool("nosound", nosound_checkbox->Value() == B_CONTROL_ON);
921 break;
922
923 case MSG_SER_A: {
924 BMenuItem *source = NULL;
925 msg->FindPointer("source", (void **)&source);
926 if (source)
927 PrefsReplaceString("seriala", source->Label());
928 break;
929 }
930
931 case MSG_SER_B: {
932 BMenuItem *source = NULL;
933 msg->FindPointer("source", (void **)&source);
934 if (source)
935 PrefsReplaceString("serialb", source->Label());
936 break;
937 }
938
939 case MSG_ETHER:
940 if (ether_checkbox->Value() == B_CONTROL_ON)
941 PrefsReplaceString("ether", "yes");
942 else
943 PrefsRemoveItem("ether");
944 break;
945
946 case MSG_RAMSIZE:
947 PrefsReplaceInt32("ramsize", ramsize_slider->Value() * 1024 * 1024);
948 break;
949
950 case MSG_MODELID_5:
951 PrefsReplaceInt32("modelid", 5);
952 break;
953
954 case MSG_MODELID_14:
955 PrefsReplaceInt32("modelid", 14);
956 break;
957
958 case MSG_CPU_68020:
959 PrefsReplaceInt32("cpu", 2);
960 PrefsReplaceBool("fpu", false);
961 break;
962
963 case MSG_CPU_68020_FPU:
964 PrefsReplaceInt32("cpu", 2);
965 PrefsReplaceBool("fpu", true);
966 break;
967
968 case MSG_CPU_68030:
969 PrefsReplaceInt32("cpu", 3);
970 PrefsReplaceBool("fpu", false);
971 break;
972
973 case MSG_CPU_68030_FPU:
974 PrefsReplaceInt32("cpu", 3);
975 PrefsReplaceBool("fpu", true);
976 break;
977
978 case MSG_CPU_68040:
979 PrefsReplaceInt32("cpu", 4);
980 PrefsReplaceBool("fpu", true);
981 break;
982
983 default: {
984 // Screen mode messages
985 if ((msg->what & 0xffff0000) == MSG_SCREEN_MODE) {
986 int m = msg->what & 0xffff;
987 uint32 mask = scr_mode[m].mode_mask;
988 for (int i=0; i<32; i++)
989 if (mask & (1 << i))
990 scr_mode_bit = i;
991 } else
992 BWindow::MessageReceived(msg);
993 }
994 }
995 }