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