Skip to content

Commit

Permalink
Only have one GUI plugin's shared library loaded at a time.
Browse files Browse the repository at this point in the history
Otherwise, GTK+3 will abort, because it checks for GTK+2 and panics if both
are loaded into a process at the same time.
  • Loading branch information
icculus committed Nov 3, 2018
1 parent cc2529e commit 6f6178e
Showing 1 changed file with 54 additions and 21 deletions.
75 changes: 54 additions & 21 deletions gui.c
Expand Up @@ -15,6 +15,8 @@ typedef struct S_PLUGINLIST
void *lib;
const MojoGui *gui;
MojoGuiPluginPriority priority;
uint32 imglen;
uint8 *img;
struct S_PLUGINLIST *next;
} PluginList;

Expand Down Expand Up @@ -71,11 +73,32 @@ static PluginList *initGuiPluginsByPriority(PluginList *plugins)
PluginList *i;
for (i = plugins->next; i != NULL; i = i->next)
{
if ( (i->priority == p) && (i->gui->init()) )
if (i->priority != p)
continue;

if (i->img != NULL)
{
i->lib = MojoPlatform_dlopen(i->img, i->imglen);
if (i->lib != NULL)
{
void *addr = MojoPlatform_dlsym(i->lib, MOJOGUI_ENTRY_POINT_STR);
MojoGuiEntryPoint entry = (MojoGuiEntryPoint) addr;
if (entry != NULL)
i->gui = entry(MOJOGUI_INTERFACE_REVISION, &GEntryPoints);
} // if
} // if

if (i->gui && i->gui->init())
{
logInfo("Selected '%0' UI.", i->gui->name());
return i;
} // if

if (i->lib)
{
MojoPlatform_dlclose(i->lib);
i->lib = NULL;
} // if
} // for
} // for

Expand All @@ -91,27 +114,27 @@ static void deleteGuiPlugin(PluginList *plugin)
plugin->gui->deinit();
if (plugin->lib)
MojoPlatform_dlclose(plugin->lib);
free(plugin->img);
free(plugin);
} // if
} // deleteGuiPlugin


static boolean tryGuiPlugin(PluginList *plugins, MojoGuiEntryPoint entry)
static PluginList *tryGuiPlugin(PluginList *plugins, MojoGuiEntryPoint entry)
{
boolean retval = false;
PluginList *plug = NULL;
const MojoGui *gui = entry(MOJOGUI_INTERFACE_REVISION, &GEntryPoints);
if (gui != NULL)
{
PluginList *plug = xmalloc(sizeof (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;
return plug;
} // tryGuiPlugin


Expand All @@ -125,32 +148,43 @@ static void loadStaticGuiPlugins(PluginList *plugins)

static boolean loadDynamicGuiPlugin(PluginList *plugins, MojoArchive *ar)
{
boolean rc = false;
void *lib = NULL;
PluginList *plug = NULL;
MojoInput *io = ar->openCurrentEntry(ar);
if (io != NULL)
{
void *lib = 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)
lib = MojoPlatform_dlopen(img, imglen);
if (lib != NULL)
{
void *addr = MojoPlatform_dlsym(lib, MOJOGUI_ENTRY_POINT_STR);
MojoGuiEntryPoint entry = (MojoGuiEntryPoint) addr;
if (entry != NULL)
{
plug = tryGuiPlugin(plugins, entry);
if (plug)
{
plug->img = img;
plug->imglen = imglen;
} // if
} // if

// always close, because GTK+2 and GTK+3 can't coexist.
// we'll reload them when trying them!
MojoPlatform_dlclose(lib);
} // if
} // if

if (!plug)
free(img);
} // if

return rc;
return plug != NULL;
} // loadDynamicGuiPlugin


Expand All @@ -163,8 +197,7 @@ static void loadDynamicGuiPlugins(PluginList *plugins)
{
if (entinfo->type != MOJOARCHIVE_ENTRY_FILE)
continue;

if (strncmp(entinfo->filename, "guis/", 5) != 0)
else if (strncmp(entinfo->filename, "guis/", 5) != 0)
continue;

loadDynamicGuiPlugin(plugins, GBaseArchive);
Expand Down

0 comments on commit 6f6178e

Please sign in to comment.