Parse ObActionsList*s from the config file (out of the xml for now).
authorDana Jansens <danakj@orodu.net>
Wed, 27 Jul 2011 20:32:05 +0000 (16:32 -0400)
committerDana Jansens <danakj@orodu.net>
Sun, 16 Oct 2011 22:55:14 +0000 (18:55 -0400)
- config.c: use the new actions parser
- actions.c: provide the actions parser a way to create a new action (takes
    a hash table of options for it)
- actions/*.c: take a hash table of options instead of an xml subtree
- *: us ObActionsList* instead of a GList* of ObActionAct*s.

TODO:
1. make filters
  openbox/filters/*.c
  openbox/filters.c as interface to them
  store filters in parsed filter tests instead of key/value pairs
2. make action(s) to change config options
  includes key and mouse binding
3. rm -rf *xml*

40 files changed:
Makefile.am
openbox/actions.c
openbox/actions.h
openbox/actions/addremovedesktop.c
openbox/actions/all.c
openbox/actions/all.h
openbox/actions/cyclewindows.c
openbox/actions/debug.c
openbox/actions/desktop.c
openbox/actions/directionalwindows.c
openbox/actions/execute.c
openbox/actions/exit.c
openbox/actions/focus.c
openbox/actions/growtoedge.c
openbox/actions/layer.c
openbox/actions/maximize.c
openbox/actions/moverelative.c
openbox/actions/moveresizeto.c
openbox/actions/movetoedge.c
openbox/actions/resize.c
openbox/actions/resizerelative.c
openbox/actions/restart.c
openbox/actions/showmenu.c
openbox/actions_list.c
openbox/actions_list.h
openbox/actions_parser.c
openbox/actions_parser.h
openbox/actions_value.c [new file with mode: 0644]
openbox/actions_value.h [new file with mode: 0644]
openbox/config.c
openbox/keyboard.c
openbox/keyboard.h
openbox/keytree.c
openbox/keytree.h
openbox/menu.c
openbox/menu.h
openbox/menuframe.c
openbox/mouse.c
openbox/mouse.h
openbox/openbox.c

index 542a2474a48ecb611cb42f8c0f6431519fcd52b2..9c281a1e6a2a834af3baacefc006afb5dc9e9989 100644 (file)
@@ -215,7 +215,6 @@ openbox_openbox_SOURCES = \
        openbox/actions/fullscreen.c \
        openbox/actions/growtoedge.c \
        openbox/actions/iconify.c \
-       openbox/actions/if.c \
        openbox/actions/kill.c \
        openbox/actions/layer.c \
        openbox/actions/lower.c \
@@ -242,6 +241,8 @@ openbox_openbox_SOURCES = \
        openbox/actions_list.h \
        openbox/actions_parser.c \
        openbox/actions_parser.h \
+       openbox/actions_value.c \
+       openbox/actions_value.h \
        openbox/apps_menu.c \
        openbox/apps_menu.h \
        openbox/client.c \
index 2288ea6d6bfbf90d0e0f1e872755a5c02aeccf32..76c7cb507a02e7ab99a6ca08f2542325e2c5be6e 100644 (file)
@@ -17,6 +17,7 @@
 */
 
 #include "actions.h"
+#include "actions_list.h"
 #include "gettext.h"
 #include "grab.h"
 #include "screen.h"
@@ -33,7 +34,7 @@ static void     actions_definition_ref(ObActionsDefinition *def);
 static void     actions_definition_unref(ObActionsDefinition *def);
 static gboolean actions_interactive_begin_act(ObActionsAct *act, guint state);
 static void     actions_interactive_end_act();
-static ObActionsAct* actions_build_act_from_string(const gchar *name);
+static ObActionsAct* actions_act_find_name(const gchar *name);
 
 static ObActionsAct *interactive_act = NULL;
 static guint         interactive_initial_state = 0;
@@ -169,7 +170,7 @@ static void actions_definition_unref(ObActionsDefinition *def)
     }
 }
 
