summaryrefslogtreecommitdiff
path: root/tools/obconf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/obconf')
-rw-r--r--tools/obconf/.cvsignore5
-rw-r--r--tools/obconf/Makefile.am26
-rw-r--r--tools/obconf/about.c18
-rw-r--r--tools/obconf/main.c91
-rw-r--r--tools/obconf/obconf.glade427
-rw-r--r--tools/obconf/obconf.gladep8
-rw-r--r--tools/obconf/obconf.h12
-rw-r--r--tools/obconf/plugins.c157
-rw-r--r--tools/obconf/plugins.h16
9 files changed, 760 insertions, 0 deletions
diff --git a/tools/obconf/.cvsignore b/tools/obconf/.cvsignore
new file mode 100644
index 00000000..b35c97a5
--- /dev/null
+++ b/tools/obconf/.cvsignore
@@ -0,0 +1,5 @@
+.deps
+.libs
+Makefile
+Makefile.in
+obconf
diff --git a/tools/obconf/Makefile.am b/tools/obconf/Makefile.am
new file mode 100644
index 00000000..a83049f3
--- /dev/null
+++ b/tools/obconf/Makefile.am
@@ -0,0 +1,26 @@
+localedir=$(datadir)/locale
+plugindir=$(libdir)/openbox/plugins
+rcdir=$(datadir)/openbox
+
+CPPFLAGS=$(GTK_CFLAGS) $(GLADE_CFLAGS) $(GMODULE_CFLAGS) $(XML_CFLAGS) \
+ @CPPFLAGS@ \
+ -DLOCALEDIR=\"$(localedir)\" \
+ -DRCDIR=\"$(rcdir)\" \
+ -DPLUGINDIR=\"$(plugindir)\" \
+ -DG_LOG_DOMAIN=\"ObConf\"
+
+INCLUDES=-I../..
+LIBS=$(GTK_LIBS) $(GLADE_LIBS) $(GMODULE_LIBS) $(XML_LIBS) @LIBS@ @LIBINTL@
+
+bin_PROGRAMS=obconf
+
+obconf_LDADD=-lobparser -L../../parser
+obconf_LDFLAGS=-export-dynamic
+obconf_SOURCES=main.c about.c plugins.c
+
+noinst_HEADERS=obconf.h plugins.h
+
+MAINTAINERCLEANFILES=Makefile.in
+
+distclean-local:
+ $(RM) *\~ *.orig *.rej .\#*
diff --git a/tools/obconf/about.c b/tools/obconf/about.c
new file mode 100644
index 00000000..34de63f9
--- /dev/null
+++ b/tools/obconf/about.c
@@ -0,0 +1,18 @@
+#include "obconf.h"
+
+void on_about_activate(GtkMenuItem *item, gpointer d)
+{
+ gtk_widget_show(GTK_WIDGET(obconf_about));
+}
+
+gboolean on_aboutdialog_delete_event(GtkWidget *w, GdkEvent *e, gpointer d)
+{
+ gtk_widget_hide(GTK_WIDGET(obconf_about));
+ return TRUE;
+}
+
+void on_about_closebutton_clicked(GtkButton *but, gpointer d)
+{
+ gtk_widget_hide(GTK_WIDGET(obconf_about));
+}
+
diff --git a/tools/obconf/main.c b/tools/obconf/main.c
new file mode 100644
index 00000000..f0eb7306
--- /dev/null
+++ b/tools/obconf/main.c
@@ -0,0 +1,91 @@
+#include "obconf.h"
+#include "plugins.h"
+#include "parser/parse.h"
+
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+
+/*#include <X11/Xlib.h>
+Display *ob_display;
+int ob_screen;
+Window ob_root;*/
+
+GtkWindow *obconf_win;
+GtkWindow *obconf_about = NULL;
+
+GtkTreeView *obconf_sections;
+GtkListStore *obconf_sections_store;
+static GtkCellRenderer *obconf_sections_renderer;
+static GtkTreeViewColumn *obconf_sections_column;
+
+GtkNotebook *obconf_options;
+
+static xmlDocPtr doc;
+static xmlNodePtr root;
+
+int main(int argc, char **argv)
+{
+ GladeXML *xml;
+
+ gtk_init(&argc, &argv);
+
+ xml = glade_xml_new("obconf.glade", NULL, NULL);
+ glade_xml_signal_autoconnect(xml);
+
+ obconf_win = GTK_WINDOW(glade_xml_get_widget(xml, "mainwindow"));
+ gtk_window_set_role(obconf_win, "main");
+ obconf_about = GTK_WINDOW(glade_xml_get_widget(xml, "aboutdialog"));
+ gtk_window_set_role(obconf_about, "about");
+ gtk_window_set_transient_for(obconf_about, obconf_win);
+ obconf_sections = GTK_TREE_VIEW(glade_xml_get_widget(xml, "sectiontree"));
+ obconf_options = GTK_NOTEBOOK(glade_xml_get_widget(xml,"optionsnotebook"));
+
+ obconf_sections_store = gtk_list_store_new(1, G_TYPE_STRING);
+ gtk_tree_view_set_model(obconf_sections,
+ GTK_TREE_MODEL(obconf_sections_store));
+ obconf_sections_renderer = gtk_cell_renderer_text_new();
+ obconf_sections_column = gtk_tree_view_column_new_with_attributes
+ ("Section", obconf_sections_renderer, "text", 0, NULL);
+ gtk_tree_view_append_column (obconf_sections, obconf_sections_column);
+
+ parse_load_rc(&doc, &root);
+
+ plugins_load();
+
+ gtk_widget_show(GTK_WIDGET(obconf_win));
+
+ gtk_main();
+ return 0;
+}
+
+gboolean on_mainwindow_delete_event(GtkWidget *w, GdkEvent *e, gpointer d)
+{
+ gtk_main_quit();
+ return FALSE;
+}
+
+void on_quit_activate(GtkMenuItem *item, gpointer d)
+{
+ gtk_main_quit();
+}
+
+void on_applybutton_clicked(GtkButton *but, gpointer d)
+{
+ g_message("apply");
+}
+
+void on_revertbutton_clicked(GtkButton *but, gpointer d)
+{
+ g_message("revert");
+}
+
+void on_helpbutton_clicked(GtkButton *but, gpointer d)
+{
+ g_message("help");
+}
+
+void on_sectiontree_row_activated(GtkTreeView *tree, GtkTreePath *path,
+ GtkTreeViewColumn *col, gpointer p)
+{
+ g_message("activated");
+}
diff --git a/tools/obconf/obconf.glade b/tools/obconf/obconf.glade
new file mode 100644
index 00000000..205706bb
--- /dev/null
+++ b/tools/obconf/obconf.glade
@@ -0,0 +1,427 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="mainwindow">
+ <property name="title" translatable="yes">ObConf</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">True</property>
+ <signal name="delete_event" handler="on_mainwindow_delete_event" last_modification_time="Sat, 24 May 2003 17:17:43 GMT"/>
+
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkMenuBar" id="menubar1">
+ <property name="visible">True</property>
+
+ <child>
+ <widget class="GtkMenuItem" id="menuitem1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="menuitem1_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="quit">
+ <property name="visible">True</property>
+ <property name="label">gtk-quit</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="on_quit_activate" last_modification_time="Sat, 24 May 2003 17:00:32 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="menuitem4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Help</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="menuitem4_menu">
+
+ <child>
+ <widget class="GtkMenuItem" id="about">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_About</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_about_activate" last_modification_time="Sat, 24 May 2003 17:00:32 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHPaned" id="hpaned1">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="position">121</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Sections</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="sectiontree">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <signal name="row_activated" handler="on_sectiontree_row_activated" last_modification_time="Sat, 24 May 2003 17:00:00 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Options</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkNotebook" id="optionsnotebook">
+ <property name="visible">True</property>
+ <property name="show_tabs">False</property>
+ <property name="show_border">False</property>
+ <property name="tab_pos">GTK_POS_TOP</property>
+ <property name="scrollable">False</property>
+ <property name="enable_popup">False</property>
+
+ <child>
+ <placeholder/>
+ </child>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHSeparator" id="hseparator1">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkHButtonBox" id="hbuttonbox1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_START</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkButton" id="helpbutton">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-help</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <signal name="clicked" handler="on_helpbutton_clicked" last_modification_time="Sat, 24 May 2003 16:59:34 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">6</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHButtonBox" id="hbuttonbox2">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkButton" id="revertbutton">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <signal name="clicked" handler="on_revertbutton_clicked" last_modification_time="Sat, 24 May 2003 16:59:29 GMT"/>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+
+ <child>
+ <widget class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="stock">gtk-cancel</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Revert</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="applybutton">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-apply</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <signal name="clicked" handler="on_applybutton_clicked" last_modification_time="Sat, 24 May 2003 16:59:16 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">6</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">6</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="aboutdialog">
+ <property name="title" translatable="yes">About ObConf</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">False</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="has_separator">True</property>
+ <signal name="delete_event" handler="on_aboutdialog_delete_event" last_modification_time="Sat, 24 May 2003 17:29:16 GMT"/>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="about_closebutton">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-close</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="response_id">-7</property>
+ <signal name="clicked" handler="on_about_closebutton_clicked" last_modification_time="Sat, 24 May 2003 17:24:49 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">ObConf
+
+ObConf is a configuration tool for the
+Openbox Window Manager.
+
+
+
+
+ObConf is (c) 2003 Ben Jansens</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
diff --git a/tools/obconf/obconf.gladep b/tools/obconf/obconf.gladep
new file mode 100644
index 00000000..5ef3ad07
--- /dev/null
+++ b/tools/obconf/obconf.gladep
@@ -0,0 +1,8 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd">
+
+<glade-project>
+ <name>ObConf</name>
+ <program_name>obconf</program_name>
+ <gnome_support>FALSE</gnome_support>
+</glade-project>
diff --git a/tools/obconf/obconf.h b/tools/obconf/obconf.h
new file mode 100644
index 00000000..5d7a2e67
--- /dev/null
+++ b/tools/obconf/obconf.h
@@ -0,0 +1,12 @@
+#ifndef __obconf_h
+#define __obconf_h
+
+#include <gtk/gtk.h>
+
+extern GtkWindow *obconf_win;
+extern GtkWindow *obconf_about;
+extern GtkTreeView *obconf_sections;
+extern GtkListStore *obconf_sections_store;
+extern GtkNotebook *obconf_options;
+
+#endif
diff --git a/tools/obconf/plugins.c b/tools/obconf/plugins.c
new file mode 100644
index 00000000..f838b962
--- /dev/null
+++ b/tools/obconf/plugins.c
@@ -0,0 +1,157 @@
+#include "obconf.h"
+#include "plugins/obconf_interface.h"
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <string.h>
+#include <gmodule.h>
+
+typedef struct ConfigPlugin {
+ GModule *module;
+ char *fname;
+ char *name;
+ char *plugin_name;
+
+ PluginStartupFunc start;
+ PluginShutdownFunc stop;
+ PluginInterfaceVersionFunc interface;
+ PluginNameFunc getname;
+ PluginPluginNameFunc getpname;
+ PluginIconFunc icon;
+ PluginToplevelWidgetFunc toplevel;
+ PluginEditedFunc edited;
+ PluginLoadFunc load;
+ PluginSaveFunc save;
+} ConfigPlugin;
+
+GSList *plugins_list = NULL;
+
+static gpointer load_sym(GModule *module, char *name, char *symbol,
+ gboolean allow_fail)
+{
+ gpointer var;
+ if (!g_module_symbol(module, symbol, &var)) {
+ if (!allow_fail)
+ g_warning("Failed to load symbol '%s' from plugin '%s'",
+ symbol, name);
+ var = NULL;
+ }
+ return var;
+}
+
+static void add_plugin(ConfigPlugin *p)
+{
+ GtkTreeIter it;
+
+ gtk_list_store_append(obconf_sections_store, &it);
+ gtk_list_store_set(obconf_sections_store, &it, 0, p->name, -1);
+ gtk_notebook_append_page(obconf_options, p->toplevel(), NULL);
+}
+
+void load_dir(char *path)
+{
+ char *fpath;
+ DIR *dir;
+ struct dirent *dirp;
+ ConfigPlugin *p;
+ GModule *mod;
+ GSList *it;
+ char *suffix;
+
+ suffix = g_strconcat("-config.", G_MODULE_SUFFIX, NULL);
+
+ if (!(dir = opendir(path)))
+ return;
+ while ((dirp = readdir(dir))) {
+ if (g_strrstr(dirp->d_name, suffix)) {
+ /* look for duplicates */
+ for (it = plugins_list; it; it = it->next)
+ if (!strcmp(((ConfigPlugin*)it->data)->fname, dirp->d_name))
+ break;
+ if (!it) {
+ fpath = g_build_filename(path, dirp->d_name, NULL);
+
+ if ((mod = g_module_open(fpath, 0))) {
+ p = g_new(ConfigPlugin, 1);
+ p->module = mod;
+ p->fname = g_strdup(dirp->d_name);
+
+ p->interface = (PluginInterfaceVersionFunc)
+ load_sym(p->module, p->fname,
+ "plugin_interface_version",
+ FALSE);
+ p->start = (PluginStartupFunc)
+ load_sym(p->module, p->fname, "plugin_startup", FALSE);
+ p->stop = (PluginShutdownFunc)
+ load_sym(p->module, p->fname, "plugin_shutdown",FALSE);
+ p->getname = (PluginNameFunc)
+ load_sym(p->module, p->fname, "plugin_name", FALSE);
+ p->getpname = (PluginNameFunc)
+ load_sym(p->module, p->fname, "plugin_plugin_name",
+ FALSE);
+ p->icon = (PluginIconFunc)
+ load_sym(p->module, p->fname, "plugin_icon", FALSE);
+ p->toplevel = (PluginToplevelWidgetFunc)
+ load_sym(p->module, p->fname, "plugin_toplevel_widget",
+ FALSE);
+ p->edited = (PluginEditedFunc)
+ load_sym(p->module, p->fname, "plugin_edited", FALSE);
+ p->load = (PluginLoadFunc)
+ load_sym(p->module, p->fname, "plugin_load", FALSE);
+ p->save = (PluginSaveFunc)
+ load_sym(p->module, p->fname, "plugin_save", FALSE);
+
+ if (!(p->start &&
+ p->stop &&
+ p->interface &&
+ p->name &&
+ p->icon &&
+ p->toplevel &&
+ p->edited &&
+ p->load &&
+ p->save)) {
+ g_module_close(p->module);
+ g_free(p->fname);
+ g_free(p);
+ } else {
+ p->start();
+ p->name = p->getname();
+ p->plugin_name = p->getpname();
+ plugins_list = g_slist_append(plugins_list, p);
+
+ add_plugin(p); /* add to the gui */
+ }
+ }
+ g_free(fpath);
+ }
+ }
+ }
+
+ g_free(suffix);
+}
+
+void plugins_load()
+{
+ char *path;
+
+ path = g_build_filename(g_get_home_dir(), ".openbox", "plugins", NULL);
+ load_dir(path);
+ g_free(path);
+
+ load_dir(PLUGINDIR);
+}
+
+gboolean plugins_edited(ConfigPlugin *p)
+{
+ return p->edited();
+}
+
+void plugins_load_settings(ConfigPlugin *p, xmlDocPtr doc, xmlNodePtr root)
+{
+ p->load(doc, root);
+}
+
+void plugins_save_settings(ConfigPlugin *p, xmlDocPtr doc, xmlNodePtr root)
+{
+ p->save(doc, root);
+}
diff --git a/tools/obconf/plugins.h b/tools/obconf/plugins.h
new file mode 100644
index 00000000..485a8c2f
--- /dev/null
+++ b/tools/obconf/plugins.h
@@ -0,0 +1,16 @@
+#ifndef __plugins_h
+#define __plugins_h
+
+#include <libxml/parser.h>
+
+typedef struct ConfigPlugin ConfigPlugin;
+
+extern GSList *plugins_list;
+
+void plugins_load();
+
+gboolean plugins_edited(ConfigPlugin *p);
+void plugins_load_settings(ConfigPlugin *p, xmlDocPtr doc, xmlNodePtr root);
+void plugins_save_settings(ConfigPlugin *p, xmlDocPtr doc, xmlNodePtr root);
+
+#endif