]> icculus.org git repositories - dana/openbox.git/blob - openbox/action_filter.c
Rename ObActionValue to ObConfigValue. This holds one of three types.
[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 "action_list_run.h"
21 #include "client_set.h"
22 #include "gettext.h"
23
24 #include "filters/_all.h"
25
26 typedef struct _ObActionFilterDefinition ObActionFilterDefinition;
27
28 struct _ObActionFilterDefinition {
29     gchar *name;
30     ObActionFilterSetupFunc setup;
31     ObActionFilterDestroyFunc destroy;
32     ObActionFilterFunc set;
33 };
34
35 struct _ObActionFilter {
36     gint ref;
37
38     ObActionFilterDefinition *def;
39     gboolean invert;
40     gpointer data;
41 };
42
43 static void action_filter_unregister(ObActionFilterDefinition *def);
44
45 /*! Holds all registered filters. */
46 static GSList *registered = NULL;
47
48 void action_filter_startup(gboolean reconfig)
49 {
50     filters__all_startup();
51 }
52
53 void action_filter_shutdown(gboolean reconfig)
54 {
55     GSList *it;
56
57     for (it = registered; it; it = g_slist_next(it))
58         action_filter_unregister(it->data);
59     g_slist_free(it);
60 }
61
62 gboolean action_filter_register(const gchar *name,
63                                 ObActionFilterSetupFunc setup,
64                                 ObActionFilterDestroyFunc destroy,
65                                 ObActionFilterFunc set)
66 {
67     ObActionFilterDefinition *def;
68     GSList *it;
69
70     g_return_val_if_fail(name != NULL, FALSE);
71     g_return_val_if_fail(set != NULL, FALSE);
72
73     for (it = registered; it; it = it->next) {
74         def = it->data;
75         if (g_strcasecmp(name, def->name) == 0)
76             return FALSE; /* already registered */
77     }
78
79     def = g_slice_new(ObActionFilterDefinition);
80     def->name = g_strdup(name);
81     def->setup = setup;
82     def->destroy = destroy;
83     def->set = set;
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 _ObConfigValue *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->invert = invert;
126     filter->data = def->setup ? def->setup(invert, v) : NULL;
127     return filter;
128 }
129
130 void action_filter_ref(ObActionFilter *f)
131 {
132     if (f) ++f->ref;
133 }
134
135 void action_filter_unref(ObActionFilter *f)
136 {
137     if (f && --f->ref < 1) {
138         if (f->def->destroy) f->def->destroy(f->data);
139         g_slice_free(ObActionFilter, f);
140     }
141 }
142
143 struct _ObClientSet* action_filter_set(ObActionFilter *f,
144                                        const ObActionListRun *run)
145 {
146     return f->def->set(f->invert, run, f->data);
147 }