]> Dogcows Code - chaz/openbox/blob - tools/obconf/plugins.c
dont use obsolete xmlChildrenNode
[chaz/openbox] / tools / obconf / plugins.c
1 #include "obconf.h"
2 #include "plugins/obconf_interface.h"
3
4 #include <sys/types.h>
5 #include <dirent.h>
6 #include <string.h>
7 #include <gmodule.h>
8
9 typedef struct ConfigPlugin {
10 GModule *module;
11 char *fname;
12 char *name;
13 char *plugin_name;
14
15 PluginStartupFunc start;
16 PluginShutdownFunc stop;
17 PluginInterfaceVersionFunc interface;
18 PluginNameFunc getname;
19 PluginPluginNameFunc getpname;
20 PluginIconFunc icon;
21 PluginToplevelWidgetFunc toplevel;
22 PluginEditedFunc edited;
23 PluginLoadFunc load;
24 PluginSaveFunc save;
25 } ConfigPlugin;
26
27 GSList *plugins_list = NULL;
28
29 static gpointer load_sym(GModule *module, char *name, char *symbol,
30 gboolean allow_fail)
31 {
32 gpointer var;
33 if (!g_module_symbol(module, symbol, &var)) {
34 if (!allow_fail)
35 g_warning("Failed to load symbol '%s' from plugin '%s'",
36 symbol, name);
37 var = NULL;
38 }
39 return var;
40 }
41
42 static void add_plugin(ConfigPlugin *p)
43 {
44 GtkTreeIter it;
45
46 gtk_list_store_append(obconf_sections_store, &it);
47 gtk_list_store_set(obconf_sections_store, &it, 0, p->name, -1);
48 gtk_notebook_append_page(obconf_options, p->toplevel(), NULL);
49 }
50
51 void load_dir(char *path)
52 {
53 char *fpath;
54 DIR *dir;
55 struct dirent *dirp;
56 ConfigPlugin *p;
57 GModule *mod;
58 GSList *it;
59 char *suffix;
60
61 suffix = g_strconcat("-config.", G_MODULE_SUFFIX, NULL);
62
63 if (!(dir = opendir(path)))
64 return;
65 while ((dirp = readdir(dir))) {
66 if (g_strrstr(dirp->d_name, suffix)) {
67 /* look for duplicates */
68 for (it = plugins_list; it; it = it->next)
69 if (!strcmp(((ConfigPlugin*)it->data)->fname, dirp->d_name))
70 break;
71 if (!it) {
72 fpath = g_build_filename(path, dirp->d_name, NULL);
73
74 if ((mod = g_module_open(fpath, 0))) {
75 p = g_new(ConfigPlugin, 1);
76 p->module = mod;
77 p->fname = g_strdup(dirp->d_name);
78
79 p->interface = (PluginInterfaceVersionFunc)
80 load_sym(p->module, p->fname,
81 "plugin_interface_version",
82 FALSE);
83 p->start = (PluginStartupFunc)
84 load_sym(p->module, p->fname, "plugin_startup", FALSE);
85 p->stop = (PluginShutdownFunc)
86 load_sym(p->module, p->fname, "plugin_shutdown",FALSE);
87 p->getname = (PluginNameFunc)
88 load_sym(p->module, p->fname, "plugin_name", FALSE);
89 p->getpname = (PluginNameFunc)
90 load_sym(p->module, p->fname, "plugin_plugin_name",
91 FALSE);
92 p->icon = (PluginIconFunc)
93 load_sym(p->module, p->fname, "plugin_icon", FALSE);
94 p->toplevel = (PluginToplevelWidgetFunc)
95 load_sym(p->module, p->fname, "plugin_toplevel_widget",
96 FALSE);
97 p->edited = (PluginEditedFunc)
98 load_sym(p->module, p->fname, "plugin_edited", FALSE);
99 p->load = (PluginLoadFunc)
100 load_sym(p->module, p->fname, "plugin_load", FALSE);
101 p->save = (PluginSaveFunc)
102 load_sym(p->module, p->fname, "plugin_save", FALSE);
103
104 if (!(p->start &&
105 p->stop &&
106 p->interface &&
107 p->name &&
108 p->icon &&
109 p->toplevel &&
110 p->edited &&
111 p->load &&
112 p->save)) {
113 g_module_close(p->module);
114 g_free(p->fname);
115 g_free(p);
116 } else {
117 p->start();
118 p->name = p->getname();
119 p->plugin_name = p->getpname();
120 plugins_list = g_slist_append(plugins_list, p);
121
122 add_plugin(p); /* add to the gui */
123 }
124 }
125 g_free(fpath);
126 }
127 }
128 }
129
130 g_free(suffix);
131 }
132
133 void plugins_load()
134 {
135 char *path;
136
137 path = g_build_filename(g_get_home_dir(), ".openbox", "plugins", NULL);
138 load_dir(path);
139 g_free(path);
140
141 load_dir(PLUGINDIR);
142 }
143
144 gboolean plugins_edited(ConfigPlugin *p)
145 {
146 return p->edited();
147 }
148
149 void plugins_load_settings(ConfigPlugin *p, xmlDocPtr doc, xmlNodePtr root)
150 {
151 p->load(doc, root);
152 }
153
154 void plugins_save_settings(ConfigPlugin *p, xmlDocPtr doc, xmlNodePtr root)
155 {
156 p->save(doc, root);
157 }
This page took 0.043707 seconds and 4 git commands to generate.