221 lines
5.1 KiB
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 ...
|
||
|
|