]> Dogcows Code - chaz/openbox/blob - openbox/plugin.c
plugins work.
[chaz/openbox] / openbox / plugin.c
1 #include <glib.h>
2 #include <gmodule.h>
3
4 typedef void (*PluginStartup)();
5 typedef void (*PluginShutdown)();
6
7 typedef struct {
8 GModule *module;
9 char *name;
10
11 PluginStartup startup;
12 PluginShutdown shutdown;
13 } Plugin;
14
15 static gpointer load_sym(GModule *module, char *name, char *symbol)
16 {
17 gpointer var = NULL;
18 if (!g_module_symbol(module, symbol, &var))
19 g_warning("Failed to load symbol '%s' from plugin '%s'", symbol, name);
20 return var;
21 }
22
23 static Plugin *plugin_new(char *name)
24 {
25 Plugin *p;
26 char *path;
27
28 p = g_new(Plugin, 1);
29
30 path = g_build_filename(PLUGINDIR, name, NULL);
31 p->module = g_module_open(path, G_MODULE_BIND_LAZY);
32 g_free(path);
33
34 if (p->module == NULL) {
35 path = g_build_filename(g_get_home_dir(), ".openbox", "plugins", name,
36 NULL);
37 p->module = g_module_open(path, G_MODULE_BIND_LAZY);
38 g_free(path);
39 }
40
41 if (p->module == NULL) {
42 g_free(p);
43 return NULL;
44 }
45
46 p->startup = load_sym(p->module, name, "startup");
47 p->shutdown = load_sym(p->module, name, "shutdown");
48
49 if (p->startup == NULL || p->shutdown == NULL) {
50 g_module_close(p->module);
51 g_free(p);
52 return NULL;
53 }
54
55 p->name = g_strdup(name);
56 return p;
57 }
58
59 static void plugin_free(Plugin *p)
60 {
61 p->shutdown();
62
63 g_free(p->name);
64 g_module_close(p->module);
65 }
66
67
68 static GData *plugins = NULL;
69
70 void plugin_startup()
71 {
72 g_datalist_init(&plugins);
73 }
74
75 void plugin_shutdown()
76 {
77 g_datalist_clear(&plugins);
78 }
79
80 gboolean plugin_open(char *name)
81 {
82 Plugin *p;
83
84 if (g_datalist_get_data(&plugins, name) != NULL) {
85 g_warning("plugin '%s' already loaded, can't load again", name);
86 return TRUE;
87 }
88
89 p = plugin_new(name);
90 if (p == NULL) {
91 g_warning("failed to load plugin '%s'", name);
92 return FALSE;
93 }
94
95 g_datalist_set_data_full(&plugins, name, p, (GDestroyNotify) plugin_free);
96 p->startup();
97 return TRUE;
98 }
99
100 void plugin_close(char *name)
101 {
102 g_datalist_remove_data(&plugins, name);
103 }
This page took 0.046823 seconds and 5 git commands to generate.