]> icculus.org git repositories - dana/openbox.git/blob - openbox/action_filter.c
Add a generic filter system similar to the action system (not connected to anything...
[dana/openbox.git] / openbox / action_filter.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3    action_filter.c for the Openbox window manager
4    Copyright (c) 2011        Dana Jansens
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    See the COPYING file for a copy of the GNU General Public License.
17 */
18
19 #include "action_filter.h"
20 #include "gettext.h"
21
22 typedef struct _ObActionFilterDefinition ObActionFilterDefinition;
23
24 struct _ObActionFilterDefinition {
25     gchar *name;
26     ObActionFilterSetupFunc setup;
27     ObActionFilterDestroyFunc destroy;
28     ObActionFilterReduceFunc reduce;
29     ObActionFilterExpandFunc expand;
30 };
31
32 struct _ObActionFilter {
33     gint ref;
34
35     ObActionFilterDefinition *def;
36     gpointer data;
37 };
38
39 static void action_filter_unregister(ObActionFilterDefinition *def);
40
41 /*! Holds all registered filters. */
42 static GSList *registered = NULL;
43
44 void action_filter_startup(gboolean reconfig)
45 {
46     //XXX filters_all_startup();
47 }
48
49 void action_filter_shutdown(gboolean reconfig)
50 {
51     GSList *it;
52
53     for (it = registered; it; it = g_slist_next(it))
54         action_filter_unregister(it->data);
55     g_slist_free(it);
56 }
57
58 gboolean action_filter_register(const gchar *name,
59                                 ObActionFilterSetupFunc setup,
60                                 ObActionFilterDestroyFunc destroy,
61                                 ObActionFilterReduceFunc reduce,
62                                 ObActionFilterExpandFunc expand)
63 {
64     ObActionFilterDefinition *def;
65     GSList *it;
66
67     g_return_val_if_fail(name != NULL, FALSE);
68     g_return_val_if_fail(setup != NULL, FALSE);
69     g_return_val_if_fail(reduce != NULL, FALSE);
70     g_return_val_if_fail(expand != NULL, FALSE);
71
72     for (it = registered; it; it = it->next) {
73         def = it->data;
74         if (g_strcasecmp(name, def->name) == 0)
75             return FALSE; /* already registered */
76     }
77
78     def = g_slice_new(ObActionFilterDefinition);
79     def->name = g_strdup(name);
80     def->setup = setup;
81     def->destroy = destroy;
82     def->reduce = reduce;
83     def->expand = expand;
84     registered = g_slist_prepend(registered, def);
85
86     return TRUE;
87 }
88
89 static void action_filter_unregister(ObActionFilterDefinition *def)
90 {
91     if (def) {
92         g_free(def->name);
93         g_slice_free(ObActionFilterDefinition, def);
94     }
95 }
96
97 ObActionFilter* action_filter_new(const gchar *key, struct _ObActionValue *v)
98 {
99     ObActionFilterDefinition *def;
100     ObActionFilter *filter;
101     GSList *it;
102     gboolean invert;
103
104     invert = FALSE;
105     if (key[0] == 'n' || key[0] == 'N')
106         if (key[1] == 'o' || key[1] == 'O') {
107             key += 2;
108             invert = TRUE;
109         }
110
111     for (it = registered; it; it = g_slist_next(it)) {
112         def = it->data;
113         if (g_strcasecmp(key, def->name) == 0)
114             break;
115     }
116     if (!it) {
117         g_message(_("Invalid filter \"%s\" requested. No such filter exists."),
118                   key);
119         return NULL;
120     }
121
122     filter = g_slice_new(ObActionFilter);
123     filter->ref = 1;
124     filter->def = def;
125     filter->data = def->setup(invert, v);
126     return filter;
127 }
128
129 void action_filter_ref(ObActionFilter *f)
130 {
131     if (f) ++f->ref;
132 }
133
134 void action_filter_unref(ObActionFilter *f)
135 {
136     if (f && --f->ref < 1) {
137         if (f->def->destroy) f->def->destroy(f->data);
138         g_slice_free(ObActionFilter, f);
139     }
140 }
141
142 void action_filter_expand(ObActionFilter *f, GHashTable *client_set)
143 {
144     g_return_if_fail(f != NULL);
145     g_return_if_fail(client_set != NULL);
146     return f->def->expand(client_set);
147 }
148
149 void action_filter_reduce(ObActionFilter *f, GHashTable *client_set)
150 {
151     g_return_if_fail(f != NULL);
152     g_return_if_fail(client_set != NULL);
153     return f->def->reduce(client_set);
154 }