diff --git a/Makefile.am b/Makefile.am index 060cf7dc..433af840 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,4 @@ -#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: diff --git a/configure.ac b/configure.ac index 21fc5219..dea5e17d 100644 --- a/configure.ac +++ b/configure.ac @@ -68,6 +68,31 @@ PKG_CHECK_MODULES(LIBSN, [libstartup-notification-1.0], ] ) +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 @@ -82,12 +107,16 @@ AC_CONFIG_FILES([Makefile 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 diff --git a/openbox/Makefile.am b/openbox/Makefile.am index ecb72969..fc9f4ae3 100644 --- a/openbox/Makefile.am +++ b/openbox/Makefile.am @@ -1,15 +1,15 @@ 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)\" @@ -20,9 +20,9 @@ LIBS=$(X_LIBS) $(XFT_LIBS) $(XINERAMA_LIBS) $(XKB_LIBS) $(XRANDR_LIBS) \ 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 \ @@ -32,7 +32,7 @@ noinst_HEADERS=action.h client.h config.h dispatch.h event.h extensions.h \ 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 diff --git a/openbox/action.c b/openbox/action.c index 9015939e..2dde0f0b 100644 --- a/openbox/action.c +++ b/openbox/action.c @@ -548,6 +548,56 @@ Action *action_from_string(char *name) 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; diff --git a/openbox/action.h b/openbox/action.h index 5630f8f4..6c1c4d32 100644 --- a/openbox/action.h +++ b/openbox/action.h @@ -2,6 +2,7 @@ #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* @@ -120,6 +121,7 @@ Action *action_new(void (*func)(union ActionData *data)); */ Action *action_from_string(char *name); +Action *action_parse(xmlDocPtr doc, xmlNodePtr node); void action_free(Action *a); /* Execute */ diff --git a/openbox/config.c b/openbox/config.c index c3fa786c..491097e4 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -1,5 +1,5 @@ #include "config.h" -#include "parse.h" +#include "parser/parse.h" gboolean config_focus_new; gboolean config_focus_follow; diff --git a/openbox/focus.c b/openbox/focus.c index 1de349ba..de98d63b 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -10,7 +10,6 @@ #include "prop.h" #include "dispatch.h" #include "focus.h" -#include "parse.h" #include "stacking.h" #include "popup.h" diff --git a/openbox/openbox.c b/openbox/openbox.c index 2b4dddce..0455e88c 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -12,13 +12,13 @@ #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" @@ -66,6 +66,8 @@ int main(int argc, char **argv) sigset_t sigset; char *path; char *theme; + xmlDocPtr doc; + xmlNodePtr node; ob_state = State_Starting; @@ -180,7 +182,8 @@ int main(int argc, char **argv) /* 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(); diff --git a/openbox/parse.c b/openbox/parse.c deleted file mode 100644 index 8f9c82fb..00000000 --- a/openbox/parse.c +++ /dev/null @@ -1,243 +0,0 @@ -#include "parse.h" -#include - -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; -} diff --git a/openbox/plugin.c b/openbox/plugin.c index a47052e4..747bde6f 100644 --- a/openbox/plugin.c +++ b/openbox/plugin.c @@ -1,12 +1,8 @@ +#include "plugins/interface.h" + #include #include -typedef void (*PluginSetupConfig)(); -typedef void (*PluginStartup)(); -typedef void (*PluginShutdown)(); -typedef void *(*PluginCreate)(/* TODO */); -typedef void (*PluginDestroy)(void *); - typedef struct { GModule *module; char *name; diff --git a/parser/.cvsignore b/parser/.cvsignore new file mode 100644 index 00000000..cb737897 --- /dev/null +++ b/parser/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +libobparser.la +parse.lo diff --git a/parser/Makefile.am b/parser/Makefile.am new file mode 100644 index 00000000..fe80db16 --- /dev/null +++ b/parser/Makefile.am @@ -0,0 +1,20 @@ +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 .\#* diff --git a/parser/parse.c b/parser/parse.c new file mode 100644 index 00000000..2b81594a --- /dev/null +++ b/parser/parse.c @@ -0,0 +1,190 @@ +#include "parse.h" +#include + +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; +} diff --git a/openbox/parse.h b/parser/parse.h similarity index 72% rename from openbox/parse.h rename to parser/parse.h index 199e8104..948bf4ba 100644 --- a/openbox/parse.h +++ b/parser/parse.h @@ -1,8 +1,6 @@ #ifndef __parse_h #define __parse_h -#include "action.h" - #include #include @@ -11,13 +9,22 @@ typedef void (*ParseCallback)(xmlDocPtr doc, xmlNodePtr node, void *data); void parse_startup(); void parse_shutdown(); +/* Loads Openbox's rc, from $HOME or $PREFIX as a fallback */ +gboolean parse_load_rc(xmlDocPtr *doc, xmlNodePtr *root); + +/* callbacks - must call parse_startup to use these */ + void parse_register(const char *tag, ParseCallback func, void *data); - -void parse_config(); - 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); @@ -33,6 +40,4 @@ gboolean parse_attr_contains(const char *val, 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 diff --git a/plugins/Makefile.am b/plugins/Makefile.am index b23259d6..ec89616d 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -1,20 +1,6 @@ -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 diff --git a/plugins/interface.h b/plugins/interface.h new file mode 100644 index 00000000..8c5c6458 --- /dev/null +++ b/plugins/interface.h @@ -0,0 +1,19 @@ +#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 diff --git a/plugins/keyboard/keyboard.c b/plugins/keyboard/keyboard.c index d1d93241..374f2493 100644 --- a/plugins/keyboard/keyboard.c +++ b/plugins/keyboard/keyboard.c @@ -5,8 +5,8 @@ #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" @@ -45,7 +45,7 @@ static void parse_key(xmlDocPtr doc, xmlNodePtr node, GList *keylist) 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 != diff --git a/plugins/menu/Makefile.am b/plugins/menu/Makefile.am index 40b9b64d..3ed9c5c6 100644 --- a/plugins/menu/Makefile.am +++ b/plugins/menu/Makefile.am @@ -1,6 +1,7 @@ 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../.. diff --git a/plugins/mouse/mouse.c b/plugins/mouse/mouse.c index 0bfe602c..a2b3d7e0 100644 --- a/plugins/mouse/mouse.c +++ b/plugins/mouse/mouse.c @@ -5,8 +5,8 @@ #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 @@ -59,7 +59,7 @@ static void parse_xml(xmlDocPtr doc, xmlNodePtr node, void *d) 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 || diff --git a/plugins/obconf_interface.h b/plugins/obconf_interface.h new file mode 100644 index 00000000..52b19a8f --- /dev/null +++ b/plugins/obconf_interface.h @@ -0,0 +1,40 @@ +#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 diff --git a/plugins/placement/history.c b/plugins/placement/history.c index 9d932b9e..716487b6 100644 --- a/plugins/placement/history.c +++ b/plugins/placement/history.c @@ -3,7 +3,7 @@ #include "kernel/frame.h" #include "kernel/client.h" #include "kernel/screen.h" -#include "kernel/parse.h" +#include "parser/parse.h" #include "history.h" #include #include @@ -193,18 +193,8 @@ static void load_history() 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) { diff --git a/plugins/placement/placement.c b/plugins/placement/placement.c index dd818970..889168b9 100644 --- a/plugins/placement/placement.c +++ b/plugins/placement/placement.c @@ -3,7 +3,7 @@ #include "kernel/frame.h" #include "kernel/screen.h" #include "kernel/openbox.h" -#include "kernel/parse.h" +#include "parser/parse.h" #include "history.h" #include diff --git a/plugins/resistance/.cvsignore b/plugins/resistance/.cvsignore new file mode 100644 index 00000000..fe97c5fa --- /dev/null +++ b/plugins/resistance/.cvsignore @@ -0,0 +1,8 @@ +.deps +.libs +Makefile +Makefile.in +resistance-config.la +resistance.la +resistance_config_la-resistance_config.lo +resistance_la-resistance.lo diff --git a/plugins/resistance/Makefile.am b/plugins/resistance/Makefile.am new file mode 100644 index 00000000..9f95f947 --- /dev/null +++ b/plugins/resistance/Makefile.am @@ -0,0 +1,32 @@ +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 .\#* diff --git a/plugins/resistance.c b/plugins/resistance/resistance.c similarity index 98% rename from plugins/resistance.c rename to plugins/resistance/resistance.c index ee6f6e1e..91c10c0e 100644 --- a/plugins/resistance.c +++ b/plugins/resistance/resistance.c @@ -1,9 +1,10 @@ #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 static int resistance; @@ -21,8 +22,8 @@ static void parse_xml(xmlDocPtr doc, xmlNodePtr node, void *d) void plugin_setup_config() { - resistance = 10; - resist_windows = TRUE; + resistance = DEFAULT_RESISTANCE; + resist_windows = DEFAULT_RESIST_WINDOWS; parse_register("resistance", parse_xml, NULL); } diff --git a/plugins/resistance/resistance.glade b/plugins/resistance/resistance.glade new file mode 100644 index 00000000..ecb52b0e --- /dev/null +++ b/plugins/resistance/resistance.glade @@ -0,0 +1,109 @@ + + + + + + + + GTK_WINDOW_POPUP + GTK_WIN_POS_NONE + False + True + False + + + + True + False + 0 + + + + True + False + 6 + + + + True + _Strength + True + False + GTK_JUSTIFY_LEFT + False + False + 0.49 + 0.5 + 0 + 0 + resist_strength + + + 0 + False + False + + + + + + True + 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. + True + 1 + 0 + True + GTK_UPDATE_ALWAYS + False + False + 1 0 30 1 10 10 + + + 0 + False + True + + + + + 0 + True + True + + + + + + True + False + 6 + + + + True + True + Resist other _Windows + True + GTK_RELIEF_NORMAL + False + False + True + + + 0 + False + False + + + + + 0 + True + True + + + + + + + diff --git a/plugins/resistance/resistance.gladep b/plugins/resistance/resistance.gladep new file mode 100644 index 00000000..1951d46b --- /dev/null +++ b/plugins/resistance/resistance.gladep @@ -0,0 +1,8 @@ + + + + + resistance + resistance + FALSE + diff --git a/plugins/resistance/resistance.h b/plugins/resistance/resistance.h new file mode 100644 index 00000000..5bec224b --- /dev/null +++ b/plugins/resistance/resistance.h @@ -0,0 +1,2 @@ +#define DEFAULT_RESISTANCE 10 +#define DEFAULT_RESIST_WINDOWS TRUE diff --git a/plugins/resistance/resistance_config.c b/plugins/resistance/resistance_config.c new file mode 100644 index 00000000..1384fe3f --- /dev/null +++ b/plugins/resistance/resistance_config.c @@ -0,0 +1,64 @@ +#include "plugins/obconf_interface.h" +#include "parser/parse.h" +#include "resistance.h" +#include +#include + +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() +{ +} 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 +#include + +/*#include +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 @@ + + + + + + + ObConf + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + True + + + + + True + False + 0 + + + + True + + + + True + _File + True + + + + + + + True + gtk-quit + True + + + + + + + + + + + True + _Help + True + + + + + + + True + _About + True + + + + + + + + + + 0 + False + False + + + + + + 6 + True + True + 121 + + + + True + False + 0 + + + + True + Sections + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + False + False + False + True + + + + + + 0 + True + True + + + + + True + False + + + + + + True + False + 0 + + + + True + Options + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + False + False + GTK_POS_TOP + False + False + + + + + + + + + + + 0 + True + True + + + + + True + True + + + + + 0 + True + True + + + + + + True + + + 0 + False + True + + + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_START + 0 + + + + True + True + True + gtk-help + True + GTK_RELIEF_NORMAL + + + + + + 6 + True + True + + + + + + True + GTK_BUTTONBOX_END + 6 + + + + True + True + True + GTK_RELIEF_NORMAL + + + + + True + 0.5 + 0.5 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-cancel + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + _Revert + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + + + + + + + True + True + True + True + gtk-apply + True + GTK_RELIEF_NORMAL + + + + + + 6 + True + True + GTK_PACK_END + + + + + 6 + False + True + + + + + + + + About ObConf + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + False + True + + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + gtk-close + True + GTK_RELIEF_NORMAL + -7 + + + + + + 0 + False + True + GTK_PACK_END + + + + + + True + ObConf + +ObConf is a configuration tool for the +Openbox Window Manager. + + + + +ObConf is (c) 2003 Ben Jansens + False + True + GTK_JUSTIFY_CENTER + True + False + 0.5 + 0.5 + 0 + 0 + + + 0 + True + True + + + + + + + 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 @@ + + + + + ObConf + obconf + FALSE + 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 + +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 +#include +#include +#include + +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 + +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