From 46ce9ff40b76e2be907eff2553f9530e6cf55491 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 3 Aug 2011 11:32:02 -0400 Subject: [PATCH] Add functions to ObClientSet to run a function on each client in the set, and add constness. Anything that doesnt change/destroy the given set takes a const ObClientSet*. --- openbox/client_set.c | 71 +++++++++++++++++++++++++++++++++++++++++--- openbox/client_set.h | 23 +++++++++++--- 2 files changed, 86 insertions(+), 8 deletions(-) diff --git a/openbox/client_set.c b/openbox/client_set.c index 5388d153..fde8bbef 100644 --- a/openbox/client_set.c +++ b/openbox/client_set.c @@ -88,7 +88,7 @@ static void foreach_clone(gpointer k, gpointer v, gpointer u) g_hash_table_insert(seth, &c->window, c); } -ObClientSet* client_set_clone(ObClientSet *a) +ObClientSet* client_set_clone(const ObClientSet *a) { ObClientSet *set; @@ -306,21 +306,84 @@ ObClientSet* client_set_expand(ObClientSet *set, ObClientSetExpandFunc f, return set; } -gboolean client_set_is_empty(ObClientSet *set) +gboolean client_set_is_empty(const ObClientSet *set) { if (set->all) return client_list == NULL; else return set->h == NULL; } -gboolean client_set_test_boolean(ObClientSet *set) +gboolean client_set_test_boolean(const ObClientSet *set) { if (set->all) return TRUE; else return set->h != NULL; } -gboolean client_set_contains(ObClientSet *set, struct _ObClient *c) +gboolean client_set_contains(const ObClientSet *set, struct _ObClient *c) { if (set->all) return TRUE; if (!set->h) return FALSE; return g_hash_table_lookup(set->h, &c->window) != NULL; } + +typedef struct { + union { + ObClientSetForeachFunc foreach; + ObClientSetRunFunc run; + } func; + const struct _ObActionListRun *run; + gpointer data; + gboolean running; +} ObClientSetForeachData; + +void foreach_func(gpointer k, gpointer v, gpointer u) +{ + const ObClientSetForeachData *const d = u; + if (!d->runnig) return; + d->runnig = d->func.foreach((ObClient*)v, d->data); +} + +void client_set_foreach(const ObClientSet *set, ObClientSetForeachFunc func, + gpointer data) +{ + g_return_if_fail(set != NULL); + + if (set->all) { + GList *it; + for (it = client_list; it; it = g_list_next(it)) + func(it->data, data); + } + else if (set->h) { + ObClientSetForeachData d; + d.func.foreach = func; + d.data = data; + d.running = TRUE; + g_hash_table_foreach(set->h, foreach_func, &d); + } +} + +void run_func(gpointer k, gpointer v, gpointer u) +{ + const ObClientSetForeachData *const d = u; + if (!d->running) return; + d->running = d->func.run((ObClient*)v, d->run, d->data); +} + +void client_set_run(const ObClientSet *set, const struct _ObActionListRun *run, + ObClientSetRunFunc func, gpointer data) +{ + g_return_if_fail(set != NULL); + + if (set->all) { + GList *it; + for (it = client_list; it; it = g_list_next(it)) + func(run, it->data, data); + } + else if (set->h) { + ObClientSetForeachData d; + d.func.run = func; + d.data = data; + d.run = run; + d.running = FALSE; + g_hash_table_foreach(set->h, run_func, &d); + } +} diff --git a/openbox/client_set.h b/openbox/client_set.h index 33474493..4a522d9c 100644 --- a/openbox/client_set.h +++ b/openbox/client_set.h @@ -19,11 +19,16 @@ #include struct _ObClient; +struct _ObActionListRun; typedef struct _ObClientSet ObClientSet; typedef gboolean (*ObClientSetReduceFunc)(struct _ObClient *c, gpointer data); typedef gboolean (*ObClientSetExpandFunc)(struct _ObClient *c, gpointer data); +typedef gboolean (*ObClientSetForeachFunc)(struct _ObClient *c, gpointer data); +typedef gboolean (*ObClientSetRunFunc)(struct _ObClient *c, + const struct _ObActionListRun *run, + gpointer data); /*! Returns a new set of clients without anything in it. */ ObClientSet* client_set_empty(void); @@ -33,7 +38,7 @@ ObClientSet* client_set_single(struct _ObClient *c); ObClientSet* client_set_all(void); /*! Returns an identical set to @a. */ -ObClientSet* client_set_clone(ObClientSet *a); +ObClientSet* client_set_clone(const ObClientSet *a); void client_set_destroy(ObClientSet *set); @@ -65,12 +70,22 @@ ObClientSet* client_set_expand(ObClientSet *set, ObClientSetExpandFunc f, gpointer data); /*! Returns TRUE if there is nothing in the set. */ -gboolean client_set_is_empty(ObClientSet *set); +gboolean client_set_is_empty(const ObClientSet *set); /*! Returns TRUE if there is someting in the set, or if it is the special "ALL" set, which contains all clients. Even when there are no clients present, this set returns TRUE. */ -gboolean client_set_test_boolean(ObClientSet *set); +gboolean client_set_test_boolean(const ObClientSet *set); /*! Returns TRUE if @set contains @c. */ -gboolean client_set_contains(ObClientSet *set, struct _ObClient *c); +gboolean client_set_contains(const ObClientSet *set, struct _ObClient *c); + +/*! Runs the given funcion on each client in the @set, passing the given + @data to the function along with the client. */ +void client_set_foreach(const ObClientSet *set, ObClientSetForeachFunc func, + gpointer data); + +/*! Runs the given funcion on each client in the @set, passing the given + @data to the function along with the client. */ +void client_set_run(const ObClientSet *set, const struct _ObActionListRun *run, + ObClientSetRunFunc func, gpointer data); -- 2.39.2