ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/prefs_editor_gtk.cpp
Revision: 1.13
Committed: 2006-04-30T21:46:31Z (18 years, 1 month ago) by gbeauche
Branch: MAIN
Changes since 1.12: +2 -6 lines
Log Message:
Add "idlewait" to Basilisk II for Windows

File Contents

# Content
1 /*
2 * prefs_editor_gtk.cpp - Preferences editor, Unix implementation using GTK+
3 *
4 * Basilisk II (C) 1997-2005 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 "sysdeps.h"
22
23 #include <stdlib.h>
24 #include <string.h>
25 #include <fcntl.h>
26 #include <sys/stat.h>
27 #include <gtk/gtk.h>
28
29 #include "user_strings.h"
30 #include "version.h"
31 #include "cdrom.h"
32 #include "xpram.h"
33 #include "prefs.h"
34 #include "prefs_editor.h"
35 #include "util_windows.h"
36 #include "b2ether/inc/b2ether_hl.h"
37
38
39 // Global variables
40 static GtkWidget *win; // Preferences window
41 static bool start_clicked = true; // Return value of PrefsEditor() function
42
43
44 // Prototypes
45 static void create_volumes_pane(GtkWidget *top);
46 static void create_scsi_pane(GtkWidget *top);
47 static void create_graphics_pane(GtkWidget *top);
48 static void create_input_pane(GtkWidget *top);
49 static void create_serial_pane(GtkWidget *top);
50 static void create_ethernet_pane(GtkWidget *top);
51 static void create_memory_pane(GtkWidget *top);
52 static void create_jit_pane(GtkWidget *top);
53 static void read_settings(void);
54
55
56 /*
57 * SheepShaver glue
58 */
59
60 #ifdef SHEEPSHAVER
61 #define DISABLE_SCSI 1
62 #define PROGRAM_NAME "SheepShaver"
63 enum {
64 STR_WINDOW_LAB = STR_WINDOW_CTRL,
65 STR_FULLSCREEN_LAB = STR_FULLSCREEN_CTRL,
66 STR_SERIALA_CTRL = STR_SERPORTA_CTRL,
67 STR_SERIALB_CTRL = STR_SERPORTB_CTRL,
68 };
69 #else
70 #define DISABLE_SCSI 1 /* XXX merge code from original Basilisk II for Windows */
71 #define PROGRAM_NAME "BasiliskII"
72 #endif
73
74
75 /*
76 * Utility functions
77 */
78
79 struct opt_desc {
80 int label_id;
81 GtkSignalFunc func;
82 };
83
84 struct combo_desc {
85 int label_id;
86 };
87
88 struct file_req_assoc {
89 file_req_assoc(GtkWidget *r, GtkWidget *e) : req(r), entry(e) {}
90 GtkWidget *req;
91 GtkWidget *entry;
92 };
93
94 static void cb_browse_ok(GtkWidget *button, file_req_assoc *assoc)
95 {
96 gchar *file = (char *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
97 gtk_entry_set_text(GTK_ENTRY(assoc->entry), file);
98 gtk_widget_destroy(assoc->req);
99 delete assoc;
100 }
101
102 static void cb_browse(GtkWidget *widget, void *user_data)
103 {
104 GtkWidget *req = gtk_file_selection_new(GetString(STR_BROWSE_TITLE));
105 gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
106 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(cb_browse_ok), new file_req_assoc(req, (GtkWidget *)user_data));
107 gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
108 gtk_widget_show(req);
109 }
110
111 static GtkWidget *make_browse_button(GtkWidget *entry)
112 {
113 GtkWidget *button;
114
115 button = gtk_button_new_with_label(GetString(STR_BROWSE_CTRL));
116 gtk_widget_show(button);
117 gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc)cb_browse, (void *)entry);
118 return button;
119 }
120
121 static void add_menu_item(GtkWidget *menu, const char *label, GtkSignalFunc func, gpointer data = NULL)
122 {
123 GtkWidget *item = gtk_menu_item_new_with_label(label);
124 gtk_widget_show(item);
125 gtk_signal_connect(GTK_OBJECT(item), "activate", func, data);
126 gtk_menu_append(GTK_MENU(menu), item);
127 }
128
129 static void add_menu_item(GtkWidget *menu, int label_id, GtkSignalFunc func)
130 {
131 add_menu_item(menu, GetString(label_id), func, NULL);
132 }
133
134 static GtkWidget *make_pane(GtkWidget *notebook, int title_id)
135 {
136 GtkWidget *frame, *label, *box;
137
138 frame = gtk_frame_new(NULL);
139 gtk_widget_show(frame);
140 gtk_container_border_width(GTK_CONTAINER(frame), 4);
141
142 label = gtk_label_new(GetString(title_id));
143 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
144
145 box = gtk_vbox_new(FALSE, 4);
146 gtk_widget_show(box);
147 gtk_container_set_border_width(GTK_CONTAINER(box), 4);
148 gtk_container_add(GTK_CONTAINER(frame), box);
149 return box;
150 }
151
152 static GtkWidget *make_button_box(GtkWidget *top, int border, const opt_desc *buttons)
153 {
154 GtkWidget *bb, *button;
155
156 bb = gtk_hbutton_box_new();
157 gtk_widget_show(bb);
158 gtk_container_set_border_width(GTK_CONTAINER(bb), border);
159 gtk_button_box_set_layout(GTK_BUTTON_BOX(bb), GTK_BUTTONBOX_DEFAULT_STYLE);
160 gtk_button_box_set_spacing(GTK_BUTTON_BOX(bb), 4);
161 gtk_box_pack_start(GTK_BOX(top), bb, FALSE, FALSE, 0);
162
163 while (buttons->label_id) {
164 button = gtk_button_new_with_label(GetString(buttons->label_id));
165 gtk_widget_show(button);
166 gtk_signal_connect_object(GTK_OBJECT(button), "clicked", buttons->func, NULL);
167 gtk_box_pack_start(GTK_BOX(bb), button, TRUE, TRUE, 0);
168 buttons++;
169 }
170 return bb;
171 }
172
173 static GtkWidget *make_separator(GtkWidget *top)
174 {
175 GtkWidget *sep = gtk_hseparator_new();
176 gtk_box_pack_start(GTK_BOX(top), sep, FALSE, FALSE, 0);
177 gtk_widget_show(sep);
178 return sep;
179 }
180
181 static GtkWidget *make_table(GtkWidget *top, int x, int y)
182 {
183 GtkWidget *table = gtk_table_new(x, y, FALSE);
184 gtk_widget_show(table);
185 gtk_box_pack_start(GTK_BOX(top), table, FALSE, FALSE, 0);
186 return table;
187 }
188
189 static GtkWidget *table_make_option_menu(GtkWidget *table, int row, int label_id, const opt_desc *options, int active)
190 {
191 GtkWidget *label, *opt, *menu;
192
193 label = gtk_label_new(GetString(label_id));
194 gtk_widget_show(label);
195 gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
196
197 opt = gtk_option_menu_new();
198 gtk_widget_show(opt);
199 menu = gtk_menu_new();
200
201 while (options->label_id) {
202 add_menu_item(menu, options->label_id, options->func);
203 options++;
204 }
205 gtk_menu_set_active(GTK_MENU(menu), active);
206
207 gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
208 gtk_table_attach(GTK_TABLE(table), opt, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
209 return menu;
210 }
211
212 static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, GList *glist)
213 {
214 GtkWidget *label, *combo;
215 char str[32];
216
217 label = gtk_label_new(GetString(label_id));
218 gtk_widget_show(label);
219 gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
220
221 combo = gtk_combo_new();
222 gtk_widget_show(combo);
223 gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
224
225 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), default_value);
226 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
227
228 return combo;
229 }
230
231 static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, const combo_desc *options)
232 {
233 GList *glist = NULL;
234 while (options->label_id) {
235 glist = g_list_append(glist, (void *)GetString(options->label_id));
236 options++;
237 }
238
239 return table_make_combobox(table, row, label_id, default_value, glist);
240 }
241
242 static GtkWidget *table_make_file_entry(GtkWidget *table, int row, int label_id, const char *prefs_item, bool only_dirs = false)
243 {
244 GtkWidget *box, *label, *entry, *button;
245
246 label = gtk_label_new(GetString(label_id));
247 gtk_widget_show(label);
248 gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
249
250 const char *str = PrefsFindString(prefs_item);
251 if (str == NULL)
252 str = "";
253
254 box = gtk_hbox_new(FALSE, 4);
255 gtk_widget_show(box);
256 gtk_table_attach(GTK_TABLE(table), box, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
257
258 entry = gtk_entry_new();
259 gtk_entry_set_text(GTK_ENTRY(entry), str);
260 gtk_widget_show(entry);
261 gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
262
263 button = make_browse_button(entry);
264 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
265 g_object_set_data(G_OBJECT(entry), "chooser_button", button);
266 return entry;
267 }
268
269 static GtkWidget *make_option_menu(GtkWidget *top, int label_id, const opt_desc *options, int active)
270 {
271 GtkWidget *box, *label, *opt, *menu;
272
273 box = gtk_hbox_new(FALSE, 4);
274 gtk_widget_show(box);
275 gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0);
276
277 label = gtk_label_new(GetString(label_id));
278 gtk_widget_show(label);
279 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
280
281 opt = gtk_option_menu_new();
282 gtk_widget_show(opt);
283 menu = gtk_menu_new();
284
285 while (options->label_id) {
286 add_menu_item(menu, options->label_id, options->func);
287 options++;
288 }
289 gtk_menu_set_active(GTK_MENU(menu), active);
290
291 gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
292 gtk_box_pack_start(GTK_BOX(box), opt, FALSE, FALSE, 0);
293 return menu;
294 }
295
296 static GtkWidget *make_file_entry(GtkWidget *top, int label_id, const char *prefs_item, bool only_dirs = false)
297 {
298 GtkWidget *box, *label, *entry;
299
300 box = gtk_hbox_new(FALSE, 4);
301 gtk_widget_show(box);
302 gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0);
303
304 label = gtk_label_new(GetString(label_id));
305 gtk_widget_show(label);
306 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
307
308 const char *str = PrefsFindString(prefs_item);
309 if (str == NULL)
310 str = "";
311
312 entry = gtk_entry_new();
313 gtk_entry_set_text(GTK_ENTRY(entry), str);
314 gtk_widget_show(entry);
315 gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
316 return entry;
317 }
318
319 static const gchar *get_file_entry_path(GtkWidget *entry)
320 {
321 return gtk_entry_get_text(GTK_ENTRY(entry));
322 }
323
324 static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_item, GtkSignalFunc func)
325 {
326 GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id));
327 gtk_widget_show(button);
328 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), PrefsFindBool(prefs_item));
329 gtk_signal_connect(GTK_OBJECT(button), "toggled", func, button);
330 gtk_box_pack_start(GTK_BOX(top), button, FALSE, FALSE, 0);
331 return button;
332 }
333
334 static GtkWidget *make_combobox(GtkWidget *top, int label_id, const char *default_value, GList *glist)
335 {
336 GtkWidget *box, *label, *combo;
337
338 box = gtk_hbox_new(FALSE, 4);
339 gtk_widget_show(box);
340 gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0);
341
342 label = gtk_label_new(GetString(label_id));
343 gtk_widget_show(label);
344 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
345
346 combo = gtk_combo_new();
347 gtk_widget_show(combo);
348 gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
349
350 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), default_value);
351 gtk_box_pack_start(GTK_BOX(box), combo, TRUE, TRUE, 0);
352
353 return combo;
354 }
355
356 static GtkWidget *make_combobox(GtkWidget *top, int label_id, const char *default_value, const combo_desc *options)
357 {
358 GList *glist = NULL;
359 while (options->label_id) {
360 glist = g_list_append(glist, (void *)GetString(options->label_id));
361 options++;
362 }
363
364 return make_combobox(top, label_id, default_value, glist);
365 }
366
367
368 /*
369 * Show preferences editor
370 * Returns true when user clicked on "Start", false otherwise
371 */
372
373 // Window closed
374 static gint window_closed(void)
375 {
376 return FALSE;
377 }
378
379 // Window destroyed
380 static void window_destroyed(void)
381 {
382 gtk_main_quit();
383 }
384
385 // "Start" button clicked
386 static void cb_start(...)
387 {
388 start_clicked = true;
389 read_settings();
390 SavePrefs();
391 gtk_widget_destroy(win);
392 }
393
394 // "Zap PRAM" button clicked
395 static void cb_zap_pram(...)
396 {
397 ZapPRAM();
398 }
399
400 // "Quit" button clicked
401 static void cb_quit(...)
402 {
403 start_clicked = false;
404 gtk_widget_destroy(win);
405 }
406
407 // "OK" button of "About" dialog clicked
408 static void dl_quit(GtkWidget *dialog)
409 {
410 gtk_widget_destroy(dialog);
411 }
412
413 // "About" button clicked
414 static void cb_about(...)
415 {
416 GtkWidget *dialog;
417
418 GtkWidget *label, *button;
419
420 char str[512];
421 sprintf(str,
422 PROGRAM_NAME "\nVersion %d.%d\n\n"
423 "Copyright (C) 1997-2005 Christian Bauer et al.\n"
424 "E-mail: cb@cebix.net\n"
425 #ifdef SHEEPSHAVER
426 "http://sheepshaver.cebix.net/\n\n"
427 #else
428 "http://basilisk.cebix.net/\n\n"
429 #endif
430 PROGRAM_NAME " comes with ABSOLUTELY NO\n"
431 "WARRANTY. This is free software, and\n"
432 "you are welcome to redistribute it\n"
433 "under the terms of the GNU General\n"
434 "Public License.\n",
435 VERSION_MAJOR, VERSION_MINOR
436 );
437
438 dialog = gtk_dialog_new();
439 gtk_window_set_title(GTK_WINDOW(dialog), GetString(STR_ABOUT_TITLE));
440 gtk_container_border_width(GTK_CONTAINER(dialog), 5);
441 gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150);
442
443 label = gtk_label_new(str);
444 gtk_widget_show(label);
445 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
446
447 button = gtk_button_new_with_label(GetString(STR_OK_BUTTON));
448 gtk_widget_show(button);
449 gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog));
450 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0);
451 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
452 gtk_widget_grab_default(button);
453
454 gtk_widget_show(dialog);
455 }
456
457 // Menu item descriptions
458 static GtkItemFactoryEntry menu_items[] = {
459 {(gchar *)GetString(STR_PREFS_MENU_FILE_GTK), NULL, NULL, 0, "<Branch>"},
460 {(gchar *)GetString(STR_PREFS_ITEM_START_GTK), "<control>S", GTK_SIGNAL_FUNC(cb_start), 0, NULL},
461 {(gchar *)GetString(STR_PREFS_ITEM_ZAP_PRAM_GTK), NULL, GTK_SIGNAL_FUNC(cb_zap_pram), 0, NULL},
462 {(gchar *)GetString(STR_PREFS_ITEM_SEPL_GTK), NULL, NULL, 0, "<Separator>"},
463 {(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK), "<control>Q", GTK_SIGNAL_FUNC(cb_quit), 0, NULL},
464 {(gchar *)GetString(STR_HELP_MENU_GTK), NULL, NULL, 0, "<LastBranch>"},
465 {(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK), "<control>H", GTK_SIGNAL_FUNC(cb_about), 0, NULL}
466 };
467
468 void PrefsMigrate(void)
469 {
470 // Ethernet
471 const char *ether = PrefsFindString("ether");
472 if (ether && ether[0] == '{') {
473 PrefsReplaceString("etherguid", ether);
474 PrefsReplaceString("ether", "b2ether");
475 }
476 if (PrefsFindBool("routerenabled")) {
477 PrefsRemoveItem("etherguid");
478 PrefsReplaceString("ether", "router");
479 }
480 }
481
482 bool PrefsEditor(void)
483 {
484 // Create window
485 win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
486 gtk_window_set_title(GTK_WINDOW(win), GetString(STR_PREFS_TITLE));
487 gtk_signal_connect(GTK_OBJECT(win), "delete_event", GTK_SIGNAL_FUNC(window_closed), NULL);
488 gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(window_destroyed), NULL);
489
490 // Create window contents
491 GtkWidget *box = gtk_vbox_new(FALSE, 4);
492 gtk_widget_show(box);
493 gtk_container_add(GTK_CONTAINER(win), box);
494
495 GtkAccelGroup *accel_group = gtk_accel_group_new();
496 GtkItemFactory *item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
497 gtk_item_factory_create_items(item_factory, sizeof(menu_items) / sizeof(menu_items[0]), menu_items, NULL);
498 #if GTK_CHECK_VERSION(1,3,15)
499 gtk_window_add_accel_group(GTK_WINDOW(win), accel_group);
500 #else
501 gtk_accel_group_attach(accel_group, GTK_OBJECT(win));
502 #endif
503 GtkWidget *menu_bar = gtk_item_factory_get_widget(item_factory, "<main>");
504 gtk_widget_show(menu_bar);
505 gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, TRUE, 0);
506
507 GtkWidget *notebook = gtk_notebook_new();
508 gtk_widget_show(notebook);
509 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
510 gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), FALSE);
511 gtk_box_pack_start(GTK_BOX(box), notebook, TRUE, TRUE, 0);
512
513 create_volumes_pane(notebook);
514 #ifndef DISABLE_SCSI
515 create_scsi_pane(notebook);
516 #endif
517 create_graphics_pane(notebook);
518 create_input_pane(notebook);
519 create_serial_pane(notebook);
520 create_ethernet_pane(notebook);
521 create_memory_pane(notebook);
522 create_jit_pane(notebook);
523
524 static const opt_desc buttons[] = {
525 {STR_START_BUTTON, GTK_SIGNAL_FUNC(cb_start)},
526 {STR_QUIT_BUTTON, GTK_SIGNAL_FUNC(cb_quit)},
527 {0, NULL}
528 };
529 make_button_box(box, 4, buttons);
530
531 // Show window and enter main loop
532 gtk_widget_show(win);
533 gtk_main();
534 return start_clicked;
535 }
536
537
538 /*
539 * "Volumes" pane
540 */
541
542 static GtkWidget *w_enableextfs, *w_extdrives, *w_cdrom_drive;
543 static GtkWidget *volume_list;
544 static int selected_volume;
545
546 // Set sensitivity of widgets
547 static void set_volumes_sensitive(void)
548 {
549 const bool enable_extfs = PrefsFindBool("enableextfs");
550 gtk_widget_set_sensitive(w_extdrives, enable_extfs);
551 const bool no_cdrom = PrefsFindBool("nocdrom");
552 gtk_widget_set_sensitive(w_cdrom_drive, !no_cdrom);
553 }
554
555 // Volume in list selected
556 static void cl_selected(GtkWidget *list, int row, int column)
557 {
558 selected_volume = row;
559 }
560
561 // Volume selected for addition
562 static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc)
563 {
564 gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
565 gtk_clist_append(GTK_CLIST(volume_list), &file);
566 gtk_widget_destroy(assoc->req);
567 delete assoc;
568 }
569
570 // Volume selected for creation
571 static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc)
572 {
573 gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
574
575 const gchar *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry));
576 size_t size = atoi(str) << 20;
577
578 int fd = _open(file, _O_WRONLY | _O_CREAT | _O_BINARY | _O_TRUNC, _S_IREAD | _S_IWRITE);
579 if (fd >= 0) {
580 if (_chsize(fd, size) == 0)
581 gtk_clist_append(GTK_CLIST(volume_list), &file);
582 _close(fd);
583 }
584 gtk_widget_destroy(GTK_WIDGET(assoc->req));
585 delete assoc;
586 }
587
588 // "Add Volume" button clicked
589 static void cb_add_volume(...)
590 {
591 GtkWidget *req = gtk_file_selection_new(GetString(STR_ADD_VOLUME_TITLE));
592 gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
593 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(add_volume_ok), new file_req_assoc(req, NULL));
594 gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
595 gtk_widget_show(req);
596 }
597
598 // "Create Hardfile" button clicked
599 static void cb_create_volume(...)
600 {
601 GtkWidget *req = gtk_file_selection_new(GetString(STR_CREATE_VOLUME_TITLE));
602
603 GtkWidget *box = gtk_hbox_new(FALSE, 4);
604 gtk_widget_show(box);
605 GtkWidget *label = gtk_label_new(GetString(STR_HARDFILE_SIZE_CTRL));
606 gtk_widget_show(label);
607 GtkWidget *entry = gtk_entry_new();
608 gtk_widget_show(entry);
609 char str[32];
610 sprintf(str, "%d", 40);
611 gtk_entry_set_text(GTK_ENTRY(entry), str);
612 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
613 gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0);
614 gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(req)->main_vbox), box, FALSE, FALSE, 0);
615
616 gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
617 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(create_volume_ok), new file_req_assoc(req, entry));
618 gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
619 gtk_widget_show(req);
620 }
621
622 // "Remove Volume" button clicked
623 static void cb_remove_volume(...)
624 {
625 gtk_clist_remove(GTK_CLIST(volume_list), selected_volume);
626 }
627
628 // "Boot From" selected
629 static void mn_boot_any(...) {PrefsReplaceInt32("bootdriver", 0);}
630 static void mn_boot_cdrom(...) {PrefsReplaceInt32("bootdriver", CDROMRefNum);}
631
632 // "Enable external file system" button toggled
633 static void tb_enableextfs(GtkWidget *widget)
634 {
635 PrefsReplaceBool("enableextfs", GTK_TOGGLE_BUTTON(widget)->active);
636 set_volumes_sensitive();
637 }
638
639 // "No CD-ROM Driver" button toggled
640 static void tb_nocdrom(GtkWidget *widget)
641 {
642 PrefsReplaceBool("nocdrom", GTK_TOGGLE_BUTTON(widget)->active);
643 set_volumes_sensitive();
644 }
645
646 // Add names of CD-ROM devices
647 static GList *add_cdrom_names(void)
648 {
649 GList *glist = NULL;
650
651 char rootdir[4] = "X:\\";
652 for (char letter = 'C'; letter <= 'Z'; letter++) {
653 rootdir[0] = letter;
654 if (GetDriveType(rootdir) == DRIVE_CDROM)
655 glist = g_list_append(glist, strdup(rootdir));
656 }
657
658 return glist;
659 }
660
661 // "Enable polling" button toggled
662 static void tb_pollmedia(GtkWidget *widget)
663 {
664 PrefsReplaceBool("pollmedia", GTK_TOGGLE_BUTTON(widget)->active);
665 }
666
667 // Read settings from widgets and set preferences
668 static void read_volumes_settings(void)
669 {
670 while (PrefsFindString("disk"))
671 PrefsRemoveItem("disk");
672
673 for (int i=0; i<GTK_CLIST(volume_list)->rows; i++) {
674 char *str;
675 gtk_clist_get_text(GTK_CLIST(volume_list), i, 0, &str);
676 PrefsAddString("disk", str);
677 }
678
679 const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_cdrom_drive)->entry));
680 if (str && strlen(str))
681 PrefsReplaceString("cdrom", str);
682 else
683 PrefsRemoveItem("cdrom");
684
685 PrefsReplaceString("extdrives", get_file_entry_path(w_extdrives));
686 }
687
688 // Create "Volumes" pane
689 static void create_volumes_pane(GtkWidget *top)
690 {
691 GtkWidget *box, *scroll, *menu;
692
693 box = make_pane(top, STR_VOLUMES_PANE_TITLE);
694
695 scroll = gtk_scrolled_window_new(NULL, NULL);
696 gtk_widget_show(scroll);
697 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
698 volume_list = gtk_clist_new(1);
699 gtk_widget_show(volume_list);
700 gtk_clist_set_selection_mode(GTK_CLIST(volume_list), GTK_SELECTION_SINGLE);
701 gtk_clist_set_shadow_type(GTK_CLIST(volume_list), GTK_SHADOW_NONE);
702 gtk_clist_set_reorderable(GTK_CLIST(volume_list), true);
703 gtk_signal_connect(GTK_OBJECT(volume_list), "select_row", GTK_SIGNAL_FUNC(cl_selected), NULL);
704 char *str;
705 int32 index = 0;
706 while ((str = const_cast<char *>(PrefsFindString("disk", index++))) != NULL)
707 gtk_clist_append(GTK_CLIST(volume_list), &str);
708 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), volume_list);
709 gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 0);
710 selected_volume = 0;
711
712 static const opt_desc buttons[] = {
713 {STR_ADD_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_add_volume)},
714 {STR_CREATE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_create_volume)},
715 {STR_REMOVE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_remove_volume)},
716 {0, NULL},
717 };
718 make_button_box(box, 0, buttons);
719 make_separator(box);
720
721 static const opt_desc options[] = {
722 {STR_BOOT_ANY_LAB, GTK_SIGNAL_FUNC(mn_boot_any)},
723 {STR_BOOT_CDROM_LAB, GTK_SIGNAL_FUNC(mn_boot_cdrom)},
724 {0, NULL}
725 };
726 int bootdriver = PrefsFindInt32("bootdriver"), active = 0;
727 switch (bootdriver) {
728 case 0: active = 0; break;
729 case CDROMRefNum: active = 1; break;
730 }
731 menu = make_option_menu(box, STR_BOOTDRIVER_CTRL, options, active);
732
733 make_checkbox(box, STR_NOCDROM_CTRL, "nocdrom", GTK_SIGNAL_FUNC(tb_nocdrom));
734
735 GList *glist = add_cdrom_names();
736 str = const_cast<char *>(PrefsFindString("cdrom"));
737 if (str == NULL)
738 str = "";
739 w_cdrom_drive = make_combobox(box, STR_CDROM_DRIVE_CTRL, str, glist);
740
741 make_checkbox(box, STR_POLLMEDIA_CTRL, "pollmedia", GTK_SIGNAL_FUNC(tb_pollmedia));
742
743 make_separator(box);
744 w_enableextfs = make_checkbox(box, STR_EXTFS_ENABLE_CTRL, "enableextfs", GTK_SIGNAL_FUNC(tb_enableextfs));
745 w_extdrives = make_file_entry(box, STR_EXTFS_DRIVES_CTRL, "extdrives", true);
746
747 set_volumes_sensitive();
748 }
749
750
751 /*
752 * "JIT Compiler" pane
753 */
754
755 #ifndef SHEEPSHAVER
756 static GtkWidget *w_jit_fpu;
757 static GtkWidget *w_jit_atraps;
758 static GtkWidget *w_jit_cache_size;
759 static GtkWidget *w_jit_lazy_flush;
760 static GtkWidget *w_jit_follow_const_jumps;
761 #endif
762
763 // Set sensitivity of widgets
764 static void set_jit_sensitive(void)
765 {
766 #ifndef SHEEPSHAVER
767 const bool jit_enabled = PrefsFindBool("jit");
768 gtk_widget_set_sensitive(w_jit_fpu, jit_enabled);
769 gtk_widget_set_sensitive(w_jit_cache_size, jit_enabled);
770 gtk_widget_set_sensitive(w_jit_lazy_flush, jit_enabled);
771 gtk_widget_set_sensitive(w_jit_follow_const_jumps, jit_enabled);
772 #endif
773 }
774
775 // "Use JIT Compiler" button toggled
776 static void tb_jit(GtkWidget *widget)
777 {
778 PrefsReplaceBool("jit", GTK_TOGGLE_BUTTON(widget)->active);
779 set_jit_sensitive();
780 }
781
782 // "Compile FPU Instructions" button toggled
783 #ifndef SHEEPSHAVER
784 static void tb_jit_fpu(GtkWidget *widget)
785 {
786 PrefsReplaceBool("jitfpu", GTK_TOGGLE_BUTTON(widget)->active);
787 }
788 #endif
789
790 // "Lazy translation cache invalidation" button toggled
791 #ifndef SHEEPSHAVER
792 static void tb_jit_lazy_flush(GtkWidget *widget)
793 {
794 PrefsReplaceBool("jitlazyflush", GTK_TOGGLE_BUTTON(widget)->active);
795 }
796 #endif
797
798 // "Translate through constant jumps (inline blocks)" button toggled
799 #ifndef SHEEPSHAVER
800 static void tb_jit_follow_const_jumps(GtkWidget *widget)
801 {
802 PrefsReplaceBool("jitinline", GTK_TOGGLE_BUTTON(widget)->active);
803 }
804 #endif
805
806 // Read settings from widgets and set preferences
807 static void read_jit_settings(void)
808 {
809 #if USE_JIT
810 bool jit_enabled = PrefsFindBool("jit");
811 if (jit_enabled) {
812 #ifndef SHEEPSHAVER
813 const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_jit_cache_size)->entry));
814 PrefsReplaceInt32("jitcachesize", atoi(str));
815 #endif
816 }
817 #endif
818 }
819
820 // "Use built-in 68k DR emulator" button toggled
821 #ifdef SHEEPSHAVER
822 static void tb_jit_68k(GtkWidget *widget)
823 {
824 PrefsReplaceBool("jit68k", GTK_TOGGLE_BUTTON(widget)->active);
825 }
826 #endif
827
828 // Create "JIT Compiler" pane
829 static void create_jit_pane(GtkWidget *top)
830 {
831 #if USE_JIT
832 GtkWidget *box, *table, *label, *menu;
833 char str[32];
834
835 box = make_pane(top, STR_JIT_PANE_TITLE);
836 make_checkbox(box, STR_JIT_CTRL, "jit", GTK_SIGNAL_FUNC(tb_jit));
837
838 #ifndef SHEEPSHAVER
839 w_jit_fpu = make_checkbox(box, STR_JIT_FPU_CTRL, "jitfpu", GTK_SIGNAL_FUNC(tb_jit_fpu));
840
841 // Translation cache size
842 static const combo_desc options[] = {
843 STR_JIT_CACHE_SIZE_2MB_LAB,
844 STR_JIT_CACHE_SIZE_4MB_LAB,
845 STR_JIT_CACHE_SIZE_8MB_LAB,
846 STR_JIT_CACHE_SIZE_16MB_LAB,
847 0
848 };
849 sprintf(str, "%d", PrefsFindInt32("jitcachesize"));
850 w_jit_cache_size = make_combobox(box, STR_JIT_CACHE_SIZE_CTRL, str, options);
851
852 // Lazy translation cache invalidation
853 w_jit_lazy_flush = make_checkbox(box, STR_JIT_LAZY_CINV_CTRL, "jitlazyflush", GTK_SIGNAL_FUNC(tb_jit_lazy_flush));
854
855 // Follow constant jumps (inline basic blocks)
856 w_jit_follow_const_jumps = make_checkbox(box, STR_JIT_FOLLOW_CONST_JUMPS, "jitinline", GTK_SIGNAL_FUNC(tb_jit_follow_const_jumps));
857 #endif
858
859 set_jit_sensitive();
860 #endif
861
862 #ifdef SHEEPSHAVER
863 make_checkbox(box, STR_JIT_68K_CTRL, "jit68k", GTK_SIGNAL_FUNC(tb_jit_68k));
864 #endif
865 }
866
867 /*
868 * "SCSI" pane
869 */
870
871 static GtkWidget *w_scsi[7];
872
873 // Read settings from widgets and set preferences
874 static void read_scsi_settings(void)
875 {
876 #ifndef DISABLE_SCSI
877 for (int id=0; id<7; id++) {
878 char prefs_name[32];
879 sprintf(prefs_name, "scsi%d", id);
880 const char *str = get_file_entry_path(w_scsi[id]);
881 if (str && strlen(str))
882 PrefsReplaceString(prefs_name, str);
883 else
884 PrefsRemoveItem(prefs_name);
885 }
886 #endif
887 }
888
889 // Create "SCSI" pane
890 static void create_scsi_pane(GtkWidget *top)
891 {
892 #ifndef DISABLE_SCSI
893 GtkWidget *box;
894
895 box = make_pane(top, STR_SCSI_PANE_TITLE);
896
897 for (int id=0; id<7; id++) {
898 char prefs_name[32];
899 sprintf(prefs_name, "scsi%d", id);
900 w_scsi[id] = make_file_entry(box, STR_SCSI_ID_0 + id, prefs_name);
901 }
902 #endif
903 }
904
905
906 /*
907 * "Graphics/Sound" pane
908 */
909
910 // Display types
911 enum {
912 DISPLAY_WINDOW,
913 DISPLAY_SCREEN
914 };
915
916 static GtkWidget *w_frameskip, *w_display_x, *w_display_y;
917 static GtkWidget *l_frameskip, *l_display_x, *l_display_y;
918 static int display_type;
919 static int dis_width, dis_height;
920
921 // Hide/show graphics widgets
922 static void hide_show_graphics_widgets(void)
923 {
924 switch (display_type) {
925 case DISPLAY_WINDOW:
926 gtk_widget_show(w_frameskip); gtk_widget_show(l_frameskip);
927 break;
928 case DISPLAY_SCREEN:
929 gtk_widget_hide(w_frameskip); gtk_widget_hide(l_frameskip);
930 break;
931 }
932 }
933
934 // "Window" video type selected
935 static void mn_window(...)
936 {
937 display_type = DISPLAY_WINDOW;
938 hide_show_graphics_widgets();
939 }
940
941 // "Fullscreen" video type selected
942 static void mn_fullscreen(...)
943 {
944 display_type = DISPLAY_SCREEN;
945 hide_show_graphics_widgets();
946 PrefsReplaceInt32("frameskip", 1);
947 }
948
949 // "5 Hz".."60Hz" selected
950 static void mn_5hz(...) {PrefsReplaceInt32("frameskip", 12);}
951 static void mn_7hz(...) {PrefsReplaceInt32("frameskip", 8);}
952 static void mn_10hz(...) {PrefsReplaceInt32("frameskip", 6);}
953 static void mn_15hz(...) {PrefsReplaceInt32("frameskip", 4);}
954 static void mn_30hz(...) {PrefsReplaceInt32("frameskip", 2);}
955 static void mn_60hz(...) {PrefsReplaceInt32("frameskip", 1);}
956 static void mn_dynamic(...) {PrefsReplaceInt32("frameskip", 0);}
957
958 // QuickDraw acceleration
959 #ifdef SHEEPSHAVER
960 static void tb_gfxaccel(GtkWidget *widget)
961 {
962 PrefsReplaceBool("gfxaccel", GTK_TOGGLE_BUTTON(widget)->active);
963 }
964 #endif
965
966 // Set sensitivity of widgets
967 static void set_graphics_sensitive(void)
968 {
969 const bool sound_enabled = !PrefsFindBool("nosound");
970 }
971
972 // "Disable Sound Output" button toggled
973 static void tb_nosound(GtkWidget *widget)
974 {
975 PrefsReplaceBool("nosound", GTK_TOGGLE_BUTTON(widget)->active);
976 set_graphics_sensitive();
977 }
978
979 // Read graphics preferences
980 static void parse_graphics_prefs(void)
981 {
982 display_type = DISPLAY_WINDOW;
983 #ifdef SHEEPSHAVER
984 dis_width = 640;
985 dis_height = 480;
986 #else
987 dis_width = 512;
988 dis_height = 384;
989 #endif
990
991 const char *str = PrefsFindString("screen");
992 if (str) {
993 if (sscanf(str, "win/%d/%d", &dis_width, &dis_height) == 2)
994 display_type = DISPLAY_WINDOW;
995 else if (sscanf(str, "dga/%d/%d", &dis_width, &dis_height) == 2)
996 display_type = DISPLAY_SCREEN;
997 }
998 }
999
1000 // Read settings from widgets and set preferences
1001 static void read_graphics_settings(void)
1002 {
1003 const char *str;
1004
1005 str = gtk_entry_get_text(GTK_ENTRY(w_display_x));
1006 dis_width = atoi(str);
1007
1008 str = gtk_entry_get_text(GTK_ENTRY(w_display_y));
1009 dis_height = atoi(str);
1010
1011 char pref[256];
1012 switch (display_type) {
1013 case DISPLAY_WINDOW:
1014 sprintf(pref, "win/%d/%d", dis_width, dis_height);
1015 break;
1016 case DISPLAY_SCREEN:
1017 sprintf(pref, "dga/%d/%d", dis_width, dis_height);
1018 break;
1019 default:
1020 PrefsRemoveItem("screen");
1021 return;
1022 }
1023 PrefsReplaceString("screen", pref);
1024 }
1025
1026 // Create "Graphics/Sound" pane
1027 static void create_graphics_pane(GtkWidget *top)
1028 {
1029 GtkWidget *box, *table, *label, *opt, *menu, *combo;
1030 char str[32];
1031
1032 parse_graphics_prefs();
1033
1034 box = make_pane(top, STR_GRAPHICS_SOUND_PANE_TITLE);
1035 table = make_table(box, 2, 5);
1036
1037 label = gtk_label_new(GetString(STR_VIDEO_TYPE_CTRL));
1038 gtk_widget_show(label);
1039 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1040
1041 opt = gtk_option_menu_new();
1042 gtk_widget_show(opt);
1043 menu = gtk_menu_new();
1044 add_menu_item(menu, STR_WINDOW_LAB, GTK_SIGNAL_FUNC(mn_window));
1045 add_menu_item(menu, STR_FULLSCREEN_LAB, GTK_SIGNAL_FUNC(mn_fullscreen));
1046 switch (display_type) {
1047 case DISPLAY_WINDOW:
1048 gtk_menu_set_active(GTK_MENU(menu), 0);
1049 break;
1050 case DISPLAY_SCREEN:
1051 gtk_menu_set_active(GTK_MENU(menu), 1);
1052 break;
1053 }
1054 gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
1055 gtk_table_attach(GTK_TABLE(table), opt, 1, 2, 0, 1, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
1056
1057 l_frameskip = gtk_label_new(GetString(STR_FRAMESKIP_CTRL));
1058 gtk_widget_show(l_frameskip);
1059 gtk_table_attach(GTK_TABLE(table), l_frameskip, 0, 1, 1, 2, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1060
1061 w_frameskip = gtk_option_menu_new();
1062 gtk_widget_show(w_frameskip);
1063 menu = gtk_menu_new();
1064 add_menu_item(menu, STR_REF_5HZ_LAB, GTK_SIGNAL_FUNC(mn_5hz));
1065 add_menu_item(menu, STR_REF_7_5HZ_LAB, GTK_SIGNAL_FUNC(mn_7hz));
1066 add_menu_item(menu, STR_REF_10HZ_LAB, GTK_SIGNAL_FUNC(mn_10hz));
1067 add_menu_item(menu, STR_REF_15HZ_LAB, GTK_SIGNAL_FUNC(mn_15hz));
1068 add_menu_item(menu, STR_REF_30HZ_LAB, GTK_SIGNAL_FUNC(mn_30hz));
1069 add_menu_item(menu, STR_REF_60HZ_LAB, GTK_SIGNAL_FUNC(mn_60hz));
1070 add_menu_item(menu, STR_REF_DYNAMIC_LAB, GTK_SIGNAL_FUNC(mn_dynamic));
1071 int frameskip = PrefsFindInt32("frameskip");
1072 int item = -1;
1073 switch (frameskip) {
1074 case 12: item = 0; break;
1075 case 8: item = 1; break;
1076 case 6: item = 2; break;
1077 case 4: item = 3; break;
1078 case 2: item = 4; break;
1079 case 1: item = 5; break;
1080 case 0: item = 6; break;
1081 }
1082 if (item >= 0)
1083 gtk_menu_set_active(GTK_MENU(menu), item);
1084 gtk_option_menu_set_menu(GTK_OPTION_MENU(w_frameskip), menu);
1085 gtk_table_attach(GTK_TABLE(table), w_frameskip, 1, 2, 1, 2, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
1086
1087 l_display_x = gtk_label_new(GetString(STR_DISPLAY_X_CTRL));
1088 gtk_widget_show(l_display_x);
1089 gtk_table_attach(GTK_TABLE(table), l_display_x, 0, 1, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1090
1091 combo = gtk_combo_new();
1092 gtk_widget_show(combo);
1093 GList *glist1 = NULL;
1094 glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_512_LAB));
1095 glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_640_LAB));
1096 glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_800_LAB));
1097 glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_1024_LAB));
1098 glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_MAX_LAB));
1099 gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist1);
1100 if (dis_width)
1101 sprintf(str, "%d", dis_width);
1102 else
1103 strcpy(str, GetString(STR_SIZE_MAX_LAB));
1104 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
1105 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 2, 3, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
1106 w_display_x = GTK_COMBO(combo)->entry;
1107
1108 l_display_y = gtk_label_new(GetString(STR_DISPLAY_Y_CTRL));
1109 gtk_widget_show(l_display_y);
1110 gtk_table_attach(GTK_TABLE(table), l_display_y, 0, 1, 3, 4, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1111
1112 combo = gtk_combo_new();
1113 gtk_widget_show(combo);
1114 GList *glist2 = NULL;
1115 glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_384_LAB));
1116 glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_480_LAB));
1117 glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_600_LAB));
1118 glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_768_LAB));
1119 glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_MAX_LAB));
1120 gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist2);
1121 if (dis_height)
1122 sprintf(str, "%d", dis_height);
1123 else
1124 strcpy(str, GetString(STR_SIZE_MAX_LAB));
1125 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
1126 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 3, 4, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
1127 w_display_y = GTK_COMBO(combo)->entry;
1128
1129 #ifdef SHEEPSHAVER
1130 make_checkbox(box, STR_GFXACCEL_CTRL, "gfxaccel", GTK_SIGNAL_FUNC(tb_gfxaccel));
1131 #endif
1132
1133 make_separator(box);
1134 make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound));
1135
1136 set_graphics_sensitive();
1137
1138 hide_show_graphics_widgets();
1139 }
1140
1141
1142 /*
1143 * "Input" pane
1144 */
1145
1146 static GtkWidget *w_keycode_file;
1147 static GtkWidget *w_mouse_wheel_lines;
1148
1149 // Set sensitivity of widgets
1150 static void set_input_sensitive(void)
1151 {
1152 const bool use_keycodes = PrefsFindBool("keycodes");
1153 gtk_widget_set_sensitive(w_keycode_file, use_keycodes);
1154 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_keycode_file), "chooser_button")), use_keycodes);
1155 gtk_widget_set_sensitive(w_mouse_wheel_lines, PrefsFindInt32("mousewheelmode") == 1);
1156 }
1157
1158 // "Use Raw Keycodes" button toggled
1159 static void tb_keycodes(GtkWidget *widget)
1160 {
1161 PrefsReplaceBool("keycodes", GTK_TOGGLE_BUTTON(widget)->active);
1162 set_input_sensitive();
1163 }
1164
1165 // "Mouse Wheel Mode" selected
1166 static void mn_wheel_page(...) {PrefsReplaceInt32("mousewheelmode", 0); set_input_sensitive();}
1167 static void mn_wheel_cursor(...) {PrefsReplaceInt32("mousewheelmode", 1); set_input_sensitive();}
1168
1169 // Read settings from widgets and set preferences
1170 static void read_input_settings(void)
1171 {
1172 const char *str = get_file_entry_path(w_keycode_file);
1173 if (str && strlen(str))
1174 PrefsReplaceString("keycodefile", str);
1175 else
1176 PrefsRemoveItem("keycodefile");
1177
1178 PrefsReplaceInt32("mousewheellines", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(w_mouse_wheel_lines)));
1179 }
1180
1181 // Create "Input" pane
1182 static void create_input_pane(GtkWidget *top)
1183 {
1184 GtkWidget *box, *hbox, *menu, *label, *button;
1185 GtkObject *adj;
1186
1187 box = make_pane(top, STR_INPUT_PANE_TITLE);
1188
1189 make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes));
1190
1191 hbox = gtk_hbox_new(FALSE, 4);
1192 gtk_widget_show(hbox);
1193 gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1194
1195 label = gtk_label_new(GetString(STR_KEYCODES_CTRL));
1196 gtk_widget_show(label);
1197 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1198
1199 const char *str = PrefsFindString("keycodefile");
1200 if (str == NULL)
1201 str = "";
1202
1203 w_keycode_file = gtk_entry_new();
1204 gtk_entry_set_text(GTK_ENTRY(w_keycode_file), str);
1205 gtk_widget_show(w_keycode_file);
1206 gtk_box_pack_start(GTK_BOX(hbox), w_keycode_file, TRUE, TRUE, 0);
1207
1208 button = make_browse_button(w_keycode_file);
1209 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1210 g_object_set_data(G_OBJECT(w_keycode_file), "chooser_button", button);
1211
1212 make_separator(box);
1213
1214 static const opt_desc options[] = {
1215 {STR_MOUSEWHEELMODE_PAGE_LAB, GTK_SIGNAL_FUNC(mn_wheel_page)},
1216 {STR_MOUSEWHEELMODE_CURSOR_LAB, GTK_SIGNAL_FUNC(mn_wheel_cursor)},
1217 {0, NULL}
1218 };
1219 int wheelmode = PrefsFindInt32("mousewheelmode"), active = 0;
1220 switch (wheelmode) {
1221 case 0: active = 0; break;
1222 case 1: active = 1; break;
1223 }
1224 menu = make_option_menu(box, STR_MOUSEWHEELMODE_CTRL, options, active);
1225
1226 hbox = gtk_hbox_new(FALSE, 4);
1227 gtk_widget_show(hbox);
1228 gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1229
1230 label = gtk_label_new(GetString(STR_MOUSEWHEELLINES_CTRL));
1231 gtk_widget_show(label);
1232 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1233
1234 adj = gtk_adjustment_new(PrefsFindInt32("mousewheellines"), 1, 1000, 1, 5, 0);
1235 w_mouse_wheel_lines = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 0.0, 0);
1236 gtk_widget_show(w_mouse_wheel_lines);
1237 gtk_box_pack_start(GTK_BOX(hbox), w_mouse_wheel_lines, FALSE, FALSE, 0);
1238
1239 set_input_sensitive();
1240 }
1241
1242
1243 /*
1244 * "Serial" pane
1245 */
1246
1247 static GtkWidget *w_seriala, *w_portfile0;
1248 static GtkWidget *w_serialb, *w_portfile1;
1249
1250 // Set sensitivity of widgets
1251 static void set_serial_sensitive(void)
1252 {
1253 const char *str;
1254 bool is_file;
1255
1256 str = gtk_entry_get_text(GTK_ENTRY(w_seriala));
1257 is_file = strcmp(str, "FILE") == 0;
1258 gtk_widget_set_sensitive(w_portfile0, is_file);
1259 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_portfile0), "chooser_button")), is_file);
1260
1261 str = gtk_entry_get_text(GTK_ENTRY(w_serialb));
1262 is_file = strcmp(str, "FILE") == 0;
1263 gtk_widget_set_sensitive(w_portfile1, is_file);
1264 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_portfile1), "chooser_button")), is_file);
1265 }
1266
1267 // Read settings from widgets and set preferences
1268 static void read_serial_settings(void)
1269 {
1270 const char *str;
1271
1272 str = gtk_entry_get_text(GTK_ENTRY(w_seriala));
1273 PrefsReplaceString("seriala", str);
1274
1275 str = gtk_entry_get_text(GTK_ENTRY(w_serialb));
1276 PrefsReplaceString("serialb", str);
1277
1278 str = gtk_entry_get_text(GTK_ENTRY(w_portfile0));
1279 PrefsReplaceString("portfile0", str);
1280
1281 str = gtk_entry_get_text(GTK_ENTRY(w_portfile1));
1282 PrefsReplaceString("portfile1", str);
1283 }
1284
1285 // Port changed in combo
1286 static void cb_serial_port_changed(...)
1287 {
1288 set_serial_sensitive();
1289 }
1290
1291 // Add names of serial devices
1292 static GList *add_serial_names(void)
1293 {
1294 GList *glist = NULL;
1295
1296 static const char *port_names[] = {
1297 "COM1", "COM2", "COM3", "COM4", "COM5", "COM6",
1298 "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6",
1299 "FILE",
1300 NULL
1301 };
1302
1303 for (int i = 0; port_names[i] != NULL; i++)
1304 glist = g_list_append(glist, (void *)port_names[i]);
1305
1306 return glist;
1307 }
1308
1309 // Create "Serial" pane
1310 static void create_serial_pane(GtkWidget *top)
1311 {
1312 GtkWidget *box, *hbox, *table, *label, *combo, *sep, *entry;
1313 GtkObject *adj;
1314
1315 box = make_pane(top, STR_SERIAL_PANE_TITLE);
1316 table = make_table(box, 2, 5);
1317
1318 GList *glist = add_serial_names();
1319 const char *str = PrefsFindString("seriala");
1320 combo = table_make_combobox(table, 0, STR_SERIALA_CTRL, str, glist);
1321 w_seriala = GTK_COMBO(combo)->entry;
1322 gtk_signal_connect(GTK_OBJECT(w_seriala), "changed", GTK_SIGNAL_FUNC(cb_serial_port_changed), NULL);
1323
1324 w_portfile0 = table_make_file_entry(table, 1, STR_FILE_CTRL, "portfile0");
1325
1326 sep = gtk_hseparator_new();
1327 gtk_widget_show(sep);
1328 gtk_table_attach(GTK_TABLE(table), sep, 0, 2, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1329
1330 str = PrefsFindString("serialb");
1331 combo = table_make_combobox(table, 3, STR_SERIALB_CTRL, str, glist);
1332 w_serialb = GTK_COMBO(combo)->entry;
1333 gtk_signal_connect(GTK_OBJECT(w_serialb), "changed", GTK_SIGNAL_FUNC(cb_serial_port_changed), NULL);
1334
1335 w_portfile1 = table_make_file_entry(table, 4, STR_FILE_CTRL, "portfile1");
1336
1337 set_serial_sensitive();
1338 }
1339
1340
1341 /*
1342 * "Ethernet" pane
1343 */
1344
1345 static GtkWidget *w_ftp_port_list, *w_tcp_port_list;
1346
1347 // Set sensitivity of widgets
1348 static void set_ethernet_sensitive(void)
1349 {
1350 const char *str = PrefsFindString("ether");
1351
1352 bool is_router = str && strcmp(str, "router") == 0;
1353 gtk_widget_set_sensitive(w_ftp_port_list, is_router);
1354 gtk_widget_set_sensitive(w_tcp_port_list, is_router);
1355 }
1356
1357 // Read settings from widgets and set preferences
1358 static void read_ethernet_settings(void)
1359 {
1360 const char *str = PrefsFindString("ether");
1361
1362 bool is_router = str && strcmp(str, "router") == 0;
1363 if (is_router) {
1364 str = gtk_entry_get_text(GTK_ENTRY(w_ftp_port_list));
1365 PrefsReplaceString("ftp_port_list", str);
1366 str = gtk_entry_get_text(GTK_ENTRY(w_tcp_port_list));
1367 PrefsReplaceString("tcp_port", str);
1368 }
1369 }
1370
1371 // Ethernet emulation type changed in menulist
1372 static void cb_ether_changed(...)
1373 {
1374 set_ethernet_sensitive();
1375 }
1376
1377 // Ethernet option "None" selected
1378 static void mn_ether_none(void)
1379 {
1380 PrefsRemoveItem("ether");
1381 PrefsRemoveItem("etherguid");
1382 }
1383
1384 // Ethernet option "Basilisk II Router" selected
1385 static void mn_ether_router(void)
1386 {
1387 PrefsReplaceString("ether", "router");
1388 PrefsRemoveItem("etherguid");
1389 }
1390
1391 // Ethernet option "Basilisk II Slirp" selected
1392 static void mn_ether_slirp(void)
1393 {
1394 PrefsReplaceString("ether", "slirp");
1395 PrefsRemoveItem("etherguid");
1396 }
1397
1398 // Ethernet option for Basilisk II driver selected
1399 static void mn_ether_b2ether(GtkWidget *, const char *guid)
1400 {
1401 PrefsReplaceString("ether", "b2ether");
1402 PrefsReplaceString("etherguid", guid);
1403 }
1404
1405 // Create ethernet interfaces menu
1406 static int create_ether_menu(GtkWidget *menu)
1407 {
1408 int active = -1;
1409 int n_items = 0;
1410 const char *ether = PrefsFindString("ether");
1411 const char *etherguid = PrefsFindString("etherguid");
1412
1413 add_menu_item(menu, STR_NONE_LAB, (GtkSignalFunc)mn_ether_none);
1414 if (ether == NULL)
1415 active = n_items;
1416 n_items++;
1417
1418 add_menu_item(menu, "Basilisk II Router", (GtkSignalFunc)mn_ether_router);
1419 if (ether && strcmp(ether, "router") == 0)
1420 active = n_items;
1421 n_items++;
1422
1423 add_menu_item(menu, "Basilisk II Slirp", (GtkSignalFunc)mn_ether_router);
1424 if (ether && strcmp(ether, "slirp") == 0)
1425 active = n_items;
1426 n_items++;
1427
1428 PacketOpenAdapter("", 0);
1429 {
1430 ULONG sz;
1431 char names[1024];
1432 sz = sizeof(names);
1433 if (PacketGetAdapterNames(NULL, names, &sz) == ERROR_SUCCESS) {
1434 char *p = names;
1435 while (*p) {
1436 const char DEVICE_HEADER[] = "\\Device\\B2ether_";
1437 if (strnicmp(p, DEVICE_HEADER, sizeof(DEVICE_HEADER) - 1) == 0) {
1438 LPADAPTER fd = PacketOpenAdapter(p + sizeof(DEVICE_HEADER) - 1, 0);
1439 if (fd) {
1440 char guid[256];
1441 sprintf(guid, "%s", p + sizeof(DEVICE_HEADER) - 1);
1442 const char *name = ether_guid_to_name(guid);
1443 if (name && (name = g_locale_to_utf8(name, -1, NULL, NULL, NULL))) {
1444 add_menu_item(menu, name, (GtkSignalFunc)mn_ether_b2ether, strdup(guid));
1445 if (etherguid && strcmp(guid, etherguid) == 0 &&
1446 ether && strcmp(ether, "b2ether") == 0)
1447 active = n_items;
1448 n_items++;
1449 }
1450 PacketCloseAdapter(fd);
1451 }
1452 }
1453 p += strlen(p) + 1;
1454 }
1455 }
1456 }
1457 PacketCloseAdapter(NULL);
1458
1459 return active;
1460 }
1461
1462 // Create "Ethernet" pane
1463 static void create_ethernet_pane(GtkWidget *top)
1464 {
1465 GtkWidget *box, *hbox, *table, *label, *sep, *entry, *opt, *menu, *item;
1466
1467 box = make_pane(top, STR_NETWORK_PANE_TITLE);
1468 table = make_table(box, 2, 5);
1469
1470 label = gtk_label_new(GetString(STR_ETHERNET_IF_CTRL));
1471 gtk_widget_show(label);
1472 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1473
1474 opt = gtk_option_menu_new();
1475 gtk_widget_show(opt);
1476 menu = gtk_menu_new();
1477 int active = create_ether_menu(menu);
1478 if (active >= 0)
1479 gtk_menu_set_active(GTK_MENU(menu), active);
1480 gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
1481 gtk_table_attach(GTK_TABLE(table), opt, 1, 2, 0, 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1482 gtk_signal_connect(GTK_OBJECT(opt), "changed", GTK_SIGNAL_FUNC(cb_ether_changed), NULL);
1483
1484 sep = gtk_hseparator_new();
1485 gtk_widget_show(sep);
1486 gtk_table_attach(GTK_TABLE(table), sep, 0, 2, 1, 2, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1487
1488 label = gtk_label_new(GetString(STR_ETHER_FTP_PORT_LIST_CTRL));
1489 gtk_widget_show(label);
1490 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1491
1492 entry = gtk_entry_new();
1493 const char *str = PrefsFindString("ftp_port_list");
1494 if (str == NULL)
1495 str = "";
1496 gtk_entry_set_text(GTK_ENTRY(entry), str);
1497 gtk_widget_show(entry);
1498 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 2, 3, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1499 w_ftp_port_list = entry;
1500
1501 label = gtk_label_new(GetString(STR_ETHER_TCP_PORT_LIST_CTRL));
1502 gtk_widget_show(label);
1503 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1504
1505 entry = gtk_entry_new();
1506 str = PrefsFindString("tcp_port");
1507 if (str == NULL)
1508 str = "";
1509 gtk_entry_set_text(GTK_ENTRY(entry), str);
1510 gtk_widget_show(entry);
1511 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 3, 4, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1512 w_tcp_port_list = entry;
1513
1514 set_ethernet_sensitive();
1515 }
1516
1517
1518 /*
1519 * "Memory/Misc" pane
1520 */
1521
1522 static GtkWidget *w_ramsize;
1523 static GtkWidget *w_rom_file;
1524
1525 // Don't use CPU when idle?
1526 static void tb_idlewait(GtkWidget *widget)
1527 {
1528 PrefsReplaceBool("idlewait", GTK_TOGGLE_BUTTON(widget)->active);
1529 }
1530
1531 // "Ignore SEGV" button toggled
1532 #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
1533 static void tb_ignoresegv(GtkWidget *widget)
1534 {
1535 PrefsReplaceBool("ignoresegv", GTK_TOGGLE_BUTTON(widget)->active);
1536 }
1537 #endif
1538
1539 // Model ID selected
1540 static void mn_modelid_5(...) {PrefsReplaceInt32("modelid", 5);}
1541 static void mn_modelid_14(...) {PrefsReplaceInt32("modelid", 14);}
1542
1543 // CPU/FPU type
1544 static void mn_cpu_68020(...) {PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", false);}
1545 static void mn_cpu_68020_fpu(...) {PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", true);}
1546 static void mn_cpu_68030(...) {PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", false);}
1547 static void mn_cpu_68030_fpu(...) {PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", true);}
1548 static void mn_cpu_68040(...) {PrefsReplaceInt32("cpu", 4); PrefsReplaceBool("fpu", true);}
1549
1550 // Read settings from widgets and set preferences
1551 static void read_memory_settings(void)
1552 {
1553 const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_ramsize)->entry));
1554 PrefsReplaceInt32("ramsize", atoi(str) << 20);
1555
1556 str = get_file_entry_path(w_rom_file);
1557 if (str && strlen(str))
1558 PrefsReplaceString("rom", str);
1559 else
1560 PrefsRemoveItem("rom");
1561
1562 }
1563
1564 // Create "Memory/Misc" pane
1565 static void create_memory_pane(GtkWidget *top)
1566 {
1567 GtkWidget *box, *hbox, *table, *label, *scale, *menu;
1568
1569 box = make_pane(top, STR_MEMORY_MISC_PANE_TITLE);
1570 table = make_table(box, 2, 5);
1571
1572 static const combo_desc options[] = {
1573 #ifndef SHEEPSHAVER
1574 STR_RAMSIZE_2MB_LAB,
1575 #endif
1576 STR_RAMSIZE_4MB_LAB,
1577 STR_RAMSIZE_8MB_LAB,
1578 STR_RAMSIZE_16MB_LAB,
1579 STR_RAMSIZE_32MB_LAB,
1580 STR_RAMSIZE_64MB_LAB,
1581 STR_RAMSIZE_128MB_LAB,
1582 STR_RAMSIZE_256MB_LAB,
1583 STR_RAMSIZE_512MB_LAB,
1584 #ifndef SHEEPSHAVER
1585 STR_RAMSIZE_1024MB_LAB,
1586 #endif
1587 0
1588 };
1589 char default_ramsize[10];
1590 sprintf(default_ramsize, "%d", PrefsFindInt32("ramsize") >> 20);
1591 w_ramsize = table_make_combobox(table, 0, STR_RAMSIZE_CTRL, default_ramsize, options);
1592
1593 #ifndef SHEEPSHAVER
1594 static const opt_desc model_options[] = {
1595 {STR_MODELID_5_LAB, GTK_SIGNAL_FUNC(mn_modelid_5)},
1596 {STR_MODELID_14_LAB, GTK_SIGNAL_FUNC(mn_modelid_14)},
1597 {0, NULL}
1598 };
1599 int modelid = PrefsFindInt32("modelid"), active = 0;
1600 switch (modelid) {
1601 case 5: active = 0; break;
1602 case 14: active = 1; break;
1603 }
1604 table_make_option_menu(table, 2, STR_MODELID_CTRL, model_options, active);
1605 #endif
1606
1607 #if EMULATED_68K
1608 static const opt_desc cpu_options[] = {
1609 {STR_CPU_68020_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020)},
1610 {STR_CPU_68020_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020_fpu)},
1611 {STR_CPU_68030_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030)},
1612 {STR_CPU_68030_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030_fpu)},
1613 {STR_CPU_68040_LAB, GTK_SIGNAL_FUNC(mn_cpu_68040)},
1614 {0, NULL}
1615 };
1616 int cpu = PrefsFindInt32("cpu");
1617 bool fpu = PrefsFindBool("fpu");
1618 active = 0;
1619 switch (cpu) {
1620 case 2: active = fpu ? 1 : 0; break;
1621 case 3: active = fpu ? 3 : 2; break;
1622 case 4: active = 4;
1623 }
1624 table_make_option_menu(table, 3, STR_CPU_CTRL, cpu_options, active);
1625 #endif
1626
1627 w_rom_file = table_make_file_entry(table, 4, STR_ROM_FILE_CTRL, "rom");
1628
1629 make_checkbox(box, STR_IDLEWAIT_CTRL, "idlewait", GTK_SIGNAL_FUNC(tb_idlewait));
1630
1631 #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
1632 make_checkbox(box, STR_IGNORESEGV_CTRL, "ignoresegv", GTK_SIGNAL_FUNC(tb_ignoresegv));
1633 #endif
1634 }
1635
1636
1637 /*
1638 * Read settings from widgets and set preferences
1639 */
1640
1641 static void read_settings(void)
1642 {
1643 read_volumes_settings();
1644 read_scsi_settings();
1645 read_graphics_settings();
1646 read_input_settings();
1647 read_serial_settings();
1648 read_ethernet_settings();
1649 read_memory_settings();
1650 read_jit_settings();
1651 }
1652
1653
1654 /*
1655 * Fake unused data and functions
1656 */
1657
1658 uint8 XPRAM[XPRAM_SIZE];
1659 void MountVolume(void *fh) { }
1660 void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size) { }
1661 void recycle_write_packet(LPPACKET) { }
1662 VOID CALLBACK packet_read_completion(DWORD, DWORD, LPOVERLAPPED) { }
1663
1664
1665 /*
1666 * Add default serial prefs (must be added, even if no ports present)
1667 */
1668
1669 void SysAddSerialPrefs(void)
1670 {
1671 PrefsAddString("seriala", "COM1");
1672 PrefsAddString("serialb", "COM2");
1673 }
1674
1675
1676 /*
1677 * Display alerts
1678 */
1679
1680 static void display_alert(int title_id, const char *text, int flags)
1681 {
1682 MessageBox(NULL, text, GetString(title_id), MB_OK | flags);
1683 }
1684
1685 void ErrorAlert(const char *text)
1686 {
1687 display_alert(STR_ERROR_ALERT_TITLE, text, MB_ICONSTOP);
1688 }
1689
1690 void WarningAlert(const char *text)
1691 {
1692 display_alert(STR_WARNING_ALERT_TITLE, text, MB_ICONSTOP);
1693 }
1694
1695
1696 /*
1697 * Start standalone GUI
1698 */
1699
1700 int main(int argc, char *argv[])
1701 {
1702 // Init GTK
1703 gtk_set_locale();
1704 gtk_init(&argc, &argv);
1705
1706 // Read preferences
1707 PrefsInit(argc, argv);
1708
1709 // Migrate preferences
1710 PrefsMigrate();
1711
1712 // Show preferences editor
1713 bool start = PrefsEditor();
1714
1715 // Exit preferences
1716 PrefsExit();
1717
1718 // Transfer control to the executable
1719 if (start) {
1720 char path[_MAX_PATH];
1721 bool ok = GetModuleFileName(NULL, path, sizeof(path)) != 0;
1722 if (ok) {
1723 char b2_path[_MAX_PATH];
1724 char *p = strrchr(path, '\\');
1725 *++p = '\0';
1726 SetCurrentDirectory(path);
1727 strcpy(b2_path, path);
1728 strcat(b2_path, PROGRAM_NAME);
1729 strcat(b2_path, ".exe");
1730 HINSTANCE h = ShellExecute(GetDesktopWindow(), "open",
1731 b2_path, "", path, SW_SHOWNORMAL);
1732 if ((int)h <= 32)
1733 ok = false;
1734 }
1735 if (!ok) {
1736 ErrorAlert("Coult not start " PROGRAM_NAME " executable");
1737 return 1;
1738 }
1739 }
1740
1741 return 0;
1742 }