Add doxygen docs

This commit is contained in:
Wim Taymans 2017-05-30 19:46:51 +02:00
parent f6ca32cdcf
commit e7327d1316
68 changed files with 4569 additions and 937 deletions

2
doxygen/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
doxygen.conf
html/

2424
doxygen/Doxyfile.in Normal file

File diff suppressed because it is too large Load diff

25
doxygen/meson.build Normal file
View file

@ -0,0 +1,25 @@
doxyfile_conf = configuration_data()
doxyfile_conf.set('PACKAGE_NAME', meson.project_name())
doxyfile_conf.set('PACKAGE_VERSION', meson.project_version())
doxyfile_conf.set('top_srcdir', meson.source_root())
doxyfile_conf.set('top_builddir', meson.build_root())
if find_program('dot', required: false).found()
doxyfile_conf.set('HAVE_DOT', 'YES')
else
doxyfile_conf.set('HAVE_DOT', 'NO')
endif
doxyfile = configure_file(input: 'Doxyfile.in',
output: 'Doxyfile',
configuration: doxyfile_conf,
install: false)
docdir = join_paths(pipewire_datadir, 'doc')
html_target = custom_target('pipewire-docs',
input: [ doxyfile ],
output: [ 'html' ],
command: [ doxygen, doxyfile ],
install: true,
install_dir: join_paths(docdir, 'pipewire'))

View file

@ -22,6 +22,10 @@ soversion = 0
libversion = '@0@.@1@.0'.format(soversion, pipewire_version_minor.to_int() * 100 + pipewire_version_micro.to_int())
prefix = get_option('prefix')
pipewire_datadir = join_paths(prefix, get_option('datadir'))
pipewire_libdir = join_paths(prefix, get_option('libdir'))
pipewire_localedir = join_paths(prefix, get_option('localedir'))
pipewire_sysconfdir = join_paths(prefix, get_option('sysconfdir'))
modules_install_dir = '@0@/pipewire-@1@'.format(get_option('libdir'), apiversion)
@ -36,9 +40,9 @@ cdata.set('PIPEWIRE_VERSION_MINOR', pipewire_version_minor)
cdata.set('PIPEWIRE_VERSION_MICRO', pipewire_version_micro)
cdata.set('PIPEWIRE_VERSION_NANO', pipewire_version_nano)
cdata.set('PIPEWIRE_API_VERSION', '"@0@"'.format(apiversion))
cdata.set('PIPEWIRE_DATADIR', '"@0@/@1@"'.format(prefix, get_option('datadir')))
cdata.set('LOCALEDIR', '"@0@/@1@"'.format(prefix, get_option('localedir')))
cdata.set('LIBDIR', '"@0@/@1@"'.format(prefix, get_option('libdir')))
cdata.set('PIPEWIRE_DATADIR', '"@0@/@1@"'.format(pipewire_datadir))
cdata.set('LOCALEDIR', '"@0@/@1@"'.format(pipewire_localedir))
cdata.set('LIBDIR', '"@0@/@1@"'.format(pipewire_libdir))
cdata.set('GETTEXT_PACKAGE', '"pipewire"')
cdata.set('PIPEWIRE_LICENSE', '"LGPL"')
cdata.set('PIPEWIRE_PACKAGE_ORIGIN', '"Unknown package origin"')
@ -49,8 +53,8 @@ cdata.set('PACKAGE_STRING', '"PipeWire @0@"'.format(pipewire_version))
cdata.set('PACKAGE_TARNAME', '"pipewire"')
cdata.set('PACKAGE_URL', '""')
cdata.set('PACKAGE_VERSION', '"@0@"'.format(pipewire_version))
cdata.set('MODULEDIR', '"@0@/@1@/pipewire-@2@"'.format(get_option('prefix'),get_option('libdir'),apiversion))
cdata.set('PIPEWIRE_CONFIG_DIR', '"@0@/pipewire"'.format(join_paths(get_option('prefix'), get_option('sysconfdir'))))
cdata.set('MODULEDIR', '"@0@/@1@/pipewire-@2@"'.format(pipewire_libdir,apiversion))
cdata.set('PIPEWIRE_CONFIG_DIR', '"@0@/pipewire"'.format(pipewire_sysconfdir))
cdata.set('VERSION', '"@0@"'.format(pipewire_version))
# FIXME: --with-memory-alignment],[8,N,malloc,pagesize (default is 32)]) option
cdata.set('MEMORY_ALIGNMENT_MALLOC', 1)
@ -137,6 +141,13 @@ subdir('spa')
subdir('pipewire')
subdir('pkgconfig')
doxygen = find_program('doxygen', required: false)
if doxygen.found()
subdir('doxygen')
else
message('Documentation disabled without doxygen')
endif
#gtkdoc = find_program('gtkdoc-scan', required : false)
#if gtkdoc.found()
# subdir('docs')

View file

