API cleanups

Fix docs
Add some more versions to interfaces
Make types for the various proxy object + inline methods that does type
checking and create proxys etc.
Set owner client of client-nodes in the properties
Pass type to bind to in create-node
Don't place global id in the info structs
Improve registration of marshal functions
Pass more types around as ids
This commit is contained in:
Wim Taymans 2017-07-13 15:21:52 +02:00
parent 465f12241e
commit 1acba78234
45 changed files with 963 additions and 764 deletions

View file

@ -780,7 +780,7 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = "@top_srcdir@/src/"
INPUT = "@top_srcdir@/src/pipewire"
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

View file

@ -43,8 +43,6 @@ enum spa_clock_state {
#include <spa/plugin.h>
#include <spa/props.h>
#define SPA_VERSION_CLOCK 0
/**
* spa_clock:
*
@ -53,6 +51,7 @@ enum spa_clock_state {
struct spa_clock {
/* the version of this clock. This can be used to expand this
* structure in the future */
#define SPA_VERSION_CLOCK 0
uint32_t version;
const struct spa_dict *info;

View file

@ -70,6 +70,7 @@ enum spa_result {
SPA_RESULT_SKIPPED = -34,
SPA_RESULT_OUT_OF_BUFFERS = -35,
SPA_RESULT_INCOMPATIBLE_PROPS = -36,
SPA_RESULT_INCOMPATIBLE_VERSION = -37,
};
#define SPA_ASYNC_BIT (1 << 30)

View file

@ -42,8 +42,6 @@ enum spa_log_level {
SPA_LOG_LEVEL_TRACE,
};
#define SPA_VERSION_LOG 0
/**
* struct spa_log:
*
@ -52,6 +50,7 @@ enum spa_log_level {
struct spa_log {
/* the version of this log. This can be used to expand this
* structure in the future */
#define SPA_VERSION_LOG 0
uint32_t version;
/**
* struct spa_log::info

View file

@ -66,8 +66,6 @@ typedef int (*spa_invoke_func_t) (struct spa_loop *loop,
void *data,
void *user_data);
#define SPA_VERSION_LOOP 0
/**
* spa_loop:
*
@ -76,6 +74,7 @@ typedef int (*spa_invoke_func_t) (struct spa_loop *loop,
struct spa_loop {
/* the version of this structure. This can be used to expand this
* structure in the future */
#define SPA_VERSION_LOOP 0
uint32_t version;
int (*add_source) (struct spa_loop *loop,
@ -160,8 +159,6 @@ typedef void (*spa_source_signal_func_t) (struct spa_loop_utils *utils,
struct spa_source *source,
int signal_number, void *data);
#define SPA_VERSION_LOOP_UTILS 0
/**
* struct spa_loop_utils:
*
@ -170,6 +167,7 @@ typedef void (*spa_source_signal_func_t) (struct spa_loop_utils *utils,
struct spa_loop_utils {
/* the version of this structure. This can be used to expand this
* structure in the future */
#define SPA_VERSION_LOOP_UTILS 0
uint32_t version;
struct spa_source *(*add_io) (struct spa_loop_utils *utils,

View file

@ -104,19 +104,17 @@ enum spa_monitor_item_state {
SPA_MONITOR_ITEM_STATE_UNAVAILABLE,
};
#define SPA_VERSION_MONITOR_CALLBACKS 0
/**
* spa_monitor_callbacks:
*/
struct spa_monitor_callbacks {
uint32_t version; /**< version of the structure */
/** version of the structure */
#define SPA_VERSION_MONITOR_CALLBACKS 0
uint32_t version;
void (*event) (struct spa_monitor *monitor, struct spa_event *event, void *user_data);
};
#define SPA_VERSION_MONITOR 0
/**
* spa_monitor:
*
@ -125,6 +123,7 @@ struct spa_monitor_callbacks {
struct spa_monitor {
/* the version of this monitor. This can be used to expand this
* structure in the future */
#define SPA_VERSION_MONITOR 0
uint32_t version;
/**

View file

@ -78,9 +78,9 @@ struct spa_port_info {
const struct spa_dict *props; /**< extra port properties */
};
#define SPA_VERSION_NODE_CALLBACKS 0
struct spa_node_callbacks {
#define SPA_VERSION_NODE_CALLBACKS 0
uint32_t version; /**< version of this structure */
/** Emited when an async operation completed */
@ -134,8 +134,6 @@ struct spa_node_callbacks {
};
#define SPA_VERSION_NODE 0
/**
* struct spa_node:
*
@ -147,6 +145,7 @@ struct spa_node_callbacks {
struct spa_node {
/* the version of this node. This can be used to expand this
* structure in the future */
#define SPA_VERSION_NODE 0
uint32_t version;
/**
* spa_node::info

View file

@ -30,10 +30,9 @@ extern "C" {
#define SPA_TYPE__Handle SPA_TYPE_INTERFACE_BASE "Handle"
#define SPA_TYPE__HandleFactory SPA_TYPE_INTERFACE_BASE "HandleFactory"
#define SPA_VERSION_HANDLE 0
struct spa_handle {
/** Version of this struct */
#define SPA_VERSION_HANDLE 0
uint32_t version;
/* user_data that can be set by the application */
@ -103,10 +102,9 @@ static inline void *spa_support_find(const struct spa_support *support,
#define SPA_SUPPORT_INIT(type,data) (struct spa_support) { (type), (data) }
#define SPA_VERSION_HANDLE_FACTORY 0
struct spa_handle_factory {
/** The version of this structure */
#define SPA_VERSION_HANDLE_FACTORY 0
uint32_t version;
/**
* spa_handle_factory::name

View file

@ -30,8 +30,6 @@ extern "C" {
#define SPA_TYPE__TypeMap SPA_TYPE_INTERFACE_BASE "TypeMap"
#define SPA_VERSION_TYPE_MAP 0
/**
* spa_type_map:
*
@ -40,6 +38,7 @@ extern "C" {
struct spa_type_map {
/* the version of this structure. This can be used to expand this
* structure in the future */
#define SPA_VERSION_TYPE_MAP 0
uint32_t version;
/**
* spa_type_map::info

View file

@ -30,8 +30,13 @@ extern "C" {
#include <spa/param-alloc.h>
#include <spa/node.h>
#define PW_TYPE__ClientNode PW_TYPE_NODE_BASE "Client"
#define PW_TYPE_CLIENT_NODE_BASE PW_TYPE__ClientNode ":"
#include <pipewire/proxy.h>
struct pw_client_node_proxy { struct pw_proxy proxy; };
#define PW_TYPE_INTERFACE__ClientNode PW_TYPE_INTERFACE_BASE "ClientNode"
#define PW_VERSION_CLIENT_NODE 0
/** information about a buffer */
struct pw_client_node_buffer {
@ -41,17 +46,18 @@ struct pw_client_node_buffer {
struct spa_buffer *buffer; /**< buffer describing metadata and buffer memory */
};
#define PW_VERSION_CLIENT_NODE 0
#define PW_CLIENT_NODE_METHOD_DONE 0
#define PW_CLIENT_NODE_METHOD_UPDATE 1
#define PW_CLIENT_NODE_METHOD_PORT_UPDATE 2
#define PW_CLIENT_NODE_METHOD_EVENT 3
#define PW_CLIENT_NODE_METHOD_DESTROY 4
#define PW_CLIENT_NODE_METHOD_NUM 5
#define PW_CLIENT_NODE_METHOD_DONE 0
#define PW_CLIENT_NODE_METHOD_UPDATE 1
#define PW_CLIENT_NODE_METHOD_PORT_UPDATE 2
#define PW_CLIENT_NODE_METHOD_EVENT 3
#define PW_CLIENT_NODE_METHOD_DESTROY 4
#define PW_CLIENT_NODE_METHOD_NUM 5
/** \ref pw_client_node methods */
struct pw_client_node_methods {
#define PW_VERSION_CLIENT_NODE_METHODS 0
uint32_t version;
/** Complete an async operation */
void (*done) (void *object, int seq, int res);
@ -113,11 +119,60 @@ struct pw_client_node_methods {
void (*destroy) (void *object);
};
#define pw_client_node_do_done(p,...) pw_proxy_do(p,struct pw_client_node_methods,done,__VA_ARGS__)
#define pw_client_node_do_update(p,...) pw_proxy_do(p,struct pw_client_node_methods,update,__VA_ARGS__)
#define pw_client_node_do_port_update(p,...) pw_proxy_do(p,struct pw_client_node_methods,port_update,__VA_ARGS__)
#define pw_client_node_do_event(p,...) pw_proxy_do(p,struct pw_client_node_methods,event,__VA_ARGS__)
#define pw_client_node_do_destroy(p) pw_proxy_do_na(p,struct pw_client_node_methods,destroy)
static inline void
pw_client_node_proxy_done(struct pw_client_node_proxy *p, int seq, int res)
{
pw_proxy_do(&p->proxy, struct pw_client_node_methods, done, seq, res);
}
static inline void
pw_client_node_proxy_update(struct pw_client_node_proxy *p,
uint32_t change_mask,
uint32_t max_input_ports,
uint32_t max_output_ports,
const struct spa_props *props)
{
pw_proxy_do(&p->proxy, struct pw_client_node_methods, update, change_mask,
max_input_ports,
max_output_ports,
props);
}
static inline void
pw_client_node_proxy_port_update(struct pw_client_node_proxy *p,
enum spa_direction direction,
uint32_t port_id,
uint32_t change_mask,
uint32_t n_possible_formats,
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)
{
pw_proxy_do(&p->proxy, struct pw_client_node_methods, port_update, direction,
port_id,
change_mask,
n_possible_formats,
possible_formats,
format,
n_params,
params,
info);
}
static inline void
pw_client_node_proxy_event(struct pw_client_node_proxy *p, struct spa_event *event)
{
pw_proxy_do(&p->proxy, struct pw_client_node_methods, event, event);
}
static inline void
pw_client_node_proxy_destroy(struct pw_client_node_proxy *p)
{
pw_proxy_do_na(&p->proxy, struct pw_client_node_methods, destroy);
}
#define PW_CLIENT_NODE_EVENT_TRANSPORT 0
#define PW_CLIENT_NODE_EVENT_SET_PROPS 1
@ -134,6 +189,8 @@ struct pw_client_node_methods {
/** \ref pw_client_node events */
struct pw_client_node_events {
#define PW_VERSION_CLIENT_NODE_EVENTS 0
uint32_t version;
/**
* Notify of a new transport area
*
@ -280,17 +337,24 @@ struct pw_client_node_events {
};
#define pw_client_node_notify_transport(r,...) pw_resource_notify(r,struct pw_client_node_events,transport,__VA_ARGS__)
#define pw_client_node_notify_set_props(r,...) pw_resource_notify(r,struct pw_client_node_events,props,__VA_ARGS__)
#define pw_client_node_notify_event(r,...) pw_resource_notify(r,struct pw_client_node_events,event,__VA_ARGS__)
#define pw_client_node_notify_add_port(r,...) pw_resource_notify(r,struct pw_client_node_events,add_port,__VA_ARGS__)
#define pw_client_node_notify_remove_port(r,...) pw_resource_notify(r,struct pw_client_node_events,remove_port,__VA_ARGS__)
#define pw_client_node_notify_set_format(r,...) pw_resource_notify(r,struct pw_client_node_events,set_format,__VA_ARGS__)
#define pw_client_node_notify_set_param(r,...) pw_resource_notify(r,struct pw_client_node_events,set_param,__VA_ARGS__)
#define pw_client_node_notify_add_mem(r,...) pw_resource_notify(r,struct pw_client_node_events,add_mem,__VA_ARGS__)
#define pw_client_node_notify_use_buffers(r,...) pw_resource_notify(r,struct pw_client_node_events,use_buffers,__VA_ARGS__)
#define pw_client_node_notify_node_command(r,...) pw_resource_notify(r,struct pw_client_node_events,node_command,__VA_ARGS__)
#define pw_client_node_notify_port_command(r,...) pw_resource_notify(r,struct pw_client_node_events,port_command,__VA_ARGS__)
static inline void
pw_client_node_proxy_add_listener(struct pw_client_node_proxy *p,
void *object, const struct pw_client_node_events *events)
{
pw_proxy_add_listener(&p->proxy, object, events);
}
#define pw_client_node_resource_transport(r,...) pw_resource_notify(r,struct pw_client_node_events,transport,__VA_ARGS__)
#define pw_client_node_resource_set_props(r,...) pw_resource_notify(r,struct pw_client_node_events,props,__VA_ARGS__)
#define pw_client_node_resource_event(r,...) pw_resource_notify(r,struct pw_client_node_events,event,__VA_ARGS__)
#define pw_client_node_resource_add_port(r,...) pw_resource_notify(r,struct pw_client_node_events,add_port,__VA_ARGS__)
#define pw_client_node_resource_remove_port(r,...) pw_resource_notify(r,struct pw_client_node_events,remove_port,__VA_ARGS__)
#define pw_client_node_resource_set_format(r,...) pw_resource_notify(r,struct pw_client_node_events,set_format,__VA_ARGS__)
#define pw_client_node_resource_set_param(r,...) pw_resource_notify(r,struct pw_client_node_events,set_param,__VA_ARGS__)
#define pw_client_node_resource_add_mem(r,...) pw_resource_notify(r,struct pw_client_node_events,add_mem,__VA_ARGS__)
#define pw_client_node_resource_use_buffers(r,...) pw_resource_notify(r,struct pw_client_node_events,use_buffers,__VA_ARGS__)
#define pw_client_node_resource_node_command(r,...) pw_resource_notify(r,struct pw_client_node_events,node_command,__VA_ARGS__)
#define pw_client_node_resource_port_command(r,...) pw_resource_notify(r,struct pw_client_node_events,port_command,__VA_ARGS__)
#ifdef __cplusplus
} /* extern "C" */

View file

@ -193,7 +193,7 @@ enum
};
static GstDevice *
new_node (GstPipeWireDeviceProvider *self, const struct pw_node_info *info)
new_node (GstPipeWireDeviceProvider *self, const struct pw_node_info *info, uint32_t id)
{
GstCaps *caps = NULL;
GstStructure *props;
@ -234,7 +234,7 @@ new_node (GstPipeWireDeviceProvider *self, const struct pw_node_info *info)
if (klass == NULL)
klass = "unknown/unknown";
return gst_pipewire_device_new (info->id,
return gst_pipewire_device_new (id,
info->name,
caps,
klass,
@ -295,18 +295,24 @@ on_sync_reply (struct pw_listener *listener, struct pw_remote *remote, uint32_t
{
GstPipeWireDeviceProvider *self = SPA_CONTAINER_OF (listener, GstPipeWireDeviceProvider, on_sync_reply);
if (seq == 1)
pw_core_do_sync(self->registry->remote->core_proxy, 2);
pw_core_proxy_sync(self->remote->core_proxy, 2);
else if (seq == 2)
self->end = true;
}
struct node_data {
GstPipeWireDeviceProvider *self;
uint32_t id;
};
static void node_event_info(void *object, struct pw_node_info *info)
{
struct pw_proxy *proxy = object;
GstPipeWireDeviceProvider *self = proxy->object;
struct node_data *node_data = proxy->user_data;
GstPipeWireDeviceProvider *self = node_data->self;
GstDevice *dev;
dev = new_node (self, info);
dev = new_node (self, info, node_data->id);
if (dev) {
if(self->list_only)
*self->devices = g_list_prepend (*self->devices, gst_object_ref_sink (dev));
@ -316,26 +322,32 @@ static void node_event_info(void *object, struct pw_node_info *info)
}
static const struct pw_node_events node_events = {
PW_VERSION_NODE_EVENTS,
&node_event_info
};
static void registry_event_global(void *object, uint32_t id, uint32_t type, uint32_t version)
{
struct pw_proxy *registry = object;
GstPipeWireDeviceProvider *self = registry->object;
struct pw_remote *remote = registry->remote;
struct pw_registry_proxy *registry = object;
GstPipeWireDeviceProvider *self = registry->proxy.user_data;
struct pw_remote *remote = self->remote;
struct pw_core *core = remote->core;
struct pw_proxy *proxy = NULL;
struct pw_node_proxy *node;
struct node_data *data;
if (type != core->type.node)
return;
proxy = pw_proxy_new(remote, SPA_ID_INVALID, core->type.node, 0);
if (proxy == NULL)
node = pw_registry_proxy_bind(registry, id, core->type.node, PW_VERSION_NODE,
sizeof(struct node_data), NULL);
if (node == NULL)
goto no_mem;
pw_proxy_set_implementation(proxy, self, PW_VERSION_NODE, &node_events, NULL);
pw_registry_do_bind(registry, id, version, proxy->id);
data = node->proxy.user_data;
data->id = id;
data->self = self;
pw_node_proxy_add_listener(node, node, &node_events);
return;
no_mem:
@ -345,8 +357,8 @@ no_mem:
static void registry_event_global_remove(void *object, uint32_t id)
{
struct pw_proxy *registry = object;
GstPipeWireDeviceProvider *self = registry->object;
struct pw_registry_proxy *registry = object;
GstPipeWireDeviceProvider *self = registry->proxy.user_data;
GstDeviceProvider *provider = GST_DEVICE_PROVIDER (self);
GstPipeWireDevice *dev;
@ -358,6 +370,7 @@ static void registry_event_global_remove(void *object, uint32_t id)
}
static const struct pw_registry_events registry_events = {
PW_VERSION_REGISTRY_EVENTS,
registry_event_global,
registry_event_global_remove,
};
@ -369,7 +382,7 @@ gst_pipewire_device_provider_probe (GstDeviceProvider * provider)
struct pw_loop *l = NULL;
struct pw_core *c = NULL;
struct pw_remote *r = NULL;
struct pw_proxy *reg = NULL;
struct pw_registry_proxy *reg = NULL;
GST_DEBUG_OBJECT (self, "starting probe");
@ -410,10 +423,10 @@ gst_pipewire_device_provider_probe (GstDeviceProvider * provider)
self->list_only = TRUE;
self->devices = NULL;
reg = pw_proxy_new(r, SPA_ID_INVALID, c->type.registry, 0);
pw_proxy_set_implementation(reg, self, PW_VERSION_REGISTRY, &registry_events, NULL);
pw_core_do_get_registry(r->core_proxy, PW_VERSION_REGISTRY, reg->id);
pw_core_do_sync(r->core_proxy, 1);
reg = pw_core_proxy_get_registry(r->core_proxy, PW_VERSION_REGISTRY, 0, NULL);
reg->proxy.user_data = self;
pw_registry_proxy_add_listener(reg, reg, &registry_events);
pw_core_proxy_sync(r->core_proxy, 1);
for (;;) {
if (r->state <= 0)
@ -515,10 +528,10 @@ gst_pipewire_device_provider_start (GstDeviceProvider * provider)
GST_DEBUG_OBJECT (self, "connected");
get_core_info (self->remote, self);
self->registry = pw_proxy_new(self->remote, SPA_ID_INVALID, self->core->type.registry, 0);
pw_proxy_set_implementation(self->registry, self, PW_VERSION_REGISTRY, &registry_events, NULL);
pw_core_do_get_registry(self->remote->core_proxy, PW_VERSION_REGISTRY, self->registry->id);
pw_core_do_sync(self->remote->core_proxy, 1);
self->registry = pw_core_proxy_get_registry(self->remote->core_proxy, PW_VERSION_REGISTRY, 0, NULL);
self->registry->proxy.user_data = self;
pw_registry_proxy_add_listener(self->registry, self->registry, &registry_events);
pw_core_proxy_sync(self->remote->core_proxy, 1);
pw_thread_loop_unlock (self->main_loop);

View file

@ -86,7 +86,7 @@ struct _GstPipeWireDeviceProvider {
struct pw_core *core;
struct pw_remote *remote;
struct pw_proxy *registry;
struct pw_registry_proxy *registry;
gboolean end;
gboolean list_only;
GList **devices;

View file

@ -554,9 +554,6 @@ gst_pipewire_src_stream_start (GstPipeWireSrc *pwsrc)
}
parse_stream_properties (pwsrc, pwsrc->stream->properties);
pw_thread_loop_unlock (pwsrc->main_loop);
pw_thread_loop_lock (pwsrc->main_loop);
GST_DEBUG_OBJECT (pwsrc, "signal started");
pwsrc->started = TRUE;
pw_thread_loop_signal (pwsrc->main_loop, FALSE);

View file

@ -101,13 +101,13 @@ on_link_state_changed(struct pw_listener *listener,
link->error);
spa_list_for_each(resource, &link->resource_list, link) {
pw_core_notify_error(resource->client->core_resource,
resource->id, SPA_RESULT_ERROR, link->error);
pw_core_resource_error(resource->client->core_resource,
resource->id, SPA_RESULT_ERROR, link->error);
}
if (info->node->owner) {
pw_core_notify_error(info->node->owner->client->core_resource,
info->node->owner->id,
SPA_RESULT_ERROR, link->error);
pw_core_resource_error(info->node->owner->client->core_resource,
info->node->owner->id,
SPA_RESULT_ERROR, link->error);
}
break;
}
@ -194,8 +194,8 @@ static void try_link_port(struct pw_node *node, struct pw_port *port, struct nod
error:
pw_log_error("module %p: can't link node '%s'", impl, error);
if (info->node->owner && info->node->owner->client->core_resource) {
pw_core_notify_error(info->node->owner->client->core_resource,
info->node->owner->id, SPA_RESULT_ERROR, error);
pw_core_resource_error(info->node->owner->client->core_resource,
info->node->owner->id, SPA_RESULT_ERROR, error);
}
free(error);
return;

View file

@ -44,6 +44,14 @@ static struct pw_node *create_node(struct pw_node_factory *factory,
{
struct pw_client_node *node;
if (properties == NULL)
properties = pw_properties_new(NULL, NULL);
if (properties == NULL)
goto no_mem;
pw_properties_setf(properties,
"pipewire.owner.client", "%d", resource->client->global->id);
node = pw_client_node_new(resource, name, properties);
if (node == NULL)
goto no_mem;
@ -52,8 +60,10 @@ static struct pw_node *create_node(struct pw_node_factory *factory,
no_mem:
pw_log_error("can't create node");
pw_core_notify_error(resource->client->core_resource,
resource->client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory");
pw_core_resource_error(resource->client->core_resource,
resource->client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory");
if (properties)
pw_properties_free(properties);
return NULL;
}
@ -68,7 +78,7 @@ static struct impl *module_new(struct pw_core *core, struct pw_properties *prope
impl->this.core = core;
impl->this.name = "client-node";
impl->this.type = spa_type_map_get_id(core->type.map, PW_TYPE__ClientNode);
pw_signal_init(&impl->this.destroy_signal);
impl->this.create_node = create_node;
@ -76,7 +86,8 @@ static struct impl *module_new(struct pw_core *core, struct pw_properties *prope
spa_list_insert(core->node_factory_list.prev, &impl->this.link);
pw_core_add_global(core, NULL, core->type.node_factory, 0, impl, NULL, &impl->this.global);
pw_core_add_global(core, NULL, core->type.node_factory, 0,
NULL, impl, &impl->this.global);
return impl;
}

View file

@ -114,8 +114,6 @@ struct proxy {
struct impl {
struct pw_client_node this;
uint32_t type_client_node;
struct pw_core *core;
struct proxy proxy;
@ -194,10 +192,10 @@ static int spa_proxy_node_send_command(struct spa_node *node, struct spa_command
core = this->impl->core;
if (SPA_COMMAND_TYPE(command) == core->type.command_node.ClockUpdate) {
pw_client_node_notify_node_command(this->resource, this->seq++, command);
pw_client_node_resource_node_command(this->resource, this->seq++, command);
} else {
/* send start */
pw_client_node_notify_node_command(this->resource, this->seq, command);
pw_client_node_resource_node_command(this->resource, this->seq, command);
if (SPA_COMMAND_TYPE(command) == core->type.command_node.Start)
send_need_input(this);
@ -470,8 +468,8 @@ spa_proxy_node_port_set_format(struct spa_node *node,
if (this->resource == NULL)
return SPA_RESULT_OK;
pw_client_node_notify_set_format(this->resource,
this->seq, direction, port_id, flags, format);
pw_client_node_resource_set_format(this->resource,
this->seq, direction, port_id, flags, format);
return SPA_RESULT_RETURN_ASYNC(this->seq++);
}
@ -644,12 +642,12 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
mb[i].offset = 0;
mb[i].size = msh->size;
pw_client_node_notify_add_mem(this->resource,
direction,
port_id,
mb[i].mem_id,
impl->core->type.data.MemFd,
msh->fd, msh->flags, msh->offset, msh->size);
pw_client_node_resource_add_mem(this->resource,
direction,
port_id,
mb[i].mem_id,
impl->core->type.data.MemFd,
msh->fd, msh->flags, msh->offset, msh->size);
for (j = 0; j < buffers[i]->n_metas; j++) {
memcpy(&b->buffer.metas[j], &buffers[i]->metas[j], sizeof(struct spa_meta));
@ -662,13 +660,13 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
if (d->type == impl->core->type.data.DmaBuf ||
d->type == impl->core->type.data.MemFd) {
pw_client_node_notify_add_mem(this->resource,
direction,
port_id,
n_mem,
d->type,
d->fd,
d->flags, d->mapoffset, d->maxsize);
pw_client_node_resource_add_mem(this->resource,
direction,
port_id,
n_mem,
d->type,
d->fd,
d->flags, d->mapoffset, d->maxsize);
b->buffer.datas[j].type = impl->core->type.data.Id;
b->buffer.datas[j].data = SPA_UINT32_TO_PTR(n_mem);
n_mem++;
@ -683,8 +681,8 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
}
}
pw_client_node_notify_use_buffers(this->resource,
this->seq, direction, port_id, n_buffers, mb);
pw_client_node_resource_use_buffers(this->resource,
this->seq, direction, port_id, n_buffers, mb);
return SPA_RESULT_RETURN_ASYNC(this->seq++);
}
@ -948,6 +946,7 @@ static void client_node_destroy(void *object)
}
static struct pw_client_node_methods client_node_methods = {
PW_VERSION_CLIENT_NODE_METHODS,
&client_node_done,
&client_node_update,
&client_node_port_update,
@ -1053,8 +1052,8 @@ static void on_initialized(struct pw_listener *listener, struct pw_node *node)
pw_client_node_get_fds(this, &readfd, &writefd);
pw_transport_get_info(impl->transport, &info);
pw_client_node_notify_transport(this->resource, node->global->id,
readfd, writefd, info.memfd, info.offset, info.size);
pw_client_node_resource_transport(this->resource, node->global->id,
readfd, writefd, info.memfd, info.offset, info.size);
}
static void
@ -1150,8 +1149,6 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
impl->fds[0] = impl->fds[1] = -1;
pw_log_debug("client-node %p: new", impl);
impl->type_client_node = spa_type_map_get_id(core->type.map, PW_TYPE__ClientNode);
pw_signal_init(&this->destroy_signal);
proxy_init(&impl->proxy, NULL, core->support, core->n_support);
@ -1168,11 +1165,9 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
if (this->node == NULL)
goto error_no_node;
this->resource->destroy = (pw_destroy_t) client_node_resource_destroy;
pw_resource_set_implementation(this->resource,
this,
PW_VERSION_CLIENT_NODE,
&client_node_methods,
(pw_destroy_t) client_node_resource_destroy);
this, &client_node_methods);
impl->proxy.resource = this->resource;

View file

@ -158,7 +158,7 @@ static bool client_node_demarshal_set_props(void *object, void *data, size_t siz
-SPA_POD_TYPE_OBJECT, &props, 0))
return false;
((struct pw_client_node_events *) proxy->implementation)->set_props(proxy, seq, props);
pw_proxy_notify(proxy, struct pw_client_node_events, set_props, seq, props);
return true;
}
@ -173,7 +173,7 @@ static bool client_node_demarshal_event_event(void *object, void *data, size_t s
!spa_pod_iter_get(&it, SPA_POD_TYPE_OBJECT, &event, 0))
return false;
((struct pw_client_node_events *) proxy->implementation)->event(proxy, event);
pw_proxy_notify(proxy, struct pw_client_node_events, event, event);
return true;
}
@ -189,8 +189,7 @@ static bool client_node_demarshal_add_port(void *object, void *data, size_t size
SPA_POD_TYPE_INT, &direction, SPA_POD_TYPE_INT, &port_id, 0))
return false;
((struct pw_client_node_events *) proxy->implementation)->add_port(proxy, seq, direction,
port_id);
pw_proxy_notify(proxy, struct pw_client_node_events, add_port, seq, direction, port_id);
return true;
}
@ -206,8 +205,7 @@ static bool client_node_demarshal_remove_port(void *object, void *data, size_t s
SPA_POD_TYPE_INT, &direction, SPA_POD_TYPE_INT, &port_id, 0))
return false;
((struct pw_client_node_events *) proxy->implementation)->remove_port(proxy, seq, direction,
port_id);
pw_proxy_notify(proxy, struct pw_client_node_events, remove_port, seq, direction, port_id);
return true;
}
@ -228,9 +226,8 @@ static bool client_node_demarshal_set_format(void *object, void *data, size_t si
-SPA_POD_TYPE_OBJECT, &format, 0))
return false;
((struct pw_client_node_events *) proxy->implementation)->set_format(proxy, seq, direction,
port_id, flags,
format);
pw_proxy_notify(proxy, struct pw_client_node_events, set_format, seq, direction, port_id,
flags, format);
return true;
}
@ -250,8 +247,7 @@ static bool client_node_demarshal_set_param(void *object, void *data, size_t siz
-SPA_POD_TYPE_OBJECT, &param, 0))
return false;
((struct pw_client_node_events *) proxy->implementation)->set_param(proxy, seq, direction,
port_id, param);
pw_proxy_notify(proxy, struct pw_client_node_events, set_param, seq, direction, port_id, param);
return true;
}
@ -276,12 +272,11 @@ static bool client_node_demarshal_add_mem(void *object, void *data, size_t size)
memfd = pw_protocol_native_get_proxy_fd(proxy, memfd_idx);
((struct pw_client_node_events *) proxy->implementation)->add_mem(proxy,
direction,
port_id,
mem_id,
type,
memfd, flags, offset, sz);
pw_proxy_notify(proxy, struct pw_client_node_events, add_mem, direction,
port_id,
mem_id,
type,
memfd, flags, offset, sz);
return true;
}
@ -340,11 +335,10 @@ static bool client_node_demarshal_use_buffers(void *object, void *data, size_t s
d->data = SPA_UINT32_TO_PTR(data_id);
}
}
((struct pw_client_node_events *) proxy->implementation)->use_buffers(proxy,
seq,
direction,
port_id,
n_buffers, buffers);
pw_proxy_notify(proxy, struct pw_client_node_events, use_buffers, seq,
direction,
port_id,
n_buffers, buffers);
return true;
}
@ -360,7 +354,7 @@ static bool client_node_demarshal_node_command(void *object, void *data, size_t
!spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &seq, SPA_POD_TYPE_OBJECT, &command, 0))
return false;
((struct pw_client_node_events *) proxy->implementation)->node_command(proxy, seq, command);
pw_proxy_notify(proxy, struct pw_client_node_events, node_command, seq, command);
return true;
}
@ -379,10 +373,9 @@ static bool client_node_demarshal_port_command(void *object, void *data, size_t
SPA_POD_TYPE_OBJECT, &command, 0))
return false;
((struct pw_client_node_events *) proxy->implementation)->port_command(proxy,
direction,
port_id,
command);
pw_proxy_notify(proxy, struct pw_client_node_events, port_command, direction,
port_id,
command);
return true;
}
@ -409,9 +402,9 @@ static bool client_node_demarshal_transport(void *object, void *data, size_t siz
if (readfd == -1 || writefd == -1 || memfd_idx == -1)
return false;
((struct pw_client_node_events *) proxy->implementation)->transport(proxy, node_id,
readfd, writefd,
memfd, offset, sz);
pw_proxy_notify(proxy, struct pw_client_node_events, transport, node_id,
readfd, writefd,
memfd, offset, sz);
return true;
}
@ -666,7 +659,7 @@ static bool client_node_demarshal_done(void *object, void *data, size_t size)
SPA_POD_TYPE_INT, &res, 0))
return false;
((struct pw_client_node_methods *) resource->implementation)->done(resource, seq, res);
pw_resource_do(resource, struct pw_client_node_methods, done, seq, res);
return true;
}
@ -685,10 +678,10 @@ static bool client_node_demarshal_update(void *object, void *data, size_t size)
SPA_POD_TYPE_INT, &max_output_ports, -SPA_POD_TYPE_OBJECT, &props, 0))
return false;
((struct pw_client_node_methods *) resource->implementation)->update(resource, change_mask,
max_input_ports,
max_output_ports,
props);
pw_resource_do(resource, struct pw_client_node_methods, update, change_mask,
max_input_ports,
max_output_ports,
props);
return true;
}
@ -738,15 +731,14 @@ static bool client_node_demarshal_port_update(void *object, void *data, size_t s
return false;
}
((struct pw_client_node_methods *) resource->implementation)->port_update(resource,
direction,
port_id,
change_mask,
n_possible_formats,
possible_formats,
format,
n_params,
params, infop);
pw_resource_do(resource, struct pw_client_node_methods, port_update, direction,
port_id,
change_mask,
n_possible_formats,
possible_formats,
format,
n_params,
params, infop);
return true;
}
@ -761,7 +753,7 @@ static bool client_node_demarshal_event_method(void *object, void *data, size_t
!spa_pod_iter_get(&it, SPA_POD_TYPE_OBJECT, &event, 0))
return false;
((struct pw_client_node_methods *) resource->implementation)->event(resource, event);
pw_resource_do(resource, struct pw_client_node_methods, event, event);
return true;
}
@ -773,11 +765,12 @@ static bool client_node_demarshal_destroy(void *object, void *data, size_t size)
if (!spa_pod_iter_struct(&it, data, size))
return false;
((struct pw_client_node_methods *) resource->implementation)->destroy(resource);
pw_resource_do_na(resource, struct pw_client_node_methods, destroy);
return true;
}
static const struct pw_client_node_methods pw_protocol_native_client_client_node_methods = {
static const struct pw_client_node_methods pw_protocol_native_client_node_method_marshal = {
PW_VERSION_CLIENT_NODE_METHODS,
&client_node_marshal_done,
&client_node_marshal_update,
&client_node_marshal_port_update,
@ -785,28 +778,7 @@ static const struct pw_client_node_methods pw_protocol_native_client_client_node
&client_node_marshal_destroy
};
static const demarshal_func_t pw_protocol_native_client_client_node_demarshal[] = {
&client_node_demarshal_transport,
&client_node_demarshal_set_props,
&client_node_demarshal_event_event,
&client_node_demarshal_add_port,
&client_node_demarshal_remove_port,
&client_node_demarshal_set_format,
&client_node_demarshal_set_param,
&client_node_demarshal_add_mem,
&client_node_demarshal_use_buffers,
&client_node_demarshal_node_command,
&client_node_demarshal_port_command,
};
static const struct pw_interface pw_protocol_native_client_client_node_interface = {
PW_TYPE__ClientNode,
PW_VERSION_CLIENT_NODE,
PW_CLIENT_NODE_METHOD_NUM, &pw_protocol_native_client_client_node_methods,
PW_CLIENT_NODE_EVENT_NUM, pw_protocol_native_client_client_node_demarshal,
};
static const demarshal_func_t pw_protocol_native_server_client_node_demarshal[] = {
static const demarshal_func_t pw_protocol_native_client_node_method_demarshal[] = {
&client_node_demarshal_done,
&client_node_demarshal_update,
&client_node_demarshal_port_update,
@ -814,7 +786,8 @@ static const demarshal_func_t pw_protocol_native_server_client_node_demarshal[]
&client_node_demarshal_destroy,
};
static const struct pw_client_node_events pw_protocol_native_server_client_node_events = {
static const struct pw_client_node_events pw_protocol_native_client_node_event_marshal = {
PW_VERSION_CLIENT_NODE_EVENTS,
&client_node_marshal_transport,
&client_node_marshal_set_props,
&client_node_marshal_event_event,
@ -828,11 +801,29 @@ static const struct pw_client_node_events pw_protocol_native_server_client_node_
&client_node_marshal_port_command,
};
const struct pw_interface pw_protocol_native_server_client_node_interface = {
PW_TYPE__ClientNode,
static const demarshal_func_t pw_protocol_native_client_node_event_demarshal[] = {
&client_node_demarshal_transport,
&client_node_demarshal_set_props,
&client_node_demarshal_event_event,
&client_node_demarshal_add_port,
&client_node_demarshal_remove_port,
&client_node_demarshal_set_format,
&client_node_demarshal_set_param,
&client_node_demarshal_add_mem,
&client_node_demarshal_use_buffers,
&client_node_demarshal_node_command,
&client_node_demarshal_port_command,
};
const struct pw_protocol_marshal pw_protocol_native_client_node_marshal = {
PW_TYPE_INTERFACE__ClientNode,
PW_VERSION_CLIENT_NODE,
PW_CLIENT_NODE_METHOD_NUM, &pw_protocol_native_server_client_node_demarshal,
PW_CLIENT_NODE_EVENT_NUM, &pw_protocol_native_server_client_node_events,
PW_CLIENT_NODE_METHOD_NUM,
&pw_protocol_native_client_node_method_marshal,
&pw_protocol_native_client_node_method_demarshal,
PW_CLIENT_NODE_EVENT_NUM,
&pw_protocol_native_client_node_event_marshal,
pw_protocol_native_client_node_event_demarshal,
};
struct pw_protocol *pw_protocol_native_ext_client_node_init(struct pw_core *core)
@ -844,9 +835,7 @@ struct pw_protocol *pw_protocol_native_ext_client_node_init(struct pw_core *core
if (protocol == NULL)
return NULL;
pw_protocol_add_interfaces(protocol,
&pw_protocol_native_client_client_node_interface,
&pw_protocol_native_server_client_node_interface);
pw_protocol_add_marshal(protocol, &pw_protocol_native_client_node_marshal);
return protocol;
}

View file

@ -69,8 +69,9 @@ struct async_pending {
struct pw_resource *resource;
char *factory_name;
char *name;
struct pw_properties *properties;
uint32_t type;
uint32_t version;
struct pw_properties *properties;
uint32_t new_id;
};
@ -230,8 +231,9 @@ do_global_filter(struct pw_global *global, struct pw_client *client, void *data)
if (link->input
&& !check_global_owner(client->core, client, link->input->node->global))
return false;
} else if (!check_global_owner(client->core, client, global))
return false;
}
else if (!check_global_owner(client->core, client, global))
return false;
return true;
}
@ -268,12 +270,13 @@ portal_response(DBusConnection *connection, DBusMessage *msg, void *user_data)
cinfo->old_methods->create_node (p->resource,
p->factory_name,
p->name,
&p->properties->dict,
p->type,
p->version,
&p->properties->dict,
p->new_id);
} else {
pw_core_notify_error(cinfo->client->core_resource,
p->resource->id, SPA_RESULT_NO_PERMISSION, "not allowed");
pw_core_resource_error(cinfo->client->core_resource,
p->resource->id, SPA_RESULT_NO_PERMISSION, "not allowed");
}
free_pending(p);
@ -288,8 +291,9 @@ portal_response(DBusConnection *connection, DBusMessage *msg, void *user_data)
static void do_create_node(void *object,
const char *factory_name,
const char *name,
const struct spa_dict *props,
uint32_t type,
uint32_t version,
const struct spa_dict *props,
uint32_t new_id)
{
struct pw_resource *resource = object;
@ -306,7 +310,7 @@ static void do_create_node(void *object,
struct async_pending *p;
if (!cinfo->is_sandboxed) {
cinfo->old_methods->create_node (object, factory_name, name, props, version, new_id);
cinfo->old_methods->create_node (object, factory_name, name, type, version, props, new_id);
return;
}
if (strcmp(factory_name, "client-node") != 0) {
@ -362,8 +366,9 @@ static void do_create_node(void *object,
p->resource = resource;
p->factory_name = strdup(factory_name);
p->name = strdup(name);
p->properties = props ? pw_properties_new_dict(props) : NULL;
p->type = type;
p->version = version;
p->properties = props ? pw_properties_new_dict(props) : NULL;
p->new_id = new_id;
pw_client_set_busy(client, true);
@ -393,8 +398,8 @@ static void do_create_node(void *object,
dbus_error_free(&error);
goto not_allowed;
not_allowed:
pw_core_notify_error(client->core_resource,
resource->id, SPA_RESULT_NO_PERMISSION, "not allowed");
pw_core_resource_error(client->core_resource,
resource->id, SPA_RESULT_NO_PERMISSION, "not allowed");
return;
}
@ -413,8 +418,8 @@ do_create_link(void *object,
struct pw_client *client = resource->client;
if (cinfo->is_sandboxed) {
pw_core_notify_error(client->core_resource,
resource->id, SPA_RESULT_NO_PERMISSION, "not allowed");
pw_core_resource_error(client->core_resource,
resource->id, SPA_RESULT_NO_PERMISSION, "not allowed");
return;
}
cinfo->old_methods->create_link (object,
@ -432,9 +437,8 @@ static void on_resource_impl(struct pw_listener *listener,
struct pw_resource *resource)
{
struct client_info *cinfo = SPA_CONTAINER_OF(listener, struct client_info, resource_impl);
struct impl *impl = cinfo->impl;
if (resource->type == impl->core->type.core) {
if (resource->type == client->core->type.core) {
cinfo->old_methods = resource->implementation;
cinfo->core_methods = *cinfo->old_methods;
resource->implementation = &cinfo->core_methods;

View file

@ -116,13 +116,13 @@ process_messages(struct pw_client *client)
client->protocol, id);
continue;
}
if (opcode >= resource->iface->n_methods) {
if (opcode >= resource->marshal->n_methods) {
pw_log_error("protocol-native %p: invalid method %u %u", client->protocol,
id, opcode);
pw_client_destroy(client);
break;
}
demarshal = resource->iface->methods;
demarshal = resource->marshal->method_demarshal;
if (!demarshal[opcode] || !demarshal[opcode] (resource, message, size)) {
pw_log_error("protocol-native %p: invalid message received %u %u",
client->protocol, id, opcode);
@ -449,13 +449,13 @@ on_remote_data(struct spa_loop_utils *utils,
pw_log_error("protocol-native %p: could not find proxy %u", this, id);
continue;
}
if (opcode >= proxy->iface->n_events) {
if (opcode >= proxy->marshal->n_events) {
pw_log_error("protocol-native %p: invalid method %u for %u", this, opcode,
id);
continue;
}
demarshal = proxy->iface->events;
demarshal = proxy->marshal->event_demarshal;
if (demarshal[opcode]) {
if (!demarshal[opcode] (proxy, message, size))
pw_log_error

View file

@ -375,7 +375,7 @@ pw_protocol_native_connection_begin_resource(struct pw_protocol_native_connectio
types[i] = spa_type_map_get_type(core->type.map, b);
client->n_types += diff;
pw_core_notify_update_types(client->core_resource, base, diff, types);
pw_core_resource_update_types(client->core_resource, base, diff, types);
}
impl->dest_id = resource->id;
@ -404,7 +404,7 @@ pw_protocol_native_connection_begin_proxy(struct pw_protocol_native_connection *
types[i] = spa_type_map_get_type(core->type.map, b);
remote->n_types += diff;
pw_core_do_update_types(remote->core_proxy, base, diff, types);
pw_core_proxy_update_types(remote->core_proxy, base, diff, types);
}
impl->dest_id = proxy->id;

View file

@ -89,9 +89,9 @@ static void core_marshal_get_registry(void *object, uint32_t version, uint32_t n
static void
core_marshal_create_node(void *object,
const char *factory_name,
const char *name, const struct spa_dict *props,
uint32_t version, uint32_t new_id)
const char *factory_name, const char *name,
uint32_t type, uint32_t version,
const struct spa_dict *props, uint32_t new_id)
{
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
@ -105,7 +105,10 @@ core_marshal_create_node(void *object,
spa_pod_builder_add(b,
SPA_POD_TYPE_STRUCT, &f,
SPA_POD_TYPE_STRING, factory_name,
SPA_POD_TYPE_STRING, name, SPA_POD_TYPE_INT, n_items, 0);
SPA_POD_TYPE_STRING, name,
SPA_POD_TYPE_ID, type,
SPA_POD_TYPE_INT, version,
SPA_POD_TYPE_INT, n_items, 0);
for (i = 0; i < n_items; i++) {
spa_pod_builder_add(b,
@ -113,7 +116,6 @@ core_marshal_create_node(void *object,
SPA_POD_TYPE_STRING, props->items[i].value, 0);
}
spa_pod_builder_add(b,
SPA_POD_TYPE_INT, version,
SPA_POD_TYPE_INT, new_id,
-SPA_POD_TYPE_STRUCT, &f, 0);
@ -192,7 +194,6 @@ static bool core_demarshal_info(void *object, void *data, size_t size)
if (!spa_pod_iter_struct(&it, data, size) ||
!spa_pod_iter_get(&it,
SPA_POD_TYPE_INT, &info.id,
SPA_POD_TYPE_LONG, &info.change_mask,
SPA_POD_TYPE_STRING, &info.user_name,
SPA_POD_TYPE_STRING, &info.host_name,
@ -292,7 +293,6 @@ static void core_marshal_info(void *object, struct pw_core_info *info)
spa_pod_builder_add(b,
SPA_POD_TYPE_STRUCT, &f,
SPA_POD_TYPE_INT, info->id,
SPA_POD_TYPE_LONG, info->change_mask,
SPA_POD_TYPE_STRING, info->user_name,
SPA_POD_TYPE_STRING, info->host_name,
@ -437,14 +437,18 @@ static bool core_demarshal_create_node(void *object, void *data, size_t size)
{
struct pw_resource *resource = object;
struct spa_pod_iter it;
uint32_t version, new_id, i;
uint32_t version, type, new_id, i;
const char *factory_name, *name;
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_STRING, &factory_name,
SPA_POD_TYPE_STRING, &name, SPA_POD_TYPE_INT, &props.n_items, 0))
SPA_POD_TYPE_STRING, &name,
SPA_POD_TYPE_ID, &type,
SPA_POD_TYPE_INT, &version,
SPA_POD_TYPE_INT, &props.n_items, 0))
return false;
props.items = alloca(props.n_items * sizeof(struct spa_dict_item));
@ -455,12 +459,12 @@ static bool core_demarshal_create_node(void *object, void *data, size_t size)
return false;
}
if (!spa_pod_iter_get(&it,
SPA_POD_TYPE_INT, &version,
SPA_POD_TYPE_INT, &new_id, 0))
return false;
pw_resource_do(resource, struct pw_core_methods, create_node, factory_name,
name, &props, version, new_id);
pw_resource_do(resource, struct pw_core_methods, create_node, factory_name, name,
type, version,
&props, new_id);
return true;
}
@ -558,16 +562,18 @@ 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, version, new_id;
uint32_t id, version, type, new_id;
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, &id,
SPA_POD_TYPE_ID, &type,
SPA_POD_TYPE_INT, &version,
SPA_POD_TYPE_INT, &new_id, 0))
return false;
pw_resource_do(resource, struct pw_registry_methods, bind, id, version, new_id);
pw_resource_do(resource, struct pw_registry_methods, bind, id, type, version, new_id);
return true;
}
@ -584,7 +590,6 @@ static void module_marshal_info(void *object, struct pw_module_info *info)
spa_pod_builder_add(b,
SPA_POD_TYPE_STRUCT, &f,
SPA_POD_TYPE_INT, info->id,
SPA_POD_TYPE_LONG, info->change_mask,
SPA_POD_TYPE_STRING, info->name,
SPA_POD_TYPE_STRING, info->filename,
@ -610,7 +615,6 @@ static bool module_demarshal_info(void *object, void *data, size_t size)
if (!spa_pod_iter_struct(&it, data, size) ||
!spa_pod_iter_get(&it,
SPA_POD_TYPE_INT, &info.id,
SPA_POD_TYPE_LONG, &info.change_mask,
SPA_POD_TYPE_STRING, &info.name,
SPA_POD_TYPE_STRING, &info.filename,
@ -640,7 +644,6 @@ static void node_marshal_info(void *object, struct pw_node_info *info)
spa_pod_builder_add(b,
SPA_POD_TYPE_STRUCT, &f,
SPA_POD_TYPE_INT, info->id,
SPA_POD_TYPE_LONG, info->change_mask,
SPA_POD_TYPE_STRING, info->name,
SPA_POD_TYPE_INT, info->max_input_ports,
@ -685,7 +688,6 @@ static bool node_demarshal_info(void *object, void *data, size_t size)
if (!spa_pod_iter_struct(&it, data, size) ||
!pw_pod_remap_data(SPA_POD_TYPE_STRUCT, data, size, &proxy->remote->types) ||
!spa_pod_iter_get(&it,
SPA_POD_TYPE_INT, &info.id,
SPA_POD_TYPE_LONG, &info.change_mask,
SPA_POD_TYPE_STRING, &info.name,
SPA_POD_TYPE_INT, &info.max_input_ports,
@ -740,7 +742,6 @@ static void client_marshal_info(void *object, struct pw_client_info *info)
spa_pod_builder_add(b,
SPA_POD_TYPE_STRUCT, &f,
SPA_POD_TYPE_INT, info->id,
SPA_POD_TYPE_LONG, info->change_mask, SPA_POD_TYPE_INT, n_items, 0);
for (i = 0; i < n_items; i++) {
@ -763,7 +764,6 @@ static bool client_demarshal_info(void *object, void *data, size_t size)
if (!spa_pod_iter_struct(&it, data, size) ||
!spa_pod_iter_get(&it,
SPA_POD_TYPE_INT, &info.id,
SPA_POD_TYPE_LONG, &info.change_mask,
SPA_POD_TYPE_INT, &props.n_items, 0))
return false;
@ -789,7 +789,6 @@ static void link_marshal_info(void *object, struct pw_link_info *info)
b = pw_protocol_native_begin_resource(resource, PW_LINK_EVENT_INFO);
spa_pod_builder_struct(b, &f,
SPA_POD_TYPE_INT, info->id,
SPA_POD_TYPE_LONG, info->change_mask,
SPA_POD_TYPE_INT, info->output_node_id,
SPA_POD_TYPE_INT, info->output_port_id,
@ -809,7 +808,6 @@ static bool link_demarshal_info(void *object, void *data, size_t size)
if (!spa_pod_iter_struct(&it, data, size) ||
!pw_pod_remap_data(SPA_POD_TYPE_STRUCT, data, size, &proxy->remote->types) ||
!spa_pod_iter_get(&it,
SPA_POD_TYPE_INT, &info.id,
SPA_POD_TYPE_LONG, &info.change_mask,
SPA_POD_TYPE_INT, &info.output_node_id,
SPA_POD_TYPE_INT, &info.output_port_id,
@ -854,7 +852,8 @@ 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 version, uint32_t new_id)
static void registry_marshal_bind(void *object, uint32_t id,
uint32_t type, uint32_t version, uint32_t new_id)
{
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
@ -864,13 +863,15 @@ static void registry_marshal_bind(void *object, uint32_t id, uint32_t version, u
spa_pod_builder_struct(b, &f,
SPA_POD_TYPE_INT, id,
SPA_POD_TYPE_ID, type,
SPA_POD_TYPE_INT, version,
SPA_POD_TYPE_INT, new_id);
pw_protocol_native_end_proxy(proxy, b);
}
static const struct pw_core_methods pw_protocol_native_client_core_methods = {
static const struct pw_core_methods pw_protocol_native_core_method_marshal = {
PW_VERSION_CORE_METHODS,
&core_marshal_update_types_client,
&core_marshal_sync,
&core_marshal_get_registry,
@ -879,82 +880,7 @@ static const struct pw_core_methods pw_protocol_native_client_core_methods = {
&core_marshal_create_link
};
static const demarshal_func_t pw_protocol_native_client_core_demarshal[PW_CORE_EVENT_NUM] = {
&core_demarshal_update_types_client,
&core_demarshal_done,
&core_demarshal_error,
&core_demarshal_remove_id,
&core_demarshal_info
};
static const struct pw_interface pw_protocol_native_client_core_interface = {
PW_TYPE__Core,
PW_VERSION_CORE,
PW_CORE_METHOD_NUM, &pw_protocol_native_client_core_methods,
PW_CORE_EVENT_NUM, pw_protocol_native_client_core_demarshal
};
static const struct pw_registry_methods pw_protocol_native_client_registry_methods = {
&registry_marshal_bind
};
static const demarshal_func_t pw_protocol_native_client_registry_demarshal[] = {
&registry_demarshal_global,
&registry_demarshal_global_remove,
};
static const struct pw_interface pw_protocol_native_client_registry_interface = {
PW_TYPE__Registry,
PW_VERSION_REGISTRY,
PW_REGISTRY_METHOD_NUM, &pw_protocol_native_client_registry_methods,
PW_REGISTRY_EVENT_NUM, pw_protocol_native_client_registry_demarshal,
};
static const demarshal_func_t pw_protocol_native_client_module_demarshal[] = {
&module_demarshal_info,
};
static const struct pw_interface pw_protocol_native_client_module_interface = {
PW_TYPE__Module,
PW_VERSION_MODULE,
0, NULL,
PW_MODULE_EVENT_NUM, pw_protocol_native_client_module_demarshal,
};
static const demarshal_func_t pw_protocol_native_client_node_demarshal[] = {
&node_demarshal_info,
};
static const struct pw_interface pw_protocol_native_client_node_interface = {
PW_TYPE__Node,
PW_VERSION_NODE,
0, NULL,
PW_NODE_EVENT_NUM, pw_protocol_native_client_node_demarshal,
};
static const demarshal_func_t pw_protocol_native_client_client_demarshal[] = {
&client_demarshal_info,
};
static const struct pw_interface pw_protocol_native_client_client_interface = {
PW_TYPE__Client,
PW_VERSION_CLIENT,
0, NULL,
PW_CLIENT_EVENT_NUM, pw_protocol_native_client_client_demarshal,
};
static const demarshal_func_t pw_protocol_native_client_link_demarshal[] = {
&link_demarshal_info,
};
static const struct pw_interface pw_protocol_native_client_link_interface = {
PW_TYPE__Link,
PW_VERSION_LINK,
0, NULL,
PW_LINK_EVENT_NUM, pw_protocol_native_client_link_demarshal,
};
static const demarshal_func_t pw_protocol_native_server_core_demarshal[PW_CORE_METHOD_NUM] = {
static const demarshal_func_t pw_protocol_native_core_method_demarshal[PW_CORE_METHOD_NUM] = {
&core_demarshal_update_types_server,
&core_demarshal_sync,
&core_demarshal_get_registry,
@ -963,7 +889,8 @@ static const demarshal_func_t pw_protocol_native_server_core_demarshal[PW_CORE_M
&core_demarshal_create_link
};
static const struct pw_core_events pw_protocol_native_server_core_events = {
static const struct pw_core_events pw_protocol_native_core_event_marshal = {
PW_VERSION_CORE_EVENTS,
&core_marshal_update_types_server,
&core_marshal_done,
&core_marshal_error,
@ -971,92 +898,134 @@ static const struct pw_core_events pw_protocol_native_server_core_events = {
&core_marshal_info
};
const struct pw_interface pw_protocol_native_server_core_interface = {
PW_TYPE__Core,
PW_VERSION_CORE,
PW_CORE_METHOD_NUM, pw_protocol_native_server_core_demarshal,
PW_CORE_EVENT_NUM, &pw_protocol_native_server_core_events,
static const demarshal_func_t pw_protocol_native_core_event_demarshal[PW_CORE_EVENT_NUM] = {
&core_demarshal_update_types_client,
&core_demarshal_done,
&core_demarshal_error,
&core_demarshal_remove_id,
&core_demarshal_info
};
static const demarshal_func_t pw_protocol_native_server_registry_demarshal[] = {
static const struct pw_protocol_marshal pw_protocol_native_core_marshal = {
PW_TYPE_INTERFACE__Core,
PW_VERSION_CORE,
PW_CORE_METHOD_NUM,
&pw_protocol_native_core_method_marshal,
pw_protocol_native_core_method_demarshal,
PW_CORE_EVENT_NUM,
&pw_protocol_native_core_event_marshal,
pw_protocol_native_core_event_demarshal
};
static const struct pw_registry_methods pw_protocol_native_registry_method_marshal = {
PW_VERSION_REGISTRY_METHODS,
&registry_marshal_bind
};
static const demarshal_func_t pw_protocol_native_registry_method_demarshal[] = {
&registry_demarshal_bind,
};
static const struct pw_registry_events pw_protocol_native_server_registry_events = {
static const struct pw_registry_events pw_protocol_native_registry_event_marshal = {
PW_VERSION_REGISTRY_EVENTS,
&registry_marshal_global,
&registry_marshal_global_remove,
};
const struct pw_interface pw_protocol_native_server_registry_interface = {
PW_TYPE__Registry,
PW_VERSION_REGISTRY,
PW_REGISTRY_METHOD_NUM, pw_protocol_native_server_registry_demarshal,
PW_REGISTRY_EVENT_NUM, &pw_protocol_native_server_registry_events,
static const demarshal_func_t pw_protocol_native_registry_event_demarshal[] = {
&registry_demarshal_global,
&registry_demarshal_global_remove,
};
static const struct pw_module_events pw_protocol_native_server_module_events = {
const struct pw_protocol_marshal pw_protocol_native_registry_marshal = {
PW_TYPE_INTERFACE__Registry,
PW_VERSION_REGISTRY,
PW_REGISTRY_METHOD_NUM,
&pw_protocol_native_registry_method_marshal,
pw_protocol_native_registry_method_demarshal,
PW_REGISTRY_EVENT_NUM,
&pw_protocol_native_registry_event_marshal,
pw_protocol_native_registry_event_demarshal,
};
static const struct pw_module_events pw_protocol_native_module_event_marshal = {
PW_VERSION_MODULE_EVENTS,
&module_marshal_info,
};
const struct pw_interface pw_protocol_native_server_module_interface = {
PW_TYPE__Module,
PW_VERSION_MODULE,
0, NULL,
PW_MODULE_EVENT_NUM, &pw_protocol_native_server_module_events,
static const demarshal_func_t pw_protocol_native_module_event_demarshal[] = {
&module_demarshal_info,
};
static const struct pw_node_events pw_protocol_native_server_node_events = {
const struct pw_protocol_marshal pw_protocol_native_module_marshal = {
PW_TYPE_INTERFACE__Module,
PW_VERSION_MODULE,
0, NULL, NULL,
PW_MODULE_EVENT_NUM,
&pw_protocol_native_module_event_marshal,
pw_protocol_native_module_event_demarshal,
};
static const struct pw_node_events pw_protocol_native_node_event_marshal = {
PW_VERSION_NODE_EVENTS,
&node_marshal_info,
};
const struct pw_interface pw_protocol_native_server_node_interface = {
PW_TYPE__Node,
PW_VERSION_NODE,
0, NULL,
PW_NODE_EVENT_NUM, &pw_protocol_native_server_node_events,
static const demarshal_func_t pw_protocol_native_node_event_demarshal[] = {
&node_demarshal_info,
};
static const struct pw_client_events pw_protocol_native_server_client_events = {
static const struct pw_protocol_marshal pw_protocol_native_node_marshal = {
PW_TYPE_INTERFACE__Node,
PW_VERSION_NODE,
0, NULL, NULL,
PW_NODE_EVENT_NUM,
&pw_protocol_native_node_event_marshal,
pw_protocol_native_node_event_demarshal,
};
static const struct pw_client_events pw_protocol_native_client_event_marshal = {
PW_VERSION_CLIENT_EVENTS,
&client_marshal_info,
};
const struct pw_interface pw_protocol_native_server_client_interface = {
PW_TYPE__Client,
PW_VERSION_CLIENT,
0, NULL,
PW_CLIENT_EVENT_NUM, &pw_protocol_native_server_client_events,
static const demarshal_func_t pw_protocol_native_client_event_demarshal[] = {
&client_demarshal_info,
};
static const struct pw_link_events pw_protocol_native_server_link_events = {
static const struct pw_protocol_marshal pw_protocol_native_client_marshal = {
PW_TYPE_INTERFACE__Client,
PW_VERSION_CLIENT,
0, NULL, NULL,
PW_CLIENT_EVENT_NUM,
&pw_protocol_native_client_event_marshal,
pw_protocol_native_client_event_demarshal,
};
static const struct pw_link_events pw_protocol_native_link_event_marshal = {
PW_VERSION_LINK_EVENTS,
&link_marshal_info,
};
const struct pw_interface pw_protocol_native_server_link_interface = {
PW_TYPE__Link,
static const demarshal_func_t pw_protocol_native_link_event_demarshal[] = {
&link_demarshal_info,
};
static const struct pw_protocol_marshal pw_protocol_native_link_marshal = {
PW_TYPE_INTERFACE__Link,
PW_VERSION_LINK,
0, NULL,
PW_LINK_EVENT_NUM, &pw_protocol_native_server_link_events,
0, NULL, NULL,
PW_LINK_EVENT_NUM,
&pw_protocol_native_link_event_marshal,
pw_protocol_native_link_event_demarshal,
};
void pw_protocol_native_init(struct pw_protocol *protocol)
{
pw_protocol_add_interfaces(protocol,
&pw_protocol_native_client_core_interface,
&pw_protocol_native_server_core_interface);
pw_protocol_add_interfaces(protocol,
&pw_protocol_native_client_registry_interface,
&pw_protocol_native_server_registry_interface);
pw_protocol_add_interfaces(protocol,
&pw_protocol_native_client_module_interface,
&pw_protocol_native_server_module_interface);
pw_protocol_add_interfaces(protocol,
&pw_protocol_native_client_node_interface,
&pw_protocol_native_server_node_interface);
pw_protocol_add_interfaces(protocol,
&pw_protocol_native_client_client_interface,
&pw_protocol_native_server_client_interface);
pw_protocol_add_interfaces(protocol,
&pw_protocol_native_client_link_interface,
&pw_protocol_native_server_link_interface);
pw_protocol_add_marshal(protocol, &pw_protocol_native_core_marshal);
pw_protocol_add_marshal(protocol, &pw_protocol_native_registry_marshal);
pw_protocol_add_marshal(protocol, &pw_protocol_native_module_marshal);
pw_protocol_add_marshal(protocol, &pw_protocol_native_node_marshal);
pw_protocol_add_marshal(protocol, &pw_protocol_native_client_marshal);
pw_protocol_add_marshal(protocol, &pw_protocol_native_link_marshal);
}

View file

@ -66,7 +66,7 @@ static struct pw_node *create_node(struct pw_node_factory *factory,
no_properties:
pw_log_error("missing properties");
if (resource) {
pw_core_notify_error(resource->client->core_resource,
pw_core_resource_error(resource->client->core_resource,
resource->client->core_resource->id,
SPA_RESULT_INVALID_ARGUMENTS, "missing properties");
}
@ -74,7 +74,7 @@ static struct pw_node *create_node(struct pw_node_factory *factory,
no_mem:
pw_log_error("can't create node");
if (resource) {
pw_core_notify_error(resource->client->core_resource,
pw_core_resource_error(resource->client->core_resource,
resource->client->core_resource->id,
SPA_RESULT_NO_MEMORY, "no memory");
}
@ -97,7 +97,8 @@ static struct impl *module_new(struct pw_core *core, struct pw_properties *prope
spa_list_insert(core->node_factory_list.prev, &impl->this.link);
pw_core_add_global(core, NULL, core->type.node_factory, 0, impl, NULL, &impl->this.global);
pw_core_add_global(core, NULL, core->type.node_factory, 0,
NULL, impl, &impl->this.global);
return impl;
}

View file

@ -38,30 +38,33 @@ static void client_unbind_func(void *data)
}
static int
client_bind_func(struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id)
client_bind_func(struct pw_global *global,
struct pw_client *client,
uint32_t version, uint32_t id)
{
struct pw_client *this = global->object;
struct pw_resource *resource;
resource = pw_resource_new(client, id, global->type, version, 0);
resource = pw_resource_new(client, id, global->type, version, 0, client_unbind_func);
if (resource == NULL)
goto no_mem;
pw_resource_set_implementation(resource, global->object, PW_VERSION_CLIENT, NULL, client_unbind_func);
pw_resource_set_implementation(resource, this, NULL);
pw_log_debug("client %p: bound to %d", global->object, resource->id);
pw_log_debug("client %p: bound to %d", this, resource->id);
spa_list_insert(this->resource_list.prev, &resource->link);
this->info.change_mask = ~0;
pw_client_notify_info(resource, &this->info);
pw_client_resource_info(resource, &this->info);
this->info.change_mask = 0;
return SPA_RESULT_OK;
no_mem:
pw_log_error("can't create client resource");
pw_core_notify_error(client->core_resource,
client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory");
pw_core_resource_error(client->core_resource,
client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory");
return SPA_RESULT_NO_MEMORY;
}
@ -111,9 +114,8 @@ struct pw_client *pw_client_new(struct pw_core *core,
spa_list_insert(core->client_list.prev, &this->link);
pw_core_add_global(core, NULL, core->type.client, PW_VERSION_CLIENT,
this, client_bind_func, &this->global);
client_bind_func, this, &this->global);
this->info.id = this->global->id;
this->info.props = this->properties ? &this->properties->dict : NULL;
return this;
@ -192,7 +194,7 @@ void pw_client_update_properties(struct pw_client *client, const struct spa_dict
pw_signal_emit(&client->properties_changed, client);
spa_list_for_each(resource, &client->resource_list, link) {
pw_client_notify_info(resource, &client->info);
pw_client_resource_info(resource, &client->info);
}
}

View file

@ -32,7 +32,6 @@
/** \cond */
struct global_impl {
struct pw_global this;
pw_bind_func_t bind;
};
struct impl {
@ -53,39 +52,59 @@ static bool pw_global_is_visible(struct pw_global *global,
core->global_filter(global, client, core->global_filter_data));
}
static void registry_bind(void *object, uint32_t id, uint32_t version, uint32_t new_id)
static struct pw_global *find_global(struct pw_core *core, uint32_t id)
{
struct pw_global *global;
spa_list_for_each(global, &core->global_list, link) {
if (global->id == id)
return global;
}
return NULL;
}
static void registry_bind(void *object, uint32_t id,
uint32_t type, uint32_t version, uint32_t new_id)
{
struct pw_resource *resource = object;
struct pw_client *client = resource->client;
struct pw_core *core = resource->core;
struct pw_global *global;
const char *type_name;
spa_list_for_each(global, &core->global_list, link) {
if (global->id == id)
break;
}
if (&global->link == &core->global_list)
if ((global = find_global(core, id)) == 0)
goto no_id;
if (!pw_global_is_visible(global, client))
goto no_id;
goto no_id;
if (type != global->type)
goto wrong_interface;
type_name = spa_type_map_get_type(core->type.map, type);
pw_log_debug("global %p: bind global id %d, iface %s to %d", global, id, type_name, new_id);
pw_log_debug("global %p: bind object id %d to %d", global, id, new_id);
pw_global_bind(global, client, version, new_id);
return;
no_id:
pw_log_debug("registry %p: no global with id %u to bind to %u", resource, id, new_id);
goto exit;
wrong_interface:
pw_log_debug("registry %p: global with id %u has no interface %u", resource, id, type);
goto exit;
exit:
/* unmark the new_id the map, the client does not yet know about the failed
* bind and will choose the next id, which we would refuse when we don't mark
* new_id as 'used and freed' */
pw_map_insert_at(&client->objects, new_id, NULL);
pw_core_notify_remove_id(client->core_resource, new_id);
pw_core_resource_remove_id(client->core_resource, new_id);
return;
}
static struct pw_registry_methods registry_methods = {
PW_VERSION_REGISTRY_METHODS,
&registry_bind
};
@ -106,7 +125,7 @@ static void core_sync(void *object, uint32_t seq)
{
struct pw_resource *resource = object;
pw_core_notify_done(resource, seq);
pw_core_resource_done(resource, seq);
}
static void core_get_registry(void *object, uint32_t version, uint32_t new_id)
@ -121,40 +140,40 @@ static void core_get_registry(void *object, uint32_t version, uint32_t new_id)
new_id,
this->type.registry,
version,
0);
0, destroy_registry_resource);
if (registry_resource == NULL)
goto no_mem;
pw_resource_set_implementation(registry_resource,
this,
PW_VERSION_REGISTRY,
&registry_methods,
destroy_registry_resource);
registry_resource,
&registry_methods);
spa_list_insert(this->registry_resource_list.prev, &registry_resource->link);
spa_list_for_each(global, &this->global_list, link) {
if (pw_global_is_visible(global, client))
pw_registry_notify_global(registry_resource,
global->id,
global->type,
global->version);
if (pw_global_is_visible(global, client)) {
pw_registry_resource_global(registry_resource,
global->id,
global->type,
global->version);
}
}
return;
no_mem:
pw_log_error("can't create registry resource");
pw_core_notify_error(client->core_resource,
resource->id, SPA_RESULT_NO_MEMORY, "no memory");
pw_core_resource_error(client->core_resource,
resource->id, SPA_RESULT_NO_MEMORY, "no memory");
}
static void
core_create_node(void *object,
const char *factory_name,
const char *name,
const struct spa_dict *props,
uint32_t type,
uint32_t version,
const struct spa_dict *props,
uint32_t new_id)
{
struct pw_resource *resource = object;
@ -167,11 +186,7 @@ core_create_node(void *object,
if (factory == NULL)
goto no_factory;
node_resource = pw_resource_new(client,
new_id,
factory->type,
version,
0);
node_resource = pw_resource_new(client, new_id, type, version, 0, NULL);
if (node_resource == NULL)
goto no_resource;
@ -191,8 +206,8 @@ core_create_node(void *object,
no_factory:
pw_log_error("can't find node factory");
pw_core_notify_error(client->core_resource,
resource->id, SPA_RESULT_INVALID_ARGUMENTS, "unknown factory name");
pw_core_resource_error(client->core_resource,
resource->id, SPA_RESULT_INVALID_ARGUMENTS, "unknown factory name");
goto done;
no_resource:
@ -203,8 +218,8 @@ core_create_node(void *object,
pw_resource_destroy(node_resource);
goto no_mem;
no_mem:
pw_core_notify_error(client->core_resource,
resource->id, SPA_RESULT_NO_MEMORY, "no memory");
pw_core_resource_error(client->core_resource,
resource->id, SPA_RESULT_NO_MEMORY, "no memory");
goto done;
}
@ -222,8 +237,8 @@ core_create_link(void *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");
pw_core_resource_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)
@ -241,6 +256,7 @@ static void core_update_types(void *object, uint32_t first_id, uint32_t n_types,
}
static const struct pw_core_methods core_methods = {
PW_VERSION_CORE_METHODS,
&core_update_types,
&core_sync,
&core_get_registry,
@ -257,26 +273,27 @@ static void core_unbind_func(void *data)
}
static int
core_bind_func(struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id)
core_bind_func(struct pw_global *global,
struct pw_client *client,
uint32_t version,
uint32_t id)
{
struct pw_core *this = global->object;
struct pw_resource *resource;
resource = pw_resource_new(client, id, global->type, version, 0);
resource = pw_resource_new(client, id, global->type, version, 0, core_unbind_func);
if (resource == NULL)
goto no_mem;
pw_resource_set_implementation(resource, global->object,
PW_VERSION_CORE, &core_methods, core_unbind_func);
pw_resource_set_implementation(resource, resource, &core_methods);
spa_list_insert(this->resource_list.prev, &resource->link);
client->core_resource = resource;
pw_log_debug("core %p: bound to %d", global->object, resource->id);
pw_log_debug("core %p: bound to %d", this, resource->id);
this->info.change_mask = PW_CORE_CHANGE_MASK_ALL;
pw_core_notify_info(resource, &this->info);
this->info.change_mask = 0;
pw_core_resource_info(resource, &this->info);
return SPA_RESULT_OK;
@ -343,9 +360,8 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop, struct pw_properties *pro
pw_signal_init(&this->global_removed);
pw_core_add_global(this, NULL, this->type.core, PW_VERSION_CORE,
this, core_bind_func, &this->global);
core_bind_func, this, &this->global);
this->info.id = this->global->id;
this->info.change_mask = 0;
this->info.user_name = pw_get_user_name();
this->info.host_name = pw_get_host_name();
@ -397,7 +413,8 @@ void pw_core_destroy(struct pw_core *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 n_ifaces number of interfaces
* \param ifaces interface information
* \param object the associated object
* \param bind a function to bind to this global
* \param[out] global a result global
@ -407,28 +424,29 @@ void pw_core_destroy(struct pw_core *core)
*/
bool
pw_core_add_global(struct pw_core *core,
struct pw_resource *owner,
struct pw_resource *owner,
uint32_t type,
uint32_t version,
void *object,
pw_bind_func_t bind,
void *object,
struct pw_global **global)
{
struct global_impl *impl;
struct pw_global *this;
struct pw_resource *registry;
const char *type_name;
impl = calloc(1, sizeof(struct global_impl));
if (impl == NULL)
return false;
this = &impl->this;
impl->bind = bind;
this->core = core;
this->owner = owner;
this->type = type;
this->version = version;
this->bind = bind;
this->object = object;
*global = this;
@ -439,11 +457,13 @@ pw_core_add_global(struct pw_core *core,
spa_list_insert(core->global_list.prev, &this->link);
pw_signal_emit(&core->global_added, core, this);
pw_log_debug("global %p: new %u %d, owner %p", this, this->id, this->type, owner);
type_name = spa_type_map_get_type(core->type.map, this->type);
pw_log_debug("global %p: new %u %s, owner %p", this, this->id, type_name, owner);
spa_list_for_each(registry, &core->registry_resource_list, link)
if (pw_global_is_visible(this, registry->client))
pw_registry_notify_global(registry, this->id, this->type, this->version);
pw_registry_resource_global(registry, this->id, this->type, this->version);
return true;
}
@ -462,18 +482,33 @@ pw_core_add_global(struct pw_core *core,
* \memberof pw_global
*/
int
pw_global_bind(struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id)
pw_global_bind(struct pw_global *global, struct pw_client *client,
uint32_t version, uint32_t id)
{
int res;
struct global_impl *impl = SPA_CONTAINER_OF(global, struct global_impl, this);
if (impl->bind) {
res = impl->bind(global, client, version, id);
} else {
res = SPA_RESULT_NOT_IMPLEMENTED;
pw_core_notify_error(client->core_resource,
client->core_resource->id, res, "can't bind object id %d", id);
}
if (global->bind == NULL)
goto no_bind;
if (global->version < version)
goto wrong_version;
res = global->bind(global, client, version, id);
return res;
wrong_version:
res = SPA_RESULT_INCOMPATIBLE_VERSION;
pw_core_resource_error(client->core_resource,
client->core_resource->id,
res, "id %d: interface version %d < %d",
id, global->version, version);
return res;
no_bind:
res = SPA_RESULT_NOT_IMPLEMENTED;
pw_core_resource_error(client->core_resource,
client->core_resource->id,
res, "can't bind object id %d to interface", id);
return res;
}
@ -493,7 +528,7 @@ void pw_global_destroy(struct pw_global *global)
spa_list_for_each(registry, &core->registry_resource_list, link)
if (pw_global_is_visible(global, registry->client))
pw_registry_notify_global_remove(registry, global->id);
pw_registry_resource_global_remove(registry, global->id);
pw_map_remove(&core->objects, global->id);
@ -534,7 +569,7 @@ void pw_core_update_properties(struct pw_core *core, const struct spa_dict *dict
pw_signal_emit(&core->info_changed, core);
spa_list_for_each(resource, &core->resource_list, link) {
pw_core_notify_info(resource, &core->info);
pw_core_resource_info(resource, &core->info);
}
core->info.change_mask = 0;
}

View file

@ -37,12 +37,6 @@ struct pw_global;
#include <pipewire/node.h>
#include <pipewire/node-factory.h>
#define PW_TYPE__Core PW_TYPE_OBJECT_BASE "Core"
#define PW_TYPE_CORE_BASE PW_TYPE__Core ":"
#define PW_TYPE__Registry PW_TYPE_OBJECT_BASE "Registry"
#define PW_TYPE_REGISTRY_BASE PW_TYPE__Registry ":"
/** \page page_server_api Server API
*
* \section page_server_overview Overview
@ -96,8 +90,10 @@ struct pw_global;
* emit events to the client and lets the client invoke methods on
* the object.
*/
typedef int (*pw_bind_func_t) (struct pw_global *global,
struct pw_client *client, uint32_t version, uint32_t id);
typedef int (*pw_bind_func_t) (struct pw_global *global, /**< the global to bind */
struct pw_client *client, /**< client that binds */
uint32_t version, /**< client interface version */
uint32_t id); /**< client proxy id */
typedef bool (*pw_global_filter_func_t) (struct pw_global *global,
struct pw_client *client, void *data);
@ -131,9 +127,12 @@ struct pw_global {
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 */
uint32_t type; /**< type of interface */
uint32_t version; /**< version of interface */
pw_bind_func_t bind; /**< function to bind to the interface */
void *object; /**< object associated with the interface */
/** Emited when the global is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_global *global));
@ -210,12 +209,15 @@ pw_core_add_global(struct pw_core *core,
struct pw_resource *owner,
uint32_t type,
uint32_t version,
void *object, pw_bind_func_t bind,
pw_bind_func_t bind,
void *object,
struct pw_global **global);
int
pw_global_bind(struct pw_global *global,
struct pw_client *client, uint32_t version, uint32_t id);
struct pw_client *client,
uint32_t version,
uint32_t id);
void
pw_global_destroy(struct pw_global *global);

View file

@ -30,7 +30,18 @@ extern "C" {
#include <spa/param-alloc.h>
#include <spa/node.h>
#include <pipewire/type.h>
#include <pipewire/introspect.h>
#include <pipewire/proxy.h>
#include <pipewire/remote.h>
#include <pipewire/core.h>
struct pw_core_proxy { struct pw_proxy proxy; };
struct pw_registry_proxy { struct pw_proxy proxy; };
struct pw_module_proxy { struct pw_proxy proxy; };
struct pw_node_proxy { struct pw_proxy proxy; };
struct pw_client_proxy { struct pw_proxy proxy; };
struct pw_link_proxy { struct pw_proxy proxy; };
/**
* \page page_pipewire_protocol The PipeWire protocol
@ -48,7 +59,16 @@ extern "C" {
* \section page_iface_pw_core API
*/
#define PW_VERSION_CORE 0
/** Core */
#define PW_TYPE_INTERFACE__Core PW_TYPE_INTERFACE_BASE "Core"
#define PW_TYPE_INTERFACE__Registry PW_TYPE_INTERFACE_BASE "Registry"
#define PW_TYPE_INTERFACE__Module PW_TYPE_INTERFACE_BASE "Module"
#define PW_TYPE_INTERFACE__Node PW_TYPE_INTERFACE_BASE "Node"
#define PW_TYPE_INTERFACE__Client PW_TYPE_INTERFACE_BASE "Client"
#define PW_TYPE_INTERFACE__Link PW_TYPE_INTERFACE_BASE "Link"
#define PW_VERSION_CORE 0
#define PW_CORE_METHOD_UPDATE_TYPES 0
#define PW_CORE_METHOD_SYNC 1
@ -67,6 +87,8 @@ extern "C" {
* for internal features.
*/
struct pw_core_methods {
#define PW_VERSION_CORE_METHODS 0
uint32_t version;
/**
* Update the type map
*
@ -111,15 +133,17 @@ struct pw_core_methods {
*
* \param factory_name the factory name to use
* \param name the node name
* \param props extra properties
* \param type the interface to bind to
* \param version the version of the interface
* \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 type,
uint32_t version,
const struct spa_dict *props,
uint32_t new_id);
/**
* Create a new link between two node ports
@ -142,12 +166,69 @@ struct pw_core_methods {
uint32_t new_id);
};
#define pw_core_do_update_types(p,...) pw_proxy_do(p,struct pw_core_methods,update_types,__VA_ARGS__)
#define pw_core_do_sync(p,...) pw_proxy_do(p,struct pw_core_methods,sync,__VA_ARGS__)
#define pw_core_do_get_registry(p,...) pw_proxy_do(p,struct pw_core_methods,get_registry,__VA_ARGS__)
#define pw_core_do_client_update(p,...) pw_proxy_do(p,struct pw_core_methods,client_update,__VA_ARGS__)
#define pw_core_do_create_node(p,...) pw_proxy_do(p,struct pw_core_methods,create_node,__VA_ARGS__)
#define pw_core_do_create_link(p,...) pw_proxy_do(p,struct pw_core_methods,create_link,__VA_ARGS__)
static inline void
pw_core_proxy_update_types(struct pw_core_proxy *core, uint32_t first_id, uint32_t n_types, const char **types)
{
pw_proxy_do(&core->proxy, struct pw_core_methods, update_types, first_id, n_types, types);
}
static inline void
pw_core_proxy_sync(struct pw_core_proxy *core, uint32_t seq)
{
pw_proxy_do(&core->proxy, struct pw_core_methods, sync, seq);
}
static inline struct pw_registry_proxy *
pw_core_proxy_get_registry(struct pw_core_proxy *core, uint32_t version, size_t user_data_size, pw_destroy_t destroy)
{
struct pw_core *c = core->proxy.remote->core;
struct pw_proxy *p = pw_proxy_new(core->proxy.remote, SPA_ID_INVALID, c->type.registry,
user_data_size, destroy);
pw_proxy_do(&core->proxy, struct pw_core_methods, get_registry, version, p->id);
return (struct pw_registry_proxy *) p;
}
static inline void
pw_core_proxy_client_update(struct pw_core_proxy *core, const struct spa_dict *props)
{
pw_proxy_do(&core->proxy, struct pw_core_methods, client_update, props);
}
static inline void *
pw_core_proxy_create_node(struct pw_core_proxy *core,
const char *factory_name,
const char *name,
uint32_t type,
uint32_t version,
const struct spa_dict *props,
size_t user_data_size,
pw_destroy_t destroy)
{
struct pw_proxy *p = pw_proxy_new(core->proxy.remote, SPA_ID_INVALID, type, user_data_size, destroy);
pw_proxy_do(&core->proxy, struct pw_core_methods, create_node, factory_name,
name, type, version, props, p->id);
return p;
}
static inline struct pw_link_proxy *
pw_core_proxy_create_link(struct pw_core_proxy *core,
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 *prop,
size_t user_data_size,
pw_destroy_t destroy)
{
struct pw_core *c = core->proxy.remote->core;
struct pw_proxy *p = pw_proxy_new(core->proxy.remote, SPA_ID_INVALID, c->type.link,
user_data_size, destroy);
pw_proxy_do(&core->proxy, struct pw_core_methods, create_link, output_node_id, output_port_id,
input_node_id, input_port_id, filter, prop, p->id);
return (struct pw_link_proxy*) p;
}
#define PW_CORE_EVENT_UPDATE_TYPES 0
#define PW_CORE_EVENT_DONE 1
@ -161,6 +242,8 @@ struct pw_core_methods {
* \ingroup pw_core_interface The pw_core interface
*/
struct pw_core_events {
#define PW_VERSION_CORE_EVENTS 0
uint32_t version;
/**
* Update the type map
*
@ -214,19 +297,31 @@ struct pw_core_events {
void (*info) (void *object, struct pw_core_info *info);
};
#define pw_core_notify_update_types(r,...) pw_resource_notify(r,struct pw_core_events,update_types,__VA_ARGS__)
#define pw_core_notify_done(r,...) pw_resource_notify(r,struct pw_core_events,done,__VA_ARGS__)
#define pw_core_notify_error(r,...) pw_resource_notify(r,struct pw_core_events,error,__VA_ARGS__)
#define pw_core_notify_remove_id(r,...) pw_resource_notify(r,struct pw_core_events,remove_id,__VA_ARGS__)
#define pw_core_notify_info(r,...) pw_resource_notify(r,struct pw_core_events,info,__VA_ARGS__)
static inline void
pw_core_proxy_add_listener(struct pw_core_proxy *core,
void *object, const struct pw_core_events *events)
{
pw_proxy_add_listener(&core->proxy, object, events);
}
#define pw_core_resource_update_types(r,...) pw_resource_notify(r,struct pw_core_events,update_types,__VA_ARGS__)
#define pw_core_resource_done(r,...) pw_resource_notify(r,struct pw_core_events,done,__VA_ARGS__)
#define pw_core_resource_error(r,...) pw_resource_notify(r,struct pw_core_events,error,__VA_ARGS__)
#define pw_core_resource_remove_id(r,...) pw_resource_notify(r,struct pw_core_events,remove_id,__VA_ARGS__)
#define pw_core_resource_info(r,...) pw_resource_notify(r,struct pw_core_events,info,__VA_ARGS__)
#define PW_VERSION_REGISTRY 0
#define PW_REGISTRY_METHOD_BIND 0
#define PW_REGISTRY_METHOD_NUM 1
#define PW_REGISTRY_METHOD_BIND 0
#define PW_REGISTRY_METHOD_NUM 1
/** Registry methods */
struct pw_registry_methods {
#define PW_VERSION_REGISTRY_METHODS 0
uint32_t version;
/**
* Bind to a global object
*
@ -235,13 +330,24 @@ struct pw_registry_methods {
* 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 type the interface type to bind to
* \param version the interface 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);
void (*bind) (void *object, uint32_t id, uint32_t type, uint32_t version, uint32_t new_id);
};
#define pw_registry_do_bind(p,...) pw_proxy_do(p,struct pw_registry_methods,bind,__VA_ARGS__)
/** Registry */
static inline void *
pw_registry_proxy_bind(struct pw_registry_proxy *registry,
uint32_t id, uint32_t type, uint32_t version,
size_t user_data_size, pw_destroy_t destroy)
{
struct pw_proxy *p = pw_proxy_new(registry->proxy.remote, SPA_ID_INVALID,
type, user_data_size, destroy);
pw_proxy_do(&registry->proxy, struct pw_registry_methods, bind, id, type, version, p->id);
return p;
}
#define PW_REGISTRY_EVENT_GLOBAL 0
#define PW_REGISTRY_EVENT_GLOBAL_REMOVE 1
@ -249,6 +355,8 @@ struct pw_registry_methods {
/** Registry events */
struct pw_registry_events {
#define PW_VERSION_REGISTRY_EVENTS 0
uint32_t version;
/**
* Notify of a new global object
*
@ -256,8 +364,8 @@ struct pw_registry_events {
* available.
*
* \param id the global object id
* \param type the type of the object
* \param version the version of the object
* \param type the type of the interface
* \param version the version of the interface
*/
void (*global) (void *object, uint32_t id, uint32_t type, uint32_t version);
/**
@ -272,8 +380,16 @@ struct pw_registry_events {
void (*global_remove) (void *object, uint32_t id);
};
#define pw_registry_notify_global(r,...) pw_resource_notify(r,struct pw_registry_events,global,__VA_ARGS__)
#define pw_registry_notify_global_remove(r,...) pw_resource_notify(r,struct pw_registry_events,global_remove,__VA_ARGS__)
static inline void
pw_registry_proxy_add_listener(struct pw_registry_proxy *registry,
void *object, const struct pw_registry_events *events)
{
pw_proxy_add_listener(&registry->proxy, object, events);
}
#define pw_registry_resource_global(r,...) pw_resource_notify(r,struct pw_registry_events,global,__VA_ARGS__)
#define pw_registry_resource_global_remove(r,...) pw_resource_notify(r,struct pw_registry_events,global_remove,__VA_ARGS__)
#define PW_VERSION_MODULE 0
@ -282,6 +398,8 @@ struct pw_registry_events {
/** Module events */
struct pw_module_events {
#define PW_VERSION_MODULE_EVENTS 0
uint32_t version;
/**
* Notify module info
*
@ -290,15 +408,24 @@ struct pw_module_events {
void (*info) (void *object, struct pw_module_info *info);
};
#define pw_module_notify_info(r,...) pw_resource_notify(r,struct pw_module_events,info,__VA_ARGS__)
static inline void
pw_module_proxy_add_listener(struct pw_module_proxy *module,
void *object, const struct pw_module_events *events)
{
pw_proxy_add_listener(&module->proxy, object, events);
}
#define PW_VERSION_NODE 0
#define pw_module_resource_info(r,...) pw_resource_notify(r,struct pw_module_events,info,__VA_ARGS__)
#define PW_VERSION_NODE 0
#define PW_NODE_EVENT_INFO 0
#define PW_NODE_EVENT_NUM 1
/** Node events */
struct pw_node_events {
#define PW_VERSION_NODE_EVENTS 0
uint32_t version;
/**
* Notify node info
*
@ -307,7 +434,14 @@ struct pw_node_events {
void (*info) (void *object, struct pw_node_info *info);
};
#define pw_node_notify_info(r,...) pw_resource_notify(r,struct pw_node_events,info,__VA_ARGS__)
static inline void
pw_node_proxy_add_listener(struct pw_node_proxy *node,
void *object, const struct pw_node_events *events)
{
pw_proxy_add_listener(&node->proxy, object, events);
}
#define pw_node_resource_info(r,...) pw_resource_notify(r,struct pw_node_events,info,__VA_ARGS__)
#define PW_VERSION_CLIENT 0
@ -316,6 +450,8 @@ struct pw_node_events {
/** Client events */
struct pw_client_events {
#define PW_VERSION_CLIENT_EVENTS 0
uint32_t version;
/**
* Notify client info
*
@ -324,15 +460,26 @@ struct pw_client_events {
void (*info) (void *object, struct pw_client_info *info);
};
#define pw_client_notify_info(r,...) pw_resource_notify(r,struct pw_client_events,info,__VA_ARGS__)
/** Client */
static inline void
pw_client_proxy_add_listener(struct pw_client_proxy *client,
void *object, const struct pw_client_events *events)
{
pw_proxy_add_listener(&client->proxy, object, events);
}
#define PW_VERSION_LINK 0
#define pw_client_resource_info(r,...) pw_resource_notify(r,struct pw_client_events,info,__VA_ARGS__)
#define PW_VERSION_LINK 0
#define PW_LINK_EVENT_INFO 0
#define PW_LINK_EVENT_NUM 1
/** Link events */
struct pw_link_events {
#define PW_VERSION_LINK_EVENTS 0
uint32_t version;
/**
* Notify link info
*
@ -341,7 +488,15 @@ struct pw_link_events {
void (*info) (void *object, struct pw_link_info *info);
};
#define pw_link_notify_info(r,...) pw_resource_notify(r,struct pw_link_events,info,__VA_ARGS__)
/** Link */
static inline void
pw_link_proxy_add_listener(struct pw_link_proxy *link,
void *object, const struct pw_link_events *events)
{
pw_proxy_add_listener(&link->proxy, object, events);
}
#define pw_link_resource_info(r,...) pw_resource_notify(r,struct pw_link_events,info,__VA_ARGS__)
#ifdef __cplusplus
} /* extern "C" */

View file

@ -125,7 +125,6 @@ struct pw_core_info *pw_core_info_update(struct pw_core_info *info,
if (info == NULL)
return NULL;
}
info->id = update->id;
info->change_mask = update->change_mask;
if (update->change_mask & (1 << 0)) {
@ -186,7 +185,6 @@ struct pw_node_info *pw_node_info_update(struct pw_node_info *info,
if (info == NULL)
return NULL;
}
info->id = update->id;
info->change_mask = update->change_mask;
if (update->change_mask & (1 << 0)) {
@ -283,7 +281,6 @@ struct pw_module_info *pw_module_info_update(struct pw_module_info *info,
if (info == NULL)
return NULL;
}
info->id = update->id;
info->change_mask = update->change_mask;
if (update->change_mask & (1 << 0)) {
@ -334,7 +331,6 @@ struct pw_client_info *pw_client_info_update(struct pw_client_info *info,
if (info == NULL)
return NULL;
}
info->id = update->id;
info->change_mask = update->change_mask;
if (update->change_mask & (1 << 0)) {
@ -363,7 +359,6 @@ struct pw_link_info *pw_link_info_update(struct pw_link_info *info,
if (info == NULL)
return NULL;
}
info->id = update->id;
info->change_mask = update->change_mask;
if (update->change_mask & (1 << 0))

View file

@ -74,7 +74,6 @@ const char * pw_link_state_as_string(enum pw_link_state state);
/** The core information. Extra information can be added in later versions \memberof pw_introspect */
struct pw_core_info {
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)
@ -101,7 +100,6 @@ void pw_core_info_free(struct pw_core_info *info);
/** The module information. Extra information can be added in later versions \memberof pw_introspect */
struct pw_module_info {
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 */
@ -119,7 +117,6 @@ void pw_module_info_free(struct pw_module_info *info);
/** The client information. Extra information can be added in later versions \memberof pw_introspect */
struct pw_client_info {
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 */
};
@ -135,7 +132,6 @@ void pw_client_info_free(struct pw_client_info *info);
/** The node information. Extra information can be added in later versions \memberof pw_introspect */
struct pw_node_info {
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_input_ports; /**< maximum number of inputs */
@ -161,7 +157,6 @@ pw_node_info_free(struct pw_node_info *info);
/** The link information. Extra information can be added in later versions \memberof pw_introspect */
struct pw_link_info {
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 */

View file

@ -939,31 +939,34 @@ static void link_unbind_func(void *data)
}
static int
link_bind_func(struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id)
link_bind_func(struct pw_global *global,
struct pw_client *client,
uint32_t version, uint32_t id)
{
struct pw_link *this = global->object;
struct pw_resource *resource;
resource = pw_resource_new(client, id, global->type, version, 0);
resource = pw_resource_new(client, id, global->type, version, 0, link_unbind_func);
if (resource == NULL)
goto no_mem;
pw_resource_set_implementation(resource, global->object, PW_VERSION_LINK, NULL, link_unbind_func);
pw_resource_set_implementation(resource, this, NULL);
pw_log_debug("link %p: bound to %d", global->object, resource->id);
pw_log_debug("link %p: bound to %d", this, resource->id);
spa_list_insert(this->resource_list.prev, &resource->link);
this->info.change_mask = ~0;
pw_link_notify_info(resource, &this->info);
pw_link_resource_info(resource, &this->info);
this->info.change_mask = 0;
return SPA_RESULT_OK;
no_mem:
pw_log_error("can't create link resource");
pw_core_notify_error(client->core_resource,
client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory");
pw_core_resource_error(client->core_resource,
client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory");
return SPA_RESULT_NO_MEMORY;
}
@ -1054,9 +1057,8 @@ struct pw_link *pw_link_new(struct pw_core *core,
spa_list_insert(core->link_list.prev, &this->link);
pw_core_add_global(core, NULL, core->type.link, PW_VERSION_LINK,
this, link_bind_func, &this->global);
link_bind_func, this, &this->global);
this->info.id = this->global->id;
this->info.output_node_id = output ? output_node->global->id : -1;
this->info.output_port_id = output ? output->port_id : -1;
this->info.input_node_id = input ? input_node->global->id : -1;

View file

@ -88,28 +88,31 @@ static char *find_module(const char *path, const char *name)
}
static int
module_bind_func(struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id)
module_bind_func(struct pw_global *global,
struct pw_client *client,
uint32_t version, uint32_t id)
{
struct pw_module *this = global->object;
struct pw_resource *resource;
resource = pw_resource_new(client, id, global->type, version, 0);
resource = pw_resource_new(client, id, global->type, version, 0, NULL);
if (resource == NULL)
goto no_mem;
pw_resource_set_implementation(resource, global->object, PW_VERSION_MODULE, NULL, NULL);
pw_resource_set_implementation(resource, this, NULL);
pw_log_debug("module %p: bound to %d", global->object, resource->id);
pw_log_debug("module %p: bound to %d", this, resource->id);
this->info.change_mask = ~0;
pw_module_notify_info(resource, &this->info);
pw_module_resource_info(resource, &this->info);
this->info.change_mask = 0;
return SPA_RESULT_OK;
no_mem:
pw_log_error("can't create module resource");
pw_core_notify_error(client->core_resource,
client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory");
pw_core_resource_error(client->core_resource,
client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory");
return SPA_RESULT_NO_MEMORY;
}
@ -181,9 +184,8 @@ struct pw_module *pw_module_load(struct pw_core *core,
goto init_failed;
pw_core_add_global(core, NULL, core->type.module, PW_VERSION_MODULE,
impl, module_bind_func, &this->global);
module_bind_func, this, &this->global);
this->info.id = this->global->id;
this->info.name = name ? strdup(name) : NULL;
this->info.filename = filename;
this->info.args = args ? strdup(args) : NULL;

View file

@ -24,8 +24,8 @@
extern "C" {
#endif
#define PW_TYPE__NodeFactory "PipeWire:Object:NodeFactory"
#define PW_TYPE_NODE_FACTORY_BASE PW_TYPE__NodeFactory ":"
#define PW_TYPE_INTERFACE__NodeFactory PW_TYPE_INTERFACE_BASE "NodeFactory"
#define PW_TYPE_NODE_FACTORY_BASE PW_TYPE_INTERFACE__NodeFactory ":"
#include <pipewire/core.h>
#include <pipewire/resource.h>
@ -42,7 +42,6 @@ struct pw_node_factory {
struct pw_global *global; /**< global for this factory */
const char *name; /**< the factory name */
uint32_t type; /**< type of the created nodes */
/** Emited when the factory is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_node_factory *object));

View file

@ -151,7 +151,6 @@ static void node_unbind_func(void *data)
static void
update_info(struct pw_node *this)
{
this->info.id = this->global->id;
this->info.input_formats = NULL;
if (!spa_list_is_empty(&this->input_ports)) {
@ -211,31 +210,33 @@ clear_info(struct pw_node *this)
}
static int
node_bind_func(struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id)
node_bind_func(struct pw_global *global,
struct pw_client *client,
uint32_t version, uint32_t id)
{
struct pw_node *this = global->object;
struct pw_resource *resource;
resource = pw_resource_new(client, id, global->type, version, 0);
resource = pw_resource_new(client, id, global->type, version, 0, node_unbind_func);
if (resource == NULL)
goto no_mem;
pw_resource_set_implementation(resource, global->object, PW_VERSION_NODE, NULL, node_unbind_func);
pw_resource_set_implementation(resource, this, NULL);
pw_log_debug("node %p: bound to %d", this, resource->id);
spa_list_insert(this->resource_list.prev, &resource->link);
this->info.change_mask = ~0;
pw_node_notify_info(resource, &this->info);
pw_node_resource_info(resource, &this->info);
this->info.change_mask = 0;
return SPA_RESULT_OK;
no_mem:
pw_log_error("can't create node resource");
pw_core_notify_error(client->core_resource,
client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory");
pw_core_resource_error(client->core_resource,
client->core_resource->id, SPA_RESULT_NO_MEMORY, "no memory");
return SPA_RESULT_NO_MEMORY;
}
@ -250,6 +251,7 @@ do_node_add(struct spa_loop *loop,
return SPA_RESULT_OK;
}
void pw_node_export(struct pw_node *this)
{
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
@ -259,7 +261,7 @@ void pw_node_export(struct pw_node *this)
spa_list_insert(this->core->node_list.prev, &this->link);
pw_core_add_global(this->core, this->owner, this->core->type.node, PW_VERSION_NODE,
this, node_bind_func, &this->global);
node_bind_func, this, &this->global);
pw_loop_invoke(this->data_loop, do_node_add, 1, 0, NULL, false, this);
@ -611,7 +613,7 @@ void pw_node_update_state(struct pw_node *node, enum pw_node_state state, char *
node->info.change_mask |= 1 << 5;
spa_list_for_each(resource, &node->resource_list, link)
pw_node_notify_info(resource, &node->info);
pw_node_resource_info(resource, &node->info);
node->info.change_mask = 0;
}
}

View file

@ -42,10 +42,8 @@ extern "C" {
struct pw_node;
#define PW_VERSION_NODE_IMPLEMENTATION 0
struct pw_node_implementation {
#define PW_VERSION_NODE_IMPLEMENTATION 0
uint32_t version;
int (*get_props) (struct pw_node *node, struct spa_props **props);
@ -71,8 +69,6 @@ struct pw_node_implementation {
* The node object processes data. The node has a list of
* input and output ports (\ref page_port) on which it
* will receive and send out buffers respectively.
*
* The node wraps an SPA node object.
*/
/** \class pw_node
*

View file

@ -23,6 +23,12 @@ struct impl {
struct pw_protocol this;
};
struct marshal {
struct spa_list link;
const struct pw_protocol_marshal *marshal;
uint32_t type;
};
struct pw_protocol *pw_protocol_new(struct pw_core *core,
const char *name,
size_t user_data_size)
@ -36,7 +42,7 @@ struct pw_protocol *pw_protocol_new(struct pw_core *core,
protocol->core = core;
protocol->name = strdup(name);
spa_list_init(&protocol->iface_list);
spa_list_init(&protocol->marshal_list);
spa_list_init(&protocol->connection_list);
spa_list_init(&protocol->listener_list);
@ -55,7 +61,7 @@ struct pw_protocol *pw_protocol_new(struct pw_core *core,
void pw_protocol_destroy(struct pw_protocol *protocol)
{
struct impl *impl = SPA_CONTAINER_OF(protocol, struct impl, this);
struct pw_protocol_iface *iface, *t1;
struct marshal *marshal, *t1;
struct pw_protocol_listener *listener, *t2;
struct pw_protocol_connection *connection, *t3;
@ -64,8 +70,8 @@ void pw_protocol_destroy(struct pw_protocol *protocol)
spa_list_remove(&protocol->link);
spa_list_for_each_safe(iface, t1, &protocol->iface_list, link)
free(iface);
spa_list_for_each_safe(marshal, t1, &protocol->marshal_list, link)
free(marshal);
spa_list_for_each_safe(listener, t2, &protocol->listener_list, link)
pw_protocol_listener_destroy(listener);
@ -82,41 +88,31 @@ void pw_protocol_destroy(struct pw_protocol *protocol)
}
void
pw_protocol_add_interfaces(struct pw_protocol *protocol,
const struct pw_interface *client_iface,
const struct pw_interface *server_iface)
pw_protocol_add_marshal(struct pw_protocol *protocol,
const struct pw_protocol_marshal *marshal)
{
struct pw_protocol_iface *iface;
const char *type;
uint32_t version;
struct marshal *impl;
iface = calloc(1, sizeof(struct pw_protocol_iface));
iface->client_iface = client_iface;
iface->server_iface = server_iface;
impl = calloc(1, sizeof(struct marshal));
impl->marshal = marshal;
impl->type = spa_type_map_get_id (protocol->core->type.map, marshal->type);
spa_list_insert(protocol->iface_list.prev, &iface->link);
spa_list_insert(protocol->marshal_list.prev, &impl->link);
type = client_iface ? client_iface->type : server_iface->type;
version = client_iface ? client_iface->version : server_iface->version;
pw_log_info("Add iface %s:%d to protocol %s", type, version, protocol->name);
pw_log_info("Add marshal %s:%d to protocol %s", marshal->type, marshal->version, protocol->name);
}
const struct pw_interface *
pw_protocol_get_interface(struct pw_protocol *protocol,
const char *type,
bool server)
const struct pw_protocol_marshal *
pw_protocol_get_marshal(struct pw_protocol *protocol, uint32_t type)
{
struct pw_protocol_iface *protocol_iface;
struct marshal *impl;
if (protocol == NULL)
return NULL;
spa_list_for_each(protocol_iface, &protocol->iface_list, link) {
const struct pw_interface *iface = server ? protocol_iface->server_iface :
protocol_iface->client_iface;
if (strcmp(iface->type, type) == 0)
return iface;
spa_list_for_each(impl, &protocol->marshal_list, link) {
if (impl->type == type)
return impl->marshal;
}
return NULL;
}

View file

@ -63,10 +63,15 @@ struct pw_protocol_listener {
#define pw_protocol_listener_destroy(l) ((l)->destroy(l))
struct pw_protocol_iface {
struct spa_list link;
const struct pw_interface *client_iface;
const struct pw_interface *server_iface;
struct pw_protocol_marshal {
const char *type; /**< interface type */
uint32_t version; /**< version */
uint32_t n_methods; /**< number of methods in the interface */
const void *method_marshal;
const void *method_demarshal;
uint32_t n_events; /**< number of events in the interface */
const void *event_marshal;
const void *event_demarshal;
};
struct pw_protocol_implementaton {
@ -86,7 +91,7 @@ struct pw_protocol {
char *name; /**< type name of the protocol */
struct spa_list iface_list; /**< list of supported interfaces */
struct spa_list marshal_list; /**< list of marshallers for supported interfaces */
struct spa_list connection_list; /**< list of current connections */
struct spa_list listener_list; /**< list of current listeners */
@ -104,9 +109,7 @@ struct pw_protocol {
#define pw_protocol_new_connection(p,...) ((p)->implementation->new_connection(p,__VA_ARGS__))
#define pw_protocol_add_listener(p,...) ((p)->implementation->add_listener(p,__VA_ARGS__))
#define pw_protocol_ext(p,type,method,...) ((type*)(p)->extension)->method( __VA_ARGS__)
#define pw_protocol_connection_ext(c,type,method,...) ((type*)(c)->protocol->extension)->method( __VA_ARGS__)
#define pw_protocol_listener_ext(l,type,method,...) ((type*)(l)->protocol->extension)->method( __VA_ARGS__)
#define pw_protocol_ext(p,type,method,...) (((type*)(p)->extension)->method( __VA_ARGS__))
struct pw_protocol *pw_protocol_new(struct pw_core *core, const char *name, size_t user_data_size);
@ -114,13 +117,11 @@ struct pw_protocol *pw_protocol_new(struct pw_core *core, const char *name, size
*
* \brief Manages protocols and their implementation
*/
void
pw_protocol_add_interfaces(struct pw_protocol *protocol,
const struct pw_interface *client_iface,
const struct pw_interface *server_iface);
void pw_protocol_add_marshal(struct pw_protocol *protocol,
const struct pw_protocol_marshal *marshal);
const struct pw_interface *
pw_protocol_get_interface(struct pw_protocol *protocol, const char *type, bool server);
const struct pw_protocol_marshal *
pw_protocol_get_marshal(struct pw_protocol *protocol, uint32_t type);
#ifdef __cplusplus
} /* extern "C" */

View file

@ -20,6 +20,7 @@
#include <pipewire/log.h>
#include <pipewire/proxy.h>
#include <pipewire/core.h>
#include <pipewire/remote.h>
/** \cond */
struct proxy {
@ -42,8 +43,10 @@ struct proxy {
* \memberof pw_proxy
*/
struct pw_proxy *pw_proxy_new(struct pw_remote *remote,
uint32_t id, uint32_t type,
size_t user_data_size)
uint32_t id,
uint32_t type,
size_t user_data_size,
pw_destroy_t destroy)
{
struct proxy *impl;
struct pw_proxy *this;
@ -54,7 +57,6 @@ struct pw_proxy *pw_proxy_new(struct pw_remote *remote,
this = &impl->this;
this->remote = remote;
this->type = type;
pw_signal_init(&this->destroy_signal);
@ -64,13 +66,13 @@ struct pw_proxy *pw_proxy_new(struct pw_remote *remote,
goto in_use;
this->id = id;
this->type = type;
this->destroy = destroy;
if (user_data_size > 0)
this->user_data = SPA_MEMBER(impl, sizeof(struct proxy), void);
this->iface = pw_protocol_get_interface(remote->conn->protocol,
spa_type_map_get_type(remote->core->type.map, type),
false);
this->marshal = pw_protocol_get_marshal(remote->conn->protocol, type);
spa_list_insert(&this->remote->proxy_list, &this->link);
@ -84,17 +86,11 @@ struct pw_proxy *pw_proxy_new(struct pw_remote *remote,
return NULL;
}
int pw_proxy_set_implementation(struct pw_proxy *proxy,
void *object,
uint32_t version,
const void *implementation,
pw_destroy_t destroy)
void pw_proxy_add_listener(struct pw_proxy *proxy,
void *object, const void *listener)
{
proxy->object = object;
proxy->version = version;
proxy->implementation = implementation;
proxy->destroy = destroy;
return SPA_RESULT_OK;
proxy->listener = listener;
}
/** Destroy a proxy object

View file

@ -26,7 +26,8 @@ extern "C" {
#include <pipewire/type.h>
#include <pipewire/utils.h>
#include <pipewire/remote.h>
struct pw_remote;
/** \page page_proxy Proxy
*
@ -82,7 +83,7 @@ extern "C" {
* 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.
* set in listener.
*
* See \ref page_proxy
*/
@ -91,39 +92,40 @@ struct pw_proxy {
struct spa_list link; /**< link in the remote */
uint32_t id; /**< client side id */
uint32_t type; /**< object type id */
const struct pw_interface *iface; /**< methods/events marshal/demarshal functions */
uint32_t type; /**< type id */
void *object; /**< client side object */
uint32_t version;
const void *implementation; /**< event handler implementation */
pw_destroy_t destroy; /**< optional destroy function to clean up the object */
const void *listener; /**< event listener */
void *object; /**< object associated with proxy */
const struct pw_protocol_marshal *marshal; /**< protocol specific marshal functions */
/** destroy is emited when the proxy is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_proxy *proxy));
void *user_data; /**< extra user data */
pw_destroy_t destroy; /**< optional destroy function to clean up the user_data */
};
/** Make a new proxy object. The id can be used to bind to a remote object. */
struct pw_proxy *
pw_proxy_new(struct pw_remote *remote,
uint32_t id,
uint32_t type,
size_t user_data_size);
pw_proxy_new(struct pw_remote *remote, /**< remote this proxy is from */
uint32_t id, /**< local id, SPA_ID_INVALID to have one automatically
* allocated for you */
uint32_t type, /**< interface type id */
size_t user_data_size, /**< size of user data */
pw_destroy_t destroy /**< destroy function for user data */);
int
pw_proxy_set_implementation(struct pw_proxy *proxy,
void *object,
uint32_t version,
const void *implementation,
pw_destroy_t destroy);
void
pw_proxy_add_listener(struct pw_proxy *proxy, /**< the proxy */
void *object, /**< object associated with proxy */
const void *events /**< events */);
void pw_proxy_destroy(struct pw_proxy *proxy);
#define pw_proxy_notify(p,type,event,...) ((type*) (p)->implementation)->event(p, __VA_ARGS__)
#define pw_proxy_notify_na(p,type,event) ((type*) (p)->implementation)->event(p)
#define pw_proxy_do(p,type,method,...) ((type*) (p)->iface->methods)->method(p, __VA_ARGS__)
#define pw_proxy_do_na(p,type,method) ((type*) (p)->iface->methods)->method(p)
#define pw_proxy_notify(p,type,event,...) ((type*) (p)->listener)->event(p, __VA_ARGS__)
#define pw_proxy_notify_na(p,type,event) ((type*) (p)->listener)->event(p)
#define pw_proxy_do(p,type,method,...) ((type*) (p)->marshal->method_marshal)->method(p, __VA_ARGS__)
#define pw_proxy_do_na(p,type,method) ((type*) (p)->marshal->method_marshal)->method(p)
#ifdef __cplusplus
}

View file

@ -87,7 +87,7 @@ remote_update_state(struct pw_remote *remote, enum pw_remote_state state, const
static void core_event_info(void *object, struct pw_core_info *info)
{
struct pw_proxy *proxy = object;
struct pw_remote *this = proxy->remote;
struct pw_remote *this = proxy->object;
pw_log_debug("got core info");
this->info = pw_core_info_update(this->info, info);
@ -97,7 +97,7 @@ static void core_event_info(void *object, struct pw_core_info *info)
static void core_event_done(void *object, uint32_t seq)
{
struct pw_proxy *proxy = object;
struct pw_remote *this = proxy->remote;
struct pw_remote *this = proxy->object;
pw_log_debug("core event done %d", seq);
if (seq == 0)
@ -109,15 +109,14 @@ static void core_event_done(void *object, uint32_t seq)
static void core_event_error(void *object, uint32_t id, int res, const char *error, ...)
{
struct pw_proxy *proxy = object;
struct pw_remote *this = proxy->remote;
struct pw_remote *this = proxy->object;
remote_update_state(this, PW_REMOTE_STATE_ERROR, error);
}
static void core_event_remove_id(void *object, uint32_t id)
{
struct pw_proxy *core_proxy = object;
struct pw_remote *this = core_proxy->remote;
struct pw_proxy *proxy;
struct pw_proxy *proxy = object;
struct pw_remote *this = proxy->object;
proxy = pw_map_lookup(&this->objects, id);
if (proxy) {
@ -130,7 +129,7 @@ static void
core_event_update_types(void *object, uint32_t first_id, uint32_t n_types, const char **types)
{
struct pw_proxy *proxy = object;
struct pw_remote *this = proxy->remote;
struct pw_remote *this = proxy->object;
int i;
for (i = 0; i < n_types; i++, first_id++) {
@ -141,6 +140,7 @@ core_event_update_types(void *object, uint32_t first_id, uint32_t n_types, const
}
static const struct pw_core_events core_events = {
PW_VERSION_CORE_EVENTS,
&core_event_update_types,
&core_event_done,
&core_event_error,
@ -230,15 +230,14 @@ void pw_remote_destroy(struct pw_remote *remote)
static int do_connect(struct pw_remote *remote)
{
remote->core_proxy = pw_proxy_new(remote, 0, remote->core->type.core, 0);
remote->core_proxy = (struct pw_core_proxy*)pw_proxy_new(remote, 0, remote->core->type.core, 0, NULL);
if (remote->core_proxy == NULL)
goto no_proxy;
pw_proxy_set_implementation(remote->core_proxy, remote, PW_VERSION_CORE,
&core_events, NULL);
pw_proxy_add_listener((struct pw_proxy*)remote->core_proxy, remote, &core_events);
pw_core_do_client_update(remote->core_proxy, &remote->properties->dict);
pw_core_do_sync(remote->core_proxy, 0);
pw_core_proxy_client_update(remote->core_proxy, &remote->properties->dict);
pw_core_proxy_sync(remote->core_proxy, 0);
return 0;

View file

@ -24,8 +24,6 @@
extern "C" {
#endif
struct pw_remote;
#include <pipewire/map.h>
#include <pipewire/loop.h>
#include <pipewire/properties.h>
@ -123,7 +121,7 @@ struct pw_remote {
struct spa_list link; /**< link in core remote_list */
struct pw_properties *properties; /**< extra properties */
struct pw_proxy *core_proxy; /**< proxy for the core object */
struct pw_core_proxy *core_proxy; /**< proxy for the core object */
struct pw_map objects; /**< map of client side proxy objects
* indexed with the client id */
struct pw_core_info *info; /**< info about the remote core */

View file

@ -32,8 +32,9 @@ struct impl {
struct pw_resource *pw_resource_new(struct pw_client *client,
uint32_t id,
uint32_t type,
uint32_t client_version,
size_t user_data_size)
uint32_t version,
size_t user_data_size,
pw_destroy_t destroy)
{
struct impl *impl;
struct pw_resource *this;
@ -46,7 +47,7 @@ struct pw_resource *pw_resource_new(struct pw_client *client,
this->core = client->core;
this->client = client;
this->type = type;
this->client_version = client_version;
this->version = version;
pw_signal_init(&this->destroy_signal);
@ -60,9 +61,9 @@ struct pw_resource *pw_resource_new(struct pw_client *client,
if (user_data_size > 0)
this->user_data = SPA_MEMBER(impl, sizeof(struct impl), void);
this->iface = pw_protocol_get_interface(client->protocol,
spa_type_map_get_type(client->core->type.map, type),
true);
this->destroy = destroy;
this->marshal = pw_protocol_get_marshal(client->protocol, type);
pw_log_debug("resource %p: new for client %p id %u", this, client, id);
pw_signal_emit(&client->resource_added, client, this);
@ -77,17 +78,12 @@ struct pw_resource *pw_resource_new(struct pw_client *client,
int
pw_resource_set_implementation(struct pw_resource *resource,
void *object,
uint32_t version,
const void *implementation,
pw_destroy_t destroy)
void *object, const void *implementation)
{
struct pw_client *client = resource->client;
resource->object = object;
resource->version = version;
resource->implementation = implementation;
resource->destroy = destroy;
pw_signal_emit(&client->resource_impl, client, resource);
return SPA_RESULT_OK;
@ -107,7 +103,7 @@ void pw_resource_destroy(struct pw_resource *resource)
resource->destroy(resource);
if (client->core_resource)
pw_core_notify_remove_id(client->core_resource, resource->id);
pw_core_resource_remove_id(client->core_resource, resource->id);
free(resource);
}

View file

@ -64,15 +64,16 @@ struct pw_resource {
struct pw_client *client; /**< owner client */
uint32_t id; /**< per client unique id, index in client objects */
uint32_t type; /**< type id of the object */
uint32_t client_version; /**< version of the client interface */
const struct pw_interface *iface; /**< protocol specific interface functions */
uint32_t type; /**< type of the client interface */
uint32_t version; /**< version of the client interface */
void *object;
const void *implementation;
void *object; /**< pointer to the object */
uint32_t version; /**< interface version */
const void *implementation; /**< method implementation */
pw_destroy_t destroy; /**< function to clean up the object */
const struct pw_protocol_marshal *marshal;
/** Emited when the resource is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_resource *resource));
@ -80,27 +81,27 @@ struct pw_resource {
void *user_data; /**< extra user data */
};
/** Make a new resource for client */
struct pw_resource *
pw_resource_new(struct pw_client *client,
uint32_t id,
uint32_t type,
uint32_t client_version,
size_t user_data_size);
pw_resource_new(struct pw_client *client, /**< the client owning the resource */
uint32_t id, /**< the remote per client id */
uint32_t type, /**< interface of the resource */
uint32_t version, /**< requested interface version */
size_t user_data_size, /**< extra user data size */
pw_destroy_t destroy /**< destroy function for user data */);
int
pw_resource_set_implementation(struct pw_resource *resource,
void *object,
uint32_t version,
const void *implementation,
pw_destroy_t destroy);
void *object, const void *implementation);
void
pw_resource_destroy(struct pw_resource *resource);
#define pw_resource_do(r,type,method,...) ((type*) r->implementation)->method(r, __VA_ARGS__)
#define pw_resource_do_na(r,type,method) ((type*) r->implementation)->method(r)
#define pw_resource_notify(r,type,event,...) ((type*) r->iface->events)->event(r, __VA_ARGS__)
#define pw_resource_notify_na(r,type,event) ((type*) r->iface->events)->event(r)
#define pw_resource_notify(r,type,event,...) ((type*) r->marshal->event_marshal)->event(r, __VA_ARGS__)
#define pw_resource_notify_na(r,type,event) ((type*) r->marshal->event_marshal)->event(r)
#ifdef __cplusplus
}

View file

@ -82,7 +82,7 @@ struct stream {
int rtwritefd;
struct spa_source *rtsocket_source;
struct pw_proxy *node_proxy;
struct pw_client_node_proxy *node_proxy;
bool disconnecting;
struct pw_listener node_proxy_destroy;
struct pw_listener node_proxy_sync_done;
@ -204,7 +204,7 @@ struct pw_stream *pw_stream_new(struct pw_remote *remote,
this->remote = remote;
this->name = strdup(name);
impl->type_client_node = spa_type_map_get_id(remote->core->type.map, PW_TYPE__ClientNode);
impl->type_client_node = spa_type_map_get_id(remote->core->type.map, PW_TYPE_INTERFACE__ClientNode);
pw_signal_init(&this->destroy_signal);
pw_signal_init(&this->state_changed);
@ -340,8 +340,8 @@ static void add_node_update(struct pw_stream *stream, uint32_t change_mask)
if (change_mask & PW_CLIENT_NODE_UPDATE_MAX_OUTPUTS)
max_output_ports = impl->direction == SPA_DIRECTION_OUTPUT ? 1 : 0;
pw_client_node_do_update(impl->node_proxy,
change_mask, max_input_ports, max_output_ports, NULL);
pw_client_node_proxy_update(impl->node_proxy,
change_mask, max_input_ports, max_output_ports, NULL);
}
static void add_port_update(struct pw_stream *stream, uint32_t change_mask)
@ -349,15 +349,15 @@ static void add_port_update(struct pw_stream *stream, uint32_t change_mask)
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
pw_client_node_do_port_update(impl->node_proxy,
impl->direction,
impl->port_id,
change_mask,
impl->n_possible_formats,
(const struct spa_format **) impl->possible_formats,
impl->format,
impl->n_params,
(const struct spa_param **) impl->params, &impl->port_info);
pw_client_node_proxy_port_update(impl->node_proxy,
impl->direction,
impl->port_id,
change_mask,
impl->n_possible_formats,
(const struct spa_format **) impl->possible_formats,
impl->format,
impl->n_params,
(const struct spa_param **) impl->params, &impl->port_info);
}
static inline void send_need_input(struct pw_stream *stream)
@ -386,19 +386,19 @@ static void add_request_clock_update(struct pw_stream *stream)
{
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
pw_client_node_do_event(impl->node_proxy, (struct spa_event *)
&SPA_EVENT_NODE_REQUEST_CLOCK_UPDATE_INIT(stream->remote->core->type.
event_node.
RequestClockUpdate,
SPA_EVENT_NODE_REQUEST_CLOCK_UPDATE_TIME,
0, 0));
pw_client_node_proxy_event(impl->node_proxy, (struct spa_event *)
&SPA_EVENT_NODE_REQUEST_CLOCK_UPDATE_INIT(stream->remote->core->type.
event_node.
RequestClockUpdate,
SPA_EVENT_NODE_REQUEST_CLOCK_UPDATE_TIME,
0, 0));
}
static void add_async_complete(struct pw_stream *stream, uint32_t seq, int res)
{
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
pw_client_node_do_done(impl->node_proxy, seq, res);
pw_client_node_proxy_done(impl->node_proxy, seq, res);
}
static void do_node_init(struct pw_stream *stream)
@ -862,6 +862,7 @@ static void client_node_transport(void *object, uint32_t node_id,
}
static const struct pw_client_node_events client_node_events = {
PW_VERSION_CLIENT_NODE_EVENTS,
&client_node_transport,
&client_node_set_props,
&client_node_event,
@ -913,27 +914,20 @@ pw_stream_connect(struct pw_stream *stream,
if (flags & PW_STREAM_FLAG_AUTOCONNECT)
pw_properties_set(stream->properties, "pipewire.autoconnect", "1");
impl->node_proxy = pw_proxy_new(stream->remote,
SPA_ID_INVALID,
impl->type_client_node,
0);
impl->node_proxy = pw_core_proxy_create_node(stream->remote->core_proxy,
"client-node",
"client-node",
impl->type_client_node,
PW_VERSION_CLIENT_NODE,
&stream->properties->dict, 0, NULL);
if (impl->node_proxy == NULL)
return false;
pw_proxy_set_implementation(impl->node_proxy, stream, PW_VERSION_CLIENT_NODE,
&client_node_events, NULL);
pw_client_node_proxy_add_listener(impl->node_proxy, stream, &client_node_events);
pw_signal_add(&impl->node_proxy->destroy_signal,
pw_signal_add(&impl->node_proxy->proxy.destroy_signal,
&impl->node_proxy_destroy, on_node_proxy_destroy);
pw_core_do_create_node(stream->remote->core_proxy,
"client-node",
"client-node",
&stream->properties->dict,
PW_VERSION_CLIENT_NODE,
impl->node_proxy->id);
do_node_init(stream);
return true;
@ -972,7 +966,7 @@ void pw_stream_disconnect(struct pw_stream *stream)
unhandle_socket(stream);
if (impl->node_proxy) {
pw_client_node_do_destroy(impl->node_proxy);
pw_client_node_proxy_destroy(impl->node_proxy);
impl->node_proxy = NULL;
}
}

View file

@ -39,13 +39,13 @@ void pw_type_init(struct pw_type *type)
{
type->map = pw_get_support_interface(SPA_TYPE__TypeMap);
type->core = spa_type_map_get_id(type->map, PW_TYPE__Core);
type->registry = spa_type_map_get_id(type->map, PW_TYPE__Registry);
type->node = spa_type_map_get_id(type->map, PW_TYPE__Node);
type->node_factory = spa_type_map_get_id(type->map, PW_TYPE__NodeFactory);
type->link = spa_type_map_get_id(type->map, PW_TYPE__Link);
type->client = spa_type_map_get_id(type->map, PW_TYPE__Client);
type->module = spa_type_map_get_id(type->map, PW_TYPE__Module);
type->core = spa_type_map_get_id(type->map, PW_TYPE_INTERFACE__Core);
type->registry = spa_type_map_get_id(type->map, PW_TYPE_INTERFACE__Registry);
type->node = spa_type_map_get_id(type->map, PW_TYPE_INTERFACE__Node);
type->node_factory = spa_type_map_get_id(type->map, PW_TYPE_INTERFACE__NodeFactory);
type->link = spa_type_map_get_id(type->map, PW_TYPE_INTERFACE__Link);
type->client = spa_type_map_get_id(type->map, PW_TYPE_INTERFACE__Client);
type->module = spa_type_map_get_id(type->map, PW_TYPE_INTERFACE__Module);
type->spa_log = spa_type_map_get_id(type->map, SPA_TYPE__Log);
type->spa_node = spa_type_map_get_id(type->map, SPA_TYPE__Node);

View file

@ -33,27 +33,13 @@ extern "C" {
#include <pipewire/map.h>
#include <pipewire/transport.h>
#define PW_TYPE__Object "PipeWire:Object"
#define PW_TYPE_BASE "PipeWire:"
#define PW_TYPE__Object PW_TYPE_BASE "Object"
#define PW_TYPE_OBJECT_BASE PW_TYPE__Object ":"
/** \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 {
const char *type; /**< interface type */
uint32_t version; /**< version */
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 */
};
#define PW_TYPE__Interface PW_TYPE_BASE "Interface"
#define PW_TYPE_INTERFACE_BASE PW_TYPE__Interface ":"
/** \class pw_type
* \brief PipeWire type support struct

View file

@ -31,13 +31,15 @@ struct data {
struct pw_loop *loop;
struct pw_core *core;
struct pw_remote *remote;
struct pw_proxy *registry_proxy;
struct pw_registry_proxy *registry_proxy;
struct pw_listener on_info_changed;
struct pw_listener on_state_changed;
};
struct proxy_data {
uint32_t id;
uint32_t version;
void *info;
};
@ -61,8 +63,7 @@ static void on_info_changed(struct pw_listener *listener, struct pw_remote *remo
struct pw_core_info *info = remote->info;
bool print_all = true, print_mark = false;
printf("\tid: %u\n", info->id);
printf("\ttype: %s\n", PW_TYPE__Core);
printf("\ttype: %s\n", PW_TYPE_INTERFACE__Core);
if (print_all) {
printf("%c\tuser-name: \"%s\"\n", MARK_CHANGE(0), info->user_name);
printf("%c\thost-name: \"%s\"\n", MARK_CHANGE(1), info->host_name);
@ -91,8 +92,8 @@ static void module_event_info(void *object, struct pw_module_info *info)
info = data->info = pw_module_info_update(data->info, info);
printf("\tid: %u\n", info->id);
printf("\ttype: %s\n", PW_TYPE__Module);
printf("\tid: %d\n", data->id);
printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Module, data->version);
if (print_all) {
printf("%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name);
printf("%c\tfilename: \"%s\"\n", MARK_CHANGE(1), info->filename);
@ -102,6 +103,7 @@ static void module_event_info(void *object, struct pw_module_info *info)
}
static const struct pw_module_events module_events = {
PW_VERSION_MODULE_EVENTS,
&module_event_info,
};
@ -123,8 +125,8 @@ static void node_event_info(void *object, struct pw_node_info *info)
info = data->info = pw_node_info_update(data->info, info);
printf("\tid: %u\n", info->id);
printf("\ttype: %s\n", PW_TYPE__Node);
printf("\tid: %d\n", data->id);
printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Node, data->version);
if (print_all) {
int i;
@ -149,6 +151,7 @@ static void node_event_info(void *object, struct pw_node_info *info)
}
static const struct pw_node_events node_events = {
PW_VERSION_NODE_EVENTS,
&node_event_info
};
@ -170,14 +173,15 @@ static void client_event_info(void *object, struct pw_client_info *info)
info = data->info = pw_client_info_update(data->info, info);
printf("\tid: %u\n", info->id);
printf("\ttype: %s\n", PW_TYPE__Client);
printf("\tid: %d\n", data->id);
printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Client, data->version);
if (print_all) {
print_properties(info->props, MARK_CHANGE(0));
}
}
static const struct pw_client_events client_events = {
PW_VERSION_CLIENT_EVENTS,
&client_event_info
};
@ -199,8 +203,8 @@ static void link_event_info(void *object, struct pw_link_info *info)
info = data->info = pw_link_info_update(data->info, info);
printf("\tid: %u\n", info->id);
printf("\ttype: %s\n", PW_TYPE__Link);
printf("\tid: %d\n", data->id);
printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Link, data->version);
if (print_all) {
printf("%c\toutput-node-id: %u\n", MARK_CHANGE(0), info->output_node_id);
printf("%c\toutput-port-id: %u\n", MARK_CHANGE(1), info->output_port_id);
@ -215,6 +219,7 @@ static void link_event_info(void *object, struct pw_link_info *info)
}
static const struct pw_link_events link_events = {
PW_VERSION_LINK_EVENTS,
&link_event_info
};
@ -222,21 +227,25 @@ static void
destroy_proxy (void *data)
{
struct pw_proxy *proxy = data;
struct pw_core *core = proxy->remote->core;
struct proxy_data *user_data = proxy->user_data;
struct pw_core *core = proxy->remote->core;
if (user_data->info == NULL)
return;
if (proxy->type == core->type.core) {
pw_core_info_free (user_data->info);
} else if (proxy->type == core->type.node) {
}
else if (proxy->type == core->type.node) {
pw_node_info_free (user_data->info);
} else if (proxy->type == core->type.module) {
}
else if (proxy->type == core->type.module) {
pw_module_info_free (user_data->info);
} else if (proxy->type == core->type.client) {
}
else if (proxy->type == core->type.client) {
pw_client_info_free (user_data->info);
} else if (proxy->type == core->type.link) {
}
else if (proxy->type == core->type.link) {
pw_link_info_free (user_data->info);
}
user_data->info = NULL;
@ -245,39 +254,45 @@ destroy_proxy (void *data)
static void registry_event_global(void *object, uint32_t id, uint32_t type, uint32_t version)
{
struct pw_proxy *registry_proxy = object;
struct data *data = registry_proxy->object;
struct pw_core *core = data->core;
struct pw_remote *remote = registry_proxy->remote;
struct pw_proxy *proxy = NULL;
struct pw_proxy *proxy = object;
struct data *data = proxy->object;
uint32_t client_version;
const void *implementation;
const void *events;
struct pw_core *core = data->core;
struct proxy_data *pd;
if (type == core->type.node) {
implementation = &node_events;
client_version = PW_VERSION_NODE;
if (type == core->type.node) {
events = &node_events;
client_version = PW_VERSION_NODE;
}
else if (type == core->type.module) {
implementation = &module_events;
client_version = PW_VERSION_MODULE;
events = &module_events;
client_version = PW_VERSION_MODULE;
}
else if (type == core->type.client) {
implementation = &client_events;
client_version = PW_VERSION_CLIENT;
events = &client_events;
client_version = PW_VERSION_CLIENT;
}
else if (type == core->type.link) {
implementation = &link_events;
client_version = PW_VERSION_LINK;
} else
return;
events = &link_events;
client_version = PW_VERSION_LINK;
}
else {
printf("added:\n");
printf("\tid: %u\n", id);
printf("\ttype: %s (version %d)\n", spa_type_map_get_type(core->type.map, type), version);
return;
}
proxy = pw_proxy_new(remote, SPA_ID_INVALID, type, sizeof(struct proxy_data));
proxy = pw_registry_proxy_bind(data->registry_proxy, id, type,
client_version, sizeof(struct proxy_data), destroy_proxy);
if (proxy == NULL)
goto no_mem;
pw_proxy_set_implementation(proxy, data, client_version, implementation, destroy_proxy);
pw_registry_do_bind(registry_proxy, id, version, proxy->id);
pd = proxy->user_data;
pd->id = id;
pd->version = version;
pw_proxy_add_listener(proxy, proxy, events);
return;
@ -293,6 +308,7 @@ static void registry_event_global_remove(void *object, uint32_t id)
}
static const struct pw_registry_events registry_events = {
PW_VERSION_REGISTRY_EVENTS,
registry_event_global,
registry_event_global_remove,
};
@ -310,16 +326,10 @@ static void on_state_changed(struct pw_listener *listener, struct pw_remote *rem
case PW_REMOTE_STATE_CONNECTED:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(remote->state));
data->registry_proxy = pw_proxy_new(data->remote,
SPA_ID_INVALID,
data->core->type.registry,
0);
pw_proxy_set_implementation(data->registry_proxy, data, PW_VERSION_REGISTRY,
&registry_events, NULL);
pw_core_do_get_registry(data->remote->core_proxy, PW_VERSION_REGISTRY,
data->registry_proxy->id);
data->registry_proxy = pw_core_proxy_get_registry(data->remote->core_proxy,
PW_VERSION_REGISTRY, 0, NULL);
pw_registry_proxy_add_listener(data->registry_proxy,
data, &registry_events);
break;
default: