From eca2203603acfabb187ada88d3cf598bd8d413d9 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 29 Sep 2015 14:09:23 +0200 Subject: [PATCH] ratbagd: add manager interface Instead of relying on the cricket ObjectManager interface, use our own manager interface. This gets rid of ridiculous recursive behavior of the ObjectManager interface and instead allows us to control the behavior. Signed-off-by: David Herrmann --- src/ratbagd-device.c | 20 ---------------- src/ratbagd.c | 56 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 23 deletions(-) diff --git a/src/ratbagd-device.c b/src/ratbagd-device.c index 07685a61..5427651e 100644 --- a/src/ratbagd-device.c +++ b/src/ratbagd-device.c @@ -263,15 +263,6 @@ void ratbagd_device_link(struct ratbagd_device *device) rbtree_add(&device->ctx->device_map, parent, node, &device->node); ++device->ctx->n_devices; - /* send out object-manager notification */ - r = sd_bus_emit_object_added(device->ctx->bus, device->path); - if (r < 0) { - errno = -r; - fprintf(stderr, - "Cannot send device notification for '%s': %m\n", - device->name); - } - /* register profile interfaces */ r = asprintf(&prefix, "%s/profile", device->path); if (r >= 0) { @@ -299,23 +290,12 @@ void ratbagd_device_link(struct ratbagd_device *device) void ratbagd_device_unlink(struct ratbagd_device *device) { - int r; - if (!ratbagd_device_linked(device)) return; device->profile_enum_slot = sd_bus_slot_unref(device->profile_enum_slot); device->profile_vtable_slot = sd_bus_slot_unref(device->profile_vtable_slot); - /* send out object-manager notification */ - r = sd_bus_emit_object_removed(device->ctx->bus, device->path); - if (r < 0) { - errno = -r; - fprintf(stderr, - "Cannot send device notification for '%s': %m\n", - device->name); - } - /* unlink from context */ --device->ctx->n_devices; rbtree_remove(&device->ctx->device_map, &device->node); diff --git a/src/ratbagd.c b/src/ratbagd.c index 29ca73c3..6619e35f 100644 --- a/src/ratbagd.c +++ b/src/ratbagd.c @@ -94,6 +94,41 @@ error: return -ENOMEM; } +static int ratbagd_get_devices(sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) +{ + struct ratbagd *ctx = userdata; + struct ratbagd_device *device; + int r; + + r = sd_bus_message_open_container(reply, 'a', "o"); + if (r < 0) + return r; + + RATBAGD_DEVICE_FOREACH(device, ctx) { + r = sd_bus_message_append(reply, + "o", + ratbagd_device_get_path(device)); + if (r < 0) + return r; + } + + return sd_bus_message_close_container(reply); +} + +static const sd_bus_vtable ratbagd_vtable[] = { + SD_BUS_VTABLE_START(0), + SD_BUS_PROPERTY("Devices", "ao", ratbagd_get_devices, 0, 0), + SD_BUS_SIGNAL("DeviceNew", "o", 0), + SD_BUS_SIGNAL("DeviceRemoved", "o", 0), + SD_BUS_VTABLE_END, +}; + static void ratbagd_process_device(struct ratbagd *ctx, struct udev_device *udevice) { @@ -120,6 +155,12 @@ static void ratbagd_process_device(struct ratbagd *ctx, if (streq_ptr("remove", udev_device_get_action(udevice))) { /* device was removed, unlink it and destroy our context */ if (device) { + (void) sd_bus_emit_signal(ctx->bus, + "/org/freedesktop/ratbag1", + "org.freedesktop.ratbag1.Manager", + "DeviceRemoved", + "o", + ratbagd_device_get_path(device)); ratbagd_device_unlink(device); ratbagd_device_free(device); } @@ -143,6 +184,12 @@ static void ratbagd_process_device(struct ratbagd *ctx, } ratbagd_device_link(device); + (void) sd_bus_emit_signal(ctx->bus, + "/org/freedesktop/ratbag1", + "org.freedesktop.ratbag1.Manager", + "DeviceNew", + "o", + ratbagd_device_get_path(device)); } } @@ -268,9 +315,12 @@ static int ratbagd_new(struct ratbagd **out) if (r < 0) return r; - r = sd_bus_add_object_manager(ctx->bus, - NULL, - "/org/freedesktop/ratbag1"); + r = sd_bus_add_object_vtable(ctx->bus, + NULL, + "/org/freedesktop/ratbag1", + "org.freedesktop.ratbag1.Manager", + ratbagd_vtable, + ctx); if (r < 0) return r;