-static ObActionsAct* actions_build_act_from_string(const gchar *name)
+static ObActionsAct* actions_act_find_name(const gchar *name)
 {
     GSList *it;
     ObActionsDefinition *def = NULL;
@@ -205,7 +206,7 @@ ObActionsAct* actions_parse_string(const gchar *name)
 {
     ObActionsAct *act = NULL;
 
-    if ((act = actions_build_act_from_string(name))) {
+    if ((act = actions_act_find_name(name))) {
         if (act->def->canbeinteractive) {
             if (act->def->setup.i)
                 act->options = act->def->setup.i(NULL,
@@ -230,11 +231,11 @@ ObActionsAct* actions_parse(xmlNodePtr node)
     ObActionsAct *act = NULL;
 
     if (obt_xml_attr_string(node, "name", &name)) {
-        if ((act = actions_build_act_from_string(name))) {
+        if ((act = actions_act_find_name(name))) {
             /* there is more stuff to parse here */
             if (act->def->canbeinteractive) {
                 if (act->def->setup.i)
-                    act->options = act->def->setup.i(node->children,
+                    act->options = act->def->setup.i(NULL,
                                                      &act->i_pre,
                                                      &act->i_input,
                                                      &act->i_cancel,
@@ -242,7 +243,7 @@ ObActionsAct* actions_parse(xmlNodePtr node)
             }
             else {
                 if (act->def->setup.n)
-                    act->options = act->def->setup.n(node->children);
+                    act->options = act->def->setup.n(NULL);
             }
         }
         g_free(name);
@@ -251,17 +252,16 @@ ObActionsAct* actions_parse(xmlNodePtr node)
     return act;
 }
 
-ObActionsAct* actions_act_new(const gchar *name, GList *keys, GList *values)
+ObActionsAct* actions_act_new(const gchar *name, GHashTable *config)
 {
     ObActionsAct *act = NULL;
 
-    act = actions_build_act_from_string(name);
+    act = actions_act_find_name(name);
     if (act) {
         /* there is more stuff to parse here */
         if (act->def->canbeinteractive) {
             if (act->def->setup.i)
-//XXX                act->options = act->def->setup.i(keys, values,
-                act->options = act->def->setup.i(NULL,
+                act->options = act->def->setup.i(config,
                                                  &act->i_pre,
                                                  &act->i_input,
                                                  &act->i_cancel,
@@ -269,11 +269,9 @@ ObActionsAct* actions_act_new(const gchar *name, GList *keys, GList *values)
         }
         else {
             if (act->def->setup.n)
-//XXX                act->options = act->def->setup.n(keys, values);
-                act->options = act->def->setup.n(NULL);
+                act->options = act->def->setup.n(config);
         }
     }
-    g_free(name);
 
     return act;
 }
@@ -318,16 +316,16 @@ static void actions_setup_data(ObActionsData *data,
     data->client = client;
 }
 
-void actions_run_acts(GSList *acts,
-                      ObUserAction uact,
-                      guint state,
-                      gint x,
-                      gint y,
-                      gint button,
-                      ObFrameContext con,
-                      struct _ObClient *client)
+gboolean actions_run_acts(ObActionsList *acts,
+                          ObUserAction uact,
+                          guint state,
+                          gint x,
+                          gint y,
+                          gint button,
+                          ObFrameContext con,
+                          struct _ObClient *client)
 {
-    GSList *it;
+    gboolean ran_interactive;
     gboolean update_user_time;
 
     /* Don't allow saving the initial state when running things from the
@@ -338,12 +336,22 @@ void actions_run_acts(GSList *acts,
     if (x < 0 && y < 0)
         screen_pointer_pos(&x, &y);
 
+    ran_interactive = FALSE;
     update_user_time = FALSE;
-    for (it = acts; it; it = g_slist_next(it)) {
+    while (acts) {
+        ObActionsAct *act;
         ObActionsData data;
-        ObActionsAct *act = it->data;
         gboolean ok = TRUE;
 
+        if (acts->isfilter) {
+            g_warning("filters not implemented!");
+            acts = acts->next;
+            continue;
+        }
+        else {
+            act = acts->u.action;
+        }
+
         actions_setup_data(&data, uact, state, x, y, button, con, client);
 
         /* if they have the same run function, then we'll assume they are
@@ -356,10 +364,13 @@ void actions_run_acts(GSList *acts,
                 if (act->i_pre)
                     if (!act->i_pre(state, act->options))
                         act->i_input = NULL; /* remove the interactivity */
+                ran_interactive = TRUE;
             }
             /* check again cuz it might have been cancelled */
-            if (actions_act_is_interactive(act))
+            if (actions_act_is_interactive(act)) {
                 ok = actions_interactive_begin_act(act, state);
+                ran_interactive = TRUE;
+            }
         }
 
         /* fire the action's run function with this data */
@@ -377,9 +388,11 @@ void actions_run_acts(GSList *acts,
                 break;
             }
         }
+        acts = acts->next;
     }
     if (update_user_time)
         event_update_user_time();
+    return ran_interactive;
 }
 
 gboolean actions_interactive_act_running(void)
index 16a48ca89fbf2da33688ef08454a0bbaf93f9c24..55b0f138f41d1a1e73f18caf659003c97586e4fe 100644 (file)
@@ -24,6 +24,8 @@
 #include <glib.h>
 #include <X11/Xlib.h>
 
+struct _ObActionsList;
+
 typedef struct _ObActionsDefinition   ObActionsDefinition;
 typedef struct _ObActionsAct          ObActionsAct;
 typedef struct _ObActionsData         ObActionsData;
@@ -35,7 +37,7 @@ typedef struct _ObActionsSelectorData ObActionsSelectorData;
 typedef void     (*ObActionsDataFreeFunc)(gpointer options);
 typedef gboolean (*ObActionsRunFunc)(ObActionsData *data,
                                      gpointer options);
-typedef gpointer (*ObActionsDataSetupFunc)(xmlNodePtr node);
+typedef gpointer (*ObActionsDataSetupFunc)(GHashTable *config);
 typedef void     (*ObActionsShutdownFunc)(void);
 
 /* functions for interactive actions */
@@ -49,7 +51,7 @@ typedef gboolean (*ObActionsIInputFunc)(guint initial_state,
                                         gpointer options,
                                         gboolean *used);
 typedef void     (*ObActionsICancelFunc)(gpointer options);
-typedef gpointer (*ObActionsIDataSetupFunc)(xmlNodePtr node,
+typedef gpointer (*ObActionsIDataSetupFunc)(GHashTable *config,
                                             ObActionsIPreFunc *pre,
                                             ObActionsIInputFunc *input,
                                             ObActionsICancelFunc *cancel,
@@ -94,7 +96,7 @@ gboolean actions_act_is_interactive(ObActionsAct *act);
   @values The values of the options passed to the action, paired with the
     keys.  These are ObActionsListValue objects.
 */
-ObActionsAct* actions_act_new(const gchar *name, GList *keys, GList *values);
+ObActionsAct* actions_act_new(const gchar *name, GHashTable *config);
 
 void actions_act_ref(ObActionsAct *act);
 void actions_act_unref(ObActionsAct *act);
@@ -108,15 +110,17 @@ void actions_set_need_pointer_replay_before_move(gboolean replay);
   actions then this will be false */
 gboolean actions_get_need_pointer_replay_before_move(void);
 
-/*! Pass in a GSList of ObActionsAct's to be run. */
-void actions_run_acts(GSList *acts,
-                      ObUserAction uact,
-                      guint state,
-                      gint x,
-                      gint y,
-                      gint button,
-                      ObFrameContext con,
-                      struct _ObClient *client);
+/*! Runs a list of actions.
+ @return TRUE if an interactive action was started, FALSE otherwise.
+*/
+gboolean actions_run_acts(struct _ObActionsList *acts,
+                          ObUserAction uact,
+                          guint state,
+                          gint x,
+                          gint y,
+                          gint button,
+                          ObFrameContext con,
+                          struct _ObClient *client);
 
 gboolean actions_interactive_act_running(void);
 void actions_interactive_cancel_act(void);
index ff6767e29423a14eab5ec46ea102f8e6ee422cd0..10458d577804572c183c49aa166907d9727fcfac 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/screen.h"
 #include <glib.h>
 
@@ -7,16 +8,16 @@ typedef struct {
     gboolean add;
 } Options;
 
-static gpointer setup_func(xmlNodePtr node);
-static gpointer setup_add_func(xmlNodePtr node);
-static gpointer setup_remove_func(xmlNodePtr node);
+static gpointer setup_func(GHashTable *config);
+static gpointer setup_add_func(GHashTable *config);
+static gpointer setup_remove_func(GHashTable *config);
 static void free_func(gpointer o);
 static gboolean run_func(ObActionsData *data, gpointer options);
 /* 3.4-compatibility */
-static gpointer setup_addcurrent_func(xmlNodePtr node);
-static gpointer setup_addlast_func(xmlNodePtr node);
-static gpointer setup_removecurrent_func(xmlNodePtr node);
-static gpointer setup_removelast_func(xmlNodePtr node);
+static gpointer setup_addcurrent_func(GHashTable *config);
+static gpointer setup_addlast_func(GHashTable *config);
+static gpointer setup_removecurrent_func(GHashTable *config);
+static gpointer setup_removelast_func(GHashTable *config);
 
 void action_addremovedesktop_startup(void)
 {
@@ -34,35 +35,35 @@ void action_addremovedesktop_startup(void)
                      free_func, run_func);
 }
 
-static gpointer setup_func(xmlNodePtr node)
+static gpointer setup_func(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
 
-    if ((n = obt_xml_find_node(node, "where"))) {
-        gchar *s = obt_xml_node_string(n);
+    v = g_hash_table_lookup(config, "where");
+    if (v && actions_value_is_string(v)) {
+        const gchar *s = actions_value_string(v);
         if (!g_ascii_strcasecmp(s, "last"))
             o->current = FALSE;
         else if (!g_ascii_strcasecmp(s, "current"))
             o->current = TRUE;
-        g_free(s);
     }
 
     return o;
 }
 
-static gpointer setup_add_func(xmlNodePtr node)
+static gpointer setup_add_func(GHashTable *config)
 {
-    Options *o = setup_func(node);
+    Options *o = setup_func(config);
     o->add = TRUE;
     return o;
 }
 
-static gpointer setup_remove_func(xmlNodePtr node)
+static gpointer setup_remove_func(GHashTable *config)
 {
-    Options *o = setup_func(node);
+    Options *o = setup_func(config);
     o->add = FALSE;
     return o;
 }
@@ -90,30 +91,30 @@ static gboolean run_func(ObActionsData *data, gpointer options)
 }
 
 /* 3.4-compatibility */
-static gpointer setup_addcurrent_func(xmlNodePtr node)
+static gpointer setup_addcurrent_func(GHashTable *config)
 {
-    Options *o = setup_add_func(node);
+    Options *o = setup_add_func(config);
     o->current = TRUE;
     return o;
 }
 
-static gpointer setup_addlast_func(xmlNodePtr node)
+static gpointer setup_addlast_func(GHashTable *config)
 {
-    Options *o = setup_add_func(node);
+    Options *o = setup_add_func(config);
     o->current = FALSE;
     return o;
 }
 
-static gpointer setup_removecurrent_func(xmlNodePtr node)
+static gpointer setup_removecurrent_func(GHashTable *config)
 {
-    Options *o = setup_remove_func(node);
+    Options *o = setup_remove_func(config);
     o->current = TRUE;
     return o;
 }
 
-static gpointer setup_removelast_func(xmlNodePtr node)
+static gpointer setup_removelast_func(GHashTable *config)
 {
-    Options *o = setup_remove_func(node);
+    Options *o = setup_remove_func(config);
     o->current = FALSE;
     return o;
 }
index 332e79ca6c92911949ddb269f113751adb755858..06e3074a94d43f3c22c74df990b019d3b1a431d4 100644 (file)
@@ -37,7 +37,6 @@ void action_all_startup(void)
     action_layer_startup();
     action_movetoedge_startup();
     action_growtoedge_startup();
-    action_if_startup();
     action_focustobottom_startup();
     /* 3.4-compatibility */
     action_shadelowerraise_startup();
index 54d63195de6d24480d6256719f439464a4ca3753..5bc337aad1471ca01c70e136295b662c1e1f3e14 100644 (file)
@@ -38,7 +38,6 @@ void action_dockautohide_startup(void);
 void action_layer_startup(void);
 void action_movetoedge_startup(void);
 void action_growtoedge_startup(void);
-void action_if_startup(void);
 void action_focustobottom_startup(void);
 /* 3.4-compatibility */
 void action_shadelowerraise_startup(void);
index 5f0db27cb5173c0f6e09a9a9e944e428548bb945..5325a60a5222418294d5a880de227a5b3107166e 100644 (file)
@@ -1,4 +1,7 @@
 #include "openbox/actions.h"
+#include "openbox/actions_list.h"
+#include "openbox/actions_parser.h"
+#include "openbox/actions_value.h"
 #include "openbox/stacking.h"
 #include "openbox/window.h"
 #include "openbox/event.h"
@@ -17,7 +20,7 @@ typedef struct {
     gboolean bar;
     gboolean raise;
     ObFocusCyclePopupMode dialog_mode;
-    GSList *actions;
+    ObActionsList *actions;
 
 
     /* options for after we're done */
@@ -25,17 +28,17 @@ typedef struct {
     guint state;     /* keyboard state when finished */
 } Options;
 
-static gpointer setup_func(xmlNodePtr node,
+static gpointer setup_func(GHashTable *config,
                            ObActionsIPreFunc *pre,
                            ObActionsIInputFunc *in,
                            ObActionsICancelFunc *c,
                            ObActionsIPostFunc *post);
-static gpointer setup_forward_func(xmlNodePtr node,
+static gpointer setup_forward_func(GHashTable *config,
                                    ObActionsIPreFunc *pre,
                                    ObActionsIInputFunc *in,
                                    ObActionsICancelFunc *c,
                                    ObActionsIPostFunc *post);
-static gpointer setup_backward_func(xmlNodePtr node,
+static gpointer setup_backward_func(GHashTable *config,
                                     ObActionsIPreFunc *pre,
                                     ObActionsIInputFunc *in,
                                     ObActionsICancelFunc *c,
@@ -57,59 +60,63 @@ void action_cyclewindows_startup(void)
                        run_func);
 }
 
-static gpointer setup_func(xmlNodePtr node,
+static gpointer setup_func(GHashTable *config,
                            ObActionsIPreFunc *pre,
                            ObActionsIInputFunc *input,
                            ObActionsICancelFunc *cancel,
                            ObActionsIPostFunc *post)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
     o->bar = TRUE;
     o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_LIST;
 
-    if ((n = obt_xml_find_node(node, "linear")))
-        o->linear = obt_xml_node_bool(n);
-    if ((n = obt_xml_find_node(node, "dialog"))) {
-        if (obt_xml_node_contains(n, "none"))
+    v = g_hash_table_lookup(config, "linear");
+    if (v && actions_value_is_string(v))
+        o->linear = actions_value_bool(v);
+    v = g_hash_table_lookup(config, "dialog");
+    if (v && actions_value_is_string(v)) {
+        const gchar *s = actions_value_string(v);
+        if (g_strcasecmp(s, "none") == 0)
             o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_NONE;
-        else if (obt_xml_node_contains(n, "no"))
+        else if (g_strcasecmp(s, "no") == 0)
             o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_NONE;
-        else if (obt_xml_node_contains(n, "icons"))
+        else if (g_strcasecmp(s, "icons") == 0)
             o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_ICONS;
     }
-    if ((n = obt_xml_find_node(node, "bar")))
-        o->bar = obt_xml_node_bool(n);
-    if ((n = obt_xml_find_node(node, "raise")))
-        o->raise = obt_xml_node_bool(n);
-    if ((n = obt_xml_find_node(node, "panels")))
-        o->dock_windows = obt_xml_node_bool(n);
-    if ((n = obt_xml_find_node(node, "hilite")))
-        o->only_hilite_windows = obt_xml_node_bool(n);
-    if ((n = obt_xml_find_node(node, "desktop")))
-        o->desktop_windows = obt_xml_node_bool(n);
-    if ((n = obt_xml_find_node(node, "allDesktops")))
-        o->all_desktops = obt_xml_node_bool(n);
-
-    if ((n = obt_xml_find_node(node, "finalactions"))) {
-        xmlNodePtr m;
-
-        m = obt_xml_find_node(n->children, "action");
-        while (m) {
-            ObActionsAct *action = actions_parse(m);
-            if (action) o->actions = g_slist_append(o->actions, action);
-            m = obt_xml_find_node(m->next, "action");
-        }
+    v = g_hash_table_lookup(config, "bar");
+    if (v && actions_value_is_string(v))
+        o->bar = actions_value_bool(v);
+    v = g_hash_table_lookup(config, "raise");
+    if (v && actions_value_is_string(v))
+        o->raise = actions_value_bool(v);
+    v = g_hash_table_lookup(config, "panels");
+    if (v && actions_value_is_string(v))
+        o->dock_windows = actions_value_bool(v);
+    v = g_hash_table_lookup(config, "hilite");
+    if (v && actions_value_is_string(v))
+        o->only_hilite_windows = actions_value_bool(v);
+    v = g_hash_table_lookup(config, "desktop");
+    if (v && actions_value_is_string(v))
+        o->desktop_windows = actions_value_bool(v);
+    v = g_hash_table_lookup(config, "allDesktops");
+    if (v && actions_value_is_string(v))
+        o->all_desktops = actions_value_bool(v);
+
+    v = g_hash_table_lookup(config, "finalactions");
+    if (v && actions_value_is_actions_list(v)) {
+        o->actions = actions_value_actions_list(v);
+        actions_list_ref(o->actions);
     }
     else {
-        o->actions = g_slist_prepend(o->actions,
-                                     actions_parse_string("Focus"));
-        o->actions = g_slist_prepend(o->actions,
-                                     actions_parse_string("Raise"));
-        o->actions = g_slist_prepend(o->actions,
-                                     actions_parse_string("Unshade"));
+        ObActionsParser *p = actions_parser_new();
+        o->actions = actions_parser_read_string(p,
+                                                "focus\n"
+                                                "raise\n"
+                                                "unshade\n");
+        actions_parser_unref(p);
     }
 
     *input = i_input_func;
@@ -118,24 +125,24 @@ static gpointer setup_func(xmlNodePtr node,
     return o;
 }
 
-static gpointer setup_forward_func(xmlNodePtr node,
+static gpointer setup_forward_func(GHashTable *config,
                                    ObActionsIPreFunc *pre,
                                    ObActionsIInputFunc *input,
                                    ObActionsICancelFunc *cancel,
                                    ObActionsIPostFunc *post)
 {
-    Options *o = setup_func(node, pre, input, cancel, post);
+    Options *o = setup_func(config, pre, input, cancel, post);
     o->forward = TRUE;
     return o;
 }
 
-static gpointer setup_backward_func(xmlNodePtr node,
+static gpointer setup_backward_func(GHashTable *config,
                                     ObActionsIPreFunc *pre,
                                     ObActionsIInputFunc *input,
                                     ObActionsICancelFunc *cancel,
                                     ObActionsIPostFunc *post)
 {
-    Options *o = setup_func(node, pre, input, cancel, post);
+    Options *o = setup_func(config, pre, input, cancel, post);
     o->forward = FALSE;
     return o;
 }
@@ -144,11 +151,7 @@ static void free_func(gpointer options)
 {
     Options *o = options;
 
-    while (o->actions) {
-        actions_act_unref(o->actions->data);
-        o->actions = g_slist_delete_link(o->actions, o->actions);
-    }
-
+    actions_list_unref(o->actions);
     g_slice_free(Options, o);
 }
 
index 99446bc471a9e74fdb35ad95e294a9cc43f69102..2ffd4f6e5344de5f7929471f0d062ba8fe8f9f29 100644 (file)
@@ -1,11 +1,12 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include <glib.h>
 
 typedef struct {
     gchar   *str;
 } Options;
 
-static gpointer setup_func(xmlNodePtr node);
+static gpointer setup_func(GHashTable *config);
 static void     free_func(gpointer options);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
@@ -14,15 +15,16 @@ void action_debug_startup(void)
     actions_register("Debug", setup_func, free_func, run_func);
 }
 
-static gpointer setup_func(xmlNodePtr node)
+static gpointer setup_func(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
 
-    if ((n = obt_xml_find_node(node, "string")))
-        o->str = obt_xml_node_string(n);
+    v = g_hash_table_lookup(config, "string");
+    if (v && actions_value_is_string(v))
+        o->str = g_strdup(actions_value_string(v));
     return o;
 }
 
index a3a1f6b9c121b00f6158a5ef42d14a1fb6681d7f..0c08d855cac85764834afb454678f9fcb23d2aef 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/screen.h"
 #include "openbox/client.h"
 #include "openbox/openbox.h"
@@ -29,12 +30,12 @@ typedef struct {
     gboolean interactive;
 } Options;
 
-static gpointer setup_go_func(xmlNodePtr node,
+static gpointer setup_go_func(GHashTable *config,
                               ObActionsIPreFunc *pre,
                               ObActionsIInputFunc *input,
                               ObActionsICancelFunc *cancel,
                               ObActionsIPostFunc *post);
-static gpointer setup_send_func(xmlNodePtr node,
+static gpointer setup_send_func(GHashTable *config,
                                 ObActionsIPreFunc *pre,
                                 ObActionsIInputFunc *input,
                                 ObActionsICancelFunc *cancel,
@@ -50,109 +51,20 @@ static gboolean i_input_func(guint initial_state,
                              gboolean *used);
 static void i_post_func(gpointer options);
 
-/* 3.4-compatibility */
-static gpointer setup_go_last_func(xmlNodePtr node);
-static gpointer setup_send_last_func(xmlNodePtr node);
-static gpointer setup_go_abs_func(xmlNodePtr node);
-static gpointer setup_go_next_func(xmlNodePtr node,
-                                   ObActionsIPreFunc *pre,
-                                   ObActionsIInputFunc *input,
-                                   ObActionsICancelFunc *cancel,
-                                   ObActionsIPostFunc *post);
-static gpointer setup_send_next_func(xmlNodePtr node,
-                                     ObActionsIPreFunc *pre,
-                                     ObActionsIInputFunc *input,
-                                     ObActionsICancelFunc *cancel,
-                                     ObActionsIPostFunc *post);
-static gpointer setup_go_prev_func(xmlNodePtr node,
-                                   ObActionsIPreFunc *pre,
-                                   ObActionsIInputFunc *input,
-                                   ObActionsICancelFunc *cancel,
-                                   ObActionsIPostFunc *post);
-static gpointer setup_send_prev_func(xmlNodePtr node,
-                                     ObActionsIPreFunc *pre,
-                                     ObActionsIInputFunc *input,
-                                     ObActionsICancelFunc *cancel,
-                                     ObActionsIPostFunc *post);
-static gpointer setup_go_left_func(xmlNodePtr node,
-                                   ObActionsIPreFunc *pre,
-                                   ObActionsIInputFunc *input,
-                                   ObActionsICancelFunc *cancel,
-                                   ObActionsIPostFunc *post);
-static gpointer setup_send_left_func(xmlNodePtr node,
-                                     ObActionsIPreFunc *pre,
-                                     ObActionsIInputFunc *input,
-                                     ObActionsICancelFunc *cancel,
-                                     ObActionsIPostFunc *post);
-static gpointer setup_go_right_func(xmlNodePtr node,
-                                    ObActionsIPreFunc *pre,
-                                    ObActionsIInputFunc *input,
-                                    ObActionsICancelFunc *cancel,
-                                    ObActionsIPostFunc *post);
-static gpointer setup_send_right_func(xmlNodePtr node,
-                                      ObActionsIPreFunc *pre,
-                                      ObActionsIInputFunc *input,
-                                      ObActionsICancelFunc *cancel,
-                                      ObActionsIPostFunc *post);
-static gpointer setup_go_up_func(xmlNodePtr node,
-                                 ObActionsIPreFunc *pre,
-                                 ObActionsIInputFunc *input,
-                                 ObActionsICancelFunc *cancel,
-                                 ObActionsIPostFunc *post);
-static gpointer setup_send_up_func(xmlNodePtr node,
-                                   ObActionsIPreFunc *pre,
-                                   ObActionsIInputFunc *input,
-                                   ObActionsICancelFunc *cancel,
-                                   ObActionsIPostFunc *post);
-static gpointer setup_go_down_func(xmlNodePtr node,
-                                   ObActionsIPreFunc *pre,
-                                   ObActionsIInputFunc *input,
-                                   ObActionsICancelFunc *cancel,
-                                   ObActionsIPostFunc *post);
-static gpointer setup_send_down_func(xmlNodePtr node,
-                                     ObActionsIPreFunc *pre,
-                                     ObActionsIInputFunc *input,
-                                     ObActionsICancelFunc *cancel,
-                                     ObActionsIPostFunc *post);
 
 void action_desktop_startup(void)
 {
     actions_register_i("GoToDesktop", setup_go_func, free_func, run_func);
     actions_register_i("SendToDesktop", setup_send_func, free_func, run_func);
-    /* 3.4-compatibility */
-    actions_register("DesktopLast", setup_go_last_func, free_func, run_func);
-    actions_register("SendToDesktopLast", setup_send_last_func,
-                     free_func, run_func);
-    actions_register("Desktop", setup_go_abs_func, free_func, run_func);
-    actions_register_i("DesktopNext", setup_go_next_func, free_func, run_func);
-    actions_register_i("SendToDesktopNext", setup_send_next_func,
-                       free_func, run_func);
-    actions_register_i("DesktopPrevious", setup_go_prev_func,
-                       free_func, run_func);
-    actions_register_i("SendToDesktopPrevious", setup_send_prev_func,
-                       free_func, run_func);
-    actions_register_i("DesktopLeft", setup_go_left_func, free_func, run_func);
-    actions_register_i("SendToDesktopLeft", setup_send_left_func,
-                       free_func, run_func);
-    actions_register_i("DesktopRight", setup_go_right_func,
-                       free_func, run_func);
-    actions_register_i("SendToDesktopRight", setup_send_right_func,
-                       free_func, run_func);
-    actions_register_i("DesktopUp", setup_go_up_func, free_func, run_func);
-    actions_register_i("SendToDesktopUp", setup_send_up_func,
-                       free_func, run_func);
-    actions_register_i("DesktopDown", setup_go_down_func, free_func, run_func);
-    actions_register_i("SendToDesktopDown", setup_send_down_func,
-                       free_func, run_func);
 }
 
-static gpointer setup_func(xmlNodePtr node,
+static gpointer setup_func(GHashTable *config,
                            ObActionsIPreFunc *pre,
                            ObActionsIInputFunc *input,
                            ObActionsICancelFunc *cancel,
                            ObActionsIPostFunc *post)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
@@ -162,8 +74,9 @@ static gpointer setup_func(xmlNodePtr node,
     /* wrap by default - it's handy! */
     o->u.rel.wrap = TRUE;
 
-    if ((n = obt_xml_find_node(node, "to"))) {
-        gchar *s = obt_xml_node_string(n);
+    v = g_hash_table_lookup(config, "to");
+    if (v && actions_value_is_string(v)) {
+        const gchar *s = actions_value_string(v);
         if (!g_ascii_strcasecmp(s, "last"))
             o->type = LAST;
         else if (!g_ascii_strcasecmp(s, "current"))
@@ -202,17 +115,17 @@ static gpointer setup_func(xmlNodePtr node,
             o->type = ABSOLUTE;
             o->u.abs.desktop = atoi(s) - 1;
         }
-        g_free(s);
     }
 
-    if ((n = obt_xml_find_node(node, "wrap")))
-        o->u.rel.wrap = obt_xml_node_bool(n);
+    v = g_hash_table_lookup(config, "wrap");
+    if (v && actions_value_is_string(v))
+        o->u.rel.wrap = actions_value_bool(v);
 
     return o;
 }
 
 
-static gpointer setup_go_func(xmlNodePtr node,
+static gpointer setup_go_func(GHashTable *config,
                               ObActionsIPreFunc *pre,
                               ObActionsIInputFunc *input,
                               ObActionsICancelFunc *cancel,
@@ -220,7 +133,7 @@ static gpointer setup_go_func(xmlNodePtr node,
 {
     Options *o;
 
-    o = setup_func(node, pre, input, cancel, post);
+    o = setup_func(config, pre, input, cancel, post);
     if (o->type == RELATIVE) {
         o->interactive = TRUE;
         *pre = i_pre_func;
@@ -231,26 +144,22 @@ static gpointer setup_go_func(xmlNodePtr node,
     return o;
 }
 
-static gpointer setup_send_func(xmlNodePtr node,
+static gpointer setup_send_func(GHashTable *config,
                                 ObActionsIPreFunc *pre,
                                 ObActionsIInputFunc *input,
                                 ObActionsICancelFunc *cancel,
                                 ObActionsIPostFunc *post)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
-    o = setup_func(node, pre, input, cancel, post);
-    if ((n = obt_xml_find_node(node, "desktop"))) {
-        /* 3.4 compatibility */
-        o->u.abs.desktop = obt_xml_node_int(n) - 1;
-        o->type = ABSOLUTE;
-    }
+    o = setup_func(config, pre, input, cancel, post);
     o->send = TRUE;
     o->follow = TRUE;
 
-    if ((n = obt_xml_find_node(node, "follow")))
-        o->follow = obt_xml_node_bool(n);
+    v = g_hash_table_lookup(config, "follow");
+    if (v && actions_value_is_string(v))
+        o->follow = actions_value_bool(v);
 
     if (o->type == RELATIVE && o->follow) {
         o->interactive = TRUE;
@@ -365,203 +274,3 @@ static void i_post_func(gpointer options)
 {
     screen_hide_desktop_popup();
 }
-
-/* 3.4-compatilibity */
-static gpointer setup_follow(xmlNodePtr node)
-{
-    xmlNodePtr n;
-    Options *o = g_slice_new0(Options);
-    o->send = TRUE;
-    o->follow = TRUE;
-    if ((n = obt_xml_find_node(node, "follow")))
-        o->follow = obt_xml_node_bool(n);
-    return o;
-}
-
-static gpointer setup_go_last_func(xmlNodePtr node)
-{
-    Options *o = g_slice_new0(Options);
-    o->type = LAST;
-    return o;
-}
-
-static gpointer setup_send_last_func(xmlNodePtr node)
-{
-    Options *o = setup_follow(node);
-    o->type = LAST;
-    return o;
-}
-
-static gpointer setup_go_abs_func(xmlNodePtr node)
-{
-    xmlNodePtr n;
-    Options *o = g_slice_new0(Options);
-    o->type = ABSOLUTE;
-    if ((n = obt_xml_find_node(node, "desktop")))
-        o->u.abs.desktop = obt_xml_node_int(n) - 1;
-    else
-        o->u.abs.desktop = screen_desktop;
-    return o;
-}
-
-static void setup_rel(Options *o, xmlNodePtr node, gboolean lin,
-                      ObDirection dir,
-                      ObActionsIPreFunc *pre,
-                      ObActionsIInputFunc *input,
-                      ObActionsIPostFunc *post)
-{
-    xmlNodePtr n;
-
-    o->type = RELATIVE;
-    o->u.rel.linear = lin;
-    o->u.rel.dir = dir;
-    o->u.rel.wrap = TRUE;
-
-    if ((n = obt_xml_find_node(node, "wrap")))
-        o->u.rel.wrap = obt_xml_node_bool(n);
-
-    if (input) {
-        o->interactive = TRUE;
-        *pre = i_pre_func;
-        *input = i_input_func;
-        *post = i_post_func;
-    }
-}
-
-static gpointer setup_go_next_func(xmlNodePtr node,
-                                   ObActionsIPreFunc *pre,
-                                   ObActionsIInputFunc *input,
-                                   ObActionsICancelFunc *cancel,
-                                   ObActionsIPostFunc *post)
-{
-    Options *o = g_slice_new0(Options);
-    setup_rel(o, node, TRUE, OB_DIRECTION_EAST, pre, input, post);
-    return o;
-}
-
-static gpointer setup_send_next_func(xmlNodePtr node,
-                                     ObActionsIPreFunc *pre,
-                                     ObActionsIInputFunc *input,
-                                     ObActionsICancelFunc *cancel,
-                                     ObActionsIPostFunc *post)
-{
-    Options *o = setup_follow(node);
-    setup_rel(o, node, TRUE, OB_DIRECTION_EAST,
-              pre, (o->follow ? input : NULL), post);
-    return o;
-}
-
-static gpointer setup_go_prev_func(xmlNodePtr node,
-                                   ObActionsIPreFunc *pre,
-                                   ObActionsIInputFunc *input,
-                                   ObActionsICancelFunc *cancel,
-                                   ObActionsIPostFunc *post)
-{
-    Options *o = g_slice_new0(Options);
-    setup_rel(o, node, TRUE, OB_DIRECTION_WEST, pre, input, post);
-    return o;
-}
-
-static gpointer setup_send_prev_func(xmlNodePtr node,
-                                     ObActionsIPreFunc *pre,
-                                     ObActionsIInputFunc *input,
-                                     ObActionsICancelFunc *cancel,
-                                     ObActionsIPostFunc *post)
-{
-    Options *o = setup_follow(node);
-    setup_rel(o, node, TRUE, OB_DIRECTION_WEST,
-              pre, (o->follow ? input : NULL), post);
-    return o;
-}
-
-static gpointer setup_go_left_func(xmlNodePtr node,
-                                   ObActionsIPreFunc *pre,
-                                   ObActionsIInputFunc *input,
-                                   ObActionsICancelFunc *cancel,
-                                   ObActionsIPostFunc *post)
-{
-    Options *o = g_slice_new0(Options);
-    setup_rel(o, node, FALSE, OB_DIRECTION_WEST, pre, input, post);
-    return o;
-}
-
-static gpointer setup_send_left_func(xmlNodePtr node,
-                                     ObActionsIPreFunc *pre,
-                                     ObActionsIInputFunc *input,
-                                     ObActionsICancelFunc *cancel,
-                                     ObActionsIPostFunc *post)
-{
-    Options *o = setup_follow(node);
-    setup_rel(o, node, FALSE, OB_DIRECTION_WEST,
-              pre, (o->follow ? input : NULL), post);
-    return o;
-}
-
-static gpointer setup_go_right_func(xmlNodePtr node,
-                                    ObActionsIPreFunc *pre,
-                                    ObActionsIInputFunc *input,
-                                    ObActionsICancelFunc *cancel,
-                                    ObActionsIPostFunc *post)
-{
-    Options *o = g_slice_new0(Options);
-    setup_rel(o, node, FALSE, OB_DIRECTION_EAST, pre, input, post);
-    return o;
-}
-
-static gpointer setup_send_right_func(xmlNodePtr node,
-                                      ObActionsIPreFunc *pre,
-                                      ObActionsIInputFunc *input,
-                                      ObActionsICancelFunc *cancel,
-                                      ObActionsIPostFunc *post)
-{
-    Options *o = setup_follow(node);
-    setup_rel(o, node, FALSE, OB_DIRECTION_EAST,
-              pre, (o->follow ? input : NULL), post);
-    return o;
-}
-
-static gpointer setup_go_up_func(xmlNodePtr node,
-                                 ObActionsIPreFunc *pre,
-                                 ObActionsIInputFunc *input,
-                                 ObActionsICancelFunc *cancel,
-                                 ObActionsIPostFunc *post)
-{
-    Options *o = g_slice_new0(Options);
-    setup_rel(o, node, FALSE, OB_DIRECTION_NORTH, pre, input, post);
-    return o;
-}
-
-static gpointer setup_send_up_func(xmlNodePtr node,
-                                   ObActionsIPreFunc *pre,
-                                   ObActionsIInputFunc *input,
-                                   ObActionsICancelFunc *cancel,
-                                   ObActionsIPostFunc *post)
-{
-    Options *o = setup_follow(node);
-    setup_rel(o, node, FALSE, OB_DIRECTION_NORTH,
-              pre, (o->follow ? input : NULL), post);
-    return o;
-}
-
-static gpointer setup_go_down_func(xmlNodePtr node,
-                                   ObActionsIPreFunc *pre,
-                                   ObActionsIInputFunc *input,
-                                   ObActionsICancelFunc *cancel,
-                                   ObActionsIPostFunc *post)
-{
-    Options *o = g_slice_new0(Options);
-    setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH, pre, input, post);
-    return o;
-}
-
-static gpointer setup_send_down_func(xmlNodePtr node,
-                                     ObActionsIPreFunc *pre,
-                                     ObActionsIInputFunc *input,
-                                     ObActionsICancelFunc *cancel,
-                                     ObActionsIPostFunc *post)
-{
-    Options *o = setup_follow(node);
-    setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH,
-              pre, (o->follow ? input : NULL), post);
-    return o;
-}
index 602e7edc33fb1dc26b67fc5fe28fc8335b5d64cc..46ac6fd7d1b22e9109eed569cdaec0b5d212a4a5 100644 (file)
@@ -1,4 +1,7 @@
 #include "openbox/actions.h"
+#include "openbox/actions_list.h"
+#include "openbox/actions_parser.h"
+#include "openbox/actions_value.h"
 #include "openbox/event.h"
 #include "openbox/stacking.h"
 #include "openbox/window.h"
@@ -16,18 +19,18 @@ typedef struct {
     ObDirection direction;
     gboolean bar;
     gboolean raise;
-    GSList *actions;
+    ObActionsList *actions;
 } Options;
 
 static gboolean cycling = FALSE;
 
-static gpointer setup_func(xmlNodePtr node);
-static gpointer setup_cycle_func(xmlNodePtr node,
+static gpointer setup_func(GHashTable *config);
+static gpointer setup_cycle_func(GHashTable *config,
                                  ObActionsIPreFunc *pre,
                                  ObActionsIInputFunc *input,
                                  ObActionsICancelFunc *cancel,
                                  ObActionsIPostFunc *post);
-static gpointer setup_target_func(xmlNodePtr node);
+static gpointer setup_target_func(GHashTable *config);
 static void     free_func(gpointer options);
 static gboolean run_func(ObActionsData *data, gpointer options);
 static gboolean i_input_func(guint initial_state,
@@ -40,54 +43,54 @@ static void     i_cancel_func(gpointer options);
 static void     end_cycle(gboolean cancel, guint state, Options *o);
 
 /* 3.4-compatibility */
-static gpointer setup_north_cycle_func(xmlNodePtr node,
+static gpointer setup_north_cycle_func(GHashTable *config,
                                        ObActionsIPreFunc *pre,
                                        ObActionsIInputFunc *in,
                                        ObActionsICancelFunc *c,
                                        ObActionsIPostFunc *post);
-static gpointer setup_south_cycle_func(xmlNodePtr node,
+static gpointer setup_south_cycle_func(GHashTable *config,
                                        ObActionsIPreFunc *pre,
                                        ObActionsIInputFunc *in,
                                        ObActionsICancelFunc *c,
                                        ObActionsIPostFunc *post);
-static gpointer setup_east_cycle_func(xmlNodePtr node,
+static gpointer setup_east_cycle_func(GHashTable *config,
                                       ObActionsIPreFunc *pre,
                                       ObActionsIInputFunc *in,
                                       ObActionsICancelFunc *c,
                                       ObActionsIPostFunc *post);
-static gpointer setup_west_cycle_func(xmlNodePtr node,
+static gpointer setup_west_cycle_func(GHashTable *config,
                                       ObActionsIPreFunc *pre,
                                       ObActionsIInputFunc *in,
                                       ObActionsICancelFunc *c,
                                       ObActionsIPostFunc *post);
-static gpointer setup_northwest_cycle_func(xmlNodePtr node,
+static gpointer setup_northwest_cycle_func(GHashTable *config,
                                            ObActionsIPreFunc *pre,
                                            ObActionsIInputFunc *in,
                                            ObActionsICancelFunc *c,
                                            ObActionsIPostFunc *post);
-static gpointer setup_northeast_cycle_func(xmlNodePtr node,
+static gpointer setup_northeast_cycle_func(GHashTable *config,
                                            ObActionsIPreFunc *pre,
                                            ObActionsIInputFunc *in,
                                            ObActionsICancelFunc *c,
                                            ObActionsIPostFunc *post);
-static gpointer setup_southwest_cycle_func(xmlNodePtr node,
+static gpointer setup_southwest_cycle_func(GHashTable *config,
                                            ObActionsIPreFunc *pre,
                                            ObActionsIInputFunc *in,
                                            ObActionsICancelFunc *c,
                                            ObActionsIPostFunc *post);
-static gpointer setup_southeast_cycle_func(xmlNodePtr node,
+static gpointer setup_southeast_cycle_func(GHashTable *config,
                                            ObActionsIPreFunc *pre,
                                            ObActionsIInputFunc *in,
                                            ObActionsICancelFunc *c,
                                            ObActionsIPostFunc *post);
-static gpointer setup_north_target_func(xmlNodePtr node);
-static gpointer setup_south_target_func(xmlNodePtr node);
-static gpointer setup_east_target_func(xmlNodePtr node);
-static gpointer setup_west_target_func(xmlNodePtr node);
-static gpointer setup_northwest_target_func(xmlNodePtr node);
-static gpointer setup_northeast_target_func(xmlNodePtr node);
-static gpointer setup_southwest_target_func(xmlNodePtr node);
-static gpointer setup_southeast_target_func(xmlNodePtr node);
+static gpointer setup_north_target_func(GHashTable *config);
+static gpointer setup_south_target_func(GHashTable *config);
+static gpointer setup_east_target_func(GHashTable *config);
+static gpointer setup_west_target_func(GHashTable *config);
+static gpointer setup_northwest_target_func(GHashTable *config);
+static gpointer setup_northeast_target_func(GHashTable *config);
+static gpointer setup_southwest_target_func(GHashTable *config);
+static gpointer setup_southeast_target_func(GHashTable *config);
 
 void action_directionalwindows_startup(void)
 {
@@ -130,27 +133,33 @@ void action_directionalwindows_startup(void)
                      free_func, run_func);
 }
 
-static gpointer setup_func(xmlNodePtr node)
+static gpointer setup_func(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
     o->dialog = TRUE;
     o->bar = TRUE;
 
-    if ((n = obt_xml_find_node(node, "dialog")))
-        o->dialog = obt_xml_node_bool(n);
-    if ((n = obt_xml_find_node(node, "bar")))
-        o->bar = obt_xml_node_bool(n);
-    if ((n = obt_xml_find_node(node, "raise")))
-        o->raise = obt_xml_node_bool(n);
-    if ((n = obt_xml_find_node(node, "panels")))
-        o->dock_windows = obt_xml_node_bool(n);
-    if ((n = obt_xml_find_node(node, "desktop")))
-        o->desktop_windows = obt_xml_node_bool(n);
-    if ((n = obt_xml_find_node(node, "direction"))) {
-        gchar *s = obt_xml_node_string(n);
+    v = g_hash_table_lookup(config, "dialog");
+    if (v && actions_value_is_string(v))
+        o->dialog = actions_value_bool(v);
+    v = g_hash_table_lookup(config, "bar");
+    if (v && actions_value_is_string(v))
+        o->bar = actions_value_bool(v);
+    v = g_hash_table_lookup(config, "raise");
+    if (v && actions_value_is_string(v))
+        o->raise = actions_value_bool(v);
+    v = g_hash_table_lookup(config, "panels");
+    if (v && actions_value_is_string(v))
+        o->dock_windows = actions_value_bool(v);
+    v = g_hash_table_lookup(config, "desktop");
+    if (v && actions_value_is_string(v))
+        o->desktop_windows = actions_value_bool(v);
+    v = g_hash_table_lookup(config, "direction");
+    if (v && actions_value_is_string(v)) {
+        const gchar *s = actions_value_string(v);
         if (!g_ascii_strcasecmp(s, "north") ||
             !g_ascii_strcasecmp(s, "up"))
             o->direction = OB_DIRECTION_NORTH;
@@ -171,47 +180,41 @@ static gpointer setup_func(xmlNodePtr node)
             o->direction = OB_DIRECTION_SOUTHWEST;
         else if (!g_ascii_strcasecmp(s, "southeast"))
             o->direction = OB_DIRECTION_SOUTHEAST;
-        g_free(s);
     }
 
-    if ((n = obt_xml_find_node(node, "finalactions"))) {
-        xmlNodePtr m;
-
-        m = obt_xml_find_node(n->children, "action");
-        while (m) {
-            ObActionsAct *action = actions_parse(m);
-            if (action) o->actions = g_slist_append(o->actions, action);
-            m = obt_xml_find_node(m->next, "action");
-        }
+    v = g_hash_table_lookup(config, "finalactions");
+    if (v && actions_value_is_actions_list(v)) {
+        o->actions = actions_value_actions_list(v);
+        actions_list_ref(o->actions);
     }
     else {
-        o->actions = g_slist_prepend(o->actions,
-                                     actions_parse_string("Focus"));
-        o->actions = g_slist_prepend(o->actions,
-                                     actions_parse_string("Raise"));
-        o->actions = g_slist_prepend(o->actions,
-                                     actions_parse_string("Unshade"));
+        ObActionsParser *p = actions_parser_new();
+        o->actions = actions_parser_read_string(p,
+                                                "focus\n"
+                                                "raise\n"
+                                                "unshade\n");
+        actions_parser_unref(p);
     }
 
     return o;
 }
 
-static gpointer setup_cycle_func(xmlNodePtr node,
+static gpointer setup_cycle_func(GHashTable *config,
                                  ObActionsIPreFunc *pre,
                                  ObActionsIInputFunc *input,
                                  ObActionsICancelFunc *cancel,
                                  ObActionsIPostFunc *post)
 {
-    Options *o = setup_func(node);
+    Options *o = setup_func(config);
     o->interactive = TRUE;
     *input = i_input_func;
     *cancel = i_cancel_func;
     return o;
 }
 
-static gpointer setup_target_func(xmlNodePtr node)
+static gpointer setup_target_func(GHashTable *config)
 {
-    Options *o = setup_func(node);
+    Options *o = setup_func(config);
     o->interactive = FALSE;
     return o;
 }
@@ -220,11 +223,7 @@ static void free_func(gpointer options)
 {
     Options *o = options;
 
-    while (o->actions) {
-        actions_act_unref(o->actions->data);
-        o->actions = g_slist_delete_link(o->actions, o->actions);
-    }
-
+    actions_list_unref(o->actions);
     g_slice_free(Options, o);
 }
 
@@ -322,146 +321,146 @@ static void end_cycle(gboolean cancel, guint state, Options *o)
 }
 
 /* 3.4-compatibility */
-static gpointer setup_north_cycle_func(xmlNodePtr node,
+static gpointer setup_north_cycle_func(GHashTable *config,
                                        ObActionsIPreFunc *pre,
                                        ObActionsIInputFunc *input,
                                        ObActionsICancelFunc *cancel,
                                        ObActionsIPostFunc *post)
 {
-    Options *o = setup_cycle_func(node, pre, input, cancel, post);
+    Options *o = setup_cycle_func(config, pre, input, cancel, post);
     o->direction = OB_DIRECTION_NORTH;
     return o;
 }
 
-static gpointer setup_south_cycle_func(xmlNodePtr node,
+static gpointer setup_south_cycle_func(GHashTable *config,
                                        ObActionsIPreFunc *pre,
                                        ObActionsIInputFunc *input,
                                        ObActionsICancelFunc *cancel,
                                        ObActionsIPostFunc *post)
 {
-    Options *o = setup_cycle_func(node, pre, input, cancel, post);
+    Options *o = setup_cycle_func(config, pre, input, cancel, post);
     o->direction = OB_DIRECTION_SOUTH;
     return o;
 }
 
-static gpointer setup_east_cycle_func(xmlNodePtr node,
+static gpointer setup_east_cycle_func(GHashTable *config,
                                       ObActionsIPreFunc *pre,
                                       ObActionsIInputFunc *input,
                                       ObActionsICancelFunc *cancel,
                                       ObActionsIPostFunc *post)
 {
-    Options *o = setup_cycle_func(node, pre, input, cancel, post);
+    Options *o = setup_cycle_func(config, pre, input, cancel, post);
     o->direction = OB_DIRECTION_EAST;
     return o;
 }
 
-static gpointer setup_west_cycle_func(xmlNodePtr node,
+static gpointer setup_west_cycle_func(GHashTable *config,
                                       ObActionsIPreFunc *pre,
                                       ObActionsIInputFunc *input,
                                       ObActionsICancelFunc *cancel,
                                       ObActionsIPostFunc *post)
 {
-    Options *o = setup_cycle_func(node, pre, input, cancel, post);
+    Options *o = setup_cycle_func(config, pre, input, cancel, post);
     o->direction = OB_DIRECTION_WEST;
     return o;
 }
 
-static gpointer setup_northwest_cycle_func(xmlNodePtr node,
+static gpointer setup_northwest_cycle_func(GHashTable *config,
                                            ObActionsIPreFunc *pre,
                                            ObActionsIInputFunc *input,
                                            ObActionsICancelFunc *cancel,
                                            ObActionsIPostFunc *post)
 {
-    Options *o = setup_cycle_func(node, pre, input, cancel, post);
+    Options *o = setup_cycle_func(config, pre, input, cancel, post);
     o->direction = OB_DIRECTION_NORTHWEST;
     return o;
 }
 
-static gpointer setup_northeast_cycle_func(xmlNodePtr node,
+static gpointer setup_northeast_cycle_func(GHashTable *config,
                                            ObActionsIPreFunc *pre,
                                            ObActionsIInputFunc *input,
                                            ObActionsICancelFunc *cancel,
                                            ObActionsIPostFunc *post)
 {
-    Options *o = setup_cycle_func(node, pre, input, cancel, post);
+    Options *o = setup_cycle_func(config, pre, input, cancel, post);
     o->direction = OB_DIRECTION_EAST;
     return o;
 }
 
-static gpointer setup_southwest_cycle_func(xmlNodePtr node,
+static gpointer setup_southwest_cycle_func(GHashTable *config,
                                            ObActionsIPreFunc *pre,
                                            ObActionsIInputFunc *input,
                                            ObActionsICancelFunc *cancel,
                                            ObActionsIPostFunc *post)
 {
-    Options *o = setup_cycle_func(node, pre, input, cancel, post);
+    Options *o = setup_cycle_func(config, pre, input, cancel, post);
     o->direction = OB_DIRECTION_SOUTHWEST;
     return o;
 }
 
-static gpointer setup_southeast_cycle_func(xmlNodePtr node,
+static gpointer setup_southeast_cycle_func(GHashTable *config,
                                            ObActionsIPreFunc *pre,
                                            ObActionsIInputFunc *input,
                                            ObActionsICancelFunc *cancel,
                                            ObActionsIPostFunc *post)
 {
-    Options *o = setup_cycle_func(node, pre, input, cancel, post);
+    Options *o = setup_cycle_func(config, pre, input, cancel, post);
     o->direction = OB_DIRECTION_SOUTHEAST;
     return o;
 }
 
-static gpointer setup_north_target_func(xmlNodePtr node)
+static gpointer setup_north_target_func(GHashTable *config)
 {
-    Options *o = setup_target_func(node);
+    Options *o = setup_target_func(config);
     o->direction = OB_DIRECTION_NORTH;
     return o;
 }
 
-static gpointer setup_south_target_func(xmlNodePtr node)
+static gpointer setup_south_target_func(GHashTable *config)
 {
-    Options *o = setup_target_func(node);
+    Options *o = setup_target_func(config);
     o->direction = OB_DIRECTION_SOUTH;
     return o;
 }
 
-static gpointer setup_east_target_func(xmlNodePtr node)
+static gpointer setup_east_target_func(GHashTable *config)
 {
-    Options *o = setup_target_func(node);
+    Options *o = setup_target_func(config);
     o->direction = OB_DIRECTION_EAST;
     return o;
 }
 
-static gpointer setup_west_target_func(xmlNodePtr node)
+static gpointer setup_west_target_func(GHashTable *config)
 {
-    Options *o = setup_target_func(node);
+    Options *o = setup_target_func(config);
     o->direction = OB_DIRECTION_WEST;
     return o;
 }
 
-static gpointer setup_northwest_target_func(xmlNodePtr node)
+static gpointer setup_northwest_target_func(GHashTable *config)
 {
-    Options *o = setup_target_func(node);
+    Options *o = setup_target_func(config);
     o->direction = OB_DIRECTION_NORTHWEST;
     return o;
 }
 
-static gpointer setup_northeast_target_func(xmlNodePtr node)
+static gpointer setup_northeast_target_func(GHashTable *config)
 {
-    Options *o = setup_target_func(node);
+    Options *o = setup_target_func(config);
     o->direction = OB_DIRECTION_NORTHEAST;
     return o;
 }
 
-static gpointer setup_southwest_target_func(xmlNodePtr node)
+static gpointer setup_southwest_target_func(GHashTable *config)
 {
-    Options *o = setup_target_func(node);
+    Options *o = setup_target_func(config);
     o->direction = OB_DIRECTION_SOUTHWEST;
     return o;
 }
 
-static gpointer setup_southeast_target_func(xmlNodePtr node)
+static gpointer setup_southeast_target_func(GHashTable *config)
 {
-    Options *o = setup_target_func(node);
+    Options *o = setup_target_func(config);
     o->direction = OB_DIRECTION_SOUTHEAST;
     return o;
 }
index 380ffa008996936d4484d3d6bb15914cf861417c..c995829aa912f93d7fb34912b130bd0b76c626a1 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/event.h"
 #include "openbox/startupnotify.h"
 #include "openbox/client.h"
@@ -21,7 +22,7 @@ typedef struct {
     ObActionsData *data;
 } Options;
 
-static gpointer setup_func(xmlNodePtr node);
+static gpointer setup_func(GHashTable *config);
 static void     free_func(gpointer options);
 static gboolean run_func(ObActionsData *data, gpointer options);
 static void shutdown_func(void);
@@ -48,34 +49,33 @@ static void client_dest(ObClient *client, gpointer data)
     }
 }
 
-static gpointer setup_func(xmlNodePtr node)
+static gpointer setup_func(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
 
-    if ((n = obt_xml_find_node(node, "command")) ||
-        (n = obt_xml_find_node(node, "execute")))
-    {
-        gchar *s = obt_xml_node_string(n);
-        o->cmd = obt_paths_expand_tilde(s);
-        g_free(s);
-    }
-
-    if ((n = obt_xml_find_node(node, "prompt")))
-        o->prompt = obt_xml_node_string(n);
-
-    if ((n = obt_xml_find_node(node, "startupnotify"))) {
-        xmlNodePtr m;
-        if ((m = obt_xml_find_node(n->children, "enabled")))
-            o->sn = obt_xml_node_bool(m);
-        if ((m = obt_xml_find_node(n->children, "name")))
-            o->sn_name = obt_xml_node_string(m);
-        if ((m = obt_xml_find_node(n->children, "icon")))
-            o->sn_icon = obt_xml_node_string(m);
-        if ((m = obt_xml_find_node(n->children, "wmclass")))
-            o->sn_wmclass = obt_xml_node_string(m);
+    v = g_hash_table_lookup(config, "command");
+    if (v && actions_value_is_string(v))
+        o->cmd = obt_paths_expand_tilde(actions_value_string(v));
+
+    v = g_hash_table_lookup(config, "prompt");
+    if (v && actions_value_is_string(v))
+        o->prompt = g_strdup(actions_value_string(v));
+
+    v = g_hash_table_lookup(config, "startupnotify");
+    if (v && actions_value_is_string(v) && actions_value_bool(v)) {
+        o->sn = TRUE;
+        v = g_hash_table_lookup(config, "name");
+        if (v && actions_value_is_string(v))
+            o->sn_name = g_strdup(actions_value_string(v));
+        v = g_hash_table_lookup(config, "icon");
+        if (v && actions_value_is_string(v))
+            o->sn_icon = g_strdup(actions_value_string(v));
+        v = g_hash_table_lookup(config, "wmclass");
+        if (v && actions_value_is_string(v))
+            o->sn_wmclass = g_strdup(actions_value_string(v));
     }
     return o;
 }
index 2d9fc63312dc9c73b196474db71fb0f79bd99f83..f27850145b39f2462f1899a50749d6bd12ccf37e 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/openbox.h"
 #include "openbox/prompt.h"
 #include "openbox/session.h"
@@ -8,7 +9,7 @@ typedef struct {
     gboolean prompt;
 } Options;
 
-static gpointer setup_func(xmlNodePtr node);
+static gpointer setup_func(GHashTable *config);
 static void free_func(gpointer o);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
@@ -18,16 +19,17 @@ void action_exit_startup(void)
     actions_register("SessionLogout", setup_func, free_func, run_func);
 }
 
-static gpointer setup_func(xmlNodePtr node)
+static gpointer setup_func(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
     o->prompt = TRUE;
 
-    if ((n = obt_xml_find_node(node, "prompt")))
-        o->prompt = obt_xml_node_bool(n);
+    v = g_hash_table_lookup(config, "prompt");
+    if (v && actions_value_is_string(v))
+        o->prompt = actions_value_bool(v);
 
     return o;
 }
index 6c8957c81eca6370814f35a86abe42834b280d1e..e5e5cc537b0c1b9d7d82bf9f13f7a9ae2deb7851 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/event.h"
 #include "openbox/client.h"
 #include "openbox/focus.h"
@@ -9,7 +10,7 @@ typedef struct {
     gboolean stop_int;
 } Options;
 
-static gpointer setup_func(xmlNodePtr node);
+static gpointer setup_func(GHashTable *config);
 static void free_func(gpointer o);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
@@ -18,18 +19,20 @@ void action_focus_startup(void)
     actions_register("Focus", setup_func, free_func, run_func);
 }
 
-static gpointer setup_func(xmlNodePtr node)
+static gpointer setup_func(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
     o->stop_int = TRUE;
 
-    if ((n = obt_xml_find_node(node, "here")))
-        o->here = obt_xml_node_bool(n);
-    if ((n = obt_xml_find_node(node, "stopInteractive")))
-        o->stop_int = obt_xml_node_bool(n);
+    v = g_hash_table_lookup(config, "here");
+    if (v && actions_value_is_string(v))
+        o->here = actions_value_bool(v);
+    v = g_hash_table_lookup(config, "stopInteractive");
+    if (v && actions_value_is_string(v))
+        o->stop_int = actions_value_bool(v);
     return o;
 }
 
index d5a7bfdd9e8a30c476dcf2203c45aa8f189e3dc3..d7618321987e793e9fb982ed4de0739988ce0c36 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/misc.h"
 #include "openbox/client.h"
 #include "openbox/frame.h"
@@ -10,15 +11,15 @@ typedef struct {
     gboolean shrink;
 } Options;
 
-static gpointer setup_func(xmlNodePtr node);
-static gpointer setup_shrink_func(xmlNodePtr node);
+static gpointer setup_func(GHashTable *config);
+static gpointer setup_shrink_func(GHashTable *config);
 static void free_func(gpointer o);
 static gboolean run_func(ObActionsData *data, gpointer options);
 /* 3.4-compatibility */
-static gpointer setup_north_func(xmlNodePtr node);
-static gpointer setup_south_func(xmlNodePtr node);
-static gpointer setup_east_func(xmlNodePtr node);
-static gpointer setup_west_func(xmlNodePtr node);
+static gpointer setup_north_func(GHashTable *config);
+static gpointer setup_south_func(GHashTable *config);
+static gpointer setup_east_func(GHashTable *config);
+static gpointer setup_west_func(GHashTable *config);
 
 void action_growtoedge_startup(void)
 {
@@ -33,17 +34,18 @@ void action_growtoedge_startup(void)
     actions_register("GrowToEdgeWest", setup_west_func, free_func, run_func);
 }
 
-static gpointer setup_func(xmlNodePtr node)
+static gpointer setup_func(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
     o->dir = OB_DIRECTION_NORTH;
     o->shrink = FALSE;
 
-    if ((n = obt_xml_find_node(node, "direction"))) {
-        gchar *s = obt_xml_node_string(n);
+    v = g_hash_table_lookup(config, "direction");
+    if (v && actions_value_is_string(v)) {
+        const gchar *s = actions_value_string(v);
         if (!g_ascii_strcasecmp(s, "north") ||
             !g_ascii_strcasecmp(s, "up"))
             o->dir = OB_DIRECTION_NORTH;
@@ -56,17 +58,16 @@ static gpointer setup_func(xmlNodePtr node)
         else if (!g_ascii_strcasecmp(s, "east") ||
                  !g_ascii_strcasecmp(s, "right"))
             o->dir = OB_DIRECTION_EAST;
-        g_free(s);
     }
 
     return o;
 }
 
-static gpointer setup_shrink_func(xmlNodePtr node)
+static gpointer setup_shrink_func(GHashTable *config)
 {
     Options *o;
 
-    o = setup_func(node);
+    o = setup_func(config);
     o->shrink = TRUE;
 
     return o;
@@ -167,7 +168,7 @@ static gboolean run_func(ObActionsData *data, gpointer options)
 }
 
 /* 3.4-compatibility */
-static gpointer setup_north_func(xmlNodePtr node)
+static gpointer setup_north_func(GHashTable *config)
 {
     Options *o = g_slice_new0(Options);
     o->shrink = FALSE;
@@ -175,7 +176,7 @@ static gpointer setup_north_func(xmlNodePtr node)
     return o;
 }
 
-static gpointer setup_south_func(xmlNodePtr node)
+static gpointer setup_south_func(GHashTable *config)
 {
     Options *o = g_slice_new0(Options);
     o->shrink = FALSE;
@@ -183,7 +184,7 @@ static gpointer setup_south_func(xmlNodePtr node)
     return o;
 }
 
-static gpointer setup_east_func(xmlNodePtr node)
+static gpointer setup_east_func(GHashTable *config)
 {
     Options *o = g_slice_new0(Options);
     o->shrink = FALSE;
@@ -191,7 +192,7 @@ static gpointer setup_east_func(xmlNodePtr node)
     return o;
 }
 
-static gpointer setup_west_func(xmlNodePtr node)
+static gpointer setup_west_func(GHashTable *config)
 {
     Options *o = g_slice_new0(Options);
     o->shrink = FALSE;
index ed1eeedc0462c26ed22557edbeb39ef028b4c61e..7baa5ab0f817acee40a8164edc31c924f40b2386 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/client.h"
 
 typedef struct {
@@ -6,15 +7,15 @@ typedef struct {
     gboolean toggle;
 } Options;
 
-static gpointer setup_func_top(xmlNodePtr node);
-static gpointer setup_func_bottom(xmlNodePtr node);
-static gpointer setup_func_send(xmlNodePtr node);
+static gpointer setup_func_top(GHashTable *config);
+static gpointer setup_func_bottom(GHashTable *config);
+static gpointer setup_func_send(GHashTable *config);
 static void free_func(gpointer o);
 static gboolean run_func(ObActionsData *data, gpointer options);
 /* 3.4-compatibility */
-static gpointer setup_sendtop_func(xmlNodePtr node);
-static gpointer setup_sendbottom_func(xmlNodePtr node);
-static gpointer setup_sendnormal_func(xmlNodePtr node);
+static gpointer setup_sendtop_func(GHashTable *config);
+static gpointer setup_sendbottom_func(GHashTable *config);
+static gpointer setup_sendnormal_func(GHashTable *config);
 
 void action_layer_startup(void)
 {
@@ -33,7 +34,7 @@ void action_layer_startup(void)
                      run_func);
 }
 
-static gpointer setup_func_top(xmlNodePtr node)
+static gpointer setup_func_top(GHashTable *config)
 {
     Options *o = g_slice_new0(Options);
     o->layer = 1;
@@ -41,7 +42,7 @@ static gpointer setup_func_top(xmlNodePtr node)
     return o;
 }
 
-static gpointer setup_func_bottom(xmlNodePtr node)
+static gpointer setup_func_bottom(GHashTable *config)
 {
     Options *o = g_slice_new0(Options);
     o->layer = -1;
@@ -49,15 +50,16 @@ static gpointer setup_func_bottom(xmlNodePtr node)
     return o;
 }
 
-static gpointer setup_func_send(xmlNodePtr node)
+static gpointer setup_func_send(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
 
-    if ((n = obt_xml_find_node(node, "layer"))) {
-        gchar *s = obt_xml_node_string(n);
+    v = g_hash_table_lookup(config, "layer");
+    if (v && actions_value_is_string(v)) {
+        const gchar *s = actions_value_string(v);
         if (!g_ascii_strcasecmp(s, "above") ||
             !g_ascii_strcasecmp(s, "top"))
             o->layer = 1;
@@ -67,7 +69,6 @@ static gpointer setup_func_send(xmlNodePtr node)
         else if (!g_ascii_strcasecmp(s, "normal") ||
                  !g_ascii_strcasecmp(s, "middle"))
             o->layer = 0;
-        g_free(s);
     }
 
     return o;
@@ -106,7 +107,7 @@ static gboolean run_func(ObActionsData *data, gpointer options)
 }
 
 /* 3.4-compatibility */
-static gpointer setup_sendtop_func(xmlNodePtr node)
+static gpointer setup_sendtop_func(GHashTable *config)
 {
     Options *o = g_slice_new0(Options);
     o->layer = 1;
@@ -114,7 +115,7 @@ static gpointer setup_sendtop_func(xmlNodePtr node)
     return o;
 }
 
-static gpointer setup_sendbottom_func(xmlNodePtr node)
+static gpointer setup_sendbottom_func(GHashTable *config)
 {
     Options *o = g_slice_new0(Options);
     o->layer = -1;
@@ -122,7 +123,7 @@ static gpointer setup_sendbottom_func(xmlNodePtr node)
     return o;
 }
 
-static gpointer setup_sendnormal_func(xmlNodePtr node)
+static gpointer setup_sendnormal_func(GHashTable *config)
 {
     Options *o = g_slice_new0(Options);
     o->layer = 0;
index db7c36bb8aaebb9fd9d47a7eea41768bb40d5662..2bb6a62bb8ff305476d282f8d35abcf3036bd897 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/client.h"
 
 /* These match the values for client_maximize */
@@ -12,59 +13,36 @@ typedef struct {
     MaxDirection dir;
 } Options;
 
-static gpointer setup_func(xmlNodePtr node);
+static gpointer setup_func(GHashTable *config);
 static void free_func(gpointer o);
 static gboolean run_func_on(ObActionsData *data, gpointer options);
 static gboolean run_func_off(ObActionsData *data, gpointer options);
 static gboolean run_func_toggle(ObActionsData *data, gpointer options);
-/* 3.4-compatibility */
-static gpointer setup_both_func(xmlNodePtr node);
-static gpointer setup_horz_func(xmlNodePtr node);
-static gpointer setup_vert_func(xmlNodePtr node);
 
 void action_maximize_startup(void)
 {
     actions_register("Maximize", setup_func, free_func, run_func_on);
     actions_register("Unmaximize", setup_func, free_func, run_func_off);
     actions_register("ToggleMaximize", setup_func, free_func, run_func_toggle);
-    /* 3.4-compatibility */
-    actions_register("MaximizeFull", setup_both_func, free_func,
-                     run_func_on);
-    actions_register("UnmaximizeFull", setup_both_func, free_func,
-                     run_func_off);
-    actions_register("ToggleMaximizeFull", setup_both_func, free_func,
-                     run_func_toggle);
-    actions_register("MaximizeHorz", setup_horz_func, free_func,
-                     run_func_on);
-    actions_register("UnmaximizeHorz", setup_horz_func, free_func,
-                     run_func_off);
-    actions_register("ToggleMaximizeHorz", setup_horz_func, free_func,
-                     run_func_toggle);
-    actions_register("MaximizeVert", setup_vert_func, free_func,
-                     run_func_on);
-    actions_register("UnmaximizeVert", setup_vert_func, free_func,
-                     run_func_off);
-    actions_register("ToggleMaximizeVert", setup_vert_func, free_func,
-                     run_func_toggle);
 }
 
-static gpointer setup_func(xmlNodePtr node)
+static gpointer setup_func(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
     o->dir = BOTH;
 
-    if ((n = obt_xml_find_node(node, "direction"))) {
-        gchar *s = obt_xml_node_string(n);
+    v = g_hash_table_lookup(config, "dir");
+    if (v && actions_value_is_string(v)) {
+        const gchar *s = actions_value_string(v);
         if (!g_ascii_strcasecmp(s, "vertical") ||
             !g_ascii_strcasecmp(s, "vert"))
             o->dir = VERT;
         else if (!g_ascii_strcasecmp(s, "horizontal") ||
                  !g_ascii_strcasecmp(s, "horz"))
             o->dir = HORZ;
-        g_free(s);
     }
 
     return o;
@@ -115,26 +93,3 @@ static gboolean run_func_toggle(ObActionsData *data, gpointer options)
     }
     return FALSE;
 }
-
-/* 3.4-compatibility */
-static gpointer setup_both_func(xmlNodePtr node)
-{
-    Options *o = g_slice_new0(Options);
-    o->dir = BOTH;
-    return o;
-}
-
-static gpointer setup_horz_func(xmlNodePtr node)
-{
-    Options *o = g_slice_new0(Options);
-    o->dir = HORZ;
-    return o;
-}
-
-static gpointer setup_vert_func(xmlNodePtr node)
-{
-    Options *o = g_slice_new0(Options);
-    o->dir = VERT;
-    return o;
-}
-
index b67b5cf1094d3c4fcf03c53726388014bb598a16..4b3a0c5afdb1f8b87fb12f86b03d68430f969073 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/client.h"
 #include "openbox/screen.h"
 #include "openbox/frame.h"
@@ -11,7 +12,7 @@ typedef struct {
     gint y_denom;
 } Options;
 
-static gpointer setup_func(xmlNodePtr node);
+static gpointer setup_func(GHashTable *config);
 static void free_func(gpointer o);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
@@ -20,24 +21,19 @@ void action_moverelative_startup(void)
     actions_register("MoveRelative", setup_func, free_func, run_func);
 }
 
-static gpointer setup_func(xmlNodePtr node)
+static gpointer setup_func(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
-    gchar *s;
 
     o = g_slice_new0(Options);
 
-    if ((n = obt_xml_find_node(node, "x"))) {
-        s = obt_xml_node_string(n);
-        config_parse_relative_number(s, &o->x, &o->x_denom);
-        g_free(s);
-    }
-    if ((n = obt_xml_find_node(node, "y"))) {
-        s = obt_xml_node_string(n);
-        config_parse_relative_number(s, &o->y, &o->y_denom);
-        g_free(s);
-    }
+    v = g_hash_table_lookup(config, "x");
+    if (v && actions_value_is_string(v))
+        actions_value_fraction(v, &o->x, &o->x_denom);
+    v = g_hash_table_lookup(config, "y");
+    if (v && actions_value_is_string(v))
+        actions_value_fraction(v, &o->y, &o->y_denom);
 
     return o;
 }
index c23661cd401c2fd37645455456de69ba5f60e467..410fc7096020c6d8593e819680b662f9dfdad3d6 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/client.h"
 #include "openbox/screen.h"
 #include "openbox/frame.h"
@@ -21,11 +22,11 @@ typedef struct {
     gint monitor;
 } Options;
 
-static gpointer setup_func(xmlNodePtr node);
+static gpointer setup_func(GHashTable *config);
 static void free_func(gpointer o);
 static gboolean run_func(ObActionsData *data, gpointer options);
 /* 3.4-compatibility */
-static gpointer setup_center_func(xmlNodePtr node);
+static gpointer setup_center_func(GHashTable *config);
 
 void action_moveresizeto_startup(void)
 {
@@ -34,9 +35,9 @@ void action_moveresizeto_startup(void)
     actions_register("MoveToCenter", setup_center_func, free_func, run_func);
 }
 
-static gpointer setup_func(xmlNodePtr node)
+static gpointer setup_func(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
@@ -46,27 +47,25 @@ static gpointer setup_func(xmlNodePtr node)
     o->h = G_MININT;
     o->monitor = CURRENT_MONITOR;
 
-    if ((n = obt_xml_find_node(node, "x")))
-        config_parse_gravity_coord(n, &o->x);
-
-    if ((n = obt_xml_find_node(node, "y")))
-        config_parse_gravity_coord(n, &o->y);
-
-    if ((n = obt_xml_find_node(node, "width"))) {
-        gchar *s = obt_xml_node_string(n);
-        if (g_ascii_strcasecmp(s, "current") != 0)
-            config_parse_relative_number(s, &o->w, &o->w_denom);
-        g_free(s);
-    }
-    if ((n = obt_xml_find_node(node, "height"))) {
-        gchar *s = obt_xml_node_string(n);
-        if (g_ascii_strcasecmp(s, "current") != 0)
-            config_parse_relative_number(s, &o->h, &o->h_denom);
-        g_free(s);
-    }
-
-    if ((n = obt_xml_find_node(node, "monitor"))) {
-        gchar *s = obt_xml_node_string(n);
+    v = g_hash_table_lookup(config, "x");
+    if (v && actions_value_is_string(v))
+        actions_value_gravity_coord(v, &o->x);
+    v = g_hash_table_lookup(config, "y");
+    if (v && actions_value_is_string(v))
+        actions_value_gravity_coord(v, &o->y);
+
+    v = g_hash_table_lookup(config, "width");
+    if (v && actions_value_is_string(v))
+        if (g_ascii_strcasecmp(actions_value_string(v), "current") != 0)
+            actions_value_fraction(v, &o->w, &o->w_denom);
+    v = g_hash_table_lookup(config, "height");
+    if (v && actions_value_is_string(v))
+        if (g_ascii_strcasecmp(actions_value_string(v), "current") != 0)
+            actions_value_fraction(v, &o->h, &o->h_denom);
+
+    v = g_hash_table_lookup(config, "monitor");
+    if (v && actions_value_is_string(v)) {
+        const gchar *s = actions_value_string(v);
         if (g_ascii_strcasecmp(s, "current") != 0) {
             if (!g_ascii_strcasecmp(s, "all"))
                 o->monitor = ALL_MONITORS;
@@ -75,9 +74,8 @@ static gpointer setup_func(xmlNodePtr node)
             else if(!g_ascii_strcasecmp(s, "prev"))
                 o->monitor = PREV_MONITOR;
             else
-                o->monitor = obt_xml_node_int(n) - 1;
+                o->monitor = actions_value_int(v) - 1;
         }
-        g_free(s);
     }
 
     return o;
@@ -173,7 +171,7 @@ static gboolean run_func(ObActionsData *data, gpointer options)
 }
 
 /* 3.4-compatibility */
-static gpointer setup_center_func(xmlNodePtr node)
+static gpointer setup_center_func(GHashTable *config)
 {
     Options *o;
 
index ef5b69201f54f8229cb0a4e7c0ffabe347569b93..cff299ec663f196ff83cb746f08156d59999fdd9 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/misc.h"
 #include "openbox/client.h"
 #include "openbox/frame.h"
@@ -9,14 +10,14 @@ typedef struct {
     ObDirection dir;
 } Options;
 
-static gpointer setup_func(xmlNodePtr node);
+static gpointer setup_func(GHashTable *config);
 static void free_func(gpointer o);
 static gboolean run_func(ObActionsData *data, gpointer options);
 /* 3.4-compatibility */
-static gpointer setup_north_func(xmlNodePtr node);
-static gpointer setup_south_func(xmlNodePtr node);
-static gpointer setup_east_func(xmlNodePtr node);
-static gpointer setup_west_func(xmlNodePtr node);
+static gpointer setup_north_func(GHashTable *config);
+static gpointer setup_south_func(GHashTable *config);
+static gpointer setup_east_func(GHashTable *config);
+static gpointer setup_west_func(GHashTable *config);
 
 void action_movetoedge_startup(void)
 {
@@ -28,16 +29,17 @@ void action_movetoedge_startup(void)
     actions_register("MoveToEdgeWest", setup_west_func, free_func, run_func);
 }
 
-static gpointer setup_func(xmlNodePtr node)
+static gpointer setup_func(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
     o->dir = OB_DIRECTION_NORTH;
 
-    if ((n = obt_xml_find_node(node, "direction"))) {
-        gchar *s = obt_xml_node_string(n);
+    v = g_hash_table_lookup(config, "direction");
+    if (v && actions_value_is_string(v)) {
+        const gchar *s = actions_value_string(v);
         if (!g_ascii_strcasecmp(s, "north") ||
             !g_ascii_strcasecmp(s, "up"))
             o->dir = OB_DIRECTION_NORTH;
@@ -50,7 +52,6 @@ static gpointer setup_func(xmlNodePtr node)
         else if (!g_ascii_strcasecmp(s, "east") ||
                  !g_ascii_strcasecmp(s, "right"))
             o->dir = OB_DIRECTION_EAST;
-        g_free(s);
     }
 
     return o;
@@ -81,28 +82,28 @@ static gboolean run_func(ObActionsData *data, gpointer options)
 }
 
 /* 3.4-compatibility */
-static gpointer setup_north_func(xmlNodePtr node)
+static gpointer setup_north_func(GHashTable *config)
 {
     Options *o = g_slice_new0(Options);
     o->dir = OB_DIRECTION_NORTH;
     return o;
 }
 
-static gpointer setup_south_func(xmlNodePtr node)
+static gpointer setup_south_func(GHashTable *config)
 {
     Options *o = g_slice_new0(Options);
     o->dir = OB_DIRECTION_SOUTH;
     return o;
 }
 
-static gpointer setup_east_func(xmlNodePtr node)
+static gpointer setup_east_func(GHashTable *config)
 {
     Options *o = g_slice_new0(Options);
     o->dir = OB_DIRECTION_EAST;
     return o;
 }
 
-static gpointer setup_west_func(xmlNodePtr node)
+static gpointer setup_west_func(GHashTable *config)
 {
     Options *o = g_slice_new0(Options);
     o->dir = OB_DIRECTION_WEST;
index f6858d2d2046edf6667bb94aa319f05dd08ce534..5d6054d855e86b56e3ce9abe8b7821bc96f062ef 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/moveresize.h"
 #include "openbox/client.h"
 #include "openbox/frame.h"
@@ -9,7 +10,7 @@ typedef struct {
     guint32 corner;
 } Options;
 
-static gpointer setup_func(xmlNodePtr node);
+static gpointer setup_func(GHashTable *config);
 static void free_func(gpointer o);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
@@ -21,15 +22,16 @@ void action_resize_startup(void)
     actions_register("Resize", setup_func, free_func, run_func);
 }
 
-static gpointer setup_func(xmlNodePtr node)
+static gpointer setup_func(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
 
-    if ((n = obt_xml_find_node(node, "edge"))) {
-        gchar *s = obt_xml_node_string(n);
+    v = g_hash_table_lookup(config, "edge");
+    if (v && actions_value_is_string(v)) {
+        const gchar *s = actions_value_string(v);
 
         o->corner_specified = TRUE;
         if (!g_ascii_strcasecmp(s, "top"))
@@ -50,8 +52,6 @@ static gpointer setup_func(xmlNodePtr node)
             o->corner = OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT);
         else
             o->corner_specified = FALSE;
-
-        g_free(s);
     }
     return o;
 }
index e32aff32d55e417888ae26985fcc7226f144a4bc..b0e4f71d37232773b0ad11dc61452973e48cabc1 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/client.h"
 #include "openbox/screen.h"
 #include "openbox/frame.h"
@@ -15,7 +16,7 @@ typedef struct {
     gint bottom_denom;
 } Options;
 
-static gpointer setup_func(xmlNodePtr node);
+static gpointer setup_func(GHashTable *config);
 static void     free_func(gpointer options);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
@@ -24,32 +25,25 @@ void action_resizerelative_startup(void)
     actions_register("ResizeRelative", setup_func, free_func, run_func);
 }
 
-static void xml_node_relative(xmlNodePtr n, gint *num, gint *denom)
+static gpointer setup_func(GHashTable *config)
 {
-    gchar *s;
-
-    s = obt_xml_node_string(n);
-    config_parse_relative_number(s, num, denom);
-    g_free(s);
-}
-
-static gpointer setup_func(xmlNodePtr node)
-{
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
 
-    if ((n = obt_xml_find_node(node, "left")))
-        xml_node_relative(n, &o->left, &o->left_denom);
-    if ((n = obt_xml_find_node(node, "right")))
-        xml_node_relative(n, &o->right, &o->right_denom);
-    if ((n = obt_xml_find_node(node, "top")) ||
-        (n = obt_xml_find_node(node, "up")))
-        xml_node_relative(n, &o->top, &o->top_denom);
-    if ((n = obt_xml_find_node(node, "bottom")) ||
-        (n = obt_xml_find_node(node, "down")))
-        xml_node_relative(n, &o->bottom, &o->bottom_denom);
+    v = g_hash_table_lookup(config, "left");
+    if (v && actions_value_is_string(v))
+        actions_value_fraction(v, &o->left, &o->left_denom);
+    v = g_hash_table_lookup(config, "right");
+    if (v && actions_value_is_string(v))
+        actions_value_fraction(v, &o->right, &o->right_denom);
+    v = g_hash_table_lookup(config, "top");
+    if (v && actions_value_is_string(v))
+        actions_value_fraction(v, &o->top, &o->top_denom);
+    v = g_hash_table_lookup(config, "bottom");
+    if (v && actions_value_is_string(v))
+        actions_value_fraction(v, &o->bottom, &o->bottom_denom);
 
     return o;
 }
index dc9a218a6985b69c437020b9cdd7182351868bb5..7387ba8395f953143b611c63278b7aa38a76f147 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/openbox.h"
 #include "obt/paths.h"
 
@@ -6,7 +7,7 @@ typedef struct {
     gchar   *cmd;
 } Options;
 
-static gpointer setup_func(xmlNodePtr node);
+static gpointer setup_func(GHashTable *config);
 static void     free_func(gpointer options);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
@@ -15,20 +16,16 @@ void action_restart_startup(void)
     actions_register("Restart", setup_func, free_func, run_func);
 }
 
-static gpointer setup_func(xmlNodePtr node)
+static gpointer setup_func(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
 
-    if ((n = obt_xml_find_node(node, "command")) ||
-        (n = obt_xml_find_node(node, "execute")))
-    {
-        gchar *s = obt_xml_node_string(n);
-        o->cmd = obt_paths_expand_tilde(s);
-        g_free(s);
-    }
+    v = g_hash_table_lookup(config, "command");
+    if (v && actions_value_is_string(v))
+        o->cmd = obt_paths_expand_tilde(actions_value_string(v));
     return o;
 }
 
index 485a31d5a7e06880eee48d0f1f6aef512db13911..1687f2a4c3538cd5d4f5c4923315e2253e006b26 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/actions_value.h"
 #include "openbox/menu.h"
 #include <glib.h>
 
@@ -6,7 +7,7 @@ typedef struct {
     gchar   *name;
 } Options;
 
-static gpointer setup_func(xmlNodePtr node);
+static gpointer setup_func(GHashTable *config);
 static void     free_func(gpointer options);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
@@ -15,15 +16,16 @@ void action_showmenu_startup(void)
     actions_register("ShowMenu", setup_func, free_func, run_func);
 }
 
-static gpointer setup_func(xmlNodePtr node)
+static gpointer setup_func(GHashTable *config)
 {
-    xmlNodePtr n;
+    ObActionsValue *v;
     Options *o;
 
     o = g_slice_new0(Options);
 
-    if ((n = obt_xml_find_node(node, "menu")))
-        o->name = obt_xml_node_string(n);
+    v = g_hash_table_lookup(config, "menu");
+    if (v && actions_value_is_string(v))
+        o->name = g_strdup(actions_value_string(v));
     return o;
 }
 
index 20f2b90e826e995bb85fca88964d8f9368f01575..345f47b917a4d3783b04b16af8cd9b25f4f803af 100644 (file)
 */
 
 #include "actions_list.h"
+#include "actions.h"
+#include "actions_value.h"
 
 #include <glib.h>
 
-struct _ObActionsListValue {
-    gint ref;
-    enum {
-        OB_AL_STRING,
-        OB_AL_INTEGER,
-        OB_AL_ACTIONSLIST
-    } type;
-    union {
-        gchar *string;
-        guint integer;
-        ObActionsList *actions;
-    } v;
-};
-
 void actions_list_ref(ObActionsList *l)
 {
-    ++l->ref;
+    if (l) ++l->ref;
 }
 
 void actions_list_unref(ObActionsList *l)
@@ -63,97 +51,18 @@ void actions_list_test_destroy(ObActionsListTest *t)
         ObActionsListTest *n = t->next;
 
         g_free(t->key);
-        actions_list_value_unref(t->value);
+        actions_value_unref(t->value);
         g_slice_free(ObActionsListTest, t);
         t = n;
     }
 }
 
-ObActionsListValue* actions_list_value_new_string(const gchar *s)
-{
-    return actions_list_value_new_string_steal(g_strdup(s));
-}
-
-ObActionsListValue* actions_list_value_new_string_steal(gchar *s)
-{
-    ObActionsListValue *v = g_slice_new(ObActionsListValue);
-    v->ref = 1;
-    v->type = OB_AL_STRING;
-    v->v.string = s;
-    return v;
-}
-
-ObActionsListValue* actions_list_value_new_int(gint i)
-{
-    ObActionsListValue *v = g_slice_new(ObActionsListValue);
-    v->ref = 1;
-    v->type = OB_AL_INTEGER;
-    v->v.integer = i;
-    return v;
-}
-
-ObActionsListValue* actions_list_value_new_actions_list(ObActionsList *al)
-{
-    ObActionsListValue *v = g_slice_new(ObActionsListValue);
-    v->ref = 1;
-    v->type = OB_AL_ACTIONSLIST;
-    v->v.actions = al;
-    actions_list_ref(al);
-    return v;
-}
-
-void actions_list_value_ref(ObActionsListValue *v)
-{
-    ++v->ref;
-}
-
-void actions_list_value_unref(ObActionsListValue *v)
-{
-    if (v && --v->ref < 1) {
-        switch (v->type) {
-        case OB_AL_STRING:
-            g_free(v->v.string);
-            break;
-        case OB_AL_ACTIONSLIST:
-            actions_list_unref(v->v.actions);
-            break;
-        case OB_AL_INTEGER:
-            break;
-        }
-        g_slice_free(ObActionsListValue, v);
-    }
-}
-
-gboolean actions_list_value_is_string(ObActionsListValue *v)
-{
-    return v->type == OB_AL_STRING;
-}
-
-gboolean actions_list_value_is_int(ObActionsListValue *v)
-{
-    return v->type == OB_AL_INTEGER;
-}
-
-gboolean actions_list_value_is_actions_list(ObActionsListValue *v)
+ObActionsList* actions_list_concat(ObActionsList *a, ObActionsList *b)
 {
-    return v->type == OB_AL_ACTIONSLIST;
-}
+    ObActionsList *start = a;
 
-gchar* actions_list_value_string(ObActionsListValue *v)
-{
-    g_return_val_if_fail(v->type == OB_AL_STRING, NULL);
-    return v->v.string;
-}
-
-gint actions_list_value_int(ObActionsListValue *v)
-{
-    g_return_val_if_fail(v->type == OB_AL_INTEGER, 0);
-    return v->v.integer;
+    if (!start) return b;
+    while (a->next) a = a->next;
+    a->next = b;
+    return start;
 }
-
-ObActionsList* actions_list_value_actions_list(ObActionsListValue *v)
-{
-    g_return_val_if_fail(v->type == OB_AL_ACTIONSLIST, NULL);
-    return v->v.actions;
-}
-
index f5710e36d5868d1c70c5acf2ed625fa430507afd..6b84666ee50ab82c96a9b1fe7f1a8c65772b4268 100644 (file)
    See the COPYING file for a copy of the GNU General Public License.
 */
 
-#include "actions.h"
-
 #include <glib.h>
 
+struct _ObActionsAct;
+struct _ObActionsValue;
+
 typedef struct _ObActionsList      ObActionsList;
 typedef struct _ObActionsListTest  ObActionsListTest;
-typedef struct _ObActionsListValue ObActionsListValue;
 
 /*! Each node of the Actions list is an action itself (or a filter bound to
   an action). */
@@ -35,14 +35,14 @@ struct _ObActionsList {
             ObActionsList *thendo; /* can be null */
             ObActionsList *elsedo; /* can be null */
         } f;
-        ObActionsAct *action;
+        struct _ObActionsAct *action;
     } u;
     ObActionsList *next;
 };
 
 struct _ObActionsListTest {
     gchar *key;
-    ObActionsListValue *value; /* can be null */
+    struct _ObActionsValue *value; /* can be null */
     gboolean and;
     ObActionsListTest *next;
 };
@@ -52,23 +52,4 @@ void actions_list_unref(ObActionsList *l);
 
 void actions_list_test_destroy(ObActionsListTest *t);
 
-/*! Creates a new value by making a copy of the given string. */
-ObActionsListValue* actions_list_value_new_string(const gchar *s);
-/*! Creates a new value from a string, and steals ownership of the string. It
-  will be freed when then value is destroyed. */
-ObActionsListValue* actions_list_value_new_string_steal(gchar *s);
-/*! Creates a new value that holds an integer. */
-ObActionsListValue* actions_list_value_new_int(gint i);
-/*! Creates a new value with a given actions list. */
-ObActionsListValue* actions_list_value_new_actions_list(ObActionsList *al);
-
-void actions_list_value_ref(ObActionsListValue *v);
-void actions_list_value_unref(ObActionsListValue *v);
-
-gboolean actions_list_value_is_string(ObActionsListValue *v);
-gboolean actions_list_value_is_int(ObActionsListValue *v);
-gboolean actions_list_value_is_actions_list(ObActionsListValue *v);
-
-gchar* actions_list_value_string(ObActionsListValue *v);
-gint actions_list_value_int(ObActionsListValue *v);
-ObActionsList* actions_list_value_actions_list(ObActionsListValue *v);
+ObActionsList* actions_list_concat(ObActionsList *a, ObActionsList *b);
index 2ef8ee8f64d14af56665657631b29a6e0c196af0..5947378dd44387d228411e4dd2e6ba7c2644d5d5 100644 (file)
 */
 
 #include "actions_parser.h"
+#include "actions.h"
+#include "actions_list.h"
+#include "actions_value.h"
 #include "gettext.h"
 
 #ifdef HAVE_STRING_H
 #  include <string.h>
 #endif
 
+struct _ObActionsList;
+struct _ObActionsListTest;
+struct _ObActionsValue;
+
 #define SKIP " \t"
-#define IDENTIFIER_FIRST G_CSET_a_2_z G_CSET_A_2_Z
-#define IDENTIFIER_NTH G_CSET_a_2_z G_CSET_A_2_Z \
-    G_CSET_DIGITS G_CSET_LATINS G_CSET_LATINC "_-"
+#define IDENTIFIER_FIRST G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_"
+#define IDENTIFIER_NTH IDENTIFIER_FIRST G_CSET_LATINS G_CSET_LATINC
 #define ESCAPE_SEQS "\"()"
 
-ObActionsList* parse_list(ObActionsParser *p, GTokenType end, gboolean *e);
-ObActionsList* parse_action(ObActionsParser *p, gboolean *e);
-ObActionsList* parse_filter(ObActionsParser *p, gboolean *e);
-ObActionsListTest* parse_filter_test(ObActionsParser *p, gboolean *e);
-ObActionsListValue* parse_value(ObActionsParser *p,
-                                gboolean allow_actions,
-                                gboolean *e);
+struct _ObActionsList* parse_list(ObActionsParser *p,
+                                  GTokenType end,
+                                  gboolean *e);
+struct _ObActionsList* parse_action(ObActionsParser *p, gboolean *e);
+struct _ObActionsList* parse_filter(ObActionsParser *p, gboolean *e);
+struct _ObActionsListTest* parse_filter_test(ObActionsParser *p, gboolean *e);
+struct _ObActionsValue* parse_value(ObActionsParser *p,
+                                        gboolean allow_actions,
+                                        gboolean *e);
 gchar* parse_string(ObActionsParser *p, guchar end, gboolean *e);
 
 struct _ObActionsParser
@@ -103,6 +111,7 @@ ObActionsList* actions_parser_read_string(ObActionsParser *p,
     g_scanner_input_text(p->scan, text, strlen(text));
     p->scan->input_name = "(console)";
 
+    e = FALSE;
     return parse_list(p, G_TOKEN_EOF, &e);
 }
 
@@ -119,6 +128,7 @@ ObActionsList* actions_parser_read_file(ObActionsParser *p,
     g_scanner_input_file(p->scan, g_io_channel_unix_get_fd(ch));
     p->scan->input_name = file;
 
+    e = FALSE;
     return parse_list(p, G_TOKEN_EOF, &e);
 }
 
@@ -126,9 +136,10 @@ ObActionsList* actions_parser_read_file(ObActionsParser *p,
 BNF for the language:
 
 TEST       := KEY=VALUE | KEY
-ACTION     := [FILTER] ACTION ACTIONELSE | ACTIONNAME ACTIONOPTS | {ACTIONLIST}
+ACTION     := [FILTER] ACTION ELSE END | ACTIONNAME ACTIONOPTS | {ACTIONLIST}
+ELSE       := nil | \| ACTION
+END        := \n | ; | EOF
 ACTIONLIST := ACTION ACTIONLIST | ACTION
-ACTIONELSE := nil | \| ACTION
 FILTER     := FILTERORS
 FILTERORS  := FILTERANDS \| FILTERORS | FILTERANDS
 FILTERANDS := TEST, FILTERANDS | TEST
@@ -160,7 +171,10 @@ ObActionsList* parse_list(ObActionsParser *p, GTokenType end, gboolean *e)
     while (t != end && t != G_TOKEN_EOF) {
         if (t == '\n')
             g_scanner_get_next_token(p->scan); /* skip empty lines */
-        else {
+        else if (t == ';') {
+            g_scanner_get_next_token(p->scan); /* separator */
+        }
+        else if (t == G_TOKEN_IDENTIFIER) {
             ObActionsList *next;
 
             /* parse the next action and stick it on the end of the list */
@@ -168,9 +182,14 @@ ObActionsList* parse_list(ObActionsParser *p, GTokenType end, gboolean *e)
             if (last) last->next = next;
             if (!first) first = next;
             last = next;
-
-            if (*e) break; /* don't parse any more after an error */
         }
+        else {
+            g_scanner_get_next_token(p->scan);
+            parse_error(p, (end ? end : G_TOKEN_NONE),
+                        _("Expected an action or end of action list"), e);
+        }
+
+        if (*e) break; /* don't parse any more after an error */
 
         t = g_scanner_peek_next_token(p->scan);
     }
@@ -186,7 +205,7 @@ ObActionsList* parse_action(ObActionsParser *p, gboolean *e)
     GTokenType t;
     ObActionsList *al;
     gchar *name;
-    GList *keys, *values;
+    GHashTable *config;
 
     t = g_scanner_get_next_token(p->scan);
 
@@ -199,44 +218,57 @@ ObActionsList* parse_action(ObActionsParser *p, gboolean *e)
 
     /* read the action's name */
     name = g_strdup(p->scan->value.v_string);
-    keys = values = NULL;
+    config = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+                                   (GDestroyNotify)actions_value_unref);
 
     /* read the action's options key:value pairs */
     t = g_scanner_peek_next_token(p->scan);
-    while (t == G_TOKEN_IDENTIFIER) {
-        gchar *key;
-        ObActionsListValue *value;
-
-        g_scanner_get_next_token(p->scan); /* eat the key */
-        t = g_scanner_peek_next_token(p->scan); /* check for ':' */
-        if (t != ':') {
-            parse_error(p, ':', NULL, e);
-            break; /* don't read any more options */
+    while (t == G_TOKEN_IDENTIFIER || t == '\\') {
+        if (t == '\\') {
+            g_scanner_get_next_token(p->scan); /* eat it */
+            t = g_scanner_get_next_token(p->scan); /* check for '\n' */
+            if (t != '\n')
+                parse_error(p, G_TOKEN_NONE, _("Expected newline"), e);
         }
+        else {
+            gchar *key;
+            ObActionsValue *value;
+
+            g_scanner_get_next_token(p->scan); /* eat the key */
+            t = g_scanner_peek_next_token(p->scan); /* check for ':' */
+            if (t != ':') {
+                g_scanner_get_next_token(p->scan);
+                parse_error(p, ':', NULL, e);
+                break; /* don't read any more options */
+            }
 
-        /* save the key */
-        key = g_strdup(p->scan->value.v_string);
-        g_scanner_get_next_token(p->scan); /* eat the ':' */
+            /* save the key */
+            key = g_strdup(p->scan->value.v_string);
+            g_scanner_get_next_token(p->scan); /* eat the ':' */
 
-        /* read the value */
-        value = parse_value(p, TRUE, e);
+            /* read the value */
+            value = parse_value(p, TRUE, e);
 
-        /* check if we read a value (regardless of errors), and save
-           the key:value pair if we did. */
-        if (value) {
-            keys = g_list_prepend(keys, key);
-            values = g_list_prepend(values, value);
+            /* check if we read a value (regardless of errors), and save
+               the key:value pair if we did. */
+            if (value)
+                g_hash_table_replace(config, key, value);
+            else
+                g_free(key); /* didn't read any value */
         }
-        else
-            g_free(key); /* didn't read any value */
 
         if (*e) break; /* don't parse any more if there was an error */
+
+        t = g_scanner_peek_next_token(p->scan);
     }
 
     al = g_slice_new(ObActionsList);
     al->ref = 1;
     al->isfilter = FALSE;
-    al->u.action = actions_act_new(name, keys, values);
+    al->u.action = actions_act_new(name, config);
+    al->next = NULL;
+    g_free(name);
+    g_hash_table_unref(config);
     return al;
 }
 
@@ -274,6 +306,7 @@ ObActionsList* parse_filter(ObActionsParser *p, gboolean *e)
     al->u.f.test = test;
     al->u.f.thendo = thendo;
     al->u.f.elsedo = elsedo;
+    al->next = NULL;
     return al;
 }
 
@@ -281,7 +314,7 @@ ObActionsListTest* parse_filter_test(ObActionsParser *p, gboolean *e)
 {
     GTokenType t;
     gchar *key;
-    ObActionsListValue *value;
+    ObActionsValue *value;
     gboolean and;
     ObActionsListTest *next;
 
@@ -309,31 +342,29 @@ ObActionsListTest* parse_filter_test(ObActionsParser *p, gboolean *e)
     /* don't allow any errors (but value can be null if not present) */
     if (*e) {
         g_free(key);
-        actions_list_value_unref(value);
+        actions_value_unref(value);
         return NULL;
     }
 
     /* check if there is another test and how we're connected */
     t = g_scanner_get_next_token(p->scan);
-    switch (t) {
-    case ',': /* and */
+    if (t == ',') { /* and */
         and = TRUE;
         next = parse_filter_test(p, e);
-        break;
-    case '|': /* or */
+    }
+    else if (t == '|') { /* or */
         and = FALSE;
         next = parse_filter_test(p, e);
-        break;
-    case ']': /* end of the filter */
-        break;
-    default:
-        parse_error(p, ']', NULL, e);
     }
+    else if (t == ']') /* end of the filter */
+        ;
+    else
+        parse_error(p, ']', NULL, e);
 
     /* don't allow any errors */
     if (*e) {
         g_free(key);
-        actions_list_value_unref(value);
+        actions_value_unref(value);
         actions_list_test_destroy(next);
         return NULL;
     }
@@ -349,26 +380,25 @@ ObActionsListTest* parse_filter_test(ObActionsParser *p, gboolean *e)
     }
 }
 
-ObActionsListValue* parse_value(ObActionsParser *p,
+ObActionsValue* parse_value(ObActionsParser *p,
                                 gboolean allow_actions,
                                 gboolean *e)
 {
     GTokenType t;
-    ObActionsListValue *v;
+    ObActionsValue *v;
 
     v = NULL;
     t = g_scanner_get_next_token(p->scan);
-    if (t == G_TOKEN_IDENTIFIER)
-        v = actions_list_value_new_string(p->scan->value.v_string);
-    else if (t == G_TOKEN_INT)
-        v = actions_list_value_new_int(p->scan->value.v_int);
+    if (t == G_TOKEN_IDENTIFIER) {
+        v = actions_value_new_string(p->scan->value.v_string);
+    }
     else if (t == '"')
-        v = actions_list_value_new_string(parse_string(p, '"', e));
+        v = actions_value_new_string(parse_string(p, '"', e));
     else if (t == '(')
-        v = actions_list_value_new_string(parse_string(p, ')', e));
+        v = actions_value_new_string(parse_string(p, ')', e));
     else if (t == '{' && allow_actions) {
         ObActionsList *l = parse_list(p, '}', e);
-        if (l) v = actions_list_value_new_actions_list(l);
+        if (l) v = actions_value_new_actions_list(l);
     }
     else
         parse_error(p, G_TOKEN_NONE, _("Expected an option value"), e);
@@ -391,27 +421,22 @@ gchar* parse_string(ObActionsParser *p, guchar end, gboolean *e)
 
     t = g_scanner_get_next_token(p->scan);
     while (t != end) {
-        switch (t) {
-        case G_TOKEN_IDENTIFIER:
+        if (t == G_TOKEN_IDENTIFIER)
             g_string_append(buf, p->scan->value.v_string);
-            break;
-        case G_TOKEN_EOF:
+        else if (t == G_TOKEN_EOF) {
             error_message = _("Missing end of quoted string");
             goto parse_string_error;
-        case G_TOKEN_NONE:
-            error_message = _("Unknown token in quoted string");
-            goto parse_string_error;
-        case '\\': /* escape sequence */
+        }
+        else if (t == '\\') { /* escape sequence */
             t = g_scanner_get_next_token(p->scan);
             if (!strchr(ESCAPE_SEQS, t)) {
                 error_message = _("Unknown escape sequence");
                 goto parse_string_error;
             }
             g_string_append_c(buf, t);
-            break;
-        default: /* other single character */
-            g_string_append_c(buf, t);
         }
+        else /* other single character */
+            g_string_append_c(buf, t);
 
         t = g_scanner_get_next_token(p->scan);
     }
index 5d26a293031581db1f4c0541172a3d8f5c50ab97..44a1972358a5da1ea4c03b4982cf397104b3c1e1 100644 (file)
    See the COPYING file for a copy of the GNU General Public License.
 */
 
-#include "actions_list.h"
-
 #include <glib.h>
 
+struct _ObActionsList;
+
 typedef struct _ObActionsParser ObActionsParser;
 
 ObActionsParser* actions_parser_new(void);
@@ -27,8 +27,8 @@ ObActionsParser* actions_parser_new(void);
 void actions_parser_ref(ObActionsParser *p);
 void actions_parser_unref(ObActionsParser *p);
 
-ObActionsList* actions_parser_read_string(ObActionsParser *p,
-                                          const gchar *text);
-ObActionsList* actions_parser_read_file(ObActionsParser *p,
-                                        const gchar *file,
-                                        GError **error);
+struct _ObActionsList* actions_parser_read_string(ObActionsParser *p,
+                                                  const gchar *text);
+struct _ObActionsList* actions_parser_read_file(ObActionsParser *p,
+                                                const gchar *file,
+                                                GError **error);
diff --git a/openbox/actions_value.c b/openbox/actions_value.c
new file mode 100644 (file)
index 0000000..5603ade
--- /dev/null
@@ -0,0 +1,166 @@
+/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
+
+   actions_value.c for the Openbox window manager
+   Copyright (c) 2011        Dana Jansens
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   See the COPYING file for a copy of the GNU General Public License.
+*/
+
+#include "actions_value.h"
+#include "actions_list.h"
+#include "geom.h"
+
+#include "stdlib.h"
+
+struct _ObActionsValue {
+    gint ref;
+    enum {
+        OB_AV_STRING,
+        OB_AV_ACTIONSLIST
+    } type;
+    union {
+        gchar *string;
+        gboolean boolean;
+        guint integer;
+        ObActionsList *actions;
+    } v;
+};
+
+ObActionsValue* actions_value_new_string(const gchar *s)
+{
+    return actions_value_new_string_steal(g_strdup(s));
+}
+
+ObActionsValue* actions_value_new_string_steal(gchar *s)
+{
+    ObActionsValue *v = g_slice_new(ObActionsValue);
+    v->ref = 1;
+    v->type = OB_AV_STRING;
+    v->v.string = s;
+    return v;
+}
+
+ObActionsValue* actions_value_new_actions_list(ObActionsList *al)
+{
+    ObActionsValue *v = g_slice_new(ObActionsValue);
+    v->ref = 1;
+    v->type = OB_AV_ACTIONSLIST;
+    v->v.actions = al;
+    actions_list_ref(al);
+    return v;
+}
+
+void actions_value_ref(ObActionsValue *v)
+{
+    ++v->ref;
+}
+
+void actions_value_unref(ObActionsValue *v)
+{
+    if (v && --v->ref < 1) {
+        switch (v->type) {
+        case OB_AV_STRING:
+            g_free(v->v.string);
+            break;
+        case OB_AV_ACTIONSLIST:
+            actions_list_unref(v->v.actions);
+            break;
+        }
+        g_slice_free(ObActionsValue, v);
+    }
+}
+
+gboolean actions_value_is_string(ObActionsValue *v)
+{
+    return v->type == OB_AV_STRING;
+}
+
+gboolean actions_value_is_actions_list(ObActionsValue *v)
+{
+    return v->type == OB_AV_ACTIONSLIST;
+}
+
+const gchar* actions_value_string(ObActionsValue *v)
+{
+    g_return_val_if_fail(v->type == OB_AV_STRING, NULL);
+    return v->v.string;
+}
+
+gboolean actions_value_bool(ObActionsValue *v)
+{
+    g_return_val_if_fail(v->type == OB_AV_STRING, FALSE);
+    if (g_strcasecmp(v->v.string, "true") == 0 ||
+        g_strcasecmp(v->v.string, "yes") == 0)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+gint actions_value_int(ObActionsValue *v)
+{
+    gchar *s;
+
+    g_return_val_if_fail(v->type == OB_AV_STRING, 0);
+    s = v->v.string;
+    return strtol(s, &s, 10);
+}
+
+void actions_value_fraction(ObActionsValue *v, gint *numer, gint *denom)
+{
+    gchar *s;
+
+    *numer = *denom = 0;
+
+    g_return_if_fail(v->type == OB_AV_STRING);
+    s = v->v.string;
+
+    *numer = strtol(s, &s, 10);
+    if (*s == '%')
+        *denom = 100;
+    else if (*s == '/')
+        *denom = atoi(s+1);
+}
+
+void actions_value_gravity_coord(ObActionsValue *v, GravityCoord *c)
+{
+    gchar *s;
+
+    c->center = FALSE;
+    c->pos = 0;
+    c->denom = 0;
+
+    g_return_if_fail(v->type == OB_AV_STRING);
+    s = v->v.string;
+
+    if (!g_ascii_strcasecmp(s, "center"))
+        c->center = TRUE;
+    else {
+        if (s[0] == '-')
+            c->opposite = TRUE;
+        if (s[0] == '-' || s[0] == '+')
+            ++s;
+
+        c->pos = strtol(s, &s, 10);
+
+        if (*s == '%')
+            c->denom = 100;
+        else if (*s == '/')
+            c->denom = atoi(s+1);
+    }
+}
+
+ObActionsList* actions_value_actions_list(ObActionsValue *v)
+{
+    g_return_val_if_fail(v->type == OB_AV_ACTIONSLIST, NULL);
+    return v->v.actions;
+}
diff --git a/openbox/actions_value.h b/openbox/actions_value.h
new file mode 100644 (file)
index 0000000..681a00c
--- /dev/null
@@ -0,0 +1,45 @@
+/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
+
+   actions_value.h for the Openbox window manager
+   Copyright (c) 2011        Dana Jansens
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   See the COPYING file for a copy of the GNU General Public License.
+*/
+
+#include <glib.h>
+
+struct _GravityCoord;
+struct _ObActionsList;
+
+typedef struct _ObActionsValue        ObActionsValue;
+
+/*! Creates a new value by making a copy of the given string. */
+ObActionsValue* actions_value_new_string(const gchar *s);
+/*! Creates a new value from a string, and steals ownership of the string. It
+  will be freed when then value is destroyed. */
+ObActionsValue* actions_value_new_string_steal(gchar *s);
+/*! Creates a new value with a given actions list. */
+ObActionsValue* actions_value_new_actions_list(struct _ObActionsList *al);
+
+void actions_value_ref(ObActionsValue *v);
+void actions_value_unref(ObActionsValue *v);
+
+gboolean actions_value_is_string(ObActionsValue *v);
+gboolean actions_value_is_actions_list(ObActionsValue *v);
+
+const gchar* actions_value_string(ObActionsValue *v);
+gboolean actions_value_bool(ObActionsValue *v);
+gint actions_value_int(ObActionsValue *v);
+void actions_value_fraction(ObActionsValue *v, gint *numer, gint *denom);
+void actions_value_gravity_coord(ObActionsValue *v, struct _GravityCoord *c);
+struct _ObActionsList* actions_value_actions_list(ObActionsValue *v);
index 0d9eb689f2e7f4e7ad8ecc4073529413c1541371..8fda459dfd91d781798063f966f373ba5dcbaa5c 100644 (file)
@@ -21,6 +21,8 @@
 #include "keyboard.h"
 #include "mouse.h"
 #include "actions.h"
+#include "actions_list.h"
+#include "actions_parser.h"
 #include "translate.h"
 #include "client.h"
 #include "screen.h"
@@ -420,11 +422,20 @@ static void parse_key(xmlNodePtr node, GList *keylist)
         }
         else if ((n = obt_xml_find_node(node->children, "action"))) {
             while (n) {
-                ObActionsAct *action;
+                ObActionsParser *p;
+                ObActionsList *actions;
+                xmlChar *c;
 
-                action = actions_parse(n);
-                if (action)
-                    keyboard_bind(keylist, action);
+                c = xmlNodeGetContent(node);
+                p = actions_parser_new();
+                actions = actions_parser_read_string(p, (gchar*)c);
+                xmlFree(c);
+                actions_parser_unref(p);
+
+                if (actions)
+                    keyboard_bind(keylist, actions);
+
+                actions_list_unref(actions);
                 n = obt_xml_find_node(n->next, "action");
             }
         }
@@ -535,11 +546,18 @@ static void parse_mouse(xmlNodePtr node, gpointer d)
 
                 nact = obt_xml_find_node(nbut->children, "action");
                 while (nact) {
-                    ObActionsAct *action;
-
-                    if ((action = actions_parse(nact)))
-                        mouse_bind(buttonstr, cx, mact, action);
+                    ObActionsList *actions;
+                    ObActionsParser *p;
+                    xmlChar *c;
+
+                    c = xmlNodeGetContent(nact);
+                    p = actions_parser_new();
+                    if ((actions = actions_parser_read_string(p, (gchar*)c)))
+                        mouse_bind(buttonstr, cx, mact, actions);
                     nact = obt_xml_find_node(nact->next, "action");
+                    actions_list_unref(actions);
+                    xmlFree(c);
+                    actions_parser_unref(p);
                 }
             g_free(buttonstr);
             next_nbut:
@@ -915,22 +933,31 @@ static void parse_resistance(xmlNodePtr node, gpointer d)
 typedef struct
 {
     const gchar *key;
-    const gchar *actname;
+    const gchar *actiontext;
 } ObDefKeyBind;
 
 static void bind_default_keyboard(void)
 {
     ObDefKeyBind *it;
     ObDefKeyBind binds[] = {
+        { "Left",
+          "Execute startupnotify:yes name:Konqueror              \\\n"
+          "  command:(kfmclient openProfile filemanagement)" },
         { "A-Tab", "NextWindow" },
         { "S-A-Tab", "PreviousWindow" },
         { "A-F4", "Close" },
         { NULL, NULL }
     };
+    ObActionsParser *p;
+
+    p = actions_parser_new();
     for (it = binds; it->key; ++it) {
         GList *l = g_list_append(NULL, g_strdup(it->key));
-        keyboard_bind(l, actions_parse_string(it->actname));
+        ObActionsList *actions = actions_parser_read_string(p, it->actiontext);
+        keyboard_bind(l, actions);
+        actions_list_unref(actions);
     }
+    actions_parser_unref(p);
 }
 
 typedef struct
@@ -994,10 +1021,17 @@ static void bind_default_mouse(void)
         { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION, "Resize" },
         { NULL, NULL, 0, NULL }
     };
+    ObActionsParser *p;
+    ObActionsList *actions;
 
-    for (it = binds; it->button; ++it)
+    p = actions_parser_new();
+    for (it = binds; it->button; ++it) {
+        actions = actions_parser_read_string(p, it->actname);
         mouse_bind(it->button, frame_context_from_string(it->context),
-                   it->mact, actions_parse_string(it->actname));
+                   it->mact, actions);
+        actions_list_unref(actions);
+    }
+    actions_parser_unref(p);
 }
 
 void config_startup(ObtXmlInst *i)
index 8f4424ea97d43c8c233b69886def08c1f9e5396f..25d3b310bb7ed540434471b185da42e2df01eaf8 100644 (file)
@@ -25,6 +25,7 @@
 #include "grab.h"
 #include "client.h"
 #include "actions.h"
+#include "actions_list.h"
 #include "menuframe.h"
 #include "config.h"
 #include "keytree.h"
@@ -139,13 +140,15 @@ void keyboard_chroot(GList *keylist)
     }
 }
 
-gboolean keyboard_bind(GList *keylist, ObActionsAct *action)
+gboolean keyboard_bind(GList *keylist, ObActionsList *actions)
 {
     KeyBindingTree *tree, *t;
     gboolean conflict;
 
     g_assert(keylist != NULL);
-    g_assert(action != NULL);
+
+    if (!actions)
+        return TRUE;
 
     if (!(tree = tree_build(keylist)))
         return FALSE;
@@ -167,7 +170,9 @@ gboolean keyboard_bind(GList *keylist, ObActionsAct *action)
     for (; t->first_child; t = t->first_child);
 
     /* set the action */
-    t->actions = g_slist_append(t->actions, action);
+    actions_list_ref(actions);
+    t->actions = actions_list_concat(t->actions, actions);
+
     /* assimilate this built tree into the main tree. assimilation
        destroys/uses the tree */
     if (tree) tree_assimilate(tree);
@@ -259,16 +264,14 @@ gboolean keyboard_event(ObClient *client, const XEvent *e)
             } else if (p->chroot)         /* an empty chroot */
                 set_curpos(p);
             else {
-                GSList *it;
+                gboolean i;
 
-                for (it = p->actions; it; it = g_slist_next(it))
-                    if (actions_act_is_interactive(it->data)) break;
-                if (it == NULL) /* reset if the actions are not interactive */
+                i = actions_run_acts(p->actions, OB_USER_ACTION_KEYBOARD_KEY,
+                                     e->xkey.state,
+                                     e->xkey.x_root, e->xkey.y_root,
+                                     0, OB_FRAME_CONTEXT_NONE, client);
+                if (!i) /* reset if an interactive was not run */
                     keyboard_reset_chains(0);
-
-                actions_run_acts(p->actions, OB_USER_ACTION_KEYBOARD_KEY,
-                                 e->xkey.state, e->xkey.x_root, e->xkey.y_root,
-                                 0, OB_FRAME_CONTEXT_NONE, client);
             }
             break;
             used = TRUE;
@@ -292,12 +295,7 @@ static void node_rebind(KeyBindingTree *node)
     }
     else {
         /* for leaf nodes, rebind each action assigned to it */
-        while (node->actions) {
-            /* add each action, and remove them from the original tree so
-               they don't get free'd on us */
-            keyboard_bind(node->keylist, node->actions->data);
-            node->actions = g_slist_delete_link(node->actions, node->actions);
-        }
+        keyboard_bind(node->keylist, node->actions);
 
         if (node->chroot)
             keyboard_chroot(node->keylist);
index c89f67e941f084439f988c576c240318d228dc08..07059a2610e4c0cd589e5309b34d962e98d845b4 100644 (file)
@@ -37,7 +37,7 @@ void keyboard_shutdown(gboolean reconfig);
 void keyboard_rebind(void);
 
 void keyboard_chroot(GList *keylist);
-gboolean keyboard_bind(GList *keylist, struct _ObActionsAct *action);
+gboolean keyboard_bind(GList *keylist, struct _ObActionsList *actions);
 void keyboard_unbind_all(void);
 
 gboolean keyboard_event(struct _ObClient *client, const XEvent *e);
index 93a0c7aa6a54aa9e6dc53b0346cf79171c1d3aa0..7b4b0f7210665c5663a92829ee3a2d5b52982d49 100644 (file)
@@ -20,6 +20,7 @@
 #include "keyboard.h"
 #include "translate.h"
 #include "actions.h"
+#include "actions_list.h"
 #include <glib.h>
 
 void tree_destroy(KeyBindingTree *tree)
@@ -31,13 +32,10 @@ void tree_destroy(KeyBindingTree *tree)
         c = tree->first_child;
         if (c == NULL) {
             GList *it;
-            GSList *sit;
             for (it = tree->keylist; it != NULL; it = it->next)
                 g_free(it->data);
             g_list_free(tree->keylist);
-            for (sit = tree->actions; sit != NULL; sit = sit->next)
-                actions_act_unref(sit->data);
-            g_slist_free(tree->actions);
+            actions_list_unref(tree->actions);
         }
         g_slice_free(KeyBindingTree, tree);
         tree = c;
index 66edc3c7faf0af58ba57827370debed953d6c74d..8504772f4954eae10fbed25834115f9a22659045 100644 (file)
 
 #include <glib.h>
 
+struct _ObActionsList;
+
 typedef struct KeyBindingTree {
     guint state;
     guint key;
     GList *keylist;
-    GSList *actions; /* list of Action pointers */
+    struct _ObActionsList *actions;
     gboolean chroot;
 
     /* the level up in the tree */
index 93b3879e2f69d0213c8c9e2681e5f454bc6655b6..28ac4edba16f3f4b7b96dafd90dbaff2dce4cc2d 100644 (file)
@@ -25,6 +25,8 @@
 #include "client.h"
 #include "config.h"
 #include "actions.h"
+#include "actions_list.h"
+#include "actions_parser.h"
 #include "screen.h"
 #include "menuframe.h"
 #include "keyboard.h"
@@ -284,16 +286,24 @@ static void parse_menu_item(xmlNodePtr node,  gpointer data)
 
         if (obt_xml_attr_string(node, "label", &label)) {
             xmlNodePtr c;
-            GSList *acts = NULL;
+            xmlChar *cc;
+            ObActionsList *acts = NULL;
+            ObActionsParser *p;
 
             c = obt_xml_find_node(node->children, "action");
+            p = actions_parser_new();
             while (c) {
-                ObActionsAct *action = actions_parse(c);
-                if (action)
-                    acts = g_slist_append(acts, action);
+                ObActionsList *al;
+
+                cc = xmlNodeGetContent(c);
+                al = actions_parser_read_string(p, (gchar*)cc);
+                xmlFree(cc);
+                acts = actions_list_concat(acts, al);
+
                 c = obt_xml_find_node(c->next, "action");
             }
             e = menu_add_normal(state->parent, -1, label, acts, TRUE);
+            actions_list_unref(acts);
             
             if (config_menu_show_icons &&
                 obt_xml_attr_string(node, "icon", &icon))
@@ -548,12 +558,7 @@ void menu_entry_unref(ObMenuEntry *self)
             RrImageUnref(self->data.normal.icon);
             g_free(self->data.normal.label);
             g_free(self->data.normal.collate_key);
-            while (self->data.normal.actions) {
-                actions_act_unref(self->data.normal.actions->data);
-                self->data.normal.actions =
-                    g_slist_delete_link(self->data.normal.actions,
-                                        self->data.normal.actions);
-            }
+            actions_list_unref(self->data.normal.actions);
             break;
         case OB_MENU_ENTRY_TYPE_SUBMENU:
             RrImageUnref(self->data.submenu.icon);
@@ -597,12 +602,13 @@ void menu_entry_remove(ObMenuEntry *self)
 }
 
 ObMenuEntry* menu_add_normal(ObMenu *self, gint id, const gchar *label,
-                             GSList *actions, gboolean allow_shortcut)
+                             ObActionsList *actions, gboolean allow_shortcut)
 {
     ObMenuEntry *e;
 
     e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_NORMAL, id);
     e->data.normal.actions = actions;
+    actions_list_ref(actions);
 
     menu_entry_set_label(e, label, allow_shortcut);
 
index 7d719729bbbc88e0c1631317160b766c1d53a3d8..c20addb1ae8d11ca1f6379847441a6ed22de8d80 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <glib.h>
 
+struct _ObActionsList;
 struct _ObClient;
 struct _ObMenuFrame;
 struct _ObMenuEntryFrame;
@@ -120,8 +121,7 @@ struct _ObNormalMenuEntry {
     /* state */
     gboolean enabled;
 
-    /* List of ObActions */
-    GSList *actions;
+    struct _ObActionsList *actions;
 
     /* Mask icon */
     RrPixmapMask *mask;
@@ -209,7 +209,8 @@ void menu_set_place_func(ObMenu *menu, ObMenuPlaceFunc func);
 /*! @param allow_shortcut this should be false when the label is coming from
            outside data like window or desktop titles */
 ObMenuEntry* menu_add_normal(ObMenu *menu, gint id, const gchar *label,
-                             GSList *actions, gboolean allow_shortcut);
+                             struct _ObActionsList *actions,
+                             gboolean allow_shortcut);
 ObMenuEntry* menu_add_submenu(ObMenu *menu, gint id, const gchar *submenu);
 ObMenuEntry* menu_add_separator(ObMenu *menu, gint id, const gchar *label);
 
index 4887173b40c04ed1e8592011b38f2d4c9ed01e4b..ab3f3b9f6a7c7a53ed8e810f4511b387d6c45554 100644 (file)
@@ -22,6 +22,7 @@
 #include "menu.h"
 #include "screen.h"
 #include "actions.h"
+#include "actions_list.h"
 #include "event.h"
 #include "grab.h"
 #include "openbox.h"
@@ -1289,7 +1290,7 @@ void menu_entry_frame_execute(ObMenuEntryFrame *self, guint state)
         ObMenuEntry *entry = self->entry;
         ObMenuExecuteFunc func = self->frame->menu->execute_func;
         gpointer data = self->frame->menu->data;
-        GSList *acts = self->entry->data.normal.actions;
+        ObActionsList *acts = self->entry->data.normal.actions;
         ObClient *client = self->frame->client;
         ObMenuFrame *frame = self->frame;
         guint mods = obt_keyboard_only_modmasks(state);
index 2f0c8f59f70e3f39bffbb6070595d08d53995274..74b8b7603a5eb54ba1ae821fcf9582a357b7147f 100644 (file)
@@ -20,6 +20,7 @@
 #include "openbox.h"
 #include "config.h"
 #include "actions.h"
+#include "actions_list.h"
 #include "event.h"
 #include "client.h"
 #include "grab.h"
@@ -34,7 +35,7 @@
 typedef struct {
     guint state;
     guint button;
-    GSList *actions[OB_NUM_MOUSE_ACTIONS]; /* lists of Action pointers */
+    ObActionsList *actions[OB_NUM_MOUSE_ACTIONS];
 } ObMouseBinding;
 
 /* Array of GSList*s of ObMouseBinding*s. */
@@ -149,13 +150,8 @@ void mouse_unbind_all(void)
             ObMouseBinding *b = it->data;
             gint j;
 
-            for (j = 0; j < OB_NUM_MOUSE_ACTIONS; ++j) {
-                GSList *jt;
-
-                for (jt = b->actions[j]; jt; jt = g_slist_next(jt))
-                    actions_act_unref(jt->data);
-                g_slist_free(b->actions[j]);
-            }
+            for (j = 0; j < OB_NUM_MOUSE_ACTIONS; ++j)
+                actions_list_unref(b->actions[j]);
             g_slice_free(ObMouseBinding, b);
         }
         g_slist_free(bound_contexts[i]);
@@ -370,7 +366,7 @@ gboolean mouse_event(ObClient *client, XEvent *e)
 }
 
 gboolean mouse_bind(const gchar *buttonstr, ObFrameContext context,
-                    ObMouseAction mact, ObActionsAct *action)
+                    ObMouseAction mact, ObActionsList *actions)
 {
     guint state, button;
     ObMouseBinding *b;
@@ -386,7 +382,8 @@ gboolean mouse_bind(const gchar *buttonstr, ObFrameContext context,
     for (it = bound_contexts[context]; it; it = g_slist_next(it)) {
         b = it->data;
         if (b->state == state && b->button == button) {
-            b->actions[mact] = g_slist_append(b->actions[mact], action);
+            actions_list_ref(actions);
+            b->actions[mact] = actions_list_concat(b->actions[mact], actions);
             return TRUE;
         }
     }
@@ -395,7 +392,8 @@ gboolean mouse_bind(const gchar *buttonstr, ObFrameContext context,
     b = g_slice_new0(ObMouseBinding);
     b->state = state;
     b->button = button;
-    b->actions[mact] = g_slist_append(NULL, action);
+    b->actions[mact] = actions;
+    actions_list_ref(actions);
     bound_contexts[context] = g_slist_append(bound_contexts[context], b);
 
     return TRUE;
index de4c0eca05637bf101bc349c8104ea0bb1e0147d..b683cdf07e5046d549429cf5ec847dcd5d0fb340 100644 (file)
 
 #include <X11/Xlib.h>
 
-struct _ObActionsAct;
+struct _ObActionsList;
 
 void mouse_startup(gboolean reconfig);
 void mouse_shutdown(gboolean reconfig);
 
 gboolean mouse_bind(const gchar *buttonstr, ObFrameContext context,
-                    ObMouseAction mact, struct _ObActionsAct *action);
+                    ObMouseAction mact, struct _ObActionsList *actions);
 void mouse_unbind_all(void);
 
 gboolean mouse_event(struct _ObClient *client, XEvent *e);
index fbc01fdddd20739ab9ddb16b55b3ee2e87d46ad0..fdf1c02354e1d49d78fc23312b56b5b122efb1b6 100644 (file)
@@ -243,7 +243,7 @@ gint main(gint argc, gchar **argv)
                 /* parse/load user options */
                 if ((config_file &&
                      obt_xml_load_file(i, config_file, "openbox_config")) ||
-                    obt_xml_load_config_file(i, "openbox", "rc.xml",
+                    obt_xml_load_config_file(i, "openbox", "rc",
                                              "openbox_config"))
                 {
                     obt_xml_tree_from_root(i);