/
gui.c
220 lines (180 loc) · 5.11 KB
1
2
3
4
5
6
7
8
/**
* 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.
*/
9
#include "gui.h"
10
#include "platform.h"
11
12
13
14
15
#include "fileio.h"
typedef struct S_PLUGINLIST
{
void *lib;
16
const MojoGui *gui;
17
18
19
20
MojoGuiPluginPriority priority;
struct S_PLUGINLIST *next;
} PluginList;
21
22
const MojoGui *GGui = NULL;
static PluginList *pluginDetails = NULL;
23
24
static const MojoGuiEntryPoint staticGui[] =
25
{
26
#if GUI_STATIC_LINK_STDIO
27
MojoGuiPlugin_stdio,
28
#endif
29
30
#if GUI_STATIC_LINK_COCOA
MojoGuiPlugin_cocoa,
31
#endif
32
33
#if GUI_STATIC_LINK_GTKPLUS2
MojoGuiPlugin_gtkplus2,
34
#endif
35
36
37
#if GUI_STATIC_LINK_WWW
MojoGuiPlugin_www,
#endif
38
39
#if GUI_STATIC_LINK_NCURSES
MojoGuiPlugin_ncurses,
40
41
#endif
NULL
42
43
44
};
45
static MojoGuiPluginPriority calcGuiPriority(const MojoGui *gui)
46
47
48
{
MojoGuiPluginPriority retval;
49
retval = gui->priority(MojoPlatform_istty());
50
51
52
53
54
// 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)
{
55
56
57
static const char *envr = NULL;
if (envr == NULL)
envr = cmdlinestr("ui", "MOJOSETUP_UI", NULL);
58
if ((envr != NULL) && (strcasecmp(envr, gui->name()) == 0))
59
60
61
62
63
64
65
retval = MOJOGUI_PRIORITY_USER_REQUESTED;
} // if
return retval;
} // calcGuiPriority
66
67
68
69
70
71
72
73
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)
{
74
if ( (i->priority == p) && (i->gui->init()) )
75
{
76
logInfo("Selected '%0' UI.", i->gui->name());
77
return i;
78
} // if
79
80
81
82
83
84
85
86
87
88
89
90
} // for
} // for
return NULL;
} // initGuiPluginsByPriority
static void deleteGuiPlugin(PluginList *plugin)
{
if (plugin != NULL)
{
if (plugin->gui)
91
plugin->gui->deinit();
92
if (plugin->lib)
93
MojoPlatform_dlclose(plugin->lib);
94
95
96
97
98
free(plugin);
} // if
} // deleteGuiPlugin
99
static boolean tryGuiPlugin(PluginList *plugins, MojoGuiEntryPoint entry)
100
{
101
102
103
boolean retval = false;
const MojoGui *gui = entry(MOJOGUI_INTERFACE_REVISION, &GEntryPoints);
if (gui != NULL)
104
{
105
PluginList *plug = xmalloc(sizeof (PluginList));
106
107
108
109
110
plug->lib = NULL;
plug->gui = gui;
plug->priority = calcGuiPriority(gui);
plug->next = plugins->next;
plugins->next = plug;
111
112
113
114
115
116
117
118
119
120
121
retval = true;
} // if
return retval;
} // tryGuiPlugin
static void loadStaticGuiPlugins(PluginList *plugins)
{
int i;
for (i = 0; staticGui[i] != NULL; i++)
122
tryGuiPlugin(plugins, staticGui[i]);
123
124
125
} // loadStaticGuiPlugins
126
static boolean loadDynamicGuiPlugin(PluginList *plugins, MojoArchive *ar)
127
{
128
boolean rc = false;
129
130
void *lib = NULL;
MojoInput *io = ar->openCurrentEntry(ar);
131
if (io != NULL)
132
{
133
134
const uint32 imglen = (uint32) io->length(io);
uint8 *img = (uint8 *) xmalloc(imglen);
135
const uint32 br = (uint32) io->read(io, img, imglen);
136
137
138
139
140
io->close(io);
if (br == imglen)
lib = MojoPlatform_dlopen(img, imglen);
free(img);
} // if
141
142
if (lib != NULL)
143
{
144
145
146
void *addr = MojoPlatform_dlsym(lib, MOJOGUI_ENTRY_POINT_STR);
MojoGuiEntryPoint entry = (MojoGuiEntryPoint) addr;
if (entry != NULL)
147
{
148
149
if ((rc = tryGuiPlugin(plugins, entry)) == false)
MojoPlatform_dlclose(lib);
150
151
152
} // if
} // if
153
return rc;
154
} // loadDynamicGuiPlugin
155
156
157
static void loadDynamicGuiPlugins(PluginList *plugins)
158
{
159
if (GBaseArchive->enumerate(GBaseArchive))
160
{
161
const MojoArchiveEntry *entinfo;
162
while ((entinfo = GBaseArchive->enumNext(GBaseArchive)) != NULL)
163
{
164
165
if (entinfo->type != MOJOARCHIVE_ENTRY_FILE)
continue;
166
167
168
169
if (strncmp(entinfo->filename, "guis/", 5) != 0)
continue;
170
loadDynamicGuiPlugin(plugins, GBaseArchive);
171
} // while
172
} // if
173
} // loadDynamicGuiPlugins
174
175
176
const MojoGui *MojoGui_initGuiPlugin(void)
177
178
{
PluginList plugins;
179
PluginList *i = NULL;
180
181
182
183
184
if (pluginDetails != NULL)
return pluginDetails->gui;
memset(&plugins, '\0', sizeof (plugins));
185
assert(GGui == NULL);
186
187
loadDynamicGuiPlugins(&plugins);
188
loadStaticGuiPlugins(&plugins);
189
190
191
192
pluginDetails = initGuiPluginsByPriority(&plugins);
// cleanout unused plugins...
193
i = plugins.next;
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
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 ...