ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/BeOS/prefs_editor_beos.cpp
Revision: 1.4
Committed: 2008-01-01T09:47:38Z (16 years, 4 months ago) by gbeauche
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +1 -1 lines
Log Message:
Happy New Year!

File Contents

# Content
1 /*
2 * prefs_editor_beos.cpp - Preferences editor, BeOS implementation
3 *
4 * SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
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 <SerialPort.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <fs_info.h>
27
28 #include "prefs_editor.h"
29 #include "prefs.h"
30 #include "main.h"
31 #include "cdrom.h"
32 #include "xpram.h"
33 #include "about_window.h"
34 #include "user_strings.h"
35
36
37 // Special colors
38 const rgb_color fill_color = {216, 216, 216, 0};
39 const rgb_color slider_fill_color = {102, 152, 255, 0};
40
41
42 // Window messages
43 const uint32 MSG_OK = 'okok'; // "Start" clicked
44 const uint32 MSG_CANCEL = 'cncl'; // "Quit" clicked
45 const uint32 MSG_ZAP_PRAM = 'zprm';
46
47 const int NUM_PANES = 4;
48
49 const uint32 MSG_VOLUME_SELECTED = 'volu'; // "Volumes" pane
50 const uint32 MSG_VOLUME_INVOKED = 'voli';
51 const uint32 MSG_ADD_VOLUME = 'addv';
52 const uint32 MSG_CREATE_VOLUME = 'crev';
53 const uint32 MSG_REMOVE_VOLUME = 'remv';
54 const uint32 MSG_ADD_VOLUME_PANEL = 'advp';
55 const uint32 MSG_CREATE_VOLUME_PANEL = 'crvp';
56 const uint32 MSG_DEVICE_NAME = 'devn';
57 const uint32 MSG_BOOT_ANY = 'bany';
58 const uint32 MSG_BOOT_CDROM = 'bcdr';
59 const uint32 MSG_NOCDROM = 'nocd';
60
61 const uint32 MSG_REF_5HZ = ' 5Hz'; // "Graphics" pane
62 const uint32 MSG_REF_7_5HZ = ' 7Hz';
63 const uint32 MSG_REF_10HZ = '10Hz';
64 const uint32 MSG_REF_15HZ = '15Hz';
65 const uint32 MSG_REF_30HZ = '30Hz';
66 const uint32 MSG_GFXACCEL = 'gfac';
67 const uint32 MSG_WINDOW_MODE = 'wmod';
68 const uint32 MSG_SCREEN_MODE = 'smod';
69 const uint32 MSG_NOSOUND = 'nosn';
70
71 const uint32 MSG_SER_A = 'sera'; // "Serial"/"Network" pane
72 const uint32 MSG_SER_B = 'serb';
73 const uint32 MSG_NONET = 'noet';
74
75 const uint32 MSG_RAMSIZE = 'rmsz'; // "Memory" pane
76 const uint32 MSG_IGNORESEGV = 'isgv';
77 const uint32 MSG_IDLEWAIT = 'idlw';
78
79
80 // RAM size slider class
81 class RAMSlider : public BSlider {
82 public:
83 RAMSlider(BRect frame, const char *name, const char *label, BMessage *message,
84 int32 minValue, int32 maxValue, thumb_style thumbType = B_BLOCK_THUMB,
85 uint32 resizingMode = B_FOLLOW_LEFT |
86 B_FOLLOW_TOP,
87 uint32 flags = B_NAVIGABLE | B_WILL_DRAW |
88 B_FRAME_EVENTS) : BSlider(frame, name, label, message, minValue, maxValue, thumbType, resizingMode, flags)
89 {
90 update_text = (char *)malloc(256);
91 }
92
93 virtual ~RAMSlider()
94 {
95 if (update_text)
96 free(update_text);
97 }
98
99 virtual char *UpdateText(void) const
100 {
101 if (update_text) {
102 sprintf(update_text, GetString(STR_RAMSIZE_FMT), Value());
103 }
104 return update_text;
105 }
106
107 private:
108 char *update_text;
109 };
110
111
112 // Volumes list view class
113 class VolumeListView : public BListView {
114 public:
115 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)
116 : BListView(frame, name, type, resizeMask, flags)
117 {}
118
119 // Handle dropped files and volumes
120 virtual void MessageReceived(BMessage *msg)
121 {
122 if (msg->what == B_SIMPLE_DATA) {
123 BMessage msg2(MSG_ADD_VOLUME_PANEL);
124 entry_ref ref;
125 for (int i=0; msg->FindRef("refs", i, &ref) == B_NO_ERROR; i++)
126 msg2.AddRef("refs", &ref);
127 Window()->PostMessage(&msg2);
128 } else
129 BListView::MessageReceived(msg);
130 }
131 };
132
133
134 // Number-entry BTextControl
135 class NumberControl : public BTextControl {
136 public:
137 NumberControl(BRect frame, float divider, const char *name, const char *label, long value, BMessage *message)
138 : BTextControl(frame, name, label, NULL, message, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE)
139 {
140 SetDivider(divider);
141 for (int c=0; c<256; c++)
142 if (!isdigit(c) && c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW)
143 ((BTextView *)ChildAt(0))->DisallowChar(c);
144 SetValue(value);
145 }
146
147 // Set integer value
148 void SetValue(long value)
149 {
150 char str[32];
151 sprintf(str, "%ld", value);
152 SetText(str);
153 }
154
155 // Get integer value
156 long Value(void)
157 {
158 return atol(Text());
159 }
160 };
161
162
163 // Path-entry BTextControl
164 class PathControl : public BTextControl {
165 public:
166 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_)
167 {
168 for (int c=0; c<' '; c++)
169 if (c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW)
170 ((BTextView *)ChildAt(0))->DisallowChar(c);
171 }
172
173 virtual void MessageReceived(BMessage *msg)
174 {
175 if (msg->what == B_SIMPLE_DATA) {
176 entry_ref the_ref;
177 BEntry the_entry;
178
179 // Look for dropped refs
180 if (msg->FindRef("refs", &the_ref) == B_NO_ERROR) {
181 if (the_entry.SetTo(&the_ref) == B_NO_ERROR && (dir_ctrl&& the_entry.IsDirectory() || !dir_ctrl && the_entry.IsFile())) {
182 BPath the_path;
183 the_entry.GetPath(&the_path);
184 SetText(the_path.Path());
185 }
186 } else
187 BTextControl::MessageReceived(msg);
188
189 MakeFocus();
190 } else
191 BTextControl::MessageReceived(msg);
192 }
193
194 private:
195 bool dir_ctrl;
196 };
197
198
199 // Preferences window class
200 class PrefsWindow : public BWindow {
201 public:
202 PrefsWindow(uint32 msg);
203 virtual ~PrefsWindow();
204 virtual void MessageReceived(BMessage *msg);
205
206 private:
207 BView *create_volumes_pane(void);
208 BView *create_graphics_pane(void);
209 BView *create_serial_pane(void);
210 BView *create_memory_pane(void);
211
212 uint32 ok_message;
213 bool send_quit_on_close;
214
215 BMessenger this_messenger;
216 BView *top;
217 BRect top_frame;
218 BTabView *pane_tabs;
219 BView *panes[NUM_PANES];
220 int current_pane;
221
222 VolumeListView *volume_list;
223 BCheckBox *nocdrom_checkbox;
224 BCheckBox *gfxaccel_checkbox;
225 BCheckBox *nosound_checkbox;
226 BCheckBox *nonet_checkbox;
227 BCheckBox *ignoresegv_checkbox;
228 BCheckBox *idlewait_checkbox;
229 RAMSlider *ramsize_slider;
230 PathControl *extfs_control;
231 PathControl *rom_control;
232
233 BFilePanel *add_volume_panel;
234 BFilePanel *create_volume_panel;
235
236 uint32 max_ramsize; // In MB
237 };
238
239
240 /*
241 * Show preferences editor
242 * When the user clicks on "OK", the message given as parameter is sent
243 * to the application; if he clicks on "Quit", B_QUIT_REQUESTED is sent
244 */
245
246 void PrefsEditor(uint32 msg)
247 {
248 new PrefsWindow(msg);
249 }
250
251
252 /*
253 * Preferences window constructor
254 */
255
256 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)
257 {
258 int i;
259 ok_message = msg;
260 send_quit_on_close = true;
261
262 // Move window to right position
263 Lock();
264 MoveTo(80, 80);
265
266 // Set up menus
267 BMenuBar *bar = new BMenuBar(Bounds(), "menu");
268 BMenu *menu = new BMenu(GetString(STR_PREFS_MENU));
269 menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_ABOUT), new BMessage(B_ABOUT_REQUESTED)));
270 menu->AddItem(new BSeparatorItem);
271 menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_START), new BMessage(MSG_OK)));
272 menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_ZAP_PRAM), new BMessage(MSG_ZAP_PRAM)));
273 menu->AddItem(new BSeparatorItem);
274 menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_QUIT), new BMessage(MSG_CANCEL), 'Q'));
275 bar->AddItem(menu);
276 AddChild(bar);
277 SetKeyMenuBar(bar);
278 int mbar_height = bar->Bounds().bottom + 1;
279
280 // Resize window to fit menu bar
281 ResizeBy(0, mbar_height);
282
283 // Light gray background
284 BRect b = Bounds();
285 top = new BView(BRect(0, mbar_height, b.right, b.bottom), "top", B_FOLLOW_NONE, B_WILL_DRAW);
286 AddChild(top);
287 top->SetViewColor(fill_color);
288 top_frame = top->Bounds();
289
290 // Create panes
291 panes[0] = create_volumes_pane();
292 panes[1] = create_graphics_pane();
293 panes[2] = create_serial_pane();
294 panes[3] = create_memory_pane();
295
296 // Prefs item tab view
297 pane_tabs = new BTabView(BRect(10, 10, top_frame.right-10, top_frame.bottom-50), "items", B_WIDTH_FROM_LABEL);
298 for (i=0; i<NUM_PANES; i++)
299 pane_tabs->AddTab(panes[i]);
300 top->AddChild(pane_tabs);
301
302 volume_list->Select(0);
303
304 // Create volume file panels
305 add_volume_panel = new BFilePanel(B_OPEN_PANEL, &this_messenger, NULL, B_FILE_NODE | B_DIRECTORY_NODE, false, new BMessage(MSG_ADD_VOLUME_PANEL));
306 add_volume_panel->SetButtonLabel(B_DEFAULT_BUTTON, GetString(STR_ADD_VOLUME_PANEL_BUTTON));
307 add_volume_panel->Window()->SetTitle(GetString(STR_ADD_VOLUME_TITLE));
308 create_volume_panel = new BFilePanel(B_SAVE_PANEL, &this_messenger, NULL, B_FILE_NODE | B_DIRECTORY_NODE, false, new BMessage(MSG_CREATE_VOLUME_PANEL));
309 create_volume_panel->SetButtonLabel(B_DEFAULT_BUTTON, GetString(STR_CREATE_VOLUME_PANEL_BUTTON));
310 create_volume_panel->Window()->SetTitle(GetString(STR_CREATE_VOLUME_TITLE));
311
312 create_volume_panel->Window()->Lock();
313 BView *background = create_volume_panel->Window()->ChildAt(0);
314 background->FindView("PoseView")->ResizeBy(0, -30);
315 background->FindView("VScrollBar")->ResizeBy(0, -30);
316 background->FindView("CountVw")->MoveBy(0, -30);
317 BView *v = background->FindView("HScrollBar");
318 if (v)
319 v->MoveBy(0, -30);
320 else {
321 i = 0;
322 while ((v = background->ChildAt(i++)) != NULL) {
323 if (v->Name() == NULL || v->Name()[0] == 0) {
324 v->MoveBy(0, -30); // unnamed horizontal scroll bar
325 break;
326 }
327 }
328 }
329 BView *filename = background->FindView("text view");
330 BRect fnr(filename->Frame());
331 fnr.OffsetBy(0, -30);
332 NumberControl *nc = new NumberControl(fnr, 80, "hardfile_size", GetString(STR_HARDFILE_SIZE_CTRL), 40, NULL);
333 background->AddChild(nc);
334 create_volume_panel->Window()->Unlock();
335
336 // "Start" button
337 BButton *button = new BButton(BRect(20, top_frame.bottom-35, 90, top_frame.bottom-10), "start", GetString(STR_START_BUTTON), new BMessage(MSG_OK));
338 top->AddChild(button);
339 SetDefaultButton(button);
340
341 // "Quit" button
342 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)));
343
344 Unlock();
345 Show();
346 }
347
348
349 /*
350 * Preferences window destructor
351 */
352
353 PrefsWindow::~PrefsWindow()
354 {
355 delete add_volume_panel;
356 if (send_quit_on_close)
357 be_app->PostMessage(B_QUIT_REQUESTED);
358 }
359
360
361 /*
362 * Create "Volumes" pane
363 */
364
365 BView *PrefsWindow::create_volumes_pane(void)
366 {
367 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);
368 pane->SetViewColor(fill_color);
369 float right = pane->Bounds().right-10;
370
371 const char *str;
372 int32 index = 0;
373 volume_list = new VolumeListView(BRect(15, 10, pane->Bounds().right-30, 108), "volumes");
374 while ((str = PrefsFindString("disk", index++)) != NULL)
375 volume_list->AddItem(new BStringItem(str));
376 volume_list->SetSelectionMessage(new BMessage(MSG_VOLUME_SELECTED));
377 volume_list->SetInvocationMessage(new BMessage(MSG_VOLUME_INVOKED));
378 pane->AddChild(new BScrollView("volumes_border", volume_list, B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true));
379
380 pane->AddChild(new BButton(BRect(10, 113, pane->Bounds().right/3, 133), "add_volume", GetString(STR_ADD_VOLUME_BUTTON), new BMessage(MSG_ADD_VOLUME)));
381 pane->AddChild(new BButton(BRect(pane->Bounds().right/3, 113, pane->Bounds().right*2/3, 133), "create_volume", GetString(STR_CREATE_VOLUME_BUTTON), new BMessage(MSG_CREATE_VOLUME)));
382 pane->AddChild(new BButton(BRect(pane->Bounds().right*2/3, 113, pane->Bounds().right-11, 133), "remove_volume", GetString(STR_REMOVE_VOLUME_BUTTON), new BMessage(MSG_REMOVE_VOLUME)));
383
384 extfs_control = new PathControl(true, BRect(10, 145, right, 160), "extfs", GetString(STR_EXTFS_CTRL), PrefsFindString("extfs"), NULL);
385 extfs_control->SetDivider(90);
386 pane->AddChild(extfs_control);
387
388 BMenuField *menu_field;
389 BPopUpMenu *menu = new BPopUpMenu("");
390 menu_field = new BMenuField(BRect(10, 165, right, 180), "bootdriver", GetString(STR_BOOTDRIVER_CTRL), menu);
391 menu_field->SetDivider(90);
392 menu->AddItem(new BMenuItem(GetString(STR_BOOT_ANY_LAB), new BMessage(MSG_BOOT_ANY)));
393 menu->AddItem(new BMenuItem(GetString(STR_BOOT_CDROM_LAB), new BMessage(MSG_BOOT_CDROM)));
394 pane->AddChild(menu_field);
395 int16 i16 = PrefsFindInt32("bootdriver");
396 BMenuItem *item;
397 if (i16 == 0) {
398 if ((item = menu->FindItem(GetString(STR_BOOT_ANY_LAB))) != NULL)
399 item->SetMarked(true);
400 } else if (i16 == CDROMRefNum) {
401 if ((item = menu->FindItem(GetString(STR_BOOT_CDROM_LAB))) != NULL)
402 item->SetMarked(true);
403 }
404
405 nocdrom_checkbox = new BCheckBox(BRect(10, 185, right, 200), "nocdrom", GetString(STR_NOCDROM_CTRL), new BMessage(MSG_NOCDROM));
406 pane->AddChild(nocdrom_checkbox);
407 nocdrom_checkbox->SetValue(PrefsFindBool("nocdrom") ? B_CONTROL_ON : B_CONTROL_OFF);
408
409 return pane;
410 }
411
412
413 /*
414 * Create "Graphics/Sound" pane
415 */
416
417 struct video_mode_box {
418 uint32 mode;
419 int mode_string_id, bit_string_id;
420 float left, top;
421 BCheckBox *box;
422 };
423
424 const int NUM_WINDOW_MODES = 6;
425 const int NUM_SCREEN_MODES = 18;
426
427 static video_mode_box window_mode_boxes[NUM_SCREEN_MODES] = {
428 {B_8_BIT_640x480, STR_W_640x480_CTRL, STR_8_BIT_CTRL, 140, 48, NULL},
429 {B_15_BIT_640x480, STR_W_640x480_CTRL, STR_16_BIT_CTRL, 220, 48, NULL},
430 {B_32_BIT_640x480, STR_W_640x480_CTRL, STR_32_BIT_CTRL, 300, 48, NULL},
431 {B_8_BIT_800x600, STR_W_800x600_CTRL, STR_8_BIT_CTRL, 140, 65, NULL},
432 {B_15_BIT_800x600, STR_W_800x600_CTRL, STR_16_BIT_CTRL, 220, 65, NULL},
433 {B_32_BIT_800x600, STR_W_800x600_CTRL, STR_32_BIT_CTRL, 300, 65, NULL},
434 };
435
436 static video_mode_box screen_mode_boxes[NUM_SCREEN_MODES] = {
437 {B_8_BIT_640x480, STR_640x480_CTRL, STR_8_BIT_CTRL, 140, 82, NULL},
438 {B_15_BIT_640x480, STR_640x480_CTRL, STR_16_BIT_CTRL, 220, 82, NULL},
439 {B_32_BIT_640x480, STR_640x480_CTRL, STR_32_BIT_CTRL, 300, 82, NULL},
440 {B_8_BIT_800x600, STR_800x600_CTRL, STR_8_BIT_CTRL, 140, 99, NULL},
441 {B_15_BIT_800x600, STR_800x600_CTRL, STR_16_BIT_CTRL, 220, 99, NULL},
442 {B_32_BIT_800x600, STR_800x600_CTRL, STR_32_BIT_CTRL, 300, 99, NULL},
443 {B_8_BIT_1024x768, STR_1024x768_CTRL, STR_8_BIT_CTRL, 140, 116, NULL},
444 {B_15_BIT_1024x768, STR_1024x768_CTRL, STR_16_BIT_CTRL, 220, 116, NULL},
445 {B_32_BIT_1024x768, STR_1024x768_CTRL, STR_32_BIT_CTRL, 300, 116, NULL},
446 {B_8_BIT_1152x900, STR_1152x900_CTRL, STR_8_BIT_CTRL, 140, 133, NULL},
447 {B_15_BIT_1152x900, STR_1152x900_CTRL, STR_16_BIT_CTRL, 220, 133, NULL},
448 {B_32_BIT_1152x900, STR_1152x900_CTRL, STR_32_BIT_CTRL, 300, 133, NULL},
449 {B_8_BIT_1280x1024, STR_1280x1024_CTRL, STR_8_BIT_CTRL, 140, 150, NULL},
450 {B_15_BIT_1280x1024, STR_1280x1024_CTRL, STR_16_BIT_CTRL, 220, 150, NULL},
451 {B_32_BIT_1280x1024, STR_1280x1024_CTRL, STR_32_BIT_CTRL, 300, 150, NULL},
452 {B_8_BIT_1600x1200, STR_1600x1200_CTRL, STR_8_BIT_CTRL, 140, 167, NULL},
453 {B_15_BIT_1600x1200, STR_1600x1200_CTRL, STR_16_BIT_CTRL, 220, 167, NULL},
454 {B_32_BIT_1600x1200, STR_1600x1200_CTRL, STR_32_BIT_CTRL, 300, 167, NULL}
455 };
456
457 BView *PrefsWindow::create_graphics_pane(void)
458 {
459 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);
460 pane->SetViewColor(fill_color);
461 float right = pane->Bounds().right-10;
462
463 BMenuField *menu_field;
464 BPopUpMenu *menu = new BPopUpMenu("");
465 menu_field = new BMenuField(BRect(10, 5, right, 20), "frameskip", GetString(STR_FRAMESKIP_CTRL), menu);
466 menu_field->SetDivider(120);
467 menu->AddItem(new BMenuItem(GetString(STR_REF_5HZ_LAB), new BMessage(MSG_REF_5HZ)));
468 menu->AddItem(new BMenuItem(GetString(STR_REF_7_5HZ_LAB), new BMessage(MSG_REF_7_5HZ)));
469 menu->AddItem(new BMenuItem(GetString(STR_REF_10HZ_LAB), new BMessage(MSG_REF_10HZ)));
470 menu->AddItem(new BMenuItem(GetString(STR_REF_15HZ_LAB), new BMessage(MSG_REF_15HZ)));
471 menu->AddItem(new BMenuItem(GetString(STR_REF_30HZ_LAB), new BMessage(MSG_REF_30HZ)));
472 pane->AddChild(menu_field);
473 int32 i32 = PrefsFindInt32("frameskip");
474 BMenuItem *item;
475 if (i32 == 12) {
476 if ((item = menu->FindItem(GetString(STR_REF_5HZ_LAB))) != NULL)
477 item->SetMarked(true);
478 } else if (i32 == 8) {
479 if ((item = menu->FindItem(GetString(STR_REF_7_5HZ_LAB))) != NULL)
480 item->SetMarked(true);
481 } else if (i32 == 6) {
482 if ((item = menu->FindItem(GetString(STR_REF_10HZ_LAB))) != NULL)
483 item->SetMarked(true);
484 } else if (i32 == 4) {
485 if ((item = menu->FindItem(GetString(STR_REF_15HZ_LAB))) != NULL)
486 item->SetMarked(true);
487 } else if (i32 == 2) {
488 if ((item = menu->FindItem(GetString(STR_REF_30HZ_LAB))) != NULL)
489 item->SetMarked(true);
490 }
491
492 gfxaccel_checkbox = new BCheckBox(BRect(10, 25, right, 40), "gfxaccel", GetString(STR_GFXACCEL_CTRL), new BMessage(MSG_GFXACCEL));
493 pane->AddChild(gfxaccel_checkbox);
494 gfxaccel_checkbox->SetValue(PrefsFindBool("gfxaccel") ? B_CONTROL_ON : B_CONTROL_OFF);
495
496 uint32 window_modes = PrefsFindInt32("windowmodes");
497 for (int i=0; i<NUM_WINDOW_MODES; i++) {
498 video_mode_box *p = window_mode_boxes + i;
499 if (p->bit_string_id == STR_8_BIT_CTRL) {
500 BStringView *text = new BStringView(BRect(10, p->top, 120, p->top + 15), "", GetString(p->mode_string_id));
501 pane->AddChild(text);
502 }
503 p->box = new BCheckBox(BRect(p->left, p->top, p->left + 80, p->top + 15), "", GetString(p->bit_string_id), new BMessage(MSG_WINDOW_MODE));
504 pane->AddChild(p->box);
505 p->box->SetValue(window_modes & p->mode ? B_CONTROL_ON : B_CONTROL_OFF);
506 }
507 uint32 screen_modes = PrefsFindInt32("screenmodes");
508 for (int i=0; i<NUM_SCREEN_MODES; i++) {
509 video_mode_box *p = screen_mode_boxes + i;
510 if (p->bit_string_id == STR_8_BIT_CTRL) {
511 BStringView *text = new BStringView(BRect(10, p->top, 120, p->top + 15), "", GetString(p->mode_string_id));
512 pane->AddChild(text);
513 }
514 p->box = new BCheckBox(BRect(p->left, p->top, p->left + 80, p->top + 15), "", GetString(p->bit_string_id), new BMessage(MSG_SCREEN_MODE));
515 pane->AddChild(p->box);
516 p->box->SetValue(screen_modes & p->mode ? B_CONTROL_ON : B_CONTROL_OFF);
517 }
518
519 nosound_checkbox = new BCheckBox(BRect(10, 185, right, 200), "nosound", GetString(STR_NOSOUND_CTRL), new BMessage(MSG_NOSOUND));
520 pane->AddChild(nosound_checkbox);
521 nosound_checkbox->SetValue(PrefsFindBool("nosound") ? B_CONTROL_ON : B_CONTROL_OFF);
522
523 return pane;
524 }
525
526
527 /*
528 * Create "Serial/Network" pane
529 */
530
531 static void add_serial_names(BPopUpMenu *menu, uint32 msg)
532 {
533 BSerialPort *port = new BSerialPort;
534 char name[B_PATH_NAME_LENGTH];
535 for (int i=0; i<port->CountDevices(); i++) {
536 port->GetDeviceName(i, name);
537 menu->AddItem(new BMenuItem(name, new BMessage(msg)));
538 }
539 if (SysInfo.platform_type == B_BEBOX_PLATFORM) {
540 BDirectory dir;
541 BEntry entry;
542 dir.SetTo("/dev/parallel");
543 if (dir.InitCheck() == B_NO_ERROR) {
544 dir.Rewind();
545 while (dir.GetNextEntry(&entry) >= 0) {
546 if (!entry.IsDirectory()) {
547 entry.GetName(name);
548 menu->AddItem(new BMenuItem(name, new BMessage(msg)));
549 }
550 }
551 }
552 }
553 delete port;
554 }
555
556 static void set_serial_label(BPopUpMenu *menu, const char *prefs_name)
557 {
558 const char *str;
559 BMenuItem *item;
560 if ((str = PrefsFindString(prefs_name)) != NULL)
561 if ((item = menu->FindItem(str)) != NULL)
562 item->SetMarked(true);
563 }
564
565 BView *PrefsWindow::create_serial_pane(void)
566 {
567 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);
568 pane->SetViewColor(fill_color);
569 float right = pane->Bounds().right-10;
570
571 BMenuField *menu_field;
572 BPopUpMenu *menu_a = new BPopUpMenu("");
573 add_serial_names(menu_a, MSG_SER_A);
574 menu_field = new BMenuField(BRect(10, 5, right, 20), "seriala", GetString(STR_SERPORTA_CTRL), menu_a);
575 menu_field->SetDivider(90);
576 pane->AddChild(menu_field);
577 set_serial_label(menu_a, "seriala");
578
579 BPopUpMenu *menu_b = new BPopUpMenu("");
580 add_serial_names(menu_b, MSG_SER_B);
581 menu_field = new BMenuField(BRect(10, 26, right, 41), "serialb", GetString(STR_SERPORTB_CTRL), menu_b);
582 menu_field->SetDivider(90);
583 pane->AddChild(menu_field);
584 set_serial_label(menu_b, "serialb");
585
586 nonet_checkbox = new BCheckBox(BRect(10, 47, right, 62), "nonet", GetString(STR_NONET_CTRL), new BMessage(MSG_NONET));
587 pane->AddChild(nonet_checkbox);
588 nonet_checkbox->SetValue(PrefsFindBool("nonet") ? B_CONTROL_ON : B_CONTROL_OFF);
589
590 return pane;
591 }
592
593
594 /*
595 * Create "Memory/Misc" pane
596 */
597
598 BView *PrefsWindow::create_memory_pane(void)
599 {
600 char str[256], str2[256];
601 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);
602 pane->SetViewColor(fill_color);
603 float right = pane->Bounds().right-10;
604
605 BEntry entry("/boot/var/swap");
606 off_t swap_space;
607 if (entry.GetSize(&swap_space) == B_NO_ERROR)
608 max_ramsize = swap_space / (1024 * 1024) - 8;
609 else
610 max_ramsize = SysInfo.max_pages * B_PAGE_SIZE / (1024 * 1024) - 8;
611
612 int32 value = PrefsFindInt32("ramsize") / (1024 * 1024);
613
614 ramsize_slider = new RAMSlider(BRect(10, 5, right, 55), "ramsize", GetString(STR_RAMSIZE_SLIDER), new BMessage(MSG_RAMSIZE), 8, max_ramsize, B_TRIANGLE_THUMB);
615 ramsize_slider->SetValue(value);
616 ramsize_slider->UseFillColor(true, &slider_fill_color);
617 sprintf(str, GetString(STR_RAMSIZE_FMT), 8);
618 sprintf(str2, GetString(STR_RAMSIZE_FMT), max_ramsize);
619 ramsize_slider->SetLimitLabels(str, str2);
620 pane->AddChild(ramsize_slider);
621
622 ignoresegv_checkbox = new BCheckBox(BRect(10, 60, right, 75), "ignoresegv", GetString(STR_IGNORESEGV_CTRL), new BMessage(MSG_IGNORESEGV));
623 pane->AddChild(ignoresegv_checkbox);
624 ignoresegv_checkbox->SetValue(PrefsFindBool("ignoresegv") ? B_CONTROL_ON : B_CONTROL_OFF);
625
626 idlewait_checkbox = new BCheckBox(BRect(10, 80, right, 95), "idlewait", GetString(STR_IDLEWAIT_CTRL), new BMessage(MSG_IDLEWAIT));
627 pane->AddChild(idlewait_checkbox);
628 idlewait_checkbox->SetValue(PrefsFindBool("idlewait") ? B_CONTROL_ON : B_CONTROL_OFF);
629
630 rom_control = new PathControl(false, BRect(10, 100, right, 115), "rom", GetString(STR_ROM_FILE_CTRL), PrefsFindString("rom"), NULL);
631 rom_control->SetDivider(117);
632 pane->AddChild(rom_control);
633
634 return pane;
635 }
636
637
638 /*
639 * Message from controls/menus received
640 */
641
642 void PrefsWindow::MessageReceived(BMessage *msg)
643 {
644 switch (msg->what) {
645 case MSG_OK: // "Start" button clicked
646 PrefsReplaceString("extfs", extfs_control->Text());
647 const char *str = rom_control->Text();
648 if (strlen(str))
649 PrefsReplaceString("rom", str);
650 else
651 PrefsRemoveItem("rom");
652 SavePrefs();
653 send_quit_on_close = false;
654 PostMessage(B_QUIT_REQUESTED);
655 be_app->PostMessage(ok_message);
656 break;
657
658 case MSG_CANCEL: // "Quit" button clicked
659 send_quit_on_close = false;
660 PostMessage(B_QUIT_REQUESTED);
661 be_app->PostMessage(B_QUIT_REQUESTED);
662 break;
663
664 case B_ABOUT_REQUESTED: // "About" menu item selected
665 OpenAboutWindow();
666 break;
667
668 case MSG_ZAP_PRAM: // "Zap PRAM File" menu item selected
669 ZapPRAM();
670 break;
671
672 case MSG_VOLUME_INVOKED: { // Double-clicked on volume name, toggle read-only flag
673 int selected = volume_list->CurrentSelection();
674 if (selected >= 0) {
675 const char *str = PrefsFindString("disk", selected);
676 BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected);
677 delete item;
678 char newstr[256];
679 if (str[0] == '*')
680 strcpy(newstr, str+1);
681 else {
682 strcpy(newstr, "*");
683 strcat(newstr, str);
684 }
685 PrefsReplaceString("disk", newstr, selected);
686 volume_list->AddItem(new BStringItem(newstr), selected);
687 volume_list->Select(selected);
688 }
689 break;
690 }
691
692 case MSG_ADD_VOLUME:
693 add_volume_panel->Show();
694 break;
695
696 case MSG_CREATE_VOLUME:
697 create_volume_panel->Show();
698 break;
699
700 case MSG_ADD_VOLUME_PANEL: {
701 entry_ref ref;
702 if (msg->FindRef("refs", &ref) == B_NO_ERROR) {
703 BEntry entry(&ref, true);
704 BPath path;
705 entry.GetPath(&path);
706 if (entry.IsFile()) {
707 PrefsAddString("disk", path.Path());
708 volume_list->AddItem(new BStringItem(path.Path()));
709 } else if (entry.IsDirectory()) {
710 BVolume volume;
711 if (path.Path()[0] == '/' && strchr(path.Path()+1, '/') == NULL && entry.GetVolume(&volume) == B_NO_ERROR) {
712 int32 i = 0;
713 dev_t d;
714 fs_info info;
715 while ((d = next_dev(&i)) >= 0) {
716 fs_stat_dev(d, &info);
717 if (volume.Device() == info.dev) {
718 PrefsAddString("disk", info.device_name);
719 volume_list->AddItem(new BStringItem(info.device_name));
720 }
721 }
722 }
723 }
724 }
725 break;
726 }
727
728 case MSG_CREATE_VOLUME_PANEL: {
729 entry_ref dir;
730 if (msg->FindRef("directory", &dir) == B_NO_ERROR) {
731 BEntry entry(&dir, true);
732 BPath path;
733 entry.GetPath(&path);
734 path.Append(msg->FindString("name"));
735
736 create_volume_panel->Window()->Lock();
737 BView *background = create_volume_panel->Window()->ChildAt(0);
738 NumberControl *v = (NumberControl *)background->FindView("hardfile_size");
739 int size = v->Value();
740
741 char cmd[1024];
742 sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", path.Path(), size);
743 int ret = system(cmd);
744 if (ret == 0) {
745 PrefsAddString("disk", path.Path());
746 volume_list->AddItem(new BStringItem(path.Path()));
747 } else {
748 sprintf(cmd, GetString(STR_CREATE_VOLUME_WARN), strerror(ret));
749 WarningAlert(cmd);
750 }
751 }
752 break;
753 }
754
755 case MSG_REMOVE_VOLUME: {
756 int selected = volume_list->CurrentSelection();
757 if (selected >= 0) {
758 PrefsRemoveItem("disk", selected);
759 BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected);
760 delete item;
761 volume_list->Select(selected);
762 }
763 break;
764 }
765
766 case MSG_BOOT_ANY:
767 PrefsReplaceInt32("bootdriver", 0);
768 break;
769
770 case MSG_BOOT_CDROM:
771 PrefsReplaceInt32("bootdriver", CDROMRefNum);
772 break;
773
774 case MSG_NOCDROM:
775 PrefsReplaceBool("nocdrom", nocdrom_checkbox->Value() == B_CONTROL_ON);
776 break;
777
778 case MSG_GFXACCEL:
779 PrefsReplaceBool("gfxaccel", gfxaccel_checkbox->Value() == B_CONTROL_ON);
780 break;
781
782 case MSG_NOSOUND:
783 PrefsReplaceBool("nosound", nosound_checkbox->Value() == B_CONTROL_ON);
784 break;
785
786 case MSG_WINDOW_MODE: {
787 BCheckBox *source = NULL;
788 msg->FindPointer("source", &source);
789 if (source == NULL)
790 break;
791 for (int i=0; i<NUM_WINDOW_MODES; i++) {
792 video_mode_box *p = window_mode_boxes + i;
793 if (p->box == source) {
794 if (p->box->Value() == B_CONTROL_ON)
795 PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") | p->mode);
796 else
797 PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") & ~(p->mode));
798 break;
799 }
800 }
801 break;
802 }
803
804 case MSG_SCREEN_MODE: {
805 BCheckBox *source = NULL;
806 msg->FindPointer("source", &source);
807 if (source == NULL)
808 break;
809 for (int i=0; i<NUM_SCREEN_MODES; i++) {
810 video_mode_box *p = screen_mode_boxes + i;
811 if (p->box == source) {
812 if (p->box->Value() == B_CONTROL_ON)
813 PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | p->mode);
814 else
815 PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~(p->mode));
816 break;
817 }
818 }
819 break;
820 }
821
822 case MSG_REF_5HZ:
823 PrefsReplaceInt32("frameskip", 12);
824 break;
825
826 case MSG_REF_7_5HZ:
827 PrefsReplaceInt32("frameskip", 8);
828 break;
829
830 case MSG_REF_10HZ:
831 PrefsReplaceInt32("frameskip", 6);
832 break;
833
834 case MSG_REF_15HZ:
835 PrefsReplaceInt32("frameskip", 4);
836 break;
837
838 case MSG_REF_30HZ:
839 PrefsReplaceInt32("frameskip", 2);
840 break;
841
842 case MSG_SER_A: {
843 BMenuItem *source = NULL;
844 msg->FindPointer("source", &source);
845 if (source)
846 PrefsReplaceString("seriala", source->Label());
847 break;
848 }
849
850 case MSG_SER_B: {
851 BMenuItem *source = NULL;
852 msg->FindPointer("source", &source);
853 if (source)
854 PrefsReplaceString("serialb", source->Label());
855 break;
856 }
857
858 case MSG_NONET:
859 PrefsReplaceBool("nonet", nonet_checkbox->Value() == B_CONTROL_ON);
860 break;
861
862 case MSG_IGNORESEGV:
863 PrefsReplaceBool("ignoresegv", ignoresegv_checkbox->Value() == B_CONTROL_ON);
864 break;
865
866 case MSG_IDLEWAIT:
867 PrefsReplaceBool("idlewait", idlewait_checkbox->Value() == B_CONTROL_ON);
868 break;
869
870 case MSG_RAMSIZE:
871 PrefsReplaceInt32("ramsize", ramsize_slider->Value() * 1024 * 1024);
872 break;
873
874 default:
875 BWindow::MessageReceived(msg);
876 }
877 }