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.29 by gbeauche, 2005-11-21T21:39:08Z vs.
Revision 1.36 by gbeauche, 2006-04-18T21:29:01Z

# 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
48 < static bool start_clicked = true;       // Return value of PrefsEditor() function
48 > static bool start_clicked = false;      // Return value of PrefsEditor() function
49  
50  
51   // Prototypes
# 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 115 | Line 124 | static GtkWidget *make_pane(GtkWidget *n
124          GtkWidget *frame, *label, *box;
125  
126          frame = gtk_frame_new(NULL);
127 <        gtk_widget_show(frame);
119 <        gtk_container_border_width(GTK_CONTAINER(frame), 4);
120 <
121 <        label = gtk_label_new(GetString(title_id));
122 <        gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
127 >        gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
128  
129          box = gtk_vbox_new(FALSE, 4);
125        gtk_widget_show(box);
130          gtk_container_set_border_width(GTK_CONTAINER(box), 4);
131          gtk_container_add(GTK_CONTAINER(frame), box);
132 +
133 +        gtk_widget_show_all(frame);
134 +
135 +        label = gtk_label_new(GetString(title_id));
136 +        gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
137          return box;
138   }
139  
# Line 419 | 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 435 | 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 510 | Line 519 | bool PrefsEditor(void)
519          gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, TRUE, 0);
520  
521          GtkWidget *notebook = gtk_notebook_new();
513        gtk_widget_show(notebook);
522          gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
523          gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), FALSE);
524          gtk_box_pack_start(GTK_BOX(box), notebook, TRUE, TRUE, 0);
525 +        gtk_widget_realize(notebook);
526  
527          create_volumes_pane(notebook);
528          create_scsi_pane(notebook);
# Line 522 | Line 531 | bool PrefsEditor(void)
531          create_serial_pane(notebook);
532          create_memory_pane(notebook);
533          create_jit_pane(notebook);
534 +        gtk_widget_show(notebook);
535  
536          static const opt_desc buttons[] = {
537                  {STR_START_BUTTON, GTK_SIGNAL_FUNC(cb_start)},
# Line 702 | Line 712 | static GtkWidget *w_jit_cache_size;
712   static GtkWidget *w_jit_lazy_flush;
713   static GtkWidget *w_jit_follow_const_jumps;
714  
715 + // Are we running a JIT capable CPU?
716 + static bool is_jit_capable(void)
717 + {
718 + #if USE_JIT && (defined __i386__ || defined __x86_64__)
719 +        return true;
720 + #elif defined __APPLE__ && defined __MACH__
721 +        // XXX run-time detect so that we can use a PPC GUI prefs editor
722 +        static char cpu[10];
723 +        if (cpu[0] == 0) {
724 +                FILE *fp = popen("uname -p", "r");
725 +                if (fp == NULL)
726 +                        return false;
727 +                fgets(cpu, sizeof(cpu) - 1, fp);
728 +                fclose(fp);
729 +        }
730 +        if (cpu[0] == 'i' && cpu[2] == '8' && cpu[3] == '6') // XXX assuming i?86
731 +                return true;
732 + #endif
733 +        return false;
734 + }
735 +
736   // Set sensitivity of widgets
737   static void set_jit_sensitive(void)
738   {
# Line 740 | Line 771 | static void tb_jit_follow_const_jumps(Gt
771   // Read settings from widgets and set preferences
772   static void read_jit_settings(void)
773   {
774 < #if USE_JIT
744 <        bool jit_enabled = PrefsFindBool("jit");
774 >        bool jit_enabled = is_jit_capable() && PrefsFindBool("jit");
775          if (jit_enabled) {
776                  const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_jit_cache_size)->entry));
777                  PrefsReplaceInt32("jitcachesize", atoi(str));
778          }
749 #endif
779   }
780  
781   // Create "JIT Compiler" pane
782   static void create_jit_pane(GtkWidget *top)
783   {
784 < #if USE_JIT
784 >        if (!is_jit_capable())
785 >                return;
786 >
787          GtkWidget *box, *table, *label, *menu;
788          char str[32];
789          
# Line 778 | Line 809 | static void create_jit_pane(GtkWidget *t
809          w_jit_follow_const_jumps = make_checkbox(box, STR_JIT_FOLLOW_CONST_JUMPS, "jitinline", GTK_SIGNAL_FUNC(tb_jit_follow_const_jumps));
810  
811          set_jit_sensitive();
781 #endif
812   }
813  
814   /*
# Line 1515 | Line 1545 | static void read_settings(void)
1545          read_memory_settings();
1546          read_jit_settings();
1547   }
1548 +
1549 +
1550 + #ifdef STANDALONE_GUI
1551 + #include <errno.h>
1552 + #include <sys/wait.h>
1553 + #include "rpc.h"
1554 +
1555 + /*
1556 + *  Fake unused data and functions
1557 + */
1558 +
1559 + uint8 XPRAM[XPRAM_SIZE];
1560 + void MountVolume(void *fh) { }
1561 + void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size) { }
1562 +
1563 + #if defined __APPLE__ && defined __MACH__
1564 + void DarwinAddCDROMPrefs(void) { }
1565 + void DarwinAddFloppyPrefs(void) { }
1566 + void DarwinAddSerialPrefs(void) { }
1567 + bool DarwinCDReadTOC(char *, uint8 *) { }
1568 + #endif
1569 +
1570 +
1571 + /*
1572 + *  Display alert
1573 + */
1574 +
1575 + static void dl_destroyed(void)
1576 + {
1577 +        gtk_main_quit();
1578 + }
1579 +
1580 + static void display_alert(int title_id, int prefix_id, int button_id, const char *text)
1581 + {
1582 +        char str[256];
1583 +        sprintf(str, GetString(prefix_id), text);
1584 +
1585 +        GtkWidget *dialog = gtk_dialog_new();
1586 +        gtk_window_set_title(GTK_WINDOW(dialog), GetString(title_id));
1587 +        gtk_container_border_width(GTK_CONTAINER(dialog), 5);
1588 +        gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150);
1589 +        gtk_signal_connect(GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(dl_destroyed), NULL);
1590 +
1591 +        GtkWidget *label = gtk_label_new(str);
1592 +        gtk_widget_show(label);
1593 +        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
1594 +
1595 +        GtkWidget *button = gtk_button_new_with_label(GetString(button_id));
1596 +        gtk_widget_show(button);
1597 +        gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog));
1598 +        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0);
1599 +        GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
1600 +        gtk_widget_grab_default(button);
1601 +        gtk_widget_show(dialog);
1602 +
1603 +        gtk_main();
1604 + }
1605 +
1606 +
1607 + /*
1608 + *  Display error alert
1609 + */
1610 +
1611 + void ErrorAlert(const char *text)
1612 + {
1613 +        display_alert(STR_ERROR_ALERT_TITLE, STR_GUI_ERROR_PREFIX, STR_QUIT_BUTTON, text);
1614 + }
1615 +
1616 +
1617 + /*
1618 + *  Display warning alert
1619 + */
1620 +
1621 + void WarningAlert(const char *text)
1622 + {
1623 +        display_alert(STR_WARNING_ALERT_TITLE, STR_GUI_WARNING_PREFIX, STR_OK_BUTTON, text);
1624 + }
1625 +
1626 +
1627 + /*
1628 + *  RPC handlers
1629 + */
1630 +
1631 + static GMainLoop *g_gui_loop;
1632 +
1633 + static int handle_ErrorAlert(rpc_connection_t *connection)
1634 + {
1635 +        D(bug("handle_ErrorAlert\n"));
1636 +
1637 +        int error;
1638 +        char *str;
1639 +        if ((error = rpc_method_get_args(connection, RPC_TYPE_STRING, &str, RPC_TYPE_INVALID)) < 0)
1640 +                return error;
1641 +
1642 +        ErrorAlert(str);
1643 +        free(str);
1644 +        return RPC_ERROR_NO_ERROR;
1645 + }
1646 +
1647 + static int handle_WarningAlert(rpc_connection_t *connection)
1648 + {
1649 +        D(bug("handle_WarningAlert\n"));
1650 +
1651 +        int error;
1652 +        char *str;
1653 +        if ((error = rpc_method_get_args(connection, RPC_TYPE_STRING, &str, RPC_TYPE_INVALID)) < 0)
1654 +                return error;
1655 +
1656 +        WarningAlert(str);
1657 +        free(str);
1658 +        return RPC_ERROR_NO_ERROR;
1659 + }
1660 +
1661 + static int handle_Exit(rpc_connection_t *connection)
1662 + {
1663 +        D(bug("handle_Exit\n"));
1664 +
1665 +        g_main_quit(g_gui_loop);
1666 +        return RPC_ERROR_NO_ERROR;
1667 + }
1668 +
1669 +
1670 + /*
1671 + *  SIGCHLD handler
1672 + */
1673 +
1674 + static char g_app_path[PATH_MAX];
1675 + static rpc_connection_t *g_gui_connection = NULL;
1676 +
1677 + static void sigchld_handler(int sig, siginfo_t *sip, void *)
1678 + {
1679 +        D(bug("Child %d exitted with status = %x\n", sip->si_pid, sip->si_status));
1680 +
1681 +        int status = sip->si_status;
1682 +        if (status & 0x80)
1683 +                status |= -1 ^0xff;
1684 +
1685 +        if (status < 0) {       // negative -> execlp/-errno
1686 +                char str[256];
1687 +                sprintf(str, GetString(STR_NO_B2_EXE_FOUND), g_app_path, strerror(-status));
1688 +                ErrorAlert(str);
1689 +                status = 1;
1690 +        }
1691 +
1692 +        if (status != 0) {
1693 +                if (g_gui_connection)
1694 +                        rpc_exit(g_gui_connection);
1695 +                exit(status);
1696 +        }
1697 + }
1698 +
1699 +
1700 + /*
1701 + *  Start standalone GUI
1702 + */
1703 +
1704 + int main(int argc, char *argv[])
1705 + {
1706 + #ifdef HAVE_GNOMEUI
1707 +        // Init GNOME/GTK
1708 +        char version[16];
1709 +        sprintf(version, "%d.%d", VERSION_MAJOR, VERSION_MINOR);
1710 +        gnome_init("Basilisk II", version, argc, argv);
1711 + #else
1712 +        // Init GTK
1713 +        gtk_set_locale();
1714 +        gtk_init(&argc, &argv);
1715 + #endif
1716 +
1717 +        // Read preferences
1718 +        PrefsInit(argc, argv);
1719 +
1720 +        // Show preferences editor
1721 +        bool start = PrefsEditor();
1722 +
1723 +        // Exit preferences
1724 +        PrefsExit();
1725 +
1726 +        // Transfer control to the executable
1727 +        if (start) {
1728 +                char gui_connection_path[64];
1729 +                sprintf(gui_connection_path, "/org/BasiliskII/GUI/%d", getpid());
1730 +
1731 +                // Catch exits from the child process
1732 +                struct sigaction sigchld_sa, old_sigchld_sa;
1733 +                sigemptyset(&sigchld_sa.sa_mask);
1734 +                sigchld_sa.sa_sigaction = sigchld_handler;
1735 +                sigchld_sa.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
1736 +                if (sigaction(SIGCHLD, &sigchld_sa, &old_sigchld_sa) < 0) {
1737 +                        char str[256];
1738 +                        sprintf(str, GetString(STR_SIG_INSTALL_ERR), SIGCHLD, strerror(errno));
1739 +                        ErrorAlert(str);
1740 +                        return 1;
1741 +                }
1742 +
1743 +                // Search and run the BasiliskII executable
1744 +                // XXX it can be in a bundle on MacOS X
1745 +                strcpy(g_app_path, argv[0]);
1746 +                char *p = strrchr(g_app_path, '/');
1747 +                p = p ? p + 1 : g_app_path;
1748 +                *p = '\0';
1749 +                strcat(g_app_path, "BasiliskII");
1750 +
1751 +                int pid = fork();
1752 +                if (pid == 0) {
1753 +                        execlp(g_app_path, g_app_path, "--gui-connection", gui_connection_path, (char *)NULL);
1754 + #ifdef _POSIX_PRIORITY_SCHEDULING
1755 +                        // XXX get a chance to run the parent process so that to not confuse/upset GTK...
1756 +                        sched_yield();
1757 + #endif
1758 +                        _exit(-errno);
1759 +                }
1760 +
1761 +                // Establish a connection to Basilisk II
1762 +                if ((g_gui_connection = rpc_init_server(gui_connection_path)) == NULL) {
1763 +                        printf("ERROR: failed to initialize GUI-side RPC server connection\n");
1764 +                        return 1;
1765 +                }
1766 +                static const rpc_method_descriptor_t vtable[] = {
1767 +                        { RPC_METHOD_ERROR_ALERT,                       handle_ErrorAlert },
1768 +                        { RPC_METHOD_WARNING_ALERT,                     handle_WarningAlert },
1769 +                        { RPC_METHOD_EXIT,                                      handle_Exit }
1770 +                };
1771 +                if (rpc_method_add_callbacks(g_gui_connection, vtable, sizeof(vtable) / sizeof(vtable[0])) < 0) {
1772 +                        printf("ERROR: failed to setup GUI method callbacks\n");
1773 +                        return 1;
1774 +                }
1775 +                int socket;
1776 +                if ((socket = rpc_listen_socket(g_gui_connection)) < 0) {
1777 +                        printf("ERROR: failed to initialize RPC server thread\n");
1778 +                        return 1;
1779 +                }
1780 +
1781 +                g_gui_loop = g_main_new(TRUE);
1782 +                while (g_main_is_running(g_gui_loop)) {
1783 +
1784 +                        // Process a few events pending
1785 +                        const int N_EVENTS_DISPATCH = 10;
1786 +                        for (int i = 0; i < N_EVENTS_DISPATCH; i++) {
1787 +                                if (!g_main_iteration(FALSE))
1788 +                                        break;
1789 +                        }
1790 +
1791 +                        // Check for RPC events (100 ms timeout)
1792 +                        int ret = rpc_wait_dispatch(g_gui_connection, 100000);
1793 +                        if (ret == 0)
1794 +                                continue;
1795 +                        if (ret < 0)
1796 +                                break;
1797 +                        rpc_dispatch(g_gui_connection);
1798 +                }
1799 +
1800 +                rpc_exit(g_gui_connection);
1801 +                return 0;
1802 +        }
1803 +
1804 +        return 0;
1805 + }
1806 + #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines