From 15394e4b1f1ceab8639a8ba20053e69c80acb70d Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 5 Aug 2011 11:35:09 -0400 Subject: [PATCH] Rename ObActionValue to ObConfigValue. This holds one of three types. 1. A string 2. A list of other ObConfigValues 3. A list of actions (ObActionList). The string type can be returned in various ways such as int, enum, fraction, gravity coordiate. Provide a ways to save the ObConfigValue into a pointer. This lets you keep the value contained withing the ObConfigValue in a variable of its basic type. --- Makefile.am | 4 +- openbox/action_filter.c | 2 +- openbox/action_filter.h | 6 +- openbox/action_list.c | 1 - openbox/action_parser.c | 27 ++- openbox/action_value.c | 166 ---------------- openbox/action_value.h | 45 ----- openbox/actions/addremovedesktop.c | 8 +- openbox/actions/cyclewindows.c | 32 ++-- openbox/actions/debug.c | 8 +- openbox/actions/desktop.c | 18 +- openbox/actions/directionalwindows.c | 32 ++-- openbox/actions/execute.c | 26 +-- openbox/actions/exit.c | 8 +- openbox/actions/focus.c | 12 +- openbox/actions/growtoedge.c | 8 +- openbox/actions/layer.c | 8 +- openbox/actions/maximize.c | 8 +- openbox/actions/moverelative.c | 12 +- openbox/actions/moveresizeto.c | 30 +-- openbox/actions/movetoedge.c | 8 +- openbox/actions/resize.c | 8 +- openbox/actions/resizerelative.c | 20 +- openbox/actions/restart.c | 8 +- openbox/actions/showmenu.c | 8 +- openbox/config_value.c | 273 +++++++++++++++++++++++++++ openbox/config_value.h | 106 +++++++++++ 27 files changed, 529 insertions(+), 363 deletions(-) delete mode 100644 openbox/action_value.c delete mode 100644 openbox/action_value.h create mode 100644 openbox/config_value.c create mode 100644 openbox/config_value.h diff --git a/Makefile.am b/Makefile.am index ad173a93..9c1084d1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -248,8 +248,6 @@ openbox_openbox_SOURCES = \ openbox/action_list_run.h \ openbox/action_parser.c \ openbox/action_parser.h \ - openbox/action_value.c \ - openbox/action_value.h \ openbox/apps_menu.c \ openbox/apps_menu.h \ openbox/client.c \ @@ -264,6 +262,8 @@ openbox_openbox_SOURCES = \ openbox/client_set.h \ openbox/config.c \ openbox/config.h \ + openbox/config_value.c \ + openbox/config_value.h \ openbox/debug.c \ openbox/debug.h \ openbox/dock.c \ diff --git a/openbox/action_filter.c b/openbox/action_filter.c index 9401fe93..08276547 100644 --- a/openbox/action_filter.c +++ b/openbox/action_filter.c @@ -94,7 +94,7 @@ static void action_filter_unregister(ObActionFilterDefinition *def) } } -ObActionFilter* action_filter_new(const gchar *key, struct _ObActionValue *v) +ObActionFilter* action_filter_new(const gchar *key, struct _ObConfigValue *v) { ObActionFilterDefinition *def; ObActionFilter *filter; diff --git a/openbox/action_filter.h b/openbox/action_filter.h index 71375e31..6342f928 100644 --- a/openbox/action_filter.h +++ b/openbox/action_filter.h @@ -19,7 +19,7 @@ #include struct _ObActionListRun; -struct _ObActionValue; +struct _ObConfigValue; struct _ObClient; struct _ObClientSet; @@ -28,7 +28,7 @@ typedef struct _ObActionFilterFuncs ObActionFilterFuncs; typedef enum _ObActionFilterDefault ObActionFilterDefault; typedef gpointer (*ObActionFilterSetupFunc)(gboolean invert, - struct _ObActionValue *v); + struct _ObConfigValue *v); typedef void (*ObActionFilterDestroyFunc)(gpointer data); typedef struct _ObClientSet* (*ObActionFilterFunc)( gboolean invert, const struct _ObActionListRun *run, gpointer data); @@ -52,7 +52,7 @@ gboolean action_filter_register(const gchar *name, ObActionFilterDestroyFunc destroy, ObActionFilterFunc set); -ObActionFilter* action_filter_new(const gchar *key, struct _ObActionValue *v); +ObActionFilter* action_filter_new(const gchar *key, struct _ObConfigValue *v); void action_filter_ref(ObActionFilter *f); void action_filter_unref(ObActionFilter *f); diff --git a/openbox/action_list.c b/openbox/action_list.c index 30b46fed..f31e49ae 100644 --- a/openbox/action_list.c +++ b/openbox/action_list.c @@ -19,7 +19,6 @@ #include "action_list.h" #include "action.h" #include "action_filter.h" -#include "action_value.h" #include diff --git a/openbox/action_parser.c b/openbox/action_parser.c index 58094936..3c975b24 100644 --- a/openbox/action_parser.c +++ b/openbox/action_parser.c @@ -20,7 +20,7 @@ #include "action.h" #include "action_filter.h" #include "action_list.h" -#include "action_value.h" +#include "config_value.h" #include "gettext.h" #ifdef HAVE_STRING_H @@ -29,7 +29,6 @@ struct _ObActionList; struct _ObActionListTest; -struct _ObActionValue; #define SKIP " \t" #define IDENTIFIER_FIRST G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_" @@ -42,7 +41,7 @@ struct _ObActionList* parse_list(ObActionParser *p, struct _ObActionList* parse_action(ObActionParser *p, gboolean *e); struct _ObActionList* parse_filter(ObActionParser *p, gboolean *e); struct _ObActionListTest* parse_filter_test(ObActionParser *p, gboolean *e); -struct _ObActionValue* parse_value(ObActionParser *p, +struct _ObConfigValue* parse_value(ObActionParser *p, gboolean allow_actions, gboolean *e); gchar* parse_string(ObActionParser *p, guchar end, gboolean *e); @@ -219,7 +218,7 @@ ObActionList* parse_action(ObActionParser *p, gboolean *e) /* read the action's name */ name = g_strdup(p->scan->value.v_string); config = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, - (GDestroyNotify)action_value_unref); + (GDestroyNotify)config_value_unref); /* read the action's options key:value pairs */ t = g_scanner_peek_next_token(p->scan); @@ -232,7 +231,7 @@ ObActionList* parse_action(ObActionParser *p, gboolean *e) } else { gchar *key; - ObActionValue *value; + ObConfigValue *value; g_scanner_get_next_token(p->scan); /* eat the key */ t = g_scanner_peek_next_token(p->scan); /* check for ':' */ @@ -314,7 +313,7 @@ ObActionListTest* parse_filter_test(ObActionParser *p, gboolean *e) { GTokenType t; gchar *key; - ObActionValue *value; + ObConfigValue *value; gboolean and; ObActionFilter *filter; ObActionListTest *next; @@ -343,7 +342,7 @@ ObActionListTest* parse_filter_test(ObActionParser *p, gboolean *e) /* don't allow any errors (but value can be null if not present) */ if (*e) { g_free(key); - action_value_unref(value); + config_value_unref(value); return NULL; } @@ -356,7 +355,7 @@ ObActionListTest* parse_filter_test(ObActionParser *p, gboolean *e) } g_free(key); - action_value_unref(value); + config_value_unref(value); if (!filter) return NULL; @@ -392,25 +391,25 @@ ObActionListTest* parse_filter_test(ObActionParser *p, gboolean *e) } } -ObActionValue* parse_value(ObActionParser *p, +ObConfigValue* parse_value(ObActionParser *p, gboolean allow_actions, gboolean *e) { GTokenType t; - ObActionValue *v; + ObConfigValue *v; v = NULL; t = g_scanner_get_next_token(p->scan); if (t == G_TOKEN_IDENTIFIER) { - v = action_value_new_string(p->scan->value.v_string); + v = config_value_new_string(p->scan->value.v_string); } else if (t == '"') - v = action_value_new_string(parse_string(p, '"', e)); + v = config_value_new_string(parse_string(p, '"', e)); else if (t == '(') - v = action_value_new_string(parse_string(p, ')', e)); + v = config_value_new_string(parse_string(p, ')', e)); else if (t == '{' && allow_actions) { ObActionList *l = parse_list(p, '}', e); - if (l) v = action_value_new_action_list(l); + if (l) v = config_value_new_action_list(l); } else parse_error(p, G_TOKEN_NONE, _("Expected an option value"), e); diff --git a/openbox/action_value.c b/openbox/action_value.c deleted file mode 100644 index ed8d691a..00000000 --- a/openbox/action_value.c +++ /dev/null @@ -1,166 +0,0 @@ -/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- - - action_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 "action_value.h" -#include "action_list.h" -#include "geom.h" - -#include "stdlib.h" - -struct _ObActionValue { - gint ref; - enum { - OB_AV_STRING, - OB_AV_ACTIONLIST - } type; - union { - gchar *string; - gboolean boolean; - guint integer; - ObActionList *actions; - } v; -}; - -ObActionValue* action_value_new_string(const gchar *s) -{ - return action_value_new_string_steal(g_strdup(s)); -} - -ObActionValue* action_value_new_string_steal(gchar *s) -{ - ObActionValue *v = g_slice_new(ObActionValue); - v->ref = 1; - v->type = OB_AV_STRING; - v->v.string = s; - return v; -} - -ObActionValue* action_value_new_action_list(ObActionList *al) -{ - ObActionValue *v = g_slice_new(ObActionValue); - v->ref = 1; - v->type = OB_AV_ACTIONLIST; - v->v.actions = al; - action_list_ref(al); - return v; -} - -void action_value_ref(ObActionValue *v) -{ - ++v->ref; -} - -void action_value_unref(ObActionValue *v) -{ - if (v && --v->ref < 1) { - switch (v->type) { - case OB_AV_STRING: - g_free(v->v.string); - break; - case OB_AV_ACTIONLIST: - action_list_unref(v->v.actions); - break; - } - g_slice_free(ObActionValue, v); - } -} - -gboolean action_value_is_string(ObActionValue *v) -{ - return v->type == OB_AV_STRING; -} - -gboolean action_value_is_action_list(ObActionValue *v) -{ - return v->type == OB_AV_ACTIONLIST; -} - -const gchar* action_value_string(ObActionValue *v) -{ - g_return_val_if_fail(v->type == OB_AV_STRING, NULL); - return v->v.string; -} - -gboolean action_value_bool(ObActionValue *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 action_value_int(ObActionValue *v) -{ - gchar *s; - - g_return_val_if_fail(v->type == OB_AV_STRING, 0); - s = v->v.string; - return strtol(s, &s, 10); -} - -void action_value_fraction(ObActionValue *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 action_value_gravity_coord(ObActionValue *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); - } -} - -ObActionList* action_value_action_list(ObActionValue *v) -{ - g_return_val_if_fail(v->type == OB_AV_ACTIONLIST, NULL); - return v->v.actions; -} diff --git a/openbox/action_value.h b/openbox/action_value.h deleted file mode 100644 index 2a2fd9f0..00000000 --- a/openbox/action_value.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- - - action_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 - -struct _GravityCoord; -struct _ObActionList; - -typedef struct _ObActionValue ObActionValue; - -/*! Creates a new value by making a copy of the given string. */ -ObActionValue* action_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. */ -ObActionValue* action_value_new_string_steal(gchar *s); -/*! Creates a new value with a given actions list. */ -ObActionValue* action_value_new_action_list(struct _ObActionList *al); - -void action_value_ref(ObActionValue *v); -void action_value_unref(ObActionValue *v); - -gboolean action_value_is_string(ObActionValue *v); -gboolean action_value_is_action_list(ObActionValue *v); - -const gchar* action_value_string(ObActionValue *v); -gboolean action_value_bool(ObActionValue *v); -gint action_value_int(ObActionValue *v); -void action_value_fraction(ObActionValue *v, gint *numer, gint *denom); -void action_value_gravity_coord(ObActionValue *v, struct _GravityCoord *c); -struct _ObActionList* action_value_action_list(ObActionValue *v); diff --git a/openbox/actions/addremovedesktop.c b/openbox/actions/addremovedesktop.c index 708086b4..9883d5d0 100644 --- a/openbox/actions/addremovedesktop.c +++ b/openbox/actions/addremovedesktop.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/client_set.h" #include "openbox/screen.h" #include @@ -27,14 +27,14 @@ void action_addremovedesktop_startup(void) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); v = g_hash_table_lookup(config, "where"); - if (v && action_value_is_string(v)) { - const gchar *s = action_value_string(v); + if (v && config_value_is_string(v)) { + const gchar *s = config_value_string(v); if (!g_ascii_strcasecmp(s, "last")) o->current = FALSE; else if (!g_ascii_strcasecmp(s, "current")) diff --git a/openbox/actions/cyclewindows.c b/openbox/actions/cyclewindows.c index 3a0bd8a8..c2d39c92 100644 --- a/openbox/actions/cyclewindows.c +++ b/openbox/actions/cyclewindows.c @@ -2,7 +2,7 @@ #include "openbox/action_list.h" #include "openbox/action_list_run.h" #include "openbox/action_parser.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/client_set.h" #include "openbox/stacking.h" #include "openbox/window.h" @@ -68,7 +68,7 @@ static gpointer setup_func(GHashTable *config, ObActionICancelFunc *cancel, ObActionIPostFunc *post) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); @@ -76,11 +76,11 @@ static gpointer setup_func(GHashTable *config, o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_LIST; v = g_hash_table_lookup(config, "linear"); - if (v && action_value_is_string(v)) - o->linear = action_value_bool(v); + if (v && config_value_is_string(v)) + o->linear = config_value_bool(v); v = g_hash_table_lookup(config, "dialog"); - if (v && action_value_is_string(v)) { - const gchar *s = action_value_string(v); + if (v && config_value_is_string(v)) { + const gchar *s = config_value_string(v); if (g_strcasecmp(s, "none") == 0) o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_NONE; else if (g_strcasecmp(s, "no") == 0) @@ -89,21 +89,21 @@ static gpointer setup_func(GHashTable *config, o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_ICONS; } v = g_hash_table_lookup(config, "bar"); - if (v && action_value_is_string(v)) - o->bar = action_value_bool(v); + if (v && config_value_is_string(v)) + o->bar = config_value_bool(v); v = g_hash_table_lookup(config, "raise"); - if (v && action_value_is_string(v)) - o->raise = action_value_bool(v); + if (v && config_value_is_string(v)) + o->raise = config_value_bool(v); v = g_hash_table_lookup(config, "panels"); - if (v && action_value_is_string(v)) - o->dock_windows = action_value_bool(v); + if (v && config_value_is_string(v)) + o->dock_windows = config_value_bool(v); v = g_hash_table_lookup(config, "desktop"); - if (v && action_value_is_string(v)) - o->desktop_windows = action_value_bool(v); + if (v && config_value_is_string(v)) + o->desktop_windows = config_value_bool(v); v = g_hash_table_lookup(config, "finalactions"); - if (v && action_value_is_action_list(v)) { - o->actions = action_value_action_list(v); + if (v && config_value_is_action_list(v)) { + o->actions = config_value_action_list(v); action_list_ref(o->actions); } else { diff --git a/openbox/actions/debug.c b/openbox/actions/debug.c index 9f194958..90b57b66 100644 --- a/openbox/actions/debug.c +++ b/openbox/actions/debug.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/client_set.h" #include @@ -21,14 +21,14 @@ void action_debug_startup(void) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); v = g_hash_table_lookup(config, "string"); - if (v && action_value_is_string(v)) - o->str = g_strdup(action_value_string(v)); + if (v && config_value_is_string(v)) + o->str = g_strdup(config_value_string(v)); return o; } diff --git a/openbox/actions/desktop.c b/openbox/actions/desktop.c index b04ce3be..a5d231fe 100644 --- a/openbox/actions/desktop.c +++ b/openbox/actions/desktop.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/screen.h" #include "openbox/client.h" #include "openbox/client_set.h" @@ -73,7 +73,7 @@ static gpointer setup_func(GHashTable *config, ObActionICancelFunc *cancel, ObActionIPostFunc *post) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); @@ -84,8 +84,8 @@ static gpointer setup_func(GHashTable *config, o->u.rel.wrap = TRUE; v = g_hash_table_lookup(config, "to"); - if (v && action_value_is_string(v)) { - const gchar *s = action_value_string(v); + if (v && config_value_is_string(v)) { + const gchar *s = config_value_string(v); if (!g_ascii_strcasecmp(s, "last")) o->type = LAST; else if (!g_ascii_strcasecmp(s, "current")) @@ -127,8 +127,8 @@ static gpointer setup_func(GHashTable *config, } v = g_hash_table_lookup(config, "wrap"); - if (v && action_value_is_string(v)) - o->u.rel.wrap = action_value_bool(v); + if (v && config_value_is_string(v)) + o->u.rel.wrap = config_value_bool(v); return o; } @@ -159,7 +159,7 @@ static gpointer setup_send_func(GHashTable *config, ObActionICancelFunc *cancel, ObActionIPostFunc *post) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = setup_func(config, pre, input, cancel, post); @@ -167,8 +167,8 @@ static gpointer setup_send_func(GHashTable *config, o->follow = TRUE; v = g_hash_table_lookup(config, "follow"); - if (v && action_value_is_string(v)) - o->follow = action_value_bool(v); + if (v && config_value_is_string(v)) + o->follow = config_value_bool(v); if (o->type == RELATIVE && o->follow) { o->interactive = TRUE; diff --git a/openbox/actions/directionalwindows.c b/openbox/actions/directionalwindows.c index 17b57c0a..fcd3d109 100644 --- a/openbox/actions/directionalwindows.c +++ b/openbox/actions/directionalwindows.c @@ -2,7 +2,7 @@ #include "openbox/action_list.h" #include "openbox/action_list_run.h" #include "openbox/action_parser.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/client_set.h" #include "openbox/event.h" #include "openbox/stacking.h" @@ -55,7 +55,7 @@ void action_directionalwindows_startup(void) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); @@ -63,23 +63,23 @@ static gpointer setup_func(GHashTable *config) o->bar = TRUE; v = g_hash_table_lookup(config, "dialog"); - if (v && action_value_is_string(v)) - o->dialog = action_value_bool(v); + if (v && config_value_is_string(v)) + o->dialog = config_value_bool(v); v = g_hash_table_lookup(config, "bar"); - if (v && action_value_is_string(v)) - o->bar = action_value_bool(v); + if (v && config_value_is_string(v)) + o->bar = config_value_bool(v); v = g_hash_table_lookup(config, "raise"); - if (v && action_value_is_string(v)) - o->raise = action_value_bool(v); + if (v && config_value_is_string(v)) + o->raise = config_value_bool(v); v = g_hash_table_lookup(config, "panels"); - if (v && action_value_is_string(v)) - o->dock_windows = action_value_bool(v); + if (v && config_value_is_string(v)) + o->dock_windows = config_value_bool(v); v = g_hash_table_lookup(config, "desktop"); - if (v && action_value_is_string(v)) - o->desktop_windows = action_value_bool(v); + if (v && config_value_is_string(v)) + o->desktop_windows = config_value_bool(v); v = g_hash_table_lookup(config, "direction"); - if (v && action_value_is_string(v)) { - const gchar *s = action_value_string(v); + if (v && config_value_is_string(v)) { + const gchar *s = config_value_string(v); if (!g_ascii_strcasecmp(s, "north") || !g_ascii_strcasecmp(s, "up")) o->direction = OB_DIRECTION_NORTH; @@ -103,8 +103,8 @@ static gpointer setup_func(GHashTable *config) } v = g_hash_table_lookup(config, "finalactions"); - if (v && action_value_is_action_list(v)) { - o->actions = action_value_action_list(v); + if (v && config_value_is_action_list(v)) { + o->actions = config_value_action_list(v); action_list_ref(o->actions); } else { diff --git a/openbox/actions/execute.c b/openbox/actions/execute.c index e4f99dd2..3f02f2a7 100644 --- a/openbox/actions/execute.c +++ b/openbox/actions/execute.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/client.h" #include "openbox/client_set.h" #include "openbox/event.h" @@ -58,31 +58,31 @@ static void client_dest(ObClient *client, gpointer data) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); v = g_hash_table_lookup(config, "command"); - if (v && action_value_is_string(v)) - o->cmd = obt_paths_expand_tilde(action_value_string(v)); + if (v && config_value_is_string(v)) + o->cmd = obt_paths_expand_tilde(config_value_string(v)); v = g_hash_table_lookup(config, "prompt"); - if (v && action_value_is_string(v)) - o->prompt = g_strdup(action_value_string(v)); + if (v && config_value_is_string(v)) + o->prompt = g_strdup(config_value_string(v)); v = g_hash_table_lookup(config, "startupnotify"); - if (v && action_value_is_string(v) && action_value_bool(v)) { + if (v && config_value_is_string(v) && config_value_bool(v)) { o->sn = TRUE; v = g_hash_table_lookup(config, "name"); - if (v && action_value_is_string(v)) - o->sn_name = g_strdup(action_value_string(v)); + if (v && config_value_is_string(v)) + o->sn_name = g_strdup(config_value_string(v)); v = g_hash_table_lookup(config, "icon"); - if (v && action_value_is_string(v)) - o->sn_icon = g_strdup(action_value_string(v)); + if (v && config_value_is_string(v)) + o->sn_icon = g_strdup(config_value_string(v)); v = g_hash_table_lookup(config, "wmclass"); - if (v && action_value_is_string(v)) - o->sn_wmclass = g_strdup(action_value_string(v)); + if (v && config_value_is_string(v)) + o->sn_wmclass = g_strdup(config_value_string(v)); } return o; } diff --git a/openbox/actions/exit.c b/openbox/actions/exit.c index ae061e15..0236f0dc 100644 --- a/openbox/actions/exit.c +++ b/openbox/actions/exit.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/client_set.h" #include "openbox/openbox.h" #include "openbox/prompt.h" @@ -24,15 +24,15 @@ void action_exit_startup(void) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); o->prompt = TRUE; v = g_hash_table_lookup(config, "prompt"); - if (v && action_value_is_string(v)) - o->prompt = action_value_bool(v); + if (v && config_value_is_string(v)) + o->prompt = config_value_bool(v); return o; } diff --git a/openbox/actions/focus.c b/openbox/actions/focus.c index 64af985c..5b94829c 100644 --- a/openbox/actions/focus.c +++ b/openbox/actions/focus.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/event.h" #include "openbox/client.h" #include "openbox/client_set.h" @@ -25,18 +25,18 @@ void action_focus_startup(void) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); o->stop_int = TRUE; v = g_hash_table_lookup(config, "here"); - if (v && action_value_is_string(v)) - o->here = action_value_bool(v); + if (v && config_value_is_string(v)) + o->here = config_value_bool(v); v = g_hash_table_lookup(config, "stopInteractive"); - if (v && action_value_is_string(v)) - o->stop_int = action_value_bool(v); + if (v && config_value_is_string(v)) + o->stop_int = config_value_bool(v); return o; } diff --git a/openbox/actions/growtoedge.c b/openbox/actions/growtoedge.c index 55f6a90c..9e74fa08 100644 --- a/openbox/actions/growtoedge.c +++ b/openbox/actions/growtoedge.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/misc.h" #include "openbox/client.h" #include "openbox/client_set.h" @@ -29,7 +29,7 @@ void action_growtoedge_startup(void) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); @@ -37,8 +37,8 @@ static gpointer setup_func(GHashTable *config) o->shrink = FALSE; v = g_hash_table_lookup(config, "direction"); - if (v && action_value_is_string(v)) { - const gchar *s = action_value_string(v); + if (v && config_value_is_string(v)) { + const gchar *s = config_value_string(v); if (!g_ascii_strcasecmp(s, "north") || !g_ascii_strcasecmp(s, "up")) o->dir = OB_DIRECTION_NORTH; diff --git a/openbox/actions/layer.c b/openbox/actions/layer.c index 8da56446..a031c5cc 100644 --- a/openbox/actions/layer.c +++ b/openbox/actions/layer.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/client.h" #include "openbox/client_set.h" @@ -44,14 +44,14 @@ static gpointer setup_func_bottom(GHashTable *config) static gpointer setup_func_send(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); v = g_hash_table_lookup(config, "layer"); - if (v && action_value_is_string(v)) { - const gchar *s = action_value_string(v); + if (v && config_value_is_string(v)) { + const gchar *s = config_value_string(v); if (!g_ascii_strcasecmp(s, "above") || !g_ascii_strcasecmp(s, "top")) o->layer = 1; diff --git a/openbox/actions/maximize.c b/openbox/actions/maximize.c index 325a4fe4..6d594ee1 100644 --- a/openbox/actions/maximize.c +++ b/openbox/actions/maximize.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/client.h" #include "openbox/client_set.h" @@ -36,15 +36,15 @@ void action_maximize_startup(void) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); o->dir = BOTH; v = g_hash_table_lookup(config, "dir"); - if (v && action_value_is_string(v)) { - const gchar *s = action_value_string(v); + if (v && config_value_is_string(v)) { + const gchar *s = config_value_string(v); if (!g_ascii_strcasecmp(s, "vertical") || !g_ascii_strcasecmp(s, "vert")) o->dir = VERT; diff --git a/openbox/actions/moverelative.c b/openbox/actions/moverelative.c index 9a05bfcd..65274e3a 100644 --- a/openbox/actions/moverelative.c +++ b/openbox/actions/moverelative.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/client.h" #include "openbox/client_set.h" #include "openbox/screen.h" @@ -27,17 +27,17 @@ void action_moverelative_startup(void) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); v = g_hash_table_lookup(config, "x"); - if (v && action_value_is_string(v)) - action_value_fraction(v, &o->x, &o->x_denom); + if (v && config_value_is_string(v)) + config_value_fraction(v, &o->x, &o->x_denom); v = g_hash_table_lookup(config, "y"); - if (v && action_value_is_string(v)) - action_value_fraction(v, &o->y, &o->y_denom); + if (v && config_value_is_string(v)) + config_value_fraction(v, &o->y, &o->y_denom); return o; } diff --git a/openbox/actions/moveresizeto.c b/openbox/actions/moveresizeto.c index 03f1c75e..1dfa6063 100644 --- a/openbox/actions/moveresizeto.c +++ b/openbox/actions/moveresizeto.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/client.h" #include "openbox/client_set.h" #include "openbox/screen.h" @@ -37,7 +37,7 @@ void action_moveresizeto_startup(void) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); @@ -48,24 +48,24 @@ static gpointer setup_func(GHashTable *config) o->monitor = CURRENT_MONITOR; v = g_hash_table_lookup(config, "x"); - if (v && action_value_is_string(v)) - action_value_gravity_coord(v, &o->x); + if (v && config_value_is_string(v)) + config_value_gravity_coord(v, &o->x); v = g_hash_table_lookup(config, "y"); - if (v && action_value_is_string(v)) - action_value_gravity_coord(v, &o->y); + if (v && config_value_is_string(v)) + config_value_gravity_coord(v, &o->y); v = g_hash_table_lookup(config, "width"); - if (v && action_value_is_string(v)) - if (g_ascii_strcasecmp(action_value_string(v), "current") != 0) - action_value_fraction(v, &o->w, &o->w_denom); + if (v && config_value_is_string(v)) + if (g_ascii_strcasecmp(config_value_string(v), "current") != 0) + config_value_fraction(v, &o->w, &o->w_denom); v = g_hash_table_lookup(config, "height"); - if (v && action_value_is_string(v)) - if (g_ascii_strcasecmp(action_value_string(v), "current") != 0) - action_value_fraction(v, &o->h, &o->h_denom); + if (v && config_value_is_string(v)) + if (g_ascii_strcasecmp(config_value_string(v), "current") != 0) + config_value_fraction(v, &o->h, &o->h_denom); v = g_hash_table_lookup(config, "monitor"); - if (v && action_value_is_string(v)) { - const gchar *s = action_value_string(v); + if (v && config_value_is_string(v)) { + const gchar *s = config_value_string(v); if (g_ascii_strcasecmp(s, "current") != 0) { if (!g_ascii_strcasecmp(s, "all")) o->monitor = ALL_MONITORS; @@ -74,7 +74,7 @@ static gpointer setup_func(GHashTable *config) else if(!g_ascii_strcasecmp(s, "prev")) o->monitor = PREV_MONITOR; else - o->monitor = action_value_int(v) - 1; + o->monitor = config_value_int(v) - 1; } } diff --git a/openbox/actions/movetoedge.c b/openbox/actions/movetoedge.c index 5ff1def7..5d5f1eba 100644 --- a/openbox/actions/movetoedge.c +++ b/openbox/actions/movetoedge.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/misc.h" #include "openbox/client.h" #include "openbox/client_set.h" @@ -25,15 +25,15 @@ void action_movetoedge_startup(void) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); o->dir = OB_DIRECTION_NORTH; v = g_hash_table_lookup(config, "direction"); - if (v && action_value_is_string(v)) { - const gchar *s = action_value_string(v); + if (v && config_value_is_string(v)) { + const gchar *s = config_value_string(v); if (!g_ascii_strcasecmp(s, "north") || !g_ascii_strcasecmp(s, "up")) o->dir = OB_DIRECTION_NORTH; diff --git a/openbox/actions/resize.c b/openbox/actions/resize.c index 010aaba5..4cd0b0e4 100644 --- a/openbox/actions/resize.c +++ b/openbox/actions/resize.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/moveresize.h" #include "openbox/client.h" #include "openbox/client_set.h" @@ -28,14 +28,14 @@ void action_resize_startup(void) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); v = g_hash_table_lookup(config, "edge"); - if (v && action_value_is_string(v)) { - const gchar *s = action_value_string(v); + if (v && config_value_is_string(v)) { + const gchar *s = config_value_string(v); o->corner_specified = TRUE; if (!g_ascii_strcasecmp(s, "top")) diff --git a/openbox/actions/resizerelative.c b/openbox/actions/resizerelative.c index 933d0aa9..ef0eca74 100644 --- a/openbox/actions/resizerelative.c +++ b/openbox/actions/resizerelative.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/client.h" #include "openbox/client_set.h" #include "openbox/screen.h" @@ -31,23 +31,23 @@ void action_resizerelative_startup(void) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); v = g_hash_table_lookup(config, "left"); - if (v && action_value_is_string(v)) - action_value_fraction(v, &o->left, &o->left_denom); + if (v && config_value_is_string(v)) + config_value_fraction(v, &o->left, &o->left_denom); v = g_hash_table_lookup(config, "right"); - if (v && action_value_is_string(v)) - action_value_fraction(v, &o->right, &o->right_denom); + if (v && config_value_is_string(v)) + config_value_fraction(v, &o->right, &o->right_denom); v = g_hash_table_lookup(config, "top"); - if (v && action_value_is_string(v)) - action_value_fraction(v, &o->top, &o->top_denom); + if (v && config_value_is_string(v)) + config_value_fraction(v, &o->top, &o->top_denom); v = g_hash_table_lookup(config, "bottom"); - if (v && action_value_is_string(v)) - action_value_fraction(v, &o->bottom, &o->bottom_denom); + if (v && config_value_is_string(v)) + config_value_fraction(v, &o->bottom, &o->bottom_denom); return o; } diff --git a/openbox/actions/restart.c b/openbox/actions/restart.c index 3b5750f0..3f3b0124 100644 --- a/openbox/actions/restart.c +++ b/openbox/actions/restart.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/client_set.h" #include "openbox/openbox.h" #include "obt/paths.h" @@ -22,14 +22,14 @@ void action_restart_startup(void) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); v = g_hash_table_lookup(config, "command"); - if (v && action_value_is_string(v)) - o->cmd = obt_paths_expand_tilde(action_value_string(v)); + if (v && config_value_is_string(v)) + o->cmd = obt_paths_expand_tilde(config_value_string(v)); return o; } diff --git a/openbox/actions/showmenu.c b/openbox/actions/showmenu.c index 256751ef..91ff5de1 100644 --- a/openbox/actions/showmenu.c +++ b/openbox/actions/showmenu.c @@ -1,6 +1,6 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/action_value.h" +#include "openbox/config_value.h" #include "openbox/client_set.h" #include "openbox/menu.h" #include @@ -22,14 +22,14 @@ void action_showmenu_startup(void) static gpointer setup_func(GHashTable *config) { - ObActionValue *v; + ObConfigValue *v; Options *o; o = g_slice_new0(Options); v = g_hash_table_lookup(config, "menu"); - if (v && action_value_is_string(v)) - o->name = g_strdup(action_value_string(v)); + if (v && config_value_is_string(v)) + o->name = g_strdup(config_value_string(v)); return o; } diff --git a/openbox/config_value.c b/openbox/config_value.c new file mode 100644 index 00000000..4d74e3cd --- /dev/null +++ b/openbox/config_value.c @@ -0,0 +1,273 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + config_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 "config_value.h" +#include "action_list.h" +#include "geom.h" + +#include "stdlib.h" + +struct _ObConfigValue { + gint ref; + enum { + OB_CV_STRING, + OB_CV_LIST, + OB_CV_ACTION_LIST + } type; + union { + gchar *string; + GList *list; + ObActionList *actions; + } v; +}; + +void config_value_ref(ObConfigValue *v) +{ + ++v->ref; +} + +void config_value_unref(ObConfigValue *v) +{ + if (v && --v->ref < 1) { + switch (v->type) { + case OB_CV_STRING: + g_free(v->v.string); + break; + case OB_CV_LIST: { + GList *it; + for (it = v->v.list; it; it = g_list_next(it)) + config_value_unref(it->data); + g_list_free(v->v.list); + break; + } + case OB_CV_ACTION_LIST: + action_list_unref(v->v.actions); + break; + } + g_slice_free(ObConfigValue, v); + } +} + +/*************************** describer functions ***************************/ + +gboolean config_value_is_string(const ObConfigValue *v) +{ + g_return_val_if_fail(v != NULL, FALSE); + return v->type == OB_CV_STRING; +} + +gboolean config_value_is_list(const ObConfigValue *v) +{ + g_return_val_if_fail(v != NULL, FALSE); + return v->type == OB_CV_LIST; +} + +gboolean config_value_is_action_list(const ObConfigValue *v) +{ + g_return_val_if_fail(v != NULL, FALSE); + return v->type == OB_CV_ACTION_LIST; +} + +/**************************** pointer functions ****************************/ + +void config_value_copy_ptr(ObConfigValue *v, + ObConfigValueDataType type, + ObConfigValueDataPtr *p, + const ObConfigValueEnum e[]) +{ + switch (type) { + case OB_CONFIG_VALUE_STRING: + *p->string = config_value_string(v); + break; + case OB_CONFIG_VALUE_BOOLEAN: + *p->boolean = config_value_bool(v); + break; + case OB_CONFIG_VALUE_INTEGER: + *p->integer = config_value_int(v); + break; + case OB_CONFIG_VALUE_ENUM: + *p->enumeration = config_value_enum(v, e); + break; + case OB_CONFIG_VALUE_FRACTION: { + gint n, d; + config_value_fraction(v, &n, &d); + p->fraction->numer = n; + p->fraction->denom = d; + break; + } + case OB_CONFIG_VALUE_GRAVITY_COORD: { + GravityCoord c; + config_value_gravity_coord(v, &c); + *p->coord = c; + break; + } + case OB_CONFIG_VALUE_LIST: + *p->list = config_value_list(v); + break; + case OB_CONFIG_VALUE_ACTIONLIST: + *p->actions = config_value_action_list(v); + break; + case NUM_OB_CONFIG_VALUE_TYPES: + default: + g_assert_not_reached(); + } +} + + +/***************************** getter functions ****************************/ + +const gchar* config_value_string(ObConfigValue *v) +{ + g_return_val_if_fail(v != NULL, NULL); + g_return_val_if_fail(config_value_is_string(v), NULL); + return v->v.string; +} +gboolean config_value_bool(ObConfigValue *v) +{ + g_return_val_if_fail(v != NULL, FALSE); + g_return_val_if_fail(config_value_is_string(v), FALSE); + return (g_strcasecmp(v->v.string, "true") == 0 || + g_strcasecmp(v->v.string, "yes") == 0); +} +guint config_value_int(ObConfigValue *v) +{ + gchar *s; + g_return_val_if_fail(v != NULL, FALSE); + g_return_val_if_fail(config_value_is_string(v), FALSE); + s = v->v.string; + return strtol(s, &s, 10); +} +guint config_value_enum(ObConfigValue *v, const ObConfigValueEnum choices[]) +{ + const ObConfigValueEnum *e; + + g_return_val_if_fail(v != NULL, (guint)-1); + g_return_val_if_fail(config_value_is_string(v), (guint)-1); + g_return_val_if_fail(choices != NULL, (guint)-1); + + for (e = choices; e->name; ++e) + if (g_strcasecmp(v->v.string, e->name) == 0) + return e->value; + return (guint)-1; +} +void config_value_fraction(ObConfigValue *v, gint *numer, gint *denom) +{ + gchar *s; + + *numer = *denom = 0; + + g_return_if_fail(v != NULL); + g_return_if_fail(config_value_is_string(v)); + + s = v->v.string; + *numer = strtol(s, &s, 10); + if (*s == '%') + *denom = 100; + else if (*s == '/') + *denom = atoi(s+1); + else + *denom = 0; +} +void config_value_gravity_coord(ObConfigValue *v, GravityCoord *c) +{ + gchar *s; + + c->center = FALSE; + c->pos = 0; + c->denom = 0; + + g_return_if_fail(v != NULL); + g_return_if_fail(config_value_is_string(v)); + + 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); + } +} +GList* config_value_list(ObConfigValue *v) +{ + g_return_val_if_fail(v != NULL, NULL); + g_return_val_if_fail(config_value_is_list(v), NULL); + return v->v.list; +} +ObActionList* config_value_action_list(ObConfigValue *v) +{ + g_return_val_if_fail(v != NULL, NULL); + g_return_val_if_fail(config_value_is_action_list(v), NULL); + return v->v.actions; +} + +/****************************** constructors ******************************/ + +ObConfigValue* config_value_new_string(const gchar *s) +{ + g_return_val_if_fail(s != NULL, NULL); + return config_value_new_string_steal(g_strdup(s)); +} + +ObConfigValue* config_value_new_string_steal(gchar *s) +{ + ObConfigValue *v; + g_return_val_if_fail(s != NULL, NULL); + v = g_slice_new(ObConfigValue); + v->ref = 1; + v->type = OB_CV_STRING; + v->v.string = s; + return v; +} + +ObConfigValue* config_value_new_list(GList *list) +{ + GList *c = g_list_copy(list); + GList *it; + + for (it = c; it; it = g_list_next(it)) + config_value_ref(it->data); + return config_value_new_list_steal(c); +} + +ObConfigValue* config_value_new_list_steal(GList *list) +{ + ObConfigValue *v = g_slice_new(ObConfigValue); + v->ref = 1; + v->type = OB_CV_LIST; + v->v.list = list; + return v; +} + +ObConfigValue* config_value_new_action_list(ObActionList *al) +{ + ObConfigValue *v = g_slice_new(ObConfigValue); + v->ref = 1; + v->type = OB_CV_ACTION_LIST; + v->v.actions = al; + action_list_ref(al); + return v; +} diff --git a/openbox/config_value.h b/openbox/config_value.h new file mode 100644 index 00000000..f2f92265 --- /dev/null +++ b/openbox/config_value.h @@ -0,0 +1,106 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + config_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 "geom.h" + +#include + +struct _GravityCoord; +struct _ObActionList; + +typedef struct _ObConfigValue ObConfigValue; +typedef struct _ObConfigValueEnum ObConfigValueEnum; + +struct _ObConfigValueEnum { + const gchar *name; + guint value; +}; + +typedef enum { + OB_CONFIG_VALUE_STRING, + OB_CONFIG_VALUE_BOOLEAN, + OB_CONFIG_VALUE_ENUM, + OB_CONFIG_VALUE_INTEGER, + OB_CONFIG_VALUE_FRACTION, + OB_CONFIG_VALUE_GRAVITY_COORD, + OB_CONFIG_VALUE_LIST, + OB_CONFIG_VALUE_ACTIONLIST, + NUM_OB_CONFIG_VALUE_TYPES +} ObConfigValueDataType; + +/*! This holds a pointer to one of the possible types in ObConfigValueType. */ +typedef union { + const gpointer *pointer; /*!< Generic pointer */ + const gchar **string; + gboolean *boolean; + guint *integer; + guint *enumeration; + struct { + guint numer; + guint denom; + } *fraction; + GravityCoord *coord; + const GList **list; /*!< A list of ObConfigValue objects */ + struct _ObActionList **actions; +} ObConfigValueDataPtr; + +void config_value_ref(ObConfigValue *v); +void config_value_unref(ObConfigValue *v); + +/*! Creates a new value by making a copy of the given string. */ +ObConfigValue* config_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. */ +ObConfigValue* config_value_new_string_steal(gchar *s); + +/*! Creates a config value which holds a list of other values + This function copies the list and adds a refcount to the values within. */ +ObConfigValue* config_value_new_list(GList *list); +/*! Creates a config value which holds a list of other values. + This function steals ownership the list and the values within. */ +ObConfigValue* config_value_new_list_steal(GList *list); +ObConfigValue* config_value_new_action_list(struct _ObActionList *al); + +gboolean config_value_is_string(const ObConfigValue *v); +gboolean config_value_is_list(const ObConfigValue *v); +gboolean config_value_is_action_list(const ObConfigValue *v); + +/*! Copies the data inside @v to the destination that the pointer @p is + pointing to. */ +void config_value_copy_ptr(ObConfigValue *v, + ObConfigValueDataType type, + ObConfigValueDataPtr *p, + const ObConfigValueEnum e[]); + +/* These ones are valid on a string value */ + +const gchar* config_value_string(ObConfigValue *v); +gboolean config_value_bool(ObConfigValue *v); +guint config_value_int(ObConfigValue *v); +/*! returns (guint)-1 if an error */ +guint config_value_enum(ObConfigValue *v, const ObConfigValueEnum e[]); +void config_value_fraction(ObConfigValue *v, gint *numer, gint *denom); +void config_value_gravity_coord(ObConfigValue *v, struct _GravityCoord *c); + +/* These ones are valid on a list value */ + +GList* config_value_list(ObConfigValue *v); + +/* These ones are value on a action list value */ + +struct _ObActionList* config_value_action_list(ObConfigValue *v); -- 2.34.1