Skip to content

Commit

Permalink
Made GUI code suck slightly less.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Nov 29, 2006
1 parent 9e4778c commit a1474a0
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 84 deletions.
44 changes: 28 additions & 16 deletions gui.c
Expand Up @@ -19,13 +19,18 @@ typedef struct S_PLUGINLIST
MojoGui *GGui = NULL;
PluginList *pluginDetails = NULL;


typedef MojoGui* (*MojoGuiStaticEntryPoint)(void);
MojoGui *MojoGuiPlugin_stdio(void);

static const MojoGuiStaticEntryPoint staticGuiPlugins[] =
static const MojoGuiEntryPoint staticGuiPlugins[] =
{
#if GUI_STATIC_LINK_STDIO
MojoGuiPlugin_stdio,
#endif
#if GUI_STATIC_LINK_WINDOWS
MojoGuiPlugin_windows,
#endif
#if GUI_STATIC_LINK_GTK_PLUS
MojoGuiPlugin_gtkplus,
#endif
NULL
};


Expand Down Expand Up @@ -84,13 +89,16 @@ static void deleteGuiPlugin(PluginList *plugin)
} // deleteGuiPlugin


// !!! FIXME: merge this code with dynamic bits, so it retrieves a MojoGui*
// !!! FIXME: and then passes it to unified code...
static void loadStaticGuiPlugins(PluginList *plugins)
{
int i;
for (i = 0; i < STATICARRAYLEN(staticGuiPlugins); i++)
STUBBED("See FIXME above.");
for (i = 0; staticGuiPlugins[i] != NULL; i++)
{
PluginList *plug;
MojoGui *gui = staticGuiPlugins[i]();
MojoGui *gui = staticGuiPlugins[i](MOJOGUI_INTERFACE_REVISION);
if (gui == NULL)
continue;
plug = xmalloc(sizeof (PluginList));
Expand All @@ -108,7 +116,6 @@ static PluginList *loadDynamicGuiPlugin(MojoArchive *ar)
char fname[128] = { 0 };
PluginList *retval = NULL;
void *lib = NULL;
MojoGuiEntryType entry = NULL;
boolean rc;
MojoInput *io = ar->openCurrentEntry(ar);
if (io == NULL)
Expand All @@ -133,15 +140,20 @@ static PluginList *loadDynamicGuiPlugin(MojoArchive *ar)
if (lib != NULL)
{
MojoGui *gui = NULL;
entry = (MojoGuiEntryType) dlsym(lib, MOJOGUI_ENTRY_POINT_STR);
if ( (entry != NULL) && ((gui = entry()) != NULL) )
MojoGuiEntryPoint entry = NULL;
entry = (MojoGuiEntryPoint) dlsym(lib, MOJOGUI_ENTRY_POINT_STR);
if (entry != NULL)
{
retval = xmalloc(sizeof (PluginList));
retval->filename = xstrdup(fname);
retval->lib = lib;
retval->gui = gui;
retval->priority = calcGuiPriority(gui);
retval->next = NULL;
gui = entry(MOJOGUI_INTERFACE_REVISION);
if (gui != NULL)
{
retval = xmalloc(sizeof (PluginList));
retval->filename = xstrdup(fname);
retval->lib = lib;
retval->gui = gui;
retval->priority = calcGuiPriority(gui);
retval->next = NULL;
} // if
} // if
} // if
} // if
Expand Down
137 changes: 87 additions & 50 deletions gui.h
Expand Up @@ -7,9 +7,6 @@
extern "C" {
#endif

// Increment this value when binary compatibility changes.
#define MOJOGUI_INTERFACE_REVISION 1

typedef enum
{
MOJOGUI_PRIORITY_NEVER_TRY = 0,
Expand All @@ -20,87 +17,127 @@ typedef enum
MOJOGUI_PRIORITY_TOTAL
} MojoGuiPluginPriority;


/*
* Abstract GUI interfaces.
*
* NEVER CHANGE A SHIPPING STRUCTURE! If you have to break binary
* compatibility, copy the latest version (MojoGui_revX) to a new struct,
* MojoGui_revX+1, and increment MOJOGUI_INTERFACE_REVISION, above.
*/
typedef struct MojoGui_rev1 MojoGui_rev1;
struct MojoGui_rev1

#define MOJOGUI_ENTRY_POINT MojoSetup_Gui_GetInterface
#define MOJOGUI_ENTRY_POINT_STR DEFINE_TO_STR(MOJOGUI_ENTRY_POINT)

// Increment this value when MojoGui's structure changes.
#define MOJOGUI_INTERFACE_REVISION 1

typedef struct MojoGui MojoGui;
struct MojoGui
{
// public
uint8 (*priority)(MojoGui_rev1 *gui);
const char* (*name)(MojoGui_rev1 *gui);
boolean (*init)(MojoGui_rev1 *gui);
void (*deinit)(MojoGui_rev1 *gui);
void (*msgbox)(MojoGui_rev1 *gui, const char *title, const char *text);
boolean (*promptyn)(MojoGui_rev1 *gui, const char *title, const char *text);
uint8 (*priority)(MojoGui *gui);
const char* (*name)(MojoGui *gui);
boolean (*init)(MojoGui *gui);
void (*deinit)(MojoGui *gui);
void (*msgbox)(MojoGui *gui, const char *title, const char *text);
boolean (*promptyn)(MojoGui *gui, const char *title, const char *text);

// private
void *opaque;
};


// Tapdance to handle interface revisions...
// (God, this is a mess.)

/*
* The latest revision struct is just called "MojoGui" for convenience
* in places that don't care about backwards compatibility, and can avoid
* the Macro Salsa.
*/
#define MOJOGUI_STRUCT_VER(v) MojoGui_rev##v
#define MOJOGUI_STRUCT2(v) MOJOGUI_STRUCT_VER(v)
#define MOJOGUI_STRUCT MOJOGUI_STRUCT2(MOJOGUI_INTERFACE_REVISION)
#define MOJOGUI_ENTRY_POINT_VER(v) MojoSetup_GUI_GetInterface_rev##v
#define MOJOGUI_ENTRY_POINT2(v) MOJOGUI_ENTRY_POINT_VER(v)
#define MOJOGUI_ENTRY_POINT MOJOGUI_ENTRY_POINT2(MOJOGUI_INTERFACE_REVISION)
#define MOJOGUI_ENTRY_POINT_STR3(v) #v
#define MOJOGUI_ENTRY_POINT_STR2(v) MOJOGUI_ENTRY_POINT_STR3(v)
#define MOJOGUI_ENTRY_POINT_STR_VER(v) MOJOGUI_ENTRY_POINT_STR2(MOJOGUI_ENTRY_POINT2(v))
#define MOJOGUI_ENTRY_POINT_STR MOJOGUI_ENTRY_POINT_STR_VER(MOJOGUI_INTERFACE_REVISION)

typedef MOJOGUI_STRUCT MojoGui;
typedef MOJOGUI_STRUCT * (*MojoGuiEntryType)(void);
typedef MojoGui* (*MojoGuiEntryPoint)(int revision);

#ifndef BUILDING_EXTERNAL_PLUGIN
extern MojoGui *GGui;
MojoGui *MojoGui_initGuiPlugin(void);
void MojoGui_deinitGuiPlugin(void);
#else

__EXPORT__ MOJOGUI_STRUCT *MOJOGUI_ENTRY_POINT(void);

__EXPORT__ MojoGui *MOJOGUI_ENTRY_POINT(int revision);

/*
* We do this as a macro so we only have to update one place, and it
* enforces some details in the plugins. Without effort, plugins don't
* support anything but the latest version of the interface.
*/
#define MOJOGUI_PLUGIN(module) \
MojoGui *MojoGuiPlugin_##module(void) \
MojoGui *MojoGuiPlugin_##module(int revision) \
{ \
static MOJOGUI_STRUCT retval; \
retval.priority = MojoGui_##module##_priority; \
retval.name = MojoGui_##module##_name; \
retval.init = MojoGui_##module##_init; \
retval.deinit = MojoGui_##module##_deinit; \
retval.msgbox = MojoGui_##module##_msgbox; \
retval.promptyn = MojoGui_##module##_promptyn; \
retval.opaque = NULL; \
return &retval; \
if (revision == MOJOGUI_INTERFACE_REVISION) { \
static MojoGui retval; \
retval.priority = MojoGui_##module##_priority; \
retval.name = MojoGui_##module##_name; \
retval.init = MojoGui_##module##_init; \
retval.deinit = MojoGui_##module##_deinit; \
retval.msgbox = MojoGui_##module##_msgbox; \
retval.promptyn = MojoGui_##module##_promptyn; \
retval.opaque = NULL; \
return &retval; \
} \
return NULL; \
} \

#define CREATE_MOJOGUI_ENTRY_POINT(module) \
MOJOGUI_STRUCT *MOJOGUI_ENTRY_POINT(void) \
MojoGui *MOJOGUI_ENTRY_POINT(int revision) \
{ \
return MOJOGUI_PLUGIN2(MOJOGUI_ENTRY_POINT,module) (); \
return MojoGuiPlugin_##module(revision); \
} \

#endif


/*
* make some decisions about which GUI plugins to build...
*/

// Probably want to support this always, unless explicitly overridden.
MojoGui *MojoGuiPlugin_stdio(int revision);
#ifndef SUPPORT_GUI_STDIO
#define SUPPORT_GUI_STDIO 1
#endif

// Probably want to statically link it, too.
#if SUPPORT_GUI_STDIO
# ifndef GUI_STATIC_LINK_STDIO
# define GUI_STATIC_LINK_STDIO 1
# endif
#endif


// !!! FIXME (Windows code isn't actually written yet...)
// Want to support this always on Windows, unless explicitly overridden.
MojoGui *MojoGuiPlugin_windows(int revision);
#ifndef SUPPORT_GUI_WINDOWS
# if PLATFORM_WINDOWS
# define SUPPORT_GUI_WINDOWS 1
# endif
#endif

// Probably want to statically link it, too.
#if SUPPORT_GUI_WINDOWS
# ifndef GUI_STATIC_LINK_WINDOWS
# define GUI_STATIC_LINK_WINDOWS 1
# endif
#endif


// !!! FIXME (GTK+ code isn't actually written yet...)
// Want to support this always on non-Mac Unix, unless explicitly overridden.
MojoGui *MojoGuiPlugin_gtkplus(int revision);
#ifndef SUPPORT_GUI_GTK_PLUS
# if ((PLATFORM_UNIX) && (!PLATFORM_MACOSX))
# define SUPPORT_GUI_GTK_PLUS 1
# endif
#endif

// Probably DON'T want to statically link it.
#if SUPPORT_GUI_GTK_PLUS
# ifndef GUI_STATIC_LINK_GTK_PLUS
# define GUI_STATIC_LINK_GTK_PLUS 0
# endif
#endif

// !!! FIXME: Qt? KDE? Gnome? Console? Cocoa?

#ifdef __cplusplus
}
#endif
Expand Down
22 changes: 6 additions & 16 deletions gui/gui_stdio.c
@@ -1,49 +1,39 @@
#define BUILDING_EXTERNAL_PLUGIN 1
#include "../gui.h"

// Probably want to support this always, unless explicitly overridden.
#ifndef SUPPORT_GUI_STDIO
#define SUPPORT_GUI_STDIO 1
#endif

// Probably want to statically link it, too.
#ifndef GUI_STDIO_STATIC_LINK
#define GUI_STDIO_STATIC_LINK 1
#endif

#if SUPPORT_GUI_STDIO

#include <ctype.h>

static uint8 MojoGui_stdio_priority(MojoGui_rev1 *gui)
static uint8 MojoGui_stdio_priority(MojoGui *gui)
{
return MOJOGUI_PRIORITY_TRY_LAST;
}

static const char* MojoGui_stdio_name(MojoGui_rev1 *gui)
static const char* MojoGui_stdio_name(MojoGui *gui)
{
return "stdio";
}

static boolean MojoGui_stdio_init(MojoGui_rev1 *gui)
static boolean MojoGui_stdio_init(MojoGui *gui)
{
return true;
}

static void MojoGui_stdio_deinit(MojoGui_rev1 *gui)
static void MojoGui_stdio_deinit(MojoGui *gui)
{
// no-op
}

static void MojoGui_stdio_msgbox(MojoGui_rev1 *gui, const char *title, const char *text)
static void MojoGui_stdio_msgbox(MojoGui *gui, const char *title, const char *text)
{
printf("NOTICE: %s\n[hit enter]", text);
fflush(stdout);
if (!feof(stdin))
getchar();
}

static boolean MojoGui_stdio_promptyn(MojoGui_rev1 *gui, const char *title, const char *text)
static boolean MojoGui_stdio_promptyn(MojoGui *gui, const char *title, const char *text)
{
if (feof(stdin))
return 0;
Expand Down
4 changes: 2 additions & 2 deletions makefile
Expand Up @@ -98,8 +98,8 @@ endif
CC := ccache gcc
LD := gcc

OPTS := -Os -fno-strict-aliasing -fomit-frame-pointer
#OPTS := -O0
#OPTS := -Os -fno-strict-aliasing -fomit-frame-pointer
OPTS := -O0

DEFINES := \
-DAPPID=$(APPID) \
Expand Down
3 changes: 3 additions & 0 deletions universal.h
Expand Up @@ -80,6 +80,9 @@ char *xstrdup(const char *str);

#define STATICARRAYLEN(x) ( (sizeof ((x))) / (sizeof ((x)[0])) )

#define DEFINE_TO_STR2(x) #x
#define DEFINE_TO_STR(x) DEFINE_TO_STR2(x)

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit a1474a0

Please sign in to comment.