mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-08-16 02:27:31 +00:00
Make Basilisk II main application not use GTK libraries when compiling with
STANDALONE_GUI. This is the second step towards a more interesting GUI alike to VMware. Communication from/to the GUI is held by some lightweight RPC. Note: The step should be enough to provide a tiny GTK GUI for MacOS X.
This commit is contained in:
@@ -36,8 +36,10 @@ SLIRP_SRCS = @SLIRP_SRCS@
|
|||||||
SLIRP_OBJS = $(SLIRP_SRCS:../slirp/%.c=obj/%.o)
|
SLIRP_OBJS = $(SLIRP_SRCS:../slirp/%.c=obj/%.o)
|
||||||
|
|
||||||
STANDALONE_GUI = @STANDALONE_GUI@
|
STANDALONE_GUI = @STANDALONE_GUI@
|
||||||
|
GUI_CFLAGS = @GUI_CFLAGS@
|
||||||
|
GUI_LIBS = @GUI_LIBS@
|
||||||
GUI_SRCS = ../prefs.cpp prefs_unix.cpp prefs_editor_gtk.cpp ../prefs_items.cpp \
|
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
|
../user_strings.cpp user_strings_unix.cpp xpram_unix.cpp sys_unix.cpp rpc_unix.cpp
|
||||||
|
|
||||||
## Files
|
## Files
|
||||||
SRCS = ../main.cpp main_unix.cpp ../prefs.cpp ../prefs_items.cpp prefs_unix.cpp \
|
SRCS = ../main.cpp main_unix.cpp ../prefs.cpp ../prefs_items.cpp prefs_unix.cpp \
|
||||||
@@ -46,7 +48,7 @@ SRCS = ../main.cpp main_unix.cpp ../prefs.cpp ../prefs_items.cpp prefs_unix.cpp
|
|||||||
timer_unix.cpp ../adb.cpp ../serial.cpp ../ether.cpp \
|
timer_unix.cpp ../adb.cpp ../serial.cpp ../ether.cpp \
|
||||||
../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp ../video.cpp video_blit.cpp \
|
../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp ../video.cpp video_blit.cpp \
|
||||||
vm_alloc.cpp sigsegv.cpp ../audio.cpp ../extfs.cpp \
|
vm_alloc.cpp sigsegv.cpp ../audio.cpp ../extfs.cpp \
|
||||||
../user_strings.cpp user_strings_unix.cpp sshpty.c strlcpy.c \
|
../user_strings.cpp user_strings_unix.cpp sshpty.c strlcpy.c rpc_unix.cpp \
|
||||||
$(SYSSRCS) $(CPUSRCS) $(SLIRP_SRCS)
|
$(SYSSRCS) $(CPUSRCS) $(SLIRP_SRCS)
|
||||||
APP = BasiliskII
|
APP = BasiliskII
|
||||||
APP_APP = $(APP).app
|
APP_APP = $(APP).app
|
||||||
@@ -55,6 +57,9 @@ PROGS = $(APP)$(EXEEXT)
|
|||||||
ifeq ($(STANDALONE_GUI),yes)
|
ifeq ($(STANDALONE_GUI),yes)
|
||||||
GUI_APP = BasiliskIIGUI
|
GUI_APP = BasiliskIIGUI
|
||||||
PROGS += $(GUI_APP)$(EXEEXT)
|
PROGS += $(GUI_APP)$(EXEEXT)
|
||||||
|
else
|
||||||
|
CXXFLAGS += $(GUI_CFLAGS)
|
||||||
|
LIBS += $(GUI_LIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
## Rules
|
## Rules
|
||||||
@@ -75,7 +80,7 @@ endef
|
|||||||
OBJS = $(SRCS_LIST_TO_OBJS)
|
OBJS = $(SRCS_LIST_TO_OBJS)
|
||||||
|
|
||||||
define GUI_SRCS_LIST_TO_OBJS
|
define GUI_SRCS_LIST_TO_OBJS
|
||||||
$(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(foreach file, $(GUI_SRCS), \
|
$(addprefix $(OBJ_DIR)/, $(addsuffix .go, $(foreach file, $(GUI_SRCS), \
|
||||||
$(basename $(notdir $(file))))))
|
$(basename $(notdir $(file))))))
|
||||||
endef
|
endef
|
||||||
GUI_OBJS = $(GUI_SRCS_LIST_TO_OBJS)
|
GUI_OBJS = $(GUI_SRCS_LIST_TO_OBJS)
|
||||||
@@ -89,7 +94,7 @@ $(APP)$(EXEEXT): $(OBJ_DIR) $(OBJS)
|
|||||||
$(BLESS) $(APP)$(EXEEXT)
|
$(BLESS) $(APP)$(EXEEXT)
|
||||||
|
|
||||||
$(GUI_APP)$(EXEEXT): $(OBJ_DIR) $(GUI_OBJS)
|
$(GUI_APP)$(EXEEXT): $(OBJ_DIR) $(GUI_OBJS)
|
||||||
$(CXX) -o $@ $(LDFLAGS) $(GUI_OBJS) $(LIBS)
|
$(CXX) -o $@ $(LDFLAGS) $(GUI_OBJS) $(LIBS) $(GUI_LIBS)
|
||||||
|
|
||||||
$(APP)_app: $(APP) ../MacOSX/Info.plist ../MacOSX/$(APP).icns
|
$(APP)_app: $(APP) ../MacOSX/Info.plist ../MacOSX/$(APP).icns
|
||||||
mkdir -p $(APP_APP)/Contents
|
mkdir -p $(APP_APP)/Contents
|
||||||
@@ -152,6 +157,8 @@ $(OBJ_DIR)/%.o : %.mm
|
|||||||
$(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -c $< -o $@
|
$(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -c $< -o $@
|
||||||
$(OBJ_DIR)/%.o : %.s
|
$(OBJ_DIR)/%.o : %.s
|
||||||
$(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@
|
$(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@
|
||||||
|
$(OBJ_DIR)/%.go : %.cpp
|
||||||
|
$(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) $(GUI_CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
# Windows resources
|
# Windows resources
|
||||||
$(OBJ_DIR)/%.o: %.rc
|
$(OBJ_DIR)/%.o: %.rc
|
||||||
|
@@ -254,9 +254,8 @@ case "x$WANT_GTK" in
|
|||||||
xgtk2*)
|
xgtk2*)
|
||||||
AM_PATH_GTK_2_0(1.3.15, [
|
AM_PATH_GTK_2_0(1.3.15, [
|
||||||
AC_DEFINE(ENABLE_GTK, 1, [Define if using GTK.])
|
AC_DEFINE(ENABLE_GTK, 1, [Define if using GTK.])
|
||||||
CFLAGS="$CFLAGS $GTK_CFLAGS"
|
GUI_CFLAGS="$GTK_CFLAGS"
|
||||||
CXXFLAGS="$CXXFLAGS $GTK_CFLAGS"
|
GUI_LIBS="$GTK_LIBS"
|
||||||
LIBS="$LIBS $GTK_LIBS"
|
|
||||||
UISRCS=prefs_editor_gtk.cpp
|
UISRCS=prefs_editor_gtk.cpp
|
||||||
WANT_GTK=gtk2
|
WANT_GTK=gtk2
|
||||||
], [
|
], [
|
||||||
@@ -276,8 +275,8 @@ esac
|
|||||||
if [[ "x$WANT_GTK" = "xgtk" ]]; then
|
if [[ "x$WANT_GTK" = "xgtk" ]]; then
|
||||||
AM_PATH_GTK(1.2.0, [
|
AM_PATH_GTK(1.2.0, [
|
||||||
AC_DEFINE(ENABLE_GTK, 1, [Define if using GTK.])
|
AC_DEFINE(ENABLE_GTK, 1, [Define if using GTK.])
|
||||||
CXXFLAGS="$CXXFLAGS $GTK_CFLAGS"
|
GUI_CFLAGS="$GTK_CFLAGS"
|
||||||
LIBS="$LIBS $GTK_LIBS"
|
GUI_LIBS="$GTK_LIBS"
|
||||||
UISRCS=prefs_editor_gtk.cpp
|
UISRCS=prefs_editor_gtk.cpp
|
||||||
dnl somehow, <gnome-i18n.h> would redefine gettext() to nothing if
|
dnl somehow, <gnome-i18n.h> would redefine gettext() to nothing if
|
||||||
dnl ENABLE_NLS is not set, thusly conflicting with C++ <string> which
|
dnl ENABLE_NLS is not set, thusly conflicting with C++ <string> which
|
||||||
@@ -285,14 +284,16 @@ if [[ "x$WANT_GTK" = "xgtk" ]]; then
|
|||||||
AM_GNU_GETTEXT
|
AM_GNU_GETTEXT
|
||||||
B2_PATH_GNOMEUI([
|
B2_PATH_GNOMEUI([
|
||||||
AC_DEFINE(HAVE_GNOMEUI, 1, [Define if libgnomeui is available.])
|
AC_DEFINE(HAVE_GNOMEUI, 1, [Define if libgnomeui is available.])
|
||||||
CXXFLAGS="$CXXFLAGS $GNOMEUI_CFLAGS"
|
GUI_CFLAGS="$GUI_CFLAGS $GNOMEUI_CFLAGS"
|
||||||
LIBS="$LIBS $GNOMEUI_LIBS"
|
GUI_LIBS="$GUI_LIBS $GNOMEUI_LIBS"
|
||||||
], [])
|
], [])
|
||||||
], [
|
], [
|
||||||
AC_MSG_WARN([Could not find GTK+, disabling user interface.])
|
AC_MSG_WARN([Could not find GTK+, disabling user interface.])
|
||||||
WANT_GTK=no
|
WANT_GTK=no
|
||||||
])
|
])
|
||||||
fi
|
fi
|
||||||
|
AC_SUBST(GUI_CFLAGS)
|
||||||
|
AC_SUBST(GUI_LIBS)
|
||||||
|
|
||||||
dnl Enable standalone GUI?
|
dnl Enable standalone GUI?
|
||||||
if [[ "$WANT_STANDALONE_GUI" != "yes" ]]; then
|
if [[ "$WANT_STANDALONE_GUI" != "yes" ]]; then
|
||||||
|
@@ -55,6 +55,11 @@ struct sigstate {
|
|||||||
# define SS_USERREGS 0x04
|
# define SS_USERREGS 0x04
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef STANDALONE_GUI
|
||||||
|
# undef ENABLE_GTK
|
||||||
|
# include "rpc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_GTK
|
#ifdef ENABLE_GTK
|
||||||
# include <gtk/gtk.h>
|
# include <gtk/gtk.h>
|
||||||
# include <gdk/gdk.h>
|
# include <gdk/gdk.h>
|
||||||
@@ -192,6 +197,11 @@ static void sigint_handler(...);
|
|||||||
static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped
|
static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef STANDALONE_GUI
|
||||||
|
static rpc_connection_t *gui_connection; // RPC connection to the GUI
|
||||||
|
static const char *gui_connection_path; // GUI connection identifier
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Prototypes
|
// Prototypes
|
||||||
static void *xpram_func(void *arg);
|
static void *xpram_func(void *arg);
|
||||||
@@ -412,6 +422,14 @@ int main(int argc, char **argv)
|
|||||||
i++; // don't remove the argument, gtk_init() needs it too
|
i++; // don't remove the argument, gtk_init() needs it too
|
||||||
if (i < argc)
|
if (i < argc)
|
||||||
x_display_name = strdup(argv[i]);
|
x_display_name = strdup(argv[i]);
|
||||||
|
#endif
|
||||||
|
#ifdef STANDALONE_GUI
|
||||||
|
} else if (strcmp(argv[i], "--gui-connection") == 0) {
|
||||||
|
argv[i++] = NULL;
|
||||||
|
if (i < argc) {
|
||||||
|
gui_connection_path = argv[i];
|
||||||
|
argv[i] = NULL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
} else if (strcmp(argv[i], "--break") == 0) {
|
} else if (strcmp(argv[i], "--break") == 0) {
|
||||||
argv[i++] = NULL;
|
argv[i++] = NULL;
|
||||||
@@ -446,6 +464,15 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef STANDALONE_GUI
|
||||||
|
if (gui_connection_path) {
|
||||||
|
if ((gui_connection = rpc_init_client(gui_connection_path)) == NULL) {
|
||||||
|
fprintf(stderr, "Failed to initialize RPC client connection to the GUI\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_GTK
|
#ifdef ENABLE_GTK
|
||||||
#ifdef HAVE_GNOMEUI
|
#ifdef HAVE_GNOMEUI
|
||||||
// Init GNOME/GTK
|
// Init GNOME/GTK
|
||||||
@@ -908,6 +935,14 @@ void QuitEmulator(void)
|
|||||||
XCloseDisplay(x_display);
|
XCloseDisplay(x_display);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef STANDALONE_GUI
|
||||||
|
// Notify GUI we are about to leave
|
||||||
|
if (gui_connection) {
|
||||||
|
if (rpc_method_invoke(gui_connection, RPC_METHOD_EXIT, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR)
|
||||||
|
rpc_method_wait_for_reply(gui_connection, RPC_TYPE_INVALID);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1548,6 +1583,13 @@ void display_alert(int title_id, int prefix_id, int button_id, const char *text)
|
|||||||
|
|
||||||
void ErrorAlert(const char *text)
|
void ErrorAlert(const char *text)
|
||||||
{
|
{
|
||||||
|
#ifdef STANDALONE_GUI
|
||||||
|
if (gui_connection) {
|
||||||
|
if (rpc_method_invoke(gui_connection, RPC_METHOD_ERROR_ALERT, RPC_TYPE_STRING, text, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR &&
|
||||||
|
rpc_method_wait_for_reply(gui_connection, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if defined(ENABLE_GTK) && !defined(USE_SDL_VIDEO)
|
#if defined(ENABLE_GTK) && !defined(USE_SDL_VIDEO)
|
||||||
if (PrefsFindBool("nogui") || x_display == NULL) {
|
if (PrefsFindBool("nogui") || x_display == NULL) {
|
||||||
printf(GetString(STR_SHELL_ERROR_PREFIX), text);
|
printf(GetString(STR_SHELL_ERROR_PREFIX), text);
|
||||||
@@ -1567,6 +1609,13 @@ void ErrorAlert(const char *text)
|
|||||||
|
|
||||||
void WarningAlert(const char *text)
|
void WarningAlert(const char *text)
|
||||||
{
|
{
|
||||||
|
#ifdef STANDALONE_GUI
|
||||||
|
if (gui_connection) {
|
||||||
|
if (rpc_method_invoke(gui_connection, RPC_METHOD_WARNING_ALERT, RPC_TYPE_STRING, text, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR &&
|
||||||
|
rpc_method_wait_for_reply(gui_connection, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if defined(ENABLE_GTK) && !defined(USE_SDL_VIDEO)
|
#if defined(ENABLE_GTK) && !defined(USE_SDL_VIDEO)
|
||||||
if (PrefsFindBool("nogui") || x_display == NULL) {
|
if (PrefsFindBool("nogui") || x_display == NULL) {
|
||||||
printf(GetString(STR_SHELL_WARNING_PREFIX), text);
|
printf(GetString(STR_SHELL_WARNING_PREFIX), text);
|
||||||
|
@@ -39,6 +39,9 @@
|
|||||||
#include "prefs.h"
|
#include "prefs.h"
|
||||||
#include "prefs_editor.h"
|
#include "prefs_editor.h"
|
||||||
|
|
||||||
|
#define DEBUG 0
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
// Global variables
|
// Global variables
|
||||||
static GtkWidget *win; // Preferences window
|
static GtkWidget *win; // Preferences window
|
||||||
@@ -1525,6 +1528,8 @@ static void read_settings(void)
|
|||||||
|
|
||||||
#ifdef STANDALONE_GUI
|
#ifdef STANDALONE_GUI
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include "rpc.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fake unused data and functions
|
* Fake unused data and functions
|
||||||
@@ -1533,7 +1538,6 @@ static void read_settings(void)
|
|||||||
uint8 XPRAM[XPRAM_SIZE];
|
uint8 XPRAM[XPRAM_SIZE];
|
||||||
void MountVolume(void *fh) { }
|
void MountVolume(void *fh) { }
|
||||||
void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size) { }
|
void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size) { }
|
||||||
void WarningAlert(const char *text) { }
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1576,12 +1580,62 @@ static void display_alert(int title_id, int prefix_id, int button_id, const char
|
|||||||
* Display error alert
|
* Display error alert
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void ErrorAlert(const char *text)
|
void ErrorAlert(const char *text)
|
||||||
{
|
{
|
||||||
display_alert(STR_ERROR_ALERT_TITLE, STR_GUI_ERROR_PREFIX, STR_QUIT_BUTTON, text);
|
display_alert(STR_ERROR_ALERT_TITLE, STR_GUI_ERROR_PREFIX, STR_QUIT_BUTTON, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Display warning alert
|
||||||
|
*/
|
||||||
|
|
||||||
|
void WarningAlert(const char *text)
|
||||||
|
{
|
||||||
|
display_alert(STR_WARNING_ALERT_TITLE, STR_GUI_WARNING_PREFIX, STR_OK_BUTTON, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RPC handlers
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int handle_ErrorAlert(rpc_connection_t *connection)
|
||||||
|
{
|
||||||
|
D(bug("handle_ErrorAlert\n"));
|
||||||
|
|
||||||
|
int error;
|
||||||
|
char *str;
|
||||||
|
if ((error = rpc_method_get_args(connection, RPC_TYPE_STRING, &str, RPC_TYPE_INVALID)) < 0)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
ErrorAlert(str);
|
||||||
|
free(str);
|
||||||
|
return RPC_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_WarningAlert(rpc_connection_t *connection)
|
||||||
|
{
|
||||||
|
D(bug("handle_WarningAlert\n"));
|
||||||
|
|
||||||
|
int error;
|
||||||
|
char *str;
|
||||||
|
if ((error = rpc_method_get_args(connection, RPC_TYPE_STRING, &str, RPC_TYPE_INVALID)) < 0)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
WarningAlert(str);
|
||||||
|
free(str);
|
||||||
|
return RPC_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_Exit(rpc_connection_t *connection)
|
||||||
|
{
|
||||||
|
D(bug("handle_Exit\n"));
|
||||||
|
|
||||||
|
return RPC_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start standalone GUI
|
* Start standalone GUI
|
||||||
*/
|
*/
|
||||||
@@ -1610,19 +1664,55 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// Transfer control to the executable
|
// Transfer control to the executable
|
||||||
if (start) {
|
if (start) {
|
||||||
char b2_path[PATH_MAX];
|
char gui_connection_path[64];
|
||||||
strcpy(b2_path, argv[0]);
|
sprintf(gui_connection_path, "/org/BasiliskII/GUI/%d", getpid());
|
||||||
char *p = strrchr(b2_path, '/');
|
|
||||||
p = p ? p + 1 : b2_path;
|
int pid = fork();
|
||||||
*p = '\0';
|
if (pid == 0) { // Child
|
||||||
strcat(b2_path, "BasiliskII");
|
char b2_path[PATH_MAX];
|
||||||
argv[0] = b2_path;
|
strcpy(b2_path, argv[0]);
|
||||||
execv(b2_path, argv);
|
char *p = strrchr(b2_path, '/');
|
||||||
|
p = p ? p + 1 : b2_path;
|
||||||
|
*p = '\0';
|
||||||
|
strcat(b2_path, "BasiliskII");
|
||||||
|
execl(b2_path, b2_path, "--gui-connection", gui_connection_path, (char *)NULL);
|
||||||
|
|
||||||
char str[256];
|
char str[256];
|
||||||
sprintf(str, GetString(STR_NO_B2_EXE_FOUND), b2_path, strerror(errno));
|
sprintf(str, GetString(STR_NO_B2_EXE_FOUND), b2_path, strerror(errno));
|
||||||
ErrorAlert(str);
|
ErrorAlert(str);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
else { // Parent
|
||||||
|
rpc_connection_t *connection;
|
||||||
|
if ((connection = rpc_init_server(gui_connection_path)) == NULL) {
|
||||||
|
printf("ERROR: failed to initialize GUI-side RPC server connection\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const rpc_method_descriptor_t vtable[] = {
|
||||||
|
{ RPC_METHOD_ERROR_ALERT, handle_ErrorAlert },
|
||||||
|
{ RPC_METHOD_WARNING_ALERT, handle_WarningAlert },
|
||||||
|
{ RPC_METHOD_EXIT, handle_Exit }
|
||||||
|
};
|
||||||
|
if (rpc_method_add_callbacks(connection, vtable, sizeof(vtable) / sizeof(vtable[0])) < 0) {
|
||||||
|
printf("ERROR: failed to setup GUI method callbacks\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rpc_listen(connection) < 0) {
|
||||||
|
printf("ERROR: failed to initialize RPC server thread\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int status, ret = -1;
|
||||||
|
while (waitpid(pid, &status, 0) != pid)
|
||||||
|
;
|
||||||
|
if (WIFEXITED(status))
|
||||||
|
ret = WEXITSTATUS(status);
|
||||||
|
|
||||||
|
rpc_exit(connection);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
101
BasiliskII/src/Unix/rpc.h
Normal file
101
BasiliskII/src/Unix/rpc.h
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* rpc.h - Remote Procedure Calls
|
||||||
|
*
|
||||||
|
* Basilisk II (C) 1997-2006 Christian Bauer
|
||||||
|
* Contributed by Gwenole Beauchesne
|
||||||
|
*
|
||||||
|
* 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 RPC_H
|
||||||
|
#define RPC_H
|
||||||
|
|
||||||
|
// Error Types
|
||||||
|
enum {
|
||||||
|
RPC_ERROR_NO_ERROR = 0,
|
||||||
|
RPC_ERROR_GENERIC = -1000,
|
||||||
|
RPC_ERROR_ERRNO_SET = -1001,
|
||||||
|
RPC_ERROR_NO_MEMORY = -1002,
|
||||||
|
RPC_ERROR_CONNECTION_NULL = -1003,
|
||||||
|
RPC_ERROR_CONNECTION_TYPE_MISMATCH = -1004,
|
||||||
|
RPC_ERROR_MESSAGE_TRUNCATED = -1005,
|
||||||
|
RPC_ERROR_MESSAGE_ARGUMENT_MISMATCH = -1006,
|
||||||
|
RPC_ERROR_MESSAGE_ARGUMENT_UNKNOWN = -1007,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Connection Handling
|
||||||
|
typedef struct rpc_connection_t rpc_connection_t;
|
||||||
|
extern rpc_connection_t *rpc_init_server(const char *ident);
|
||||||
|
extern rpc_connection_t *rpc_init_client(const char *ident);
|
||||||
|
extern int rpc_exit(rpc_connection_t *connection);
|
||||||
|
extern int rpc_listen_socket(rpc_connection_t *connection);
|
||||||
|
extern int rpc_listen(rpc_connection_t *connection);
|
||||||
|
extern int rpc_dispatch(rpc_connection_t *connection);
|
||||||
|
extern int rpc_connection_busy(rpc_connection_t *connection);
|
||||||
|
|
||||||
|
// Message Passing
|
||||||
|
enum {
|
||||||
|
RPC_TYPE_INVALID = 0,
|
||||||
|
RPC_TYPE_CHAR = -2000,
|
||||||
|
RPC_TYPE_BOOLEAN = -2001,
|
||||||
|
RPC_TYPE_INT32 = -2002,
|
||||||
|
RPC_TYPE_UINT32 = -2003,
|
||||||
|
RPC_TYPE_STRING = -2004,
|
||||||
|
RPC_TYPE_ARRAY = -2005,
|
||||||
|
};
|
||||||
|
typedef struct rpc_message_t rpc_message_t;
|
||||||
|
extern int rpc_message_send_char(rpc_message_t *message, char c);
|
||||||
|
extern int rpc_message_send_int32(rpc_message_t *message, int32_t value);
|
||||||
|
extern int rpc_message_send_uint32(rpc_message_t *message, uint32_t value);
|
||||||
|
extern int rpc_message_send_string(rpc_message_t *message, const char *str);
|
||||||
|
extern int rpc_message_send_bytes(rpc_message_t *message, unsigned char *bytes, int count);
|
||||||
|
extern int rpc_message_recv_char(rpc_message_t *message, char *ret);
|
||||||
|
extern int rpc_message_recv_int32(rpc_message_t *message, int32_t *ret);
|
||||||
|
extern int rpc_message_recv_uint32(rpc_message_t *message, uint32_t *ret);
|
||||||
|
extern int rpc_message_recv_string(rpc_message_t *message, char **ret);
|
||||||
|
extern int rpc_message_recv_bytes(rpc_message_t *message, unsigned char *bytes, int count);
|
||||||
|
typedef int (*rpc_message_callback_t)(rpc_message_t *message, void *p_value);
|
||||||
|
typedef struct {
|
||||||
|
int id;
|
||||||
|
int size;
|
||||||
|
rpc_message_callback_t send_callback;
|
||||||
|
rpc_message_callback_t recv_callback;
|
||||||
|
} rpc_message_descriptor_t;
|
||||||
|
extern int rpc_message_add_callbacks(const rpc_message_descriptor_t *descs, int n_descs);
|
||||||
|
|
||||||
|
// Method Callbacks Handling
|
||||||
|
typedef int (*rpc_method_callback_t)(rpc_connection_t *connection);
|
||||||
|
typedef struct {
|
||||||
|
int id;
|
||||||
|
rpc_method_callback_t callback;
|
||||||
|
} rpc_method_descriptor_t;
|
||||||
|
extern int rpc_method_add_callbacks(rpc_connection_t *connection, const rpc_method_descriptor_t *descs, int n_descs);
|
||||||
|
extern int rpc_method_remove_callback_id(rpc_connection_t *connection, int id);
|
||||||
|
extern int rpc_method_remove_callbacks(rpc_connection_t *connection, const rpc_method_descriptor_t *descs, int n_descs);
|
||||||
|
|
||||||
|
// Remote Procedure Call (method invocation)
|
||||||
|
extern int rpc_method_invoke(rpc_connection_t *connection, int method, ...);
|
||||||
|
extern int rpc_method_wait_for_reply(rpc_connection_t *connection, ...);
|
||||||
|
extern int rpc_method_get_args(rpc_connection_t *connection, ...);
|
||||||
|
extern int rpc_method_send_reply(rpc_connection_t *connection, ...);
|
||||||
|
|
||||||
|
// Message Protocol
|
||||||
|
enum {
|
||||||
|
RPC_METHOD_ERROR_ALERT = 1,
|
||||||
|
RPC_METHOD_WARNING_ALERT,
|
||||||
|
RPC_METHOD_EXIT
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* RPC_H */
|
1135
BasiliskII/src/Unix/rpc_unix.cpp
Normal file
1135
BasiliskII/src/Unix/rpc_unix.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user