1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 client_set.c for the Openbox window manager
4 Copyright (c) 2011 Dana Jansens
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.
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.
16 See the COPYING file for a copy of the GNU General Public License.
19 #include "client_set.h"
30 static void client_destroyed(ObClient *client, ObClientSet *set)
32 g_hash_table_remove(set->h, &client->window);
35 ObClientSet* client_set_empty(void)
39 set = g_slice_new(ObClientSet);
42 client_add_destroy_notify((ObClientCallback)client_destroyed, set);
46 ObClientSet* client_set_single(void)
51 c = event_current_target();
53 set = g_slice_new(ObClientSet);
55 set->h = g_hash_table_new(g_int_hash, g_int_equal);
56 g_hash_table_insert(set->h, &c->window, c);
60 /*! Returns a new set of clients with all possible client in it.*/
61 ObClientSet* client_set_all(void)
65 if (!client_list) return NULL;
66 set = g_slice_new(ObClientSet);
72 void client_set_destroy(ObClientSet *set)
75 client_remove_destroy_notify_data((ObClientCallback)client_destroyed,
77 if (set->h) g_hash_table_destroy(set->h);
79 g_slice_free(ObClientSet, set);
82 static void foreach_union(gpointer k, gpointer v, gpointer u)
85 g_hash_table_insert(set, k, v); /* add everything in the other set */
88 /* Returns a new set which contains all clients in either @a or @b. The sets
89 @a and @b are considered freed once passed to this function.
91 ObClientSet* client_set_union(ObClientSet *a, ObClientSet *b)
93 g_return_val_if_fail(a != NULL, NULL);
94 g_return_val_if_fail(b != NULL, NULL);
97 client_set_destroy(b);
101 client_set_destroy(a);
105 client_set_destroy(a);
109 client_set_destroy(b);
113 g_hash_table_foreach(b->h, foreach_union, a->h);
114 client_set_destroy(b);
118 static gboolean foreach_intersection(gpointer k, gpointer v, gpointer u)
121 return !g_hash_table_lookup(set, k); /* remove if not in the other set */
124 /* Returns a new set which contains all clients in both @a and @b. The sets
125 @a and @b are considered freed once passed to this function.
127 ObClientSet* client_set_intersection(ObClientSet *a, ObClientSet *b)
129 g_return_val_if_fail(a != NULL, NULL);
130 g_return_val_if_fail(b != NULL, NULL);
133 client_set_destroy(a);
137 client_set_destroy(b);
141 client_set_destroy(b);
145 client_set_destroy(a);
149 g_hash_table_foreach_remove(a->h, foreach_intersection, b->h);
150 client_set_destroy(b);
154 struct ObClientSetForeachReduce {
155 ObClientSetReduceFunc f;
159 static gboolean foreach_reduce(gpointer k, gpointer v, gpointer u)
162 struct ObClientSetForeachReduce *d = u;
163 return d->f(c, d->data);
166 ObClientSet* client_set_reduce(ObClientSet *set, ObClientSetReduceFunc f,
169 struct ObClientSetForeachReduce d;
171 g_return_val_if_fail(set != NULL, NULL);
172 g_return_val_if_fail(f != NULL, NULL);
176 g_hash_table_foreach_remove(set->h, foreach_reduce, &d);
177 if (g_hash_table_size(set->h) == 0) {
178 g_hash_table_destroy(set->h);
184 ObClientSet* client_set_expand(ObClientSet *set, ObClientSetExpandFunc f,
189 g_return_val_if_fail(set != NULL, NULL);
190 g_return_val_if_fail(f != NULL, NULL);
192 for (it = client_list; it; it = g_list_next(it)) {
193 ObClient *c = it->data;
194 if (!set->h || !g_hash_table_lookup(set->h, &c->window))
197 set->h = g_hash_table_new(g_int_hash, g_int_equal);
198 g_hash_table_insert(set->h, &c->window, c);
204 gboolean client_set_is_empty(ObClientSet *set)
206 if (set->all) return client_list == NULL;
207 else return set->h == NULL;
210 gboolean client_set_test_boolean(ObClientSet *set)
212 if (set->all) return TRUE;
213 else return set->h != NULL;