From 74718d6def1b553219e3531276ab758edd44dd41 Mon Sep 17 00:00:00 2001 From: George Kiagiadakis Date: Thu, 26 Mar 2020 12:55:54 +0200 Subject: [PATCH] session-manager: add update/free functions for the info structures --- src/extensions/meson.build | 1 + .../session-manager/introspect-funcs.h | 317 ++++++++++++++++++ 2 files changed, 318 insertions(+) create mode 100644 src/extensions/session-manager/introspect-funcs.h diff --git a/src/extensions/meson.build b/src/extensions/meson.build index 9d45327fa..0f2e6134f 100644 --- a/src/extensions/meson.build +++ b/src/extensions/meson.build @@ -2,6 +2,7 @@ pipewire_ext_sm_headers = [ 'session-manager/impl-interfaces.h', 'session-manager/interfaces.h', 'session-manager/introspect.h', + 'session-manager/introspect-funcs.h', 'session-manager/keys.h', ] diff --git a/src/extensions/session-manager/introspect-funcs.h b/src/extensions/session-manager/introspect-funcs.h new file mode 100644 index 000000000..cc5f1c056 --- /dev/null +++ b/src/extensions/session-manager/introspect-funcs.h @@ -0,0 +1,317 @@ +/* PipeWire + * + * Copyright © 2020 Collabora Ltd. + * @author George Kiagiadakis + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef PIPEWIRE_EXT_SESSION_MANAGER_INTROSPECT_FUNCS_H +#define PIPEWIRE_EXT_SESSION_MANAGER_INTROSPECT_FUNCS_H + +#include "introspect.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static inline struct pw_session_info * +pw_session_info_update (struct pw_session_info *info, + const struct pw_session_info *update) +{ + struct extended_info { + struct pw_properties *props_storage; + struct pw_session_info info; + } *ext; + + if (update == NULL) + return info; + + if (info == NULL) { + ext = (struct extended_info *) calloc(1, sizeof(*ext)); + if (ext == NULL) + return NULL; + + info = &ext->info; + info->id = update->id; + } else { + ext = SPA_CONTAINER_OF(info, struct extended_info, info); + } + + info->change_mask = update->change_mask; + + if (update->change_mask & PW_SESSION_CHANGE_MASK_PROPS) { + if (!ext->props_storage) { + ext->props_storage = pw_properties_new(NULL, NULL); + info->props = &ext->props_storage->dict; + } + pw_properties_clear(ext->props_storage); + pw_properties_update(ext->props_storage, update->props); + } + if (update->change_mask & PW_SESSION_CHANGE_MASK_PARAMS) { + info->n_params = update->n_params; + free((void *) info->params); + if (update->params) { + size_t size = info->n_params * sizeof(struct spa_param_info); + info->params = (struct spa_param_info *) malloc(size); + memcpy(info->params, update->params, size); + } + else + info->params = NULL; + } + return info; +} + +static inline void +pw_session_info_free (struct pw_session_info *info) +{ + struct extended_info { + struct pw_properties *props_storage; + struct pw_session_info info; + } *ext = SPA_CONTAINER_OF(info, struct extended_info, info); + + if (ext->props_storage) + pw_properties_free(ext->props_storage); + free((void *) info->params); + free(ext); +} + +static inline struct pw_endpoint_info * +pw_endpoint_info_update (struct pw_endpoint_info *info, + const struct pw_endpoint_info *update) +{ + struct extended_info { + struct pw_properties *props_storage; + struct pw_endpoint_info info; + } *ext; + + if (update == NULL) + return info; + + if (info == NULL) { + ext = (struct extended_info *) calloc(1, sizeof(*ext)); + if (ext == NULL) + return NULL; + + info = &ext->info; + info->id = update->id; + info->name = strdup(update->name); + info->media_class = strdup(update->media_class); + info->direction = update->direction; + info->flags = update->flags; + } else { + ext = SPA_CONTAINER_OF(info, struct extended_info, info); + } + + info->change_mask = update->change_mask; + + if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_STREAMS) + info->n_streams = update->n_streams; + + if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_SESSION) + info->session_id = update->session_id; + + if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_PROPS) { + if (!ext->props_storage) { + ext->props_storage = pw_properties_new(NULL, NULL); + info->props = &ext->props_storage->dict; + } + pw_properties_clear(ext->props_storage); + pw_properties_update(ext->props_storage, update->props); + } + if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_PARAMS) { + info->n_params = update->n_params; + free((void *) info->params); + if (update->params) { + size_t size = info->n_params * sizeof(struct spa_param_info); + info->params = (struct spa_param_info *) malloc(size); + memcpy(info->params, update->params, size); + } + else + info->params = NULL; + } + return info; +} + +static inline void +pw_endpoint_info_free (struct pw_endpoint_info *info) +{ + struct extended_info { + struct pw_properties *props_storage; + struct pw_endpoint_info info; + } *ext = SPA_CONTAINER_OF(info, struct extended_info, info); + + if (ext->props_storage) + pw_properties_free(ext->props_storage); + free(info->name); + free(info->media_class); + free((void *) info->params); + free(ext); +} + +static inline struct pw_endpoint_stream_info * +pw_endpoint_stream_info_update (struct pw_endpoint_stream_info *info, + const struct pw_endpoint_stream_info *update) +{ + struct extended_info { + struct pw_properties *props_storage; + struct pw_endpoint_stream_info info; + } *ext; + + if (update == NULL) + return info; + + if (info == NULL) { + ext = (struct extended_info *) calloc(1, sizeof(*ext)); + if (ext == NULL) + return NULL; + + info = &ext->info; + info->id = update->id; + info->endpoint_id = update->endpoint_id; + info->name = strdup(update->name); + } else { + ext = SPA_CONTAINER_OF(info, struct extended_info, info); + } + + info->change_mask = update->change_mask; + + if (update->change_mask & PW_ENDPOINT_STREAM_CHANGE_MASK_LINK_PARAMS) { + free(info->link_params); + info->link_params = spa_pod_copy(update->link_params); + } + if (update->change_mask & PW_ENDPOINT_STREAM_CHANGE_MASK_PROPS) { + if (!ext->props_storage) { + ext->props_storage = pw_properties_new(NULL, NULL); + info->props = &ext->props_storage->dict; + } + pw_properties_clear(ext->props_storage); + pw_properties_update(ext->props_storage, update->props); + } + if (update->change_mask & PW_ENDPOINT_STREAM_CHANGE_MASK_PARAMS) { + info->n_params = update->n_params; + free((void *) info->params); + if (update->params) { + size_t size = info->n_params * sizeof(struct spa_param_info); + info->params = (struct spa_param_info *) malloc(size); + memcpy(info->params, update->params, size); + } + else + info->params = NULL; + } + return info; +} + +static inline void +pw_endpoint_stream_info_free (struct pw_endpoint_stream_info *info) +{ + struct extended_info { + struct pw_properties *props_storage; + struct pw_endpoint_stream_info info; + } *ext = SPA_CONTAINER_OF(info, struct extended_info, info); + + if (ext->props_storage) + pw_properties_free(ext->props_storage); + free(info->name); + free(info->link_params); + free((void *) info->params); + free(ext); +} + + +static inline struct pw_endpoint_link_info * +pw_endpoint_link_info_update (struct pw_endpoint_link_info *info, + const struct pw_endpoint_link_info *update) +{ + struct extended_info { + struct pw_properties *props_storage; + struct pw_endpoint_link_info info; + } *ext; + + if (update == NULL) + return info; + + if (info == NULL) { + ext = (struct extended_info *) calloc(1, sizeof(*ext)); + if (ext == NULL) + return NULL; + + info = &ext->info; + info->id = update->id; + info->session_id = update->session_id; + info->output_endpoint_id = update->output_endpoint_id; + info->output_stream_id = update->output_stream_id; + info->input_endpoint_id = update->input_endpoint_id; + info->input_stream_id = update->input_stream_id; + } else { + ext = SPA_CONTAINER_OF(info, struct extended_info, info); + } + + info->change_mask = update->change_mask; + + if (update->change_mask & PW_ENDPOINT_LINK_CHANGE_MASK_STATE) { + info->state = update->state; + free(info->error); + info->error = update->error ? strdup(update->error) : NULL; + } + if (update->change_mask & PW_ENDPOINT_LINK_CHANGE_MASK_PROPS) { + if (!ext->props_storage) { + ext->props_storage = pw_properties_new(NULL, NULL); + info->props = &ext->props_storage->dict; + } + pw_properties_clear(ext->props_storage); + pw_properties_update(ext->props_storage, update->props); + } + if (update->change_mask & PW_ENDPOINT_LINK_CHANGE_MASK_PARAMS) { + info->n_params = update->n_params; + free((void *) info->params); + if (update->params) { + size_t size = info->n_params * sizeof(struct spa_param_info); + info->params = (struct spa_param_info *) malloc(size); + memcpy(info->params, update->params, size); + } + else + info->params = NULL; + } + return info; +} + +static inline void +pw_endpoint_link_info_free (struct pw_endpoint_link_info *info) +{ + struct extended_info { + struct pw_properties *props_storage; + struct pw_endpoint_link_info info; + } *ext = SPA_CONTAINER_OF(info, struct extended_info, info); + + if (ext->props_storage) + pw_properties_free(ext->props_storage); + free(info->error); + free((void *) info->params); + free(ext); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PIPEWIRE_EXT_SESSION_MANAGER_INTROSPECT_FUNCS_H */