ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/BeOS/prefs_editor_beos.cpp
Revision: 1.6
Committed: 2000-04-10T18:52:52Z (24 years, 7 months ago) by cebix
Branch: MAIN
CVS Tags: snapshot-13072000
Changes since 1.5: +1 -1 lines
Log Message:
- updated copyright info: 1999->2000

File Contents

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