summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2003-05-24 21:47:06 +0000
committerDana Jansens <danakj@orodu.net>2003-05-24 21:47:06 +0000
commitd1e355de2c6aae38cea3cdc0e0b902ea2b194e86 (patch)
treedcb99d7232895e2b54ed58fbaa7d3a775da9ccfc /tools
parent927f99e4125743bbecf41b1aa7dbce9587fb6156 (diff)
this is a big one! im putting stats in here just cuz!
59 files changed, 1691 insertions(+), 607 deletions(-) Adding the beginings of ObConf. Adding a resistance-config plugin for ObConf. Creating an obparser library that obrender can use, the kernel can use, plugins can use, and ObConf and its plugins can use. (its just code for using libXml2)
Diffstat (limited to 'tools')
-rw-r--r--tools/.cvsignore2
-rw-r--r--tools/Makefile.am5
-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
11 files changed, 767 insertions, 0 deletions
diff --git a/tools/.cvsignore b/tools/.cvsignore
new file mode 100644
index 00000000..282522db
--- /dev/null
+++ b/tools/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644
index 00000000..86eaea70
--- /dev/null
+++ b/tools/Makefile.am
@@ -0,0 +1,5 @@
+SUBDIRS =
+
+if OBCONF
+SUBDIRS += obconf
+endif
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