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"
25 void client_destroyed(ObClient *client, ObClientSet *set);
31 static ObClientSet* empty_set(void)
35 set = g_slice_new(ObClientSet);
36 set->h = g_hash_table_new(g_int_hash, g_int_equal);
37 client_add_destroy_notify((ObClientCallback)client_destroyed, set);
41 ObClientSet* client_set_single(void)
46 c = event_current_target();
49 g_hash_table_insert(set->h, &c->window, c);
53 /*! Returns a new set of clients with all possible client in it.*/
54 ObClientSet* client_set_all(void)
59 if (!client_list) return NULL;
60 set = g_slice_new(ObClientSet);
61 set->h = g_hash_table_new(g_int_hash, g_int_equal);
62 for (it = client_list; it; it = g_list_next(it)) {
63 ObClient *c = it->data;
64 g_hash_table_insert(set->h, &c->window, c);
66 client_add_destroy_notify((ObClientCallback)client_destroyed, set);
70 void client_destroyed(ObClient *client, ObClientSet *set)
72 g_hash_table_remove(set->h, &client->window);
75 void client_set_destroy(ObClientSet *set)
77 client_remove_destroy_notify_data((ObClientCallback)client_destroyed, set);
78 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_hash_table_foreach(b->h, foreach_union, a->h);
94 client_set_destroy(b);
98 static gboolean foreach_intersection(gpointer k, gpointer v, gpointer u)
101 return !g_hash_table_lookup(set, k); /* remove if not in the other set */
104 /* Returns a new set which contains all clients in both @a and @b. The sets
105 @a and @b are considered freed once passed to this function.
107 ObClientSet* client_set_intersection(ObClientSet *a, ObClientSet *b)
109 g_hash_table_foreach_remove(a->h, foreach_intersection, b->h);
110 client_set_destroy(b);
114 static gboolean foreach_reduce(gpointer k, gpointer v, gpointer u)
117 ObClientSetReduceFunc f = u;
121 ObClientSet* client_set_reduce(ObClientSet *set, ObClientSetReduceFunc f)
123 g_hash_table_foreach_remove(set->h, foreach_reduce, f);
124 if (g_hash_table_size(set->h) > 0)
126 client_set_destroy(set);
130 ObClientSet* client_set_expand(ObClientSet *set, ObClientSetExpandFunc f)
134 for (it = client_list; it; it = g_list_next(it)) {
135 ObClient *c = it->data;
136 if (!set || !g_hash_table_lookup(set->h, &c->window)) {
138 if (!set) set = empty_set();
139 g_hash_table_insert(set->h, &c->window, c);