MegaGlest/mk/linux/mojosetup/gui.c

221 lines
5.1 KiB
C

/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
#include "gui.h"
#include "platform.h"
#include "fileio.h"
typedef struct S_PLUGINLIST
{
void *lib;
const MojoGui *gui;
MojoGuiPluginPriority priority;
struct S_PLUGINLIST *next;
} PluginList;
const MojoGui *GGui = NULL;
static PluginList *pluginDetails = NULL;
static const MojoGuiEntryPoint staticGui[] =
{
#if GUI_STATIC_LINK_STDIO
MojoGuiPlugin_stdio,
#endif
#if GUI_STATIC_LINK_COCOA
MojoGuiPlugin_cocoa,
#endif
#if GUI_STATIC_LINK_GTKPLUS2
MojoGuiPlugin_gtkplus2,
#endif
#if GUI_STATIC_LINK_WWW
MojoGuiPlugin_www,
#endif
#if GUI_STATIC_LINK_NCURSES
MojoGuiPlugin_ncurses,
#endif
NULL
};
static MojoGuiPluginPriority calcGuiPriority(const MojoGui *gui)
{
MojoGuiPluginPriority retval;
retval = gui->priority(MojoPlatform_istty());
// If the plugin isn't saying "don't try me at all" then see if the
// user explicitly wants this one.
if (retval != MOJOGUI_PRIORITY_NEVER_TRY)
{
static const char *envr = NULL;
if (envr == NULL)
envr = cmdlinestr("ui", "MOJOSETUP_UI", NULL);
if ((envr != NULL) && (strcasecmp(envr, gui->name()) == 0))
retval = MOJOGUI_PRIORITY_USER_REQUESTED;
} // if
return retval;
} // calcGuiPriority
static PluginList *initGuiPluginsByPriority(PluginList *plugins)
{
MojoGuiPluginPriority p;
for (p = MOJOGUI_PRIORITY_USER_REQUESTED; p < MOJOGUI_PRIORITY_TOTAL; p++)
{
PluginList *i;
for (i = plugins->next; i != NULL; i = i->next)
{
if ( (i->priority == p) && (i->gui->init()) )
{
logInfo("Selected '%0' UI.", i->gui->name());
return i;
} // if
} // for
} // for
return NULL;
} // initGuiPluginsByPriority
static void deleteGuiPlugin(PluginList *plugin)
{
if (plugin != NULL)
{
if (plugin->gui)
plugin->gui->deinit();
if (plugin->lib)
MojoPlatform_dlclose(plugin->lib);
free(plugin);
} // if
} // deleteGuiPlugin
static boolean tryGuiPlugin(PluginList *plugins, MojoGuiEntryPoint entry)
{
boolean retval = false;
const MojoGui *gui = entry(MOJOGUI_INTERFACE_REVISION, &GEntryPoints);
if (gui != NULL)
{
PluginList *plug = xmalloc(sizeof (PluginList));
plug->lib = NULL;
plug->gui = gui;
plug->priority = calcGuiPriority(gui);
plug->next = plugins->next;
plugins->next = plug;
retval = true;
} // if
return retval;
} // tryGuiPlugin
static void loadStaticGuiPlugins(PluginList *plugins)
{
int i;
for (i = 0; staticGui[i] != NULL; i++)
tryGuiPlugin(plugins, staticGui[i]);
} // loadStaticGuiPlugins
static boolean loadDynamicGuiPlugin(PluginList *plugins, MojoArchive *ar)
{
boolean rc = false;
void *lib = NULL;
MojoInput *io = ar->openCurrentEntry(ar);
if (io != NULL)
{
const uint32 imglen = (uint32) io->length(io);
uint8 *img = (uint8 *) xmalloc(imglen);
const uint32 br = (uint32) io->read(io, img, imglen);
io->close(io);
if (br == imglen)
lib = MojoPlatform_dlopen(img, imglen);
free(img);
} // if
if (lib != NULL)
{
void *addr = MojoPlatform_dlsym(lib, MOJOGUI_ENTRY_POINT_STR);
MojoGuiEntryPoint entry = (MojoGuiEntryPoint) addr;
if (entry != NULL)
{
if ((rc = tryGuiPlugin(plugins, entry)) == false)
MojoPlatform_dlclose(lib);
} // if
} // if
return rc;
} // loadDynamicGuiPlugin
static void loadDynamicGuiPlugins(PluginList *plugins)
{
if (GBaseArchive->enumerate(GBaseArchive))
{
const MojoArchiveEntry *entinfo;
while ((entinfo = GBaseArchive->enumNext(GBaseArchive)) != NULL)
{
if (entinfo->type != MOJOARCHIVE_ENTRY_FILE)
continue;
if (strncmp(entinfo->filename, "guis/", 5) != 0)
continue;
loadDynamicGuiPlugin(plugins, GBaseArchive);
} // while
} // if
} // loadDynamicGuiPlugins
const MojoGui *MojoGui_initGuiPlugin(void)
{
PluginList plugins;
PluginList *i = NULL;
if (pluginDetails != NULL)
return pluginDetails->gui;
memset(&plugins, '\0', sizeof (plugins));
assert(GGui == NULL);
loadDynamicGuiPlugins(&plugins);
loadStaticGuiPlugins(&plugins);
pluginDetails = initGuiPluginsByPriority(&plugins);
// cleanout unused plugins...
i = plugins.next;
while (i != NULL)
{
PluginList *next = i->next;
if (i != pluginDetails)
deleteGuiPlugin(i);
i = next;
} // while
if (pluginDetails != NULL)
{
GGui = pluginDetails->gui;
pluginDetails->next = NULL;
} // if
return GGui;
} // MojoGui_findGuiPlugin
void MojoGui_deinitGuiPlugin(void)
{
GGui = NULL;
deleteGuiPlugin(pluginDetails);
pluginDetails = NULL;
} // MojoGui_deinitGuiPlugin
// end of gui.c ...