@ -26,21 +26,31 @@ extern "C" {
#include <spa/defs.h>
/** \class pw_array
*
* \brief An array object
*
* The array is a dynamically resizable data structure that can
* hold items of the same size.
*/
struct pw_array {
void *data;
size_t size;
size_t alloc;
size_t extend;
void *data; /**< pointer to array data */
size_t size; /**< length of array in bytes */
size_t alloc; /**< number of allocated memory in \a data */
size_t extend; /**< number of bytes to extend with */
};
#define PW_ARRAY_INIT(extend) { NULL, 0, 0, extend }
#define PW_ARRAY_INIT(extend) (struct pw_array) { NULL, 0, 0, extend }
#define pw_array_get_len_s(a,s) ((a)->size / (s))
#define pw_array_get_unchecked_s(a,idx,s,t) SPA_MEMBER((a)->data,(idx)*(s),t)
#define pw_array_check_index_s(a,idx,s) ((idx) < pw_array_get_len(a,s))
/** Get the number of items of type \a t in array \memberof pw_array */
#define pw_array_get_len(a,t) pw_array_get_len_s(a,sizeof(t))
/** Get the item with index \a idx and type \a t from array \memberof pw_array */
#define pw_array_get_unchecked(a,idx,t) pw_array_get_unchecked_s(a,idx,sizeof(t),t)
/** Check if an item with index \a idx and type \a t exist in array \memberof pw_array */
#define pw_array_check_index(a,idx,t) pw_array_check_index_s(a,idx,sizeof(t))
#define pw_array_for_each(pos, array) \
@ -48,6 +58,7 @@ struct pw_array {
(const uint8_t *) pos < ((const uint8_t *) (array)->data + (array)->size); \
(pos)++)
/** Initialize the array with given extend \memberof pw_array */
static inline void pw_array_init(struct pw_array *arr, size_t extend)
{
arr->data = NULL;
@ -55,11 +66,13 @@ static inline void pw_array_init(struct pw_array *arr, size_t extend)
arr->extend = extend;
}
/** Clear the array */
static inline void pw_array_clear(struct pw_array *arr)
{
free(arr->data);
}
/** Make sure \a size bytes can be added to the array \memberof pw_array */
static inline bool pw_array_ensure_size(struct pw_array *arr, size_t size)
{
size_t alloc, need;
@ -80,6 +93,8 @@ static inline bool pw_array_ensure_size(struct pw_array *arr, size_t size)
return true;
}
/** Add \a ref size bytes to \a arr. A pointer to memory that can
* hold at least \a size bytes is returned \memberof pw_array */
static inline void *pw_array_add(struct pw_array *arr, size_t size)
{
void *p;
@ -93,6 +108,8 @@ static inline void *pw_array_add(struct pw_array *arr, size_t size)
return p;
}
/** Add \a ref size bytes to \a arr. When there is not enough memory to
* hold \a size bytes, NULL is returned \memberof pw_array */
static inline void *pw_array_add_fixed(struct pw_array *arr, size_t size)
{
void *p;
@ -106,6 +123,7 @@ static inline void *pw_array_add_fixed(struct pw_array *arr, size_t size)
return p;
}
/** Add a pointer to array \memberof pw_array */
#define pw_array_add_ptr(a,p) \
*((void**) pw_array_add(a, sizeof(void*))) = (p)

View file

@ -31,6 +31,8 @@
#include "connection.h"
#include "log.h"
/** \cond */
#define MAX_BUFFER_SIZE 4096
#define MAX_FDS 28
@ -56,6 +58,16 @@ struct pw_connection_impl {
struct buffer in, out;
};
/** \endcond */
/** Get an fd from a connection
*
* \param conn the connection
* \param index the index of the fd to get
* \return the fd at \a index or -1 when no such fd exists
*
* \memberof pw_connection
*/
int pw_connection_get_fd(struct pw_connection *conn, uint32_t index)
{
struct pw_connection_impl *impl = SPA_CONTAINER_OF(conn, struct pw_connection_impl, this);
@ -66,6 +78,14 @@ int pw_connection_get_fd(struct pw_connection *conn, uint32_t index)
return impl->in.fds[index];
}
/** Add an fd to a connection
*
* \param conn the connection
* \param fd the fd to add
* \return the index of the fd or -1 when an error occured
*
* \memberof pw_connection
*/
uint32_t pw_connection_add_fd(struct pw_connection *conn, int fd)
{
struct pw_connection_impl *impl = SPA_CONTAINER_OF(conn, struct pw_connection_impl, this);
@ -157,6 +177,13 @@ static void clear_buffer(struct buffer *buf)
buf->buffer_size = 0;
}
/** Make a new connection object for the given socket
*
* \param fd the socket
* \returns a newly allocated connection object
*
* \memberof pw_connection
*/
struct pw_connection *pw_connection_new(int fd)
{
struct pw_connection_impl *impl;
@ -194,6 +221,12 @@ struct pw_connection *pw_connection_new(int fd)
return NULL;
}
/** Destroy a connection
*
* \param conn the connection to destroy
*
* \memberof pw_connection
*/
void pw_connection_destroy(struct pw_connection *conn)
{
struct pw_connection_impl *impl = SPA_CONTAINER_OF(conn, struct pw_connection_impl, this);
@ -207,13 +240,19 @@ void pw_connection_destroy(struct pw_connection *conn)
free(impl);
}
/**
* pw_connection_has_next:
* @iter: a connection
/** Move to the next packet in the connection
*
* Move to the next packet in @conn.
* \param conn the connection
* \param opcode addres of result opcode
* \param dest_id addres of result destination id
* \param dt pointer to packet data
* \param sz size of packet data
* \return true on success
*
* Returns: %true if more packets are available.
* Get the next packet in \a conn and store the opcode and destination
* id as well as the packet data and size.
*
* \memberof pw_connection
*/
bool
pw_connection_get_next(struct pw_connection *conn,
@ -287,6 +326,17 @@ pw_connection_get_next(struct pw_connection *conn,
return true;
}
/** Start writing \a size bytes
*
* \param conn the connection
* \param size the number of bytes to write
* \return memory to write into
*
* Makes sure that \a size bytes can be written to \a conn and
* returns a pointer to the memory to write into
*
* \memberof pw_connection
*/
void *pw_connection_begin_write(struct pw_connection *conn, uint32_t size)
{
struct pw_connection_impl *impl = SPA_CONTAINER_OF(conn, struct pw_connection_impl, this);
@ -297,6 +347,18 @@ void *pw_connection_begin_write(struct pw_connection *conn, uint32_t size)
return p + 2;
}
/** End writing to the connection
*
* \param conn the connection
* \param dest_id the destination id
* \param opcode the opcode
* \param size the total written size
*
* Finnish writing a message of \a size to \a conn and write the
* \a dest_id and \a opcode and final size to the connection
*
* \memberof pw_connection
*/
void
pw_connection_end_write(struct pw_connection *conn, uint32_t dest_id, uint8_t opcode, uint32_t size)
{
@ -318,6 +380,15 @@ pw_connection_end_write(struct pw_connection *conn, uint32_t dest_id, uint8_t op
pw_signal_emit(&conn->need_flush, conn);
}
/** Flush the connection object
*
* \param conn the connection object
* \return true on success
*
* Write the queued messages on the connection to the socket
*
* \memberof pw_connection
*/
bool pw_connection_flush(struct pw_connection *conn)
{
struct pw_connection_impl *impl = SPA_CONTAINER_OF(conn, struct pw_connection_impl, this);
@ -381,6 +452,15 @@ bool pw_connection_flush(struct pw_connection *conn)
return false;
}
/** Clear the connection object
*
* \param conn the connection object
* \return true on success
*
* Remove all queued messages from \a conn
*
* \memberof pw_connection
*/
bool pw_connection_clear(struct pw_connection *conn)
{
struct pw_connection_impl *impl = SPA_CONTAINER_OF(conn, struct pw_connection_impl, this);

View file

@ -27,10 +27,19 @@ extern "C" {
#include <spa/defs.h>
#include <pipewire/client/sig.h>
/** \class pw_connection
*
* \brief Manages the connection between client and server
*
* The \ref pw_connection handles the connection between client
* and server on a given socket.
*/
struct pw_connection {
int fd;
int fd; /**< the socket */
/** Emited when data has been written that needs to be flushed */
PW_SIGNAL(need_flush, (struct pw_listener *listener, struct pw_connection *conn));
/** Emited when the connection is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_connection *conn));
};

View file

@ -31,6 +31,7 @@
#include "pipewire/client/connection.h"
#include "pipewire/client/subscribe.h"
/** \cond */
struct context {
struct pw_context this;
@ -44,15 +45,8 @@ struct context {
struct pw_listener need_flush;
struct spa_source *flush_event;
};
/** \endcond */
/**
* pw_context_state_as_string:
* @state: a #enum pw_context_state
*
* Return the string representation of @state.
*
* Returns: the string representation of @state.
*/
const char *pw_context_state_as_string(enum pw_context_state state)
{
switch (state) {
@ -274,7 +268,7 @@ destroy_proxy (struct pw_proxy *proxy)
proxy->user_data = NULL;
}
static void registry_event_global(void *object, uint32_t id, const char *type)
static void registry_event_global(void *object, uint32_t id, const char *type, uint32_t version)
{
struct pw_proxy *registry_proxy = object;
struct pw_context *this = registry_proxy->context;
@ -284,7 +278,7 @@ static void registry_event_global(void *object, uint32_t id, const char *type)
if (impl->no_proxy)
return;
pw_log_debug("got global %u %s", id, type);
pw_log_debug("got global %u %s %u", id, type, version);
if (!strcmp(type, PIPEWIRE_TYPE__Node)) {
proxy = pw_proxy_new(this, SPA_ID_INVALID, this->type.node);
@ -313,7 +307,7 @@ static void registry_event_global(void *object, uint32_t id, const char *type)
}
if (proxy) {
proxy->destroy = (pw_destroy_t)destroy_proxy;
pw_registry_do_bind(registry_proxy, id, proxy->id);
pw_registry_do_bind(registry_proxy, id, version, proxy->id);
}
return;
@ -406,15 +400,15 @@ on_context_data(struct spa_loop_utils *utils,
}
}
/**
* pw_context_new:
* @context: a #GMainContext to run in
* @name: an application name
* @properties: (transfer full): optional properties
/** Create a new unconnected context
*
* Make a new unconnected #struct pw_context
* \param loop a \ref pw_loop to use as event loop
* \param name an application name
* \param properties optional properties, ownership of the properties is
* taken.
* \return a new unconnected context
*
* Returns: a new unconnected #struct pw_context
* \memberof pw_context
*/
struct pw_context *pw_context_new(struct pw_loop *loop,
const char *name, struct pw_properties *properties)
@ -453,7 +447,6 @@ struct pw_context *pw_context_new(struct pw_loop *loop,
pw_map_init(&this->types, 64, 32);
spa_list_init(&this->stream_list);
spa_list_init(&this->global_list);
spa_list_init(&this->proxy_list);
pw_signal_init(&this->state_changed);
@ -468,6 +461,12 @@ struct pw_context *pw_context_new(struct pw_loop *loop,
return NULL;
}
/** Destroy a context
*
* \param context a \ref pw_context to destroy to destroy
*
* \memberof pw_context
*/
void pw_context_destroy(struct pw_context *context)
{
struct context *impl = SPA_CONTAINER_OF(context, struct context, this);
@ -497,13 +496,13 @@ void pw_context_destroy(struct pw_context *context)
free(impl);
}
/**
* pw_context_connect:
* @context: a #struct pw_context
/** Connect to the PipeWire daemon
*
* Connect to the daemon
* \param context a \ref pw_context
* \param flags flags to use
* \return true on success.
*
* Returns: %TRUE on success.
* \memberof pw_context
*/
bool pw_context_connect(struct pw_context *context, enum pw_context_flags flags)
{
@ -552,14 +551,14 @@ bool pw_context_connect(struct pw_context *context, enum pw_context_flags flags)
return false;
}
/**
* pw_context_connect_fd:
* @context: a #struct pw_context
* @fd: FD of a connected PipeWire socket
/** Connect to the PipeWire daemon on the given socket
*
* Connect to a daemon. @fd should already be connected to a PipeWire socket.
* \param context a \ref pw_context
* \param flags flags to use
* \param fd the connected socket to use
* \return true on success.
*
* Returns: %TRUE on success.
* \memberof pw_context
*/
bool pw_context_connect_fd(struct pw_context *context, enum pw_context_flags flags, int fd)
{
@ -618,13 +617,12 @@ bool pw_context_connect_fd(struct pw_context *context, enum pw_context_flags fla
return false;
}
/**
* pw_context_disconnect:
* @context: a #struct pw_context
/** Disconnect from the daemon.
*
* Disonnect from the daemon.
* \param context a \ref pw_context
* \return true on success.
*
* Returns: %TRUE on success.
* \memberof pw_context
*/
bool pw_context_disconnect(struct pw_context *context)
{
@ -658,6 +656,14 @@ bool pw_context_disconnect(struct pw_context *context)
return true;
}
/** Get core information
*
* \param context A \ref pw_context
* \param cb the callback to call with the result
* \param user_data user data passed to \a cb
*
* \memberof pw_introspect
*/
void pw_context_get_core_info(struct pw_context *context, pw_core_info_cb_t cb, void *user_data)
{
struct pw_proxy *proxy;
@ -695,13 +701,33 @@ static void do_list(struct pw_context *context, uint32_t type, list_func_t cb, v
cb(context, SPA_RESULT_ENUM_END, NULL, user_data);
}
/** Get all module information
*
* \param context A \ref pw_context
* \param cb the callback to call with the results
* \param user_data user data passed to \a cb
*
* \a cb is called for each module
*
* \memberof pw_introspect
*/
void
pw_context_list_module_info(struct pw_context *context, pw_module_info_cb_t cb, void *user_data)
{
do_list(context, context->type.module, (list_func_t) cb, user_data);
}
/** Get module information
*
* \param context A \ref pw_context
* \param id the server side id of the module to query
* \param cb the callback to call with the results
* \param user_data user data passed to \a cb
*
* \a cb is called for the module with \a id
*
* \memberof pw_introspect
*/
void
pw_context_get_module_info_by_id(struct pw_context *context,
uint32_t id, pw_module_info_cb_t cb, void *user_data)
@ -719,12 +745,33 @@ pw_context_get_module_info_by_id(struct pw_context *context,
cb(context, SPA_RESULT_ENUM_END, NULL, user_data);
}
/** Get all client information
*
* \param context A \ref pw_context
* \param cb the callback to call with the results
* \param user_data user data passed to \a cb
*
* \a cb is called for each client
*
* \memberof pw_introspect
*/
void
pw_context_list_client_info(struct pw_context *context, pw_client_info_cb_t cb, void *user_data)
{
do_list(context, context->type.client, (list_func_t) cb, user_data);
}
/** Get client information
*
* \param context A \ref pw_context
* \param id the server side id of the client to query
* \param cb the callback to call with the results
* \param user_data user data passed to \a cb
*
* \a cb is called for the client with \a id
*
* \memberof pw_introspect
*/
void
pw_context_get_client_info_by_id(struct pw_context *context,
uint32_t id, pw_client_info_cb_t cb, void *user_data)
@ -742,11 +789,32 @@ pw_context_get_client_info_by_id(struct pw_context *context,
cb(context, SPA_RESULT_ENUM_END, NULL, user_data);
}
/** Get all node information
*
* \param context A \ref pw_context
* \param cb the callback to call with the results
* \param user_data user data passed to \a cb
*
* \a cb is called for each node
*
* \memberof pw_introspect
*/
void pw_context_list_node_info(struct pw_context *context, pw_node_info_cb_t cb, void *user_data)
{
do_list(context, context->type.node, (list_func_t) cb, user_data);
}
/** Get node information
*
* \param context A \ref pw_context
* \param id the server side id of the node to query
* \param cb the callback to call with the results
* \param user_data user data passed to \a cb
*
* \a cb is called for the node with \a id
*
* \memberof pw_introspect
*/
void
pw_context_get_node_info_by_id(struct pw_context *context,
uint32_t id, pw_node_info_cb_t cb, void *user_data)
@ -764,11 +832,32 @@ pw_context_get_node_info_by_id(struct pw_context *context,
cb(context, SPA_RESULT_ENUM_END, NULL, user_data);
}
/** Get all link information
*
* \param context A \ref pw_context
* \param cb the callback to call with the results
* \param user_data user data passed to \a cb
*
* \a cb is called for each link
*
* \memberof pw_introspect
*/
void pw_context_list_link_info(struct pw_context *context, pw_link_info_cb_t cb, void *user_data)
{
do_list(context, context->type.link, (list_func_t) cb, user_data);
}
/** Get link information
*
* \param context A \ref pw_context
* \param id the server side id of the link to query
* \param cb the callback to call with the results
* \param user_data user data passed to \a cb
*
* \a cb is called for the link with \a id
*
* \memberof pw_introspect
*/
void
pw_context_get_link_info_by_id(struct pw_context *context,
uint32_t id, pw_link_info_cb_t cb, void *user_data)

View file

@ -31,81 +31,80 @@ extern "C" {
#include <pipewire/client/proxy.h>
#include <pipewire/client/type.h>
/**
* pw_context_state:
* @PW_CONTEXT_STATE_ERROR: context is in error
* @PW_CONTEXT_STATE_UNCONNECTED: not connected
* @PW_CONTEXT_STATE_CONNECTING: connecting to daemon
* @PW_CONTEXT_STATE_CONNECTED: context is connected and ready
*
* The state of a pw_context
*/
/** \enum pw_context_state The state of a \ref pw_context \memberof pw_context */
enum pw_context_state {
PW_CONTEXT_STATE_ERROR = -1,
PW_CONTEXT_STATE_UNCONNECTED = 0,
PW_CONTEXT_STATE_CONNECTING = 1,
PW_CONTEXT_STATE_CONNECTED = 2,
PW_CONTEXT_STATE_ERROR = -1, /**< context is in error */
PW_CONTEXT_STATE_UNCONNECTED = 0, /**< not connected */
PW_CONTEXT_STATE_CONNECTING = 1, /**< connecting to PipeWire daemon */
PW_CONTEXT_STATE_CONNECTED = 2, /**< context is connected and ready */
};
/** Convert a \ref pw_context_state to a readable string \memberof pw_context */
const char *pw_context_state_as_string(enum pw_context_state state);
/** \enum pw_context_flags Extra flags passed to \ref pw_context_connect() \memberof pw_context */
enum pw_context_flags {
PW_CONTEXT_FLAG_NONE = 0,
PW_CONTEXT_FLAG_NO_REGISTRY = (1 << 0),
PW_CONTEXT_FLAG_NO_PROXY = (1 << 1),
PW_CONTEXT_FLAG_NONE = 0, /**< no flags */
PW_CONTEXT_FLAG_NO_REGISTRY = (1 << 0), /**< don't create the registry object */
PW_CONTEXT_FLAG_NO_PROXY = (1 << 1), /**< don't automatically create proxies for
* server side objects */
};
/**
* pw_context:
/** \class pw_context
*
* PipeWire context object class.
* \brief Represents a connection with the PipeWire server
*
* a \ref pw_context is created and used to connect to the server.
* A \ref pw_proxy for the core object will automatically be created
* when connecting.
*/
struct pw_context {
char *name;
struct pw_properties *properties;
char *name; /**< the application name */
struct pw_properties *properties; /**< extra properties */
struct pw_type type;
struct pw_type type; /**< the type map */
struct pw_loop *loop;
struct pw_loop *loop; /**< the main loop */
struct pw_proxy *core_proxy;
struct pw_proxy *registry_proxy;
struct pw_proxy *core_proxy; /**< proxy for the core object */
struct pw_proxy *registry_proxy; /**< proxy for the registry object. Can
* be NULL when \ref PW_CONTEXT_FLAG_NO_PROXY
* was specified */
struct pw_map objects; /**< map of client side proxy objects
* indexed with the client id */
uint32_t n_types; /**< number of client types */
struct pw_map types; /**< client types */
struct pw_map objects;
uint32_t n_types;
struct pw_map types;
struct spa_list stream_list; /**< list of \ref pw_stream objects */
struct spa_list proxy_list; /**< list of \ref pw_proxy objects */
struct spa_list global_list;
struct spa_list stream_list;
struct spa_list proxy_list;
void *protocol_private; /**< private data for the protocol */
void *protocol_private;
enum pw_context_state state;
char *error;
enum pw_context_state state; /**< context state */
char *error; /**< error string */
/** Signal emited when the state changes */
PW_SIGNAL(state_changed, (struct pw_listener *listener, struct pw_context *context));
/** Signal emited when a global is added/changed/removed */
PW_SIGNAL(subscription, (struct pw_listener *listener,
struct pw_context *context,
enum pw_subscription_event event, uint32_t type, uint32_t id));
/** Signal emited when the context is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_context *context));
};
struct pw_context *
pw_context_new(struct pw_loop *loop,
const char *name, struct pw_properties *properties);
void
pw_context_destroy(struct pw_context *context);
bool
pw_context_connect(struct pw_context *context, enum pw_context_flags flags);
void pw_context_destroy(struct pw_context *context);
bool
pw_context_connect_fd(struct pw_context *context, enum pw_context_flags flags, int fd);
bool pw_context_connect(struct pw_context *context, enum pw_context_flags flags);
bool
pw_context_disconnect(struct pw_context *context);
bool pw_context_connect_fd(struct pw_context *context, enum pw_context_flags flags, int fd);
bool pw_context_disconnect(struct pw_context *context);
#ifdef __cplusplus
}

View file

@ -40,18 +40,77 @@ extern "C" {
#define PW_CORE_METHOD_UPDATE_TYPES 5
#define PW_CORE_METHOD_NUM 6
/** \file
*
* The object interfaces
*
* Methods are sent from client to server and events from
* server to client.
*/
/** Core methods */
struct pw_core_methods {
/**
* Update the client properties
* \param props the new client properties
*/
void (*client_update) (void *object, const struct spa_dict *props);
/**
* Do server roundtrip
*
* Ask the server to emit the 'done' event with \a id.
* Since methods are handled in-order and events are delivered
* in-order, this can be used as a barrier to ensure all previous
* methods and the resulting events have been handled.
* \param seq the sequence number passed to the done event
*/
void (*sync) (void *object, uint32_t seq);
/**
* Get the registry object
*
* Create a registry object that allows the client to list and bind
* the global objects available from the PipeWire server
* \param id the client proxy id
*/
void (*get_registry) (void *object, uint32_t new_id);
/**
* Create a new node on the PipeWire server from a factory
*
* \param factory_name the factory name to use
* \param name the node name
* \param props extra properties
* \param new_id the client proxy id
*/
void (*create_node) (void *object,
const char *factory_name,
const char *name, const struct spa_dict *props, uint32_t new_id);
const char *name,
const struct spa_dict *props,
uint32_t new_id);
/**
* Create a new node on the server. The node can be controlled
* with the client node interface.
*
* \param name the node name
* \param props extra properties
* \param new_id the client proxy id
*/
void (*create_client_node) (void *object,
const char *name,
const struct spa_dict *props, uint32_t new_id);
const struct spa_dict *props,
uint32_t new_id);
/**
* Update the type map
*
* Send a type map update to the PipeWire server. The server uses this
* information to keep a mapping between client types and the server types.
* \param first_id the id of the first type
* \param n_types the number of types
* \param types the types as a string
*/
void (*update_types) (void *object,
uint32_t first_id, uint32_t n_types, const char **types);
uint32_t first_id,
uint32_t n_types,
const char **types);
};
#define pw_core_do_client_update(r,...) ((struct pw_core_methods*)r->iface->methods)->client_update(r,__VA_ARGS__)
@ -68,13 +127,59 @@ struct pw_core_methods {
#define PW_CORE_EVENT_UPDATE_TYPES 4
#define PW_CORE_EVENT_NUM 5
/** Core events */
struct pw_core_events {
/**
* Notify new core info
*
* \param info new core info
*/
void (*info) (void *object, struct pw_core_info *info);
/**
* Emit a done event
*
* The done event is emited as a result of a sync method with the
* same sequence number.
* \param seq the sequence number passed to the sync method call
*/
void (*done) (void *object, uint32_t seq);
/**
* Fatal error event
*
* The error event is sent out when a fatal (non-recoverable)
* error has occurred. The id argument is the object where
* the error occurred, most often in response to a request to that
* object. The message is a brief description of the error,
* for (debugging) convenience.
* \param id object where the error occurred
* \param res error code
* \param error error description
*/
void (*error) (void *object, uint32_t id, int res, const char *error, ...);
/**
* Remove an object ID
*
* This event is used internally by the object ID management
* logic. When a client deletes an object, the server will send
* this event to acknowledge that it has seen the delete request.
* When the client receives this event, it will know that it can
* safely reuse the object ID.
* \param id deleted object ID
*/
void (*remove_id) (void *object, uint32_t id);
/**
* Update the type map
*
* Send a type map update to the client. The client uses this
* information to keep a mapping between server types and the client types.
* \param first_id the id of the first type
* \param n_types the number of types
* \param types the types as a string
*/
void (*update_types) (void *object,
uint32_t first_id, uint32_t n_types, const char **types);
uint32_t first_id,
uint32_t n_types,
const char **types);
};
#define pw_core_notify_info(r,...) ((struct pw_core_events*)r->iface->events)->info(r,__VA_ARGS__)
@ -87,8 +192,20 @@ struct pw_core_events {
#define PW_REGISTRY_METHOD_BIND 0
#define PW_REGISTRY_METHOD_NUM 1
/** Registry methods */
struct pw_registry_methods {
void (*bind) (void *object, uint32_t id, uint32_t new_id);
/**
* Bind to a global object
*
* Bind to the global object with \a id and use the client proxy
* with new_id as the proxy. After this call, methods can be
* send to the remote global object and events can be received
*
* \param id the global id to bind to
* \param version the version to use
* \param new_id the client proxy to use
*/
void (*bind) (void *object, uint32_t id, uint32_t version, uint32_t new_id);
};
#define pw_registry_do_bind(r,...) ((struct pw_registry_methods*)r->iface->methods)->bind(r,__VA_ARGS__)
@ -97,8 +214,28 @@ struct pw_registry_methods {
#define PW_REGISTRY_EVENT_GLOBAL_REMOVE 1
#define PW_REGISTRY_EVENT_NUM 2
/** Registry events */
struct pw_registry_events {
void (*global) (void *object, uint32_t id, const char *type);
/**
* Notify of a new global object
*
* The registry emits this event when a new global object is
* available.
*
* \param id the global object id
* \param type the type of the object
* \param version the version of the object
*/
void (*global) (void *object, uint32_t id, const char *type, uint32_t version);
/**
* Notify of a global object removal
*
* Emited when a global object was removed from the registry.
* If the client has any bindings to the global, it should destroy
* those.
*
* \param id the id of the global that was removed
*/
void (*global_remove) (void *object, uint32_t id);
};
@ -108,7 +245,13 @@ struct pw_registry_events {
#define PW_MODULE_EVENT_INFO 0
#define PW_MODULE_EVENT_NUM 1
/** Module events */
struct pw_module_events {
/**
* Notify module info
*
* \param info info about the module
*/
void (*info) (void *object, struct pw_module_info *info);
};
@ -117,17 +260,24 @@ struct pw_module_events {
#define PW_NODE_EVENT_INFO 0
#define PW_NODE_EVENT_NUM 1
/** Node events */
struct pw_node_events {
/**
* Notify node info
*
* \param info info about the node
*/
void (*info) (void *object, struct pw_node_info *info);
};
#define pw_node_notify_info(r,...) ((struct pw_node_events*)r->iface->events)->info(r,__VA_ARGS__)
/** information about a buffer */
struct pw_client_node_buffer {
uint32_t mem_id;
uint32_t offset;
uint32_t size;
struct spa_buffer *buffer;
uint32_t mem_id; /**< the memory id for the metadata */
uint32_t offset; /**< offset in memory */
uint32_t size; /**< size in memory */
struct spa_buffer *buffer; /**< buffer describing metadata and buffer memory */
};
#define PW_CLIENT_NODE_METHOD_UPDATE 0
@ -136,15 +286,41 @@ struct pw_client_node_buffer {
#define PW_CLIENT_NODE_METHOD_DESTROY 3
#define PW_CLIENT_NODE_METHOD_NUM 4
/** \ref pw_client_node methods */
struct pw_client_node_methods {
/**
* Update the node ports and properties
*
* Update the maximum number of ports and the properties of the
* client node.
* \param change_mask bitfield with changed parameters
* \param max_input_ports new max input ports
* \param max_output_ports new max output ports
* \param props new properties
*/
void (*update) (void *object,
#define PW_MESSAGE_NODE_UPDATE_MAX_INPUTS (1 << 0)
#define PW_MESSAGE_NODE_UPDATE_MAX_OUTPUTS (1 << 1)
#define PW_MESSAGE_NODE_UPDATE_PROPS (1 << 2)
uint32_t change_mask,
uint32_t max_input_ports,
uint32_t max_output_ports, const struct spa_props *props);
uint32_t max_output_ports,
const struct spa_props *props);
/**
* Update a node port
*
* Update the information of one port of a node.
* \param direction the direction of the port
* \param port_id the port id to update
* \param change_mask a bitfield of changed items
* \param n_possible_formats number of possible formats
* \param possible_formats array of possible formats on the port
* \param format the current format on the port
* \param n_params number of port parameters
* \param params array of port parameters
* \param info port information
*/
void (*port_update) (void *object, enum spa_direction direction, uint32_t port_id,
#define PW_MESSAGE_PORT_UPDATE_POSSIBLE_FORMATS (1 << 0)
#define PW_MESSAGE_PORT_UPDATE_FORMAT (1 << 1)
@ -155,8 +331,16 @@ struct pw_client_node_methods {
const struct spa_format **possible_formats,
const struct spa_format *format,
uint32_t n_params,
const struct spa_param **params, const struct spa_port_info *info);
const struct spa_param **params,
const struct spa_port_info *info);
/**
* Send an event to the node
* \param event the event to send
*/
void (*event) (void *object, struct spa_event *event);
/**
* Destroy the client_node
*/
void (*destroy) (void *object);
};
@ -166,52 +350,175 @@ struct pw_client_node_methods {
#define pw_client_node_do_destroy(r) ((struct pw_client_node_methods*)r->iface->methods)->destroy(r)
#define PW_CLIENT_NODE_EVENT_DONE 0
#define PW_CLIENT_NODE_EVENT_EVENT 1
#define PW_CLIENT_NODE_EVENT_ADD_PORT 2
#define PW_CLIENT_NODE_EVENT_REMOVE_PORT 3
#define PW_CLIENT_NODE_EVENT_SET_FORMAT 4
#define PW_CLIENT_NODE_EVENT_SET_PROPERTY 5
#define PW_CLIENT_NODE_EVENT_ADD_MEM 6
#define PW_CLIENT_NODE_EVENT_USE_BUFFERS 7
#define PW_CLIENT_NODE_EVENT_NODE_COMMAND 8
#define PW_CLIENT_NODE_EVENT_PORT_COMMAND 9
#define PW_CLIENT_NODE_EVENT_TRANSPORT 10
#define PW_CLIENT_NODE_EVENT_NUM 11
#define PW_CLIENT_NODE_EVENT_SET_PROPS 1
#define PW_CLIENT_NODE_EVENT_EVENT 2
#define PW_CLIENT_NODE_EVENT_ADD_PORT 3
#define PW_CLIENT_NODE_EVENT_REMOVE_PORT 4
#define PW_CLIENT_NODE_EVENT_SET_FORMAT 5
#define PW_CLIENT_NODE_EVENT_SET_PARAM 6
#define PW_CLIENT_NODE_EVENT_ADD_MEM 7
#define PW_CLIENT_NODE_EVENT_USE_BUFFERS 8
#define PW_CLIENT_NODE_EVENT_NODE_COMMAND 9
#define PW_CLIENT_NODE_EVENT_PORT_COMMAND 10
#define PW_CLIENT_NODE_EVENT_TRANSPORT 11
#define PW_CLIENT_NODE_EVENT_NUM 12
/** \ref pw_client_node events */
struct pw_client_node_events {
/**
* Notify the creation of the client node
*
* A set of sockets are exchanged that are used to notify when
* commands are available for reading and writing.
*
* \param readfd the fd used for receiving commands
* \param writefd the fd used for sending command
*/
void (*done) (void *object, int readfd, int writefd);
/**
* Notify of a property change
*
* When the server configures the properties on the node
* this event is sent
*
* \param seq a sequence number
* \param props the props to set
*/
void (*set_props) (void *object,
uint32_t seq,
const struct spa_props *props);
/**
* Receive an event from the client node
* \param event the received event */
void (*event) (void *object, const struct spa_event *event);
/**
* A new port was added to the node
*
* The server can at any time add a port to the node when there
* are free ports available.
*
* \param seq a sequence number
* \param direction the direction of the port
* \param port_id the new port id
*/
void (*add_port) (void *object,
uint32_t seq, enum spa_direction direction, uint32_t port_id);
uint32_t seq,
enum spa_direction direction,
uint32_t port_id);
/**
* A port was removed from the node
*
* \param seq a sequence number
* \param direction a port direction
* \param port_id the remove port id
*/
void (*remove_port) (void *object,
uint32_t seq, enum spa_direction direction, uint32_t port_id);
uint32_t seq,
enum spa_direction direction,
uint32_t port_id);
/**
* A format was configured on the port
*
* \param seq a sequence number
* \param direction a port direction
* \param port_id the port id
* \param flags flags used when setting the format
* \param format the new format
*/
void (*set_format) (void *object,
uint32_t seq,
enum spa_direction direction,
uint32_t port_id, uint32_t flags, const struct spa_format *format);
void (*set_property) (void *object,
uint32_t seq, uint32_t id, uint32_t size, const void *value);
uint32_t port_id,
uint32_t flags,
const struct spa_format *format);
/**
* A parameter was configured on the port
*
* \param seq a sequence number
* \param direction a port direction
* \param port_id the port id
* \param param the new param
*/
void (*set_param) (void *object,
uint32_t seq,
enum spa_direction direction,
uint32_t port_id,
const struct spa_param *param);
/**
* Memory was added for a port
*
* \param direction a port direction
* \param port_id the port id
* \param mem_id the id of the memory
* \param type the memory type
* \param memfd the fd of the memory
* \param flags flags for the \a memfd
* \param offset valid offset of mapped memory from \a memfd
* \param size valid size of mapped memory from \a memfd
*/
void (*add_mem) (void *object,
enum spa_direction direction,
uint32_t port_id,
uint32_t mem_id,
uint32_t type, int memfd, uint32_t flags, uint32_t offset, uint32_t size);
uint32_t type,
int memfd,
uint32_t flags,
uint32_t offset,
uint32_t size);
/**
* Notify the port of buffers
*
* \param seq a sequence number
* \param direction a port direction
* \param port_id the port id
* \param n_buffer the number of buffers
* \param buffers and array of buffer descriptions
*/
void (*use_buffers) (void *object,
uint32_t seq,
enum spa_direction direction,
uint32_t port_id,
uint32_t n_buffers, struct pw_client_node_buffer *buffers);
uint32_t n_buffers,
struct pw_client_node_buffer *buffers);
/**
* Notify of a new node command
*
* \param seq a sequence number
* \param command the command
*/
void (*node_command) (void *object, uint32_t seq, const struct spa_command *command);
void (*port_command) (void *object, uint32_t port_id, const struct spa_command *command);
/**
* Notify of a new port command
*
* \param direction a port direction
* \param port_id the port id
* \param command the command
*/
void (*port_command) (void *object,
enum spa_direction direction,
uint32_t port_id,
const struct spa_command *command);
/**
* Notify of a new transport area
*
* The transport area is used to exchange real-time commands between
* the client and the server.
*
* \param memfd the memory fd of the area
* \param offset the offset to map
* \param size the size to map
*/
void (*transport) (void *object, int memfd, uint32_t offset, uint32_t size);
};
#define pw_client_node_notify_done(r,...) ((struct pw_client_node_events*)r->iface->events)->done(r,__VA_ARGS__)
#define pw_client_node_notify_set_props(r,...) ((struct pw_client_node_events*)r->iface->events)->props(r,__VA_ARGS__)
#define pw_client_node_notify_event(r,...) ((struct pw_client_node_events*)r->iface->events)->event(r,__VA_ARGS__)
#define pw_client_node_notify_add_port(r,...) ((struct pw_client_node_events*)r->iface->events)->add_port(r,__VA_ARGS__)
#define pw_client_node_notify_remove_port(r,...) ((struct pw_client_node_events*)r->iface->events)->remove_port(r,__VA_ARGS__)
#define pw_client_node_notify_set_format(r,...) ((struct pw_client_node_events*)r->iface->events)->set_format(r,__VA_ARGS__)
#define pw_client_node_notify_set_property(r,...) ((struct pw_client_node_events*)r->iface->events)->set_property(r,__VA_ARGS__)
#define pw_client_node_notify_set_param(r,...) ((struct pw_client_node_events*)r->iface->events)->set_param(r,__VA_ARGS__)
#define pw_client_node_notify_add_mem(r,...) ((struct pw_client_node_events*)r->iface->events)->add_mem(r,__VA_ARGS__)
#define pw_client_node_notify_use_buffers(r,...) ((struct pw_client_node_events*)r->iface->events)->use_buffers(r,__VA_ARGS__)
#define pw_client_node_notify_node_command(r,...) ((struct pw_client_node_events*)r->iface->events)->node_command(r,__VA_ARGS__)
@ -221,7 +528,13 @@ struct pw_client_node_events {
#define PW_CLIENT_EVENT_INFO 0
#define PW_CLIENT_EVENT_NUM 1
/** Client events */
struct pw_client_events {
/**
* Notify client info
*
* \param info info about the client
*/
void (*info) (void *object, struct pw_client_info *info);
};
@ -230,7 +543,13 @@ struct pw_client_events {
#define PW_LINK_EVENT_INFO 0
#define PW_LINK_EVENT_NUM 1
/** Link events */
struct pw_link_events {
/**
* Notify link info
*
* \param info info about the link
*/
void (*info) (void *object, struct pw_link_info *info);
};

View file

@ -24,14 +24,6 @@
#include "pipewire/client/context.h"
#include "pipewire/client/subscribe.h"
/**
* pw_node_state_as_string:
* @state: a #enum pw_node_state
*
* Return the string representation of @state.
*
* Returns: the string representation of @state.
*/
const char *pw_node_state_as_string(enum pw_node_state state)
{
switch (state) {
@ -49,14 +41,6 @@ const char *pw_node_state_as_string(enum pw_node_state state)
return "invalid-state";
}
/**
* pw_direction_as_string:
* @direction: a #enum pw_direction
*
* Return the string representation of @direction.
*
* Returns: the string representation of @direction.
*/
const char *pw_direction_as_string(enum pw_direction direction)
{
switch (direction) {
@ -70,14 +54,6 @@ const char *pw_direction_as_string(enum pw_direction direction)
return "invalid-direction";
}
/**
* pw_link_state_as_string:
* @state: a #enum pw_link_state
*
* Return the string representation of @state.
*
* Returns: the string representation of @state.
*/
const char *pw_link_state_as_string(enum pw_link_state state)
{
switch (state) {

View file

@ -32,87 +32,52 @@ struct pw_context;
#include <pipewire/client/context.h>
#include <pipewire/client/properties.h>
/**
* pw_node_state:
* @PW_NODE_STATE_ERROR: the node is in error
* @PW_NODE_STATE_CREATING: the node is being created
* @PW_NODE_STATE_SUSPENDED: the node is suspended, the device might
* be closed
* @PW_NODE_STATE_IDLE: the node is running but there is no active
* port
* @PW_NODE_STATE_RUNNING: the node is running
*
* The different node states
*/
/** \enum pw_node_state The different node states \memberof pw_node */
enum pw_node_state {
PW_NODE_STATE_ERROR = -1,
PW_NODE_STATE_CREATING = 0,
PW_NODE_STATE_SUSPENDED = 1,
PW_NODE_STATE_IDLE = 2,
PW_NODE_STATE_RUNNING = 3,
PW_NODE_STATE_ERROR = -1, /**< error state */
PW_NODE_STATE_CREATING = 0, /**< the node is being created */
PW_NODE_STATE_SUSPENDED = 1, /**< the node is suspended, the device might
* be closed */
PW_NODE_STATE_IDLE = 2, /**< the node is running but there is no active
* port */
PW_NODE_STATE_RUNNING = 3, /**< the node is running */
};
const char *
pw_node_state_as_string(enum pw_node_state state);
/** Convert a \ref pw_node_state to a readable string \memberof pw_node */
const char * pw_node_state_as_string(enum pw_node_state state);
/**
* pw_direction:
* @PW_DIRECTION_INVALID: invalid direction
* @PW_DIRECTION_INPUT: an input port
* @PW_DIRECTION_OUTPUT: an output port
*
* The direction of a port
*/
/** \enum pw_direction The direction of a port \memberof pw_introspect */
enum pw_direction {
PW_DIRECTION_INPUT = SPA_DIRECTION_INPUT,
PW_DIRECTION_OUTPUT = SPA_DIRECTION_OUTPUT
PW_DIRECTION_INPUT = SPA_DIRECTION_INPUT, /**< an input port direction */
PW_DIRECTION_OUTPUT = SPA_DIRECTION_OUTPUT /**< an output port direction */
};
const char *
pw_direction_as_string(enum pw_direction direction);
/** Convert a \ref pw_direction to a readable string \memberof pw_introspect */
const char * pw_direction_as_string(enum pw_direction direction);
/**
* pw_link_state:
* @PW_LINK_STATE_ERROR: the link is in error
* @PW_LINK_STATE_UNLINKED: the link is unlinked
* @PW_LINK_STATE_INIT: the link is initialized
* @PW_LINK_STATE_NEGOTIATING: the link is negotiating formats
* @PW_LINK_STATE_ALLOCATING: the link is allocating buffers
* @PW_LINK_STATE_PAUSED: the link is paused
* @PW_LINK_STATE_RUNNING: the link is running
*
* The different link states
*/
/** \enum pw_link_state The different link states \memberof pw_link */
enum pw_link_state {
PW_LINK_STATE_ERROR = -2,
PW_LINK_STATE_UNLINKED = -1,
PW_LINK_STATE_INIT = 0,
PW_LINK_STATE_NEGOTIATING = 1,
PW_LINK_STATE_ALLOCATING = 2,
PW_LINK_STATE_PAUSED = 3,
PW_LINK_STATE_RUNNING = 4,
PW_LINK_STATE_ERROR = -2, /**< the link is in error */
PW_LINK_STATE_UNLINKED = -1, /**< the link is unlinked */
PW_LINK_STATE_INIT = 0, /**< the link is initialized */
PW_LINK_STATE_NEGOTIATING = 1, /**< the link is negotiating formats */
PW_LINK_STATE_ALLOCATING = 2, /**< the link is allocating buffers */
PW_LINK_STATE_PAUSED = 3, /**< the link is paused */
PW_LINK_STATE_RUNNING = 4, /**< the link is running */
};
const char *
pw_link_state_as_string(enum pw_link_state state);
/** Convert a \ref pw_link_state to a readable string \memberof pw_link */
const char * pw_link_state_as_string(enum pw_link_state state);
/**
* pw_core_info:
* @id: generic id of the core
* @change_mask: bitfield of changed fields since last call
* @user_name: name of the user that started the core
* @host_name: name of the machine the core is running on
* @version: version of the core
* @name: name of the core
* @cookie: a random cookie for identifying this instance of PipeWire
* @props: extra properties
/** \class pw_introspect
*
* The core information. Extra information can be added in later
* versions.
* The introspection methods and structures are used to get information
* about the object in the PipeWire server
*/
/** The core information. Extra information can be added in later versions \memberof pw_introspect */
struct pw_core_info {
uint32_t id;
uint64_t change_mask;
uint32_t id; /**< server side id of the core */
#define PW_CORE_CHANGE_MASK_USER_NAME (1 << 0)
#define PW_CORE_CHANGE_MASK_HOST_NAME (1 << 1)
#define PW_CORE_CHANGE_MASK_VERSION (1 << 2)
@ -120,68 +85,63 @@ struct pw_core_info {
#define PW_CORE_CHANGE_MASK_COOKIE (1 << 4)
#define PW_CORE_CHANGE_MASK_PROPS (1 << 5)
#define PW_CORE_CHANGE_MASK_ALL (~0)
const char *user_name;
const char *host_name;
const char *version;
const char *name;
uint32_t cookie;
struct spa_dict *props;
uint64_t change_mask; /**< bitfield of changed fields since last call */
const char *user_name; /**< name of the user that started the core */
const char *host_name; /**< name of the machine the core is running on */
const char *version; /**< version of the core */
const char *name; /**< name of the core */
uint32_t cookie; /**< a random cookie for identifying this instance of PipeWire */
struct spa_dict *props; /**< extra properties */
};
/** Update and existing \ref pw_core_info with \a update \memberof pw_introspect */
struct pw_core_info *
pw_core_info_update(struct pw_core_info *info,
const struct pw_core_info *update);
void
pw_core_info_free(struct pw_core_info *info);
/** Free a \ref pw_core_info \memberof pw_introspect */
void pw_core_info_free(struct pw_core_info *info);
/**
* pw_core_info_cb_t:
* @c: a #struct pw_context
* @info: a #struct pw_core_info
* @user_data: user data
/** Callback with information about the PipeWire core
* \param c A \ref pw_context
* \param res A result code
* \param info a \ref pw_core_info
* \param user_data user data as passed to \ref pw_context_get_core_info()
*
* Callback with information about the PipeWire core in @info.
* \memberof pw_introspect
*/
typedef void (*pw_core_info_cb_t) (struct pw_context *c,
int res, const struct pw_core_info *info, void *user_data);
void
pw_context_get_core_info(struct pw_context *context, pw_core_info_cb_t cb, void *user_data);
void pw_context_get_core_info(struct pw_context *context, pw_core_info_cb_t cb, void *user_data);
/**
* pw_module_info:
* @id: generic id of the module
* @change_mask: bitfield of changed fields since last call
* @props: extra properties
*
* The module information. Extra information can be added in later
* versions.
*/
/** The module information. Extra information can be added in later versions \memberof pw_introspect */
struct pw_module_info {
uint32_t id;
uint64_t change_mask;
const char *name;
const char *filename;
const char *args;
struct spa_dict *props;
uint32_t id; /**< server side id of the module */
uint64_t change_mask; /**< bitfield of changed fields since last call */
const char *name; /**< name of the module */
const char *filename; /**< filename of the module */
const char *args; /**< arguments passed to the module */
struct spa_dict *props; /**< extra properties */
};
/** Update and existing \ref pw_module_info with \a update \memberof pw_introspect */
struct pw_module_info *
pw_module_info_update(struct pw_module_info *info,
const struct pw_module_info *update);
void
pw_module_info_free(struct pw_module_info *info);
/** Free a \ref pw_module_info \memberof pw_introspect */
void pw_module_info_free(struct pw_module_info *info);
/**
* pw_module_info_cb_t:
* @c: a #struct pw_context
* @info: a #struct pw_module_info
* @user_data: user data
/** Callback with information about a module
* \param c A \ref pw_context
* \param res A result code
* \param info a \ref pw_module_info
* \param user_data user data as passed to \ref pw_context_list_module_info()
*
* Callback with information about the PipeWire module in @info.
* \memberof pw_introspect
*/
typedef void (*pw_module_info_cb_t) (struct pw_context *c,
int res, const struct pw_module_info *info, void *user_data);
@ -189,40 +149,35 @@ typedef void (*pw_module_info_cb_t) (struct pw_context *c,
void
pw_context_list_module_info(struct pw_context *context,
pw_module_info_cb_t cb, void *user_data);
void
pw_context_get_module_info_by_id(struct pw_context *context,
uint32_t id, pw_module_info_cb_t cb, void *user_data);
/**
* pw_client_info:
* @id: generic id of the client
* @change_mask: bitfield of changed fields since last call
* @props: extra properties
*
* The client information. Extra information can be added in later
* versions.
*/
/** The client information. Extra information can be added in later versions \memberof pw_introspect */
struct pw_client_info {
uint32_t id;
uint64_t change_mask;
struct spa_dict *props;
uint32_t id; /**< server side id of the client */
uint64_t change_mask; /**< bitfield of changed fields since last call */
struct spa_dict *props; /**< extra properties */
};
/** Update and existing \ref pw_client_info with \a update \memberof pw_introspect */
struct pw_client_info *
pw_client_info_update(struct pw_client_info *info,
const struct pw_client_info *update);
void
pw_client_info_free(struct pw_client_info *info);
/** Free a \ref pw_client_info \memberof pw_introspect */
void pw_client_info_free(struct pw_client_info *info);
/**
* pw_client_info_cb_t:
* @c: a #struct pw_context
* @info: a #struct pw_client_info
* @user_data: user data
/** Callback with information about a client
* \param c A \ref pw_context
* \param res A result code
* \param info a \ref pw_client_info
* \param user_data user data as passed to \ref pw_context_list_client_info()
*
* Callback with information about the PipeWire client in @info.
* \memberof pw_introspect
*/
typedef void (*pw_client_info_cb_t) (struct pw_context *c,
int res, const struct pw_client_info *info, void *user_data);
@ -235,33 +190,22 @@ void
pw_context_get_client_info_by_id(struct pw_context *context,
uint32_t id, pw_client_info_cb_t cb, void *user_data);
/**
* pw_node_info:
* @id: generic id of the node
* @change_mask: bitfield of changed fields since last call
* @name: name the node, suitable for display
* @state: the current state of the node
* @error: an error reason if @state is error
* @props: the properties of the node
*
* The node information. Extra information can be added in later
* versions.
*/
/** The node information. Extra information can be added in later versions \memberof pw_introspect */
struct pw_node_info {
uint32_t id;
uint64_t change_mask;
const char *name;
uint32_t max_inputs;
uint32_t n_inputs;
uint32_t n_input_formats;
struct spa_format **input_formats;
uint32_t max_outputs;
uint32_t n_outputs;
uint32_t n_output_formats;
struct spa_format **output_formats;
enum pw_node_state state;
const char *error;
struct spa_dict *props;
uint32_t id; /**< server side id of the node */
uint64_t change_mask; /**< bitfield of changed fields since last call */
const char *name; /**< name the node, suitable for display */
uint32_t max_inputs; /**< maximum number of inputs */
uint32_t n_inputs; /**< number of inputs */
uint32_t n_input_formats; /**< number of input formats */
struct spa_format **input_formats; /**< array of input formats */
uint32_t max_outputs; /**< maximum number of outputs */
uint32_t n_outputs; /**< number of outputs */
uint32_t n_output_formats; /**< number of output formats */
struct spa_format **output_formats; /**< array of output formats */
enum pw_node_state state; /**< the current state of the node */
const char *error; /**< an error reason if \a state is error */
struct spa_dict *props; /**< the properties of the node */
};
struct pw_node_info *
@ -271,13 +215,13 @@ pw_node_info_update(struct pw_node_info *info,
void
pw_node_info_free(struct pw_node_info *info);
/**
* pw_node_info_cb_t:
* @c: a #struct pw_context
* @info: a #struct pw_node_info
* @user_data: user data
/** Callback with information about a node
* \param c A \ref pw_context
* \param res A result code
* \param info a \ref pw_node_info
* \param user_data user data as passed to \ref pw_context_list_node_info()
*
* Callback with information about the PipeWire node in @info.
* \memberof pw_introspect
*/
typedef void (*pw_node_info_cb_t) (struct pw_context *c,
int res, const struct pw_node_info *info, void *user_data);
@ -290,25 +234,14 @@ pw_context_get_node_info_by_id(struct pw_context *context,
uint32_t id, pw_node_info_cb_t cb, void *user_data);
/**
* pw_link_info:
* @id: generic id of the link
* @change_mask: bitfield of changed fields since last call
* @output_node_path: the output node
* @output_port: the output port
* @input_node_path: the input node
* @input_port: the input port
*
* The link information. Extra information can be added in later
* versions.
*/
/** The link information. Extra information can be added in later versions \memberof pw_introspect */
struct pw_link_info {
uint32_t id;
uint64_t change_mask;
uint32_t output_node_id;
uint32_t output_port_id;
uint32_t input_node_id;
uint32_t input_port_id;
uint32_t id; /**< server side id of the link */
uint64_t change_mask; /**< bitfield of changed fields since last call */
uint32_t output_node_id; /**< server side output node id */
uint32_t output_port_id; /**< output port id */
uint32_t input_node_id; /**< server side input node id */
uint32_t input_port_id; /**< input port id */
};
struct pw_link_info *
@ -319,13 +252,13 @@ void
pw_link_info_free(struct pw_link_info *info);
/**
* pw_link_info_cb_t:
* @c: a #struct pw_context
* @info: a #struct pw_link_info
* @user_data: user data
/** Callback with information about a link
* \param c A \ref pw_context
* \param res A result code
* \param info a \ref pw_link_info
* \param user_data user data as passed to \ref pw_context_list_link_info()
*
* Callback with information about the PipeWire link in @info.
* \memberof pw_introspect
*/
typedef void (*pw_link_info_cb_t) (struct pw_context *c,
int res, const struct pw_link_info *info, void *user_data);

View file

@ -29,6 +29,7 @@
enum spa_log_level pw_log_level = DEFAULT_LOG_LEVEL;
/** \cond */
#define TRACE_BUFFER (16*1024)
struct debug_log {
@ -37,6 +38,7 @@ struct debug_log {
uint8_t trace_data[TRACE_BUFFER];
struct spa_source *source;
};
/** \endcond */
static void
do_logv(struct spa_log *log,
@ -99,11 +101,19 @@ static struct debug_log log = {
{0, 0, TRACE_BUFFER, TRACE_BUFFER - 1},
};
/** Get the global log interface
* \return the global log
* \memberof pw_log
*/
struct spa_log *pw_log_get(void)
{
return &log.log;
}
/** Set the global log level
* \param level the new log level
* \memberof pw_log
*/
void pw_log_set_level(enum spa_log_level level)
{
pw_log_level = level;
@ -138,6 +148,14 @@ static void on_trace_event(struct spa_source *source)
}
}
/** Set the trace notify event
* \param source the trace notify event
*
* When the trace log has produced new logging in the ringbuffer, this event
* will be triggered and will then write the trace log to stderr
*
* \memberof pw_log
*/
void pw_log_set_trace_event(struct spa_source *source)
{
log.source = source;
@ -145,6 +163,16 @@ void pw_log_set_trace_event(struct spa_source *source)
log.source->data = &log;
}
/** Log a message
* \param level the log level
* \param file the file this message originated from
* \param line the line number
* \param func the function
* \param fmt the printf style format
* \param ... printf style arguments to log
*
* \memberof pw_log
*/
void
pw_log_log(enum spa_log_level level,
const char *file,
@ -160,6 +188,16 @@ pw_log_log(enum spa_log_level level,
}
}
/** Log a message with va_list
* \param level the log level
* \param file the file this message originated from
* \param line the line number
* \param func the function
* \param fmt the printf style format
* \param args a va_list of arguments
*
* \memberof pw_log
*/
void
pw_log_logv(enum spa_log_level level,
const char *file,
@ -172,3 +210,35 @@ pw_log_logv(enum spa_log_level level,
do_logv(&log.log, level, file, line, func, fmt, args);
}
}
/** \fn void pw_log_error (const char *format, ...)
* Log an error message
* \param format a printf style format
* \param ... printf style arguments
* \memberof pw_log
*/
/** \fn void pw_log_warn (const char *format, ...)
* Log a warning message
* \param format a printf style format
* \param ... printf style arguments
* \memberof pw_log
*/
/** \fn void pw_log_info (const char *format, ...)
* Log an info message
* \param format a printf style format
* \param ... printf style arguments
* \memberof pw_log
*/
/** \fn void pw_log_debug (const char *format, ...)
* Log a debug message
* \param format a printf style format
* \param ... printf style arguments
* \memberof pw_log
*/
/** \fn void pw_log_trace (const char *format, ...)
* Log a trace message. Trace messages may be generated from
* \param format a printf style format
* \param ... printf style arguments
* realtime threads
* \memberof pw_log
*/

View file

@ -27,6 +27,16 @@
extern "C" {
#endif
/** \class pw_log
*
* Logging functions of PipeWire
*
* Loggin is performed to stdout and stderr. Trace logging is performed
* in a lockfree ringbuffer and written out from the main thread as to not
* block the realtime threads.
*/
/** The global log level */
extern enum spa_log_level pw_log_level;
struct spa_log *pw_log_get(void);
@ -50,6 +60,8 @@ pw_log_logv(enum spa_log_level level,
int line, const char *func,
const char *fmt, va_list args) SPA_PRINTF_FUNC(5, 0);
/** Check if a loglevel is enabled \memberof pw_log */
#define pw_log_level_enabled(lev) (pw_log_level >= (lev))
#if __STDC_VERSION__ >= 199901L
@ -68,15 +80,15 @@ pw_log_logv(enum spa_log_level level,
#include <stdarg.h>
#define PW_LOG_FUNC(name,lev) \
static inline void pw_log_##name (const char *format, ...) \
{ \
if (SPA_UNLIKELY(pw_log_level_enabled(lev))) { \
va_list varargs; \
va_start(varargs, format); \
pw_log_logv(lev,__FILE__,__LINE__,__func__,format,varargs); \
va_end(varargs); \
} \
#define PW_LOG_FUNC(name,lev) \
static inline void pw_log_##name (const char *format, ...) SPA_PRINTF_FUNC(1, 0); \
{ \
if (SPA_UNLIKELY(pw_log_level_enabled(lev))) { \
va_list varargs; \
va_start(varargs, format); \
pw_log_logv(lev,__FILE__,__LINE__,__func__,format,varargs); \
va_end(varargs); \
} \
}
PW_LOG_FUNC(error, SPA_LOG_LEVEL_ERROR)

View file

@ -37,6 +37,8 @@
#define DATAS_SIZE (4096 * 8)
/** \cond */
struct invoke_item {
size_t item_size;
spa_invoke_func_t func;
@ -86,6 +88,7 @@ struct source_impl {
int signal_number;
bool enabled;
};
/** \endcond */
static inline uint32_t spa_io_to_epoll(enum spa_io mask)
{
@ -574,6 +577,10 @@ static void loop_destroy_source(struct spa_source *source)
spa_list_insert(&loop_impl->destroy_list, &impl->link);
}
/** Create a new loop
* \returns a newly allocated loop
* \memberof pw_loop
*/
struct pw_loop *pw_loop_new(void)
{
struct impl *impl;
@ -634,6 +641,10 @@ struct pw_loop *pw_loop_new(void)
return NULL;
}
/** Destroy a loop
* \param loop a loop to destroy
* \memberof pw_loop
*/
void pw_loop_destroy(struct pw_loop *loop)
{
struct impl *impl = SPA_CONTAINER_OF(loop, struct impl, this);

View file

@ -28,17 +28,20 @@ extern "C" {
#include <spa/loop.h>
#include <pipewire/client/sig.h>
/**
* pw_loop:
/** \class pw_loop
*
* PipeWire loop interface.
* PipeWire loop interface provides an implementation of
* the spa loop interfaces. It can be used to implement various
* event loops.
*/
struct pw_loop {
struct spa_loop *loop;
struct spa_loop_control *control;
struct spa_loop_utils *utils;
struct spa_loop *loop; /**< wrapped loop */
struct spa_loop_control *control; /**< loop control */
struct spa_loop_utils *utils; /**< loop utils */
/** Emited before the loop iteration starts */
PW_SIGNAL(before_iterate, (struct pw_listener *listener, struct pw_loop *loop));
/** Emited when the loop is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_loop *loop));
};

View file

@ -31,14 +31,21 @@ extern "C" {
#include <pipewire/client/array.h>
#include <pipewire/client/log.h>
/** \class pw_map
*
* A map that holds objects indexed by id
*/
/** An entry in the map \memberof pw_map */
union pw_map_item {
uint32_t next;
void *data;
uint32_t next; /**< next free index */
void *data; /**< data of this item, must be an even address */
};
/** A map \memberof pw_map */
struct pw_map {
struct pw_array items;
uint32_t free_list;
struct pw_array items; /**< an array with the map items */
uint32_t free_list; /**< the free items */
};
#define PW_MAP_INIT(extend) { PW_ARRAY_INIT(extend), 0 }
@ -51,9 +58,17 @@ struct pw_map {
#define pw_map_has_item(m,id) (pw_map_check_id(m,id) && !pw_map_id_is_free(m, id))
#define pw_map_lookup_unchecked(m,id) pw_map_get_item(m,id)->data
/** Convert an id to a pointer that can be inserted into the map \memberof pw_map */
#define PW_MAP_ID_TO_PTR(id) (SPA_UINT32_TO_PTR((id)<<1))
/** Convert a pointer to an id that can be retrieved from the map \memberof pw_map */
#define PW_MAP_PTR_TO_ID(p) (SPA_PTR_TO_UINT32(p)>>1)
/** Initialize a map
* \param map the map to initialize
* \param size the initial size of the map
* \param extend the amount to bytes to grow the map with when needed
* \memberof pw_map
*/
static inline void pw_map_init(struct pw_map *map, size_t size, size_t extend)
{
pw_array_init(&map->items, extend);
@ -61,11 +76,21 @@ static inline void pw_map_init(struct pw_map *map, size_t size, size_t extend)
map->free_list = 0;
}
/** Clear a map
* \param map the map to clear
* \memberof pw_map
*/
static inline void pw_map_clear(struct pw_map *map)
{
pw_array_clear(&map->items);
}
/** Insert data in the map
* \param map the map to insert into
* \param data the item to add
* \return the id where the item was inserted
* \memberof pw_map
*/
static inline uint32_t pw_map_insert_new(struct pw_map *map, void *data)
{
union pw_map_item *start, *item;
@ -86,6 +111,13 @@ static inline uint32_t pw_map_insert_new(struct pw_map *map, void *data)
return id;
}
/** Insert data in the map at an index
* \param map the map to inser into
* \param id the index to insert at
* \param data the data to insert
* \return true on success, false when the index is invalid
* \memberof pw_map
*/
static inline bool pw_map_insert_at(struct pw_map *map, uint32_t id, void *data)
{
size_t size = pw_map_get_size(map);
@ -102,12 +134,23 @@ static inline bool pw_map_insert_at(struct pw_map *map, uint32_t id, void *data)
return true;
}
/** Remove and item at index
* \param map the map to remove from
* \param id the index to remove
* \memberof pw_map
*/
static inline void pw_map_remove(struct pw_map *map, uint32_t id)
{
pw_map_get_item(map, id)->next = map->free_list;
map->free_list = (id << 1) | 1;
}
/** Find an item in the map
* \param map the map to use
* \param id the index to look at
* \return the item at \a id or NULL when no such item exists
* \memberof pw_map
*/
static inline void *pw_map_lookup(struct pw_map *map, uint32_t id)
{
if (SPA_LIKELY(pw_map_check_id(map, id))) {
@ -118,6 +161,12 @@ static inline void *pw_map_lookup(struct pw_map *map, uint32_t id)
return NULL;
}
/** Iterate all map items
* \param map the map to iterate
* \param func the function to call for each item
* \param data data to pass to \a func
* \memberof pw_map
*/
static inline void pw_map_for_each(struct pw_map *map, void (*func) (void *, void *), void *data)
{
union pw_map_item *item;

View file

@ -27,11 +27,13 @@
#include <pipewire/client/map.h>
/** \cond */
struct impl {
struct spa_type_map map;
struct pw_map types;
struct pw_array strings;
};
/** \endcond */
static uint32_t type_map_get_id(struct spa_type_map *map, const char *type)
{
@ -86,6 +88,10 @@ static struct impl default_type_map = {
PW_ARRAY_INIT(4096)
};
/** Get the default type map
* \return the default type map
* \memberof pw_pipewire
*/
struct spa_type_map *pw_type_map_get_default(void)
{
spa_type_map_set_default(&default_type_map.map);

View file

@ -76,6 +76,11 @@ static inline int memfd_create(const char *name, unsigned int flags)
#undef USE_MEMFD
/** Map a memblock
* \param mem a memblock
* \return 0 on success, < 0 on error
* \memberof pw_memblock
*/
int pw_memblock_map(struct pw_memblock *mem)
{
if (mem->ptr != NULL)
@ -124,6 +129,13 @@ int pw_memblock_map(struct pw_memblock *mem)
return SPA_RESULT_OK;
}
/** Create a new memblock
* \param flags memblock flags
* \param size size to allocate
* \param[out] mem memblock structure to fill
* \return 0 on success, < 0 on error
* \memberof pw_memblock
*/
int pw_memblock_alloc(enum pw_memblock_flags flags, size_t size, struct pw_memblock *mem)
{
bool use_fd;
@ -186,6 +198,10 @@ int pw_memblock_alloc(enum pw_memblock_flags flags, size_t size, struct pw_membl
return SPA_RESULT_NO_MEMORY;
}
/** Free a memblock
* \param mem a memblock
* \memberof pw_memblock
*/
void pw_memblock_free(struct pw_memblock *mem)
{
if (mem == NULL)

View file

@ -26,6 +26,7 @@
extern "C" {
#endif
/** Flags passed to \ref pw_memblock_alloc() \memberof pw_memblock */
enum pw_memblock_flags {
PW_MEMBLOCK_FLAG_NONE = 0,
PW_MEMBLOCK_FLAG_WITH_FD = (1 << 0),
@ -37,12 +38,14 @@ enum pw_memblock_flags {
#define PW_MEMBLOCK_FLAG_MAP_READWRITE (PW_MEMBLOCK_FLAG_MAP_READ | PW_MEMBLOCK_FLAG_MAP_WRITE)
/** \class pw_memblock
* Memory block structure */
struct pw_memblock {
enum pw_memblock_flags flags;
int fd;
off_t offset;
void *ptr;
size_t size;
enum pw_memblock_flags flags; /**< flags used when allocating */
int fd; /**< memfd if any */
off_t offset; /**< offset of mappable memory */
void *ptr; /**< ptr to mapped memory */
size_t size; /**< size of mapped memory */
};
int

View file

@ -40,13 +40,17 @@ static void configure_debug(const char *str)
categories = pw_split_strv(level[1], ",", INT_MAX, &n_tokens);
}
/**
* pw_init:
* @argc: pointer to argc
* @argv: pointer to argv
/** Initialize PipeWire
*
* initialize the PipeWire system, parse and modify any parameters given
* by @argc and @argv.
* \param argc pointer to argc
* \param argv pointer to argv
*
* Initialize the PipeWire system, parse and modify any parameters given
* by \a argc and \a argv and set up debugging.
*
* The environment variable \a PIPEWIRE_DEBUG
*
* \memberof pw_pipewire
*/
void pw_init(int *argc, char **argv[])
{
@ -56,6 +60,16 @@ void pw_init(int *argc, char **argv[])
configure_debug(str);
}
/** Check if a debug category is enabled
*
* \param name the name of the category to check
* \return true if enabled
*
* Debugging categories can be enabled by using the PIPEWIRE_DEBUG
* environment variable
*
* \memberof pw_pipewire
*/
bool pw_debug_is_category_enabled(const char *name)
{
int i;
@ -70,11 +84,13 @@ bool pw_debug_is_category_enabled(const char *name)
return false;
}
/** Get the application name \memberof pw_pipewire */
const char *pw_get_application_name(void)
{
return NULL;
}
/** Get the program name \memberof pw_pipewire */
const char *pw_get_prgname(void)
{
static char tcomm[16 + 1];
@ -86,6 +102,7 @@ const char *pw_get_prgname(void)
return NULL;
}
/** Get the user name \memberof pw_pipewire */
const char *pw_get_user_name(void)
{
struct passwd *pw;
@ -96,6 +113,7 @@ const char *pw_get_user_name(void)
return NULL;
}
/** Get the host name \memberof pw_pipewire */
const char *pw_get_host_name(void)
{
static char hname[256];
@ -107,12 +125,13 @@ const char *pw_get_host_name(void)
return hname;
}
/**
* pw_client_name:
/** Get the client name
*
* Make a new PipeWire client name that can be used to construct a context.
*
* \memberof pw_pipewire
*/
char *pw_client_name(void)
char *pw_get_client_name(void)
{
char *c;
const char *cc;
@ -127,11 +146,12 @@ char *pw_client_name(void)
}
}
/**
* pw_fill_context_properties:
* @properties: a #struct pw_properties
/** Fill context properties
* \param properties a \ref pw_properties
*
* Fill @properties with a set of default context properties.
* Fill \a properties with a set of default context properties.
*
* \memberof pw_pipewire
*/
void pw_fill_context_properties(struct pw_properties *properties)
{
@ -159,16 +179,18 @@ void pw_fill_context_properties(struct pw_properties *properties)
}
}
/**
* pw_fill_stream_properties
* @properties: a #struct pw_properties
/** Fill stream properties
* \param properties a \ref pw_properties
*
* Fill @properties with a set of default stream properties.
* Fill \a properties with a set of default stream properties.
*
* \memberof pw_pipewire
*/
void pw_fill_stream_properties(struct pw_properties *properties)
{
}
/** Reverse the direction \memberof pw_pipewire */
enum pw_direction pw_direction_reverse(enum pw_direction direction)
{
if (direction == PW_DIRECTION_INPUT)

View file

@ -37,6 +37,10 @@ extern "C" {
#include <spa/type-map.h>
/** \class pw_pipewire
*
* \brief PipeWire initalization and infrasctructure functions
*/
void
pw_init(int *argc, char **argv[]);
@ -56,7 +60,7 @@ const char *
pw_get_host_name(void);
char *
pw_client_name(void);
pw_get_client_name(void);
void
pw_fill_context_properties(struct pw_properties *properties);

View file

@ -20,11 +20,13 @@
#include "pipewire/client/pipewire.h"
#include "pipewire/client/properties.h"
/** \cond */
struct properties {
struct pw_properties this;
struct pw_array items;
};
/** \endcond */
static void add_func(struct pw_properties *this, char *key, char *value)
{
@ -59,14 +61,13 @@ static int find_index(struct pw_properties *this, const char *key)
return -1;
}
/**
* pw_properties_new:
* @key: first key
* @...: value
/** Make a new properties object
*
* Make a new #struct pw_properties with given, NULL-terminated key/value pairs.
* \param key a first key
* \param ... value and more keys NULL terminated
* \return a newly allocated properties object
*
* Returns: a new #struct pw_properties
* \memberof pw_properties
*/
struct pw_properties *pw_properties_new(const char *key, ...)
{
@ -91,13 +92,12 @@ struct pw_properties *pw_properties_new(const char *key, ...)
return &impl->this;
}
/**
* pw_properties_new_dict:
* @dict: a dict
/** Make a new properties object from the given dictionary
*
* Make a new #struct pw_properties with given @dict.
* \param dict a dictionary. keys and values are copied
* \return a new properties object
*
* Returns: a new #struct pw_properties
* \memberof pw_properties
*/
struct pw_properties *pw_properties_new_dict(const struct spa_dict *dict)
{
@ -116,13 +116,12 @@ struct pw_properties *pw_properties_new_dict(const struct spa_dict *dict)
return &impl->this;
}
/**
* pw_properties_copy:
* @properties: a #struct pw_properties
/** Copy a properties object
*
* Make a copy of @properties.
* \param properties properties to copy
* \return a new properties object
*
* Returns: a copy of @properties
* \memberof pw_properties
*/
struct pw_properties *pw_properties_copy(struct pw_properties *properties)
{
@ -140,6 +139,17 @@ struct pw_properties *pw_properties_copy(struct pw_properties *properties)
return copy;
}
/** Merge properties into one
*
* \param oldprops properties to merge into
* \param newprops properties to merge
* \return a newly allocated \ref pw_properties
*
* A new \ref pw_properties is allocated and the properties of
* \a oldprops and \a newprops are copied into it in that order.
*
* \memberof pw_properties
*/
struct pw_properties *pw_properties_merge(struct pw_properties *oldprops,
struct pw_properties *newprops)
{
@ -167,11 +177,11 @@ struct pw_properties *pw_properties_merge(struct pw_properties *oldprops,
return res;
}
/**
* pw_properties_free:
* @properties: a #struct pw_properties
/** Free a properties object
*
* Free @properties
* \param properties the properties to free
*
* \memberof pw_properties
*/
void pw_properties_free(struct pw_properties *properties)
{
@ -214,30 +224,34 @@ static void do_replace(struct pw_properties *properties, char *key, char *value)
}
}
/**
* pw_properties_set:
* @properties: a #struct pw_properties
* @key: a key
* @value: a value
/** Set a property value
*
* Set the property in @properties with @key to @value. Any previous value
* of @key will be overwritten. When @value is %NULL, the key will be
* \param properties the properties to change
* \param key a key
* \param value a value or NULL to remove the key
*
* Set the property in \a properties with \a key to \a value. Any previous value
* of \a key will be overwritten. When \a value is NULL, the key will be
* removed.
*
* \memberof pw_properties
*/
void pw_properties_set(struct pw_properties *properties, const char *key, const char *value)
{
do_replace(properties, strdup(key), value ? strdup(value) : NULL);
}
/**
* pw_properties_setf:
* @properties: a #struct pw_properties
* @key: a key
* @format: a value
* @...: extra arguments
/** Set a property value by format
*
* Set the property in @properties with @key to the value in printf style @format
* Any previous value of @key will be overwritten.
* \param properties a \ref pw_properties
* \param key a key
* \param format a value
* \param ... extra arguments
*
* Set the property in \a properties with \a key to the value in printf style \a format
* Any previous value of \a key will be overwritten.
*
* \memberof pw_properties
*/
void pw_properties_setf(struct pw_properties *properties, const char *key, const char *format, ...)
{
@ -251,14 +265,15 @@ void pw_properties_setf(struct pw_properties *properties, const char *key, const
do_replace(properties, strdup(key), value);
}
/**
* pw_properties_get:
* @properties: a #struct pw_properties
* @key: a key
/** Get a property
*
* Get the property in @properties with @key.
* \param properties a \ref pw_properties
* \param key a key
* \return the property for \a key or NULL when the key was not found
*
* Returns: the property for @key or %NULL when the key was not found
* Get the property in \a properties with \a key.
*
* \memberof pw_properties
*/
const char *pw_properties_get(struct pw_properties *properties, const char *key)
{
@ -271,19 +286,18 @@ const char *pw_properties_get(struct pw_properties *properties, const char *key)
return pw_array_get_unchecked(&impl->items, index, struct spa_dict_item)->value;
}
/**
* pw_properties_iterate:
* @properties: a #struct pw_properties
* @state: state
/** Iterate property values
*
* Iterate over @properties, returning each key in turn. @state should point
* to a pointer holding %NULL to get the first element and will be updated
* after each iteration. When %NULL is returned, all elements have been
* \param properties a \ref pw_properties
* \param state state
* \return The next key or NULL when there are no more keys to iterate.
*
* Iterate over \a properties, returning each key in turn. \a state should point
* to a pointer holding NULL to get the first element and will be updated
* after each iteration. When NULL is returned, all elements have been
* iterated.
*
* Aborting the iteration before %NULL is returned might cause memory leaks.
*
* Returns: The next key or %NULL when there are no more keys to iterate.
* \memberof pw_properties
*/
const char *pw_properties_iterate(struct pw_properties *properties, void **state)
{

View file

@ -26,6 +26,15 @@
#include <spa/dict.h>
/** \class pw_properties
*
* \brief A collection of key/value pairs
*
* Properties are used to pass around arbitrary key/value pairs.
* Both keys and values are strings which keeps things simple.
* Encoding of arbitrary values should be done by using a string
* serialization such as base64 for binary blobs.
*/
struct pw_properties {
struct spa_dict dict;
};

View file

@ -26,6 +26,7 @@
#include "pipewire/client/interfaces.h"
#include "pipewire/client/connection.h"
/** \cond */
struct builder {
struct spa_pod_builder b;
struct pw_connection *connection;
@ -33,6 +34,8 @@ struct builder {
typedef bool(*demarshal_func_t) (void *object, void *data, size_t size);
/** \endcond */
static uint32_t write_pod(struct spa_pod_builder *b, uint32_t ref, const void *data, uint32_t size)
{
if (ref == -1)
@ -525,6 +528,23 @@ static bool client_node_demarshal_done(void *object, void *data, size_t size)
return true;
}
static bool client_node_demarshal_set_props(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_iter it;
uint32_t seq;
const struct spa_props *props = NULL;
if (!spa_pod_iter_struct(&it, data, size) ||
!spa_pod_iter_get(&it,
SPA_POD_TYPE_INT, &seq,
-SPA_POD_TYPE_OBJECT, &props, 0))
return false;
((struct pw_client_node_events *) proxy->implementation)->set_props(proxy, seq, props);
return true;
}
static bool client_node_demarshal_event(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
@ -587,7 +607,8 @@ static bool client_node_demarshal_set_format(void *object, void *data, size_t si
SPA_POD_TYPE_INT, &seq,
SPA_POD_TYPE_INT, &direction,
SPA_POD_TYPE_INT, &port_id,
SPA_POD_TYPE_INT, &flags, -SPA_POD_TYPE_OBJECT, &format, 0))
SPA_POD_TYPE_INT, &flags,
-SPA_POD_TYPE_OBJECT, &format, 0))
return false;
((struct pw_client_node_events *) proxy->implementation)->set_format(proxy, seq, direction,
@ -596,22 +617,24 @@ static bool client_node_demarshal_set_format(void *object, void *data, size_t si
return true;
}
static bool client_node_demarshal_set_property(void *object, void *data, size_t size)
static bool client_node_demarshal_set_param(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_iter it;
uint32_t seq, id;
const void *value;
uint32_t s;
uint32_t seq, direction, port_id;
const struct spa_param *param = NULL;
if (!spa_pod_iter_struct(&it, data, size) ||
!pw_pod_remap_data(SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!spa_pod_iter_get(&it,
SPA_POD_TYPE_INT, &seq,
SPA_POD_TYPE_INT, &id, SPA_POD_TYPE_BYTES, &value, &s, 0))
SPA_POD_TYPE_INT, &direction,
SPA_POD_TYPE_INT, &port_id,
-SPA_POD_TYPE_OBJECT, &param, 0))
return false;
((struct pw_client_node_events *) proxy->implementation)->set_property(proxy, seq, id, s,
value);
((struct pw_client_node_events *) proxy->implementation)->set_param(proxy, seq, direction,
port_id, param);
return true;
}
@ -730,14 +753,19 @@ static bool client_node_demarshal_port_command(void *object, void *data, size_t
struct pw_proxy *proxy = object;
struct spa_pod_iter it;
const struct spa_command *command;
uint32_t port_id;
uint32_t direction, port_id;
if (!spa_pod_iter_struct(&it, data, size) ||
!pw_pod_remap_data(SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &port_id, SPA_POD_TYPE_OBJECT, &command, 0))
!spa_pod_iter_get(&it,
SPA_POD_TYPE_INT, &direction,
SPA_POD_TYPE_INT, &port_id,
SPA_POD_TYPE_OBJECT, &command, 0))
return false;
((struct pw_client_node_events *) proxy->implementation)->port_command(proxy, port_id,
((struct pw_client_node_events *) proxy->implementation)->port_command(proxy,
direction,
port_id,
command);
return true;
}
@ -753,7 +781,8 @@ static bool client_node_demarshal_transport(void *object, void *data, size_t siz
if (!spa_pod_iter_struct(&it, data, size) ||
!spa_pod_iter_get(&it,
SPA_POD_TYPE_INT, &memfd_idx,
SPA_POD_TYPE_INT, &offset, SPA_POD_TYPE_INT, &sz, 0))
SPA_POD_TYPE_INT, &offset,
SPA_POD_TYPE_INT, &sz, 0))
return false;
memfd = pw_connection_get_fd(connection, memfd_idx);
@ -813,14 +842,17 @@ static bool registry_demarshal_global(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_iter it;
uint32_t id;
uint32_t id, version;
const char *type;
if (!spa_pod_iter_struct(&it, data, size) ||
!spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &id, SPA_POD_TYPE_STRING, &type, 0))
!spa_pod_iter_get(&it,
SPA_POD_TYPE_INT, &id,
SPA_POD_TYPE_STRING, &type,
SPA_POD_TYPE_INT, &version, 0))
return false;
((struct pw_registry_events *) proxy->implementation)->global (proxy, id, type);
((struct pw_registry_events *) proxy->implementation)->global (proxy, id, type, version);
return true;
}
@ -838,7 +870,7 @@ static bool registry_demarshal_global_remove(void *object, void *data, size_t si
return true;
}
static void registry_marshal_bind(void *object, uint32_t id, uint32_t new_id)
static void registry_marshal_bind(void *object, uint32_t id, uint32_t version, uint32_t new_id)
{
struct pw_proxy *proxy = object;
struct pw_connection *connection = proxy->context->protocol_private;
@ -850,7 +882,10 @@ static void registry_marshal_bind(void *object, uint32_t id, uint32_t new_id)
core_update_map(proxy->context);
spa_pod_builder_struct(&b.b, &f, SPA_POD_TYPE_INT, id, SPA_POD_TYPE_INT, new_id);
spa_pod_builder_struct(&b.b, &f,
SPA_POD_TYPE_INT, id,
SPA_POD_TYPE_INT, version,
SPA_POD_TYPE_INT, new_id);
pw_connection_end_write(connection, proxy->id, PW_REGISTRY_METHOD_BIND, b.b.offset);
}
@ -900,11 +935,12 @@ static const struct pw_client_node_methods pw_protocol_native_client_client_node
static const demarshal_func_t pw_protocol_native_client_client_node_demarshal[] = {
&client_node_demarshal_done,
&client_node_demarshal_set_props,
&client_node_demarshal_event,
&client_node_demarshal_add_port,
&client_node_demarshal_remove_port,
&client_node_demarshal_set_format,
&client_node_demarshal_set_property,
&client_node_demarshal_set_param,
&client_node_demarshal_add_mem,
&client_node_demarshal_use_buffers,
&client_node_demarshal_node_command,

View file

@ -21,10 +21,26 @@
#include <pipewire/client/proxy.h>
#include <pipewire/client/protocol-native.h>
/** \cond */
struct proxy {
struct pw_proxy this;
};
/** \endcond */
/** Create a proxy object with a given id and type
*
* \param context Context object
* \param id Id of the new object, SPA_ID_INVALID will choose a new id
* \param type Type of the proxy object
* \return A newly allocated proxy object or NULL on failure
*
* This function creates a new proxy object with the supplied id and type. The
* proxy object will have an id assigned from the client id space.
*
* \sa pw_context
*
* \memberof pw_proxy
*/
struct pw_proxy *pw_proxy_new(struct pw_context *context, uint32_t id, uint32_t type)
{
struct proxy *impl;
@ -61,6 +77,14 @@ struct pw_proxy *pw_proxy_new(struct pw_context *context, uint32_t id, uint32_t
return NULL;
}
/** Destroy a proxy object
*
* \param proxy Proxy object to destroy
*
* \note This is normally called by \ref pw_context when the server
* decides to destroy the server side object
* \memberof pw_proxy
*/
void pw_proxy_destroy(struct pw_proxy *proxy)
{
struct proxy *impl = SPA_CONTAINER_OF(proxy, struct proxy, this);

View file

@ -29,27 +29,38 @@ extern "C" {
#include <pipewire/client/type.h>
#include <pipewire/client/utils.h>
/** \class pw_proxy
*
* \brief Represents an object on the client side.
*
* A pw_proxy acts as a client side proxy to an object existing in the
* pipewire server. The proxy is responsible for converting interface functions
* invoked by the client to PipeWire messages. Events will call the handlers
* set in implementation.
*/
struct pw_proxy {
/** the owner context of this proxy */
struct pw_context *context;
/** link in the context */
struct spa_list link;
uint32_t id;
uint32_t type;
uint32_t id; /**< client side id */
uint32_t type; /**< object type id */
const struct pw_interface *iface;
const void *implementation;
const struct pw_interface *iface; /**< methods/events marshal/demarshal functions */
const void *implementation; /**< event handler implementation */
void *user_data;
pw_destroy_t destroy;
void *user_data; /**< optional client user data */
pw_destroy_t destroy; /**< optional destroy function to clean up user_data */
/** destroy_signal is emited when the proxy is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_proxy *proxy));
};
struct pw_proxy *
pw_proxy_new(struct pw_context *context, uint32_t id, uint32_t type);
void
pw_proxy_destroy(struct pw_proxy *proxy);
void pw_proxy_destroy(struct pw_proxy *proxy);
#ifdef __cplusplus
}

View file

@ -51,9 +51,11 @@
#include "rtkit.h"
/** \cond */
struct pw_rtkit_bus {
DBusConnection *bus;
};
/** \endcond */
struct pw_rtkit_bus *pw_rtkit_bus_get_system(void)
{

View file

@ -30,44 +30,58 @@ extern "C" {
#define RTKIT_SERVICE_NAME "org.freedesktop.RealtimeKit1"
#define RTKIT_OBJECT_PATH "/org/freedesktop/RealtimeKit1"
/** \class pw_rtkit
*
* RTKit helpers
*/
/** Get an RTKit bus \memberof pw_rtkit */
struct pw_rtkit_bus *
pw_rtkit_bus_get_system(void);
/** Free an RTKit bus \memberof pw_rtkit */
void
pw_rtkit_bus_free(struct pw_rtkit_bus *system_bus);
/* This is mostly equivalent to sched_setparam(thread, SCHED_RR, {
/** This is mostly equivalent to sched_setparam(thread, SCHED_RR, {
* .sched_priority = priority }). 'thread' needs to be a kernel thread
* id as returned by gettid(), not a pthread_t! If 'thread' is 0 the
* current thread is used. The returned value is a negative errno
* style error code, or 0 on success. */
* style error code, or 0 on success.
* \memberof pw_rtkit
*/
int
pw_rtkit_make_realtime(struct pw_rtkit_bus *system_bus, pid_t thread, int priority);
/* This is mostly equivalent to setpriority(PRIO_PROCESS, thread,
/** This is mostly equivalent to setpriority(PRIO_PROCESS, thread,
* nice_level). 'thread' needs to be a kernel thread id as returned by
* gettid(), not a pthread_t! If 'thread' is 0 the current thread is
* used. The returned value is a negative errno style error code, or
* 0 on success. */
* 0 on success.
* \memberof pw_rtkit
*/
int
pw_rtkit_make_high_priority(struct pw_rtkit_bus *system_bus, pid_t thread, int nice_level);
/* Return the maximum value of realtime priority available. Realtime requests
/** Return the maximum value of realtime priority available. Realtime requests
* above this value will fail. A negative value is an errno style error code.
* \memberof pw_rtkit
*/
int
pw_rtkit_get_max_realtime_priority(struct pw_rtkit_bus *system_bus);
/* Retreive the minimum value of nice level available. High prio requests
/** Retreive the minimum value of nice level available. High prio requests
* below this value will fail. The returned value is a negative errno
* style error code, or 0 on success.*/
* style error code, or 0 on success.
* \memberof pw_rtkit
*/
int
pw_rtkit_get_min_nice_level(struct pw_rtkit_bus *system_bus, int *min_nice_level);
/* Return the maximum value of RLIMIT_RTTIME to set before attempting a
/** Return the maximum value of RLIMIT_RTTIME to set before attempting a
* realtime request. A negative value is an errno style error code.
* \memberof pw_rtkit
*/
long long
pw_rtkit_get_rttime_usec_max(struct pw_rtkit_bus *system_bus);

View file

@ -26,20 +26,28 @@
extern "C" {
#endif
/** \class pw_signal
* Signal emission helpers
*/
/** A listener \memberof pw_signal */
struct pw_listener {
struct spa_list link;
void (*notify) (void *);
struct spa_list link; /**< link in the signal listeners */
void (*notify) (void *); /**< notify function */
};
/** A signal definition \memberof pw_signal */
#define PW_SIGNAL(name,func) \
union { \
struct spa_list listeners; \
void (*notify) func; \
} name;
/** Initialize a signal \memberof pw_signal */
#define pw_signal_init(signal) \
spa_list_init(&(signal)->listeners);
/** Add a signal listener \memberof pw_signal */
#define pw_signal_add(signal,listener,func) \
do { \
__typeof__((signal)->notify) n = (func); \
@ -47,11 +55,13 @@ do { \
spa_list_insert((signal)->listeners.prev, &(listener)->link); \
} while (false);
/** Remove a signal listener \memberof pw_signal */
static inline void pw_signal_remove(struct pw_listener *listener)
{
spa_list_remove(&listener->link);
}
/** Emit a signal \memberof pw_signal */
#define pw_signal_emit(signal,...) \
do { \
struct pw_listener *l, *next; \

View file

@ -36,6 +36,8 @@
#include "pipewire/client/transport.h"
#include "pipewire/client/utils.h"
/** \cond */
#define MAX_BUFFER_SIZE 4096
#define MAX_FDS 32
#define MAX_INPUTS 64
@ -98,6 +100,7 @@ struct stream {
int32_t last_rate;
int64_t last_monotonic;
};
/** \endcond */
static void clear_memid(struct mem_id *mid)
{
@ -153,14 +156,6 @@ static bool stream_set_state(struct pw_stream *stream, enum pw_stream_state stat
return res;
}
/**
* pw_stream_state_as_string:
* @state: a #enum pw_stream_state
*
* Return the string representation of @state.
*
* Returns: the string representation of @state.
*/
const char *pw_stream_state_as_string(enum pw_stream_state state)
{
switch (state) {
@ -182,15 +177,14 @@ const char *pw_stream_state_as_string(enum pw_stream_state state)
return "invalid-state";
}
/**
* pw_stream_new:
* @context: a #struct pw_context
* @name: a stream name
* @properties: (transfer full): stream properties
/** Create a new unconneced \ref pw_stream
*
* Make a new unconnected #struct pw_stream
* \param context a \ref pw_context
* \param name a stream name
* \param props stream properties, ownership is taken
* \return a newly allocated \ref pw_stream
*
* Returns: a new unconnected #struct pw_stream
* \memberof pw_stream
*/
struct pw_stream *pw_stream_new(struct pw_context *context,
const char *name, struct pw_properties *props)
@ -298,6 +292,10 @@ static void set_params(struct pw_stream *stream, int n_params, struct spa_param
}
}
/** Destroy a stream
* \param stream the stream to destroy
* \memberof pw_stream
*/
void pw_stream_destroy(struct pw_stream *stream)
{
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
@ -572,11 +570,6 @@ static void handle_socket(struct pw_stream *stream, int rtreadfd, int rtwritefd)
return;
}
static void handle_node_event(struct pw_stream *stream, const struct spa_event *event)
{
pw_log_warn("unhandled node event %d", SPA_EVENT_TYPE(event));
}
static bool
handle_node_command(struct pw_stream *stream, uint32_t seq, const struct spa_command *command)
{
@ -644,11 +637,15 @@ static void client_node_done(void *object, int readfd, int writefd)
stream_set_state(stream, PW_STREAM_STATE_CONFIGURE, NULL);
}
static void
client_node_set_props(void *object, uint32_t seq, const struct spa_props *props)
{
pw_log_warn("set property not implemented");
}
static void client_node_event(void *object, const struct spa_event *event)
{
struct pw_proxy *proxy = object;
struct pw_stream *stream = proxy->user_data;
handle_node_event(stream, event);
pw_log_warn("unhandled node event %d", SPA_EVENT_TYPE(event));
}
static void
@ -687,9 +684,13 @@ client_node_set_format(void *object,
}
static void
client_node_set_property(void *object, uint32_t seq, uint32_t id, uint32_t size, const void *value)
client_node_set_param(void *object,
uint32_t seq,
enum spa_direction direction,
uint32_t port_id,
const struct spa_param *param)
{
pw_log_warn("set property not implemented");
pw_log_warn("set param not implemented");
}
static void
@ -847,7 +848,10 @@ static void client_node_node_command(void *object, uint32_t seq, const struct sp
}
static void
client_node_port_command(void *object, uint32_t port_id, const struct spa_command *command)
client_node_port_command(void *object,
uint32_t direction,
uint32_t port_id,
const struct spa_command *command)
{
pw_log_warn("port command not supported");
}
@ -874,11 +878,12 @@ static void client_node_transport(void *object, int memfd, uint32_t offset, uint
static const struct pw_client_node_events client_node_events = {
&client_node_done,
&client_node_set_props,
&client_node_event,
&client_node_add_port,
&client_node_remove_port,
&client_node_set_format,
&client_node_set_property,
&client_node_set_param,
&client_node_add_mem,
&client_node_use_buffers,
&client_node_node_command,
@ -897,23 +902,21 @@ static void on_node_proxy_destroy(struct pw_listener *listener, struct pw_proxy
stream_set_state(this, PW_STREAM_STATE_UNCONNECTED, NULL);
}
/**
* pw_stream_connect:
* @stream: a #struct pw_stream
* @direction: the stream direction
* @mode: a #enum pw_stream_mode
* @port_path: the port path to connect to or %NULL to get the default port
* @flags: a #struct pw_stream
* @n_possible_formats: number of items in @possible_formats
* @possible_formats: an array with possible accepted formats
/** Connect a stream for input or output on \a port_path.
* \param stream a \ref pw_stream
* \param direction the stream direction
* \param mode a \ref pw_stream_mode
* \param port_path the port path to connect to or NULL to let the server choose a port
* \param flags a \ref pw_stream
* \param n_possible_formats number of items in \a possible_formats
* \param possible_formats an array with possible accepted formats
* \return true on success.
*
* Connect @stream for input or output on @port_path.
*
* When @mode is #PW_STREAM_MODE_BUFFER, you should connect to the new-buffer
* signal and use pw_stream_capture_buffer() to get the latest metadata and
* When \a mode is \ref PW_STREAM_MODE_BUFFER, you should connect to the new-buffer
* signal and use pw_stream_peek_buffer() to get the latest metadata and
* data.
*
* Returns: %true on success.
* \memberof pw_stream
*/
bool
pw_stream_connect(struct pw_stream *stream,
@ -959,21 +962,22 @@ pw_stream_connect(struct pw_stream *stream,
return true;
}
/**
* pw_stream_finish_format:
* @stream: a #struct pw_stream
* @res: a #int
* @params: an array of pointers to #struct spa_param
* @n_params: number of elements in @params
/** Complete the negotiation process with result code \a res
* \param stream a \ref pw_stream
* \param res a result code
* \param params an array of pointers to \ref spa_param
* \param n_params number of elements in \a params
*
* Complete the negotiation process with result code @res.
* Complete the negotiation process with result code \a res.
*
* This function should be called after notification of the format.
* When @res indicates success, @params contain the parameters for the
* When \a res indicates success, \a params contain the parameters for the
* allocation state.
*
* Returns: %true on success
*
* \memberof pw_stream
*/
bool
pw_stream_finish_format(struct pw_stream *stream,
@ -999,13 +1003,11 @@ pw_stream_finish_format(struct pw_stream *stream,
return true;
}
/**
* pw_stream_disconnect:
* @stream: a #struct pw_stream
/** Disconnect \a stream
* \param stream: a \ref pw_stream
* \return true on success
*
* Disconnect @stream.
*
* Returns: %true on success
* \memberof pw_stream
*/
bool pw_stream_disconnect(struct pw_stream *stream)
{
@ -1036,14 +1038,13 @@ bool pw_stream_get_time(struct pw_stream *stream, struct pw_time *time)
return true;
}
/**
* pw_stream_get_empty_buffer:
* @stream: a #struct pw_stream
/** Get the id of an empty buffer that can be filled
*
* Get the id of an empty buffer that can be filled
*
* Returns: the id of an empty buffer or #SPA_ID_INVALID when no buffer is
* \param stream: a \ref pw_stream
* \return the id of an empty buffer or \ref SPA_ID_INVALID when no buffer is
* available.
*
* \memberof pw_stream
*/
uint32_t pw_stream_get_empty_buffer(struct pw_stream *stream)
{
@ -1058,14 +1059,14 @@ uint32_t pw_stream_get_empty_buffer(struct pw_stream *stream)
return bid->id;
}
/**
* pw_stream_recycle_buffer:
* @stream: a #struct pw_stream
* @id: a buffer id
/** Recycle the buffer with \a id
* \param stream: a \ref pw_stream
* \param id: a buffer id
* \return true on success
*
* Recycle the buffer with @id.
* Let the PipeWire server know that it can reuse the buffer with \a id.
*
* Returns: %true on success.
* \memberof pw_stream
*/
bool pw_stream_recycle_buffer(struct pw_stream *stream, uint32_t id)
{
@ -1087,15 +1088,14 @@ bool pw_stream_recycle_buffer(struct pw_stream *stream, uint32_t id)
return true;
}
/**
* pw_stream_peek_buffer:
* @stream: a #struct pw_stream
* @id: the buffer id
/** Get the buffer with \a id from \a stream
* \param stream: a \ref pw_stream
* \param id: the buffer id
* \return a \ref spa_buffer or NULL when there is no buffer
*
* Get the buffer with @id from @stream. This function should be called from
* the new-buffer signal callback.
* This function should be called from the new-buffer signal callback.
*
* Returns: a #struct spa_buffer or %NULL when there is no buffer.
* \memberof pw_stream
*/
struct spa_buffer *pw_stream_peek_buffer(struct pw_stream *stream, uint32_t id)
{
@ -1107,19 +1107,15 @@ struct spa_buffer *pw_stream_peek_buffer(struct pw_stream *stream, uint32_t id)
return NULL;
}
/**
* pw_stream_send_buffer:
* @stream: a #struct pw_stream
* @id: a buffer id
* @offset: the offset in the buffer
* @size: the size in the buffer
/** Send a buffer with \a id to \a stream
* \param stream a \ref pw_stream
* \param id a buffer id
* \return true when \a id was handled
*
* Send a buffer with @id to @stream.
* For provider or playback streams, this function should be called whenever
* there is a new frame available.
*
* For provider streams, this function should be called whenever there is a new frame
* available.
*
* Returns: %true when @id was handled
* \memberof pw_stream
*/
bool pw_stream_send_buffer(struct pw_stream *stream, uint32_t id)
{

View file

@ -29,63 +29,81 @@
extern "C" {
#endif
/** \enum pw_stream_state The state of a stream \memberof pw_stream */
enum pw_stream_state {
PW_STREAM_STATE_ERROR = -1,
PW_STREAM_STATE_UNCONNECTED = 0,
PW_STREAM_STATE_CONNECTING = 1,
PW_STREAM_STATE_CONFIGURE = 2,
PW_STREAM_STATE_READY = 3,
PW_STREAM_STATE_PAUSED = 4,
PW_STREAM_STATE_STREAMING = 5
PW_STREAM_STATE_ERROR = -1, /**< the strean is in error */
PW_STREAM_STATE_UNCONNECTED = 0, /**< unconnected */
PW_STREAM_STATE_CONNECTING = 1, /**< connection is in progress */
PW_STREAM_STATE_CONFIGURE = 2, /**< stream is being configured */
PW_STREAM_STATE_READY = 3, /**< stream is ready */
PW_STREAM_STATE_PAUSED = 4, /**< paused, fully configured but not
* processing data yet */
PW_STREAM_STATE_STREAMING = 5 /**< streaming */
};
const char *
pw_stream_state_as_string(enum pw_stream_state state);
/** Convert a stream state to a readable string \memberof pw_stream */
const char * pw_stream_state_as_string(enum pw_stream_state state);
/** \enum pw_stream_flags Extra flags that can be used in \ref pw_stream_connect() \memberof pw_stream */
enum pw_stream_flags {
PW_STREAM_FLAG_NONE = 0,
PW_STREAM_FLAG_AUTOCONNECT = (1 << 0),
PW_STREAM_FLAG_CLOCK_UPDATE = (1 << 1),
PW_STREAM_FLAG_NONE = 0, /**< no flags */
PW_STREAM_FLAG_AUTOCONNECT = (1 << 0), /**< don't try to automatically connect
* this stream */
PW_STREAM_FLAG_CLOCK_UPDATE = (1 << 1), /**< request periodic clock updates for
* this stream */
};
/** \enum pw_stream_mode The method for transfering data for a stream \memberof pw_stream */
enum pw_stream_mode {
PW_STREAM_MODE_BUFFER = 0,
PW_STREAM_MODE_RINGBUFFER = 1,
PW_STREAM_MODE_BUFFER = 0, /**< data is placed in buffers */
PW_STREAM_MODE_RINGBUFFER = 1, /**< a ringbuffer is used to exchange data */
};
/** A time structure \memberof pw_stream */
struct pw_time {
int64_t now;
int64_t ticks;
int32_t rate;
int64_t now; /**< the monotonic time */
int64_t ticks; /**< the ticks at \a now */
int32_t rate; /**< the rate of \a ticks */
};
/**
* pw_stream:
/** \class pw_stream
*
* PipeWire stream object class.
* \brief PipeWire stream object class
*
* The stream object provides a convenient way to send and
* receive data streams from/to PipeWire.
*/
struct pw_stream {
struct pw_context *context;
struct spa_list link;
struct pw_context *context; /**< the owner context */
struct spa_list link; /**< link in the context */
char *name;
struct pw_properties *properties;
char *name; /**< the name of the stream */
struct pw_properties *properties; /**< properties of the stream */
/** Emited when the stream is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_stream *stream));
enum pw_stream_state state;
char *error;
enum pw_stream_state state; /**< stream state */
char *error; /**< error reason when state is in error */
/** Emited when the stream state changes */
PW_SIGNAL(state_changed, (struct pw_listener *listener, struct pw_stream *stream));
/** Emited when the format changed. The listener should call
* pw_stream_finish_format() to complete format negotiation */
PW_SIGNAL(format_changed, (struct pw_listener *listener,
struct pw_stream *stream, struct spa_format *format));
struct pw_stream *stream, struct spa_format *format));
/** Emited when a new buffer was created for this stream */
PW_SIGNAL(add_buffer, (struct pw_listener *listener,
struct pw_stream *stream, uint32_t id));
struct pw_stream *stream, uint32_t id));
/** Emited when a buffer was destroyed for this stream */
PW_SIGNAL(remove_buffer, (struct pw_listener *listener,
struct pw_stream *stream, uint32_t id));
struct pw_stream *stream, uint32_t id));
/** Emited when a buffer can be reused (for playback streams) or
* is filled (for capture streams */
PW_SIGNAL(new_buffer, (struct pw_listener *listener,
struct pw_stream *stream, uint32_t id));
struct pw_stream *stream, uint32_t id));
/** Emited when a buffer is needed (for playback streams) */
PW_SIGNAL(need_buffer, (struct pw_listener *listener, struct pw_stream *stream));
};

View file

@ -44,6 +44,10 @@ extern "C" {
#define PIPEWIRE_TYPE__Module "PipeWire:Object:Module"
#define PIPEWIRE_TYPE_MODULE_BASE PIPEWIRE_TYPE__Module ":"
/** \class pw_subscribe
*
* subscription events
*/
enum pw_subscription_event {
PW_SUBSCRIPTION_EVENT_NEW = 0,
PW_SUBSCRIPTION_EVENT_CHANGE = 1,

View file

@ -22,6 +22,7 @@
#include "pipewire.h"
#include "thread-mainloop.h"
/** \cond */
struct thread_main_loop {
struct pw_thread_main_loop this;
@ -39,6 +40,7 @@ struct thread_main_loop {
int n_waiting;
int n_waiting_for_accept;
};
/** \endcond */
static void pre_hook(struct spa_loop_control *ctrl, void *data)
{
@ -58,15 +60,19 @@ static void do_stop(struct spa_loop_utils *utils, struct spa_source *source, voi
impl->running = false;
}
/**
* pw_thread_main_loop_new:
* @context: a #GMainContext
* @name: a thread name
/** Create a new \ref pw_thread_main_loop
*
* Make a new #struct pw_thread_main_loop that will run a mainloop on @context in
* a thread with @name.
* \param loop the loop to wrap
* \param name the name of the thread or NULL
* \return a newly allocated \ref pw_thread_main_loop
*
* Returns: a #struct pw_thread_main_loop
* Make a new \ref pw_thread_main_loop that will run a mainloop on \a loop in
* a thread with \a name.
*
* After this function you should probably call pw_thread_main_loop_start() to
* actually start the thread
*
* \memberof pw_thread_main_loop
*/
struct pw_thread_main_loop *pw_thread_main_loop_new(struct pw_loop *loop, const char *name)
{
@ -99,6 +105,7 @@ struct pw_thread_main_loop *pw_thread_main_loop_new(struct pw_loop *loop, const
return this;
}
/** Destroy a threaded main loop \memberof pw_thread_main_loop */
void pw_thread_main_loop_destroy(struct pw_thread_main_loop *loop)
{
struct thread_main_loop *impl = SPA_CONTAINER_OF(loop, struct thread_main_loop, this);
@ -137,13 +144,12 @@ static void *do_loop(void *user_data)
return NULL;
}
/**
* pw_thread_main_loop_start:
* @loop: a #struct pw_thread_main_loop
/** Start the thread to handle \a loop
*
* Start the thread to handle @loop.
* \param loop a \ref pw_thread_main_loop
* \return \ref SPA_RESULT_OK on success
*
* Returns: %SPA_RESULT_OK on success.
* \memberof pw_thread_main_loop
*/
int pw_thread_main_loop_start(struct pw_thread_main_loop *loop)
{
@ -163,11 +169,11 @@ int pw_thread_main_loop_start(struct pw_thread_main_loop *loop)
return SPA_RESULT_OK;
}
/**
* pw_thread_main_loop_stop:
* @loop: a #struct pw_thread_main_loop
/** Quit the main loop and stop its thread
*
* Quit the main loop and stop its thread.
* \param loop a \ref pw_thread_main_loop
*
* \memberof pw_thread_main_loop
*/
void pw_thread_main_loop_stop(struct pw_thread_main_loop *loop)
{
@ -185,11 +191,11 @@ void pw_thread_main_loop_stop(struct pw_thread_main_loop *loop)
pw_log_debug("thread-mainloop: %p stopped", impl);
}
/**
* pw_thread_main_loop_lock:
* @loop: a #struct pw_thread_main_loop
/** Lock the mutex associated with \a loop
*
* Lock the mutex associated with @loop.
* \param loop a \ref pw_thread_main_loop
*
* \memberof pw_thread_main_loop
*/
void pw_thread_main_loop_lock(struct pw_thread_main_loop *loop)
{
@ -197,11 +203,11 @@ void pw_thread_main_loop_lock(struct pw_thread_main_loop *loop)
pthread_mutex_lock(&impl->lock);
}
/**
* pw_thread_main_loop_unlock:
* @loop: a #struct pw_thread_main_loop
/** Unlock the mutex associated with \a loop
*
* Unlock the mutex associated with @loop.
* \param loop a \ref pw_thread_main_loop
*
* \memberof pw_thread_main_loop
*/
void pw_thread_main_loop_unlock(struct pw_thread_main_loop *loop)
{
@ -209,12 +215,15 @@ void pw_thread_main_loop_unlock(struct pw_thread_main_loop *loop)
pthread_mutex_unlock(&impl->lock);
}
/**
* pw_thread_main_loop_signal:
* @loop: a #struct pw_thread_main_loop
/** Signal the main thread
*
* Signal the main thread of @loop. If @wait_for_accept is %TRUE,
* this function waits until pw_thread_main_loop_accept() is called.
* \param loop a \ref pw_thread_main_loop to signal
* \param wait_for_accept if we need to wait for accept
*
* Signal the main thread of \a loop. If \a wait_for_accept is true,
* this function waits until \ref pw_thread_main_loop_accept() is called.
*
* \memberof pw_thread_main_loop
*/
void pw_thread_main_loop_signal(struct pw_thread_main_loop *loop, bool wait_for_accept)
{
@ -231,11 +240,11 @@ void pw_thread_main_loop_signal(struct pw_thread_main_loop *loop, bool wait_for_
}
}
/**
* pw_thread_main_loop_wait:
* @loop: a #struct pw_thread_main_loop
/** Wait for the loop thread to call \ref pw_thread_main_loop_signal()
*
* Wait for the loop thread to call pw_thread_main_loop_signal().
* \param loop a \ref pw_thread_main_loop to signal
*
* \memberof pw_thread_main_loop
*/
void pw_thread_main_loop_wait(struct pw_thread_main_loop *loop)
{
@ -247,11 +256,11 @@ void pw_thread_main_loop_wait(struct pw_thread_main_loop *loop)
impl->n_waiting--;
}
/**
* pw_thread_main_loop_accept:
* @loop: a #struct pw_thread_main_loop
/** Signal the loop thread waiting for accept with \ref pw_thread_main_loop_signal()
*
* Signal the loop thread waiting for accept with pw_thread_main_loop_signal().
* \param loop a \ref pw_thread_main_loop to signal
*
* \memberof pw_thread_main_loop
*/
void pw_thread_main_loop_accept(struct pw_thread_main_loop *loop)
{
@ -261,13 +270,12 @@ void pw_thread_main_loop_accept(struct pw_thread_main_loop *loop)
pthread_cond_signal(&impl->accept_cond);
}
/**
* pw_thread_main_loop_in_thread:
* @loop: a #struct pw_thread_main_loop
/** Check if we are inside the thread of the loop
*
* Check if we are inside the thread of @loop.
* \param loop a \ref pw_thread_main_loop to signal
* \return true when called inside the thread of \a loop.
*
* Returns: %TRUE when called inside the thread of @loop.
* \memberof pw_thread_main_loop
*/
bool pw_thread_main_loop_in_thread(struct pw_thread_main_loop *loop)
{

View file

@ -26,15 +26,21 @@
extern "C" {
#endif
/**
* pw_thread_main_loop:
/** \class pw_thread_main_loop
*
* PipeWire main loop object class.
* \brief PipeWire threaded main loop object
*
* The threaded main loop object runs a \ref pw_loop in a separate thread
* and ensures proper locking is done.
*
* All of the loop callbacks will be executed with the main loop
* lock held.
*/
struct pw_thread_main_loop {
struct pw_loop *loop;
char *name;
struct pw_loop *loop; /**< the \ref pw_loop that is wrapped */
char *name; /**< the thread name */
/** Emited when the mainloop is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener,
struct pw_thread_main_loop *loop));
};

View file

@ -24,6 +24,8 @@
#include <pipewire/client/log.h>
#include <pipewire/client/transport.h>
/** \cond */
#define INPUT_BUFFER_SIZE (1<<12)
#define OUTPUT_BUFFER_SIZE (1<<12)
@ -41,6 +43,7 @@ struct transport {
struct spa_event current;
uint32_t current_index;
};
/** \endcond */
static size_t transport_area_get_size(struct pw_transport_area *area)
{
@ -98,6 +101,12 @@ static void transport_reset_area(struct pw_transport *trans)
spa_ringbuffer_init(trans->output_buffer, OUTPUT_BUFFER_SIZE);
}
/** Create a new transport
* \param max_inputs maximum number of inputs
* \param max_outputs maximum number of outputs
* \return a newly allocated \ref pw_transport
* \memberof pw_transport
*/
struct pw_transport *pw_transport_new(uint32_t max_inputs, uint32_t max_outputs)
{
struct transport *impl;
@ -171,7 +180,10 @@ struct pw_transport *pw_transport_new_from_info(struct pw_transport_info *info)
return NULL;
}
/** Destroy a transport
* \param trans a transport to destroy
* \memberof pw_transport
*/
void pw_transport_destroy(struct pw_transport *trans)
{
struct transport *impl = (struct transport *) trans;
@ -184,6 +196,16 @@ void pw_transport_destroy(struct pw_transport *trans)
free(impl);
}
/** Get transport info
* \param trans the transport to get info of
* \param[out] info transport info
* \return 0 on success
*
* Fill \a info with the transport info of \a trans. This information can be
* passed to the client to set up the shared transport.
*
* \memberof pw_transport
*/
int pw_transport_get_info(struct pw_transport *trans, struct pw_transport_info *info)
{
struct transport *impl = (struct transport *) trans;
@ -195,6 +217,16 @@ int pw_transport_get_info(struct pw_transport *trans, struct pw_transport_info *
return SPA_RESULT_OK;
}
/** Add an event to the transport
* \param trans the transport to send the event on
* \param event the event to add
* \return 0 on success, < 0 on error
*
* Write \a event to the shared ringbuffer and signal the other side that
* new data can be read.
*
* \memberof pw_transport
*/
int pw_transport_add_event(struct pw_transport *trans, struct spa_event *event)
{
struct transport *impl = (struct transport *) trans;
@ -218,6 +250,20 @@ int pw_transport_add_event(struct pw_transport *trans, struct spa_event *event)
return SPA_RESULT_OK;
}
/** Get next event from a transport
* \param trans the transport to get the event of
* \param[out] event the event to read
* \return 0 on success, < 0 on error, SPA_RESULT_ENUM_END when no more events
* are available.
*
* Get the skeleton next event from \a trans into \a event. This function will
* only read the head and object body of the event.
*
* After the complete size of the event has been calculated, you should call
* \ref pw_transport_parse_event() to read the complete event contents.
*
* \memberof pw_transport
*/
int pw_transport_next_event(struct pw_transport *trans, struct spa_event *event)
{
struct transport *impl = (struct transport *) trans;
@ -240,6 +286,15 @@ int pw_transport_next_event(struct pw_transport *trans, struct spa_event *event)
return SPA_RESULT_OK;
}
/** Parse the complete event on transport
* \param trans the transport to read from
* \param[out] event memory that can hold the complete event
* \return 0 on success, < 0 on error
*
* Use this function after \ref pw_transport_next_event().
*
* \memberof pw_transport
*/
int pw_transport_parse_event(struct pw_transport *trans, void *event)
{
struct transport *impl = (struct transport *) trans;

View file

@ -32,34 +32,40 @@ extern "C" {
#include <pipewire/client/mem.h>
#include <pipewire/client/sig.h>
/** information about the transport region \memberof pw_transport */
struct pw_transport_info {
int memfd;
uint32_t offset;
uint32_t size;
int memfd; /**< the memfd of the transport area */
uint32_t offset; /**< offset to map \a memfd at */
uint32_t size; /**< size of memfd mapping */
};
/**
* struct pw_transport_area:
*
* Shared structure between client and server
*/
/** Shared structure between client and server \memberof pw_transport */
struct pw_transport_area {
uint32_t max_inputs;
uint32_t n_inputs;
uint32_t max_outputs;
uint32_t n_outputs;
uint32_t max_inputs; /**< max inputs of the node */
uint32_t n_inputs; /**< number of inputs of the node */
uint32_t max_outputs; /**< max outputs of the node */
uint32_t n_outputs; /**< number of outputs of the node */
};
/** \class pw_transport
*
* \brief Transport object
*
* The transport object contains shared data and ringbuffers to exchange
* events and data between the server and the client in a low-latency and
* lockfree way.
*/
struct pw_transport {
/** Emited when the transport is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_transport *trans));
struct pw_transport_area *area;
struct spa_port_io *inputs;
struct spa_port_io *outputs;
void *input_data;
struct spa_ringbuffer *input_buffer;
void *output_data;
struct spa_ringbuffer *output_buffer;
struct pw_transport_area *area; /**< the transport area */
struct spa_port_io *inputs; /**< array of input port io */
struct spa_port_io *outputs; /**< array of output port io */
void *input_data; /**< input memory for ringbuffer */
struct spa_ringbuffer *input_buffer; /**< ringbuffer for input memory */
void *output_data; /**< output memory for ringbuffer */
struct spa_ringbuffer *output_buffer; /**< ringbuffer for output memory */
};
struct pw_transport *

View file

@ -31,6 +31,10 @@
#include "spa/monitor.h"
/** Initializes the type system
* \param type a type structure
* \memberof pw_type
*/
void pw_type_init(struct pw_type *type)
{
type->map = pw_type_map_get_default();

View file

@ -33,20 +33,30 @@ extern "C" {
#include <pipewire/client/map.h>
#include <pipewire/client/transport.h>
/** \class pw_interface
* \brief The interface definition
*
* The interface implements the methods and events for a \ref
* pw_proxy. It typically implements marshal functions for the
* methods and calls the user installed implementation after
* demarshalling the events.
*
* \sa pw_proxy, pw_resource
*/
struct pw_interface {
uint32_t n_methods;
const void *methods;
uint32_t n_events;
const void *events;
uint32_t n_methods; /**< number of methods in the interface */
const void *methods; /**< method implementations of the interface */
uint32_t n_events; /**< number of events in the interface */
const void *events; /**< event implementations of the interface */
};
/**
* pw_type:
/** \class pw_type
* \brief PipeWire type support struct
*
* PipeWire Type support struct.
*/
* This structure contains some of the most common types
* and should be initialized with \ref pw_type_init() */
struct pw_type {
struct spa_type_map *map;
struct spa_type_map *map; /**< the type mapper */
uint32_t core;
uint32_t registry;

View file

@ -23,6 +23,19 @@
#include <pipewire/client/log.h>
#include <pipewire/client/utils.h>
/** Split a string based on delimiters
* \param str a string to split
* \param delimiter delimiter characters to split on
* \param[out] len the length of the current string
* \param[in,out] state a state variable
* \return a string or NULL when the end is reached
*
* Repeatedly call this function to split \a str into all substrings
* delimited by \a delimiter. \a state should be set to NULL on the first
* invocation and passed to the function until NULL is returned.
*
* \memberof pw_utils
*/
const char *pw_split_walk(const char *str, const char *delimiter, size_t * len, const char **state)
{
const char *s = *state ? *state : str;
@ -38,6 +51,16 @@ const char *pw_split_walk(const char *str, const char *delimiter, size_t * len,
return s;
}
/** Split a string based on delimiters
* \param str a string to split
* \param delimiter delimiter characters to split on
* \param max_tokens the max number of tokens to split
* \param[out] n_tokens the number of tokens
* \return a NULL terminated array of strings that should be
* freed with \ref pw_free_strv.
*
* \memberof pw_utils
*/
char **pw_split_strv(const char *str, const char *delimiter, int max_tokens, int *n_tokens)
{
const char *state = NULL, *s = NULL;
@ -64,7 +87,13 @@ char **pw_split_strv(const char *str, const char *delimiter, int max_tokens, int
return arr.data;
}
/** Free a NULL terminated array of strings
* \param str a NULL terminated array of string
*
* Free all the strings in the array and the array
*
* \memberof pw_utils
*/
void pw_free_strv(char **str)
{
int i;
@ -73,6 +102,16 @@ void pw_free_strv(char **str)
free(str);
}
/** Strip all whitespace before and after a string
* \param str a string to strip
* \param whitespace characters to strip
* \return the stripped part of \a str
*
* Strip whitespace before and after \a str. \a str will be
* modified.
*
* \memberof pw_utils
*/
char *pw_strip(char *str, const char *whitespace)
{
char *e, *l = NULL;

View file

@ -27,6 +27,12 @@ extern "C" {
#include <spa/defs.h>
#include <spa/pod-utils.h>
/** \class pw_utils
*
* Various utility functions
*/
/** a function to destroy an item \memberof pw_utils */
typedef void (*pw_destroy_t) (void *object);
const char *
@ -41,6 +47,7 @@ pw_free_strv(char **str);
char *
pw_strip(char *str, const char *whitespace);
/** Copy a pod structure \memberof pw_utils */
static inline struct spa_pod *
pw_spa_pod_copy(const struct spa_pod *pod)
{

View file

@ -551,7 +551,7 @@ gst_pipewire_device_provider_set_property (GObject * object,
GST_WARNING_OBJECT (self,
"Empty PipeWire client name not allowed. "
"Resetting to default value");
self->client_name = pw_client_name ();
self->client_name = pw_get_client_name ();
} else
self->client_name = g_value_dup_string (value);
break;
@ -602,7 +602,7 @@ gst_pipewire_device_provider_class_init (GstPipeWireDeviceProviderClass * klass)
dm_class->start = gst_pipewire_device_provider_start;
dm_class->stop = gst_pipewire_device_provider_stop;
client_name = pw_client_name ();
client_name = pw_get_client_name ();
g_object_class_install_property (gobject_class,
PROP_CLIENT_NAME,
g_param_spec_string ("client-name", "Client Name",
@ -620,5 +620,5 @@ gst_pipewire_device_provider_class_init (GstPipeWireDeviceProviderClass * klass)
static void
gst_pipewire_device_provider_init (GstPipeWireDeviceProvider * self)
{
self->client_name = pw_client_name ();
self->client_name = pw_get_client_name ();
}

View file

@ -292,7 +292,7 @@ gst_pipewire_sink_init (GstPipeWireSink * sink)
{
sink->allocator = gst_fd_allocator_new ();
sink->pool = gst_pipewire_pool_new ();
sink->client_name = pw_client_name();
sink->client_name = pw_get_client_name();
sink->mode = DEFAULT_PROP_MODE;
g_signal_connect (sink->pool, "activated", G_CALLBACK (pool_activated), sink);

View file

@ -305,7 +305,7 @@ gst_pipewire_src_init (GstPipeWireSrc * src)
g_queue_init (&src->queue);
src->fd_allocator = gst_fd_allocator_new ();
src->client_name = pw_client_name ();
src->client_name = pw_get_client_name ();
src->buf_ids = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) gst_buffer_unref);
src->loop = pw_loop_new ();

View file

@ -38,6 +38,8 @@
#include "pipewire/server/core.h"
#include "pipewire/server/client-node.h"
/** \cond */
#define MAX_INPUTS 64
#define MAX_OUTPUTS 64
@ -129,6 +131,8 @@ struct impl {
int other_fds[2];
};
/** \endcond */
static int clear_buffers(struct proxy *this, struct proxy_port *port)
{
if (port->n_buffers) {
@ -1107,20 +1111,21 @@ static void on_node_free(struct pw_listener *listener, struct pw_node *node)
free(impl);
}
/**
* pw_client_node_new:
* @client: a #pw_client
* @id: an id
* @name: a name
* @properties: extra properties
/** Create a new client node
* \param client an owner \ref pw_client
* \param id an id
* \param name a name
* \param properties extra properties
* \return a newly allocated client node
*
* Create a new #struct pw_node.
* Create a new \ref pw_node.
*
* Returns: a new #struct pw_node
* \memberof pw_client_node
*/
struct pw_client_node *pw_client_node_new(struct pw_client *client,
uint32_t id,
const char *name, struct pw_properties *properties)
const char *name,
struct pw_properties *properties)
{
struct impl *impl;
struct pw_client_node *this;
@ -1178,19 +1183,20 @@ void pw_client_node_destroy(struct pw_client_node *this)
pw_resource_destroy(this->resource);
}
/**
* pw_client_node_get_fds:
* @node: a #struct pw_client_node
* @readfd: an fd for reading
* @writefd: an fd for writing
/** Get the set of fds for this \ref pw_client_node
*
* Create or return a previously create set of fds for @node.
* \param node a \ref pw_client_node
* \param[out] readfd an fd for reading
* \param[out] writefd an fd for writing
* \return 0 on success < 0 on error
*
* Returns: %SPA_RESULT_OK on success
* Create or return a previously created set of fds for \a node.
*
* \memberof pw_client_node
*/
int pw_client_node_get_fds(struct pw_client_node *this, int *readfd, int *writefd)
int pw_client_node_get_fds(struct pw_client_node *node, int *readfd, int *writefd)
{
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
if (impl->fds[0] == -1) {
#if 0
@ -1212,7 +1218,7 @@ int pw_client_node_get_fds(struct pw_client_node *this, int *readfd, int *writef
#endif
spa_loop_add_source(impl->proxy.data_loop, &impl->proxy.data_source);
pw_log_debug("client-node %p: add data fd %d", this, impl->proxy.data_source.fd);
pw_log_debug("client-node %p: add data fd %d", node, impl->proxy.data_source.fd);
}
*readfd = impl->other_fds[0];
*writefd = impl->other_fds[1];

View file

@ -29,8 +29,7 @@ extern "C" {
#define PIPEWIRE_TYPE__ClientNode "PipeWire:Object:ClientNode"
#define PIPEWIRE_TYPE_CLIENT_NODE_BASE PIPEWIRE_TYPE__ClientNode ":"
/**
* pw_client_node:
/** \class pw_client_node
*
* PipeWire client node interface
*/

View file

@ -25,9 +25,11 @@
#include "pipewire/server/client.h"
#include "pipewire/server/resource.h"
/** \cond */
struct impl {
struct pw_client this;
};
/** \endcond */
static void client_unbind_func(void *data)
{
@ -61,14 +63,14 @@ client_bind_func(struct pw_global *global, struct pw_client *client, uint32_t ve
return SPA_RESULT_NO_MEMORY;
}
/**
* pw_client_new:
* @core: a #pw_core
* @properties: extra client properties
/** Make a new client object
*
* Make a new #struct pw_client object and register it to @core
* \param core a \ref pw_core object to register the client with
* \param ucred a ucred structure or NULL when unknown
* \param properties optional client properties, ownership is taken
* \return a newly allocated client object
*
* Returns: a new #struct pw_client
* \memberof pw_client
*/
struct pw_client *pw_client_new(struct pw_core *core,
struct ucred *ucred, struct pw_properties *properties)
@ -112,11 +114,11 @@ static void destroy_resource(void *object, void *data)
pw_resource_destroy(object);
}
/**
* pw_client_destroy:
* @client: a #struct pw_client
/** Destroy a client object
*
* Trigger removal of @client
* \param client the client to destroy
*
* \memberof pw_client
*/
void pw_client_destroy(struct pw_client *client)
{
@ -143,6 +145,17 @@ void pw_client_destroy(struct pw_client *client)
free(impl);
}
/** Update client properties
*
* \param client the client
* \param dict a \ref spa_dict with properties
*
* Add all properties in \a dict to the client properties. Existing
* properties are overwritten. Items can be removed by setting the value
* to NULL.
*
* \memberof pw_client
*/
void pw_client_update_properties(struct pw_client *client, const struct spa_dict *dict)
{
struct pw_resource *resource;

View file

@ -33,37 +33,46 @@ extern "C" {
#include <pipewire/server/core.h>
#include <pipewire/server/resource.h>
/**
* pw_client:
/** \class pw_client
*
* PipeWire client object class.
* \brief PipeWire client object class.
*
* The client object represents a client connection with the PipeWire
* server.
*
* Each client has its own list of resources it is bound to along with
* a mapping between the client types and server types.
*/
struct pw_client {
struct pw_core *core;
struct spa_list link;
struct pw_global *global;
struct pw_core *core; /**< core object */
struct spa_list link; /**< link in core object client list */
struct pw_global *global; /**< global object created for this client */
struct pw_properties *properties;
struct pw_properties *properties; /**< Client properties */
/** Emited when the properties changed */
PW_SIGNAL(properties_changed, (struct pw_listener *listener, struct pw_client *client));
struct pw_client_info info;
bool ucred_valid;
struct ucred ucred;
struct pw_client_info info; /**< client info */
bool ucred_valid; /**< if the ucred member is valid */
struct ucred ucred; /**< ucred information */
void *protocol_private;
void *protocol_private; /**< private data for the protocol implementation */
struct pw_resource *core_resource;
struct pw_resource *core_resource; /**< core resource object */
struct pw_map objects;
uint32_t n_types;
struct pw_map types;
struct pw_map objects; /**< list of resource objects */
uint32_t n_types; /**< number of client types */
struct pw_map types; /**< map of client types */
struct spa_list resource_list;
struct spa_list resource_list; /**< The list of resources of this client */
/** Emited when a resource is added */
PW_SIGNAL(resource_added, (struct pw_listener *listener,
struct pw_client *client, struct pw_resource *resource));
/** Emited when a resource is removed */
PW_SIGNAL(resource_removed, (struct pw_listener *listener,
struct pw_client *client, struct pw_resource *resource));
/** Emited when the client is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_client *client));
};

View file

@ -26,6 +26,7 @@
#include "command.h"
/** \cond */
typedef bool(*pw_command_func_t) (struct pw_command *command, struct pw_core *core, char **err);
static bool execute_command_module_load(struct pw_command *command,
@ -54,6 +55,7 @@ static const struct command_parse parsers[] = {
};
static const char whitespace[] = " \t";
/** \endcond */
static struct pw_command *parse_command_module_load(const char *line, char **err)
{
@ -90,11 +92,13 @@ execute_command_module_load(struct pw_command *command, struct pw_core *core, ch
return pw_module_load(core, impl->args[1], impl->args[2], err) != NULL;
}
/**
* pw_command_free:
* @command: A #struct pw_command
/** Free command
*
* Free all resources assicated with @command.
* \param command a command to free
*
* Free all resources assicated with \a command.
*
* \memberof pw_command
*/
void pw_command_free(struct pw_command *command)
{
@ -105,15 +109,15 @@ void pw_command_free(struct pw_command *command)
free(impl);
}
/**
* pw_command_parse:
* @line: command line to parse
* @err: Return location for an error
/** Parses a command line
* \param line command line to parse
* \param[out] err Return location for an error
* \return The command or NULL when \a err is set.
*
* Parses a command line, @line, and return the parsed command.
* A command can later be executed with pw_command_run().
* Parses a command line, \a line, and return the parsed command.
* A command can later be executed with \ref pw_command_run()
*
* Returns: The command or %NULL when @err is set.
* \memberof pw_command
*/
struct pw_command *pw_command_parse(const char *line, char **err)
{
@ -139,15 +143,14 @@ struct pw_command *pw_command_parse(const char *line, char **err)
return command;
}
/**
* pw_command_run:
* @command: A #struct pw_comman
* @core: A #struct pw_core
* @err: Return location for a #GError, or %NULL
/** Run a command
*
* Run @command.
* \param command: A \ref pw_command
* \param core: A \ref pw_core
* \param err: Return location for an error string, or NULL
* \return true if \a command was executed successfully, false otherwise.
*
* Returns: %true if @command was executed successfully, %false otherwise.
* \memberof pw_command
*/
bool pw_command_run(struct pw_command *command, struct pw_core *core, char **err)
{
@ -155,18 +158,3 @@ bool pw_command_run(struct pw_command *command, struct pw_core *core, char **err
return impl->func(command, core, err);
}
/**
* pw_command_get_name:
* @command: A #struct pw_command
*
* Get the name of @command.
*
* Returns: The name of @command.
*/
const char *pw_command_get_name(struct pw_command *command)
{
struct impl *impl = SPA_CONTAINER_OF(command, struct impl, this);
return impl->args[0];
}

View file

@ -27,10 +27,14 @@ extern "C" {
#include <pipewire/server/core.h>
/** \class command
*
* A configuration command
*/
struct pw_command {
struct spa_list link;
struct spa_list link; /**< link in list of commands */
const char *name;
const char *name; /**< command name */
};

View file

@ -26,6 +26,7 @@
#include <spa/lib/debug.h>
#include <spa/format-utils.h>
/** \cond */
struct global_impl {
struct pw_global this;
pw_bind_func_t bind;
@ -37,21 +38,30 @@ struct impl {
struct spa_support support[4];
};
struct access_create_client_node {
struct pw_access_data data;
char *name;
struct pw_properties *properties;
uint32_t new_id;
bool async;
};
/** \endcond */
#define ACCESS_VIEW_GLOBAL(client,global) (client->core->access == NULL || \
client->core->access->view_global (client->core->access, \
client, global) == SPA_RESULT_OK)
static void registry_bind(void *object, uint32_t id, uint32_t new_id)
static void registry_bind(void *object, uint32_t id, uint32_t version, uint32_t new_id)
{
struct pw_resource *resource = object;
struct pw_client *client = resource->client;
struct pw_core *core = resource->core;
struct pw_global *global;
spa_list_for_each(global, &core->global_list, link)
if (global->id == id)
break;
spa_list_for_each(global, &core->global_list, link) {
if (global->id == id)
break;
}
if (&global->link == &core->global_list)
goto no_id;
@ -59,7 +69,7 @@ static void registry_bind(void *object, uint32_t id, uint32_t new_id)
goto no_id;
pw_log_debug("global %p: bind object id %d to %d", global, id, new_id);
pw_global_bind(global, client, 0, new_id);
pw_global_bind(global, client, version, new_id);
return;
@ -120,7 +130,8 @@ static void core_get_registry(void *object, uint32_t new_id)
pw_registry_notify_global(registry_resource,
global->id,
spa_type_map_get_type(this->type.map,
global->type));
global->type),
global->version);
}
return;
@ -143,14 +154,6 @@ core_create_node(void *object,
resource->id, SPA_RESULT_NOT_IMPLEMENTED, "not implemented");
}
struct access_create_client_node {
struct pw_access_data data;
char *name;
struct pw_properties *properties;
uint32_t new_id;
bool async;
};
static void *async_create_client_node_copy(struct pw_access_data *data, size_t size)
{
struct access_create_client_node *d;
@ -317,6 +320,14 @@ core_bind_func(struct pw_global *global, struct pw_client *client, uint32_t vers
return SPA_RESULT_NO_MEMORY;
}
/** Create a new core object
*
* \param main_loop the main loop to use
* \param properties extra properties for the core, ownership it taken
* \return a newly allocated core object
*
* \memberof pw_core
*/
struct pw_core *pw_core_new(struct pw_main_loop *main_loop, struct pw_properties *properties)
{
struct impl *impl;
@ -380,6 +391,12 @@ struct pw_core *pw_core_new(struct pw_main_loop *main_loop, struct pw_properties
return NULL;
}
/** Destroy a core object
*
* \param core a core to destroy
*
* \memberof pw_core
*/
void pw_core_destroy(struct pw_core *core)
{
struct impl *impl = SPA_CONTAINER_OF(core, struct impl, this);
@ -395,11 +412,27 @@ void pw_core_destroy(struct pw_core *core)
free(impl);
}
/** 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 version the version
* \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
*/
bool
pw_core_add_global(struct pw_core *core,
struct pw_client *owner,
uint32_t type,
uint32_t version, void *object, pw_bind_func_t bind, struct pw_global **global)
uint32_t version,
void *object,
pw_bind_func_t bind,
struct pw_global **global)
{
struct global_impl *impl;
struct pw_global *this;
@ -432,11 +465,24 @@ pw_core_add_global(struct pw_core *core,
spa_list_for_each(registry, &core->registry_resource_list, link)
if (ACCESS_VIEW_GLOBAL(registry->client, this))
pw_registry_notify_global(registry, this->id, type_name);
pw_registry_notify_global(registry, this->id, type_name, this->version);
return true;
}
/** 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 version, uint32_t id)
{
@ -453,6 +499,12 @@ pw_global_bind(struct pw_global *global, struct pw_client *client, uint32_t vers
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;
@ -474,6 +526,15 @@ void pw_global_destroy(struct pw_global *global)
free(global);
}
/** Update core properties
*
* \param core a core
* \param dict properties to update
*
* Update the core object with the given properties
*
* \memberof pw_core
*/
void pw_core_update_properties(struct pw_core *core, const struct spa_dict *dict)
{
struct pw_resource *resource;
@ -497,12 +558,26 @@ void pw_core_update_properties(struct pw_core *core, const struct spa_dict *dict
}
}
/** Find a port to link with
*
* \param core a core
* \param other_port a port to find a link with
* \param id the id of a port or SPA_ID_INVALID
* \param props extra properties
* \param n_format_filters number of filters
* \param format_filters array of format filters
* \param[out] error an error when something is wrong
* \return a port that can be used to link to \a otherport or NULL on error
*
* \memberof pw_core
*/
struct pw_port *pw_core_find_port(struct pw_core *core,
struct pw_port *other_port,
uint32_t id,
struct pw_properties *props,
uint32_t n_format_filters,
struct spa_format **format_filters, char **error)
struct spa_format **format_filters,
char **error)
{
struct pw_port *best = NULL;
bool have_id;
@ -560,12 +635,29 @@ struct pw_port *pw_core_find_port(struct pw_core *core,
return best;
}
/** Find a common format between two ports
*
* \param core a core object
* \param output an output port
* \param input an input port
* \param props extra properties
* \param n_format_filters number of format filters
* \param format_filters array of format filters
* \param[out] error an error when something is wrong
* \return a common format of NULL on error
*
* Find a common format between the given ports. The format will
* be restricted to a subset given with the format filters.
*
* \memberof pw_core
*/
struct spa_format *pw_core_find_format(struct pw_core *core,
struct pw_port *output,
struct pw_port *input,
struct pw_properties *props,
uint32_t n_format_filters,
struct spa_format **format_filterss, char **error)
struct spa_format **format_filters,
char **error)
{
uint32_t out_state, in_state;
int res;
@ -647,6 +739,16 @@ struct spa_format *pw_core_find_format(struct pw_core *core,
return NULL;
}
/** Find a node by name
*
* \param core the core object
* \param name the name of the node to find
*
* Find in the list of nodes registered in \a core for one with
* the given \a name.
*
* \memberof pw_core
*/
struct pw_node_factory *pw_core_find_node_factory(struct pw_core *core, const char *name)
{
struct pw_node_factory *factory;

View file

@ -39,54 +39,68 @@ struct pw_global;
typedef int (*pw_bind_func_t) (struct pw_global *global,
struct pw_client *client, uint32_t version, uint32_t id);
/** \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.
*/
struct pw_global {
struct pw_core *core;
struct pw_client *owner;
struct pw_core *core; /**< the core */
struct pw_client *owner; /**< the owner of this object, NULL when the
* PipeWire server is the owner */
struct spa_list link;
uint32_t id;
uint32_t type;
uint32_t version;
void *object;
struct spa_list link; /**< link in core list of globals */
uint32_t id; /**< server id of the object */
uint32_t type; /**< type of the object */
uint32_t version; /**< version of the object */
void *object; /**< object associated with the global */
/** Emited when the global is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_global *global));
};
/**
* struct pw_core:
/** \class pw_core
*
* PipeWire core object class.
* \brief the core PipeWire object
*
* The server core object manages all resources available on the
* server.
*/
struct pw_core {
struct pw_global *global;
struct pw_global *global; /**< the global of the core */
struct pw_core_info info;
struct pw_core_info info; /**< info about the core */
struct pw_properties *properties;
struct pw_properties *properties; /**< properties of the core */
struct pw_type type;
struct pw_access *access;
struct pw_type type; /**< type map and common types */
struct pw_access *access; /**< access control checks */
struct pw_map objects;
struct pw_map objects; /**< map of known objects */
struct spa_list resource_list;
struct spa_list registry_resource_list;
struct spa_list global_list;
struct spa_list client_list;
struct spa_list node_list;
struct spa_list node_factory_list;
struct spa_list link_list;
struct spa_list resource_list; /**< list of resources */
struct spa_list registry_resource_list; /**< list of registry resources */
struct spa_list global_list; /**< list of globals */
struct spa_list client_list; /**< list of clients */
struct spa_list node_list; /**< list of nodes */
struct spa_list node_factory_list; /**< list of node factories */
struct spa_list link_list; /**< list of links */
struct pw_main_loop *main_loop;
struct pw_data_loop *data_loop;
struct pw_main_loop *main_loop; /**< main loop for control */
struct pw_data_loop *data_loop; /**< data loop for data passing */
struct spa_support *support;
uint32_t n_support;
struct spa_support *support; /**< support for spa plugins */
uint32_t n_support; /**< number of support items */
/** Emited when the core is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_core *core));
/** Emited when a global is added */
PW_SIGNAL(global_added, (struct pw_listener *listener,
struct pw_core *core, struct pw_global *global));
/** Emited when a global is removed */
PW_SIGNAL(global_removed, (struct pw_listener *listener,
struct pw_core *core, struct pw_global *global));
};

View file

@ -32,6 +32,7 @@
#include "pipewire/client/rtkit.h"
#include "pipewire/server/data-loop.h"
/** \cond */
struct impl {
struct pw_data_loop this;
@ -40,6 +41,7 @@ struct impl {
bool running;
pthread_t thread;
};
/** \endcond */
static void make_realtime(struct pw_data_loop *this)
{
@ -112,12 +114,10 @@ static void do_stop(struct spa_loop_utils *utils, struct spa_source *source, voi
impl->running = false;
}
/**
* pw_data_loop_new:
/** Create a new \ref pw_data_loop.
* \return a newly allocated data loop
*
* Create a new #struct pw_data_loop.
*
* Returns: a new #struct pw_data_loop
* \memberof pw_data_loop
*/
struct pw_data_loop *pw_data_loop_new(void)
{
@ -145,6 +145,10 @@ struct pw_data_loop *pw_data_loop_new(void)
return NULL;
}
/** Destroy a data loop
* \param loop the data loop to destroy
* \memberof pw_data_loop
*/
void pw_data_loop_destroy(struct pw_data_loop *loop)
{
struct impl *impl = SPA_CONTAINER_OF(loop, struct impl, this);
@ -159,6 +163,14 @@ void pw_data_loop_destroy(struct pw_data_loop *loop)
free(impl);
}
/** Start a data loop
* \param loop the data loop to start
* \return 0 if ok, -1 on error
*
* This will start the realtime thread that manages the loop.
*
* \memberof pw_data_loop
*/
int pw_data_loop_start(struct pw_data_loop *loop)
{
struct impl *impl = SPA_CONTAINER_OF(loop, struct impl, this);
@ -176,6 +188,14 @@ int pw_data_loop_start(struct pw_data_loop *loop)
return SPA_RESULT_OK;
}
/** Stop a data loop
* \param loop the data loop to Stop
* \return \ref SPA_RESULT_OK
*
* This will stop and join the realtime thread that manages the loop.
*
* \memberof pw_data_loop
*/
int pw_data_loop_stop(struct pw_data_loop *loop)
{
struct impl *impl = SPA_CONTAINER_OF(loop, struct impl, this);
@ -188,6 +208,12 @@ int pw_data_loop_stop(struct pw_data_loop *loop)
return SPA_RESULT_OK;
}
/** Check if we are inside the data loop
* \param loop the data loop to check
* \return true is the current thread is the data loop thread
*
* \memberof pw_data_loop
*/
bool pw_data_loop_in_thread(struct pw_data_loop * loop)
{
struct impl *impl = SPA_CONTAINER_OF(loop, struct impl, this);

View file

@ -26,14 +26,14 @@ extern "C" {
#include <pipewire/client/loop.h>
/**
* pw_data_loop:
/** \class pw_data_loop
*
* PipeWire rt-loop object.
*/
struct pw_data_loop {
struct pw_loop *loop;
struct pw_loop *loop; /**< wrapped loop object */
/** Emited when the data loop is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_data_loop *loop));
};

View file

@ -33,6 +33,7 @@
#define MAX_BUFFERS 16
/** \cond */
struct impl {
struct pw_link this;
@ -40,7 +41,7 @@ struct impl {
struct pw_work_queue *work;
struct spa_format **format_filter;
struct spa_format *format_filter;
struct pw_properties *properties;
struct pw_listener input_port_destroy;
@ -54,6 +55,8 @@ struct impl {
uint32_t n_buffers;
};
/** \endcond */
static void pw_link_update_state(struct pw_link *link, enum pw_link_state state, char *error)
{
enum pw_link_state old = link->state;
@ -858,10 +861,22 @@ link_bind_func(struct pw_global *global, struct pw_client *client, uint32_t vers
return SPA_RESULT_NO_MEMORY;
}
/** Create a new link
* \param core the core class
* \param output an output port
* \param input an input port
* \param format_filter a format filter
* \param properties extra properties
*
* Make a link between \a output and \a input
*
* \memberof pw_link
*/
struct pw_link *pw_link_new(struct pw_core *core,
struct pw_port *output,
struct pw_port *input,
struct spa_format **format_filter, struct pw_properties *properties)
struct spa_format *format_filter,
struct pw_properties *properties)
{
struct impl *impl;
struct pw_link *this;
@ -991,42 +1006,43 @@ do_link_remove(struct spa_loop *loop,
return res;
}
/**
* pw_link_destroy:
* @link: a #struct pw_link
/** Destroy a link
* \param link the link to destroy
*
* Trigger removal of @link
* Trigger removal of \a link
*
* \memberof pw_link
*/
void pw_link_destroy(struct pw_link *this)
void pw_link_destroy(struct pw_link *link)
{
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
struct impl *impl = SPA_CONTAINER_OF(link, struct impl, this);
struct pw_resource *resource, *tmp;
pw_log_debug("link %p: destroy", impl);
pw_signal_emit(&this->destroy_signal, this);
pw_signal_emit(&link->destroy_signal, link);
pw_global_destroy(this->global);
spa_list_remove(&this->link);
pw_global_destroy(link->global);
spa_list_remove(&link->link);
spa_list_for_each_safe(resource, tmp, &this->resource_list, link)
spa_list_for_each_safe(resource, tmp, &link->resource_list, link)
pw_resource_destroy(resource);
if (this->input) {
if (link->input) {
pw_signal_remove(&impl->input_port_destroy);
pw_signal_remove(&impl->input_async_complete);
impl->refcount++;
pw_loop_invoke(this->input->node->data_loop->loop,
do_link_remove, 1, 0, NULL, this);
pw_loop_invoke(link->input->node->data_loop->loop,
do_link_remove, 1, 0, NULL, link);
}
if (this->output) {
if (link->output) {
pw_signal_remove(&impl->output_port_destroy);
pw_signal_remove(&impl->output_async_complete);
impl->refcount++;
pw_loop_invoke(this->output->node->data_loop->loop,
do_link_remove, 2, 0, NULL, this);
pw_loop_invoke(link->output->node->data_loop->loop,
do_link_remove, 2, 0, NULL, link);
}
if (--impl->refcount == 0)
pw_link_free(this);
pw_link_free(link);
}

View file

@ -32,8 +32,7 @@ extern "C" {
#include <pipewire/server/port.h>
#include <pipewire/server/main-loop.h>
/**
* pw_link:
/** \class pw_link
*
* PipeWire link interface.
*/
@ -76,7 +75,7 @@ struct pw_link *
pw_link_new(struct pw_core *core,
struct pw_port *output,
struct pw_port *input,
struct spa_format **format_filter,
struct spa_format *format_filter,
struct pw_properties *properties);
void

View file

@ -27,18 +27,18 @@
#include "pipewire/client/log.h"
#include "pipewire/server/main-loop.h"
/** \cond */
struct impl {
struct pw_main_loop this;
bool running;
};
/** \endcond */
/**
* pw_main_loop_new:
/** Create a new new main loop
* \return a newly allocated \ref pw_main_loop
*
* Create a new #struct pw_main_loop.
*
* Returns: a new #struct pw_main_loop
* \memberof pw_main_loop
*/
struct pw_main_loop *pw_main_loop_new(void)
{
@ -65,6 +65,11 @@ struct pw_main_loop *pw_main_loop_new(void)
return NULL;
}
/** Destroy a main loop
* \param loop the main loop to destroy
*
* \memberof pw_main_loop
*/
void pw_main_loop_destroy(struct pw_main_loop *loop)
{
struct impl *impl = SPA_CONTAINER_OF(loop, struct impl, this);
@ -77,11 +82,12 @@ void pw_main_loop_destroy(struct pw_main_loop *loop)
free(impl);
}
/**
* pw_main_loop_quit:
* @loop: a #struct pw_main_loop
/** Stop a main loop
* \param loop a \ref pw_main_loop to stop
*
* Stop the running @loop.
* The call to \ref pw_main_loop_run() will return
*
* \memberof pw_main_loop
*/
void pw_main_loop_quit(struct pw_main_loop *loop)
{
@ -90,12 +96,13 @@ void pw_main_loop_quit(struct pw_main_loop *loop)
impl->running = false;
}
/**
* pw_main_loop_run:
* @loop: a #struct pw_main_loop
/** Start a main loop
* \param loop the main loop to start
*
* Start running @loop. This function blocks until pw_main_loop_quit()
* has been called.
* Start running \a loop. This function blocks until \ref pw_main_loop_quit()
* has been called
*
* \memberof pw_main_loop
*/
void pw_main_loop_run(struct pw_main_loop *loop)
{

View file

@ -27,14 +27,18 @@ extern "C" {
#include <spa/include/spa/loop.h>
#include <pipewire/client/loop.h>
/**
* pa_main_loop:
/** \class pa_main_loop
*
* PipeWire main-loop interface.
* \brief PipeWire main-loop interface.
*
* A main loop object
*/
struct pw_main_loop {
struct pw_loop *loop;
/** A main loop object \memberof pw_main_loop */
struct pw_main_loop {
struct pw_loop *loop; /**< the wrapped loop */
/** Emited when the loop is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_main_loop *loop));
};

View file

@ -27,18 +27,17 @@
#include <sys/stat.h>
#include <errno.h>
#include "pipewire/client/pipewire.h"
#include "pipewire/client/interfaces.h"
#include "pipewire/client/utils.h"
#include "pipewire/server/module.h"
#define PIPEWIRE_SYMBOL_MODULE_INIT "pipewire__module_init"
/** \cond */
struct impl {
struct pw_module this;
void *hnd;
};
/** \endcond */
static char *find_module(const char *path, const char *name)
{
@ -111,16 +110,15 @@ module_bind_func(struct pw_global *global, struct pw_client *client, uint32_t ve
return SPA_RESULT_NO_MEMORY;
}
/**
* pw_module_load:
* @core: a #struct pw_core
* @name: name of the module to load
* @args: A string with arguments for the module
* @err: Return location for an error string, or %NULL
/** Load a module
*
* Load module with @name.
* \param core a \ref pw_core
* \param name name of the module to load
* \param args A string with arguments for the module
* \param[out] err Return location for an error string, or NULL
* \return A \ref pw_module if the module could be loaded, or NULL on failure.
*
* Returns: A #struct pw_module if the module could be loaded, or %NULL on failure.
* \memberof pw_module
*/
struct pw_module *pw_module_load(struct pw_core *core,
const char *name, const char *args, char **err)
@ -208,18 +206,22 @@ struct pw_module *pw_module_load(struct pw_core *core,
return NULL;
}
void pw_module_destroy(struct pw_module *this)
/** Destroy a module
* \param module the module to destroy
* \memberof pw_module
*/
void pw_module_destroy(struct pw_module *module)
{
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
struct impl *impl = SPA_CONTAINER_OF(module, struct impl, this);
pw_signal_emit(&this->destroy_signal, this);
pw_signal_emit(&module->destroy_signal, module);
if (this->info.name)
free((char *) this->info.name);
if (this->info.filename)
free((char *) this->info.filename);
if (this->info.args)
free((char *) this->info.args);
if (module->info.name)
free((char *) module->info.name);
if (module->info.filename)
free((char *) module->info.filename);
if (module->info.args)
free((char *) module->info.args);
dlclose(impl->hnd);
free(impl);
}

View file

@ -27,27 +27,35 @@ extern "C" {
#include <pipewire/server/core.h>
#define PIPEWIRE_SYMBOL_MODULE_INIT "pipewire__module_init"
/** \class pw_module
*
* A dynamically loadable module
*/
struct pw_module {
struct pw_core *core;
struct spa_list link;
struct pw_global *global;
struct pw_core *core; /**< the core object */
struct spa_list link; /**< link in the core module_list */
struct pw_global *global; /**< global object for this module */
struct pw_module_info info;
struct pw_module_info info; /**< introspectable module info */
void *user_data;
void *user_data; /**< module user_data */
/** Emited when the module is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_module *module));
};
/**
* pw_module_init_func_t:
* @module: A #struct pw_module
* @args: Arguments to the module
/** Module init function signature
*
* \param module A \ref pw_module
* \param args Arguments to the module
* \return true on success, false otherwise
*
* A module should provide an init function with this signature. This function
* will be called when a module is loaded.
*
* Returns: %true on success, %false otherwise
* \memberof pw_module
*/
typedef bool (*pw_module_init_func_t) (struct pw_module *module, char *args);

View file

@ -29,6 +29,7 @@
#include "pipewire/server/main-loop.h"
#include "pipewire/server/work-queue.h"
/** \cond */
struct impl {
struct pw_node this;
@ -37,6 +38,8 @@ struct impl {
bool async_init;
};
/** \endcond */
static void init_complete(struct pw_node *this);
static void update_port_ids(struct pw_node *node)
@ -651,40 +654,42 @@ do_node_remove(struct spa_loop *loop,
return res;
}
/**
* pw_node_destroy:
* @node: a #struct pw_node
/** Destroy a node
* \param node a node to destroy
*
* Remove @node. This will stop the transfer on the node and
* free the resources allocated by @node.
* Remove \a node. This will stop the transfer on the node and
* free the resources allocated by \a node.
*
* \memberof pw_node
*/
void pw_node_destroy(struct pw_node *this)
void pw_node_destroy(struct pw_node *node)
{
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
struct pw_resource *resource, *tmp;
pw_log_debug("node %p: destroy", impl);
pw_signal_emit(&this->destroy_signal, this);
pw_signal_emit(&node->destroy_signal, node);
if (!impl->async_init) {
spa_list_remove(&this->link);
pw_global_destroy(this->global);
spa_list_remove(&node->link);
pw_global_destroy(node->global);
}
spa_list_for_each_safe(resource, tmp, &this->resource_list, link)
spa_list_for_each_safe(resource, tmp, &node->resource_list, link)
pw_resource_destroy(resource);
pw_loop_invoke(this->data_loop->loop, do_node_remove, 1, 0, NULL, this);
pw_loop_invoke(node->data_loop->loop, do_node_remove, 1, 0, NULL, node);
}
/**
* pw_node_get_free_port:
* @node: a #struct pw_node
* @direction: a #enum pw_direction
* \param node a \ref pw_node
* \param direction a \ref pw_direction
* \return the new port or NULL on error
*
* Find a new unused port in @node with @direction
* Find a new unused port in \a node with \a direction
*
* Returns: the new port or %NULL on error
* \memberof pw_node
*/
struct pw_port *pw_node_get_free_port(struct pw_node *node, enum pw_direction direction)
{
@ -774,14 +779,14 @@ static void node_activate(struct pw_node *this)
}
}
/**
* pw_node_set_state:
* @node: a #struct pw_node
* @state: a #enum pw_node_state
/** Set th node state
* \param node a \ref pw_node
* \param state a \ref pw_node_state
* \return 0 on success < 0 on error
*
* Set the state of @node to @state.
* Set the state of \a node to \a state.
*
* Returns: a #int
* \memberof pw_node
*/
int pw_node_set_state(struct pw_node *node, enum pw_node_state state)
{
@ -822,14 +827,15 @@ int pw_node_set_state(struct pw_node *node, enum pw_node_state state)
return res;
}
/**
* pw_node_update_state:
* @node: a #struct pw_node
* @state: a #enum pw_node_state
* @error: error when @state is #PW_NODE_STATE_ERROR
/** Update the node state
* \param node a \ref pw_node
* \param state a \ref pw_node_state
* \param error error when \a state is \ref PW_NODE_STATE_ERROR
*
* Update the state of a node. This method is used from
* inside @node itself.
* Update the state of a node. This method is used from inside \a node
* itself.
*
* \memberof pw_node
*/
void pw_node_update_state(struct pw_node *node, enum pw_node_state state, char *error)
{

View file

@ -39,8 +39,7 @@ extern "C" {
#include <pipewire/server/client.h>
#include <pipewire/server/data-loop.h>
/**
* pw_node:
/** \class pw_node
*
* PipeWire node class.
*/

View file

@ -25,11 +25,13 @@
#include "pipewire/server/port.h"
/** \cond */
struct impl {
struct pw_port this;
uint32_t seq;
};
/** \endcond */
struct pw_port *pw_port_new(struct pw_node *node, enum pw_direction direction, uint32_t port_id)
{
@ -95,29 +97,25 @@ static struct pw_link *find_link(struct pw_port *output_port, struct pw_port *in
return NULL;
}
struct pw_link *pw_port_get_link(struct pw_port *output_port, struct pw_port *input_port)
{
return find_link(output_port, input_port);
}
/**
* pw_port_link:
* @output_port: an output port
* @input_port: an input port
* @format_filter: a format filter
* @properties: extra properties
* @error: an error or %NULL
/** Link two ports
* \param output_port an output port
* \param input_port an input port
* \param format_filter a format filter
* \param properties extra properties
* \param error an error or NULL
* \return a newly allocated \ref pw_link or NULL and \a error is set.
*
* Make a link between @output_port and @input_port
* Make a link between \a output_port and \a input_port
*
* If the ports were already linked, the existing links will be returned.
* If the ports were already linked, the existing link will be returned.
*
* Returns: a new #struct pw_link or %NULL and @error is set.
* \memberof pw_port
*/
struct pw_link *pw_port_link(struct pw_port *output_port,
struct pw_port *input_port,
struct spa_format **format_filter,
struct pw_properties *properties, char **error)
struct spa_format *format_filter,
struct pw_properties *properties,
char **error)
{
struct pw_node *input_node, *output_node;
struct pw_link *link;

View file

@ -44,6 +44,10 @@ enum pw_port_state {
PW_PORT_STATE_STREAMING = 4,
};
/** \class pw_port
*
* The port object
*/
struct pw_port {
struct spa_list link;
@ -77,7 +81,7 @@ pw_port_destroy(struct pw_port *port);
struct pw_link *
pw_port_link(struct pw_port *output_port,
struct pw_port *input_port,
struct spa_format **format_filter,
struct spa_format *format_filter,
struct pw_properties *properties,
char **error);

View file

@ -24,12 +24,14 @@
#include "pipewire/server/resource.h"
#include "pipewire/server/protocol-native.h"
/** \cond */
typedef bool(*demarshal_func_t) (void *object, void *data, size_t size);
struct builder {
struct spa_pod_builder b;
struct pw_connection *connection;
};
/** \endcond */
static uint32_t write_pod(struct spa_pod_builder *b, uint32_t ref, const void *data, uint32_t size)
{
@ -296,7 +298,7 @@ static bool core_demarshal_update_types(void *object, void *data, size_t size)
return true;
}
static void registry_marshal_global(void *object, uint32_t id, const char *type)
static void registry_marshal_global(void *object, uint32_t id, const char *type, uint32_t version)
{
struct pw_resource *resource = object;
struct pw_connection *connection = resource->client->protocol_private;
@ -305,7 +307,10 @@ static void registry_marshal_global(void *object, uint32_t id, const char *type)
core_update_map(resource->client);
spa_pod_builder_struct(&b.b, &f, SPA_POD_TYPE_INT, id, SPA_POD_TYPE_STRING, type);
spa_pod_builder_struct(&b.b, &f,
SPA_POD_TYPE_INT, id,
SPA_POD_TYPE_STRING, type,
SPA_POD_TYPE_INT, version);
pw_connection_end_write(connection, resource->id, PW_REGISTRY_EVENT_GLOBAL, b.b.offset);
}
@ -329,13 +334,16 @@ static bool registry_demarshal_bind(void *object, void *data, size_t size)
{
struct pw_resource *resource = object;
struct spa_pod_iter it;
uint32_t id, new_id;
uint32_t id, version, new_id;
if (!spa_pod_iter_struct(&it, data, size) ||
!spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &id, SPA_POD_TYPE_INT, &new_id, 0))
!spa_pod_iter_get(&it,
SPA_POD_TYPE_INT, &id,
SPA_POD_TYPE_INT, &version,
SPA_POD_TYPE_INT, &new_id, 0))
return false;
((struct pw_registry_methods *) resource->implementation)->bind(resource, id, new_id);
((struct pw_registry_methods *) resource->implementation)->bind(resource, id, version, new_id);
return true;
}
@ -458,6 +466,24 @@ static void client_node_marshal_done(void *object, int readfd, int writefd)
pw_connection_end_write(connection, resource->id, PW_CLIENT_NODE_EVENT_DONE, b.b.offset);
}
static void
client_node_marshal_set_props(void *object, uint32_t seq, const struct spa_props *props)
{
struct pw_resource *resource = object;
struct pw_connection *connection = resource->client->protocol_private;
struct builder b = { {NULL, 0, 0, NULL, write_pod}, connection };
struct spa_pod_frame f;
core_update_map(resource->client);
spa_pod_builder_struct(&b.b, &f,
SPA_POD_TYPE_INT, seq,
SPA_POD_TYPE_POD, props);
pw_connection_end_write(connection, resource->id, PW_CLIENT_NODE_EVENT_SET_PROPS,
b.b.offset);
}
static void client_node_marshal_event(void *object, const struct spa_event *event)
{
struct pw_resource *resource = object;
@ -514,7 +540,9 @@ static void
client_node_marshal_set_format(void *object,
uint32_t seq,
enum spa_direction direction,
uint32_t port_id, uint32_t flags, const struct spa_format *format)
uint32_t port_id,
uint32_t flags,
const struct spa_format *format)
{
struct pw_resource *resource = object;
struct pw_connection *connection = resource->client->protocol_private;
@ -527,15 +555,19 @@ client_node_marshal_set_format(void *object,
SPA_POD_TYPE_INT, seq,
SPA_POD_TYPE_INT, direction,
SPA_POD_TYPE_INT, port_id,
SPA_POD_TYPE_INT, flags, SPA_POD_TYPE_POD, format);
SPA_POD_TYPE_INT, flags,
SPA_POD_TYPE_POD, format);
pw_connection_end_write(connection, resource->id, PW_CLIENT_NODE_EVENT_SET_FORMAT,
b.b.offset);
}
static void
client_node_marshal_set_property(void *object,
uint32_t seq, uint32_t id, uint32_t size, const void *value)
client_node_marshal_set_param(void *object,
uint32_t seq,
enum spa_direction direction,
uint32_t port_id,
const struct spa_param *param)
{
struct pw_resource *resource = object;
struct pw_connection *connection = resource->client->protocol_private;
@ -546,9 +578,11 @@ client_node_marshal_set_property(void *object,
spa_pod_builder_struct(&b.b, &f,
SPA_POD_TYPE_INT, seq,
SPA_POD_TYPE_INT, id, SPA_POD_TYPE_BYTES, value, size);
SPA_POD_TYPE_INT, direction,
SPA_POD_TYPE_INT, port_id,
SPA_POD_TYPE_POD, param);
pw_connection_end_write(connection, resource->id, PW_CLIENT_NODE_EVENT_SET_PROPERTY,
pw_connection_end_write(connection, resource->id, PW_CLIENT_NODE_EVENT_SET_PARAM,
b.b.offset);
}
@ -648,7 +682,10 @@ client_node_marshal_node_command(void *object, uint32_t seq, const struct spa_co
}
static void
client_node_marshal_port_command(void *object, uint32_t port_id, const struct spa_command *command)
client_node_marshal_port_command(void *object,
uint32_t direction,
uint32_t port_id,
const struct spa_command *command)
{
struct pw_resource *resource = object;
struct pw_connection *connection = resource->client->protocol_private;
@ -657,7 +694,10 @@ client_node_marshal_port_command(void *object, uint32_t port_id, const struct sp
core_update_map(resource->client);
spa_pod_builder_struct(&b.b, &f, SPA_POD_TYPE_INT, port_id, SPA_POD_TYPE_POD, command);
spa_pod_builder_struct(&b.b, &f,
SPA_POD_TYPE_INT, direction,
SPA_POD_TYPE_INT, port_id,
SPA_POD_TYPE_POD, command);
pw_connection_end_write(connection, resource->id, PW_CLIENT_NODE_EVENT_PORT_COMMAND,
b.b.offset);
@ -879,11 +919,12 @@ static const demarshal_func_t pw_protocol_native_server_client_node_demarshal[]
static const struct pw_client_node_events pw_protocol_native_server_client_node_events = {
&client_node_marshal_done,
&client_node_marshal_set_props,
&client_node_marshal_event,
&client_node_marshal_add_port,
&client_node_marshal_remove_port,
&client_node_marshal_set_format,
&client_node_marshal_set_property,
&client_node_marshal_set_param,
&client_node_marshal_add_mem,
&client_node_marshal_use_buffers,
&client_node_marshal_node_command,

View file

@ -22,9 +22,11 @@
#include "pipewire/client/interfaces.h"
#include "pipewire/server/resource.h"
/** \cond */
struct impl {
struct pw_resource this;
};
/** \endcond */
struct pw_resource *pw_resource_new(struct pw_client *client,
uint32_t id, uint32_t type, void *object, pw_destroy_t destroy)

View file

@ -23,6 +23,7 @@
#include "pipewire/client/log.h"
#include "pipewire/server/work-queue.h"
/** \cond */
struct work_item {
uint32_t id;
void *obj;
@ -43,7 +44,7 @@ struct impl {
struct spa_list free_list;
int n_queued;
};
/** \endcond */
static void process_work_queue(struct spa_loop_utils *utils, struct spa_source *source, void *data)
{
@ -77,12 +78,12 @@ static void process_work_queue(struct spa_loop_utils *utils, struct spa_source *
}
}
/**
* pw_work_queue_new:
/** Create a new \ref pw_work_queue
*
* Create a new #struct pw_work_queue.
* \param loop the loop to use
* \return a newly allocated work queue
*
* Returns: a new #struct pw_work_queue
* \memberof pw_work_queue
*/
struct pw_work_queue *pw_work_queue_new(struct pw_loop *loop)
{
@ -104,6 +105,11 @@ struct pw_work_queue *pw_work_queue_new(struct pw_loop *loop)
return this;
}
/** Destroy a work queue
* \param queue the work queue to destroy
*
* \memberof pw_work_queue
*/
void pw_work_queue_destroy(struct pw_work_queue *queue)
{
struct impl *impl = SPA_CONTAINER_OF(queue, struct impl, this);
@ -125,6 +131,16 @@ void pw_work_queue_destroy(struct pw_work_queue *queue)
free(impl);
}
/** Add an item to the work queue
*
* \param queue the work queue
* \param obj the object owning the work item
* \param res a result code
* \param func a work function
* \param data passed to \a func
*
* \memberof pw_work_queue
*/
uint32_t
pw_work_queue_add(struct pw_work_queue *queue, void *obj, int res, pw_work_func_t func, void *data)
{
@ -169,6 +185,13 @@ pw_work_queue_add(struct pw_work_queue *queue, void *obj, int res, pw_work_func_
return item->id;
}
/** Cancel a work item
* \param queue the work queue
* \param obj the owner object
* \param id the wotk id to cancel
*
* \memberof pw_work_queue
*/
void pw_work_queue_cancel(struct pw_work_queue *queue, void *obj, uint32_t id)
{
struct impl *impl = SPA_CONTAINER_OF(queue, struct impl, this);
@ -188,6 +211,14 @@ void pw_work_queue_cancel(struct pw_work_queue *queue, void *obj, uint32_t id)
pw_loop_signal_event(impl->this.loop, impl->wakeup);
}
/** Complete a work item
* \param queue the work queue
* \param obj the owner object
* \param seq the sequence number that completed
* \param res the result of the completed work
*
* \memberof pw_work_queue
*/
bool pw_work_queue_complete(struct pw_work_queue *queue, void *obj, uint32_t seq, int res)
{
struct work_item *item;

View file

@ -28,14 +28,14 @@ extern "C" {
typedef void (*pw_work_func_t) (void *obj, void *data, int res, uint32_t id);
/**
* pw_work_queue:
/** \class pw_work_queue
*
* PipeWire work queue object.
* PipeWire work queue object
*/
struct pw_work_queue {
struct pw_loop *loop;
struct pw_loop *loop; /**< the loop used for handling work */
/** Emited when the work queue is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_work_queue *queue));
};