/
gui.c
258 lines (213 loc) · 6.28 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
MojoGuiPluginPriority priority;
18
19
uint32 imglen;
uint8 *img;
20
21
22
struct S_PLUGINLIST *next;
} PluginList;
23
24
const MojoGui *GGui = NULL;
static PluginList *pluginDetails = NULL;
25
26
27
28
29
30
31
32
33
typedef struct StaticGuiPlugin
{
const char* name;
const MojoGuiEntryPoint entry;
} StaticGuiPlugin;
#define STATIC_GUI_PLUGIN(name) {#name, MojoGuiPlugin_##name}
static StaticGuiPlugin staticGui[] =
34
{
35
#if GUI_STATIC_LINK_STDIO
36
STATIC_GUI_PLUGIN(stdio),
37
#endif
38
#if GUI_STATIC_LINK_COCOA
39
STATIC_GUI_PLUGIN(cocoa),
40
#endif
41
#if GUI_STATIC_LINK_GTKPLUS3
42
STATIC_GUI_PLUGIN(gtkplus3),
43
#endif
44
#if GUI_STATIC_LINK_GTKPLUS2
45
STATIC_GUI_PLUGIN(gtkplus2),
46
#endif
47
#if GUI_STATIC_LINK_WWW
48
STATIC_GUI_PLUGIN(www),
49
#endif
50
#if GUI_STATIC_LINK_NCURSES
51
STATIC_GUI_PLUGIN(ncurses),
52
#endif
53
{NULL, NULL}
54
};
55
#undef STATIC_GUI_PLUGIN
56
57
58
static MojoGuiPluginPriority calcGuiPriority(const MojoGui *gui)
59
60
61
{
MojoGuiPluginPriority retval;
62
retval = gui->priority(MojoPlatform_istty());
63
64
65
66
67
// 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)
{
68
69
70
static const char *envr = NULL;
if (envr == NULL)
envr = cmdlinestr("ui", "MOJOSETUP_UI", NULL);
71
if ((envr != NULL) && (strcasecmp(envr, gui->name()) == 0))
72
73
74
75
76
77
78
retval = MOJOGUI_PRIORITY_USER_REQUESTED;
} // if
return retval;
} // calcGuiPriority
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
const MojoGui *MojoSetup_loadGuiPlugin(const uint8 *img, uint32 len, void **lib)
{
*lib = MojoPlatform_dlopen(img, len);
if (*lib != NULL)
{
void *addr = MojoPlatform_dlsym(*lib, MOJOGUI_ENTRY_POINT_STR);
MojoGuiEntryPoint entry = (MojoGuiEntryPoint) addr;
if (entry != NULL)
return entry(MOJOGUI_INTERFACE_REVISION, &GEntryPoints);
} // if
return NULL;
} // MojoSetup_loadGuiPlugin
94
95
96
97
98
99
100
101
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)
{
102
103
104
105
if (i->priority != p)
continue;
if (i->img != NULL)
106
i->gui = MojoSetup_loadGuiPlugin(i->img, i->imglen, &i->lib);
107
108
if (i->gui && i->gui->init())
109
{
110
logInfo("Selected '%0' UI.", i->gui->name());
111
return i;
112
} // if
113
114
115
116
117
if (i->lib)
{
MojoPlatform_dlclose(i->lib);
i->lib = NULL;
118
i->gui = NULL;
119
} // if
120
121
122
123
124
125
126
127
128
129
130
131
} // for
} // for
return NULL;
} // initGuiPluginsByPriority
static void deleteGuiPlugin(PluginList *plugin)
{
if (plugin != NULL)
{
if (plugin->gui)
132
plugin->gui->deinit();
133
if (plugin->lib)
134
MojoPlatform_dlclose(plugin->lib);
135
free(plugin->img);
136
137
138
139
140
free(plugin);
} // if
} // deleteGuiPlugin
141
static PluginList *addGuiPlugin(PluginList *plugins, const MojoGui *gui, MojoGuiPluginPriority priority)
142
{
143
144
145
146
147
148
PluginList *plug = xmalloc(sizeof (PluginList));
plug->lib = NULL;
plug->gui = gui;
plug->priority = priority;
plug->next = plugins->next;
plugins->next = plug;
149
150
return plug;
151
} // addGuiPlugin
152
153
154
155
156
static void loadStaticGuiPlugins(PluginList *plugins)
{
int i;
157
158
for (i = 0; staticGui[i].entry != NULL; i++)
{
159
const MojoGui *gui;
160
logInfo("Testing static GUI plugin %0", staticGui[i].name);
161
162
163
gui = staticGui[i].entry(MOJOGUI_INTERFACE_REVISION, &GEntryPoints);
if (gui != NULL)
addGuiPlugin(plugins, gui, calcGuiPriority(gui));
164
}
165
166
167
} // loadStaticGuiPlugins
168
static boolean loadDynamicGuiPlugin(PluginList *plugins, MojoArchive *ar)
169
{
170
PluginList *plug = NULL;
171
MojoInput *io = ar->openCurrentEntry(ar);
172
if (io != NULL)
173
{
174
175
const uint32 imglen = (uint32) io->length(io);
uint8 *img = (uint8 *) xmalloc(imglen);
176
const uint32 br = (uint32) io->read(io, img, imglen);
177
178
io->close(io);
if (br == imglen)
179
{
180
181
182
MojoGuiPluginPriority priority;
priority = MojoPlatform_getGuiPriority(img, imglen);
if (priority != MOJOGUI_PRIORITY_NEVER_TRY)
183
{
184
185
186
187
plug = addGuiPlugin(plugins, NULL, priority);
plug->img = img;
plug->imglen = imglen;
}
188
189
190
} // if
} // if
191
return plug != NULL;
192
} // loadDynamicGuiPlugin
193
194
195
static void loadDynamicGuiPlugins(PluginList *plugins)
196
{
197
if (GBaseArchive->enumerate(GBaseArchive))
198
{
199
const MojoArchiveEntry *entinfo;
200
while ((entinfo = GBaseArchive->enumNext(GBaseArchive)) != NULL)
201
{
202
203
if (entinfo->type != MOJOARCHIVE_ENTRY_FILE)
continue;
204
else if (strncmp(entinfo->filename, "guis/", 5) != 0)
205
206
continue;
207
logInfo("Testing dynamic GUI plugin %0", entinfo->filename);
208
loadDynamicGuiPlugin(plugins, GBaseArchive);
209
} // while
210
} // if
211
} // loadDynamicGuiPlugins
212
213
214
const MojoGui *MojoGui_initGuiPlugin(void)
215
216
{
PluginList plugins;
217
PluginList *i = NULL;
218
219
220
221
222
if (pluginDetails != NULL)
return pluginDetails->gui;
memset(&plugins, '\0', sizeof (plugins));
223
assert(GGui == NULL);
224
225
loadDynamicGuiPlugins(&plugins);
226
loadStaticGuiPlugins(&plugins);
227
228
229
230
pluginDetails = initGuiPluginsByPriority(&plugins);
// cleanout unused plugins...
231
i = plugins.next;
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
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 ...