ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/prefs_editor_gtk.cpp
Revision: 1.19
Committed: 2002-01-15T14:58:37Z (22 years, 5 months ago) by cebix
Branch: MAIN
CVS Tags: snapshot-15012002
Changes since 1.18: +1 -1 lines
Log Message:
- documentation updates
- 2001 -> 2002
- version 0.9 -> 1.0

File Contents

# Content
1 /*
2 * prefs_editor_gtk.cpp - Preferences editor, Unix implementation using GTK+
3 *
4 * Basilisk II (C) 1997-2002 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 <gtk/gtk.h>
24 #include <stdlib.h>
25 #include <dirent.h>
26 #include <sys/socket.h>
27 #include <sys/ioctl.h>
28 #include <net/if.h>
29 #include <net/if_arp.h>
30
31 #include "user_strings.h"
32 #include "version.h"
33 #include "cdrom.h"
34 #include "xpram.h"
35 #include "prefs.h"
36 #include "prefs_editor.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_memory_pane(GtkWidget *top);
51 static void read_settings(void);
52
53
54 /*
55 * Utility functions
56 */
57
58 struct opt_desc {
59 int label_id;
60 GtkSignalFunc func;
61 };
62
63 static void add_menu_item(GtkWidget *menu, int label_id, GtkSignalFunc func)
64 {
65 GtkWidget *item = gtk_menu_item_new_with_label(GetString(label_id));
66 gtk_widget_show(item);
67 gtk_signal_connect(GTK_OBJECT(item), "activate", func, NULL);
68 gtk_menu_append(GTK_MENU(menu), item);
69 }
70
71 static GtkWidget *make_pane(GtkWidget *notebook, int title_id)
72 {
73 GtkWidget *frame, *label, *box;
74
75 frame = gtk_frame_new(NULL);
76 gtk_widget_show(frame);
77 gtk_container_border_width(GTK_CONTAINER(frame), 4);
78
79 label = gtk_label_new(GetString(title_id));
80 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
81
82 box = gtk_vbox_new(FALSE, 4);
83 gtk_widget_show(box);
84 gtk_container_set_border_width(GTK_CONTAINER(box), 4);
85 gtk_container_add(GTK_CONTAINER(frame), box);
86 return box;
87 }
88
89 static GtkWidget *make_button_box(GtkWidget *top, int border, const opt_desc *buttons)
90 {
91 GtkWidget *bb, *button;
92
93 bb = gtk_hbutton_box_new();
94 gtk_widget_show(bb);
95 gtk_container_set_border_width(GTK_CONTAINER(bb), border);
96 gtk_button_box_set_layout(GTK_BUTTON_BOX(bb), GTK_BUTTONBOX_DEFAULT_STYLE);
97 gtk_button_box_set_spacing(GTK_BUTTON_BOX(bb), 4);
98 gtk_box_pack_start(GTK_BOX(top), bb, FALSE, FALSE, 0);
99
100 while (buttons->label_id) {
101 button = gtk_button_new_with_label(GetString(buttons->label_id));
102 gtk_widget_show(button);
103 gtk_signal_connect_object(GTK_OBJECT(button), "clicked", buttons->func, NULL);
104 gtk_box_pack_start(GTK_BOX(bb), button, TRUE, TRUE, 0);
105 buttons++;
106 }
107 return bb;
108 }
109
110 static GtkWidget *make_separator(GtkWidget *top)
111 {
112 GtkWidget *sep = gtk_hseparator_new();
113 gtk_box_pack_start(GTK_BOX(top), sep, FALSE, FALSE, 0);
114 gtk_widget_show(sep);
115 return sep;
116 }
117
118 static GtkWidget *make_table(GtkWidget *top, int x, int y)
119 {
120 GtkWidget *table = gtk_table_new(x, y, FALSE);
121 gtk_widget_show(table);
122 gtk_box_pack_start(GTK_BOX(top), table, FALSE, FALSE, 0);
123 return table;
124 }
125
126 static GtkWidget *make_option_menu(GtkWidget *top, int label_id, const opt_desc *options, int active)
127 {
128 GtkWidget *box, *label, *opt, *menu;
129
130 box = gtk_hbox_new(FALSE, 4);
131 gtk_widget_show(box);
132 gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0);
133
134 label = gtk_label_new(GetString(label_id));
135 gtk_widget_show(label);
136 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
137
138 opt = gtk_option_menu_new();
139 gtk_widget_show(opt);
140 menu = gtk_menu_new();
141
142 while (options->label_id) {
143 add_menu_item(menu, options->label_id, options->func);
144 options++;
145 }
146 gtk_menu_set_active(GTK_MENU(menu), active);
147
148 gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
149 gtk_box_pack_start(GTK_BOX(box), opt, FALSE, FALSE, 0);
150 return menu;
151 }
152
153 static GtkWidget *make_entry(GtkWidget *top, int label_id, const char *prefs_item)
154 {
155 GtkWidget *box, *label, *entry;
156
157 box = gtk_hbox_new(FALSE, 4);
158 gtk_widget_show(box);
159 gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0);
160
161 label = gtk_label_new(GetString(label_id));
162 gtk_widget_show(label);
163 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
164
165 entry = gtk_entry_new();
166 gtk_widget_show(entry);
167 const char *str = PrefsFindString(prefs_item);
168 if (str == NULL)
169 str = "";
170 gtk_entry_set_text(GTK_ENTRY(entry), str);
171 gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
172 return entry;
173 }
174
175 static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_item, GtkSignalFunc func)
176 {
177 GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id));
178 gtk_widget_show(button);
179 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), PrefsFindBool(prefs_item));
180 gtk_signal_connect(GTK_OBJECT(button), "toggled", func, button);
181 gtk_box_pack_start(GTK_BOX(top), button, FALSE, FALSE, 0);
182 return button;
183 }
184
185
186 /*
187 * Show preferences editor
188 * Returns true when user clicked on "Start", false otherwise
189 */
190
191 // Window closed
192 static gint window_closed(void)
193 {
194 return FALSE;
195 }
196
197 // Window destroyed
198 static void window_destroyed(void)
199 {
200 gtk_main_quit();
201 }
202
203 // "Start" button clicked
204 static void cb_start(...)
205 {
206 start_clicked = true;
207 read_settings();
208 SavePrefs();
209 gtk_widget_destroy(win);
210 }
211
212 // "Quit" button clicked
213 static void cb_quit(...)
214 {
215 start_clicked = false;
216 gtk_widget_destroy(win);
217 }
218
219 // "OK" button of "About" dialog clicked
220 static void dl_quit(GtkWidget *dialog)
221 {
222 gtk_widget_destroy(dialog);
223 }
224
225 // "About" selected
226 static void mn_about(...)
227 {
228 GtkWidget *dialog, *label, *button;
229
230 char str[512];
231 sprintf(str,
232 "Basilisk II\nVersion %d.%d\n\n"
233 "Copyright (C) 1997-2001 Christian Bauer et al.\n"
234 "E-mail: Christian.Bauer@uni-mainz.de\n"
235 "http://www.uni-mainz.de/~bauec002/B2Main.html\n\n"
236 "Basilisk II comes with ABSOLUTELY NO\n"
237 "WARRANTY. This is free software, and\n"
238 "you are welcome to redistribute it\n"
239 "under the terms of the GNU General\n"
240 "Public License.\n",
241 VERSION_MAJOR, VERSION_MINOR
242 );
243
244 dialog = gtk_dialog_new();
245 gtk_window_set_title(GTK_WINDOW(dialog), GetString(STR_ABOUT_TITLE));
246 gtk_container_border_width(GTK_CONTAINER(dialog), 5);
247 gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150);
248
249 label = gtk_label_new(str);
250 gtk_widget_show(label);
251 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
252
253 button = gtk_button_new_with_label(GetString(STR_OK_BUTTON));
254 gtk_widget_show(button);
255 gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog));
256 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0);
257 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
258 gtk_widget_grab_default(button);
259 gtk_widget_show(dialog);
260 }
261
262 // "Zap PRAM" selected
263 static void mn_zap_pram(...)
264 {
265 ZapPRAM();
266 }
267
268 // Menu item descriptions
269 static GtkItemFactoryEntry menu_items[] = {
270 {(gchar *)GetString(STR_PREFS_MENU_FILE_GTK), NULL, NULL, 0, "<Branch>"},
271 {(gchar *)GetString(STR_PREFS_ITEM_START_GTK), NULL, GTK_SIGNAL_FUNC(cb_start), 0, NULL},
272 {(gchar *)GetString(STR_PREFS_ITEM_ZAP_PRAM_GTK), NULL, GTK_SIGNAL_FUNC(mn_zap_pram), 0, NULL},
273 {(gchar *)GetString(STR_PREFS_ITEM_SEPL_GTK), NULL, NULL, 0, "<Separator>"},
274 {(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK), "<control>Q", GTK_SIGNAL_FUNC(cb_quit), 0, NULL},
275 {(gchar *)GetString(STR_HELP_MENU_GTK), NULL, NULL, 0, "<LastBranch>"},
276 {(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK), NULL, GTK_SIGNAL_FUNC(mn_about), 0, NULL}
277 };
278
279 bool PrefsEditor(void)
280 {
281 // Create window
282 win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
283 gtk_window_set_title(GTK_WINDOW(win), GetString(STR_PREFS_TITLE));
284 gtk_signal_connect(GTK_OBJECT(win), "delete_event", GTK_SIGNAL_FUNC(window_closed), NULL);
285 gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(window_destroyed), NULL);
286
287 // Create window contents
288 GtkWidget *box = gtk_vbox_new(FALSE, 4);
289 gtk_widget_show(box);
290 gtk_container_add(GTK_CONTAINER(win), box);
291
292 GtkAccelGroup *accel_group = gtk_accel_group_new();
293 GtkItemFactory *item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
294 gtk_item_factory_create_items(item_factory, sizeof(menu_items) / sizeof(menu_items[0]), menu_items, NULL);
295 gtk_accel_group_attach(accel_group, GTK_OBJECT(win));
296 GtkWidget *menu_bar = gtk_item_factory_get_widget(item_factory, "<main>");
297 gtk_widget_show(menu_bar);
298 gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, TRUE, 0);
299
300 GtkWidget *notebook = gtk_notebook_new();
301 gtk_widget_show(notebook);
302 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
303 gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), FALSE);
304 gtk_box_pack_start(GTK_BOX(box), notebook, TRUE, TRUE, 0);
305
306 create_volumes_pane(notebook);
307 create_scsi_pane(notebook);
308 create_graphics_pane(notebook);
309 create_input_pane(notebook);
310 create_serial_pane(notebook);
311 create_memory_pane(notebook);
312
313 static const opt_desc buttons[] = {
314 {STR_START_BUTTON, GTK_SIGNAL_FUNC(cb_start)},
315 {STR_QUIT_BUTTON, GTK_SIGNAL_FUNC(cb_quit)},
316 {0, NULL}
317 };
318 make_button_box(box, 4, buttons);
319
320 // Show window and enter main loop
321 gtk_widget_show(win);
322 gtk_main();
323 return start_clicked;
324 }
325
326
327 /*
328 * "Volumes" pane
329 */
330
331 static GtkWidget *volume_list, *w_extfs;
332 static int selected_volume;
333
334 // Volume in list selected
335 static void cl_selected(GtkWidget *list, int row, int column)
336 {
337 selected_volume = row;
338 }
339
340 struct file_req_assoc {
341 file_req_assoc(GtkWidget *r, GtkWidget *e) : req(r), entry(e) {}
342 GtkWidget *req;
343 GtkWidget *entry;
344 };
345
346 // Volume selected for addition
347 static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc)
348 {
349 char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
350 gtk_clist_append(GTK_CLIST(volume_list), &file);
351 gtk_widget_destroy(assoc->req);
352 delete assoc;
353 }
354
355 // Volume selected for creation
356 static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc)
357 {
358 char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
359
360 char *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry));
361 int size = atoi(str);
362
363 char cmd[1024];
364 sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", file, size);
365 int ret = system(cmd);
366 if (ret == 0)
367 gtk_clist_append(GTK_CLIST(volume_list), &file);
368 gtk_widget_destroy(GTK_WIDGET(assoc->req));
369 delete assoc;
370 }
371
372 // "Add Volume" button clicked
373 static void cb_add_volume(...)
374 {
375 GtkWidget *req = gtk_file_selection_new(GetString(STR_ADD_VOLUME_TITLE));
376 gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
377 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(add_volume_ok), new file_req_assoc(req, NULL));
378 gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
379 gtk_widget_show(req);
380 }
381
382 // "Create Hardfile" button clicked
383 static void cb_create_volume(...)
384 {
385 GtkWidget *req = gtk_file_selection_new(GetString(STR_CREATE_VOLUME_TITLE));
386
387 GtkWidget *box = gtk_hbox_new(FALSE, 4);
388 gtk_widget_show(box);
389 GtkWidget *label = gtk_label_new(GetString(STR_HARDFILE_SIZE_CTRL));
390 gtk_widget_show(label);
391 GtkWidget *entry = gtk_entry_new();
392 gtk_widget_show(entry);
393 char str[32];
394 sprintf(str, "%d", 40);
395 gtk_entry_set_text(GTK_ENTRY(entry), str);
396 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
397 gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0);
398 gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(req)->main_vbox), box, FALSE, FALSE, 0);
399
400 gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
401 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(create_volume_ok), new file_req_assoc(req, entry));
402 gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
403 gtk_widget_show(req);
404 }
405
406 // "Remove Volume" button clicked
407 static void cb_remove_volume(...)
408 {
409 gtk_clist_remove(GTK_CLIST(volume_list), selected_volume);
410 }
411
412 // "Boot From" selected
413 static void mn_boot_any(...) {PrefsReplaceInt32("bootdriver", 0);}
414 static void mn_boot_cdrom(...) {PrefsReplaceInt32("bootdriver", CDROMRefNum);}
415
416 // "No CD-ROM Driver" button toggled
417 static void tb_nocdrom(GtkWidget *widget)
418 {
419 PrefsReplaceBool("nocdrom", GTK_TOGGLE_BUTTON(widget)->active);
420 }
421
422 // Read settings from widgets and set preferences
423 static void read_volumes_settings(void)
424 {
425 while (PrefsFindString("disk"))
426 PrefsRemoveItem("disk");
427
428 for (int i=0; i<GTK_CLIST(volume_list)->rows; i++) {
429 char *str;
430 gtk_clist_get_text(GTK_CLIST(volume_list), i, 0, &str);
431 PrefsAddString("disk", str);
432 }
433
434 PrefsReplaceString("extfs", gtk_entry_get_text(GTK_ENTRY(w_extfs)));
435 }
436
437 // Create "Volumes" pane
438 static void create_volumes_pane(GtkWidget *top)
439 {
440 GtkWidget *box, *scroll, *menu;
441
442 box = make_pane(top, STR_VOLUMES_PANE_TITLE);
443
444 scroll = gtk_scrolled_window_new(NULL, NULL);
445 gtk_widget_show(scroll);
446 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
447 volume_list = gtk_clist_new(1);
448 gtk_widget_show(volume_list);
449 gtk_clist_set_selection_mode(GTK_CLIST(volume_list), GTK_SELECTION_SINGLE);
450 gtk_clist_set_shadow_type(GTK_CLIST(volume_list), GTK_SHADOW_NONE);
451 gtk_clist_set_reorderable(GTK_CLIST(volume_list), true);
452 gtk_signal_connect(GTK_OBJECT(volume_list), "select_row", GTK_SIGNAL_FUNC(cl_selected), NULL);
453 char *str;
454 int32 index = 0;
455 while ((str = (char *)PrefsFindString("disk", index++)) != NULL)
456 gtk_clist_append(GTK_CLIST(volume_list), &str);
457 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), volume_list);
458 gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 0);
459 selected_volume = 0;
460
461 static const opt_desc buttons[] = {
462 {STR_ADD_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_add_volume)},
463 {STR_CREATE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_create_volume)},
464 {STR_REMOVE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_remove_volume)},
465 {0, NULL},
466 };
467 make_button_box(box, 0, buttons);
468 make_separator(box);
469
470 w_extfs = make_entry(box, STR_EXTFS_CTRL, "extfs");
471
472 static const opt_desc options[] = {
473 {STR_BOOT_ANY_LAB, GTK_SIGNAL_FUNC(mn_boot_any)},
474 {STR_BOOT_CDROM_LAB, GTK_SIGNAL_FUNC(mn_boot_cdrom)},
475 {0, NULL}
476 };
477 int bootdriver = PrefsFindInt32("bootdriver"), active = 0;
478 switch (bootdriver) {
479 case 0: active = 0; break;
480 case CDROMRefNum: active = 1; break;
481 }
482 menu = make_option_menu(box, STR_BOOTDRIVER_CTRL, options, active);
483
484 make_checkbox(box, STR_NOCDROM_CTRL, "nocdrom", GTK_SIGNAL_FUNC(tb_nocdrom));
485 }
486
487
488 /*
489 * "SCSI" pane
490 */
491
492 static GtkWidget *w_scsi[7];
493
494 // Read settings from widgets and set preferences
495 static void read_scsi_settings(void)
496 {
497 for (int id=0; id<7; id++) {
498 char prefs_name[32];
499 sprintf(prefs_name, "scsi%d", id);
500 const char *str = gtk_entry_get_text(GTK_ENTRY(w_scsi[id]));
501 if (str && strlen(str))
502 PrefsReplaceString(prefs_name, str);
503 else
504 PrefsRemoveItem(prefs_name);
505 }
506 }
507
508 // Create "SCSI" pane
509 static void create_scsi_pane(GtkWidget *top)
510 {
511 GtkWidget *box;
512
513 box = make_pane(top, STR_SCSI_PANE_TITLE);
514
515 for (int id=0; id<7; id++) {
516 char prefs_name[32];
517 sprintf(prefs_name, "scsi%d", id);
518 w_scsi[id] = make_entry(box, STR_SCSI_ID_0 + id, prefs_name);
519 }
520 }
521
522
523 /*
524 * "Graphics/Sound" pane
525 */
526
527 // Display types
528 enum {
529 DISPLAY_WINDOW,
530 DISPLAY_SCREEN
531 };
532
533 static GtkWidget *w_frameskip, *w_display_x, *w_display_y;
534 static GtkWidget *l_frameskip, *l_display_x, *l_display_y;
535 static int display_type;
536 static int dis_width, dis_height;
537
538 #ifdef ENABLE_FBDEV_DGA
539 static GtkWidget *w_fbdev_name, *w_fbdevice_file;
540 static GtkWidget *l_fbdev_name, *l_fbdevice_file;
541 static char fbdev_name[256];
542 #endif
543
544 // Hide/show graphics widgets
545 static void hide_show_graphics_widgets(void)
546 {
547 switch (display_type) {
548 case DISPLAY_WINDOW:
549 gtk_widget_show(w_frameskip); gtk_widget_show(l_frameskip);
550 #ifdef ENABLE_FBDEV_DGA
551 gtk_widget_show(w_display_x); gtk_widget_show(l_display_x);
552 gtk_widget_show(w_display_y); gtk_widget_show(l_display_y);
553 gtk_widget_hide(w_fbdev_name); gtk_widget_hide(l_fbdev_name);
554 #endif
555 break;
556 case DISPLAY_SCREEN:
557 gtk_widget_hide(w_frameskip); gtk_widget_hide(l_frameskip);
558 #ifdef ENABLE_FBDEV_DGA
559 gtk_widget_hide(w_display_x); gtk_widget_hide(l_display_x);
560 gtk_widget_hide(w_display_y); gtk_widget_hide(l_display_y);
561 gtk_widget_show(w_fbdev_name); gtk_widget_show(l_fbdev_name);
562 #endif
563 break;
564 }
565 }
566
567 // "Window" video type selected
568 static void mn_window(...)
569 {
570 display_type = DISPLAY_WINDOW;
571 hide_show_graphics_widgets();
572 }
573
574 // "Fullscreen" video type selected
575 static void mn_fullscreen(...)
576 {
577 display_type = DISPLAY_SCREEN;
578 hide_show_graphics_widgets();
579 }
580
581 // "5 Hz".."60Hz" selected
582 static void mn_5hz(...) {PrefsReplaceInt32("frameskip", 12);}
583 static void mn_7hz(...) {PrefsReplaceInt32("frameskip", 8);}
584 static void mn_10hz(...) {PrefsReplaceInt32("frameskip", 6);}
585 static void mn_15hz(...) {PrefsReplaceInt32("frameskip", 4);}
586 static void mn_30hz(...) {PrefsReplaceInt32("frameskip", 2);}
587 static void mn_60hz(...) {PrefsReplaceInt32("frameskip", 1);}
588 static void mn_dynamic(...) {PrefsReplaceInt32("frameskip", 0);}
589
590 // "Disable Sound Output" button toggled
591 static void tb_nosound(GtkWidget *widget)
592 {
593 PrefsReplaceBool("nosound", GTK_TOGGLE_BUTTON(widget)->active);
594 }
595
596 // Read graphics preferences
597 static void parse_graphics_prefs(void)
598 {
599 display_type = DISPLAY_WINDOW;
600 dis_width = 512;
601 dis_height = 384;
602 #ifdef ENABLE_FBDEV_DGA
603 fbdev_name[0] = 0;
604 #endif
605
606 const char *str = PrefsFindString("screen");
607 if (str) {
608 if (sscanf(str, "win/%d/%d", &dis_width, &dis_height) == 2)
609 display_type = DISPLAY_WINDOW;
610 #ifdef ENABLE_FBDEV_DGA
611 else if (sscanf(str, "dga/%255s", fbdev_name) == 1)
612 #else
613 else if (sscanf(str, "dga/%d/%d", &dis_width, &dis_height) == 2)
614 #endif
615 display_type = DISPLAY_SCREEN;
616 }
617 }
618
619 // Read settings from widgets and set preferences
620 static void read_graphics_settings(void)
621 {
622 const char *str;
623
624 str = gtk_entry_get_text(GTK_ENTRY(w_display_x));
625 dis_width = atoi(str);
626
627 str = gtk_entry_get_text(GTK_ENTRY(w_display_y));
628 dis_height = atoi(str);
629
630 char pref[256];
631 switch (display_type) {
632 case DISPLAY_WINDOW:
633 sprintf(pref, "win/%d/%d", dis_width, dis_height);
634 break;
635 case DISPLAY_SCREEN:
636 #ifdef ENABLE_FBDEV_DGA
637 str = gtk_entry_get_text(GTK_ENTRY(w_fbdev_name));
638 sprintf(pref, "dga/%s", str);
639 #else
640 sprintf(pref, "dga/%d/%d", dis_width, dis_height);
641 #endif
642 break;
643 default:
644 PrefsRemoveItem("screen");
645 return;
646 }
647 PrefsReplaceString("screen", pref);
648 }
649
650 // Create "Graphics/Sound" pane
651 static void create_graphics_pane(GtkWidget *top)
652 {
653 GtkWidget *box, *table, *label, *opt, *menu, *combo;
654 char str[32];
655
656 parse_graphics_prefs();
657
658 box = make_pane(top, STR_GRAPHICS_SOUND_PANE_TITLE);
659 table = make_table(box, 2, 5);
660
661 label = gtk_label_new(GetString(STR_VIDEO_TYPE_CTRL));
662 gtk_widget_show(label);
663 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
664
665 opt = gtk_option_menu_new();
666 gtk_widget_show(opt);
667 menu = gtk_menu_new();
668 add_menu_item(menu, STR_WINDOW_LAB, GTK_SIGNAL_FUNC(mn_window));
669 add_menu_item(menu, STR_FULLSCREEN_LAB, GTK_SIGNAL_FUNC(mn_fullscreen));
670 switch (display_type) {
671 case DISPLAY_WINDOW:
672 gtk_menu_set_active(GTK_MENU(menu), 0);
673 break;
674 case DISPLAY_SCREEN:
675 gtk_menu_set_active(GTK_MENU(menu), 1);
676 break;
677 }
678 gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
679 gtk_table_attach(GTK_TABLE(table), opt, 1, 2, 0, 1, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
680
681 l_frameskip = gtk_label_new(GetString(STR_FRAMESKIP_CTRL));
682 gtk_widget_show(l_frameskip);
683 gtk_table_attach(GTK_TABLE(table), l_frameskip, 0, 1, 1, 2, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
684
685 w_frameskip = gtk_option_menu_new();
686 gtk_widget_show(w_frameskip);
687 menu = gtk_menu_new();
688 add_menu_item(menu, STR_REF_5HZ_LAB, GTK_SIGNAL_FUNC(mn_5hz));
689 add_menu_item(menu, STR_REF_7_5HZ_LAB, GTK_SIGNAL_FUNC(mn_7hz));
690 add_menu_item(menu, STR_REF_10HZ_LAB, GTK_SIGNAL_FUNC(mn_10hz));
691 add_menu_item(menu, STR_REF_15HZ_LAB, GTK_SIGNAL_FUNC(mn_15hz));
692 add_menu_item(menu, STR_REF_30HZ_LAB, GTK_SIGNAL_FUNC(mn_30hz));
693 add_menu_item(menu, STR_REF_60HZ_LAB, GTK_SIGNAL_FUNC(mn_60hz));
694 add_menu_item(menu, STR_REF_DYNAMIC_LAB, GTK_SIGNAL_FUNC(mn_dynamic));
695 int frameskip = PrefsFindInt32("frameskip");
696 int item = -1;
697 switch (frameskip) {
698 case 12: item = 0; break;
699 case 8: item = 1; break;
700 case 6: item = 2; break;
701 case 4: item = 3; break;
702 case 2: item = 4; break;
703 case 1: item = 5; break;
704 case 0: item = 6; break;
705 }
706 if (item >= 0)
707 gtk_menu_set_active(GTK_MENU(menu), item);
708 gtk_option_menu_set_menu(GTK_OPTION_MENU(w_frameskip), menu);
709 gtk_table_attach(GTK_TABLE(table), w_frameskip, 1, 2, 1, 2, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
710
711 l_display_x = gtk_label_new(GetString(STR_DISPLAY_X_CTRL));
712 gtk_widget_show(l_display_x);
713 gtk_table_attach(GTK_TABLE(table), l_display_x, 0, 1, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
714
715 combo = gtk_combo_new();
716 gtk_widget_show(combo);
717 GList *glist1 = NULL;
718 glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_512_LAB));
719 glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_640_LAB));
720 glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_800_LAB));
721 glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_1024_LAB));
722 glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_MAX_LAB));
723 gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist1);
724 if (dis_width)
725 sprintf(str, "%d", dis_width);
726 else
727 strcpy(str, GetString(STR_SIZE_MAX_LAB));
728 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
729 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 2, 3, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
730 w_display_x = GTK_COMBO(combo)->entry;
731
732 l_display_y = gtk_label_new(GetString(STR_DISPLAY_Y_CTRL));
733 gtk_widget_show(l_display_y);
734 gtk_table_attach(GTK_TABLE(table), l_display_y, 0, 1, 3, 4, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
735
736 combo = gtk_combo_new();
737 gtk_widget_show(combo);
738 GList *glist2 = NULL;
739 glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_384_LAB));
740 glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_480_LAB));
741 glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_600_LAB));
742 glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_768_LAB));
743 glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_MAX_LAB));
744 gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist2);
745 if (dis_height)
746 sprintf(str, "%d", dis_height);
747 else
748 strcpy(str, GetString(STR_SIZE_MAX_LAB));
749 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
750 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 3, 4, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
751 w_display_y = GTK_COMBO(combo)->entry;
752
753 #ifdef ENABLE_FBDEV_DGA
754 l_fbdev_name = gtk_label_new(GetString(STR_FBDEV_NAME_CTRL));
755 gtk_widget_show(l_fbdev_name);
756 gtk_table_attach(GTK_TABLE(table), l_fbdev_name, 0, 1, 4, 5, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
757
758 w_fbdev_name = gtk_entry_new();
759 gtk_widget_show(w_fbdev_name);
760 gtk_entry_set_text(GTK_ENTRY(w_fbdev_name), fbdev_name);
761 gtk_table_attach(GTK_TABLE(table), w_fbdev_name, 1, 2, 4, 5, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
762
763 w_fbdevice_file = make_entry(box, STR_FBDEVICE_FILE_CTRL, "fbdevicefile");
764 #endif
765
766 make_separator(box);
767 make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound));
768
769 hide_show_graphics_widgets();
770 }
771
772
773 /*
774 * "Input" pane
775 */
776
777 static GtkWidget *w_keycode_file;
778 static GtkWidget *w_mouse_wheel_lines;
779
780 // Set sensitivity of widgets
781 static void set_input_sensitive(void)
782 {
783 gtk_widget_set_sensitive(w_keycode_file, PrefsFindBool("keycodes"));
784 gtk_widget_set_sensitive(w_mouse_wheel_lines, PrefsFindInt32("mousewheelmode") == 1);
785 }
786
787 // "Use Raw Keycodes" button toggled
788 static void tb_keycodes(GtkWidget *widget)
789 {
790 PrefsReplaceBool("keycodes", GTK_TOGGLE_BUTTON(widget)->active);
791 set_input_sensitive();
792 }
793
794 // "Mouse Wheel Mode" selected
795 static void mn_wheel_page(...) {PrefsReplaceInt32("mousewheelmode", 0); set_input_sensitive();}
796 static void mn_wheel_cursor(...) {PrefsReplaceInt32("mousewheelmode", 1); set_input_sensitive();}
797
798 // Read settings from widgets and set preferences
799 static void read_input_settings(void)
800 {
801 const char *str = gtk_entry_get_text(GTK_ENTRY(w_keycode_file));
802 if (str && strlen(str))
803 PrefsReplaceString("keycodefile", str);
804 else
805 PrefsRemoveItem("keycodefile");
806
807 PrefsReplaceInt32("mousewheellines", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(w_mouse_wheel_lines)));
808 }
809
810 // Create "Input" pane
811 static void create_input_pane(GtkWidget *top)
812 {
813 GtkWidget *box, *hbox, *menu, *label;
814 GtkObject *adj;
815
816 box = make_pane(top, STR_INPUT_PANE_TITLE);
817
818 make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes));
819 w_keycode_file = make_entry(box, STR_KEYCODE_FILE_CTRL, "keycodefile");
820
821 make_separator(box);
822
823 static const opt_desc options[] = {
824 {STR_MOUSEWHEELMODE_PAGE_LAB, GTK_SIGNAL_FUNC(mn_wheel_page)},
825 {STR_MOUSEWHEELMODE_CURSOR_LAB, GTK_SIGNAL_FUNC(mn_wheel_cursor)},
826 {0, NULL}
827 };
828 int wheelmode = PrefsFindInt32("mousewheelmode"), active = 0;
829 switch (wheelmode) {
830 case 0: active = 0; break;
831 case 1: active = 1; break;
832 }
833 menu = make_option_menu(box, STR_MOUSEWHEELMODE_CTRL, options, active);
834
835 hbox = gtk_hbox_new(FALSE, 4);
836 gtk_widget_show(hbox);
837 gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
838
839 label = gtk_label_new(GetString(STR_MOUSEWHEELLINES_CTRL));
840 gtk_widget_show(label);
841 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
842
843 adj = gtk_adjustment_new(PrefsFindInt32("mousewheellines"), 1, 1000, 1, 5, 0);
844 w_mouse_wheel_lines = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 0.0, 0);
845 gtk_widget_show(w_mouse_wheel_lines);
846 gtk_box_pack_start(GTK_BOX(hbox), w_mouse_wheel_lines, FALSE, FALSE, 0);
847
848 set_input_sensitive();
849 }
850
851
852 /*
853 * "Serial/Network" pane
854 */
855
856 static GtkWidget *w_seriala, *w_serialb, *w_ether, *w_udp_port;
857
858 // Set sensitivity of widgets
859 static void set_serial_sensitive(void)
860 {
861 #if SUPPORTS_UDP_TUNNEL
862 gtk_widget_set_sensitive(w_ether, !PrefsFindBool("udptunnel"));
863 gtk_widget_set_sensitive(w_udp_port, PrefsFindBool("udptunnel"));
864 #endif
865 }
866
867 // "Tunnel AppleTalk over IP" button toggled
868 static void tb_udptunnel(GtkWidget *widget)
869 {
870 PrefsReplaceBool("udptunnel", GTK_TOGGLE_BUTTON(widget)->active);
871 set_serial_sensitive();
872 }
873
874 // Read settings from widgets and set preferences
875 static void read_serial_settings(void)
876 {
877 const char *str;
878
879 str = gtk_entry_get_text(GTK_ENTRY(w_seriala));
880 PrefsReplaceString("seriala", str);
881
882 str = gtk_entry_get_text(GTK_ENTRY(w_serialb));
883 PrefsReplaceString("serialb", str);
884
885 str = gtk_entry_get_text(GTK_ENTRY(w_ether));
886 if (str && strlen(str))
887 PrefsReplaceString("ether", str);
888 else
889 PrefsRemoveItem("ether");
890
891 #if SUPPORTS_UDP_TUNNEL
892 PrefsReplaceInt32("udpport", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(w_udp_port)));
893 #endif
894 }
895
896 // Add names of serial devices
897 static gint gl_str_cmp(gconstpointer a, gconstpointer b)
898 {
899 return strcmp((char *)a, (char *)b);
900 }
901
902 static GList *add_serial_names(void)
903 {
904 GList *glist = NULL;
905
906 // Search /dev for ttyS* and lp*
907 DIR *d = opendir("/dev");
908 if (d) {
909 struct dirent *de;
910 while ((de = readdir(d)) != NULL) {
911 #if defined(__linux__)
912 if (strncmp(de->d_name, "ttyS", 4) == 0 || strncmp(de->d_name, "lp", 2) == 0) {
913 #elif defined(__FreeBSD__)
914 if (strncmp(de->d_name, "cuaa", 4) == 0 || strncmp(de->d_name, "lpt", 3) == 0) {
915 #elif defined(__NetBSD__)
916 if (strncmp(de->d_name, "tty0", 4) == 0 || strncmp(de->d_name, "lpt", 3) == 0) {
917 #elif defined(sgi)
918 if (strncmp(de->d_name, "ttyf", 4) == 0 || strncmp(de->d_name, "plp", 3) == 0) {
919 #else
920 if (false) {
921 #endif
922 char *str = new char[64];
923 sprintf(str, "/dev/%s", de->d_name);
924 glist = g_list_append(glist, str);
925 }
926 }
927 closedir(d);
928 }
929 if (glist)
930 g_list_sort(glist, gl_str_cmp);
931 else
932 glist = g_list_append(glist, (void *)GetString(STR_NONE_LAB));
933 return glist;
934 }
935
936 // Add names of ethernet interfaces
937 static GList *add_ether_names(void)
938 {
939 GList *glist = NULL;
940
941 // Get list of all Ethernet interfaces
942 int s = socket(PF_INET, SOCK_DGRAM, 0);
943 if (s >= 0) {
944 char inbuf[8192];
945 struct ifconf ifc;
946 ifc.ifc_len = sizeof(inbuf);
947 ifc.ifc_buf = inbuf;
948 if (ioctl(s, SIOCGIFCONF, &ifc) == 0) {
949 struct ifreq req, *ifr = ifc.ifc_req;
950 for (int i=0; i<ifc.ifc_len; i+=sizeof(ifreq), ifr++) {
951 req = *ifr;
952 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(sgi)
953 if (ioctl(s, SIOCGIFADDR, &req) == 0 && (req.ifr_addr.sa_family == ARPHRD_ETHER || req.ifr_addr.sa_family == ARPHRD_ETHER+1)) {
954 #elif defined(__linux__)
955 if (ioctl(s, SIOCGIFHWADDR, &req) == 0 && req.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
956 #else
957 if (false) {
958 #endif
959 char *str = new char[64];
960 strncpy(str, ifr->ifr_name, 63);
961 glist = g_list_append(glist, str);
962 }
963 }
964 }
965 close(s);
966 }
967 if (glist)
968 g_list_sort(glist, gl_str_cmp);
969 else
970 glist = g_list_append(glist, (void *)GetString(STR_NONE_LAB));
971 return glist;
972 }
973
974 // Create "Serial/Network" pane
975 static void create_serial_pane(GtkWidget *top)
976 {
977 GtkWidget *box, *hbox, *table, *label, *combo, *sep;
978 GtkObject *adj;
979
980 box = make_pane(top, STR_SERIAL_NETWORK_PANE_TITLE);
981 table = make_table(box, 2, 4);
982
983 label = gtk_label_new(GetString(STR_SERIALA_CTRL));
984 gtk_widget_show(label);
985 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
986
987 GList *glist = add_serial_names();
988 combo = gtk_combo_new();
989 gtk_widget_show(combo);
990 gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
991 const char *str = PrefsFindString("seriala");
992 if (str == NULL)
993 str = "";
994 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
995 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
996 w_seriala = GTK_COMBO(combo)->entry;
997
998 label = gtk_label_new(GetString(STR_SERIALB_CTRL));
999 gtk_widget_show(label);
1000 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1001
1002 combo = gtk_combo_new();
1003 gtk_widget_show(combo);
1004 gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
1005 str = PrefsFindString("serialb");
1006 if (str == NULL)
1007 str = "";
1008 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
1009 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 1, 2, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1010 w_serialb = GTK_COMBO(combo)->entry;
1011
1012 sep = gtk_hseparator_new();
1013 gtk_widget_show(sep);
1014 gtk_table_attach(GTK_TABLE(table), sep, 0, 2, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1015
1016 label = gtk_label_new(GetString(STR_ETHERNET_IF_CTRL));
1017 gtk_widget_show(label);
1018 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1019
1020 glist = add_ether_names();
1021 combo = gtk_combo_new();
1022 gtk_widget_show(combo);
1023 gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
1024 str = PrefsFindString("ether");
1025 if (str == NULL)
1026 str = "";
1027 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
1028 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 3, 4, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1029 w_ether = GTK_COMBO(combo)->entry;
1030
1031 #if SUPPORTS_UDP_TUNNEL
1032 make_checkbox(box, STR_UDPTUNNEL_CTRL, "udptunnel", GTK_SIGNAL_FUNC(tb_udptunnel));
1033
1034 hbox = gtk_hbox_new(FALSE, 4);
1035 gtk_widget_show(hbox);
1036 gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1037
1038 label = gtk_label_new(GetString(STR_UDPPORT_CTRL));
1039 gtk_widget_show(label);
1040 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1041
1042 adj = gtk_adjustment_new(PrefsFindInt32("udpport"), 1, 65535, 1, 5, 0);
1043 w_udp_port = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 0.0, 0);
1044 gtk_widget_show(w_udp_port);
1045 gtk_box_pack_start(GTK_BOX(hbox), w_udp_port, FALSE, FALSE, 0);
1046 #endif
1047
1048 set_serial_sensitive();
1049 }
1050
1051
1052 /*
1053 * "Memory/Misc" pane
1054 */
1055
1056 static GtkObject *w_ramsize_adj;
1057 static GtkWidget *w_rom_file;
1058
1059 // Model ID selected
1060 static void mn_modelid_5(...) {PrefsReplaceInt32("modelid", 5);}
1061 static void mn_modelid_14(...) {PrefsReplaceInt32("modelid", 14);}
1062
1063 // CPU/FPU type
1064 static void mn_cpu_68020(...) {PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", false);}
1065 static void mn_cpu_68020_fpu(...) {PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", true);}
1066 static void mn_cpu_68030(...) {PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", false);}
1067 static void mn_cpu_68030_fpu(...) {PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", true);}
1068 static void mn_cpu_68040(...) {PrefsReplaceInt32("cpu", 4); PrefsReplaceBool("fpu", true);}
1069
1070 // Read settings from widgets and set preferences
1071 static void read_memory_settings(void)
1072 {
1073 PrefsReplaceInt32("ramsize", int(GTK_ADJUSTMENT(w_ramsize_adj)->value) << 20);
1074
1075 const char *str = gtk_entry_get_text(GTK_ENTRY(w_rom_file));
1076 if (str && strlen(str))
1077 PrefsReplaceString("rom", str);
1078 else
1079 PrefsRemoveItem("rom");
1080
1081 }
1082
1083 // Create "Memory/Misc" pane
1084 static void create_memory_pane(GtkWidget *top)
1085 {
1086 GtkWidget *box, *hbox, *vbox, *hbox2, *label, *scale;
1087
1088 box = make_pane(top, STR_MEMORY_MISC_PANE_TITLE);
1089
1090 hbox = gtk_hbox_new(FALSE, 4);
1091 gtk_widget_show(hbox);
1092
1093 label = gtk_label_new(GetString(STR_RAMSIZE_SLIDER));
1094 gtk_widget_show(label);
1095 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1096
1097 vbox = gtk_vbox_new(FALSE, 4);
1098 gtk_widget_show(vbox);
1099
1100 gfloat min, max;
1101 min = 1;
1102 max = 1024;
1103 w_ramsize_adj = gtk_adjustment_new(min, min, max, 1, 16, 0);
1104 gtk_adjustment_set_value(GTK_ADJUSTMENT(w_ramsize_adj), PrefsFindInt32("ramsize") >> 20);
1105
1106 scale = gtk_hscale_new(GTK_ADJUSTMENT(w_ramsize_adj));
1107 gtk_widget_show(scale);
1108 gtk_scale_set_digits(GTK_SCALE(scale), 0);
1109 gtk_box_pack_start(GTK_BOX(vbox), scale, TRUE, TRUE, 0);
1110
1111 hbox2 = gtk_hbox_new(FALSE, 4);
1112 gtk_widget_show(hbox2);
1113
1114 char val[32];
1115 sprintf(val, GetString(STR_RAMSIZE_FMT), int(min));
1116 label = gtk_label_new(val);
1117 gtk_widget_show(label);
1118 gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
1119
1120 sprintf(val, GetString(STR_RAMSIZE_FMT), int(max));
1121 label = gtk_label_new(val);
1122 gtk_widget_show(label);
1123 gtk_box_pack_end(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
1124 gtk_box_pack_start(GTK_BOX(vbox), hbox2, TRUE, TRUE, 0);
1125 gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
1126 gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1127
1128 static const opt_desc model_options[] = {
1129 {STR_MODELID_5_LAB, GTK_SIGNAL_FUNC(mn_modelid_5)},
1130 {STR_MODELID_14_LAB, GTK_SIGNAL_FUNC(mn_modelid_14)},
1131 {0, NULL}
1132 };
1133 int modelid = PrefsFindInt32("modelid"), active = 0;
1134 switch (modelid) {
1135 case 5: active = 0; break;
1136 case 14: active = 1; break;
1137 }
1138 make_option_menu(box, STR_MODELID_CTRL, model_options, active);
1139
1140 #if EMULATED_68K
1141 static const opt_desc cpu_options[] = {
1142 {STR_CPU_68020_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020)},
1143 {STR_CPU_68020_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020_fpu)},
1144 {STR_CPU_68030_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030)},
1145 {STR_CPU_68030_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030_fpu)},
1146 {STR_CPU_68040_LAB, GTK_SIGNAL_FUNC(mn_cpu_68040)},
1147 {0, NULL}
1148 };
1149 int cpu = PrefsFindInt32("cpu");
1150 bool fpu = PrefsFindBool("fpu");
1151 active = 0;
1152 switch (cpu) {
1153 case 2: active = fpu ? 1 : 0; break;
1154 case 3: active = fpu ? 3 : 2; break;
1155 case 4: active = 4;
1156 }
1157 make_option_menu(box, STR_CPU_CTRL, cpu_options, active);
1158 #endif
1159
1160 w_rom_file = make_entry(box, STR_ROM_FILE_CTRL, "rom");
1161 }
1162
1163
1164 /*
1165 * Read settings from widgets and set preferences
1166 */
1167
1168 static void read_settings(void)
1169 {
1170 read_volumes_settings();
1171 read_scsi_settings();
1172 read_graphics_settings();
1173 read_input_settings();
1174 read_serial_settings();
1175 read_memory_settings();
1176 }