#include #include #include #include #include PA_MODULE_AUTHOR("Alexander Sulfrian"); PA_MODULE_DESCRIPTION("Module that notify you on volume changes of sinks."); PA_MODULE_VERSION(PACKAGE_VERSION); PA_MODULE_USAGE(""); struct userdata { pa_core *core; pa_module *module; pa_subscription *subscription; /* dbus stuff */ DBusError dbus_error; DBusConnection *dbus_connection; }; void sink_change_event_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { pa_sink *s; char vol[PA_CVOLUME_SNPRINT_MAX]; if (PA_SUBSCRIPTION_EVENT_CHANGE & t == 0) return; s = pa_idxset_get_by_index(c->sinks, idx); if (!s) return; pa_cvolume_snprint(vol, PA_CVOLUME_SNPRINT_MAX, &s->reference_volume); pa_log("Volume: %s %s", s->name, vol); } void pa__done(pa_module *m) { struct userdata *u; if (!(u = m->userdata)) return; pa_subscription_free(u->subscription); if (u->dbus_connection) dbus_connection_close(u->dbus_connection); pa_xfree(u); } int pa__init(pa_module* m) { struct userdata *u; pa_subscription_mask_t mask; int ret; m->userdata = u = pa_xnew0(struct userdata, 1); u->core = m->core; u->module = m; mask = PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT | PA_SUBSCRIPTION_EVENT_CHANGE; u->subscription = pa_subscription_new(m->core, mask, sink_change_event_cb, u); /* initialize dbus */ dbus_error_init(&u->dbus_error); u->dbus_connection = dbus_bus_get(DBUS_BUS_SESSION, &u->dbus_error); if (dbus_error_is_set(&u->dbus_error)) { pa_log("DBus Connection Error (%s)\n", u->dbus_error.message); dbus_error_free(&u->dbus_error); } if (!u->dbus_connection) goto fail; /* request a name on the bus */ ret = dbus_bus_request_name(u->dbus_connection, "org.PulseAudio.VolumeNotification", DBUS_NAME_FLAG_REPLACE_EXISTING, &u->dbus_error); if (dbus_error_is_set(&u->dbus_error)) { pa_log("DBus Name Error (%s)\n", u->dbus_error.message); dbus_error_free(&u->dbus_error); } if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { goto fail; } return 0; fail: pa__done(m); return -1; }