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

# User Rev Content
1 cebix 1.1 /*
2     * prefs_editor_beos.cpp - Preferences editor, BeOS implementation
3     *
4 gbeauche 1.4 * SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
5 cebix 1.1 *
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     }