ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/prefs_editor_gtk.cpp
(Generate patch)

Comparing BasiliskII/src/Unix/prefs_editor_gtk.cpp (file contents):
Revision 1.25 by cebix, 2004-01-12T15:29:25Z vs.
Revision 1.33 by gbeauche, 2006-04-16T21:25:41Z

# Line 1 | Line 1
1   /*
2   *  prefs_editor_gtk.cpp - Preferences editor, Unix implementation using GTK+
3   *
4 < *  Basilisk II (C) 1997-2004 Christian Bauer
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
# Line 39 | Line 39
39   #include "prefs.h"
40   #include "prefs_editor.h"
41  
42 + #define DEBUG 0
43 + #include "debug.h"
44 +
45  
46   // Global variables
47   static GtkWidget *win;                          // Preferences window
# Line 60 | Line 63 | static void read_settings(void);
63   *  Utility functions
64   */
65  
66 + #if ! GLIB_CHECK_VERSION(2,0,0)
67 + #define G_OBJECT(obj)                                                   GTK_OBJECT(obj)
68 + #define g_object_get_data(obj, key)                             gtk_object_get_data((obj), (key))
69 + #define g_object_set_data(obj, key, data)               gtk_object_set_data((obj), (key), (data))
70 + #endif
71 +
72   struct opt_desc {
73          int label_id;
74          GtkSignalFunc func;
# Line 69 | Line 78 | struct combo_desc {
78          int label_id;
79   };
80  
81 + struct file_req_assoc {
82 +        file_req_assoc(GtkWidget *r, GtkWidget *e) : req(r), entry(e) {}
83 +        GtkWidget *req;
84 +        GtkWidget *entry;
85 + };
86 +
87 + static void cb_browse_ok(GtkWidget *button, file_req_assoc *assoc)
88 + {
89 +        gchar *file = (char *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
90 +        gtk_entry_set_text(GTK_ENTRY(assoc->entry), file);
91 +        gtk_widget_destroy(assoc->req);
92 +        delete assoc;
93 + }
94 +
95 + static void cb_browse(GtkWidget *widget, void *user_data)
96 + {
97 +        GtkWidget *req = gtk_file_selection_new(GetString(STR_BROWSE_TITLE));
98 +        gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
99 +        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));
100 +        gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
101 +        gtk_widget_show(req);
102 + }
103 +
104 + static GtkWidget *make_browse_button(GtkWidget *entry)
105 + {
106 +        GtkWidget *button;
107 +
108 +        button = gtk_button_new_with_label(GetString(STR_BROWSE_CTRL));
109 +        gtk_widget_show(button);
110 +        gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc)cb_browse, (void *)entry);
111 +        return button;
112 + }
113 +
114   static void add_menu_item(GtkWidget *menu, int label_id, GtkSignalFunc func)
115   {
116          GtkWidget *item = gtk_menu_item_new_with_label(GetString(label_id));
# Line 132 | Line 174 | static GtkWidget *make_table(GtkWidget *
174          return table;
175   }
176  
177 + static GtkWidget *table_make_option_menu(GtkWidget *table, int row, int label_id, const opt_desc *options, int active)
178 + {
179 +        GtkWidget *label, *opt, *menu;
180 +
181 +        label = gtk_label_new(GetString(label_id));
182 +        gtk_widget_show(label);
183 +        gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
184 +
185 +        opt = gtk_option_menu_new();
186 +        gtk_widget_show(opt);
187 +        menu = gtk_menu_new();
188 +
189 +        while (options->label_id) {
190 +                add_menu_item(menu, options->label_id, options->func);
191 +                options++;
192 +        }
193 +        gtk_menu_set_active(GTK_MENU(menu), active);
194 +
195 +        gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
196 +        gtk_table_attach(GTK_TABLE(table), opt, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
197 +        return menu;
198 + }
199 +
200 + static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, GList *glist)
201 + {
202 +        GtkWidget *label, *combo;
203 +        char str[32];
204 +
205 +        label = gtk_label_new(GetString(label_id));
206 +        gtk_widget_show(label);
207 +        gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
208 +        
209 +        combo = gtk_combo_new();
210 +        gtk_widget_show(combo);
211 +        gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
212 +
213 +        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), default_value);
214 +        gtk_table_attach(GTK_TABLE(table), combo, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
215 +        
216 +        return combo;
217 + }
218 +
219 + static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, const combo_desc *options)
220 + {
221 +        GList *glist = NULL;
222 +        while (options->label_id) {
223 +                glist = g_list_append(glist, (void *)GetString(options->label_id));
224 +                options++;
225 +        }
226 +
227 +        return table_make_combobox(table, row, label_id, default_value, glist);
228 + }
229 +
230 + static GtkWidget *table_make_file_entry(GtkWidget *table, int row, int label_id, const char *prefs_item, bool only_dirs = false)
231 + {
232 +        GtkWidget *box, *label, *entry, *button;
233 +
234 +        label = gtk_label_new(GetString(label_id));
235 +        gtk_widget_show(label);
236 +        gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
237 +
238 +        const char *str = PrefsFindString(prefs_item);
239 +        if (str == NULL)
240 +                str = "";
241 +
242 +        box = gtk_hbox_new(FALSE, 4);
243 +        gtk_widget_show(box);
244 +        gtk_table_attach(GTK_TABLE(table), box, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
245 +
246 +        entry = gtk_entry_new();
247 +        gtk_entry_set_text(GTK_ENTRY(entry), str);
248 +        gtk_widget_show(entry);
249 +        gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
250 +
251 +        button = make_browse_button(entry);
252 +        gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
253 +        g_object_set_data(G_OBJECT(entry), "chooser_button", button);
254 +        return entry;
255 + }
256 +
257   static GtkWidget *make_option_menu(GtkWidget *top, int label_id, const opt_desc *options, int active)
258   {
259          GtkWidget *box, *label, *opt, *menu;
# Line 189 | Line 311 | static GtkWidget *make_file_entry(GtkWid
311          return entry;
312   }
313  
314 < static char *get_file_entry_path(GtkWidget *entry)
314 > static const gchar *get_file_entry_path(GtkWidget *entry)
315   {
316   #ifdef HAVE_GNOMEUI
317          return gnome_file_entry_get_full_path(GNOME_FILE_ENTRY(entry), false);
# Line 306 | Line 428 | static void mn_about(...)
428          dialog = gnome_about_new(
429                  "Basilisk II",
430                  version,
431 <                "Copyright (C) 1997-2004 Christian Bauer",
431 >                "Copyright (C) 1997-2005 Christian Bauer",
432                  authors,
433                  "Basilisk II comes with ABSOLUTELY NO WARRANTY."
434                  "This is free software, and you are welcome to redistribute it"
# Line 322 | Line 444 | static void mn_about(...)
444          char str[512];
445          sprintf(str,
446                  "Basilisk II\nVersion %d.%d\n\n"
447 <                "Copyright (C) 1997-2004 Christian Bauer et al.\n"
447 >                "Copyright (C) 1997-2005 Christian Bauer et al.\n"
448                  "E-mail: Christian.Bauer@uni-mainz.de\n"
449                  "http://www.uni-mainz.de/~bauec002/B2Main.html\n\n"
450                  "Basilisk II comes with ABSOLUTELY NO\n"
# Line 363 | Line 485 | static void mn_zap_pram(...)
485   // Menu item descriptions
486   static GtkItemFactoryEntry menu_items[] = {
487          {(gchar *)GetString(STR_PREFS_MENU_FILE_GTK),           NULL,                   NULL,                                                   0, "<Branch>"},
488 <        {(gchar *)GetString(STR_PREFS_ITEM_START_GTK),          NULL,                   GTK_SIGNAL_FUNC(cb_start),              0, NULL},
488 >        {(gchar *)GetString(STR_PREFS_ITEM_START_GTK),          "<control>S",   GTK_SIGNAL_FUNC(cb_start),              0, NULL},
489          {(gchar *)GetString(STR_PREFS_ITEM_ZAP_PRAM_GTK),       NULL,                   GTK_SIGNAL_FUNC(mn_zap_pram),   0, NULL},
490          {(gchar *)GetString(STR_PREFS_ITEM_SEPL_GTK),           NULL,                   NULL,                                                   0, "<Separator>"},
491          {(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK),           "<control>Q",   GTK_SIGNAL_FUNC(cb_quit),               0, NULL},
# Line 387 | Line 509 | bool PrefsEditor(void)
509          GtkAccelGroup *accel_group = gtk_accel_group_new();
510          GtkItemFactory *item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
511          gtk_item_factory_create_items(item_factory, sizeof(menu_items) / sizeof(menu_items[0]), menu_items, NULL);
512 + #if GTK_CHECK_VERSION(1,3,15)
513 +        gtk_window_add_accel_group(GTK_WINDOW(win), accel_group);
514 + #else
515          gtk_accel_group_attach(accel_group, GTK_OBJECT(win));
516 + #endif
517          GtkWidget *menu_bar = gtk_item_factory_get_widget(item_factory, "<main>");
518          gtk_widget_show(menu_bar);
519          gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, TRUE, 0);
# Line 433 | Line 559 | static void cl_selected(GtkWidget *list,
559          selected_volume = row;
560   }
561  
436 struct file_req_assoc {
437        file_req_assoc(GtkWidget *r, GtkWidget *e) : req(r), entry(e) {}
438        GtkWidget *req;
439        GtkWidget *entry;
440 };
441
562   // Volume selected for addition
563   static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc)
564   {
565 <        char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
565 >        gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
566          gtk_clist_append(GTK_CLIST(volume_list), &file);
567          gtk_widget_destroy(assoc->req);
568          delete assoc;
# Line 451 | Line 571 | static void add_volume_ok(GtkWidget *but
571   // Volume selected for creation
572   static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc)
573   {
574 <        char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
574 >        gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
575  
576 <        char *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry));
576 >        const gchar *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry));
577          int size = atoi(str);
578  
579          char cmd[1024];
# Line 589 | Line 709 | static GtkWidget *w_jit_fpu;
709   static GtkWidget *w_jit_atraps;
710   static GtkWidget *w_jit_cache_size;
711   static GtkWidget *w_jit_lazy_flush;
712 + static GtkWidget *w_jit_follow_const_jumps;
713  
714   // Set sensitivity of widgets
715   static void set_jit_sensitive(void)
# Line 597 | Line 718 | static void set_jit_sensitive(void)
718          gtk_widget_set_sensitive(w_jit_fpu, jit_enabled);
719          gtk_widget_set_sensitive(w_jit_cache_size, jit_enabled);
720          gtk_widget_set_sensitive(w_jit_lazy_flush, jit_enabled);
721 +        gtk_widget_set_sensitive(w_jit_follow_const_jumps, jit_enabled);
722   }
723  
724   // "Use JIT Compiler" button toggled
# Line 618 | Line 740 | static void tb_jit_lazy_flush(GtkWidget
740          PrefsReplaceBool("jitlazyflush", GTK_TOGGLE_BUTTON(widget)->active);
741   }
742  
743 + // "Translate through constant jumps (inline blocks)" button toggled
744 + static void tb_jit_follow_const_jumps(GtkWidget *widget)
745 + {
746 +        PrefsReplaceBool("jitinline", GTK_TOGGLE_BUTTON(widget)->active);
747 + }
748 +
749   // Read settings from widgets and set preferences
750   static void read_jit_settings(void)
751   {
# Line 654 | Line 782 | static void create_jit_pane(GtkWidget *t
782          
783          // Lazy translation cache invalidation
784          w_jit_lazy_flush = make_checkbox(box, STR_JIT_LAZY_CINV_CTRL, "jitlazyflush", GTK_SIGNAL_FUNC(tb_jit_lazy_flush));
785 <        
785 >
786 >        // Follow constant jumps (inline basic blocks)
787 >        w_jit_follow_const_jumps = make_checkbox(box, STR_JIT_FOLLOW_CONST_JUMPS, "jitinline", GTK_SIGNAL_FUNC(tb_jit_follow_const_jumps));
788 >
789          set_jit_sensitive();
790   #endif
791   }
# Line 979 | Line 1110 | static GtkWidget *w_mouse_wheel_lines;
1110   // Set sensitivity of widgets
1111   static void set_input_sensitive(void)
1112   {
1113 <        gtk_widget_set_sensitive(w_keycode_file, PrefsFindBool("keycodes"));
1113 >        const bool use_keycodes = PrefsFindBool("keycodes");
1114 >        gtk_widget_set_sensitive(w_keycode_file, use_keycodes);
1115 >        gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_keycode_file), "chooser_button")), use_keycodes);
1116          gtk_widget_set_sensitive(w_mouse_wheel_lines, PrefsFindInt32("mousewheelmode") == 1);
1117   }
1118  
# Line 1009 | Line 1142 | static void read_input_settings(void)
1142   // Create "Input" pane
1143   static void create_input_pane(GtkWidget *top)
1144   {
1145 <        GtkWidget *box, *hbox, *menu, *label;
1145 >        GtkWidget *box, *hbox, *menu, *label, *button;
1146          GtkObject *adj;
1147  
1148          box = make_pane(top, STR_INPUT_PANE_TITLE);
1149  
1150          make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes));
1151 <        w_keycode_file = make_file_entry(box, STR_KEYCODE_FILE_CTRL, "keycodefile");
1151 >
1152 >        hbox = gtk_hbox_new(FALSE, 4);
1153 >        gtk_widget_show(hbox);
1154 >        gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1155 >
1156 >        label = gtk_label_new(GetString(STR_KEYCODES_CTRL));
1157 >        gtk_widget_show(label);
1158 >        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1159 >
1160 >        const char *str = PrefsFindString("keycodefile");
1161 >        if (str == NULL)
1162 >                str = "";
1163 >
1164 >        w_keycode_file = gtk_entry_new();
1165 >        gtk_entry_set_text(GTK_ENTRY(w_keycode_file), str);
1166 >        gtk_widget_show(w_keycode_file);
1167 >        gtk_box_pack_start(GTK_BOX(hbox), w_keycode_file, TRUE, TRUE, 0);
1168 >
1169 >        button = make_browse_button(w_keycode_file);
1170 >        gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1171 >        g_object_set_data(G_OBJECT(w_keycode_file), "chooser_button", button);
1172  
1173          make_separator(box);
1174  
# Line 1163 | Line 1316 | static GList *add_ether_names(void)
1316                  }
1317                  close(s);
1318          }
1319 + #ifdef HAVE_SLIRP
1320 +        static char s_slirp[] = "slirp";
1321 +        glist = g_list_append(glist, s_slirp);
1322 + #endif
1323          if (glist)
1324                  g_list_sort(glist, gl_str_cmp);
1325          else
# Line 1252 | Line 1409 | static void create_serial_pane(GtkWidget
1409   *  "Memory/Misc" pane
1410   */
1411  
1412 < static GtkObject *w_ramsize_adj;
1412 > static GtkWidget *w_ramsize;
1413   static GtkWidget *w_rom_file;
1414  
1415   // "Ignore SEGV" button toggled
# Line 1277 | Line 1434 | static void mn_cpu_68040(...) {PrefsRepl
1434   // Read settings from widgets and set preferences
1435   static void read_memory_settings(void)
1436   {
1437 <        PrefsReplaceInt32("ramsize", int(GTK_ADJUSTMENT(w_ramsize_adj)->value) << 20);
1437 >        const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_ramsize)->entry));
1438 >        PrefsReplaceInt32("ramsize", atoi(str) << 20);
1439  
1440 <        const char *str = get_file_entry_path(w_rom_file);
1440 >        str = get_file_entry_path(w_rom_file);
1441          if (str && strlen(str))
1442                  PrefsReplaceString("rom", str);
1443          else
# Line 1290 | Line 1448 | static void read_memory_settings(void)
1448   // Create "Memory/Misc" pane
1449   static void create_memory_pane(GtkWidget *top)
1450   {
1451 <        GtkWidget *box, *hbox, *vbox, *hbox2, *label, *scale;
1451 >        GtkWidget *box, *hbox, *table, *label, *menu;
1452  
1453          box = make_pane(top, STR_MEMORY_MISC_PANE_TITLE);
1454 +        table = make_table(box, 2, 5);
1455  
1456 <        hbox = gtk_hbox_new(FALSE, 4);
1457 <        gtk_widget_show(hbox);
1458 <
1459 <        label = gtk_label_new(GetString(STR_RAMSIZE_SLIDER));
1460 <        gtk_widget_show(label);
1461 <        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1462 <
1463 <        vbox = gtk_vbox_new(FALSE, 4);
1464 <        gtk_widget_show(vbox);
1465 <
1466 <        gfloat min, max;
1467 <        min = 1;
1468 <        max = 1024;
1469 <        w_ramsize_adj = gtk_adjustment_new(min, min, max, 1, 16, 0);
1470 <        gtk_adjustment_set_value(GTK_ADJUSTMENT(w_ramsize_adj), PrefsFindInt32("ramsize") >> 20);
1471 <
1313 <        scale = gtk_hscale_new(GTK_ADJUSTMENT(w_ramsize_adj));
1314 <        gtk_widget_show(scale);
1315 <        gtk_scale_set_digits(GTK_SCALE(scale), 0);
1316 <        gtk_box_pack_start(GTK_BOX(vbox), scale, TRUE, TRUE, 0);
1317 <
1318 <        hbox2 = gtk_hbox_new(FALSE, 4);
1319 <        gtk_widget_show(hbox2);
1320 <
1321 <        char val[32];
1322 <        sprintf(val, GetString(STR_RAMSIZE_FMT), int(min));
1323 <        label = gtk_label_new(val);
1324 <        gtk_widget_show(label);
1325 <        gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
1326 <
1327 <        sprintf(val, GetString(STR_RAMSIZE_FMT), int(max));
1328 <        label = gtk_label_new(val);
1329 <        gtk_widget_show(label);
1330 <        gtk_box_pack_end(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
1331 <        gtk_box_pack_start(GTK_BOX(vbox), hbox2, TRUE, TRUE, 0);
1332 <        gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
1333 <        gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1456 >        static const combo_desc options[] = {
1457 >                STR_RAMSIZE_2MB_LAB,
1458 >                STR_RAMSIZE_4MB_LAB,
1459 >                STR_RAMSIZE_8MB_LAB,
1460 >                STR_RAMSIZE_16MB_LAB,
1461 >                STR_RAMSIZE_32MB_LAB,
1462 >                STR_RAMSIZE_64MB_LAB,
1463 >                STR_RAMSIZE_128MB_LAB,
1464 >                STR_RAMSIZE_256MB_LAB,
1465 >                STR_RAMSIZE_512MB_LAB,
1466 >                STR_RAMSIZE_1024MB_LAB,
1467 >                0
1468 >        };
1469 >        char default_ramsize[10];
1470 >        sprintf(default_ramsize, "%d", PrefsFindInt32("ramsize") >> 20);
1471 >        w_ramsize = table_make_combobox(table, 0, STR_RAMSIZE_CTRL, default_ramsize, options);
1472  
1473          static const opt_desc model_options[] = {
1474                  {STR_MODELID_5_LAB, GTK_SIGNAL_FUNC(mn_modelid_5)},
# Line 1342 | Line 1480 | static void create_memory_pane(GtkWidget
1480                  case 5: active = 0; break;
1481                  case 14: active = 1; break;
1482          }
1483 <        make_option_menu(box, STR_MODELID_CTRL, model_options, active);
1483 >        table_make_option_menu(table, 2, STR_MODELID_CTRL, model_options, active);
1484  
1485   #if EMULATED_68K
1486          static const opt_desc cpu_options[] = {
# Line 1361 | Line 1499 | static void create_memory_pane(GtkWidget
1499                  case 3: active = fpu ? 3 : 2; break;
1500                  case 4: active = 4;
1501          }
1502 <        make_option_menu(box, STR_CPU_CTRL, cpu_options, active);
1502 >        table_make_option_menu(table, 3, STR_CPU_CTRL, cpu_options, active);
1503   #endif
1504  
1505 <        w_rom_file = make_file_entry(box, STR_ROM_FILE_CTRL, "rom");
1505 >        w_rom_file = table_make_file_entry(table, 4, STR_ROM_FILE_CTRL, "rom");
1506  
1507   #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
1508          make_checkbox(box, STR_IGNORESEGV_CTRL, "ignoresegv", GTK_SIGNAL_FUNC(tb_ignoresegv));
# Line 1386 | Line 1524 | static void read_settings(void)
1524          read_memory_settings();
1525          read_jit_settings();
1526   }
1527 +
1528 +
1529 + #ifdef STANDALONE_GUI
1530 + #include <errno.h>
1531 + #include <sys/wait.h>
1532 + #include "rpc.h"
1533 +
1534 + /*
1535 + *  Fake unused data and functions
1536 + */
1537 +
1538 + uint8 XPRAM[XPRAM_SIZE];
1539 + void MountVolume(void *fh) { }
1540 + void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size) { }
1541 +
1542 +
1543 + /*
1544 + *  Display alert
1545 + */
1546 +
1547 + static void dl_destroyed(void)
1548 + {
1549 +        gtk_main_quit();
1550 + }
1551 +
1552 + static void display_alert(int title_id, int prefix_id, int button_id, const char *text)
1553 + {
1554 +        char str[256];
1555 +        sprintf(str, GetString(prefix_id), text);
1556 +
1557 +        GtkWidget *dialog = gtk_dialog_new();
1558 +        gtk_window_set_title(GTK_WINDOW(dialog), GetString(title_id));
1559 +        gtk_container_border_width(GTK_CONTAINER(dialog), 5);
1560 +        gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150);
1561 +        gtk_signal_connect(GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(dl_destroyed), NULL);
1562 +
1563 +        GtkWidget *label = gtk_label_new(str);
1564 +        gtk_widget_show(label);
1565 +        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
1566 +
1567 +        GtkWidget *button = gtk_button_new_with_label(GetString(button_id));
1568 +        gtk_widget_show(button);
1569 +        gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog));
1570 +        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0);
1571 +        GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
1572 +        gtk_widget_grab_default(button);
1573 +        gtk_widget_show(dialog);
1574 +
1575 +        gtk_main();
1576 + }
1577 +
1578 +
1579 + /*
1580 + *  Display error alert
1581 + */
1582 +
1583 + void ErrorAlert(const char *text)
1584 + {
1585 +        display_alert(STR_ERROR_ALERT_TITLE, STR_GUI_ERROR_PREFIX, STR_QUIT_BUTTON, text);
1586 + }
1587 +
1588 +
1589 + /*
1590 + *  Display warning alert
1591 + */
1592 +
1593 + void WarningAlert(const char *text)
1594 + {
1595 +        display_alert(STR_WARNING_ALERT_TITLE, STR_GUI_WARNING_PREFIX, STR_OK_BUTTON, text);
1596 + }
1597 +
1598 +
1599 + /*
1600 + *  RPC handlers
1601 + */
1602 +
1603 + static int handle_ErrorAlert(rpc_connection_t *connection)
1604 + {
1605 +        D(bug("handle_ErrorAlert\n"));
1606 +
1607 +        int error;
1608 +        char *str;
1609 +        if ((error = rpc_method_get_args(connection, RPC_TYPE_STRING, &str, RPC_TYPE_INVALID)) < 0)
1610 +                return error;
1611 +
1612 +        ErrorAlert(str);
1613 +        free(str);
1614 +        return RPC_ERROR_NO_ERROR;
1615 + }
1616 +
1617 + static int handle_WarningAlert(rpc_connection_t *connection)
1618 + {
1619 +        D(bug("handle_WarningAlert\n"));
1620 +
1621 +        int error;
1622 +        char *str;
1623 +        if ((error = rpc_method_get_args(connection, RPC_TYPE_STRING, &str, RPC_TYPE_INVALID)) < 0)
1624 +                return error;
1625 +
1626 +        WarningAlert(str);
1627 +        free(str);
1628 +        return RPC_ERROR_NO_ERROR;
1629 + }
1630 +
1631 + static int handle_Exit(rpc_connection_t *connection)
1632 + {
1633 +        D(bug("handle_Exit\n"));
1634 +
1635 +        return RPC_ERROR_NO_ERROR;
1636 + }
1637 +
1638 +
1639 + /*
1640 + *  Start standalone GUI
1641 + */
1642 +
1643 + int main(int argc, char *argv[])
1644 + {
1645 + #ifdef HAVE_GNOMEUI
1646 +        // Init GNOME/GTK
1647 +        char version[16];
1648 +        sprintf(version, "%d.%d", VERSION_MAJOR, VERSION_MINOR);
1649 +        gnome_init("Basilisk II", version, argc, argv);
1650 + #else
1651 +        // Init GTK
1652 +        gtk_set_locale();
1653 +        gtk_init(&argc, &argv);
1654 + #endif
1655 +
1656 +        // Read preferences
1657 +        PrefsInit(argc, argv);
1658 +
1659 +        // Show preferences editor
1660 +        bool start = PrefsEditor();
1661 +
1662 +        // Exit preferences
1663 +        PrefsExit();
1664 +
1665 +        // Transfer control to the executable
1666 +        if (start) {
1667 +                char gui_connection_path[64];
1668 +                sprintf(gui_connection_path, "/org/BasiliskII/GUI/%d", getpid());
1669 +                
1670 +                int pid = fork();
1671 +                if (pid == 0) {                 // Child
1672 +                        char b2_path[PATH_MAX];
1673 +                        strcpy(b2_path, argv[0]);
1674 +                        char *p = strrchr(b2_path, '/');
1675 +                        p = p ? p + 1 : b2_path;
1676 +                        *p = '\0';
1677 +                        strcat(b2_path, "BasiliskII");
1678 +                        execl(b2_path, b2_path, "--gui-connection", gui_connection_path, (char *)NULL);
1679 +
1680 +                        char str[256];
1681 +                        sprintf(str, GetString(STR_NO_B2_EXE_FOUND), b2_path, strerror(errno));
1682 +                        ErrorAlert(str);
1683 +                        return 1;
1684 +                }
1685 +                else {                                  // Parent
1686 +                        rpc_connection_t *connection;
1687 +                        if ((connection = rpc_init_server(gui_connection_path)) == NULL) {
1688 +                        printf("ERROR: failed to initialize GUI-side RPC server connection\n");
1689 +                        return 1;
1690 +                        }
1691 +
1692 +                        static const rpc_method_descriptor_t vtable[] = {
1693 +                                { RPC_METHOD_ERROR_ALERT,                       handle_ErrorAlert },
1694 +                                { RPC_METHOD_WARNING_ALERT,                     handle_WarningAlert },
1695 +                                { RPC_METHOD_EXIT,                                      handle_Exit }
1696 +                        };
1697 +                        if (rpc_method_add_callbacks(connection, vtable, sizeof(vtable) / sizeof(vtable[0])) < 0) {
1698 +                                printf("ERROR: failed to setup GUI method callbacks\n");
1699 +                                return 1;
1700 +                        }
1701 +
1702 +                        if (rpc_listen(connection) < 0) {
1703 +                                printf("ERROR: failed to initialize RPC server thread\n");
1704 +                                return 1;
1705 +                        }
1706 +
1707 +                        int status, ret = -1;
1708 +                        while (waitpid(pid, &status, 0) != pid)
1709 +                                ;
1710 +                        if (WIFEXITED(status))
1711 +                                ret = WEXITSTATUS(status);
1712 +
1713 +                        rpc_exit(connection);
1714 +                        return ret;
1715 +                }
1716 +        }
1717 +
1718 +        return 0;
1719 + }
1720 + #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines