ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/BeOS/prefs_editor_beos.cpp
Revision: 1.4
Committed: 1999-10-28T09:31:39Z (24 years, 8 months ago) by cebix
Branch: MAIN
Changes since 1.3: +10 -0 lines
Log Message:
- Lauri's FPU now works on big-endian machines
- included "FPU" checkbox in prefs editor

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