-#SUBDIRS = po themes doc render cwmcc obcl kernel plugins
-SUBDIRS = po themes data render kernel plugins
+SUBDIRS = po themes data render parser kernel plugins tools
MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in stamp-h.in
doc:
]
)
+PKG_CHECK_MODULES(GTK, [gtk+-2.0],
+ [
+ AC_SUBST(GTK_CFLAGS)
+ AC_SUBST(GTK_LIBS)
+ use_gtk="yes"
+
+ PKG_CHECK_MODULES(GLADE, [libglade-2.0],
+ [
+ AC_SUBST(GLADE_CFLAGS)
+ AC_SUBST(GLADE_LIBS)
+ use_glade="yes"
+ ],
+ [
+ use_glade="no"
+ AC_MSG_WARN([disabling build of the configuration tool])
+ ]
+ )
+ ],
+ [
+ use_gtk="no"
+ AC_MSG_WARN([disabling build of the configuration tool])
+ ]
+)
+AM_CONDITIONAL(OBCONF, [test "$use_gtk" = "yes" && test "$use_glade" = "yes"])
+
# Check for X11 extensions
X11_EXT_XKB
X11_EXT_XRANDR
themes/Makefile
data/Makefile
render/Makefile
+ parser/Makefile
kernel/Makefile
plugins/Makefile
+ plugins/resistance/Makefile
plugins/placement/Makefile
plugins/mouse/Makefile
plugins/keyboard/Makefile
- plugins/menu/Makefile])
+ plugins/menu/Makefile
+ tools/Makefile
+ tools/obconf/Makefile])
AC_OUTPUT
AC_MSG_RESULT
localedir=$(datadir)/locale
-plugindir=$(libdir)/openbox/plugins
rcdir=$(datadir)/openbox
+plugindir=$(libdir)/openbox/plugins
binary=openbox3
-url=http://icculus.org/openbox
+url=http://openbox.org/
CPPFLAGS=$(X_CFLAGS) $(XFT_CFLAGS) $(GLIB_CFLAGS) $(GMODULE_CFLAGS) \
$(LIBSN_CFLAGS) $(GL_CFLAGS) $(XML_CFLAGS) @CPPFLAGS@ \
-DLOCALEDIR=\"$(localedir)\" \
- -DRCDIR=\"$(rcdir)\" \
-DPLUGINDIR=\"$(plugindir)\" \
+ -DRCDIR=\"$(rcdir)\" \
-DG_LOG_DOMAIN=\"Openbox\" \
-DBINARY=\"$(binary)\"
bin_PROGRAMS=$(binary)
-openbox3_LDADD=-lobrender -L../render
+openbox3_LDADD=-lobrender -L../render -lobparser -L../parser
openbox3_LDFLAGS=-export-dynamic
-openbox3_SOURCES=action.c client.c config.c parse.c \
+openbox3_SOURCES=action.c client.c config.c \
extensions.c focus.c frame.c grab.c menu.c menu_render.c \
openbox.c framerender.c plugin.c prop.c screen.c \
stacking.c dispatch.c event.c group.c timer.c xerror.c \
focus.h frame.h framerender.h geom.h gettext.h grab.h group.h \
menu.h openbox.h plugin.h prop.h screen.h \
stacking.h timer.h xerror.h moveresize.h startup.h popup.h \
- dock.h window.h parse.h
+ dock.h window.h
MAINTAINERCLEANFILES=Makefile.in
return a;
}
+Action *action_parse(xmlDocPtr doc, xmlNodePtr node)
+{
+ char *actname;
+ Action *act = NULL;
+ xmlNodePtr n;
+
+ if (parse_attr_string("name", node, &actname)) {
+ if ((act = action_from_string(actname))) {
+ if (act->func == action_execute || act->func == action_restart) {
+ if ((n = parse_find_node("execute", node->xmlChildrenNode)))
+ act->data.execute.path = parse_string(doc, n);
+ } else if (act->func == action_showmenu) {
+ if ((n = parse_find_node("menu", node->xmlChildrenNode)))
+ act->data.showmenu.name = parse_string(doc, n);
+ } else if (act->func == action_desktop) {
+ if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
+ act->data.desktop.desk = parse_int(doc, n);
+ if (act->data.desktop.desk > 0) act->data.desktop.desk--;
+ } else if (act->func == action_send_to_desktop) {
+ if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
+ act->data.sendto.desk = parse_int(doc, n);
+ if (act->data.sendto.desk > 0) act->data.sendto.desk--;
+ } else if (act->func == action_move_relative_horz ||
+ act->func == action_move_relative_vert ||
+ act->func == action_resize_relative_horz ||
+ act->func == action_resize_relative_vert) {
+ if ((n = parse_find_node("delta", node->xmlChildrenNode)))
+ act->data.relative.delta = parse_int(doc, n);
+ } else if (act->func == action_desktop_right ||
+ act->func == action_desktop_left ||
+ act->func == action_desktop_up ||
+ act->func == action_desktop_down) {
+ if ((n = parse_find_node("wrap", node->xmlChildrenNode))) {
+ g_message("WRAP %d", parse_bool(doc, n));
+ act->data.desktopdir.wrap = parse_bool(doc, n);
+ }
+ } else if (act->func == action_send_to_desktop_right ||
+ act->func == action_send_to_desktop_left ||
+ act->func == action_send_to_desktop_up ||
+ act->func == action_send_to_desktop_down) {
+ if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
+ act->data.sendtodir.wrap = parse_bool(doc, n);
+ if ((n = parse_find_node("follow", node->xmlChildrenNode)))
+ act->data.sendtodir.follow = parse_bool(doc, n);
+ }
+ }
+ }
+ return act;
+}
+
void action_execute(union ActionData *data)
{
GError *e = NULL;
#define __action_h
#include "client.h"
+#include "parser/parse.h"
/* These have to all have a Client* at the top even if they don't use it, so
that I can set it blindly later on. So every function will have a Client*
*/
Action *action_from_string(char *name);
+Action *action_parse(xmlDocPtr doc, xmlNodePtr node);
void action_free(Action *a);
/* Execute */
#include "config.h"
-#include "parse.h"
+#include "parser/parse.h"
gboolean config_focus_new;
gboolean config_focus_follow;
#include "prop.h"
#include "dispatch.h"
#include "focus.h"
-#include "parse.h"
#include "stacking.h"
#include "popup.h"
#include "moveresize.h"
#include "frame.h"
#include "extensions.h"
-#include "parse.h"
#include "grab.h"
#include "plugin.h"
#include "timer.h"
#include "group.h"
#include "config.h"
#include "gettext.h"
+#include "parser/parse.h"
#include "render/render.h"
#include "render/font.h"
#include "render/theme.h"
sigset_t sigset;
char *path;
char *theme;
+ xmlDocPtr doc;
+ xmlNodePtr node;
ob_state = State_Starting;
/* set up the kernel config shit */
config_startup();
/* parse/load user options */
- parse_config();
+ if (parse_load_rc(&doc, &node))
+ parse_tree(doc, node->xmlChildrenNode, NULL);
/* we're done with parsing now, kill it */
parse_shutdown();
+++ /dev/null
-#include "parse.h"
-#include <glib.h>
-
-struct Callback {
- char *tag;
- ParseCallback func;
- void *data;
-};
-
-static GHashTable *callbacks;
-static xmlDocPtr doc_config = NULL;
-
-static void destfunc(struct Callback *c)
-{
- g_free(c->tag);
- g_free(c);
-}
-
-void parse_startup()
-{
- callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
- (GDestroyNotify)destfunc);
-}
-
-void parse_shutdown()
-{
- xmlFree(doc_config);
- doc_config = NULL;
-
- g_hash_table_destroy(callbacks);
-}
-
-void parse_register(const char *tag, ParseCallback func, void *data)
-{
- struct Callback *c;
-
- if ((c = g_hash_table_lookup(callbacks, tag))) {
- g_warning("tag '%s' already registered", tag);
- return;
- }
-
- c = g_new(struct Callback, 1);
- c->tag = g_strdup(tag);
- c->func = func;
- c->data = data;
- g_hash_table_insert(callbacks, c->tag, c);
-}
-
-void parse_config()
-{
- char *path;
- xmlNodePtr node = NULL;
-
- xmlLineNumbersDefault(1);
-
- path = g_build_filename(g_get_home_dir(), ".openbox", "rc3", NULL);
- if ((doc_config = xmlParseFile(path))) {
- node = xmlDocGetRootElement(doc_config);
- if (!node) {
- xmlFreeDoc(doc_config);
- doc_config = NULL;
- g_warning("%s is an empty document", path);
- } else {
- if (xmlStrcasecmp(node->name, (const xmlChar*)"openbox_config")) {
- xmlFreeDoc(doc_config);
- doc_config = NULL;
- g_warning("document %s is of wrong type. root node is "
- "not 'openbox_config'", path);
- }
- }
- }
- g_free(path);
- if (!doc_config) {
- path = g_build_filename(RCDIR, "rc3", NULL);
- if ((doc_config = xmlParseFile(path))) {
- node = xmlDocGetRootElement(doc_config);
- if (!node) {
- xmlFreeDoc(doc_config);
- doc_config = NULL;
- g_warning("%s is an empty document", path);
- } else {
- if (xmlStrcasecmp(node->name,
- (const xmlChar*)"openbox_config")) {
- xmlFreeDoc(doc_config);
- doc_config = NULL;
- g_warning("document %s is of wrong type. root node is "
- "not 'openbox_config'", path);
- }
- }
- }
- g_free(path);
- }
- if (!doc_config) {
- g_message("unable to find a valid config file, using defaults");
- } else {
- parse_tree(doc_config, node->xmlChildrenNode, NULL);
- }
-}
-
-void parse_tree(xmlDocPtr doc, xmlNodePtr node, void *nothing)
-{
- while (node) {
- struct Callback *c = g_hash_table_lookup(callbacks, node->name);
-
- if (c)
- c->func(doc, node->xmlChildrenNode, c->data);
-
- node = node->next;
- }
-}
-
-char *parse_string(xmlDocPtr doc, xmlNodePtr node)
-{
- xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
- char *s = g_strdup((char*)c);
- xmlFree(c);
- return s;
-}
-
-int parse_int(xmlDocPtr doc, xmlNodePtr node)
-{
- xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
- int i = atoi((char*)c);
- xmlFree(c);
- return i;
-}
-
-gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node)
-{
- xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
- gboolean b = FALSE;
- if (!xmlStrcasecmp(c, (const xmlChar*) "true"))
- b = TRUE;
- else if (!xmlStrcasecmp(c, (const xmlChar*) "yes"))
- b = TRUE;
- else if (!xmlStrcasecmp(c, (const xmlChar*) "on"))
- b = TRUE;
- xmlFree(c);
- return b;
-}
-
-gboolean parse_contains(const char *val, xmlDocPtr doc, xmlNodePtr node)
-{
- xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
- gboolean r;
- r = !xmlStrcasecmp(c, (const xmlChar*) val);
- xmlFree(c);
- return r;
-}
-
-xmlNodePtr parse_find_node(const char *tag, xmlNodePtr node)
-{
- while (node) {
- if (!xmlStrcasecmp(node->name, (const xmlChar*) tag))
- return node;
- node = node->next;
- }
- return NULL;
-}
-
-gboolean parse_attr_int(const char *name, xmlNodePtr node, int *value)
-{
- xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
- gboolean r = FALSE;
- if (c) {
- *value = atoi((char*)c);
- r = TRUE;
- }
- xmlFree(c);
- return r;
-}
-
-gboolean parse_attr_string(const char *name, xmlNodePtr node, char **value)
-{
- xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
- gboolean r = FALSE;
- if (c) {
- *value = g_strdup((char*)c);
- r = TRUE;
- }
- xmlFree(c);
- return r;
-}
-
-Action *parse_action(xmlDocPtr doc, xmlNodePtr node)
-{
- char *actname;
- Action *act = NULL;
- xmlNodePtr n;
-
- if (parse_attr_string("name", node, &actname)) {
- if ((act = action_from_string(actname))) {
- if (act->func == action_execute || act->func == action_restart) {
- if ((n = parse_find_node("execute", node->xmlChildrenNode)))
- act->data.execute.path = parse_string(doc, n);
- } else if (act->func == action_showmenu) {
- if ((n = parse_find_node("menu", node->xmlChildrenNode)))
- act->data.showmenu.name = parse_string(doc, n);
- } else if (act->func == action_desktop) {
- if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
- act->data.desktop.desk = parse_int(doc, n);
- if (act->data.desktop.desk > 0) act->data.desktop.desk--;
- } else if (act->func == action_send_to_desktop) {
- if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
- act->data.sendto.desk = parse_int(doc, n);
- if (act->data.sendto.desk > 0) act->data.sendto.desk--;
- } else if (act->func == action_move_relative_horz ||
- act->func == action_move_relative_vert ||
- act->func == action_resize_relative_horz ||
- act->func == action_resize_relative_vert) {
- if ((n = parse_find_node("delta", node->xmlChildrenNode)))
- act->data.relative.delta = parse_int(doc, n);
- } else if (act->func == action_desktop_right ||
- act->func == action_desktop_left ||
- act->func == action_desktop_up ||
- act->func == action_desktop_down) {
- if ((n = parse_find_node("wrap", node->xmlChildrenNode))) {
- g_message("WRAP %d", parse_bool(doc, n));
- act->data.desktopdir.wrap = parse_bool(doc, n);
- }
- } else if (act->func == action_send_to_desktop_right ||
- act->func == action_send_to_desktop_left ||
- act->func == action_send_to_desktop_up ||
- act->func == action_send_to_desktop_down) {
- if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
- act->data.sendtodir.wrap = parse_bool(doc, n);
- if ((n = parse_find_node("follow", node->xmlChildrenNode)))
- act->data.sendtodir.follow = parse_bool(doc, n);
- }
- }
- }
- return act;
-}
-
-gboolean parse_attr_contains(const char *val, xmlNodePtr node,
- const char *name)
-{
- xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
- gboolean r;
- r = !xmlStrcasecmp(c, (const xmlChar*) val);
- xmlFree(c);
- return r;
-}
+#include "plugins/interface.h"
+
#include <glib.h>
#include <gmodule.h>
-typedef void (*PluginSetupConfig)();
-typedef void (*PluginStartup)();
-typedef void (*PluginShutdown)();
-typedef void *(*PluginCreate)(/* TODO */);
-typedef void (*PluginDestroy)(void *);
-
typedef struct {
GModule *module;
char *name;
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+libobparser.la
+parse.lo
--- /dev/null
+localedir=$(datadir)/locale
+rcdir=$(datadir)/openbox
+
+CPPFLAGS=$(GLIB_CFLAGS) $(XML_CFLAGS) @CPPFLAGS@ \
+ -DG_LOG_DOMAIN=\"Parser\" \
+ -DLOCALEDIR=\"$(localedir)\" \
+ -DRCDIR=\"$(rcdir)\"
+
+INCLUDES=-I..
+LIBS=$(GLIB_LIBS) $(XML_LIBS) @LIBS@
+
+lib_LTLIBRARIES=libobparser.la
+libobparser_la_SOURCES=parse.c
+
+noinst_HEADERS=parse.h
+
+MAINTAINERCLEANFILES=Makefile.in
+
+distclean-local:
+ $(RM) *\~ *.orig *.rej .\#*
--- /dev/null
+#include "parse.h"
+#include <glib.h>
+
+struct Callback {
+ char *tag;
+ ParseCallback func;
+ void *data;
+};
+
+static GHashTable *callbacks;
+
+static void destfunc(struct Callback *c)
+{
+ g_free(c->tag);
+ g_free(c);
+}
+
+void parse_startup()
+{
+ callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify)destfunc);
+}
+
+void parse_shutdown()
+{
+ g_hash_table_destroy(callbacks);
+}
+
+void parse_register(const char *tag, ParseCallback func, void *data)
+{
+ struct Callback *c;
+
+ if ((c = g_hash_table_lookup(callbacks, tag))) {
+ g_warning("tag '%s' already registered", tag);
+ return;
+ }
+
+ c = g_new(struct Callback, 1);
+ c->tag = g_strdup(tag);
+ c->func = func;
+ c->data = data;
+ g_hash_table_insert(callbacks, c->tag, c);
+}
+
+gboolean parse_load_rc(xmlDocPtr *doc, xmlNodePtr *root)
+{
+ char *path;
+ gboolean r = FALSE;
+
+ path = g_build_filename(g_get_home_dir(), ".openbox", "rc3", NULL);
+ if (parse_load(path, "openbox_config", doc, root)) {
+ r = TRUE;
+ } else {
+ g_free(path);
+ path = g_build_filename(RCDIR, "rc3", NULL);
+ if (parse_load(path, "openbox_config", doc, root)) {
+ r = TRUE;
+ }
+ }
+ g_free(path);
+ if (!r)
+ g_message("unable to find a valid config file, using defaults");
+ return r;
+}
+
+gboolean parse_load(const char *path, const char *rootname,
+ xmlDocPtr *doc, xmlNodePtr *root)
+{
+
+ xmlLineNumbersDefault(1);
+
+ if ((*doc = xmlParseFile(path))) {
+ *root = xmlDocGetRootElement(*doc);
+ if (!*root) {
+ xmlFreeDoc(*doc);
+ *doc = NULL;
+ g_warning("%s is an empty document", path);
+ } else {
+ if (xmlStrcasecmp((*root)->name, (const xmlChar*)rootname)) {
+ xmlFreeDoc(*doc);
+ *doc = NULL;
+ g_warning("document %s is of wrong type. root *root is "
+ "not 'openbox_config'", path);
+ }
+ }
+ }
+ if (!*doc)
+ return FALSE;
+ return TRUE;
+}
+
+void parse_close(xmlDocPtr doc)
+{
+ xmlFree(doc);
+}
+
+void parse_tree(xmlDocPtr doc, xmlNodePtr node, void *nothing)
+{
+ while (node) {
+ struct Callback *c = g_hash_table_lookup(callbacks, node->name);
+
+ if (c)
+ c->func(doc, node->xmlChildrenNode, c->data);
+
+ node = node->next;
+ }
+}
+
+char *parse_string(xmlDocPtr doc, xmlNodePtr node)
+{
+ xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
+ char *s = g_strdup((char*)c);
+ xmlFree(c);
+ return s;
+}
+
+int parse_int(xmlDocPtr doc, xmlNodePtr node)
+{
+ xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
+ int i = atoi((char*)c);
+ xmlFree(c);
+ return i;
+}
+
+gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node)
+{
+ xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
+ gboolean b = FALSE;
+ if (!xmlStrcasecmp(c, (const xmlChar*) "true"))
+ b = TRUE;
+ else if (!xmlStrcasecmp(c, (const xmlChar*) "yes"))
+ b = TRUE;
+ else if (!xmlStrcasecmp(c, (const xmlChar*) "on"))
+ b = TRUE;
+ xmlFree(c);
+ return b;
+}
+
+gboolean parse_contains(const char *val, xmlDocPtr doc, xmlNodePtr node)
+{
+ xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
+ gboolean r;
+ r = !xmlStrcasecmp(c, (const xmlChar*) val);
+ xmlFree(c);
+ return r;
+}
+
+xmlNodePtr parse_find_node(const char *tag, xmlNodePtr node)
+{
+ while (node) {
+ if (!xmlStrcasecmp(node->name, (const xmlChar*) tag))
+ return node;
+ node = node->next;
+ }
+ return NULL;
+}
+
+gboolean parse_attr_int(const char *name, xmlNodePtr node, int *value)
+{
+ xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
+ gboolean r = FALSE;
+ if (c) {
+ *value = atoi((char*)c);
+ r = TRUE;
+ }
+ xmlFree(c);
+ return r;
+}
+
+gboolean parse_attr_string(const char *name, xmlNodePtr node, char **value)
+{
+ xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
+ gboolean r = FALSE;
+ if (c) {
+ *value = g_strdup((char*)c);
+ r = TRUE;
+ }
+ xmlFree(c);
+ return r;
+}
+
+gboolean parse_attr_contains(const char *val, xmlNodePtr node,
+ const char *name)
+{
+ xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
+ gboolean r;
+ r = !xmlStrcasecmp(c, (const xmlChar*) val);
+ xmlFree(c);
+ return r;
+}
#ifndef __parse_h
#define __parse_h
-#include "action.h"
-
#include <libxml/parser.h>
#include <glib.h>
void parse_startup();
void parse_shutdown();
-void parse_register(const char *tag, ParseCallback func, void *data);
+/* Loads Openbox's rc, from $HOME or $PREFIX as a fallback */
+gboolean parse_load_rc(xmlDocPtr *doc, xmlNodePtr *root);
-void parse_config();
+/* callbacks - must call parse_startup to use these */
+void parse_register(const char *tag, ParseCallback func, void *data);
void parse_tree(xmlDocPtr doc, xmlNodePtr node, void *nothing);
+/* open/close */
+
+gboolean parse_load(const char *path, const char *rootname,
+ xmlDocPtr *doc, xmlNodePtr *root);
+void parse_close(xmlDocPtr doc);
+
+
/* helpers */
xmlNodePtr parse_find_node(const char *tag, xmlNodePtr node);
gboolean parse_attr_string(const char *name, xmlNodePtr node, char **value);
gboolean parse_attr_int(const char *name, xmlNodePtr node, int *value);
-Action *parse_action(xmlDocPtr doc, xmlNodePtr node);
-
#endif
-plugindir=$(libdir)/openbox/plugins
+SUBDIRS = keyboard mouse placement menu resistance
-SUBDIRS = keyboard mouse placement menu
-
-CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) $(GL_CFLAGS) \
- $(XML_CFLAGS) @CPPFLAGS@ \
--DPLUGINDIR=\"$(plugindir)\"
-
-INCLUDES=-I..
-
-plugin_LTLIBRARIES=resistance.la
-
-resistance_la_CPPFLAGS=-DG_LOG_DOMAIN=\"Plugin-Resistance\"
-resistance_la_LDFLAGS=-module -avoid-version
-resistance_la_SOURCES=resistance.c
-
-noinst_HEADERS=
+noinst_HEADERS = interface.h obconf_interface.h
MAINTAINERCLEANFILES= Makefile.in
--- /dev/null
+#ifndef __plugins_interface_h
+#define __plugins_interface_h
+
+/* plugin_setup_config() */
+typedef void (*PluginSetupConfig)(void);
+
+/* plugin_startup() */
+typedef void (*PluginStartup)(void);
+
+/* plugin_shutdown() */
+typedef void (*PluginShutdown)(void);
+
+/* plugin_create() - for menu plugins only */
+typedef void *(*PluginCreate)(/* TODO */);
+
+/* plugin_destroy() - for menu plugins only */
+typedef void (*PluginDestroy)(void *);
+
+#endif
#include "kernel/grab.h"
#include "kernel/action.h"
#include "kernel/prop.h"
-#include "kernel/parse.h"
#include "kernel/timer.h"
+#include "parser/parse.h"
#include "tree.h"
#include "keyboard.h"
#include "translate.h"
if (keylist) {
nact = parse_find_node("action", node);
while (nact) {
- if ((action = parse_action(doc, nact))) {
+ if ((action = action_parse(doc, nact))) {
/* validate that its okay for a key binding */
if (action->func == action_moveresize &&
action->data.moveresize.corner !=
plugindir=$(libdir)/openbox/plugins
-CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) @CPPFLAGS@ \
+CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) $(XML_CFLAGS)
+ \@CPPFLAGS@ \
-DG_LOG_DOMAIN=\"Plugin-Timed-Menu\"
INCLUDES=-I../..
#include "kernel/client.h"
#include "kernel/prop.h"
#include "kernel/grab.h"
-#include "kernel/parse.h"
#include "kernel/frame.h"
+#include "parser/parse.h"
#include "translate.h"
#include "mouse.h"
#include <glib.h>
goto next_nbut;
nact = parse_find_node("action", nbut->xmlChildrenNode);
while (nact) {
- if ((action = parse_action(doc, nact))) {
+ if ((action = action_parse(doc, nact))) {
/* validate that its okay for a mouse binding*/
if (mact == MouseAction_Motion) {
if (action->func != action_moveresize ||
--- /dev/null
+#ifndef __obconf_plugin_interface_h
+#define __obconf_plugin_interface_h
+
+#include "parser/parse.h"
+
+struct GtkWidget;
+
+#define OBCONF_INTERFACE_VERSION 1
+
+/* plugin_interface_version() */
+typedef int (*PluginInterfaceVersionFunc)(void);
+
+/* plugin_startup() */
+typedef void (*PluginStartupFunc)(void);
+
+/* plugin_shutdown() */
+typedef void (*PluginShutdownFunc)(void);
+
+/* plugin_name() - user friendly name of the plugin */
+typedef char* (*PluginNameFunc)(void);
+
+/* plugin_plugin_name() - the name of the plugin to load with openbox */
+typedef char* (*PluginPluginNameFunc)(void);
+
+/* plugin_icon() XXX FIXME */
+typedef void (*PluginIconFunc)(void);
+
+/* plugin_toplevel_widget() */
+typedef struct _GtkWidget* (*PluginToplevelWidgetFunc)(void);
+
+/* plugin_edited() */
+typedef gboolean (*PluginEditedFunc)(void);
+
+/* plugin_load() */
+typedef void (*PluginLoadFunc)(xmlDocPtr doc, xmlNodePtr root);
+
+/* plugin_save() */
+typedef void (*PluginSaveFunc)(xmlDocPtr doc, xmlNodePtr root);
+
+#endif
#include "kernel/frame.h"
#include "kernel/client.h"
#include "kernel/screen.h"
-#include "kernel/parse.h"
+#include "parser/parse.h"
#include "history.h"
#include <glib.h>
#include <string.h>
char *role;
struct HistoryItem *hi;
- if (!(doc = xmlParseFile(history_path)))
+ if (!parse_load(history_path, "openbox_history", &doc, &node))
return;
- if (!(node = xmlDocGetRootElement(doc))) {
- xmlFreeDoc(doc);
- doc = NULL;
- return;
- }
- if (xmlStrcasecmp(node->name, (const xmlChar*)"openbox_history")) {
- xmlFreeDoc(doc);
- doc = NULL;
- return;
- }
node = parse_find_node("entry", node->xmlChildrenNode);
while (node) {
#include "kernel/frame.h"
#include "kernel/screen.h"
#include "kernel/openbox.h"
-#include "kernel/parse.h"
+#include "parser/parse.h"
#include "history.h"
#include <glib.h>
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+resistance-config.la
+resistance.la
+resistance_config_la-resistance_config.lo
+resistance_la-resistance.lo
--- /dev/null
+plugindir=$(libdir)/openbox/plugins
+
+CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) $(GL_CFLAGS) \
+ $(XML_CFLAGS) @CPPFLAGS@ \
+ -DPLUGINDIR=\"$(plugindir)\"
+
+INCLUDES=-I../.. -I../../tools
+
+plugin_LTLIBRARIES=resistance.la
+if OBCONF
+plugin_LTLIBRARIES+=resistance-config.la
+endif
+
+resistance_la_CPPFLAGS=-DG_LOG_DOMAIN=\"Plugin-Resistance\"
+resistance_la_LDFLAGS=-module -avoid-version
+resistance_la_SOURCES=resistance.c
+
+if OBCONF
+resistance_config_la_CPPFLAGS=-DG_LOG_DOMAIN=\"Plugin-Resistance\" \
+ $(GTK_CFLAGS) $(GLADE_CFLAGS)
+resistance_config_la_LDFLAGS=-module -avoid-version
+resistance_config_la_SOURCES=resistance_config.c
+endif
+
+noinst_HEADERS=resistance.h
+
+noinst_DATA=resistance.glade resistance.gladep
+
+MAINTAINERCLEANFILES= Makefile.in
+
+distclean-local:
+ $(RM) *\~ *.orig *.rej .\#*
#include "kernel/dispatch.h"
#include "kernel/client.h"
#include "kernel/frame.h"
-#include "kernel/parse.h"
#include "kernel/stacking.h"
#include "kernel/screen.h"
+#include "parser/parse.h"
+#include "resistance.h"
#include <glib.h>
static int resistance;
void plugin_setup_config()
{
- resistance = 10;
- resist_windows = TRUE;
+ resistance = DEFAULT_RESISTANCE;
+ resist_windows = DEFAULT_RESIST_WINDOWS;
parse_register("resistance", parse_xml, NULL);
}
--- /dev/null
+<?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="resistwindow">
+ <property name="title" translatable="yes"></property>
+ <property name="type">GTK_WINDOW_POPUP</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">False</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Strength</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.49</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">resist_strength</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkSpinButton" id="resist_strength">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Set to the amount of resistance to provide when moving or resizing a window past a screen or window edge. A value of 0 disables resistance.</property>
+ <property name="can_focus">True</property>
+ <property name="climb_rate">1</property>
+ <property name="digits">0</property>
+ <property name="numeric">True</property>
+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+ <property name="snap_to_ticks">False</property>
+ <property name="wrap">False</property>
+ <property name="adjustment">1 0 30 1 10 10</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">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="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkCheckButton" id="resist_windows">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Resist other _Windows</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
--- /dev/null
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd">
+
+<glade-project>
+ <name>resistance</name>
+ <program_name>resistance</program_name>
+ <gnome_support>FALSE</gnome_support>
+</glade-project>
--- /dev/null
+#define DEFAULT_RESISTANCE 10
+#define DEFAULT_RESIST_WINDOWS TRUE
--- /dev/null
+#include "plugins/obconf_interface.h"
+#include "parser/parse.h"
+#include "resistance.h"
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+
+static GtkWidget *conf_widget;
+static GtkCheckButton *conf_resist_windows;
+static GtkSpinButton *conf_resist_strength;
+static gboolean conf_edited = FALSE;
+
+int plugin_interface_version() { return OBCONF_INTERFACE_VERSION; }
+
+char *plugin_name() { return "Resistance"; }
+char *plugin_plugin_name() { return "resistance"; }
+void plugin_icon() {}
+
+GtkWidget *plugin_toplevel_widget() { return conf_widget; }
+
+gboolean plugin_edited() { return conf_edited; }
+
+void plugin_load(xmlDocPtr doc, xmlNodePtr root)
+{
+ xmlNodePtr node, n;
+
+ gtk_spin_button_set_value(conf_resist_strength, DEFAULT_RESISTANCE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(conf_resist_windows),
+ DEFAULT_RESIST_WINDOWS);
+
+ node = parse_find_node("resistance", root);
+ while (node) {
+ if ((n = parse_find_node("strength", node)))
+ gtk_spin_button_set_value(conf_resist_strength,
+ parse_int(doc, n));
+ if ((n = parse_find_node("windows", node)))
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON(conf_resist_windows),
+ parse_bool(doc, n));
+
+ node = parse_find_node("resistance", node->next);
+ }
+}
+
+void plugin_save(xmlDocPtr doc, xmlNodePtr root)
+{
+}
+
+void plugin_startup()
+{
+ GladeXML *xml;
+
+ xml = glade_xml_new("obconf.glade", NULL, NULL);
+ glade_xml_signal_autoconnect(xml);
+
+ conf_widget = glade_xml_get_widget(xml, "resistwindow");
+ conf_resist_strength =
+ GTK_SPIN_BUTTON(glade_xml_get_widget(xml, "resist_strength"));
+ conf_resist_windows =
+ GTK_CHECK_BUTTON(glade_xml_get_widget(xml, "resist_windows"));
+}
+
+void plugin_shutdown()
+{
+}
--- /dev/null
+Makefile
+Makefile.in
--- /dev/null
+SUBDIRS =
+
+if OBCONF
+SUBDIRS += obconf
+endif
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+obconf
--- /dev/null
+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 .\#*
--- /dev/null
+#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));
+}
+
--- /dev/null
+#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");
+}
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+#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
--- /dev/null
+#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);
+}
--- /dev/null
+#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