ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/BeOS/prefs_editor_beos.cpp
Revision: 1.14
Committed: 2005-01-30T21:42:13Z (19 years, 9 months ago) by gbeauche
Branch: MAIN
CVS Tags: nigel-build-19, nigel-build-17
Changes since 1.13: +1 -1 lines
Log Message:
Happy New Year!

File Contents

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