/* PipeWire */
/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */
/* SPDX-License-Identifier: MIT */
#ifndef PIPEWIRE_CORE_H
#define PIPEWIRE_CORE_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#include <errno.h>
#include <spa/utils/hook.h>
#include <pipewire/type.h>
/** \defgroup pw_core Core
*
* \ brief The core global object .
*
* This is a special singleton object . It is used for internal PipeWire
* protocol features . Connecting to a PipeWire instance returns one core
* object , the caller should then register event listeners
* using \ ref pw_core_add_listener .
*
* Updates to the core object are then provided through the \ ref
* pw_core_events interface . See \ ref page_tutorial2 for an example .
*/
/**
* \ addtogroup pw_core
* \ {
*/
#define PW_TYPE_INTERFACE_Core PW_TYPE_INFO_INTERFACE_BASE "Core"
#define PW_TYPE_INTERFACE_Registry PW_TYPE_INFO_INTERFACE_BASE "Registry"
#define PW_CORE_PERM_MASK PW_PERM_R|PW_PERM_X|PW_PERM_M
#define PW_VERSION_CORE 4
struct pw_core;
#define PW_VERSION_REGISTRY 3
struct pw_registry;
#ifndef PW_API_CORE_IMPL
#define PW_API_CORE_IMPL static inline
#endif
#ifndef PW_API_REGISTRY_IMPL
#define PW_API_REGISTRY_IMPL static inline
#endif
/** The default remote name to connect to */
#define PW_DEFAULT_REMOTE "pipewire-0"
/** default ID for the core object after connect */
#define PW_ID_CORE 0
/* invalid ID that matches any object when used for permissions */
#define PW_ID_ANY (uint32_t)(0 xffffffff)
/** The core information. Extra information may be added in later versions,
* clients must not assume a constant struct size */
struct pw_core_info {
uint32_t id; /**< id of the global */
uint32_t cookie; /**< a random cookie for identifying this instance of PipeWire */
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 */
#define PW_CORE_CHANGE_MASK_PROPS (1 << 0 )
#define PW_CORE_CHANGE_MASK_ALL ((1 << 1 )-1 )
uint64_t change_mask; /**< bitfield of changed fields since last call */
struct spa_dict *props; /**< extra properties */
};
#include <pipewire/context.h>
#include <pipewire/properties.h>
#include <pipewire/proxy.h>
/** Update an existing \ref pw_core_info with \a update with reset. When info is NULL,
* a new one will be allocated. Returns NULL on failure. */
struct pw_core_info *
pw_core_info_update(struct pw_core_info *info,
const struct pw_core_info *update);
/** Update an existing \ref pw_core_info with \a update. When info is NULL, a new one
* will be allocated. Returns NULL on failure */
struct pw_core_info *
pw_core_info_merge(struct pw_core_info *info,
const struct pw_core_info *update, bool reset);
/** Free a \ref pw_core_info */
void pw_core_info_free(struct pw_core_info *info);
/** Core */
#define PW_CORE_EVENT_INFO 0
#define PW_CORE_EVENT_DONE 1
#define PW_CORE_EVENT_PING 2
#define PW_CORE_EVENT_ERROR 3
#define PW_CORE_EVENT_REMOVE_ID 4
#define PW_CORE_EVENT_BOUND_ID 5
#define PW_CORE_EVENT_ADD_MEM 6
#define PW_CORE_EVENT_REMOVE_MEM 7
#define PW_CORE_EVENT_BOUND_PROPS 8
#define PW_CORE_EVENT_NUM 9
/** \struct pw_core_events
* \ brief Core events
*/
struct pw_core_events {
#define PW_VERSION_CORE_EVENTS 1
uint32_t version;
/**
* Notify new core info
*
* This event is emitted when first bound to the core or when the
* hello method is called .
*
* \ param info new core info
*/
void (*info) (void *data, const struct pw_core_info *info);
/**
* Emit a done event
*
* The done event is emitted as a result of a sync method with the
* same seq number .
*
* \ param seq the seq number passed to the sync method call
*/
void (*done) (void *data, uint32_t id, int seq);
/** Emit a ping event
*
* The client should reply with a pong reply with the same seq
* number .
*/
void (*ping) (void *data, uint32_t id, int seq);
/**
* Fatal error event
*
* The error event is sent out when a fatal ( non - recoverable )
* error has occurred . The id argument is the proxy 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 .
*
* This event is usually also emitted on the proxy object with
* \ a id .
*
* \ param id object where the error occurred
* \ param seq the sequence number that generated the error
* \ param res error code
* \ param message error description
*/
void (*error) (void *data, uint32_t id, int seq, int res, const char *message);
/**
* 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 *data, uint32_t id);
/**
* Notify an object binding
*
* This event is emitted when a local object ID is bound to a
* global ID . It is emitted before the global becomes visible in the
* registry .
*
* The bound_props event is an enhanced version of this event that
* also contains the extra global properties .
*
* \ param id bound object ID
* \ param global_id the global id bound to
*/
void (*bound_id) (void *data, uint32_t id, uint32_t global_id);
/**
* Add memory for a client
*
* Memory is given to a client as \ a fd of a certain
* memory \ a type .
*
* Further references to this fd will be made with the per memory
* unique identifier \ a id .
*
* \ param id the unique id of the memory
* \ param type the memory type , one of enum spa_data_type
* \ param fd the file descriptor
* \ param flags extra flags
*/
void (*add_mem) (void *data, uint32_t id, uint32_t type, int fd, uint32_t flags);
/**
* Remove memory for a client
*
* \ param id the memory id to remove
*/
void (*remove_mem) (void *data, uint32_t id);
/**
* Notify an object binding
*
* This event is emitted when a local object ID is bound to a
* global ID . It is emitted before the global becomes visible in the
* registry .
*
* This is an enhanced version of the bound_id event .
*
* \ param id bound object ID
* \ param global_id the global id bound to
* \ param props The properties of the new global object .
*
* Since version 4 : 1
*/
void (*bound_props) (void *data, uint32_t id, uint32_t global_id, const struct spa_dict *props);
};
#define PW_CORE_METHOD_ADD_LISTENER 0
#define PW_CORE_METHOD_HELLO 1
#define PW_CORE_METHOD_SYNC 2
#define PW_CORE_METHOD_PONG 3
#define PW_CORE_METHOD_ERROR 4
#define PW_CORE_METHOD_GET_REGISTRY 5
#define PW_CORE_METHOD_CREATE_OBJECT 6
#define PW_CORE_METHOD_DESTROY 7
#define PW_CORE_METHOD_NUM 8
/**
* \ struct pw_core_methods
* \ brief Core methods
*
* The core global object . This is a singleton object used for
* creating new objects in the remote PipeWire instance . It is
* also used for internal features .
*/
struct pw_core_methods {
#define PW_VERSION_CORE_METHODS 0
uint32_t version;
int (*add_listener) (void *object,
struct spa_hook *listener,
const struct pw_core_events *events,
void *data);
/**
* Start a conversation with the server . This will send
* the core info and will destroy all resources for the client
* ( except the core and client resource ) .
*
* This requires X permissions on the core .
*/
int (*hello) (void *object, uint32_t version);
/**
* Do server roundtrip
*
* Ask the server to emit the ' done ' event with \ a seq .
*
* 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 seq number passed to the done event
*
* This requires X permissions on the core .
*/
int (*sync) (void *object, uint32_t id, int seq);
/**
* Reply to a server ping event .
*
* Reply to the server ping event with the same seq .
*
* \ param seq the seq number received in the ping event
*
* This requires X permissions on the core .
*/
int (*pong) (void *object, uint32_t id, int seq);
/**
* Fatal error event
*
* The error method is sent out when a fatal ( non - recoverable )
* error has occurred . The id argument is the proxy object where
* the error occurred , most often in response to an event on that
* object . The message is a brief description of the error ,
* for ( debugging ) convenience .
*
* This method is usually also emitted on the resource object with
* \ a id .
*
* \ param id resource id where the error occurred
* \ param res error code
* \ param message error description
*
* This requires X permissions on the core .
*/
int (*error) (void *object, uint32_t id, int seq, int res, const char *message);
/**
* 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 version the client version
* \ param user_data_size extra size
*
* This requires X permissions on the core .
*/
struct pw_registry * (*get_registry) (void *object, uint32_t version,
size_t user_data_size);
/**
* Create a new object on the PipeWire server from a factory .
*
* \ param factory_name the factory name to use
* \ param type the interface to bind to
* \ param version the version of the interface
* \ param props extra properties
* \ param user_data_size extra size
*
* This requires X permissions on the core .
*/
void * (*create_object) (void *object,
const char *factory_name,
const char *type,
uint32_t version,
const struct spa_dict *props,
size_t user_data_size);
/**
* Destroy an resource
*
* Destroy the server resource for the given proxy .
*
* \ param obj the proxy to destroy
*
* This requires X permissions on the core .
*/
int (*destroy) (void *object, void *proxy);
};
/** \copydoc pw_core_methods.add_listener
* \sa pw_core_methods.add_listener */
PW_API_CORE_IMPL int pw_core_add_listener(struct pw_core *object,
struct spa_hook *listener,
const struct pw_core_events *events,
void *data)
{
return spa_api_method_r(int , -ENOTSUP,
pw_core, (struct spa_interface*)object, add_listener, 0 ,
listener, events, data);
}
/** \copydoc pw_core_methods.hello
* \sa pw_core_methods.hello */
PW_API_CORE_IMPL int pw_core_hello(struct pw_core *object, uint32_t version)
{
return spa_api_method_r(int , -ENOTSUP,
pw_core, (struct spa_interface*)object, hello, 0 ,
version);
}
/** \copydoc pw_core_methods.sync
* \sa pw_core_methods.sync */
PW_API_CORE_IMPL int pw_core_sync(struct pw_core *object, uint32_t id, int seq)
{
return spa_api_method_r(int , -ENOTSUP,
pw_core, (struct spa_interface*)object, sync, 0 ,
id, seq);
}
/** \copydoc pw_core_methods.pong
* \sa pw_core_methods.pong */
PW_API_CORE_IMPL int pw_core_pong(struct pw_core *object, uint32_t id, int seq)
{
return spa_api_method_r(int , -ENOTSUP,
pw_core, (struct spa_interface*)object, pong, 0 ,
id, seq);
}
/** \copydoc pw_core_methods.error
* \sa pw_core_methods.error */
PW_API_CORE_IMPL int pw_core_error(struct pw_core *object, uint32_t id, int seq, int res, const char *message)
{
return spa_api_method_r(int , -ENOTSUP,
pw_core, (struct spa_interface*)object, error, 0 ,
id, seq, res, message);
}
PW_API_CORE_IMPL
SPA_PRINTF_FUNC(5 , 0 ) int
pw_core_errorv(struct pw_core *core, uint32_t id, int seq,
int res, const char *message, va_list args)
{
char buffer[1024 ];
vsnprintf(buffer, sizeof (buffer), message, args);
buffer[1023 ] = '\0' ;
return pw_core_error(core, id, seq, res, buffer);
}
PW_API_CORE_IMPL
SPA_PRINTF_FUNC(5 , 6 ) int
pw_core_errorf(struct pw_core *core, uint32_t id, int seq,
int res, const char *message, ...)
{
va_list args;
int r;
va_start(args, message);
r = pw_core_errorv(core, id, seq, res, message, args);
va_end(args);
return r;
}
/** \copydoc pw_core_methods.get_registry
* \sa pw_core_methods.get_registry */
PW_API_CORE_IMPL struct pw_registry *
pw_core_get_registry(struct pw_core *core, uint32_t version, size_t user_data_size)
{
return spa_api_method_r(struct pw_registry*, NULL,
pw_core, (struct spa_interface*)core, get_registry, 0 ,
version, user_data_size);
}
/** \copydoc pw_core_methods.create_object
* \sa pw_core_methods.create_object */
PW_API_CORE_IMPL void *
pw_core_create_object(struct pw_core *core,
const char *factory_name,
const char *type,
uint32_t version,
const struct spa_dict *props,
size_t user_data_size)
{
return spa_api_method_r(void *, NULL,
pw_core, (struct spa_interface*)core, create_object, 0 ,
factory_name, type, version, props, user_data_size);
}
/** \copydoc pw_core_methods.destroy
* \sa pw_core_methods.destroy */
PW_API_CORE_IMPL void
pw_core_destroy(struct pw_core *core, void *proxy)
{
spa_api_method_v(pw_core, (struct spa_interface*)core, destroy, 0 ,
proxy);
}
/**
* \ }
*/
/** \defgroup pw_registry Registry
*
* The registry object is a singleton object that keeps track of
* global objects on the PipeWire instance . See also \ ref pw_global .
*
* Global objects typically represent an actual object in PipeWire
* ( for example , a module or node ) or they are singleton
* objects such as the core .
*
* When a client creates a registry object , the registry object
* will emit a global event for each global currently in the
* registry . Globals come and go as a result of device hotplugs or
* reconfiguration or other events , and the registry will send out
* global and global_remove events to keep the client up to date
* with the changes . To mark the end of the initial burst of
* events , the client can use the pw_core . sync methosd immediately
* after calling pw_core . get_registry .
*
* A client can bind to a global object by using the bind
* request . This creates a client - side proxy that lets the object
* emit events to the client and lets the client invoke methods on
* the object . See \ ref page_proxy
*
* Clients can also change the permissions of the global objects that
* it can see . This is interesting when you want to configure a
* pipewire session before handing it to another application . You
* can , for example , hide certain existing or new objects or limit
* the access permissions on an object .
*/
/**
* \ addtogroup pw_registry
* \ {
*/
#define PW_REGISTRY_EVENT_GLOBAL 0
#define PW_REGISTRY_EVENT_GLOBAL_REMOVE 1
#define PW_REGISTRY_EVENT_NUM 2
/** Registry events */
struct pw_registry_events {
#define PW_VERSION_REGISTRY_EVENTS 0
uint32_t version;
/**
* 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 permissions the permissions of the object
* \ param type the type of the interface
* \ param version the version of the interface
* \ param props extra properties of the global
*/
void (*global) (void *data, uint32_t id,
uint32_t permissions, const char *type, uint32_t version,
const struct spa_dict *props);
/**
* Notify of a global object removal
*
* Emitted 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 *data, uint32_t id);
};
#define PW_REGISTRY_METHOD_ADD_LISTENER 0
#define PW_REGISTRY_METHOD_BIND 1
#define PW_REGISTRY_METHOD_DESTROY 2
#define PW_REGISTRY_METHOD_NUM 3
/** Registry methods */
struct pw_registry_methods {
#define PW_VERSION_REGISTRY_METHODS 0
uint32_t version;
int (*add_listener) (void *object,
struct spa_hook *listener,
const struct pw_registry_events *events,
void *data);
/**
* 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 type the interface type to bind to
* \ param version the interface version to use
* \ returns the new object
*/
void * (*bind) (void *object, uint32_t id, const char *type, uint32_t version,
size_t use_data_size);
/**
* Attempt to destroy a global object
*
* Try to destroy the global object .
*
* \ param id the global id to destroy . The client needs X permissions
* on the global .
*/
int (*destroy) (void *object, uint32_t id);
};
/** Registry */
/** \copydoc pw_registry_methods.add_listener
* \sa pw_registry_methods.add_listener */
PW_API_REGISTRY_IMPL int pw_registry_add_listener(struct pw_registry *registry,
struct spa_hook *listener,
const struct pw_registry_events *events,
void *data)
{
return spa_api_method_r(int , -ENOTSUP,
pw_registry, (struct spa_interface*)registry, add_listener, 0 ,
listener, events, data);
}
/** \copydoc pw_registry_methods.bind
* \sa pw_registry_methods.bind */
PW_API_REGISTRY_IMPL void *
pw_registry_bind(struct pw_registry *registry,
uint32_t id, const char *type, uint32_t version,
size_t user_data_size)
{
return spa_api_method_r(void *, NULL,
pw_registry, (struct spa_interface*)registry, bind, 0 ,
id, type, version, user_data_size);
}
/** \copydoc pw_registry_methods.destroy
* \sa pw_registry_methods.destroy */
PW_API_REGISTRY_IMPL int
pw_registry_destroy(struct pw_registry *registry, uint32_t id)
{
return spa_api_method_r(int , -ENOTSUP,
pw_registry, (struct spa_interface*)registry, destroy, 0 , id);
}
/**
* \ }
*/
/**
* \ addtogroup pw_core
* \ {
*/
/** Connect to a PipeWire instance
*
* \ param context a \ ref pw_context
* \ param properties optional properties , ownership of the properties is
* taken .
* \ param user_data_size extra user data size
*
* \ return a \ ref pw_core on success or NULL with errno set on error . The core
* will have an id of \ ref PW_ID_CORE ( 0 )
*/
struct pw_core *
pw_context_connect(struct pw_context *context,
struct pw_properties *properties,
size_t user_data_size);
/** Connect to a PipeWire instance on the given socket
*
* \ param context a \ ref pw_context
* \ param fd the connected socket to use , the socket will be closed
* automatically on disconnect or error .
* \ param properties optional properties , ownership of the properties is
* taken .
* \ param user_data_size extra user data size
*
* \return a \ref pw_core on success or NULL with errno set on error */
struct pw_core *
pw_context_connect_fd(struct pw_context *context,
int fd,
struct pw_properties *properties,
size_t user_data_size);
/** Connect to a given PipeWire instance
*
* \ param context a \ ref pw_context to connect to
* \ param properties optional properties , ownership of the properties is
* taken .
* \ param user_data_size extra user data size
*
* \return a \ref pw_core on success or NULL with errno set on error */
struct pw_core *
pw_context_connect_self(struct pw_context *context,
struct pw_properties *properties,
size_t user_data_size);
/** Steal the fd of the core connection or < 0 on error. The core
* will be disconnected after this call. */
int pw_core_steal_fd(struct pw_core *core);
/** Pause or resume the core. When the core is paused, no new events
* will be dispatched until the core is resumed again. */
int pw_core_set_paused(struct pw_core *core, bool paused);
/** disconnect and destroy a core */
int pw_core_disconnect(struct pw_core *core);
/** Get the user_data. It is of the size specified when this object was
* constructed */
void *pw_core_get_user_data(struct pw_core *core);
/** Get the client proxy of the connected core. This will have the id
* of PW_ID_CLIENT (1) */
struct pw_client * pw_core_get_client(struct pw_core *core);
/** Get the context object used to created this core */
struct pw_context * pw_core_get_context(struct pw_core *core);
/** Get properties from the core */
const struct pw_properties *pw_core_get_properties(struct pw_core *core);
/** Update the core properties. This updates the properties
* of the associated client .
* \return the number of properties that were updated */
int pw_core_update_properties(struct pw_core *core, const struct spa_dict *dict);
/** Get the core mempool object */
struct pw_mempool * pw_core_get_mempool(struct pw_core *core);
/** Get the proxy with the given id */
struct pw_proxy *pw_core_find_proxy(struct pw_core *core, uint32_t id);
/** Export an object into the PipeWire instance associated with core */
struct pw_proxy *pw_core_export(struct pw_core *core, /**< the core */
const char *type, /**< the type of object */
const struct spa_dict *props, /**< extra properties */
void *object, /**< object to export */
size_t user_data_size /**< extra user data */);
/**
* \ }
*/
#ifdef __cplusplus
}
#endif
#endif /* PIPEWIRE_CORE_H */
Messung V0.5 in Prozent C=92 H=90 G=90
¤ Dauer der Verarbeitung: 0.12 Sekunden
¤
*© Formatika GbR, Deutschland