]> icculus.org git repositories - dana/openbox.git/blob - openbox/action_filter.c
Make warnings about parse problems in .desktop files "debug" messages. Most people...
[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(registered);
60     registered = NULL;
61 }
62
63 gboolean action_filter_register(const gchar *name,
64                                 ObActionFilterSetupFunc setup,
65                                 ObActionFilterDestroyFunc destroy,
66                                 ObActionFilterFunc set)
67 {
68     ObActionFilterDefinition *def;
69     GSList *it;
70
71     g_return_val_if_fail(name != NULL, FALSE);
72     g_return_val_if_fail(set != NULL, FALSE);
73
74     for (it = registered; it; it = it->next) {
75         def = it->data;
76         if (g_strcasecmp(name, def->name) == 0)
77             return FALSE; /* already registered */
78     }
79
80     def = g_slice_new(ObActionFilterDefinition);
81     def->name = g_strdup(name);
82     def->setup = setup;
83     def->destroy = destroy;
84     def->set = set;
85     registered = g_slist_prepend(registered, def);
86
87     return TRUE;
88 }
89
90 static void action_filter_unregister(ObActionFilterDefinition *def)
91 {
92     if (def) {
93         g_free(def->name);
94         g_slice_free(ObActionFilterDefinition, def);
95     }
96 }
97
98 ObActionFilter* action_filter_new(const gchar *key, struct _ObConfigValue *v)
99 {
100     ObActionFilterDefinition *def;
101     ObActionFilter *filter;
102     GSList *it;
103     gboolean invert;
104
105     invert = FALSE;
106     if (key[0] == 'n' || key[0] == 'N')
107         if (key[1] == 'o' || key[1] == 'O') {
108             key += 2;
109             invert = TRUE;
110         }
111
112     for (it = registered; it; it = g_slist_next(it)) {
113         def = it->data;
114         if (g_strcasecmp(key, def->name) == 0)
115             break;
116     }
117     if (!it) {
118         g_message(_("Invalid filter \"%s\" requested. No such filter exists."),
119                   key);
120         return NULL;
121     }
122
123     filter = g_slice_new(ObActionFilter);
124     filter->ref = 1;
125     filter->def = def;
126     filter->invert = invert;
127     filter->data = def->setup ? def->setup(invert, v) : NULL;
128     return filter;
129 }
130
131 void action_filter_ref(ObActionFilter *f)
132 {
133     if (f) ++f->ref;
134 }
135
136 void action_filter_unref(ObActionFilter *f)
137 {
138     if (f && --f->ref < 1) {
139         if (f->def->destroy) f->def->destroy(f->data);
140         g_slice_free(ObActionFilter, f);
141     }
142 }
143
144 struct _ObClientSet* action_filter_set(ObActionFilter *f,
145                                        const ObActionListRun *run)
146 {
147     return f->def->set(f->invert, run, f->data);
148 }