Unix: Support for GTK 3

- Minimum version required is GTK 3.14.5
- Choose version using the --with-gtk={2,3} configure option
- Settings UI has been ported to GtkBuilder XML files
New features:
- Native file chooser support (with GTK_USE_PORTAL=1 envvar)
- CD-ROMs, both real and virtual, are listed in the volumes pane
- Use the checkbox to set a volume as a CD-ROM
- Header bar on DEs that use it, menu bar on those that don't
- Additional options including hotkey, swap_opt_cmd and nogui
This commit is contained in:
robxnano
2024-08-07 18:25:59 +01:00
parent 2658de9556
commit d1b288ba19
29 changed files with 4394 additions and 114 deletions

View File

@@ -20,6 +20,12 @@ cputbl.h
cpuemu_nf.cpp
cpustbl_nf.cpp
cpufunctbl.cpp
compemu.cpp
compstbl.cpp
comptbl.h
# Generated GLib resource files
g_resource.cpp
patches/*
.pc*

View File

@@ -17,6 +17,7 @@ DESTDIR =
CC = @CC@
CXX = @CXX@
GCR = @GCR@
CFLAGS = @CFLAGS@
CXXFLAGS = @CXXFLAGS@
CPUINCLUDES_FLAGS=@CPUINCLUDES@
@@ -45,6 +46,9 @@ GUI_LIBS = @GUI_LIBS@
GUI_SRCS = ../prefs.cpp prefs_unix.cpp prefs_editor_gtk.cpp ../prefs_items.cpp \
../user_strings.cpp user_strings_unix.cpp xpram_unix.cpp sys_unix.cpp rpc_unix.cpp
GRESOURCE_SRCS = ui/help-overlay.ui ui/menu.ui ui/prefs-editor.ui
GRESOURCE_XML = ui/basiliskii.gresource.xml
XPLAT_SRCS = ../CrossPlatform/vm_alloc.cpp ../CrossPlatform/sigsegv.cpp ../CrossPlatform/video_blit.cpp
## Files
@@ -171,10 +175,10 @@ uninstall:
rmdir $(DESTDIR)$(datadir)/$(APP)
mostlyclean:
rm -f $(PROGS) $(OBJ_DIR)/* core* *.core *~ *.bak
rm -f $(PROGS) $(OBJ_DIR)/* core* *.core *~ *.bak ui/*~ ui/*.bak
clean: mostlyclean
rm -f cpuemu.cpp cpudefs.cpp cputmp*.s cpufast*.s cpustbl.cpp cputbl.h compemu.cpp compstbl.cpp comptbl.h
rm -f cpuemu.cpp cpudefs.cpp cputmp*.s cpufast*.s cpustbl.cpp cputbl.h compemu.cpp compstbl.cpp comptbl.h g_resource.cpp
distclean: clean
rm -rf $(OBJ_DIR)
@@ -288,5 +292,8 @@ $(OBJ_DIR)/compemu7.o: compemu.cpp
$(OBJ_DIR)/compemu8.o: compemu.cpp
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_8 $(CXXFLAGS) -c $< -o $@
g_resource.cpp: $(GRESOURCE_SRCS) $(GRESOURCE_XML)
$(GCR) --generate-source $(GRESOURCE_XML) --target $@
#-------------------------------------------------------------------------
# DO NOT DELETE THIS LINE -- make depend depends on it.

View File

@@ -74,12 +74,14 @@ AC_ARG_ENABLE(addressing,
dnl External packages.
AC_ARG_WITH(esd, [ --with-esd support ESD for sound under Linux/FreeBSD [default=yes]], [WANT_ESD=$withval], [WANT_ESD=yes])
AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]],
AC_ARG_WITH(gtk, [ --with-gtk use GTK 2 or 3 for user interface [default=any]],
[case "$withval" in
yes|gtk2) WANT_GTK="gtk2";;
*) WANT_GTK="no";;
yes|true|any) WANT_GTK="any";;
*3) WANT_GTK="GTK3";;
*2) WANT_GTK="GTK2";;
*) WANT_GTK="no";;
esac],
[WANT_GTK="gtk2"])
[WANT_GTK="any"])
AC_ARG_WITH(mon, [ --with-mon use mon as debugger [default=no]], [WANT_MON=$withval], [WANT_MON=no])
AC_ARG_WITH(bincue,
@@ -458,24 +460,57 @@ if [[ "x$WANT_XF86_VIDMODE" = "xyes" ]]; then
])
fi
# Check for pkg-config macro, thanks to rdiez
m4_ifndef([PKG_PROG_PKG_CONFIG], [m4_fatal(
[The PKG_PROG_PKG_CONFIG macro is not available. You need to install pkg-config.]
)])
PKG_PROG_PKG_CONFIG
dnl We use GTK+ if possible.
UISRCS=../dummy/prefs_editor_dummy.cpp
if [[ "x$WANT_GTK" = "xgtk2" ]]; then
AM_PATH_GTK_2_0(2.6.4, [
GUI_CFLAGS="$GTK_CFLAGS"
GUI_LIBS="$GTK_LIBS"
WANT_GTK=gtk2
if [[ "$WANT_GTK" = "any" -o "$WANT_GTK" = "GTK3" ]]; then
PKG_CHECK_MODULES([GTK3], [gtk+-3.0 >= 3.14.5], [
WANT_GTK=GTK3
GUI_CFLAGS="$GTK3_CFLAGS"
GUI_LIBS="$GTK3_LIBS"
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
AC_CHECK_PROG([ac_cv_gcr], [glib-compile-resources], [yes])
if [[ "$ac_cv_gcr" = "yes" ]]; then
GCR="glib-compile-resources"
else
AC_MSG_ERROR([glib-compile-resources not found.])
fi
], [
AC_MSG_WARN([Could not find GTK+ 2.0, disabling user interface.])
if [[ "$WANT_GTK" = "any" ]]; then
AC_MSG_WARN([Could not find GTK3 (version >= 3.14.5), falling back to GTK2.])
WANT_GTK=GTK2
else
AC_MSG_WARN([Could not find GTK3 (version >= 3.14.5), disabling user interface.])
WANT_GTK=no
fi
])
fi
if [[ "$WANT_GTK" = "GTK2" ]]; then
PKG_CHECK_MODULES([GTK2], [gtk+-2.0 >= 2.6.4], [
WANT_GTK=GTK2
GUI_CFLAGS="$GTK2_CFLAGS"
GUI_LIBS="$GTK2_LIBS"
], [
AC_MSG_WARN([Could not find GTK2 (version >= 2.6.4), disabling user interface.])
WANT_GTK=no
])
fi
if [[ "x$WANT_GTK" != "xno" -a "x$WANT_STANDALONE_GUI" = "xno" ]]; then
AC_DEFINE(ENABLE_GTK, 1, [Define if using GTK.])
UISRCS=prefs_editor_gtk.cpp
if [[ "$WANT_GTK" = "GTK3" ]]; then
UISRCS="prefs_editor_gtk3.cpp g_resource.cpp"
else
UISRCS="prefs_editor_gtk.cpp"
fi
fi
AC_SUBST(GUI_CFLAGS)
AC_SUBST(GUI_LIBS)
AC_SUBST(GCR)
dnl Build external GUI if requested.
if [[ "$WANT_STANDALONE_GUI" != "yes" ]]; then

View File

@@ -70,6 +70,9 @@ struct sigstate {
# if !defined(GDK_WINDOWING_QUARTZ) && !defined(GDK_WINDOWING_WAYLAND)
# include <X11/Xlib.h>
# endif
# if GTK_CHECK_VERSION(3, 14, 0)
# define ENABLE_GTK3
# endif
#endif
#ifdef ENABLE_XF86_DGA
@@ -155,6 +158,7 @@ static uint8 last_xpram[XPRAM_SIZE]; // Buffer for monitoring XPRAM changes
#if !EMULATED_68K
static pthread_t emul_thread; // Handle of MacOS emulation thread (main thread)
#endif
static int use_gui = -1; // Override prefs and show gui
static bool xpram_thread_active = false; // Flag: XPRAM watchdog installed
static volatile bool xpram_thread_cancel = false; // Flag: Cancel XPRAM thread
@@ -414,8 +418,33 @@ static void usage(const char *prg_name)
exit(0);
}
#ifdef ENABLE_GTK
GtkWindow *win;
static void gui_startup (void)
{
if (!PrefsEditor())
QuitEmulator();
}
#ifdef ENABLE_GTK3
static void gui_activate (GtkApplication *app)
{
g_assert (GTK_IS_APPLICATION (app));
win = gtk_application_get_active_window (app);
/* Ask the window manager/compositor to present the window. */
if (win != NULL)
gtk_window_present (win);
}
#endif
#endif
int main(int argc, char **argv)
{
#ifdef ENABLE_GTK3
GtkApplication *app = NULL;
int ret;
#endif
#if defined(ENABLE_GTK) && !defined(GDK_WINDOWING_QUARTZ) && !defined(GDK_WINDOWING_WAYLAND)
XInitThreads();
#endif
@@ -478,6 +507,21 @@ int main(int argc, char **argv)
printf("switch address not defined\n");
usage(argv[0]);
}
// We intercept the --nogui commandline so that the settings
// window can change the setting from the prefs file
} else if (strcmp(argv[i], "--nogui") == 0) {
argv[i++] = NULL;
if (i < argc) {
if (strcmp(argv[i], "true") == 0)
use_gui = false;
else
use_gui = true;
argv[i] = NULL;
}
// Alternative commands to enter the GUI
} else if (strcmp(argv[i], "--gui") == 0 || strcmp(argv[i], "--settings") == 0) {
use_gui = true;
argv[i] = NULL;
vde_sock = argv[i];
argv[i] = NULL;
}
@@ -518,16 +562,11 @@ int main(int argc, char **argv)
}
}
#ifdef ENABLE_GTK
if (!gui_connection) {
// Init GTK
gtk_set_locale();
gtk_init(&argc, &argv);
}
#endif
// Read preferences
PrefsInit(vmdir, argc, argv);
// Only use nogui preference if not passed as command line argument
if (use_gui == -1)
use_gui = !PrefsFindBool("nogui");
// Any command line arguments left?
for (int i=1; i<argc; i++) {
@@ -586,10 +625,24 @@ int main(int argc, char **argv)
// Init system routines
SysInit();
// Show preferences editor
if (!gui_connection && !PrefsFindBool("nogui"))
if (!PrefsEditor())
QuitEmulator();
#ifdef ENABLE_GTK3
if (!gui_connection) {
// Init GTK
app = gtk_application_new (GetString(STR_APP_ID), G_APPLICATION_FLAGS_NONE);
g_set_prgname (GetString(STR_APP_DISPLAY_NAME));
g_signal_connect (app, "activate", G_CALLBACK (gui_activate), NULL);
g_signal_connect (app, "startup", G_CALLBACK (gui_startup), NULL);
g_application_register (G_APPLICATION (app), NULL, NULL);
ret = g_application_run (G_APPLICATION (app), argc, argv);
}
#elif defined(ENABLE_GTK)
if (!gui_connection) {
// Init GTK
gtk_set_locale();
gtk_init(&argc, &argv);
gui_startup();
}
#endif
// Install the handler for SIGSEGV
if (!sigsegv_install_handler(sigsegv_handler)) {
@@ -633,7 +686,7 @@ int main(int argc, char **argv)
#else
const bool can_map_all_memory = false;
#endif
// Try to allocate all memory from 0x0000, if it is not known to crash
if (can_map_all_memory && (vm_acquire_mac_fixed(0, RAMSize + 0x100000) == 0)) {
D(bug("Could allocate RAM and ROM from 0x0000\n"));

View File

@@ -227,7 +227,7 @@ static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, c
label = gtk_label_new(GetString(label_id));
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
combo = gtk_combo_box_entry_new_text();
gtk_widget_show(combo);
while(list)
@@ -238,7 +238,7 @@ static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, c
gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN (combo))), pref);
gtk_table_attach(GTK_TABLE(table), combo, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
return combo;
}
@@ -270,7 +270,7 @@ static GtkWidget *table_make_file_entry(GtkWidget *table, int row, int label_id,
gtk_table_attach(GTK_TABLE(table), box, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
entry = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(entry), str);
gtk_entry_set_text(GTK_ENTRY(entry), str);
gtk_widget_show(entry);
gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
@@ -322,7 +322,7 @@ static GtkWidget *make_file_entry(GtkWidget *top, int label_id, const char *pref
str = "";
entry = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(entry), str);
gtk_entry_set_text(GTK_ENTRY(entry), str);
button = make_browse_button(entry, only_dirs);
gtk_widget_show(entry);
@@ -374,11 +374,11 @@ static GtkWidget *make_combobox(GtkWidget *top, int label_id, const char *prefs_
sprintf(str, "%d", PrefsFindInt32(prefs_item));
gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN (combo))), str);
gtk_box_pack_start(GTK_BOX(box), combo, TRUE, TRUE, 0);
return combo;
}
/*
* Show preferences editor
* Returns true when user clicked on "Start", false otherwise
@@ -585,7 +585,7 @@ static void cb_create_volume_response (GtkWidget *chooser, int response, GtkEntr
}
// "Add Volume" button clicked
static void cb_add_volume (...)
static void cb_add_volume (GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
GtkWidget *chooser = gtk_file_chooser_dialog_new(GetString(STR_ADD_VOLUME_TITLE),
GTK_WINDOW(win),
@@ -601,7 +601,7 @@ static void cb_add_volume (...)
}
// "Create Hardfile" button clicked
static void cb_create_volume (...)
static void cb_create_volume (GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
GtkWidget *chooser = gtk_file_chooser_dialog_new(GetString(STR_CREATE_VOLUME_TITLE),
GTK_WINDOW(win),
@@ -633,7 +633,7 @@ static void cb_create_volume (...)
}
// "Remove Volume" button clicked
static void cb_remove_volume(...)
static void cb_remove_volume(GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
gtk_clist_remove(GTK_CLIST(volume_list), selected_volume);
}
@@ -801,12 +801,12 @@ static void create_jit_pane(GtkWidget *top)
return;
GtkWidget *box;
box = make_pane(top, STR_JIT_PANE_TITLE);
make_checkbox(box, STR_JIT_CTRL, "jit", G_CALLBACK(tb_jit));
w_jit_fpu = make_checkbox(box, STR_JIT_FPU_CTRL, "jitfpu", G_CALLBACK(tb_jit_fpu));
// Translation cache size
static const combo_desc options[] = {
STR_JIT_CACHE_SIZE_2MB_LAB,
@@ -816,7 +816,7 @@ static void create_jit_pane(GtkWidget *top)
0
};
w_jit_cache_size = make_combobox(box, STR_JIT_CACHE_SIZE_CTRL, "jitcachesize", options);
// Lazy translation cache invalidation
w_jit_lazy_flush = make_checkbox(box, STR_JIT_LAZY_CINV_CTRL, "jitlazyflush", G_CALLBACK(tb_jit_lazy_flush));
@@ -1114,7 +1114,7 @@ static void create_graphics_pane(GtkWidget *top)
w_fbdev_name = gtk_entry_new();
gtk_widget_show(w_fbdev_name);
gtk_entry_set_text(GTK_ENTRY(w_fbdev_name), fbdev_name);
gtk_entry_set_text(GTK_ENTRY(w_fbdev_name), fbdev_name);
gtk_table_attach(GTK_TABLE(table), w_fbdev_name, 1, 2, 4, 5, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
w_fbdevice_file = make_file_entry(box, STR_FBDEVICE_FILE_CTRL, "fbdevicefile");
@@ -1196,7 +1196,7 @@ static void create_input_pane(GtkWidget *top)
str = "";
w_keycode_file = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(w_keycode_file), str);
gtk_entry_set_text(GTK_ENTRY(w_keycode_file), str);
gtk_widget_show(w_keycode_file);
gtk_box_pack_start(GTK_BOX(hbox), w_keycode_file, TRUE, TRUE, 0);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/net/cebix/BasiliskII">
<file preprocess="xml-stripblanks" compressed="true">ui/menu.ui</file>
<file preprocess="xml-stripblanks" compressed="true">ui/prefs-editor.ui</file>
<file preprocess="xml-stripblanks" compressed="true">ui/help-overlay.ui</file>
</gresource>
</gresources>

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkShortcutsWindow" id="emulator-shortcuts">
<property name="modal">1</property>
<child>
<object class="GtkShortcutsSection">
<property name="visible">1</property>
<property name="section-name">shortcuts</property>
<property name="max-height">10</property>
<child>
<object class="GtkShortcutsGroup">
<property name="visible">1</property>
<property name="title" translatable="yes">Settings</property>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;ctrl&gt;S</property>
<property name="title" translatable="yes">Start</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;ctrl&gt;Q</property>
<property name="title" translatable="yes">Quit</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkShortcutsGroup">
<property name="title" translatable="yes">Emulator Hotkeys</property>
<property name="visible">1</property>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;ctrl&gt;Return</property>
<property name="title" translatable="yes">Toggle Full Screen</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;ctrl&gt;F5</property>
<property name="title" translatable="yes">Toggle Mouse Grab</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;ctrl&gt;Escape</property>
<property name="title" translatable="yes">Force Quit</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkShortcutsGroup">
<property name="visible">1</property>
<property name="title" translatable="yes">Mac OS Modifier Keys</property>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;ctrl&gt;</property>
<property name="title" translatable="yes">⌃ Control</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;alt&gt;</property>
<property name="title" translatable="yes">⌘ Command</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;super&gt;</property>
<property name="title" translatable="yes">⌥ Option</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.14"/>
<menu id="app-menu">
<section>
<item>
<attribute name="action">win.save-settings</attribute>
<attribute name="label" translatable="yes">_Save Settings</attribute>
</item>
<item>
<attribute name="action">win.zap-pram</attribute>
<attribute name="label" translatable="yes">_Clear XPRAM Data</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.show-help-overlay</attribute>
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
</item>
<item>
<attribute name="action">win.help</attribute>
<attribute name="label" translatable="yes">_Help</attribute>
</item>
<item>
<attribute name="action">win.about</attribute>
<attribute name="label" translatable="yes">_About</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.quit</attribute>
<attribute name="label" translatable="yes">_Quit</attribute>
<attribute name="accel">&lt;control&gt;Q</attribute>
</item>
</section>
</menu>
<menu id="prefs-editor-menu">
<submenu>
<attribute name="label" translatable="yes">_File</attribute>
<section>
<item>
<attribute name="action">win.start</attribute>
<attribute name="label" translatable="yes">_Start Basilisk II</attribute>
<attribute name="accel">&lt;control&gt;S</attribute>
</item>
<item>
<attribute name="action">win.save-settings</attribute>
<attribute name="label" translatable="yes">Sa_ve Settings</attribute>
</item>
<item>
<attribute name="action">win.zap-pram</attribute>
<attribute name="label" translatable="yes">_Clear XPRAM Data</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.quit</attribute>
<attribute name="label" translatable="yes">_Quit</attribute>
<attribute name="accel">&lt;control&gt;Q</attribute>
</item>
</section>
</submenu>
<submenu>
<attribute name="label" translatable="yes">_Help</attribute>
<section>
<item>
<attribute name="action">win.help</attribute>
<attribute name="label" translatable="yes">_Help</attribute>
<attribute name="accel">F1</attribute>
</item>
<item>
<attribute name="action">win.show-help-overlay</attribute>
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.about</attribute>
<attribute name="label" translatable="yes">_About Basilisk II</attribute>
</item>
</section>
</submenu>
</menu>
</interface>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
#ifndef __RESOURCE_basiliskii_H__
#define __RESOURCE_basiliskii_H__
#include <gio/gio.h>
extern GResource *basiliskii_get_resource (void);
#endif

View File

@@ -21,6 +21,27 @@
#ifndef PREFS_EDITOR_H
#define PREFS_EDITOR_H
#ifdef __BEOS__
extern void PrefsEditor(uint32 msg);
#else
extern bool PrefsEditor(void);
#endif
#if defined(ENABLE_GTK) || defined(STANDALONE_GUI)
#include <gtk/gtk.h>
#if !GLIB_CHECK_VERSION(2, 24, 0)
#define GVariant void
#endif
#if !GLIB_CHECK_VERSION(2, 28, 0)
#define GSimpleAction void
#endif
extern "C" {
void dl_quit(GtkWidget *dialog);
void cb_swap_opt_cmd (GtkWidget *widget);
void cb_infobar_show (GtkWidget *widget);
}
#endif
#endif

View File

@@ -39,6 +39,12 @@ enum {
STR_START_BUTTON,
STR_QUIT_BUTTON,
STR_CANCEL_BUTTON,
STR_CONTINUE_BUTTON,
STR_SELECT_BUTTON,
STR_CREATE_BUTTON,
STR_APP_NAME,
STR_APP_DISPLAY_NAME,
STR_APP_ID,
// Error messages
STR_NO_MEM_ERR = 1000,

View File

@@ -57,6 +57,12 @@ user_string_def common_strings[] = {
{STR_START_BUTTON, "Start"},
{STR_QUIT_BUTTON, "Quit"},
{STR_CANCEL_BUTTON, "Cancel"},
{STR_CONTINUE_BUTTON, "Continue"},
{STR_SELECT_BUTTON, "Select"},
{STR_CREATE_BUTTON, "Create"},
{STR_APP_NAME, "BasiliskII"},
{STR_APP_DISPLAY_NAME, "Basilisk II"},
{STR_APP_ID, "net.cebix.BasiliskII"},
{STR_NO_MEM_ERR, "Not enough free memory."},
{STR_NOT_ENOUGH_MEMORY_ERR, "Your computer does not have enough memory to run Basilisk II."},

View File

@@ -56,7 +56,7 @@ links:
include/adb.h include/audio.h include/audio_defs.h \
include/cdrom.h include/clip.h include/debug.h include/disk.h \
include/extfs.h include/extfs_defs.h include/pict.h \
include/prefs.h include/scsi.h include/serial.h \
include/prefs.h include/scsi.h include/serial.h include/prefs_editor.h \
include/serial_defs.h include/sony.h include/sys.h \
include/timer.h include/xpram.h \
BeOS/audio_beos.cpp BeOS/extfs_beos.cpp BeOS/scsi_beos.cpp \

View File

@@ -25,3 +25,6 @@ basic-dyngen-ops-x86_64_macos.hpp
ppc-dyngen-ops-x86_32.hpp
ppc-dyngen-ops-x86_64.hpp
ppc-dyngen-ops-x86_64_macos.hpp
# Generated GLib resource files
g_resource.cpp

View File

@@ -15,6 +15,7 @@ DESTDIR =
CC = @CC@
CXX = @CXX@
GCR = @GCR@
CFLAGS = @CFLAGS@
CXXFLAGS = @CXXFLAGS@
CPPFLAGS = @CPPFLAGS@ -I../include -I. -I../CrossPlatform -I../slirp
@@ -52,6 +53,9 @@ GUI_SRCS = ../prefs.cpp prefs_unix.cpp prefs_editor_gtk.cpp ../prefs_items.cpp \
../user_strings.cpp user_strings_unix.cpp xpram_unix.cpp sys_unix.cpp rpc_unix.cpp \
../dummy/prefs_dummy.cpp
GRESOURCE_SRCS = ui/help-overlay.ui ui/menu.ui ui/prefs-editor.ui
GRESOURCE_XML = ui/sheepshaver.gresource.xml
XPLAT_SRCS = ../CrossPlatform/vm_alloc.cpp ../CrossPlatform/sigsegv.cpp ../CrossPlatform/video_blit.cpp
# Append disassembler to dyngen, if available
@@ -177,7 +181,7 @@ uninstall:
rmdir $(DESTDIR)$(datadir)/$(APP)
clean:
rm -f $(PROGS) $(OBJ_DIR)/* core* *.core *~ *.bak ppc-execute-impl.cpp
rm -f $(PROGS) $(OBJ_DIR)/* core* *.core *~ *.bak ui/*~ ui/*.bak ppc-execute-impl.cpp g_resource.cpp
rm -f dyngen {basic,ppc}-dyngen-ops*.hpp ppc_asm.out.s
rm -rf $(APP_APP) $(GUI_APP_APP)
@@ -283,5 +287,8 @@ $(OBJ_DIR)/test-powerpc.o: $(kpxsrcdir)/test/test-powerpc.cpp
test-powerpc$(EXEEXT): $(TESTOBJS)
$(CXX) -o $@ $(LDFLAGS) $(TESTOBJS) $(LIBS)
g_resource.cpp: $(GRESOURCE_SRCS) $(GRESOURCE_XML)
$(GCR) --generate-source $(GRESOURCE_XML) --target $@
#-------------------------------------------------------------------------
# DO NOT DELETE THIS LINE -- make depend depends on it.

View File

@@ -37,12 +37,14 @@ AC_ARG_ENABLE(xf86-vidmode, [ --enable-xf86-vidmode use the XFree86 VidMode e
AC_ARG_ENABLE(vosf, [ --enable-vosf enable video on SEGV signals [default=no]], [WANT_VOSF=$enableval], [WANT_VOSF=no])
AC_ARG_ENABLE(standalone-gui,[ --enable-standalone-gui enable a standalone GUI prefs editor [default=no]], [WANT_STANDALONE_GUI=$enableval], [WANT_STANDALONE_GUI=no])
AC_ARG_WITH(esd, [ --with-esd support ESD for sound under Linux/FreeBSD [default=yes]], [WANT_ESD=$withval], [WANT_ESD=yes])
AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]],
AC_ARG_WITH(gtk, [ --with-gtk use GTK 2 or 3 for user interface [default=any]],
[case "$withval" in
yes|gtk2) WANT_GTK="gtk2";;
*) WANT_GTK="no";;
yes|true|any) WANT_GTK="any";;
*3) WANT_GTK="GTK3";;
*2) WANT_GTK="GTK2";;
*) WANT_GTK="no";;
esac],
[WANT_GTK="gtk2"])
[WANT_GTK="any"])
AC_ARG_WITH(mon, [ --with-mon use mon as debugger [default=yes]], [WANT_MON=$withval], [WANT_MON=no])
AC_ARG_WITH(dgcc, [ --with-dgcc=COMPILER use C++ COMPILER to compile synthetic opcodes or 'precompiled'], [DYNGEN_CC=$withval], [DYNGEN_CC=precompiled])
@@ -335,24 +337,57 @@ if [[ "x$WANT_XF86_VIDMODE" = "xyes" ]]; then
])
fi
# Check for pkg-config macro, thanks to rdiez
m4_ifndef([PKG_PROG_PKG_CONFIG], [m4_fatal(
[The PKG_PROG_PKG_CONFIG macro is not available. You need to install pkg-config.]
)])
PKG_PROG_PKG_CONFIG
dnl We use GTK+ if possible.
UISRCS=../dummy/prefs_editor_dummy.cpp
if [[ "x$WANT_GTK" = "xgtk2" ]]; then
AM_PATH_GTK_2_0(2.6.4, [
GUI_CFLAGS="$GTK_CFLAGS"
GUI_LIBS="$GTK_LIBS"
WANT_GTK=gtk2
if [[ "$WANT_GTK" = "GTK3" -o "$WANT_GTK" = "any" ]]; then
PKG_CHECK_MODULES([GTK3], [gtk+-3.0 >= 3.14.5], [
WANT_GTK=GTK3
GUI_CFLAGS="$GTK3_CFLAGS"
GUI_LIBS="$GTK3_LIBS"
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
AC_CHECK_PROG([ac_cv_gcr], [glib-compile-resources], [yes])
if [[ "$ac_cv_gcr" = "yes" ]]; then
GCR="glib-compile-resources"
else
AC_MSG_ERROR([glib-compile-resources not found.])
fi
], [
AC_MSG_WARN([Could not find GTK+ 2, disabling user interface.])
if [[ "$WANT_GTK" = "any" ]]; then
AC_MSG_WARN([Could not find GTK3 (version >= 3.14.5), falling back to GTK2.])
WANT_GTK=GTK2
else
AC_MSG_WARN([Could not find GTK3 (version >= 3.14.5), disabling user interface.])
WANT_GTK=no
fi
])
fi
if [[ "$WANT_GTK" = "GTK2" ]]; then
PKG_CHECK_MODULES([GTK2], [gtk+-2.0 >= 2.6.4], [
WANT_GTK=GTK2
GUI_CFLAGS="$GTK2_CFLAGS"
GUI_LIBS="$GTK2_LIBS"
], [
AC_MSG_WARN([Could not find GTK2 (version >= 2.6.4), disabling user interface.])
WANT_GTK=no
])
fi
if [[ "x$WANT_GTK" != "xno" -a "x$WANT_STANDALONE_GUI" = "xno" ]]; then
AC_DEFINE(ENABLE_GTK, 1, [Define if using GTK.])
UISRCS=prefs_editor_gtk.cpp
if [[ "$WANT_GTK" = "GTK3" ]]; then
UISRCS="prefs_editor_gtk3.cpp g_resource.cpp"
else
UISRCS="prefs_editor_gtk.cpp"
fi
fi
AC_SUBST(GUI_CFLAGS)
AC_SUBST(GUI_LIBS)
AC_SUBST(GCR)
dnl Build external GUI if requested.
if [[ "$WANT_STANDALONE_GUI" != "yes" ]]; then

View File

@@ -140,9 +140,13 @@
#ifdef ENABLE_GTK
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#if !defined(GDK_WINDOWING_QUARTZ) && !defined(GDK_WINDOWING_WAYLAND)
#include <X11/Xlib.h>
#endif
#if GTK_CHECK_VERSION(3, 14, 0)
#define ENABLE_GTK3
#endif
#endif
#ifdef ENABLE_XF86_DGA
@@ -234,6 +238,7 @@ static bool tick_thread_active = false; // Flag: MacOS thread installed
static volatile bool tick_thread_cancel; // Flag: Cancel 60Hz thread
static pthread_t tick_thread; // 60Hz thread
static pthread_t emul_thread; // MacOS thread
static int use_gui = -1; // Override prefs and show gui
static bool ready_for_signals = false; // Handler installed, signals can be sent
@@ -752,8 +757,33 @@ static bool init_sdl()
}
#endif
#ifdef ENABLE_GTK
GtkWindow *win;
static void gui_startup (void)
{
if (use_gui && !PrefsEditor())
QuitEmulator();
}
#ifdef ENABLE_GTK3
static void gui_activate (GtkApplication *app)
{
g_assert (GTK_IS_APPLICATION (app));
win = gtk_application_get_active_window (app);
/* Ask the window manager/compositor to present the window. */
if (win != NULL)
gtk_window_present (win);
}
#endif
#endif
int main(int argc, char **argv)
{
#ifdef ENABLE_GTK3
GtkApplication *app = NULL;
int ret;
#endif
#if defined(ENABLE_GTK) && !defined(GDK_WINDOWING_QUARTZ) && !defined(GDK_WINDOWING_WAYLAND)
XInitThreads();
#endif
@@ -825,6 +855,21 @@ int main(int argc, char **argv)
UserPrefsPath = argv[i];
argv[i] = NULL;
}
// We intercept the --nogui commandline so that the settings
// window can change the setting from the prefs file
} else if (strcmp(argv[i], "--nogui") == 0) {
argv[i++] = NULL;
if (i < argc) {
if (strcmp(argv[i], "true") == 0)
use_gui = false;
else
use_gui = true;
argv[i] = NULL;
}
// Alternative commands to enter the GUI
} else if (strcmp(argv[i], "--gui") == 0 || strcmp(argv[i], "--settings") == 0) {
use_gui = true;
argv[i] = NULL;
} else if (valid_vmdir(argv[i])) {
vmdir = argv[i];
argv[i] = NULL;
@@ -859,16 +904,11 @@ int main(int argc, char **argv)
}
}
#ifdef ENABLE_GTK
if (!gui_connection) {
// Init GTK
gtk_set_locale();
gtk_init(&argc, &argv);
}
#endif
// Read preferences
PrefsInit(vmdir, argc, argv);
// Only use nogui preference if not passed as command line argument
if (use_gui == -1)
use_gui = !PrefsFindBool("nogui");
#if SDL_PLATFORM_MACOS && SDL_VERSION_ATLEAST(2,0,0)
// On Mac OS X hosts, SDL2 will create its own menu bar. This is mostly OK,
@@ -922,10 +962,24 @@ int main(int argc, char **argv)
// Init system routines
SysInit();
// Show preferences editor
if (!PrefsFindBool("nogui"))
if (!PrefsEditor())
goto quit;
#ifdef ENABLE_GTK3
if (!gui_connection) {
// Init GTK
app = gtk_application_new (GetString(STR_APP_ID), G_APPLICATION_FLAGS_NONE);
g_set_prgname (GetString(STR_APP_DISPLAY_NAME));
g_signal_connect (app, "activate", G_CALLBACK (gui_activate), NULL);
g_signal_connect (app, "startup", G_CALLBACK (gui_startup), NULL);
g_application_register (G_APPLICATION (app), NULL, NULL);
ret = g_application_run (G_APPLICATION (app), argc, argv);
}
#elif defined(ENABLE_GTK)
if (!gui_connection) {
// Init GTK
gtk_set_locale();
gtk_init(&argc, &argv);
gui_startup();
}
#endif
#if !EMULATED_PPC
// Check some things
@@ -2013,7 +2067,7 @@ static void sigsegv_handler(int sig, siginfo_t *sip, void *scp)
}
// In GUI mode, show error alert
if (!PrefsFindBool("nogui")) {
if (use_gui) {
char str[256];
if (transfer_type == TYPE_LOAD || transfer_type == TYPE_STORE)
sprintf(str, GetString(STR_MEM_ACCESS_ERR), transfer_size == SIZE_BYTE ? "byte" : transfer_size == SIZE_HALFWORD ? "halfword" : "word", transfer_type == TYPE_LOAD ? GetString(STR_MEM_ACCESS_READ) : GetString(STR_MEM_ACCESS_WRITE), addr, r->pc(), r->gpr(24), r->gpr(1));
@@ -2192,7 +2246,7 @@ power_inst: sprintf(str, GetString(STR_POWER_INSTRUCTION_ERR), r->pc(), r->gpr(
}
// In GUI mode, show error alert
if (!PrefsFindBool("nogui")) {
if (use_gui) {
sprintf(str, GetString(STR_UNKNOWN_SEGV_ERR), r->pc(), r->gpr(24), r->gpr(1), opcode);
ErrorAlert(str);
QuitEmulator();

View File

@@ -29,10 +29,6 @@
#include <net/if.h>
#include <net/if_arp.h>
#ifdef __sun__
#include <sys/sockio.h>
#endif
#include <cerrno>
#include "user_strings.h"
@@ -208,7 +204,7 @@ static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, c
label = gtk_label_new(GetString(label_id));
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
combo = gtk_combo_box_entry_new_text();
gtk_widget_show(combo);
gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
@@ -221,7 +217,7 @@ static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, c
gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN (combo))), pref);
gtk_table_attach(GTK_TABLE(table), combo, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
return combo;
}
@@ -253,7 +249,7 @@ static GtkWidget *table_make_file_entry(GtkWidget *table, int row, int label_id,
gtk_table_attach(GTK_TABLE(table), box, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
entry = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(entry), str);
gtk_entry_set_text(GTK_ENTRY(entry), str);
gtk_widget_show(entry);
gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
@@ -541,7 +537,7 @@ static void cb_create_volume_response (GtkWidget *chooser, int response, GtkEntr
}
// "Add Volume" button clicked
static void cb_add_volume (...)
static void cb_add_volume (GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
GtkWidget *chooser = gtk_file_chooser_dialog_new(GetString(STR_ADD_VOLUME_TITLE),
GTK_WINDOW(win),
@@ -557,7 +553,7 @@ static void cb_add_volume (...)
}
// "Create Hardfile" button clicked
static void cb_create_volume (...)
static void cb_create_volume (GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
GtkWidget *chooser = gtk_file_chooser_dialog_new(GetString(STR_CREATE_VOLUME_TITLE),
GTK_WINDOW(win),
@@ -588,7 +584,7 @@ static void cb_create_volume (...)
gtk_widget_show(chooser);
}
// "Remove Volume" button clicked
static void cb_remove_volume(...)
static void cb_remove_volume(GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
gtk_clist_remove(GTK_CLIST(volume_list), selected_volume);
}
@@ -729,7 +725,7 @@ static void create_jit_pane(GtkWidget *top)
{
GtkWidget *box, *table, *label, *menu;
char str[32];
box = make_pane(top, STR_JIT_PANE_TITLE);
if (is_jit_capable()) {
@@ -1074,7 +1070,7 @@ static void create_input_pane(GtkWidget *top)
str = "";
w_keycode_file = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(w_keycode_file), str);
gtk_entry_set_text(GTK_ENTRY(w_keycode_file), str);
gtk_widget_show(w_keycode_file);
gtk_box_pack_start(GTK_BOX(hbox), w_keycode_file, TRUE, TRUE, 0);

View File

@@ -0,0 +1 @@
../../../BasiliskII/src/Unix/prefs_editor_gtk3.cpp

View File

@@ -0,0 +1 @@
../../../../BasiliskII/src/Unix/ui/help-overlay.ui

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.14"/>
<menu id="app-menu">
<section>
<item>
<attribute name="action">win.save-settings</attribute>
<attribute name="label" translatable="yes">_Save Settings</attribute>
</item>
<item>
<attribute name="action">win.zap-pram</attribute>
<attribute name="label" translatable="yes">_Clear XPRAM Data</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.show-help-overlay</attribute>
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
</item>
<item>
<attribute name="action">win.help</attribute>
<attribute name="label" translatable="yes">_Help</attribute>
<attribute name="accel">F1</attribute>
</item>
<item>
<attribute name="action">win.about</attribute>
<attribute name="label" translatable="yes">_About</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.quit</attribute>
<attribute name="label" translatable="yes">_Quit</attribute>
<attribute name="accel">&lt;control&gt;Q</attribute>
</item>
</section>
</menu>
<menu id="prefs-editor-menu">
<submenu>
<attribute name="label" translatable="yes">_File</attribute>
<section>
<item>
<attribute name="action">win.start</attribute>
<attribute name="label" translatable="yes">_Start SheepShaver</attribute>
<attribute name="accel">&lt;control&gt;S</attribute>
</item>
<item>
<attribute name="action">win.save-settings</attribute>
<attribute name="label" translatable="yes">Sa_ve Settings</attribute>
</item>
<item>
<attribute name="action">win.zap-pram</attribute>
<attribute name="label" translatable="yes">_Clear XPRAM Data</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.quit</attribute>
<attribute name="label" translatable="yes">_Quit</attribute>
<attribute name="accel">&lt;control&gt;Q</attribute>
</item>
</section>
</submenu>
<submenu>
<attribute name="label" translatable="yes">_Help</attribute>
<section>
<item>
<attribute name="action">win.help</attribute>
<attribute name="label" translatable="yes">_Help</attribute>
<attribute name="accel">F1</attribute>
</item>
<item>
<attribute name="action">win.show-help-overlay</attribute>
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.about</attribute>
<attribute name="label" translatable="yes">_About SheepShaver</attribute>
</item>
</section>
</submenu>
</menu>
</interface>

View File

@@ -0,0 +1 @@
../../../../BasiliskII/src/Unix/ui/prefs-editor.ui

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/net/cebix/SheepShaver">
<file preprocess="xml-stripblanks" compressed="true">ui/menu.ui</file>
<file preprocess="xml-stripblanks" compressed="true">ui/prefs-editor.ui</file>
<file preprocess="xml-stripblanks" compressed="true">ui/help-overlay.ui</file>
</gresource>
</gresources>

View File

@@ -0,0 +1,7 @@
#ifndef __RESOURCE_sheepshaver_H__
#define __RESOURCE_sheepshaver_H__
#include <gio/gio.h>
extern GResource *sheepshaver_get_resource (void);
#endif

View File

@@ -1,30 +0,0 @@
/*
* prefs_editor.h - Preferences editor
*
* SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PREFS_EDITOR_H
#define PREFS_EDITOR_H
#ifdef __BEOS__
extern void PrefsEditor(uint32 msg);
#else
extern bool PrefsEditor(void);
#endif
#endif

View File

@@ -0,0 +1 @@
../../../BasiliskII/src/include/prefs_editor.h

View File

@@ -40,6 +40,12 @@ enum {
STR_QUIT_BUTTON,
STR_CANCEL_BUTTON,
STR_IGNORE_BUTTON,
STR_CONTINUE_BUTTON,
STR_SELECT_BUTTON,
STR_CREATE_BUTTON,
STR_APP_NAME,
STR_APP_DISPLAY_NAME,
STR_APP_ID,
// Error messages
STR_NOT_ENOUGH_MEMORY_ERR = 1000,
@@ -163,9 +169,9 @@ enum {
STR_IGNORESEGV_CTRL,
STR_IDLEWAIT_CTRL,
STR_ROM_FILE_CTRL,
STR_NOGUI_CTRL,
STR_NOGUI_TIP,
STR_NOGUI_TIP2,
STR_NOGUI_CTRL,
STR_NOGUI_TIP,
STR_NOGUI_TIP2,
// JIT Compiler pane
STR_JIT_PANE_TITLE = 3700,

View File

@@ -58,6 +58,12 @@ user_string_def common_strings[] = {
{STR_QUIT_BUTTON, "Quit"},
{STR_CANCEL_BUTTON, "Cancel"},
{STR_IGNORE_BUTTON, "Ignore"},
{STR_CONTINUE_BUTTON, "Continue"},
{STR_SELECT_BUTTON, "Select"},
{STR_CREATE_BUTTON, "Create"},
{STR_APP_NAME, "SheepShaver"},
{STR_APP_DISPLAY_NAME, "SheepShaver"},
{STR_APP_ID, "net.cebix.SheepShaver"},
{STR_NOT_ENOUGH_MEMORY_ERR, "Your computer does not have enough memory to run SheepShaver."},
{STR_NO_KERNEL_DATA_ERR, "Cannot create Kernel Data area: %s (%08x)."},