Add a generic filter system similar to the action system (not connected to anything...
authorDana Jansens <danakj@orodu.net>
Thu, 28 Jul 2011 19:45:43 +0000 (15:45 -0400)
committerDana Jansens <danakj@orodu.net>
Sun, 16 Oct 2011 22:55:14 +0000 (18:55 -0400)
Makefile.am
openbox/action_filter.c [new file with mode: 0644]
openbox/action_filter.h [new file with mode: 0644]

index c9a42e032563c3ac203be49966e204abf52f4807..2a9e6d8cb86c1a9da95219ea6295417d3b1e590b 100644 (file)
@@ -236,6 +236,8 @@ openbox_openbox_SOURCES = \
        openbox/actions/unfocus.c \
        openbox/action.c \
        openbox/action.h \
+       openbox/action_filter.c \
+       openbox/action_filter.h \
        openbox/action_list.c \
        openbox/action_list.h \
        openbox/action_parser.c \
diff --git a/openbox/action_filter.c b/openbox/action_filter.c
new file mode 100644 (file)
index 0000000..bbeaa91
--- /dev/null
@@ -0,0 +1,154 @@
+/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
+
+   action_filter.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_filter.h"
+#include "gettext.h"
+
+typedef struct _ObActionFilterDefinition ObActionFilterDefinition;
+
+struct _ObActionFilterDefinition {
+    gchar *name;
+    ObActionFilterSetupFunc setup;
+    ObActionFilterDestroyFunc destroy;
+    ObActionFilterReduceFunc reduce;
+    ObActionFilterExpandFunc expand;
+};
+
+struct _ObActionFilter {
+    gint ref;
+
+    ObActionFilterDefinition *def;
+    gpointer data;
+};
+
+static void action_filter_unregister(ObActionFilterDefinition *def);
+
+/*! Holds all registered filters. */
+static GSList *registered = NULL;
+
+void action_filter_startup(gboolean reconfig)
+{
+    //XXX filters_all_startup();
+}
+
+void action_filter_shutdown(gboolean reconfig)
+{
+    GSList *it;
+
+    for (it = registered; it; it = g_slist_next(it))
+        action_filter_unregister(it->data);
+    g_slist_free(it);
+}
+
+gboolean action_filter_register(const gchar *name,
+                                ObActionFilterSetupFunc setup,
+                                ObActionFilterDestroyFunc destroy,
+                                ObActionFilterReduceFunc reduce,
+                                ObActionFilterExpandFunc expand)
+{
+    ObActionFilterDefinition *def;
+    GSList *it;
+
+    g_return_val_if_fail(name != NULL, FALSE);
+    g_return_val_if_fail(setup != NULL, FALSE);
+    g_return_val_if_fail(reduce != NULL, FALSE);
+    g_return_val_if_fail(expand != NULL, FALSE);
+
+    for (it = registered; it; it = it->next) {
+        def = it->data;
+        if (g_strcasecmp(name, def->name) == 0)
+            return FALSE; /* already registered */
+    }
+
+    def = g_slice_new(ObActionFilterDefinition);
+    def->name = g_strdup(name);
+    def->setup = setup;
+    def->destroy = destroy;
+    def->reduce = reduce;
+    def->expand = expand;
+    registered = g_slist_prepend(registered, def);
+
+    return TRUE;
+}
+
+static void action_filter_unregister(ObActionFilterDefinition *def)
+{
+    if (def) {
+        g_free(def->name);
+        g_slice_free(ObActionFilterDefinition, def);
+    }
+}
+
+ObActionFilter* action_filter_new(const gchar *key, struct _ObActionValue *v)
+{
+    ObActionFilterDefinition *def;
+    ObActionFilter *filter;
+    GSList *it;
+    gboolean invert;
+
+    invert = FALSE;
+    if (key[0] == 'n' || key[0] == 'N')
+        if (key[1] == 'o' || key[1] == 'O') {
+            key += 2;
+            invert = TRUE;
+        }
+
+    for (it = registered; it; it = g_slist_next(it)) {
+        def = it->data;
+        if (g_strcasecmp(key, def->name) == 0)
+            break;
+    }
+    if (!it) {
+        g_message(_("Invalid filter \"%s\" requested. No such filter exists."),
+                  key);
+        return NULL;
+    }
+
+    filter = g_slice_new(ObActionFilter);
+    filter->ref = 1;
+    filter->def = def;
+    filter->data = def->setup(invert, v);
+    return filter;
+}
+
+void action_filter_ref(ObActionFilter *f)
+{
+    if (f) ++f->ref;
+}
+
+void action_filter_unref(ObActionFilter *f)
+{
+    if (f && --f->ref < 1) {
+        if (f->def->destroy) f->def->destroy(f->data);
+        g_slice_free(ObActionFilter, f);
+    }
+}
+
+void action_filter_expand(ObActionFilter *f, GHashTable *client_set)
+{
+    g_return_if_fail(f != NULL);
+    g_return_if_fail(client_set != NULL);
+    return f->def->expand(client_set);
+}
+
+void action_filter_reduce(ObActionFilter *f, GHashTable *client_set)
+{
+    g_return_if_fail(f != NULL);
+    g_return_if_fail(client_set != NULL);
+    return f->def->reduce(client_set);
+}
diff --git a/openbox/action_filter.h b/openbox/action_filter.h
new file mode 100644 (file)
index 0000000..ff2e99a
--- /dev/null
@@ -0,0 +1,53 @@
+/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
+
+   action_filter.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 _ObActionValue;
+struct _ObClient;
+
+typedef struct _ObActionFilter ObActionFilter;
+typedef struct _ObActionFilterFuncs ObActionFilterFuncs;
+
+typedef gpointer (*ObActionFilterSetupFunc)(gboolean invert,
+                                            struct _ObActionValue *v);
+typedef void (*ObActionFilterDestroyFunc)(gpointer data);
+/*! Runs the filter and modifies the client set as appropriate.  This function
+  is given a set of clients and may simply remove clients that do not
+  match its criteria. */
+typedef void (*ObActionFilterReduceFunc)(GHashTable *client_set);
+/*! Runs the filter and creates a new client set as appropriate.  This function
+  is given a set of clients and must add all unlisted clients possible that
+  match its criteria. */
+typedef void (*ObActionFilterExpandFunc)(GHashTable *client_set);
+
+void action_filter_startup(gboolean reconfig);
+void action_filter_shutdown(gboolean reconfig);
+
+gboolean action_filter_register(const gchar *name,
+                                ObActionFilterSetupFunc setup,
+                                ObActionFilterDestroyFunc destroy,
+                                ObActionFilterReduceFunc reduce,
+                                ObActionFilterExpandFunc expand);
+
+ObActionFilter* action_filter_new(const gchar *key, struct _ObActionValue *v);
+void action_filter_ref(ObActionFilter *f);
+void action_filter_unref(ObActionFilter *f);
+
+void action_filter_expand(ObActionFilter *f, GHashTable *client_set);
+void action_filter_reduce(ObActionFilter *f, GHashTable *client_set);