mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-16 08:56:45 -05:00
monitor: Remove monitor event
Remove the monitor event and emit events with structures like we do for the devices.
This commit is contained in:
parent
3780bd1b30
commit
9785d99821
12 changed files with 268 additions and 422 deletions
|
|
@ -37,41 +37,34 @@ extern "C" {
|
||||||
#define SPA_VERSION_MONITOR 0
|
#define SPA_VERSION_MONITOR 0
|
||||||
struct spa_monitor { struct spa_interface iface; };
|
struct spa_monitor { struct spa_interface iface; };
|
||||||
|
|
||||||
enum spa_monitor_event {
|
struct spa_monitor_info {
|
||||||
SPA_MONITOR_EVENT_Invalid,
|
#define SPA_VERSION_MONITOR_INFO 0
|
||||||
SPA_MONITOR_EVENT_Added,
|
uint32_t version;
|
||||||
SPA_MONITOR_EVENT_Removed,
|
|
||||||
SPA_MONITOR_EVENT_Changed,
|
#define SPA_MONITOR_CHANGE_MASK_FLAGS (1u<<0)
|
||||||
|
#define SPA_MONITOR_CHANGE_MASK_PROPS (1u<<1)
|
||||||
|
uint64_t change_mask;
|
||||||
|
uint64_t flags;
|
||||||
|
const struct spa_dict *props;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** monitor event id, one of enum spa_monitor_event */
|
#define SPA_MONITOR_INFO_INIT() (struct spa_monitor_info){ SPA_VERSION_MONITOR_INFO, }
|
||||||
#define SPA_MONITOR_EVENT_ID(ev) SPA_EVENT_ID(ev, SPA_TYPE_EVENT_Monitor)
|
|
||||||
|
|
||||||
enum spa_monitor_item_flags {
|
struct spa_monitor_object_info {
|
||||||
SPA_MONITOR_ITEM_FLAG_NONE = 0,
|
#define SPA_VERSION_MONITOR_OBJECT_INFO 0
|
||||||
};
|
uint32_t version;
|
||||||
|
|
||||||
/** The monitor item state */
|
uint32_t type;
|
||||||
enum spa_monitor_item_state {
|
const struct spa_handle_factory *factory;
|
||||||
SPA_MONITOR_ITEM_STATE_Invalid, /*< The item is available */
|
|
||||||
SPA_MONITOR_ITEM_STATE_Available, /*< The item is available */
|
#define SPA_MONITOR_OBJECT_CHANGE_MASK_FLAGS (1u<<0)
|
||||||
SPA_MONITOR_ITEM_STATE_Disabled, /*< The item is disabled */
|
#define SPA_MONITOR_OBJECT_CHANGE_MASK_PROPS (1u<<1)
|
||||||
SPA_MONITOR_ITEM_STATE_Unavailable, /*< The item is unavailable */
|
uint64_t change_mask;
|
||||||
};
|
uint64_t flags;
|
||||||
|
const struct spa_dict *props;
|
||||||
/** properties for SPA_TYPE_OBJECT_MonitorItem */
|
|
||||||
enum spa_monitor_item {
|
|
||||||
SPA_MONITOR_ITEM_START, /**< id of object, one of enum spa_monitor_event */
|
|
||||||
SPA_MONITOR_ITEM_id,
|
|
||||||
SPA_MONITOR_ITEM_flags, /**< one of enum spa_monitor_item_flags */
|
|
||||||
SPA_MONITOR_ITEM_state, /**< one of enum spa_monitor_item_state */
|
|
||||||
SPA_MONITOR_ITEM_name,
|
|
||||||
SPA_MONITOR_ITEM_class,
|
|
||||||
SPA_MONITOR_ITEM_info,
|
|
||||||
SPA_MONITOR_ITEM_factory,
|
|
||||||
SPA_MONITOR_ITEM_type,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SPA_MONITOR_OBJECT_INFO_INIT() (struct spa_monitor_object_info){ SPA_VERSION_MONITOR_OBJECT_INFO, }
|
||||||
/**
|
/**
|
||||||
* spa_monitor_callbacks:
|
* spa_monitor_callbacks:
|
||||||
*/
|
*/
|
||||||
|
|
@ -81,10 +74,15 @@ struct spa_monitor_callbacks {
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
|
|
||||||
/** receive extra information about the monitor */
|
/** receive extra information about the monitor */
|
||||||
int (*info) (void *data, const struct spa_dict *info);
|
int (*info) (void *data, const struct spa_monitor_info *info);
|
||||||
|
|
||||||
/** an item is added/removed/changed on the monitor */
|
/** an item is added/removed/changed on the monitor */
|
||||||
int (*event) (void *data, const struct spa_event *event);
|
int (*event) (void *data, const struct spa_event *event);
|
||||||
|
|
||||||
|
/** info changed for an object managed by the monitor, info is NULL when
|
||||||
|
* the object is removed */
|
||||||
|
int (*object_info) (void *data, uint32_t id,
|
||||||
|
const struct spa_monitor_object_info *info);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,6 @@ extern "C" {
|
||||||
#define SPA_TYPE_INFO_MONITOR_EVENT_BASE SPA_TYPE_INFO_MonitorEvent ":"
|
#define SPA_TYPE_INFO_MONITOR_EVENT_BASE SPA_TYPE_INFO_MonitorEvent ":"
|
||||||
|
|
||||||
static const struct spa_type_info spa_type_monitor_event_id[] = {
|
static const struct spa_type_info spa_type_monitor_event_id[] = {
|
||||||
{ SPA_MONITOR_EVENT_Added, SPA_TYPE_Int, SPA_TYPE_INFO_MONITOR_EVENT_BASE "Added", NULL },
|
|
||||||
{ SPA_MONITOR_EVENT_Removed, SPA_TYPE_Int, SPA_TYPE_INFO_MONITOR_EVENT_BASE "Removed", NULL },
|
|
||||||
{ SPA_MONITOR_EVENT_Changed, SPA_TYPE_Int, SPA_TYPE_INFO_MONITOR_EVENT_BASE "Changed", NULL },
|
|
||||||
{ 0, 0, NULL, NULL },
|
{ 0, 0, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -47,42 +44,6 @@ static const struct spa_type_info spa_type_monitor_event[] = {
|
||||||
{ 0, 0, NULL, NULL },
|
{ 0, 0, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SPA_TYPE_INFO_MonitorItemFlags SPA_TYPE_INFO_FLAGS_BASE "MonitorItemFlags"
|
|
||||||
#define SPA_TYPE_INFO_MONITOR_ITEM_FLAGS_BASE SPA_TYPE_INFO_MonitorItemFlags ":"
|
|
||||||
|
|
||||||
static const struct spa_type_info spa_type_monitor_item_flags[] = {
|
|
||||||
{ SPA_MONITOR_ITEM_FLAG_NONE, SPA_TYPE_Int, SPA_TYPE_INFO_MONITOR_ITEM_FLAGS_BASE "none", NULL },
|
|
||||||
{ 0, 0, NULL, NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SPA_TYPE_INFO_MonitorItemState SPA_TYPE_INFO_ENUM_BASE "MonitorItemState"
|
|
||||||
#define SPA_TYPE_INFO_MONITOR_ITEM_STATE_BASE SPA_TYPE_INFO_MonitorItemState ":"
|
|
||||||
|
|
||||||
static const struct spa_type_info spa_type_monitor_item_state[] = {
|
|
||||||
{ SPA_MONITOR_ITEM_STATE_Available, SPA_TYPE_Int, SPA_TYPE_INFO_MONITOR_ITEM_STATE_BASE "Available", NULL },
|
|
||||||
{ SPA_MONITOR_ITEM_STATE_Disabled, SPA_TYPE_Int, SPA_TYPE_INFO_MONITOR_ITEM_STATE_BASE "Disabled", NULL },
|
|
||||||
{ SPA_MONITOR_ITEM_STATE_Unavailable, SPA_TYPE_Int, SPA_TYPE_INFO_MONITOR_ITEM_STATE_BASE "Unavailable", NULL },
|
|
||||||
{ 0, 0, NULL, NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SPA_TYPE_INFO_MonitorItem SPA_TYPE_INFO_OBJECT_BASE "MonitorItem"
|
|
||||||
#define SPA_TYPE_INFO_MONITOR_ITEM_BASE SPA_TYPE_INFO_MonitorItem ":"
|
|
||||||
|
|
||||||
static const struct spa_type_info spa_type_monitor_item[] = {
|
|
||||||
{ SPA_MONITOR_ITEM_START, SPA_TYPE_Int, SPA_TYPE_INFO_MONITOR_ITEM_BASE, NULL },
|
|
||||||
{ SPA_MONITOR_ITEM_id, SPA_TYPE_String, SPA_TYPE_INFO_MONITOR_ITEM_BASE "id", NULL },
|
|
||||||
{ SPA_MONITOR_ITEM_flags, SPA_TYPE_Id, SPA_TYPE_INFO_MONITOR_ITEM_BASE "flags",
|
|
||||||
spa_type_monitor_item_flags },
|
|
||||||
{ SPA_MONITOR_ITEM_state, SPA_TYPE_Id, SPA_TYPE_INFO_MONITOR_ITEM_BASE "state",
|
|
||||||
spa_type_monitor_item_state },
|
|
||||||
{ SPA_MONITOR_ITEM_name, SPA_TYPE_String, SPA_TYPE_INFO_MONITOR_ITEM_BASE "name", NULL },
|
|
||||||
{ SPA_MONITOR_ITEM_class, SPA_TYPE_String, SPA_TYPE_INFO_MONITOR_ITEM_BASE "class", NULL },
|
|
||||||
{ SPA_MONITOR_ITEM_info, SPA_TYPE_Pod, SPA_TYPE_INFO_MONITOR_ITEM_BASE "info", NULL },
|
|
||||||
{ SPA_MONITOR_ITEM_factory, SPA_TYPE_Pointer, SPA_TYPE_INFO_MONITOR_ITEM_BASE "factory", NULL },
|
|
||||||
{ SPA_MONITOR_ITEM_type, SPA_TYPE_Id, SPA_TYPE_INFO_MONITOR_ITEM_BASE "type", NULL },
|
|
||||||
{ 0, 0, NULL, NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ static inline int spa_device_enum_params_sync(struct spa_device *device,
|
||||||
|
|
||||||
#define spa_monitor_call_info(hook,i) spa_monitor_call(hook, info, 0, i)
|
#define spa_monitor_call_info(hook,i) spa_monitor_call(hook, info, 0, i)
|
||||||
#define spa_monitor_call_event(hook,e) spa_monitor_call(hook, event, 0, e)
|
#define spa_monitor_call_event(hook,e) spa_monitor_call(hook, event, 0, e)
|
||||||
|
#define spa_monitor_call_object_info(hook,id,i) spa_monitor_call(hook, object_info, 0, id, i)
|
||||||
|
|
||||||
#define spa_device_emit(hooks,method,version,...) \
|
#define spa_device_emit(hooks,method,version,...) \
|
||||||
spa_hook_list_call_simple(hooks, struct spa_device_events, \
|
spa_hook_list_call_simple(hooks, struct spa_device_events, \
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,6 @@ static const struct spa_type_info spa_types[] = {
|
||||||
{ SPA_TYPE_COMMAND_Node, SPA_TYPE_Object, SPA_TYPE_INFO_COMMAND_BASE "Node", spa_type_node_command },
|
{ SPA_TYPE_COMMAND_Node, SPA_TYPE_Object, SPA_TYPE_INFO_COMMAND_BASE "Node", spa_type_node_command },
|
||||||
|
|
||||||
{ SPA_TYPE_OBJECT_START, SPA_TYPE_Object, SPA_TYPE_INFO_Object, NULL },
|
{ SPA_TYPE_OBJECT_START, SPA_TYPE_Object, SPA_TYPE_INFO_Object, NULL },
|
||||||
{ SPA_TYPE_OBJECT_MonitorItem, SPA_TYPE_Object, SPA_TYPE_INFO_MonitorItem, spa_type_monitor_item },
|
|
||||||
{ SPA_TYPE_OBJECT_PropInfo, SPA_TYPE_Object, SPA_TYPE_INFO_PropInfo, spa_type_prop_info, },
|
{ SPA_TYPE_OBJECT_PropInfo, SPA_TYPE_Object, SPA_TYPE_INFO_PropInfo, spa_type_prop_info, },
|
||||||
{ SPA_TYPE_OBJECT_Props, SPA_TYPE_Object, SPA_TYPE_INFO_Props, spa_type_props },
|
{ SPA_TYPE_OBJECT_Props, SPA_TYPE_Object, SPA_TYPE_INFO_Props, spa_type_props },
|
||||||
{ SPA_TYPE_OBJECT_Format, SPA_TYPE_Object, SPA_TYPE_INFO_Format, spa_type_format },
|
{ SPA_TYPE_OBJECT_Format, SPA_TYPE_Object, SPA_TYPE_INFO_Format, spa_type_format },
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,6 @@ enum {
|
||||||
|
|
||||||
/* Objects */
|
/* Objects */
|
||||||
SPA_TYPE_OBJECT_START = 0x50000,
|
SPA_TYPE_OBJECT_START = 0x50000,
|
||||||
SPA_TYPE_OBJECT_MonitorItem,
|
|
||||||
SPA_TYPE_OBJECT_PropInfo,
|
SPA_TYPE_OBJECT_PropInfo,
|
||||||
SPA_TYPE_OBJECT_Props,
|
SPA_TYPE_OBJECT_Props,
|
||||||
SPA_TYPE_OBJECT_Format,
|
SPA_TYPE_OBJECT_Format,
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,10 @@
|
||||||
|
|
||||||
#define MAX_CARDS 64
|
#define MAX_CARDS 64
|
||||||
|
|
||||||
|
#define ACTION_ADD 0
|
||||||
|
#define ACTION_CHANGE 1
|
||||||
|
#define ACTION_REMOVE 2
|
||||||
|
|
||||||
extern const struct spa_handle_factory spa_alsa_device_factory;
|
extern const struct spa_handle_factory spa_alsa_device_factory;
|
||||||
|
|
||||||
struct impl {
|
struct impl {
|
||||||
|
|
@ -81,19 +85,6 @@ static int impl_udev_close(struct impl *this)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void add_dict(struct spa_pod_builder *builder, const char *key, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
va_start(args, key);
|
|
||||||
while (key) {
|
|
||||||
spa_pod_builder_string(builder, key);
|
|
||||||
spa_pod_builder_string(builder, va_arg(args, const char*));
|
|
||||||
key = va_arg(args, const char *);
|
|
||||||
}
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *path_get_card_id(const char *path)
|
static const char *path_get_card_id(const char *path)
|
||||||
{
|
{
|
||||||
const char *e;
|
const char *e;
|
||||||
|
|
@ -110,11 +101,20 @@ static const char *path_get_card_id(const char *path)
|
||||||
return e + 5;
|
return e + 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fill_item(struct impl *this, struct udev_device *dev,
|
static int emit_object_info(struct impl *this, uint32_t id, struct udev_device *dev)
|
||||||
struct spa_pod **result, struct spa_pod_builder *builder)
|
|
||||||
{
|
{
|
||||||
|
struct spa_monitor_object_info info;
|
||||||
const char *str, *name;
|
const char *str, *name;
|
||||||
struct spa_pod_frame f[2];
|
struct spa_dict_item items[20];
|
||||||
|
uint32_t n_items = 0;
|
||||||
|
|
||||||
|
info = SPA_MONITOR_OBJECT_INFO_INIT();
|
||||||
|
|
||||||
|
info.type = SPA_TYPE_INTERFACE_Device;
|
||||||
|
info.factory = &spa_alsa_device_factory;
|
||||||
|
info.change_mask = SPA_MONITOR_OBJECT_CHANGE_MASK_FLAGS |
|
||||||
|
SPA_MONITOR_OBJECT_CHANGE_MASK_PROPS;
|
||||||
|
info.flags = 0;
|
||||||
|
|
||||||
name = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE");
|
name = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE");
|
||||||
if (!(name && *name)) {
|
if (!(name && *name)) {
|
||||||
|
|
@ -126,54 +126,41 @@ static int fill_item(struct impl *this, struct udev_device *dev,
|
||||||
if (!(name && *name))
|
if (!(name && *name))
|
||||||
name = "Unknown";
|
name = "Unknown";
|
||||||
|
|
||||||
spa_pod_builder_push_object(builder, &f[0], SPA_TYPE_OBJECT_MonitorItem, 0);
|
items[n_items++] = SPA_DICT_ITEM_INIT("udev-probed", "1");
|
||||||
spa_pod_builder_add(builder,
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.path", udev_device_get_devnode(dev));
|
||||||
SPA_MONITOR_ITEM_id, SPA_POD_String(udev_device_get_syspath(dev)),
|
|
||||||
SPA_MONITOR_ITEM_flags, SPA_POD_Id(SPA_MONITOR_ITEM_FLAG_NONE),
|
|
||||||
SPA_MONITOR_ITEM_state, SPA_POD_Id(SPA_MONITOR_ITEM_STATE_Available),
|
|
||||||
SPA_MONITOR_ITEM_name, SPA_POD_String(name),
|
|
||||||
SPA_MONITOR_ITEM_class, SPA_POD_String("Audio/Device"),
|
|
||||||
SPA_MONITOR_ITEM_factory, SPA_POD_Pointer(SPA_TYPE_INTERFACE_HandleFactory, &spa_alsa_device_factory),
|
|
||||||
SPA_MONITOR_ITEM_type, SPA_POD_Id(SPA_TYPE_INTERFACE_Device),
|
|
||||||
0);
|
|
||||||
|
|
||||||
if ((str = path_get_card_id(udev_device_get_property_value(dev, "DEVPATH"))) == NULL)
|
if ((str = path_get_card_id(udev_device_get_property_value(dev, "DEVPATH"))) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
spa_pod_builder_prop(builder, SPA_MONITOR_ITEM_info, 0);
|
items[n_items++] = SPA_DICT_ITEM_INIT("alsa.card", str);
|
||||||
spa_pod_builder_push_struct(builder, &f[1]),
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.name", name);
|
||||||
add_dict(builder,
|
|
||||||
"udev-probed", "1",
|
|
||||||
"device.path", udev_device_get_devnode(dev),
|
|
||||||
"alsa.card", str,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if ((str = udev_device_get_property_value(dev, "SOUND_CLASS")) && *str)
|
if ((str = udev_device_get_property_value(dev, "SOUND_CLASS")) && *str)
|
||||||
add_dict(builder, "device.class", str, NULL);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.class", str);
|
||||||
|
|
||||||
if ((str = udev_device_get_property_value(dev, "USEC_INITIALIZED")) && *str)
|
if ((str = udev_device_get_property_value(dev, "USEC_INITIALIZED")) && *str)
|
||||||
add_dict(builder, "device.plugged.usec", str, NULL);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.plugged.usec", str);
|
||||||
|
|
||||||
str = udev_device_get_property_value(dev, "ID_PATH");
|
str = udev_device_get_property_value(dev, "ID_PATH");
|
||||||
if (!(str && *str))
|
if (!(str && *str))
|
||||||
str = udev_device_get_syspath(dev);
|
str = udev_device_get_syspath(dev);
|
||||||
if (str && *str) {
|
if (str && *str) {
|
||||||
add_dict(builder, "device.bus_path", str, 0);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.bus_path", str);
|
||||||
}
|
}
|
||||||
if ((str = udev_device_get_syspath(dev)) && *str) {
|
if ((str = udev_device_get_syspath(dev)) && *str) {
|
||||||
add_dict(builder, "sysfs.path", str, 0);
|
items[n_items++] = SPA_DICT_ITEM_INIT("sysfs.path", str);
|
||||||
}
|
}
|
||||||
if ((str = udev_device_get_property_value(dev, "ID_ID")) && *str) {
|
if ((str = udev_device_get_property_value(dev, "ID_ID")) && *str) {
|
||||||
add_dict(builder, "udev.id", str, 0);
|
items[n_items++] = SPA_DICT_ITEM_INIT("udev.id", str);
|
||||||
}
|
}
|
||||||
if ((str = udev_device_get_property_value(dev, "ID_BUS")) && *str) {
|
if ((str = udev_device_get_property_value(dev, "ID_BUS")) && *str) {
|
||||||
add_dict(builder, "device.bus", str, 0);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.bus", str);
|
||||||
}
|
}
|
||||||
if ((str = udev_device_get_property_value(dev, "SUBSYSTEM")) && *str) {
|
if ((str = udev_device_get_property_value(dev, "SUBSYSTEM")) && *str) {
|
||||||
add_dict(builder, "device.subsystem", str, 0);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.subsystem", str);
|
||||||
}
|
}
|
||||||
if ((str = udev_device_get_property_value(dev, "ID_VENDOR_ID")) && *str) {
|
if ((str = udev_device_get_property_value(dev, "ID_VENDOR_ID")) && *str) {
|
||||||
add_dict(builder, "device.vendor.id", str, 0);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.vendor.id", str);
|
||||||
}
|
}
|
||||||
str = udev_device_get_property_value(dev, "ID_VENDOR_FROM_DATABASE");
|
str = udev_device_get_property_value(dev, "ID_VENDOR_FROM_DATABASE");
|
||||||
if (!(str && *str)) {
|
if (!(str && *str)) {
|
||||||
|
|
@ -183,26 +170,27 @@ static int fill_item(struct impl *this, struct udev_device *dev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (str && *str) {
|
if (str && *str) {
|
||||||
add_dict(builder, "device.vendor.name", str, 0);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.vendor.name", str);
|
||||||
}
|
}
|
||||||
if ((str = udev_device_get_property_value(dev, "ID_MODEL_ID")) && *str) {
|
if ((str = udev_device_get_property_value(dev, "ID_MODEL_ID")) && *str) {
|
||||||
add_dict(builder, "device.product.id", str, 0);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.product.id", str);
|
||||||
}
|
}
|
||||||
add_dict(builder, "device.product.name", name, 0);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.product.name", name);
|
||||||
|
|
||||||
if ((str = udev_device_get_property_value(dev, "ID_SERIAL")) && *str) {
|
if ((str = udev_device_get_property_value(dev, "ID_SERIAL")) && *str) {
|
||||||
add_dict(builder, "device.serial", str, 0);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.serial", str);
|
||||||
}
|
}
|
||||||
if ((str = udev_device_get_property_value(dev, "SOUND_FORM_FACTOR")) && *str) {
|
if ((str = udev_device_get_property_value(dev, "SOUND_FORM_FACTOR")) && *str) {
|
||||||
add_dict(builder, "device.form_factor", str, 0);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.form_factor", str);
|
||||||
}
|
}
|
||||||
spa_pod_builder_pop(builder, &f[1]);
|
info.props = &SPA_DICT_INIT(items, n_items);
|
||||||
*result = spa_pod_builder_pop(builder, &f[0]);
|
spa_monitor_call_object_info(&this->callbacks, id, &info);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int need_notify(struct impl *this, struct udev_device *dev, uint32_t id, bool enumerated)
|
static int need_notify(struct impl *this, struct udev_device *dev, uint32_t action, bool enumerated,
|
||||||
|
uint32_t *id)
|
||||||
{
|
{
|
||||||
const char *str;
|
const char *str;
|
||||||
uint32_t idx, i, found = SPA_ID_INVALID;
|
uint32_t idx, i, found = SPA_ID_INVALID;
|
||||||
|
|
@ -225,8 +213,8 @@ static int need_notify(struct impl *this, struct udev_device *dev, uint32_t id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (id) {
|
switch (action) {
|
||||||
case SPA_MONITOR_EVENT_Added:
|
case ACTION_ADD:
|
||||||
if (found != SPA_ID_INVALID)
|
if (found != SPA_ID_INVALID)
|
||||||
return 0;
|
return 0;
|
||||||
if (this->n_cards >= MAX_CARDS)
|
if (this->n_cards >= MAX_CARDS)
|
||||||
|
|
@ -237,14 +225,14 @@ static int need_notify(struct impl *this, struct udev_device *dev, uint32_t id,
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPA_MONITOR_EVENT_Changed:
|
case ACTION_CHANGE:
|
||||||
if (found == SPA_ID_INVALID)
|
if (found == SPA_ID_INVALID)
|
||||||
return 0;
|
return 0;
|
||||||
if ((str = udev_device_get_property_value(dev, "SOUND_INITIALIZED")) == NULL)
|
if ((str = udev_device_get_property_value(dev, "SOUND_INITIALIZED")) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPA_MONITOR_EVENT_Removed:
|
case ACTION_REMOVE:
|
||||||
if (found == SPA_ID_INVALID)
|
if (found == SPA_ID_INVALID)
|
||||||
return 0;
|
return 0;
|
||||||
this->cards[found] = this->cards[--this->n_cards];
|
this->cards[found] = this->cards[--this->n_cards];
|
||||||
|
|
@ -252,21 +240,26 @@ static int need_notify(struct impl *this, struct udev_device *dev, uint32_t id,
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*id = idx;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int emit_device(struct impl *this, uint32_t id, struct udev_device *dev)
|
static int emit_device(struct impl *this, uint32_t action, bool enumerated, struct udev_device *dev)
|
||||||
{
|
{
|
||||||
uint8_t buffer[4096];
|
uint32_t id;
|
||||||
struct spa_pod_builder b = { NULL, };
|
|
||||||
struct spa_event *event;
|
|
||||||
struct spa_pod *item;
|
|
||||||
|
|
||||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
if (!need_notify(this, dev, action, enumerated, &id))
|
||||||
event = spa_pod_builder_add_object(&b, SPA_TYPE_EVENT_Monitor, id);
|
return 0;
|
||||||
fill_item(this, dev, &item, &b);
|
|
||||||
|
|
||||||
spa_monitor_call_event(&this->callbacks, event);
|
switch (action) {
|
||||||
|
case ACTION_ADD:
|
||||||
|
case ACTION_CHANGE:
|
||||||
|
emit_object_info(this, id, dev);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
spa_monitor_call_object_info(&this->callbacks, id, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -275,7 +268,7 @@ static void impl_on_fd_events(struct spa_source *source)
|
||||||
struct impl *this = source->data;
|
struct impl *this = source->data;
|
||||||
struct udev_device *dev;
|
struct udev_device *dev;
|
||||||
const char *action;
|
const char *action;
|
||||||
uint32_t id;
|
uint32_t a;
|
||||||
|
|
||||||
dev = udev_monitor_receive_device(this->umonitor);
|
dev = udev_monitor_receive_device(this->umonitor);
|
||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
|
|
@ -287,16 +280,15 @@ static void impl_on_fd_events(struct spa_source *source)
|
||||||
spa_log_debug(this->log, "action %s", action);
|
spa_log_debug(this->log, "action %s", action);
|
||||||
|
|
||||||
if (strcmp(action, "add") == 0) {
|
if (strcmp(action, "add") == 0) {
|
||||||
id = SPA_MONITOR_EVENT_Added;
|
a = ACTION_ADD;
|
||||||
} else if (strcmp(action, "change") == 0) {
|
} else if (strcmp(action, "change") == 0) {
|
||||||
id = SPA_MONITOR_EVENT_Changed;
|
a = ACTION_CHANGE;
|
||||||
} else if (strcmp(action, "remove") == 0) {
|
} else if (strcmp(action, "remove") == 0) {
|
||||||
id = SPA_MONITOR_EVENT_Removed;
|
a = ACTION_REMOVE;
|
||||||
} else
|
} else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (need_notify(this, dev, id, false))
|
emit_device(this, a, false, dev);
|
||||||
emit_device(this, id, dev);
|
|
||||||
|
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
}
|
}
|
||||||
|
|
@ -354,8 +346,7 @@ static int enum_devices(struct impl *this)
|
||||||
|
|
||||||
dev = udev_device_new_from_syspath(this->udev, udev_list_entry_get_name(devices));
|
dev = udev_device_new_from_syspath(this->udev, udev_list_entry_get_name(devices));
|
||||||
|
|
||||||
if (need_notify(this, dev, SPA_MONITOR_EVENT_Added, true))
|
emit_device(this, ACTION_ADD, true, dev);
|
||||||
emit_device(this, SPA_MONITOR_EVENT_Added, dev);
|
|
||||||
|
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ struct spa_bt_monitor {
|
||||||
struct spa_callbacks callbacks;
|
struct spa_callbacks callbacks;
|
||||||
|
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
struct spa_list adapter_list;
|
struct spa_list adapter_list;
|
||||||
struct spa_list device_list;
|
struct spa_list device_list;
|
||||||
|
|
@ -82,39 +83,6 @@ static inline void add_dict(struct spa_pod_builder *builder, const char *key, co
|
||||||
spa_pod_builder_string(builder, val);
|
spa_pod_builder_string(builder, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fill_item(struct spa_bt_monitor *this, struct spa_bt_device *device,
|
|
||||||
struct spa_pod **result, struct spa_pod_builder *builder)
|
|
||||||
{
|
|
||||||
char dev[16];
|
|
||||||
struct spa_pod_frame f[2];
|
|
||||||
|
|
||||||
spa_pod_builder_push_object(builder, &f[0], SPA_TYPE_OBJECT_MonitorItem, 0);
|
|
||||||
spa_pod_builder_add(builder,
|
|
||||||
SPA_MONITOR_ITEM_id, SPA_POD_String(device->path),
|
|
||||||
SPA_MONITOR_ITEM_flags, SPA_POD_Id(SPA_MONITOR_ITEM_FLAG_NONE),
|
|
||||||
SPA_MONITOR_ITEM_state, SPA_POD_Id(SPA_MONITOR_ITEM_STATE_Available),
|
|
||||||
SPA_MONITOR_ITEM_name, SPA_POD_String(device->name),
|
|
||||||
SPA_MONITOR_ITEM_class, SPA_POD_String("Adapter/Bluetooth"),
|
|
||||||
SPA_MONITOR_ITEM_factory, SPA_POD_Pointer(SPA_TYPE_INTERFACE_HandleFactory,
|
|
||||||
&spa_bluez5_device_factory),
|
|
||||||
SPA_MONITOR_ITEM_type, SPA_POD_Id(SPA_TYPE_INTERFACE_Device),
|
|
||||||
0);
|
|
||||||
|
|
||||||
spa_pod_builder_prop(builder, SPA_MONITOR_ITEM_info, 0);
|
|
||||||
spa_pod_builder_push_struct(builder, &f[1]);
|
|
||||||
snprintf(dev, sizeof(dev), "%p", device);
|
|
||||||
|
|
||||||
add_dict(builder, "device.api", "bluez5");
|
|
||||||
add_dict(builder, "device.name", device->name);
|
|
||||||
add_dict(builder, "device.alias", device->alias);
|
|
||||||
add_dict(builder, "device.icon", device->icon);
|
|
||||||
add_dict(builder, "device.bluez5.address", device->address);
|
|
||||||
add_dict(builder, "bluez5.device", dev);
|
|
||||||
|
|
||||||
spa_pod_builder_pop(builder, &f[1]);
|
|
||||||
*result = spa_pod_builder_pop(builder, &f[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t a2dp_default_bitpool(struct spa_bt_monitor *monitor, uint8_t freq, uint8_t mode) {
|
static uint8_t a2dp_default_bitpool(struct spa_bt_monitor *monitor, uint8_t freq, uint8_t mode) {
|
||||||
/* These bitpool values were chosen based on the A2DP spec recommendation */
|
/* These bitpool values were chosen based on the A2DP spec recommendation */
|
||||||
switch (freq) {
|
switch (freq) {
|
||||||
|
|
@ -489,6 +457,7 @@ static struct spa_bt_device *device_create(struct spa_bt_monitor *monitor, const
|
||||||
if (d == NULL)
|
if (d == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
d->id = monitor->id++;
|
||||||
d->monitor = monitor;
|
d->monitor = monitor;
|
||||||
d->path = strdup(path);
|
d->path = strdup(path);
|
||||||
spa_list_init(&d->transport_list);
|
spa_list_init(&d->transport_list);
|
||||||
|
|
@ -521,40 +490,45 @@ static int device_free(struct spa_bt_device *device)
|
||||||
|
|
||||||
static int device_add(struct spa_bt_monitor *monitor, struct spa_bt_device *device)
|
static int device_add(struct spa_bt_monitor *monitor, struct spa_bt_device *device)
|
||||||
{
|
{
|
||||||
struct spa_event *event;
|
struct spa_monitor_object_info info;
|
||||||
struct spa_pod_builder b = { NULL, };
|
char dev[16];
|
||||||
uint8_t buffer[4096];
|
struct spa_dict_item items[20];
|
||||||
struct spa_pod *item;
|
uint32_t n_items = 0;
|
||||||
|
|
||||||
if (device->added)
|
if (device->added)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
info = SPA_MONITOR_OBJECT_INFO_INIT();
|
||||||
event = spa_pod_builder_add_object(&b, SPA_TYPE_EVENT_Monitor, SPA_MONITOR_EVENT_Added);
|
info.type = SPA_TYPE_INTERFACE_Device;
|
||||||
fill_item(monitor, device, &item, &b);
|
info.factory = &spa_bluez5_device_factory;
|
||||||
|
info.change_mask = SPA_MONITOR_OBJECT_CHANGE_MASK_FLAGS |
|
||||||
|
SPA_MONITOR_OBJECT_CHANGE_MASK_PROPS;
|
||||||
|
info.flags = 0;
|
||||||
|
|
||||||
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.path", device->path);
|
||||||
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.name", device->name);
|
||||||
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.api", "bluez5");
|
||||||
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.alias", device->alias);
|
||||||
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.icon", device->icon);
|
||||||
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.bluez5.address", device->address);
|
||||||
|
snprintf(dev, sizeof(dev), "%p", device);
|
||||||
|
items[n_items++] = SPA_DICT_ITEM_INIT("bluez5.device", dev);
|
||||||
|
|
||||||
|
info.props = &SPA_DICT_INIT(items, n_items);
|
||||||
|
|
||||||
device->added = true;
|
device->added = true;
|
||||||
spa_monitor_call_event(&monitor->callbacks, event);
|
spa_monitor_call_object_info(&monitor->callbacks, device->id, &info);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int device_remove(struct spa_bt_monitor *monitor, struct spa_bt_device *device)
|
static int device_remove(struct spa_bt_monitor *monitor, struct spa_bt_device *device)
|
||||||
{
|
{
|
||||||
struct spa_event *event;
|
|
||||||
struct spa_pod_builder b = { NULL, };
|
|
||||||
uint8_t buffer[4096];
|
|
||||||
struct spa_pod *item;
|
|
||||||
|
|
||||||
if (!device->added)
|
if (!device->added)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
|
||||||
event = spa_pod_builder_add_object(&b, SPA_TYPE_EVENT_Monitor, SPA_MONITOR_EVENT_Removed);
|
|
||||||
fill_item(monitor, device, &item, &b);
|
|
||||||
|
|
||||||
device->added = false;
|
device->added = false;
|
||||||
spa_monitor_call_event(&monitor->callbacks, event);
|
spa_monitor_call_object_info(&monitor->callbacks, device->id, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,7 @@ struct spa_bt_device {
|
||||||
struct spa_list link;
|
struct spa_list link;
|
||||||
struct spa_bt_monitor *monitor;
|
struct spa_bt_monitor *monitor;
|
||||||
struct spa_bt_adapter *adapter;
|
struct spa_bt_adapter *adapter;
|
||||||
|
uint32_t id;
|
||||||
char *path;
|
char *path;
|
||||||
char *alias;
|
char *alias;
|
||||||
char *address;
|
char *address;
|
||||||
|
|
|
||||||
|
|
@ -74,17 +74,36 @@ static int impl_udev_close(struct impl *this)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void add_dict(struct spa_pod_builder *builder, const char *key, const char *val)
|
static uint32_t get_device_id(struct impl *this, struct udev_device *dev)
|
||||||
{
|
{
|
||||||
spa_pod_builder_string(builder, key);
|
const char *str;
|
||||||
spa_pod_builder_string(builder, val);
|
|
||||||
|
if ((str = udev_device_get_devnode(dev)) == NULL)
|
||||||
|
return SPA_ID_INVALID;
|
||||||
|
|
||||||
|
if (!(str = strrchr(str, '/')))
|
||||||
|
return SPA_ID_INVALID;
|
||||||
|
|
||||||
|
if (strlen(str) <= 6 || strncmp(str, "/video", 6) != 0)
|
||||||
|
return SPA_ID_INVALID;
|
||||||
|
|
||||||
|
return atoi(str + 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fill_item(struct impl *this, struct udev_device *dev,
|
static int emit_object_info(struct impl *this, uint32_t id, struct udev_device *dev)
|
||||||
struct spa_pod **result, struct spa_pod_builder *builder)
|
|
||||||
{
|
{
|
||||||
|
struct spa_monitor_object_info info;
|
||||||
const char *str, *name;
|
const char *str, *name;
|
||||||
struct spa_pod_frame f[2];
|
struct spa_dict_item items[20];
|
||||||
|
uint32_t n_items = 0;
|
||||||
|
|
||||||
|
info = SPA_MONITOR_OBJECT_INFO_INIT();
|
||||||
|
|
||||||
|
info.type = SPA_TYPE_INTERFACE_Device;
|
||||||
|
info.factory = &spa_v4l2_device_factory;
|
||||||
|
info.change_mask = SPA_MONITOR_OBJECT_CHANGE_MASK_FLAGS |
|
||||||
|
SPA_MONITOR_OBJECT_CHANGE_MASK_PROPS;
|
||||||
|
info.flags = 0;
|
||||||
|
|
||||||
name = udev_device_get_property_value(dev, "ID_V4L_PRODUCT");
|
name = udev_device_get_property_value(dev, "ID_V4L_PRODUCT");
|
||||||
if (!(name && *name)) {
|
if (!(name && *name)) {
|
||||||
|
|
@ -99,45 +118,33 @@ static void fill_item(struct impl *this, struct udev_device *dev,
|
||||||
if (!(name && *name))
|
if (!(name && *name))
|
||||||
name = "Unknown";
|
name = "Unknown";
|
||||||
|
|
||||||
spa_pod_builder_push_object(builder, &f[0], SPA_TYPE_OBJECT_MonitorItem, 0);
|
items[n_items++] = SPA_DICT_ITEM_INIT("udev-probed", "1");
|
||||||
spa_pod_builder_add(builder,
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.path", udev_device_get_devnode(dev));
|
||||||
SPA_MONITOR_ITEM_id, SPA_POD_String(udev_device_get_syspath(dev)),
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.name", name);
|
||||||
SPA_MONITOR_ITEM_flags, SPA_POD_Id(SPA_MONITOR_ITEM_FLAG_NONE),
|
|
||||||
SPA_MONITOR_ITEM_state, SPA_POD_Id(SPA_MONITOR_ITEM_STATE_Available),
|
|
||||||
SPA_MONITOR_ITEM_name, SPA_POD_String(name),
|
|
||||||
SPA_MONITOR_ITEM_class, SPA_POD_String("Video/Device"),
|
|
||||||
SPA_MONITOR_ITEM_factory, SPA_POD_Pointer(SPA_TYPE_INTERFACE_HandleFactory, &spa_v4l2_device_factory),
|
|
||||||
SPA_MONITOR_ITEM_type, SPA_POD_Id(SPA_TYPE_INTERFACE_Device),
|
|
||||||
0);
|
|
||||||
|
|
||||||
spa_pod_builder_prop(builder, SPA_MONITOR_ITEM_info, 0);
|
|
||||||
spa_pod_builder_push_struct(builder, &f[1]);
|
|
||||||
add_dict(builder, "udev-probed", "1");
|
|
||||||
add_dict(builder, "device.path", udev_device_get_devnode(dev));
|
|
||||||
|
|
||||||
if ((str = udev_device_get_property_value(dev, "USEC_INITIALIZED")) && *str)
|
if ((str = udev_device_get_property_value(dev, "USEC_INITIALIZED")) && *str)
|
||||||
add_dict(builder, "device.plugged.usec", str);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.plugged.usec", str);
|
||||||
|
|
||||||
str = udev_device_get_property_value(dev, "ID_PATH");
|
str = udev_device_get_property_value(dev, "ID_PATH");
|
||||||
if (!(str && *str))
|
if (!(str && *str))
|
||||||
str = udev_device_get_syspath(dev);
|
str = udev_device_get_syspath(dev);
|
||||||
if (str && *str) {
|
if (str && *str) {
|
||||||
add_dict(builder, "device.bus_path", str);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.bus_path", str);
|
||||||
}
|
}
|
||||||
if ((str = udev_device_get_syspath(dev)) && *str) {
|
if ((str = udev_device_get_syspath(dev)) && *str) {
|
||||||
add_dict(builder, "sysfs.path", str);
|
items[n_items++] = SPA_DICT_ITEM_INIT("sysfs.path", str);
|
||||||
}
|
}
|
||||||
if ((str = udev_device_get_property_value(dev, "ID_ID")) && *str) {
|
if ((str = udev_device_get_property_value(dev, "ID_ID")) && *str) {
|
||||||
add_dict(builder, "udev.id", str);
|
items[n_items++] = SPA_DICT_ITEM_INIT("udev.id", str);
|
||||||
}
|
}
|
||||||
if ((str = udev_device_get_property_value(dev, "ID_BUS")) && *str) {
|
if ((str = udev_device_get_property_value(dev, "ID_BUS")) && *str) {
|
||||||
add_dict(builder, "device.bus", str);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.bus", str);
|
||||||
}
|
}
|
||||||
if ((str = udev_device_get_property_value(dev, "SUBSYSTEM")) && *str) {
|
if ((str = udev_device_get_property_value(dev, "SUBSYSTEM")) && *str) {
|
||||||
add_dict(builder, "device.subsystem", str);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.subsystem", str);
|
||||||
}
|
}
|
||||||
if ((str = udev_device_get_property_value(dev, "ID_VENDOR_ID")) && *str) {
|
if ((str = udev_device_get_property_value(dev, "ID_VENDOR_ID")) && *str) {
|
||||||
add_dict(builder, "device.vendor.id", str);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.vendor.id", str);
|
||||||
}
|
}
|
||||||
str = udev_device_get_property_value(dev, "ID_VENDOR_FROM_DATABASE");
|
str = udev_device_get_property_value(dev, "ID_VENDOR_FROM_DATABASE");
|
||||||
if (!(str && *str)) {
|
if (!(str && *str)) {
|
||||||
|
|
@ -147,36 +154,22 @@ static void fill_item(struct impl *this, struct udev_device *dev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (str && *str) {
|
if (str && *str) {
|
||||||
add_dict(builder, "device.vendor.name", str);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.vendor.name", str);
|
||||||
}
|
}
|
||||||
if ((str = udev_device_get_property_value(dev, "ID_MODEL_ID")) && *str) {
|
if ((str = udev_device_get_property_value(dev, "ID_MODEL_ID")) && *str) {
|
||||||
add_dict(builder, "device.product.id", str);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.product.id", str);
|
||||||
}
|
}
|
||||||
add_dict(builder, "device.product.name", name);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.product.name", name);
|
||||||
if ((str = udev_device_get_property_value(dev, "ID_SERIAL")) && *str) {
|
if ((str = udev_device_get_property_value(dev, "ID_SERIAL")) && *str) {
|
||||||
add_dict(builder, "device.serial", str);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.serial", str);
|
||||||
}
|
}
|
||||||
if ((str = udev_device_get_property_value(dev, "ID_V4L_CAPABILITIES")) && *str) {
|
if ((str = udev_device_get_property_value(dev, "ID_V4L_CAPABILITIES")) && *str) {
|
||||||
add_dict(builder, "device.capabilities", str);
|
items[n_items++] = SPA_DICT_ITEM_INIT("device.capabilities", str);
|
||||||
}
|
}
|
||||||
|
info.props = &SPA_DICT_INIT(items, n_items);
|
||||||
|
spa_monitor_call_object_info(&this->callbacks, id, &info);
|
||||||
|
|
||||||
spa_pod_builder_pop(builder, &f[1]);
|
return 1;
|
||||||
*result = spa_pod_builder_pop(builder, &f[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int emit_device(struct impl *this, uint32_t id, struct udev_device *dev)
|
|
||||||
{
|
|
||||||
uint8_t buffer[4096];
|
|
||||||
struct spa_pod_builder b = { NULL, };
|
|
||||||
struct spa_event *event;
|
|
||||||
struct spa_pod *item;
|
|
||||||
|
|
||||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
|
||||||
event = spa_pod_builder_add_object(&b, SPA_TYPE_EVENT_Monitor, id);
|
|
||||||
fill_item(this, dev, &item, &b);
|
|
||||||
|
|
||||||
spa_monitor_call_event(&this->callbacks, event);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void impl_on_fd_events(struct spa_source *source)
|
static void impl_on_fd_events(struct spa_source *source)
|
||||||
|
|
@ -190,20 +183,18 @@ static void impl_on_fd_events(struct spa_source *source)
|
||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if ((id = get_device_id(this, dev)) == SPA_ID_INVALID)
|
||||||
|
return;
|
||||||
|
|
||||||
if ((action = udev_device_get_action(dev)) == NULL)
|
if ((action = udev_device_get_action(dev)) == NULL)
|
||||||
action = "change";
|
action = "change";
|
||||||
|
|
||||||
if (strcmp(action, "add") == 0) {
|
if (strcmp(action, "add") == 0 ||
|
||||||
id = SPA_MONITOR_EVENT_Added;
|
strcmp(action, "change") == 0) {
|
||||||
} else if (strcmp(action, "change") == 0) {
|
emit_object_info(this, id, dev);
|
||||||
id = SPA_MONITOR_EVENT_Changed;
|
} else {
|
||||||
} else if (strcmp(action, "remove") == 0) {
|
spa_monitor_call_object_info(&this->callbacks, id, NULL);
|
||||||
id = SPA_MONITOR_EVENT_Removed;
|
}
|
||||||
} else
|
|
||||||
return;
|
|
||||||
|
|
||||||
emit_device(this, id, dev);
|
|
||||||
|
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,10 +249,16 @@ static int enum_devices(struct impl *this)
|
||||||
|
|
||||||
while (devices) {
|
while (devices) {
|
||||||
struct udev_device *dev;
|
struct udev_device *dev;
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
dev = udev_device_new_from_syspath(this->udev, udev_list_entry_get_name(devices));
|
dev = udev_device_new_from_syspath(this->udev, udev_list_entry_get_name(devices));
|
||||||
|
if (dev == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
emit_device(this, SPA_MONITOR_EVENT_Added, dev);
|
if ((id = get_device_id(this, dev)) == SPA_ID_INVALID)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
emit_object_info(this, id, dev);
|
||||||
|
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,15 +111,14 @@ static void test_abi(void)
|
||||||
spa_assert(SPA_TYPE_COMMAND_LAST == 0x40002);
|
spa_assert(SPA_TYPE_COMMAND_LAST == 0x40002);
|
||||||
|
|
||||||
spa_assert(SPA_TYPE_OBJECT_START == 0x50000);
|
spa_assert(SPA_TYPE_OBJECT_START == 0x50000);
|
||||||
spa_assert(SPA_TYPE_OBJECT_MonitorItem == 0x50001);
|
spa_assert(SPA_TYPE_OBJECT_PropInfo == 0x50001);
|
||||||
spa_assert(SPA_TYPE_OBJECT_PropInfo == 0x50002);
|
spa_assert(SPA_TYPE_OBJECT_Props == 0x50002);
|
||||||
spa_assert(SPA_TYPE_OBJECT_Props == 0x50003);
|
spa_assert(SPA_TYPE_OBJECT_Format == 0x50003);
|
||||||
spa_assert(SPA_TYPE_OBJECT_Format == 0x50004);
|
spa_assert(SPA_TYPE_OBJECT_ParamBuffers == 0x50004);
|
||||||
spa_assert(SPA_TYPE_OBJECT_ParamBuffers == 0x50005);
|
spa_assert(SPA_TYPE_OBJECT_ParamMeta == 0x50005);
|
||||||
spa_assert(SPA_TYPE_OBJECT_ParamMeta == 0x50006);
|
spa_assert(SPA_TYPE_OBJECT_ParamIO == 0x50006);
|
||||||
spa_assert(SPA_TYPE_OBJECT_ParamIO == 0x50007);
|
spa_assert(SPA_TYPE_OBJECT_ParamProfile == 0x50007);
|
||||||
spa_assert(SPA_TYPE_OBJECT_ParamProfile == 0x50008);
|
spa_assert(SPA_TYPE_OBJECT_LAST == 0x50008);
|
||||||
spa_assert(SPA_TYPE_OBJECT_LAST == 0x50009);
|
|
||||||
|
|
||||||
spa_assert(SPA_TYPE_VENDOR_PipeWire == 0x02000000);
|
spa_assert(SPA_TYPE_VENDOR_PipeWire == 0x02000000);
|
||||||
spa_assert(SPA_TYPE_VENDOR_Other == 0x7f000000);
|
spa_assert(SPA_TYPE_VENDOR_Other == 0x7f000000);
|
||||||
|
|
|
||||||
|
|
@ -56,34 +56,27 @@ struct data {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void inspect_item(struct data *data, struct spa_pod *item)
|
static void inspect_info(struct data *data, const struct spa_monitor_object_info *info)
|
||||||
{
|
{
|
||||||
spa_debug_pod(0, NULL, item);
|
spa_debug_dict(0, info->props);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_monitor_info(void *_data, const struct spa_dict *info)
|
static int on_monitor_info(void *_data, const struct spa_monitor_info *info)
|
||||||
{
|
{
|
||||||
spa_debug_dict(0, info);
|
spa_debug_dict(0, info->props);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_monitor_event(void *_data, const struct spa_event *event)
|
static int on_monitor_object_info(void *_data, uint32_t id, const struct spa_monitor_object_info *info)
|
||||||
{
|
{
|
||||||
struct data *data = _data;
|
struct data *data = _data;
|
||||||
|
|
||||||
switch (SPA_MONITOR_EVENT_ID(event)) {
|
if (info == NULL) {
|
||||||
case SPA_MONITOR_EVENT_Added:
|
fprintf(stderr, "removed: %u\n", id);
|
||||||
fprintf(stderr, "added:\n");
|
}
|
||||||
inspect_item(data, SPA_POD_CONTENTS(struct spa_event, event));
|
else {
|
||||||
break;
|
fprintf(stderr, "added/changed: %u\n", id);
|
||||||
case SPA_MONITOR_EVENT_Removed:
|
inspect_info(data, info);
|
||||||
fprintf(stderr, "removed:\n");
|
|
||||||
inspect_item(data, SPA_POD_CONTENTS(struct spa_event, event));
|
|
||||||
break;
|
|
||||||
case SPA_MONITOR_EVENT_Changed:
|
|
||||||
fprintf(stderr, "changed:\n");
|
|
||||||
inspect_item(data, SPA_POD_CONTENTS(struct spa_event, event));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -107,7 +100,7 @@ static const struct spa_loop_methods impl_loop = {
|
||||||
static const struct spa_monitor_callbacks impl_callbacks = {
|
static const struct spa_monitor_callbacks impl_callbacks = {
|
||||||
SPA_VERSION_MONITOR_CALLBACKS,
|
SPA_VERSION_MONITOR_CALLBACKS,
|
||||||
.info = on_monitor_info,
|
.info = on_monitor_info,
|
||||||
.event = on_monitor_event,
|
.object_info = on_monitor_object_info,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void handle_monitor(struct data *data, struct spa_monitor *monitor)
|
static void handle_monitor(struct data *data, struct spa_monitor *monitor)
|
||||||
|
|
|
||||||
|
|
@ -48,12 +48,12 @@
|
||||||
#include "spa-monitor.h"
|
#include "spa-monitor.h"
|
||||||
#include "spa-device.h"
|
#include "spa-device.h"
|
||||||
|
|
||||||
struct monitor_item {
|
struct monitor_object {
|
||||||
char *id;
|
uint32_t id;
|
||||||
|
char *name;
|
||||||
struct spa_list link;
|
struct spa_list link;
|
||||||
struct spa_handle *handle;
|
struct spa_handle *handle;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
void *iface;
|
|
||||||
void *object;
|
void *object;
|
||||||
struct spa_hook object_listener;
|
struct spa_hook object_listener;
|
||||||
};
|
};
|
||||||
|
|
@ -69,13 +69,12 @@ struct impl {
|
||||||
|
|
||||||
static void device_free(void *data)
|
static void device_free(void *data)
|
||||||
{
|
{
|
||||||
struct monitor_item *mitem = data;
|
struct monitor_object *obj = data;
|
||||||
spa_hook_remove(&mitem->object_listener);
|
spa_hook_remove(&obj->object_listener);
|
||||||
spa_list_remove(&mitem->link);
|
spa_list_remove(&obj->link);
|
||||||
spa_handle_clear(mitem->handle);
|
spa_handle_clear(obj->handle);
|
||||||
free(mitem->handle);
|
free(obj->handle);
|
||||||
free(mitem->id);
|
free(obj);
|
||||||
free(mitem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pw_device_events device_events = {
|
static const struct pw_device_events device_events = {
|
||||||
|
|
@ -83,56 +82,28 @@ static const struct pw_device_events device_events = {
|
||||||
.free = device_free
|
.free = device_free
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct monitor_item *add_item(struct pw_spa_monitor *this,
|
static struct monitor_object *add_object(struct pw_spa_monitor *this, uint32_t id,
|
||||||
struct spa_pod *item, uint64_t now)
|
const struct spa_monitor_object_info *info, uint64_t now)
|
||||||
{
|
{
|
||||||
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
|
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
|
||||||
int res;
|
int res;
|
||||||
struct spa_handle *handle;
|
struct spa_handle *handle;
|
||||||
struct monitor_item *mitem;
|
struct monitor_object *obj;
|
||||||
|
const char *name, *str;
|
||||||
void *iface;
|
void *iface;
|
||||||
struct pw_properties *props = NULL;
|
struct pw_properties *props = NULL;
|
||||||
const char *name, *id, *klass, *str;
|
|
||||||
struct spa_handle_factory *factory;
|
|
||||||
enum spa_monitor_item_state state;
|
|
||||||
struct spa_pod *info = NULL;
|
|
||||||
const struct spa_support *support;
|
const struct spa_support *support;
|
||||||
uint32_t n_support, type, ftype;
|
uint32_t n_support;
|
||||||
|
|
||||||
if (spa_pod_parse_object(item,
|
if (info->props)
|
||||||
SPA_TYPE_OBJECT_MonitorItem, NULL,
|
props = pw_properties_new_dict(info->props);
|
||||||
SPA_MONITOR_ITEM_id, SPA_POD_String(&id),
|
else
|
||||||
SPA_MONITOR_ITEM_state, SPA_POD_Id(&state),
|
props = pw_properties_new(NULL, NULL);
|
||||||
SPA_MONITOR_ITEM_name, SPA_POD_String(&name),
|
|
||||||
SPA_MONITOR_ITEM_class, SPA_POD_String(&klass),
|
|
||||||
SPA_MONITOR_ITEM_factory, SPA_POD_Pointer(&ftype, &factory),
|
|
||||||
SPA_MONITOR_ITEM_type, SPA_POD_Id(&type),
|
|
||||||
SPA_MONITOR_ITEM_info, SPA_POD_Pod(&info)) < 0) {
|
|
||||||
pw_log_warn("monitor %p: could not parse item", this);
|
|
||||||
spa_debug_pod(0, NULL, item);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pw_log_debug("monitor %p: add: \"%s\" (%s)", this, name, id);
|
if ((name = pw_properties_get(props, PW_KEY_DEVICE_NAME)) == NULL)
|
||||||
|
name = "unknown";
|
||||||
|
|
||||||
props = pw_properties_new(NULL, NULL);
|
pw_log_debug("monitor %p: add: \"%s\" (%u)", this, name, id);
|
||||||
|
|
||||||
if (info) {
|
|
||||||
struct spa_pod_parser prs;
|
|
||||||
struct spa_pod_frame f;
|
|
||||||
|
|
||||||
spa_pod_parser_pod(&prs, info);
|
|
||||||
if (spa_pod_parser_push_struct(&prs, &f) == 0) {
|
|
||||||
while (true) {
|
|
||||||
const char *key, *val;
|
|
||||||
if (spa_pod_parser_get(&prs,
|
|
||||||
SPA_POD_String(&key),
|
|
||||||
SPA_POD_String(&val), NULL) < 0)
|
|
||||||
break;
|
|
||||||
pw_properties_set(props, key, val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((str = pw_properties_get(props, PW_KEY_DEVICE_FORM_FACTOR)) != NULL)
|
if ((str = pw_properties_get(props, PW_KEY_DEVICE_FORM_FACTOR)) != NULL)
|
||||||
if (strcmp(str, "internal") == 0)
|
if (strcmp(str, "internal") == 0)
|
||||||
|
|
@ -142,8 +113,8 @@ static struct monitor_item *add_item(struct pw_spa_monitor *this,
|
||||||
|
|
||||||
support = pw_core_get_support(impl->core, &n_support);
|
support = pw_core_get_support(impl->core, &n_support);
|
||||||
|
|
||||||
handle = calloc(1, spa_handle_factory_get_size(factory, NULL));
|
handle = calloc(1, spa_handle_factory_get_size(info->factory, NULL));
|
||||||
if ((res = spa_handle_factory_init(factory,
|
if ((res = spa_handle_factory_init(info->factory,
|
||||||
handle,
|
handle,
|
||||||
&props->dict,
|
&props->dict,
|
||||||
support,
|
support,
|
||||||
|
|
@ -153,138 +124,100 @@ static struct monitor_item *add_item(struct pw_spa_monitor *this,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((res = spa_handle_get_interface(handle, info->type, &iface)) < 0) {
|
||||||
if ((res = spa_handle_get_interface(handle, type, &iface)) < 0) {
|
pw_log_error("can't get %d interface: %d", info->type, res);
|
||||||
pw_log_error("can't get %d interface: %d", type, res);
|
|
||||||
pw_properties_free(props);
|
pw_properties_free(props);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mitem = calloc(1, sizeof(struct monitor_item));
|
obj = calloc(1, sizeof(struct monitor_object));
|
||||||
mitem->id = strdup(id);
|
obj->id = id;
|
||||||
mitem->handle = handle;
|
obj->name = strdup(name);
|
||||||
mitem->type = type;
|
obj->handle = handle;
|
||||||
|
obj->type = info->type;
|
||||||
|
|
||||||
switch (type) {
|
switch (obj->type) {
|
||||||
case SPA_TYPE_INTERFACE_Device:
|
case SPA_TYPE_INTERFACE_Device:
|
||||||
{
|
{
|
||||||
struct pw_device *device;
|
struct pw_device *device;
|
||||||
device = pw_spa_device_new(impl->core, NULL, impl->parent, name,
|
device = pw_spa_device_new(impl->core, NULL, impl->parent, name,
|
||||||
0, iface, handle, props, 0);
|
0, iface, handle, props, 0);
|
||||||
pw_device_add_listener(device, &mitem->object_listener,
|
pw_device_add_listener(device, &obj->object_listener,
|
||||||
&device_events, mitem);
|
&device_events, obj);
|
||||||
mitem->object = device;
|
obj->object = device;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
pw_log_error("interface %d not implemented", type);
|
pw_log_error("interface %d not implemented", obj->type);
|
||||||
free(mitem->id);
|
free(obj->name);
|
||||||
free(mitem);
|
free(obj);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
spa_list_append(&impl->item_list, &mitem->link);
|
spa_list_append(&impl->item_list, &obj->link);
|
||||||
|
|
||||||
return mitem;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct monitor_item *find_item(struct pw_spa_monitor *this, const char *id)
|
static struct monitor_object *find_object(struct pw_spa_monitor *this, uint32_t id)
|
||||||
{
|
{
|
||||||
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
|
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
|
||||||
struct monitor_item *mitem;
|
struct monitor_object *obj;
|
||||||
|
|
||||||
spa_list_for_each(mitem, &impl->item_list, link) {
|
spa_list_for_each(obj, &impl->item_list, link) {
|
||||||
if (strcmp(mitem->id, id) == 0) {
|
if (obj->id == id) {
|
||||||
return mitem;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_item(struct monitor_item *mitem)
|
void destroy_object(struct monitor_object *obj)
|
||||||
{
|
{
|
||||||
switch (mitem->type) {
|
switch (obj->type) {
|
||||||
case SPA_TYPE_INTERFACE_Node:
|
case SPA_TYPE_INTERFACE_Node:
|
||||||
pw_node_destroy(mitem->object);
|
pw_node_destroy(obj->object);
|
||||||
break;
|
break;
|
||||||
case SPA_TYPE_INTERFACE_Device:
|
case SPA_TYPE_INTERFACE_Device:
|
||||||
pw_device_destroy(mitem->object);
|
pw_device_destroy(obj->object);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remove_item(struct pw_spa_monitor *this, struct spa_pod *item, uint64_t now)
|
static void change_object(struct pw_spa_monitor *this, struct monitor_object *obj,
|
||||||
|
const struct spa_monitor_object_info *info, uint64_t now)
|
||||||
{
|
{
|
||||||
struct monitor_item *mitem;
|
pw_log_debug("monitor %p: change: \"%s\" (%u)", this, obj->name, obj->id);
|
||||||
const char *name, *id;
|
|
||||||
|
|
||||||
if (spa_pod_parse_object(item,
|
|
||||||
SPA_TYPE_OBJECT_MonitorItem, NULL,
|
|
||||||
SPA_MONITOR_ITEM_name, SPA_POD_String(&name),
|
|
||||||
SPA_MONITOR_ITEM_id, SPA_POD_String(&id)) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pw_log_debug("monitor %p: remove: \"%s\" (%s)", this, name, id);
|
|
||||||
mitem = find_item(this, id);
|
|
||||||
if (mitem)
|
|
||||||
destroy_item(mitem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void change_item(struct pw_spa_monitor *this, struct spa_pod *item, uint64_t now)
|
static int on_monitor_object_info(void *data, uint32_t id,
|
||||||
{
|
const struct spa_monitor_object_info *info)
|
||||||
struct monitor_item *mitem;
|
|
||||||
const char *name, *id;
|
|
||||||
enum spa_monitor_item_state state;
|
|
||||||
|
|
||||||
if (spa_pod_parse_object(item,
|
|
||||||
SPA_TYPE_OBJECT_MonitorItem, NULL,
|
|
||||||
SPA_MONITOR_ITEM_name, SPA_POD_String(&name),
|
|
||||||
SPA_MONITOR_ITEM_state, SPA_POD_Id(&state),
|
|
||||||
SPA_MONITOR_ITEM_id, SPA_POD_String(&id)) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pw_log_debug("monitor %p: change: \"%s\" (%s)", this, name, id);
|
|
||||||
mitem = find_item(this, id);
|
|
||||||
if (mitem == NULL)
|
|
||||||
mitem = add_item(this, item, now);
|
|
||||||
if (mitem == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case SPA_MONITOR_ITEM_STATE_Available:
|
|
||||||
break;
|
|
||||||
case SPA_MONITOR_ITEM_STATE_Disabled:
|
|
||||||
case SPA_MONITOR_ITEM_STATE_Unavailable:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int on_monitor_event(void *data, const struct spa_event *event)
|
|
||||||
{
|
{
|
||||||
struct impl *impl = data;
|
struct impl *impl = data;
|
||||||
struct pw_spa_monitor *this = &impl->this;
|
struct pw_spa_monitor *this = &impl->this;
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
uint64_t now_nsec;
|
uint64_t now_nsec;
|
||||||
struct spa_pod *item;
|
struct monitor_object *obj;
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
now_nsec = SPA_TIMESPEC_TO_NSEC(&now);
|
now_nsec = SPA_TIMESPEC_TO_NSEC(&now);
|
||||||
|
|
||||||
item = SPA_POD_CONTENTS(struct spa_event, event);
|
obj = find_object(this, id);
|
||||||
switch (SPA_MONITOR_EVENT_ID(event)) {
|
|
||||||
case SPA_MONITOR_EVENT_Added:
|
if (info == NULL) {
|
||||||
add_item(this, item, now_nsec);
|
if (obj == NULL)
|
||||||
break;
|
return -ENODEV;
|
||||||
case SPA_MONITOR_EVENT_Removed:
|
|
||||||
remove_item(this, item, now_nsec);
|
pw_log_debug("monitor %p: remove: (%s) %u", this, obj->name, id);
|
||||||
break;
|
destroy_object(obj);
|
||||||
case SPA_MONITOR_EVENT_Changed:
|
} else if (obj == NULL) {
|
||||||
change_item(this, item, now_nsec);
|
obj = add_object(this, id, info, now_nsec);
|
||||||
break;
|
if (obj == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
} else {
|
||||||
|
change_object(this, obj, info, now_nsec);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -317,7 +250,7 @@ static void update_monitor(struct pw_core *core, const char *name)
|
||||||
|
|
||||||
static const struct spa_monitor_callbacks callbacks = {
|
static const struct spa_monitor_callbacks callbacks = {
|
||||||
SPA_VERSION_MONITOR_CALLBACKS,
|
SPA_VERSION_MONITOR_CALLBACKS,
|
||||||
.event = on_monitor_event,
|
.object_info = on_monitor_object_info,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pw_spa_monitor *pw_spa_monitor_load(struct pw_core *core,
|
struct pw_spa_monitor *pw_spa_monitor_load(struct pw_core *core,
|
||||||
|
|
@ -386,12 +319,12 @@ struct pw_spa_monitor *pw_spa_monitor_load(struct pw_core *core,
|
||||||
void pw_spa_monitor_destroy(struct pw_spa_monitor *monitor)
|
void pw_spa_monitor_destroy(struct pw_spa_monitor *monitor)
|
||||||
{
|
{
|
||||||
struct impl *impl = SPA_CONTAINER_OF(monitor, struct impl, this);
|
struct impl *impl = SPA_CONTAINER_OF(monitor, struct impl, this);
|
||||||
struct monitor_item *mitem, *tmp;
|
struct monitor_object *obj, *tmp;
|
||||||
|
|
||||||
pw_log_debug("spa-monitor %p: destroy", impl);
|
pw_log_debug("spa-monitor %p: destroy", impl);
|
||||||
|
|
||||||
spa_list_for_each_safe(mitem, tmp, &impl->item_list, link)
|
spa_list_for_each_safe(obj, tmp, &impl->item_list, link)
|
||||||
destroy_item(mitem);
|
destroy_object(obj);
|
||||||
|
|
||||||
pw_unload_spa_handle(monitor->handle);
|
pw_unload_spa_handle(monitor->handle);
|
||||||
free(monitor->lib);
|
free(monitor->lib);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue