From: Dana Jansens Date: Thu, 28 Jul 2011 19:45:43 +0000 (-0400) Subject: Add a generic filter system similar to the action system (not connected to anything... X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=6484843712cedc7b39079d61eb9fa4a54865a28e;p=dana%2Fopenbox.git Add a generic filter system similar to the action system (not connected to anything yet) --- diff --git a/Makefile.am b/Makefile.am index c9a42e03..2a9e6d8c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 index 00000000..bbeaa91d --- /dev/null +++ b/openbox/action_filter.c @@ -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 index 00000000..ff2e99a4 --- /dev/null +++ b/openbox/action_filter.h @@ -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 + +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);