ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/BeOS/prefs_editor_beos.cpp
Revision: 1.3
Committed: 1999-10-21T09:03:44Z (24 years, 8 months ago) by cebix
Branch: MAIN
CVS Tags: snapshot-21101999
Changes since 1.2: +1 -1 lines
Log Message:
- enlarged prefs editor window to make volumes pane fit

File Contents

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