From 8a200aa3619a2dc8b4d7cc1596a30be7e9f32c79 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 8 Aug 2017 19:26:41 +0200 Subject: [PATCH] move global to separate file --- src/pipewire/client.h | 53 ++++++---- src/pipewire/core.c | 211 +-------------------------------------- src/pipewire/core.h | 68 +------------ src/pipewire/global.h | 107 ++++++++++++++++++++ src/pipewire/meson.build | 2 + 5 files changed, 148 insertions(+), 293 deletions(-) create mode 100644 src/pipewire/global.h diff --git a/src/pipewire/client.h b/src/pipewire/client.h index e5f7913d0..79460dbf7 100644 --- a/src/pipewire/client.h +++ b/src/pipewire/client.h @@ -112,32 +112,43 @@ struct pw_client_events { /** Create a new client. This is mainly used by protocols. */ struct pw_client * -pw_client_new(struct pw_core *core, - struct pw_global *parent, - struct ucred *ucred, - struct pw_properties *properties, - size_t user_data_size); +pw_client_new(struct pw_core *core, /**< the core object */ + struct pw_global *parent, /**< the client parent */ + struct ucred *ucred, /**< optional ucred */ + struct pw_properties *properties, /**< client properties */ + size_t user_data_size /**< extra user data size */); +/** Destroy a previously created client */ void pw_client_destroy(struct pw_client *client); -const struct pw_client_info *pw_client_get_info(struct pw_client *client); - -void pw_client_update_properties(struct pw_client *client, const struct spa_dict *dict); - -const struct pw_properties *pw_client_get_properties(struct pw_client *client); - -struct pw_core *pw_client_get_core(struct pw_client *client); - -struct pw_resource *pw_client_get_core_resource(struct pw_client *client); - -struct pw_resource *pw_client_get_resource(struct pw_client *client, uint32_t id); - -struct pw_global *pw_client_get_global(struct pw_client *client); - -const struct ucred *pw_client_get_ucred(struct pw_client *client); - +/** Get the client user data */ void *pw_client_get_user_data(struct pw_client *client); +/** Get the client information */ +const struct pw_client_info *pw_client_get_info(struct pw_client *client); + +/** Update the client properties */ +void pw_client_update_properties(struct pw_client *client, const struct spa_dict *dict); + +/** Get the client properties */ +const struct pw_properties *pw_client_get_properties(struct pw_client *client); + +/** Get the core used to create this client */ +struct pw_core *pw_client_get_core(struct pw_client *client); + +/** Get the client core resource */ +struct pw_resource *pw_client_get_core_resource(struct pw_client *client); + +/** Get a resource with the given id */ +struct pw_resource *pw_client_get_resource(struct pw_client *client, uint32_t id); + +/** Get the global associated with this client */ +struct pw_global *pw_client_get_global(struct pw_client *client); + +/** Get the ucred from a client or NULL when not specified/valid */ +const struct ucred *pw_client_get_ucred(struct pw_client *client); + +/** listen to events from this client */ void pw_client_add_listener(struct pw_client *client, struct spa_hook *listener, const struct pw_client_events *events, diff --git a/src/pipewire/core.c b/src/pipewire/core.c index e517805b8..8f07fbdcd 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -31,39 +31,12 @@ #include /** \cond */ -struct global_impl { - struct pw_global this; -}; - struct resource_data { struct spa_hook resource_listener; }; /** \endcond */ -static inline uint32_t pw_global_permissions(struct pw_global *global, - struct pw_client *client) -{ - struct pw_core *core = client->core; - - if (core->permission_func == NULL) - return PW_PERM_RWX; - - return core->permission_func(global, client, core->permission_data); -} - -#define PW_PERM_IS_R(p) (((p)&PW_PERM_R) == PW_PERM_R) - -static struct pw_global *find_global(struct pw_core *core, uint32_t id) -{ - struct pw_global *global; - spa_list_for_each(global, &core->global_list, link) { - if (global->id == id) - return global; - } - return NULL; -} - static void registry_bind(void *object, uint32_t id, uint32_t type, uint32_t version, uint32_t new_id) { @@ -73,10 +46,10 @@ static void registry_bind(void *object, uint32_t id, struct pw_global *global; uint32_t permissions; - if ((global = find_global(core, id)) == 0) + if ((global = pw_core_find_global(core, id)) == NULL) goto no_id; - permissions = pw_global_permissions(global, client); + permissions = pw_global_get_permissions(global, client); if (!PW_PERM_IS_R(permissions)) goto no_id; @@ -166,7 +139,7 @@ static void core_get_registry(void *object, uint32_t version, uint32_t new_id) spa_list_insert(this->registry_resource_list.prev, ®istry_resource->link); spa_list_for_each(global, &this->global_list, link) { - uint32_t permissions = pw_global_permissions(global, client); + uint32_t permissions = pw_global_get_permissions(global, client); if (PW_PERM_IS_R(permissions)) { pw_registry_resource_global(registry_resource, global->id, @@ -440,76 +413,6 @@ void pw_core_destroy(struct pw_core *core) free(core); } -/** Create and add a new global to the core - * - * \param core a core - * \param owner an optional owner of the global - * \param type the type of the global - * \param n_ifaces number of interfaces - * \param ifaces interface information - * \param object the associated object - * \param bind a function to bind to this global - * \param[out] global a result global - * \return true on success - * - * \memberof pw_core - */ -struct pw_global * -pw_core_add_global(struct pw_core *core, - struct pw_client *owner, - struct pw_global *parent, - uint32_t type, - uint32_t version, - pw_bind_func_t bind, - void *object) -{ - struct global_impl *impl; - struct pw_global *this; - struct pw_resource *registry; - - impl = calloc(1, sizeof(struct global_impl)); - if (impl == NULL) - return NULL; - - this = &impl->this; - - this->core = core; - this->owner = owner; - this->type = type; - this->version = version; - this->bind = bind; - this->object = object; - - this->id = pw_map_insert_new(&core->globals, this); - - if (owner) - parent = owner->global; - if (parent == NULL) - parent = core->global; - if (parent == NULL) - parent = this; - this->parent = parent; - - spa_list_insert(core->global_list.prev, &this->link); - - spa_hook_list_call(&core->listener_list, struct pw_core_events, global_added, this); - - pw_log_debug("global %p: new %u %s, owner %p", this, this->id, - spa_type_map_get_type(core->type.map, this->type), owner); - - spa_list_for_each(registry, &core->registry_resource_list, link) { - uint32_t permissions = pw_global_permissions(this, registry->client); - if (PW_PERM_IS_R(permissions)) - pw_registry_resource_global(registry, - this->id, - this->parent->id, - permissions, - this->type, - this->version); - } - return this; -} - const struct pw_core_info *pw_core_get_info(struct pw_core *core) { return &core->info; @@ -520,114 +423,6 @@ struct pw_global *pw_core_get_global(struct pw_core *core) return core->global; } -struct pw_core *pw_global_get_core(struct pw_global *global) -{ - return global->core; -} - - -struct pw_client *pw_global_get_owner(struct pw_global *global) -{ - return global->owner; -} - -struct pw_global *pw_global_get_parent(struct pw_global *global) -{ - return global->parent; -} - -uint32_t pw_global_get_type(struct pw_global *global) -{ - return global->type; -} - -uint32_t pw_global_get_version(struct pw_global *global) -{ - return global->version; -} - -void * pw_global_get_object(struct pw_global *global) -{ - return global->object; -} - -uint32_t pw_global_get_id(struct pw_global *global) -{ - return global->id; -} - -/** Bind to a global - * - * \param global the global to bind to - * \param client the client that binds - * \param version the version - * \param id the id - * - * Let \a client bind to \a global with the given version and id. - * After binding, the client and the global object will be able to - * exchange messages. - * - * \memberof pw_global - */ -int -pw_global_bind(struct pw_global *global, struct pw_client *client, uint32_t permissions, - uint32_t version, uint32_t id) -{ - int res; - - if (global->bind == NULL) - goto no_bind; - - if (global->version < version) - goto wrong_version; - - res = global->bind(global, client, permissions, version, id); - - return res; - - wrong_version: - res = SPA_RESULT_INCOMPATIBLE_VERSION; - pw_core_resource_error(client->core_resource, - client->core_resource->id, - res, "id %d: interface version %d < %d", - id, global->version, version); - return res; - no_bind: - res = SPA_RESULT_NOT_IMPLEMENTED; - pw_core_resource_error(client->core_resource, - client->core_resource->id, - res, "can't bind object id %d to interface", id); - return res; -} - -/** Destroy a global - * - * \param global a global to destroy - * - * \memberof pw_global - */ -void pw_global_destroy(struct pw_global *global) -{ - struct pw_core *core = global->core; - struct pw_resource *registry; - - pw_log_debug("global %p: destroy %u", global, global->id); - - spa_list_for_each(registry, &core->registry_resource_list, link) { - uint32_t permissions = pw_global_permissions(global, registry->client); - if (PW_PERM_IS_R(permissions)) - pw_registry_resource_global_remove(registry, global->id); - } - - pw_map_remove(&core->globals, global->id); - - spa_list_remove(&global->link); - spa_hook_list_call(&core->listener_list, struct pw_core_events, global_removed, global); - - pw_log_debug("global %p: free", global); - free(global); -} - void pw_core_add_listener(struct pw_core *core, struct spa_hook *listener, const struct pw_core_events *events, diff --git a/src/pipewire/core.h b/src/pipewire/core.h index fb6638f02..a4f7508ea 100644 --- a/src/pipewire/core.h +++ b/src/pipewire/core.h @@ -27,8 +27,6 @@ extern "C" { #include #include -struct pw_global; - /** \class pw_core * * \brief the core PipeWire object @@ -42,6 +40,7 @@ struct pw_core; #include #include +#include #include #include #include @@ -100,11 +99,6 @@ struct pw_core; * emit events to the client and lets the client invoke methods on * the object. */ -typedef int (*pw_bind_func_t) (struct pw_global *global, /**< the global to bind */ - struct pw_client *client, /**< client that binds */ - uint32_t permissions, /**< permissions for the bind */ - uint32_t version, /**< client interface version */ - uint32_t id); /**< client proxy id */ #define PW_PERM_R 0400 /**< object can be seen and events can be received */ #define PW_PERM_W 0200 /**< methods can be called that modify the object */ @@ -114,29 +108,9 @@ typedef int (*pw_bind_func_t) (struct pw_global *global, /**< the global to bind typedef uint32_t (*pw_permission_func_t) (struct pw_global *global, struct pw_client *client, void *data); -/** \page page_global Global - * - * Global objects represent resources that are available on the server and - * accessible to clients. - * Globals come and go when devices or other resources become available for - * clients. - * - * The client receives a list of globals when it binds to the registry - * object. See \ref page_registry. - * - * A client can bind to a global to send methods or receive events from - * the global. - */ -/** \class pw_global - * - * \brief A global object visible to all clients - * - * A global object is visible to all clients and represents a resource - * that can be used or inspected. - * - * See \ref page_server_api - */ -struct pw_global; +#define PW_PERM_IS_R(p) (((p)&PW_PERM_R) == PW_PERM_R) +#define PW_PERM_IS_W(p) (((p)&PW_PERM_W) == PW_PERM_W) +#define PW_PERM_IS_X(p) (((p)&PW_PERM_X) == PW_PERM_X) struct pw_core_events { #define PW_VERSION_CORE_EVENTS 0 @@ -184,42 +158,8 @@ bool pw_core_for_each_global(struct pw_core *core, bool (*callback) (void *data, struct pw_global *global), void *data); -struct pw_global * -pw_core_add_global(struct pw_core *core, - struct pw_client *owner, - struct pw_global *parent, - uint32_t type, - uint32_t version, - pw_bind_func_t bind, - void *object); - struct pw_global *pw_core_find_global(struct pw_core *core, uint32_t id); - -struct pw_core *pw_global_get_core(struct pw_global *global); - -struct pw_client *pw_global_get_owner(struct pw_global *global); - -struct pw_global *pw_global_get_parent(struct pw_global *global); - -uint32_t pw_global_get_type(struct pw_global *global); - -uint32_t pw_global_get_version(struct pw_global *global); - -void *pw_global_get_object(struct pw_global *global); - -uint32_t pw_global_get_id(struct pw_global *global); - -int -pw_global_bind(struct pw_global *global, - struct pw_client *client, - uint32_t permissions, - uint32_t version, - uint32_t id); - -void -pw_global_destroy(struct pw_global *global); - struct spa_format * pw_core_find_format(struct pw_core *core, struct pw_port *output, diff --git a/src/pipewire/global.h b/src/pipewire/global.h new file mode 100644 index 000000000..fdd781e44 --- /dev/null +++ b/src/pipewire/global.h @@ -0,0 +1,107 @@ +/* PipeWire + * Copyright (C) 2017 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __PIPEWIRE_GLOBAL_H__ +#define __PIPEWIRE_GLOBAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +struct pw_global; +/** \page page_global Global + * + * Global objects represent resources that are available on the server and + * accessible to clients. + * Globals come and go when devices or other resources become available for + * clients. + * + * The client receives a list of globals when it binds to the registry + * object. See \ref page_registry. + * + * A client can bind to a global to send methods or receive events from + * the global. + */ +/** \class pw_global + * + * \brief A global object visible to all clients + * + * A global object is visible to all clients and represents a resource + * that can be used or inspected. + * + * See \ref page_server_api + */ +struct pw_global; + +#include +#include +#include +#include +#include +#include + +typedef int (*pw_bind_func_t) (struct pw_global *global, /**< the global to bind */ + struct pw_client *client, /**< client that binds */ + uint32_t permissions, /**< permissions for the bind */ + uint32_t version, /**< client interface version */ + uint32_t id /**< client proxy id */); + +struct pw_global * +pw_core_add_global(struct pw_core *core, + struct pw_client *owner, + struct pw_global *parent, + uint32_t type, + uint32_t version, + pw_bind_func_t bind, + void *object); + +uint32_t pw_global_get_permissions(struct pw_global *global, struct pw_client *client); + +struct pw_core *pw_global_get_core(struct pw_global *global); + +struct pw_client *pw_global_get_owner(struct pw_global *global); + +struct pw_global *pw_global_get_parent(struct pw_global *global); + +uint32_t pw_global_get_type(struct pw_global *global); + +uint32_t pw_global_get_version(struct pw_global *global); + +void *pw_global_get_object(struct pw_global *global); + +uint32_t pw_global_get_id(struct pw_global *global); + +int +pw_global_bind(struct pw_global *global, + struct pw_client *client, + uint32_t permissions, + uint32_t version, + uint32_t id); + +void +pw_global_destroy(struct pw_global *global); + +#ifdef __cplusplus +} +#endif + +#endif /* __PIPEWIRE_GLOBAL_H__ */ diff --git a/src/pipewire/meson.build b/src/pipewire/meson.build index 30e4a4313..40ab2afe9 100644 --- a/src/pipewire/meson.build +++ b/src/pipewire/meson.build @@ -4,6 +4,7 @@ pipewire_headers = [ 'command.h', 'core.h', 'data-loop.h', + 'global.h', 'interfaces.h', 'introspect.h', 'link.h', @@ -35,6 +36,7 @@ pipewire_sources = [ 'command.c', 'core.c', 'data-loop.c', + 'global.c', 'introspect.c', 'link.c', 'log.c',