mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
Add create_link message
Add create_link for completeness Add some more docs
This commit is contained in:
parent
6a3b5b1bf7
commit
e48c361a66
12 changed files with 329 additions and 64 deletions
|
|
@ -153,11 +153,11 @@ core_event_update_types(void *object, uint32_t first_id, uint32_t n_types, const
|
|||
}
|
||||
|
||||
static const struct pw_core_events core_events = {
|
||||
&core_event_info,
|
||||
&core_event_update_types,
|
||||
&core_event_done,
|
||||
&core_event_error,
|
||||
&core_event_remove_id,
|
||||
&core_event_update_types
|
||||
&core_event_info,
|
||||
};
|
||||
|
||||
static void module_event_info(void *object, struct pw_module_info *info)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,16 @@ extern "C" {
|
|||
* The most convenient way to deal with the asynchronous calls is probably
|
||||
* with the thread loop (See \subpage page_thread_loop for more details).
|
||||
*
|
||||
* \subsection ssec_client_api_context_proxy Proxy
|
||||
*
|
||||
* Proxies are client side representations of server side resources. They
|
||||
* allow communication between client and server objects.
|
||||
*
|
||||
* The context maintains a list of all proxies, including a core proxy
|
||||
* object and a registry object.
|
||||
*
|
||||
* See also \subpage page_proxy
|
||||
*
|
||||
* \section sec_client_api_context Context
|
||||
*
|
||||
* \subsection ssec_context_create Create
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ extern "C" {
|
|||
#include <pipewire/client/introspect.h>
|
||||
|
||||
/**
|
||||
* \page page_pipewire The PipeWire protocol
|
||||
* \page page_pipewire_protocol The PipeWire protocol
|
||||
* \section page_ifaces_pipewire Interfaces
|
||||
* - \subpage page_iface_pw_core - core global object
|
||||
* - \subpage page_iface_pw_registry - global registry object
|
||||
|
|
@ -48,13 +48,14 @@ extern "C" {
|
|||
* \section page_iface_pw_core API
|
||||
*/
|
||||
|
||||
#define PW_CORE_METHOD_CLIENT_UPDATE 0
|
||||
#define PW_CORE_METHOD_UPDATE_TYPES 0
|
||||
#define PW_CORE_METHOD_SYNC 1
|
||||
#define PW_CORE_METHOD_GET_REGISTRY 2
|
||||
#define PW_CORE_METHOD_CREATE_NODE 3
|
||||
#define PW_CORE_METHOD_CREATE_CLIENT_NODE 4
|
||||
#define PW_CORE_METHOD_UPDATE_TYPES 5
|
||||
#define PW_CORE_METHOD_NUM 6
|
||||
#define PW_CORE_METHOD_CLIENT_UPDATE 3
|
||||
#define PW_CORE_METHOD_CREATE_NODE 4
|
||||
#define PW_CORE_METHOD_CREATE_CLIENT_NODE 5
|
||||
#define PW_CORE_METHOD_CREATE_LINK 6
|
||||
#define PW_CORE_METHOD_NUM 7
|
||||
|
||||
/**
|
||||
* \struct pw_core_methods
|
||||
|
|
@ -66,10 +67,18 @@ extern "C" {
|
|||
*/
|
||||
struct pw_core_methods {
|
||||
/**
|
||||
* Update the client properties
|
||||
* \param props the new client properties
|
||||
* 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 (*client_update) (void *object, const struct spa_dict *props);
|
||||
void (*update_types) (void *object,
|
||||
uint32_t first_id,
|
||||
uint32_t n_types,
|
||||
const char **types);
|
||||
/**
|
||||
* Do server roundtrip
|
||||
*
|
||||
|
|
@ -88,6 +97,11 @@ struct pw_core_methods {
|
|||
* \param id the client proxy id
|
||||
*/
|
||||
void (*get_registry) (void *object, uint32_t new_id);
|
||||
/**
|
||||
* Update the client properties
|
||||
* \param props the new client properties
|
||||
*/
|
||||
void (*client_update) (void *object, const struct spa_dict *props);
|
||||
/**
|
||||
* Create a new node on the PipeWire server from a factory
|
||||
*
|
||||
|
|
@ -114,32 +128,39 @@ struct pw_core_methods {
|
|||
const struct spa_dict *props,
|
||||
uint32_t new_id);
|
||||
/**
|
||||
* Update the type map
|
||||
* Create a new link between two node ports
|
||||
*
|
||||
* 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
|
||||
* \param output_node_id the global id of the output node
|
||||
* \param output_port_id the id of the output port
|
||||
* \param input_node_id the global id of the input node
|
||||
* \param input_port_id the id of the input port
|
||||
* \param filter an optional format filter
|
||||
* \param props optional properties
|
||||
* \param new_id the client proxy id
|
||||
*/
|
||||
void (*update_types) (void *object,
|
||||
uint32_t first_id,
|
||||
uint32_t n_types,
|
||||
const char **types);
|
||||
void (*create_link) (void *object,
|
||||
uint32_t output_node_id,
|
||||
uint32_t output_port_id,
|
||||
uint32_t input_node_id,
|
||||
uint32_t input_port_id,
|
||||
const struct spa_format *filter,
|
||||
const struct spa_dict *props,
|
||||
uint32_t new_id);
|
||||
};
|
||||
|
||||
#define pw_core_do_client_update(r,...) ((struct pw_core_methods*)r->iface->methods)->client_update(r,__VA_ARGS__)
|
||||
#define pw_core_do_update_types(r,...) ((struct pw_core_methods*)r->iface->methods)->update_types(r,__VA_ARGS__)
|
||||
#define pw_core_do_sync(r,...) ((struct pw_core_methods*)r->iface->methods)->sync(r,__VA_ARGS__)
|
||||
#define pw_core_do_get_registry(r,...) ((struct pw_core_methods*)r->iface->methods)->get_registry(r,__VA_ARGS__)
|
||||
#define pw_core_do_client_update(r,...) ((struct pw_core_methods*)r->iface->methods)->client_update(r,__VA_ARGS__)
|
||||
#define pw_core_do_create_node(r,...) ((struct pw_core_methods*)r->iface->methods)->create_node(r,__VA_ARGS__)
|
||||
#define pw_core_do_create_client_node(r,...) ((struct pw_core_methods*)r->iface->methods)->create_client_node(r,__VA_ARGS__)
|
||||
#define pw_core_do_update_types(r,...) ((struct pw_core_methods*)r->iface->methods)->update_types(r,__VA_ARGS__)
|
||||
#define pw_core_do_create_link(r,...) ((struct pw_core_methods*)r->iface->methods)->create_link(r,__VA_ARGS__)
|
||||
|
||||
#define PW_CORE_EVENT_INFO 0
|
||||
#define PW_CORE_EVENT_UPDATE_TYPES 0
|
||||
#define PW_CORE_EVENT_DONE 1
|
||||
#define PW_CORE_EVENT_ERROR 2
|
||||
#define PW_CORE_EVENT_REMOVE_ID 3
|
||||
#define PW_CORE_EVENT_UPDATE_TYPES 4
|
||||
#define PW_CORE_EVENT_INFO 4
|
||||
#define PW_CORE_EVENT_NUM 5
|
||||
|
||||
/** \struct pw_core_events
|
||||
|
|
@ -148,11 +169,18 @@ struct pw_core_methods {
|
|||
*/
|
||||
struct pw_core_events {
|
||||
/**
|
||||
* Notify new core info
|
||||
* Update the type map
|
||||
*
|
||||
* \param info new core info
|
||||
* 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 (*info) (void *object, struct pw_core_info *info);
|
||||
void (*update_types) (void *object,
|
||||
uint32_t first_id,
|
||||
uint32_t n_types,
|
||||
const char **types);
|
||||
/**
|
||||
* Emit a done event
|
||||
*
|
||||
|
|
@ -186,25 +214,18 @@ struct pw_core_events {
|
|||
*/
|
||||
void (*remove_id) (void *object, uint32_t id);
|
||||
/**
|
||||
* Update the type map
|
||||
* Notify new core info
|
||||
*
|
||||
* 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
|
||||
* \param info new core info
|
||||
*/
|
||||
void (*update_types) (void *object,
|
||||
uint32_t first_id,
|
||||
uint32_t n_types,
|
||||
const char **types);
|
||||
void (*info) (void *object, struct pw_core_info *info);
|
||||
};
|
||||
|
||||
#define pw_core_notify_info(r,...) ((struct pw_core_events*)r->iface->events)->info(r,__VA_ARGS__)
|
||||
#define pw_core_notify_update_types(r,...) ((struct pw_core_events*)r->iface->events)->update_types(r,__VA_ARGS__)
|
||||
#define pw_core_notify_done(r,...) ((struct pw_core_events*)r->iface->events)->done(r,__VA_ARGS__)
|
||||
#define pw_core_notify_error(r,...) ((struct pw_core_events*)r->iface->events)->error(r,__VA_ARGS__)
|
||||
#define pw_core_notify_remove_id(r,...) ((struct pw_core_events*)r->iface->events)->remove_id(r,__VA_ARGS__)
|
||||
#define pw_core_notify_update_types(r,...) ((struct pw_core_events*)r->iface->events)->update_types(r,__VA_ARGS__)
|
||||
#define pw_core_notify_info(r,...) ((struct pw_core_events*)r->iface->events)->info(r,__VA_ARGS__)
|
||||
|
||||
|
||||
#define PW_REGISTRY_METHOD_BIND 0
|
||||
|
|
|
|||
|
|
@ -193,6 +193,50 @@ core_marshal_create_client_node(void *object,
|
|||
b.b.offset);
|
||||
}
|
||||
|
||||
static void
|
||||
core_marshal_create_link(void *object,
|
||||
uint32_t output_node_id,
|
||||
uint32_t output_port_id,
|
||||
uint32_t input_node_id,
|
||||
uint32_t input_port_id,
|
||||
const struct spa_format *filter,
|
||||
const struct spa_dict *props,
|
||||
uint32_t new_id)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct pw_connection *connection = proxy->context->protocol_private;
|
||||
struct builder b = { {NULL, 0, 0, NULL, write_pod}, connection };
|
||||
struct spa_pod_frame f;
|
||||
uint32_t i, n_items;
|
||||
|
||||
if (connection == NULL)
|
||||
return;
|
||||
|
||||
core_update_map(proxy->context);
|
||||
|
||||
n_items = props ? props->n_items : 0;
|
||||
|
||||
spa_pod_builder_add(&b.b,
|
||||
SPA_POD_TYPE_STRUCT, &f,
|
||||
SPA_POD_TYPE_INT, output_node_id,
|
||||
SPA_POD_TYPE_INT, output_port_id,
|
||||
SPA_POD_TYPE_INT, input_node_id,
|
||||
SPA_POD_TYPE_INT, input_port_id,
|
||||
SPA_POD_TYPE_POD, filter,
|
||||
SPA_POD_TYPE_INT, n_items, 0);
|
||||
|
||||
for (i = 0; i < n_items; i++) {
|
||||
spa_pod_builder_add(&b.b,
|
||||
SPA_POD_TYPE_STRING, props->items[i].key,
|
||||
SPA_POD_TYPE_STRING, props->items[i].value, 0);
|
||||
}
|
||||
spa_pod_builder_add(&b.b,
|
||||
SPA_POD_TYPE_INT, new_id,
|
||||
-SPA_POD_TYPE_STRUCT, &f, 0);
|
||||
|
||||
pw_connection_end_write(connection, proxy->id, PW_CORE_METHOD_CREATE_LINK, b.b.offset);
|
||||
}
|
||||
|
||||
static void
|
||||
core_marshal_update_types(void *object, uint32_t first_id, uint32_t n_types, const char **types)
|
||||
{
|
||||
|
|
@ -891,20 +935,21 @@ static void registry_marshal_bind(void *object, uint32_t id, uint32_t version, u
|
|||
}
|
||||
|
||||
static const struct pw_core_methods pw_protocol_native_client_core_methods = {
|
||||
&core_marshal_client_update,
|
||||
&core_marshal_update_types,
|
||||
&core_marshal_sync,
|
||||
&core_marshal_get_registry,
|
||||
&core_marshal_client_update,
|
||||
&core_marshal_create_node,
|
||||
&core_marshal_create_client_node,
|
||||
&core_marshal_update_types,
|
||||
&core_marshal_create_link
|
||||
};
|
||||
|
||||
static const demarshal_func_t pw_protocol_native_client_core_demarshal[] = {
|
||||
&core_demarshal_info,
|
||||
static const demarshal_func_t pw_protocol_native_client_core_demarshal[PW_CORE_EVENT_NUM] = {
|
||||
&core_demarshal_update_types,
|
||||
&core_demarshal_done,
|
||||
&core_demarshal_error,
|
||||
&core_demarshal_remove_id,
|
||||
&core_demarshal_update_types,
|
||||
&core_demarshal_info
|
||||
};
|
||||
|
||||
static const struct pw_interface pw_protocol_native_client_core_interface = {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,53 @@ extern "C" {
|
|||
#include <pipewire/client/type.h>
|
||||
#include <pipewire/client/utils.h>
|
||||
|
||||
/** \page page_proxy Proxy
|
||||
*
|
||||
* \section sec_page_proxy_overview Overview
|
||||
*
|
||||
* The proxy object is a client side representation of a resource
|
||||
* that lives on the server.
|
||||
*
|
||||
* It is used to communicate with the server side object.
|
||||
*
|
||||
* \section sec_page_proxy_create Create
|
||||
*
|
||||
* A client first creates a new proxy object with pw_proxy_new(). A
|
||||
* type must be provided for this object.
|
||||
*
|
||||
* The protocol of the context will usually install an interface to
|
||||
* translate method calls and events to the wire format.
|
||||
*
|
||||
* The creator of the proxy will usually also install an event
|
||||
* implementation of the particular object type.
|
||||
*
|
||||
* \section sec_page_proxy_bind Bind
|
||||
*
|
||||
* To actually use the proxy object, one needs to create a server
|
||||
* side resource for it. This can be done by, for example, binding
|
||||
* to a global object or by calling a method that creates and binds
|
||||
* to a new remote object. In all cases, the local id is passed to
|
||||
* the server and is used to create a resource with the same id.
|
||||
*
|
||||
* \section sec_page_proxy_methods Methods
|
||||
*
|
||||
* To call a method on the proxy use the interface methods. Calling
|
||||
* any interface method will result in a request to the server to
|
||||
* perform the requested action on the corresponding resource.
|
||||
*
|
||||
* \section sec_page_proxy_events Events
|
||||
*
|
||||
* Events send from the server to the proxy will be demarshalled by
|
||||
* the protocol and will then result in a call to the installed
|
||||
* implementation of the proxy.
|
||||
*
|
||||
* \section sec_page_proxy_destroy Destroy
|
||||
*
|
||||
* Use pw_proxy_destroy() to destroy the client side object. This
|
||||
* is usually done automatically when the server removes the resource
|
||||
* associated to the proxy.
|
||||
*/
|
||||
|
||||
/** \class pw_proxy
|
||||
*
|
||||
* \brief Represents an object on the client side.
|
||||
|
|
@ -37,6 +84,8 @@ extern "C" {
|
|||
* 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.
|
||||
*
|
||||
* See \ref page_proxy
|
||||
*/
|
||||
struct pw_proxy {
|
||||
/** the owner context of this proxy */
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ extern "C" {
|
|||
* \section sec_overview Overview
|
||||
*
|
||||
* Media streams are used to exchange data with the PipeWire server. A
|
||||
* stream is a wrapper around a \ref pw_client_node with one port.
|
||||
* stream is a wrapper around a proxy for a \ref pw_client_node with
|
||||
* just one port.
|
||||
*
|
||||
* Streams can be used to:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ struct pw_access_data {
|
|||
|
||||
|
||||
/**
|
||||
* struct pw_access:
|
||||
* \struct pw_access
|
||||
*
|
||||
* PipeWire Access support struct.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -33,6 +33,36 @@ extern "C" {
|
|||
#include <pipewire/server/core.h>
|
||||
#include <pipewire/server/resource.h>
|
||||
|
||||
/** \page page_client Client
|
||||
*
|
||||
* \section sec_page_client_overview Overview
|
||||
*
|
||||
* The \ref pw_client object is created by a protocol implementation when
|
||||
* a new client connects.
|
||||
*
|
||||
* The client is used to keep track of all resources belonging to one
|
||||
* connection with the PipeWire server.
|
||||
*
|
||||
* \section sec_page_client_credentials Credentials
|
||||
*
|
||||
* The client object will have its credentials filled in by the protocol.
|
||||
* This information is used to check if a resource or action is available
|
||||
* for this client. See also \ref page_access
|
||||
*
|
||||
* \section sec_page_client_types Types
|
||||
*
|
||||
* The client and server maintain a mapping between the client and server
|
||||
* types. All type ids that are in messages exchanged between the client
|
||||
* and server will automatically be remapped. See also \ref page_types.
|
||||
*
|
||||
* \section sec_page_client_resources Resources
|
||||
*
|
||||
* When a client binds to core global object, a resource is made for this
|
||||
* binding and a unique id is assigned to the resources. The client and
|
||||
* server will use this id as the destination when exchanging messages.
|
||||
* See also \ref page_resource
|
||||
*/
|
||||
|
||||
/** \class pw_client
|
||||
*
|
||||
* \brief PipeWire client object class.
|
||||
|
|
|
|||
|
|
@ -263,6 +263,24 @@ core_create_client_node(void *object,
|
|||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
core_create_link(void *object,
|
||||
uint32_t output_node_id,
|
||||
uint32_t output_port_id,
|
||||
uint32_t input_node_id,
|
||||
uint32_t input_port_id,
|
||||
const struct spa_format *filter,
|
||||
const struct spa_dict *props,
|
||||
uint32_t new_id)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct pw_client *client = resource->client;
|
||||
|
||||
pw_log_error("can't create link");
|
||||
pw_core_notify_error(client->core_resource,
|
||||
resource->id, SPA_RESULT_NOT_IMPLEMENTED, "not implemented");
|
||||
}
|
||||
|
||||
static void core_update_types(void *object, uint32_t first_id, uint32_t n_types, const char **types)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
|
|
@ -278,12 +296,13 @@ static void core_update_types(void *object, uint32_t first_id, uint32_t n_types,
|
|||
}
|
||||
|
||||
static struct pw_core_methods core_methods = {
|
||||
&core_client_update,
|
||||
&core_update_types,
|
||||
&core_sync,
|
||||
&core_get_registry,
|
||||
&core_client_update,
|
||||
&core_create_node,
|
||||
&core_create_client_node,
|
||||
&core_update_types
|
||||
&core_create_link
|
||||
};
|
||||
|
||||
static void core_unbind_func(void *data)
|
||||
|
|
|
|||
|
|
@ -40,18 +40,41 @@ struct pw_global;
|
|||
*
|
||||
* \section page_server_overview Overview
|
||||
*
|
||||
* \subpage page_core
|
||||
*
|
||||
* \subpage page_global
|
||||
*
|
||||
* \subpage page_client
|
||||
*
|
||||
* \subpage page_resource
|
||||
*
|
||||
*/
|
||||
|
||||
/** \page page_core Core
|
||||
*
|
||||
* \section page_core_overview Overview
|
||||
*
|
||||
* The core object is a singleton object that manages the state and
|
||||
* resources of the PipeWire server.
|
||||
*
|
||||
*/
|
||||
typedef int (*pw_bind_func_t) (struct pw_global *global,
|
||||
struct pw_client *client, uint32_t version, uint32_t id);
|
||||
|
||||
/** \page page_global Global
|
||||
*
|
||||
* Global objects represent resources that are available on the server and
|
||||
* accessible to clients.
|
||||
*
|
||||
*/
|
||||
/** \class pw_global
|
||||
*
|
||||
* \brief A global object visible to all clients
|
||||
*
|
||||
* A global object is visible to all clients and represents a resource
|
||||
* that can be used or inspected.
|
||||
*
|
||||
* See \ref page_server_api
|
||||
*/
|
||||
struct pw_global {
|
||||
struct pw_core *core; /**< the core */
|
||||
|
|
@ -89,7 +112,7 @@ struct pw_core {
|
|||
|
||||
struct pw_map objects; /**< map of known objects */
|
||||
|
||||
struct spa_list resource_list; /**< list of resources */
|
||||
struct spa_list resource_list; /**< list of core 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 */
|
||||
|
|
|
|||
|
|
@ -276,6 +276,47 @@ static bool core_demarshal_create_client_node(void *object, void *data, size_t s
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool core_demarshal_create_link(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_iter it;
|
||||
uint32_t new_id, i;
|
||||
uint32_t output_node_id, output_port_id, input_node_id, input_port_id;
|
||||
struct spa_format *filter = NULL;
|
||||
struct spa_dict props;
|
||||
|
||||
if (!spa_pod_iter_struct(&it, data, size) ||
|
||||
!pw_pod_remap_data(SPA_POD_TYPE_STRUCT, data, size, &resource->client->types) ||
|
||||
!spa_pod_iter_get(&it,
|
||||
SPA_POD_TYPE_INT, &output_node_id,
|
||||
SPA_POD_TYPE_INT, &output_port_id,
|
||||
SPA_POD_TYPE_INT, &input_node_id,
|
||||
SPA_POD_TYPE_INT, &input_port_id,
|
||||
-SPA_POD_TYPE_OBJECT, &filter,
|
||||
SPA_POD_TYPE_INT, &props.n_items, 0))
|
||||
return false;
|
||||
|
||||
props.items = alloca(props.n_items * sizeof(struct spa_dict_item));
|
||||
for (i = 0; i < props.n_items; i++) {
|
||||
if (!spa_pod_iter_get(&it,
|
||||
SPA_POD_TYPE_STRING, &props.items[i].key,
|
||||
SPA_POD_TYPE_STRING, &props.items[i].value, 0))
|
||||
return false;
|
||||
}
|
||||
if (!spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &new_id, 0))
|
||||
return false;
|
||||
|
||||
((struct pw_core_methods *) resource->implementation)->create_link(resource,
|
||||
output_node_id,
|
||||
output_port_id,
|
||||
input_node_id,
|
||||
input_port_id,
|
||||
filter,
|
||||
&props,
|
||||
new_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool core_demarshal_update_types(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
|
|
@ -847,21 +888,22 @@ static void link_marshal_info(void *object, struct pw_link_info *info)
|
|||
pw_connection_end_write(connection, resource->id, PW_LINK_EVENT_INFO, b.b.offset);
|
||||
}
|
||||
|
||||
static const demarshal_func_t pw_protocol_native_server_core_demarshal[] = {
|
||||
&core_demarshal_client_update,
|
||||
static const demarshal_func_t pw_protocol_native_server_core_demarshal[PW_CORE_METHOD_NUM] = {
|
||||
&core_demarshal_update_types,
|
||||
&core_demarshal_sync,
|
||||
&core_demarshal_get_registry,
|
||||
&core_demarshal_client_update,
|
||||
&core_demarshal_create_node,
|
||||
&core_demarshal_create_client_node,
|
||||
&core_demarshal_update_types
|
||||
&core_demarshal_create_link
|
||||
};
|
||||
|
||||
static const struct pw_core_events pw_protocol_native_server_core_events = {
|
||||
&core_marshal_info,
|
||||
&core_marshal_update_types,
|
||||
&core_marshal_done,
|
||||
&core_marshal_error,
|
||||
&core_marshal_remove_id,
|
||||
&core_marshal_update_types
|
||||
&core_marshal_info
|
||||
};
|
||||
|
||||
const struct pw_interface pw_protocol_native_server_core_interface = {
|
||||
|
|
|
|||
|
|
@ -32,20 +32,45 @@ extern "C" {
|
|||
#include <pipewire/client/sig.h>
|
||||
#include <pipewire/server/core.h>
|
||||
|
||||
/** \page page_resource Resource
|
||||
*
|
||||
* \section sec_page_resource Overview
|
||||
*
|
||||
* Resources represent objects owned by a \ref pw_client. They are
|
||||
* the result of binding to a global resource or by calling API that
|
||||
* creates client owned objects.
|
||||
*
|
||||
* The client usually has a proxy object associated with the resource
|
||||
* that it can use to communicate with the resource. See \ref page_proxy.
|
||||
*
|
||||
* Resources are destroyed when the client or the bound object is
|
||||
* destroyed.
|
||||
*
|
||||
*/
|
||||
/** \class pw_resource
|
||||
*
|
||||
* \brief Client owned objects
|
||||
*
|
||||
* Resources are objects owned by a client and are destroyed when the
|
||||
* client disappears.
|
||||
*
|
||||
* See also \ref page_resource
|
||||
*/
|
||||
struct pw_resource {
|
||||
struct pw_core *core;
|
||||
struct spa_list link;
|
||||
struct pw_core *core; /**< the core object */
|
||||
struct spa_list link; /**< link in object resource_list */
|
||||
|
||||
struct pw_client *client;
|
||||
struct pw_client *client; /**< owner client */
|
||||
|
||||
uint32_t id;
|
||||
uint32_t type;
|
||||
void *object;
|
||||
pw_destroy_t destroy;
|
||||
uint32_t id; /**< per client unique id, index in client objects */
|
||||
uint32_t type; /**< type id of the object */
|
||||
void *object; /**< pointer to the object */
|
||||
pw_destroy_t destroy; /**< function to clean up the object */
|
||||
|
||||
const struct pw_interface *iface;
|
||||
const void *implementation;
|
||||
const struct pw_interface *iface; /**< protocol specific interface functions */
|
||||
const void *implementation; /**< implementation */
|
||||
|
||||
/** Emited when the resource is destroyed */
|
||||
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_resource *resource));
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue