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

# User Rev Content
1 cebix 1.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 cebix 1.2 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 cebix 1.1 {
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 cebix 1.2 if (the_entry.SetTo(&the_ref) == B_NO_ERROR && (dir_ctrl&& the_entry.IsDirectory() || !dir_ctrl && the_entry.IsFile())) {
191 cebix 1.1 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 cebix 1.2
203     private:
204     bool dir_ctrl;
205 cebix 1.1 };
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 cebix 1.2 void read_volumes_prefs(void);
217 cebix 1.1 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 cebix 1.2 PathControl *extfs_control;
248 cebix 1.1 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 cebix 1.3 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 cebix 1.1 {
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 cebix 1.2 void PrefsWindow::read_volumes_prefs(void)
388     {
389     PrefsReplaceString("extfs", extfs_control->Text());
390     }
391    
392 cebix 1.1 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 cebix 1.2 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 cebix 1.1 BMenuField *menu_field;
416     BPopUpMenu *menu = new BPopUpMenu("");
417 cebix 1.2 menu_field = new BMenuField(BRect(10, 165, right, 180), "bootdriver", GetString(STR_BOOTDRIVER_CTRL), menu);
418 cebix 1.1 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 cebix 1.2 nocdrom_checkbox = new BCheckBox(BRect(10, 185, right, 200), "nocdrom", GetString(STR_NOCDROM_CTRL), new BMessage(MSG_NOCDROM));
433 cebix 1.1 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 cebix 1.2 rom_control = new PathControl(false, BRect(10, 82, right, 97), "rom", GetString(STR_ROM_FILE_CTRL), PrefsFindString("rom"), NULL);
710 cebix 1.1 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 cebix 1.2 read_volumes_prefs();
726 cebix 1.1 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     }