From: Giulio Camuffo Date: Thu, 11 Aug 2016 15:23:10 +0000 (+0200) Subject: Add API to retrieve and iterate over the resources list of a client X-Git-Tag: 1.11.91~11 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2f617250d27ec3258071077997934c43948c384b;p=platform%2Fupstream%2Fwayland.git Add API to retrieve and iterate over the resources list of a client To complement on the new resource created signal, this allows to iterate over the existing resources of a client. Signed-off-by: Giulio Camuffo Reviewed-by: Jonas Ã…dahl [Pekka: added empty lines, init ret in for_each_helper()] Signed-off-by: Pekka Paalanen --- diff --git a/src/wayland-private.h b/src/wayland-private.h index adfbe01..ac712d9 100644 --- a/src/wayland-private.h +++ b/src/wayland-private.h @@ -75,7 +75,8 @@ struct wl_map { uint32_t free_list; }; -typedef void (*wl_iterator_func_t)(void *element, void *data); +typedef enum wl_iterator_result (*wl_iterator_func_t)(void *element, + void *data); void wl_map_init(struct wl_map *map, uint32_t side); diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h index bb0a989..56e8d80 100644 --- a/src/wayland-server-core.h +++ b/src/wayland-server-core.h @@ -216,6 +216,15 @@ void wl_client_add_resource_created_listener(struct wl_client *client, struct wl_listener *listener); +typedef enum wl_iterator_result (*wl_client_for_each_resource_iterator_func_t)( + struct wl_resource *resource, + void *user_data); + +void +wl_client_for_each_resource(struct wl_client *client, + wl_client_for_each_resource_iterator_func_t iterator, + void *user_data); + /** \class wl_listener * * \brief A single listener for Wayland signals diff --git a/src/wayland-server.c b/src/wayland-server.c index a396410..dd648ac 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -565,7 +565,7 @@ wl_resource_post_no_memory(struct wl_resource *resource) WL_DISPLAY_ERROR_NO_MEMORY, "no memory"); } -static void +static enum wl_iterator_result destroy_resource(void *element, void *data) { struct wl_resource *resource = element; @@ -580,6 +580,8 @@ destroy_resource(void *element, void *data) if (!(flags & WL_MAP_ENTRY_LEGACY)) free(resource); + + return WL_ITERATOR_CONTINUE; } WL_EXPORT void @@ -1604,6 +1606,52 @@ wl_client_add_resource_created_listener(struct wl_client *client, wl_signal_add(&client->resource_created_signal, listener); } +struct wl_resource_iterator_context { + void *user_data; + wl_client_for_each_resource_iterator_func_t it; +}; + +static enum wl_iterator_result +resource_iterator_helper(void *res, void *user_data) +{ + struct wl_resource_iterator_context *context = user_data; + struct wl_resource *resource = res; + + return context->it(resource, context->user_data); +} + +/** Iterate over all the resources of a client + * + * \param client The client object + * \param iterator The iterator function + * \param user_data The user data pointer + * + * The function pointed by \a iterator will be called for each + * resource owned by the client. The \a user_data will be passed + * as the second argument of the iterator function. + * If the \a iterator function returns \a WL_ITERATOR_CONTINUE the iteration + * will continue, if it returns \a WL_ITERATOR_STOP it will stop. + * + * Creating and destroying resources while iterating is safe, but new + * resources may or may not be picked up by the iterator. + * + * \sa wl_iterator_result + * + * \memberof wl_client + */ +WL_EXPORT void +wl_client_for_each_resource(struct wl_client *client, + wl_client_for_each_resource_iterator_func_t iterator, + void *user_data) +{ + struct wl_resource_iterator_context context = { + .user_data = user_data, + .it = iterator, + }; + + wl_map_for_each(&client->objects, resource_iterator_helper, &context); +} + /** \cond */ /* Deprecated functions below. */ uint32_t diff --git a/src/wayland-util.c b/src/wayland-util.c index 7467366..639ccf8 100644 --- a/src/wayland-util.c +++ b/src/wayland-util.c @@ -359,24 +359,33 @@ wl_map_lookup_flags(struct wl_map *map, uint32_t i) return 0; } -static void +static enum wl_iterator_result for_each_helper(struct wl_array *entries, wl_iterator_func_t func, void *data) { union map_entry *start, *end, *p; + enum wl_iterator_result ret = WL_ITERATOR_CONTINUE; start = entries->data; end = (union map_entry *) ((char *) entries->data + entries->size); for (p = start; p < end; p++) - if (p->data && !map_entry_is_free(*p)) - func(map_entry_get_data(*p), data); + if (p->data && !map_entry_is_free(*p)) { + ret = func(map_entry_get_data(*p), data); + if (ret != WL_ITERATOR_CONTINUE) + break; + } + + return ret; } WL_EXPORT void wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data) { - for_each_helper(&map->client_entries, func, data); - for_each_helper(&map->server_entries, func, data); + enum wl_iterator_result ret; + + ret = for_each_helper(&map->client_entries, func, data); + if (ret == WL_ITERATOR_CONTINUE) + for_each_helper(&map->server_entries, func, data); } static void diff --git a/src/wayland-util.h b/src/wayland-util.h index 8da156c..cacc122 100644 --- a/src/wayland-util.h +++ b/src/wayland-util.h @@ -311,6 +311,17 @@ typedef int (*wl_dispatcher_func_t)(const void *, void *, uint32_t, typedef void (*wl_log_func_t)(const char *, va_list) WL_PRINTF(1, 0); +/** \enum wl_iterator_result + * + * This enum represents the return value of an iterator function. + */ +enum wl_iterator_result { + /** Stop the iteration */ + WL_ITERATOR_STOP, + /** Continue the iteration */ + WL_ITERATOR_CONTINUE +}; + #ifdef __cplusplus } #endif