From 5e8ec2cb781ba07341a5970b3e829cc59a8cf332 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 21 Jun 2007 23:17:45 +0000 Subject: [PATCH] maybe the new actions framework is kinda there now --- openbox/actions.c | 89 ++++++++++++++++++++++++++++++++++++++++------- openbox/actions.h | 39 ++++++++++++++++----- openbox/config.c | 5 +-- 3 files changed, 110 insertions(+), 23 deletions(-) diff --git a/openbox/actions.c b/openbox/actions.c index 48778faf..6cd1d1cc 100644 --- a/openbox/actions.c +++ b/openbox/actions.c @@ -17,18 +17,28 @@ */ #include "actions.h" +#include "gettext.h" -static void actions_unregister(ObActionsDefinition *def); +static void actions_definition_ref(ObActionsDefinition *def); +static void actions_definition_unref(ObActionsDefinition *def); struct _ObActionsDefinition { + guint ref; + gchar *name; - gboolean interactive; + gboolean allow_interactive; - ObActionsDataParseFunc parse; + ObActionsDataSetupFunc setup; ObActionsDataFreeFunc free; ObActionsRunFunc run; +}; + +struct _ObActionsAct { + guint ref; + + ObActionsDefinition *def; - gpointer action_data; + gpointer options; }; static GSList *registered = NULL; @@ -47,15 +57,14 @@ void actions_shutdown(gboolean reconfig) /* free all the registered actions */ while (registered) { - actions_unregister(registered->data); + actions_definition_unref(registered->data); registered = g_slist_delete_link(registered, registered); } } gboolean actions_register(const gchar *name, - gboolean interactive, + gboolean allow_interactive, ObActionsDataSetupFunc setup, - ObActionsDataParseFunc parse, ObActionsDataFreeFunc free, ObActionsRunFunc run) { @@ -69,20 +78,74 @@ gboolean actions_register(const gchar *name, } def = g_new(ObActionsDefinition, 1); + def->ref = 1; def->name = g_strdup(name); - def->interactive = interactive; - def->parse = parse; + def->allow_interactive = allow_interactive; + def->setup = setup; def->free = free; def->run = run; - def->action_data = setup(); return TRUE; } -static void actions_unregister(ObActionsDefinition *def) +static void actions_definition_ref(ObActionsDefinition *def) +{ + ++def->ref; +} + +static void actions_definition_unref(ObActionsDefinition *def) { - if (def) { - def->free(def->action_data); + if (def && --def->ref == 0) { g_free(def->name); g_free(def); } } + +ObActionsAct* actions_parse(ObParseInst *i, + xmlDocPtr doc, + xmlNodePtr node) +{ + GSList *it; + gchar *name; + ObActionsDefinition *def; + ObActionsAct *act = NULL; + + if (!parse_attr_string("name", node, &name)) return NULL; + + /* find the requested action */ + for (it = registered; it; it = g_slist_next(it)) { + def = it->data; + if (!g_ascii_strcasecmp(name, def->name)) + break; + } + + /* if we found the action */ + if (it != NULL) { + act = g_new(ObActionsAct, 1); + act->ref = 1; + act->def = def; + actions_definition_ref(act->def); + act->options = def->setup(i, doc, node->children); + } else + g_message(_("Invalid action '%s' requested. No such action exists."), + name); + + g_free(name); + + return act; +} + +void actions_act_ref(ObActionsAct *act) +{ + ++act->ref; +} + +void actions_act_unref(ObActionsAct *act) +{ + if (act && --act->ref == 0) { + /* free the action specific options */ + act->def->free(act->options); + /* unref the definition */ + actions_definition_unref(act->def); + g_free(act); + } +} diff --git a/openbox/actions.h b/openbox/actions.h index cb1d377f..ca152e28 100644 --- a/openbox/actions.h +++ b/openbox/actions.h @@ -22,6 +22,8 @@ #include typedef struct _ObActionsDefinition ObActionsDefinition; +typedef struct _ObActionsAct ObActionsAct; +typedef struct _ObActionsData ObActionsData; typedef struct _ObActionsAnyData ObActionsAnyData; typedef struct _ObActionsGlobalData ObActionsGlobalData; typedef struct _ObActionsClientData ObActionsClientData; @@ -34,13 +36,11 @@ typedef enum { OB_NUM_ACTIONS_INTERACTIVE_STATES } ObActionsInteractiveState; -typedef gpointer (*ObActionsDataSetupFunc)(); -typedef void (*ObActionsDataParseFunc)(gpointer action_data, - ObParseInst *i, +typedef gpointer (*ObActionsDataSetupFunc)(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node); -typedef void (*ObActionsDataFreeFunc)(gpointer action_data); -typedef void (*ObActionsRunFunc)(ObActionsAnyData *data, - gpointer action_data); +typedef void (*ObActionsDataFreeFunc)(gpointer options); +typedef void (*ObActionsRunFunc)(ObActionsData *data, + gpointer options); /* The theory goes: @@ -50,6 +50,12 @@ typedef void (*ObActionsRunFunc)(ObActionsAnyData *data, 06:11 (@dana) eg show menu/exit, raise/focus, and cycling/directional/expose */ +typedef enum { + OB_ACTION_TYPE_GLOBAL, + OB_ACTION_TYPE_CLIENT, + OB_ACTION_TYPE_SELECTOR +} ObActionsType; + struct _ObActionsAnyData { ObUserAction uact; gint x; @@ -77,12 +83,29 @@ struct _ObActionsSelectorData { GSList *actions; }; +struct _ObActionsData { + ObActionsType type; + + union { + ObActionsAnyData any; + ObActionsGlobalData global; + ObActionsClientData client; + ObActionsSelectorData selector; + }; +}; + void actions_startup(gboolean reconfigure); void actions_shutdown(gboolean reconfigure); gboolean actions_register(const gchar *name, - gboolean interactive, + gboolean allow_interactive, ObActionsDataSetupFunc setup, - ObActionsDataParseFunc parse, ObActionsDataFreeFunc free, ObActionsRunFunc run); + +ObActionsAct* actions_parse(ObParseInst *i, + xmlDocPtr doc, + xmlNodePtr node); + +void actions_act_ref(ObActionsAct *act); +void actions_act_unref(ObActionsAct *act); diff --git a/openbox/config.c b/openbox/config.c index 2eb8e13c..1f651ced 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -23,6 +23,7 @@ #include "prop.h" #include "translate.h" #include "client.h" +#include "actions.h" #include "screen.h" #include "parser/parse.h" #include "openbox.h" @@ -357,9 +358,9 @@ static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, } else if ((n = parse_find_node("action", node->children))) { while (n) { - ObAction *action; + ObActionsDefinition *action; - action = action_parse(i, doc, n, OB_USER_ACTION_KEYBOARD_KEY); + action = actions_parse(i, doc, n); if (action) keyboard_bind(keylist, action); n = parse_find_node("action", n->next); -- 2.39.2