ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/BeOS/prefs_editor_beos.cpp
Revision: 1.12
Committed: 2002-01-15T14:58:35Z (22 years, 10 months ago) by cebix
Branch: MAIN
CVS Tags: nigel-build-12, nigel-build-13, snapshot-15012002
Changes since 1.11: +1 -1 lines
Log Message:
- documentation updates
- 2001 -> 2002
- version 0.9 -> 1.0

File Contents

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