[pulseaudio-commits] r1597 - /branches/lennart/src/modules/module-hal-detect.c
svnmailer-noreply at 0pointer.de
svnmailer-noreply at 0pointer.de
Thu Aug 9 06:49:28 PDT 2007
Author: lennart
Date: Thu Aug 9 15:49:27 2007
New Revision: 1597
URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=3D1597&root=3Dpulseaudio&vi=
ew=3Drev
Log:
listen for HAL ACL events; play an event sound on hw coldplug, hotplug and =
ACL access
Modified:
branches/lennart/src/modules/module-hal-detect.c
Modified: branches/lennart/src/modules/module-hal-detect.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/modules/mo=
dule-hal-detect.c?rev=3D1597&root=3Dpulseaudio&r1=3D1596&r2=3D1597&view=3Dd=
iff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- branches/lennart/src/modules/module-hal-detect.c (original)
+++ branches/lennart/src/modules/module-hal-detect.c Thu Aug 9 15:49:27 20=
07
@@ -44,6 +44,8 @@
#include <pulsecore/hashmap.h>
#include <pulsecore/idxset.h>
#include <pulsecore/core-util.h>
+#include <pulsecore/namereg.h>
+#include <pulsecore/core-scache.h>
=
#include <hal/libhal.h>
=
@@ -57,6 +59,7 @@
struct device {
uint32_t index;
char *udi;
+ char *sink_name, *source_name;
};
=
struct userdata {
@@ -79,6 +82,8 @@
pa_assert(d);
=
pa_xfree(d->udi);
+ pa_xfree(d->sink_name);
+ pa_xfree(d->source_name);
pa_xfree(d);
}
=
@@ -136,15 +141,22 @@
return r;
}
=
-static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi=
) {
+static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi=
, char **sink_name, char **source_name) {
char args[128];
alsa_type_t type;
int device, card;
const char *module_name;
DBusError error;
- =
- dbus_error_init(&error);
-
+ pa_module *m;
+ =
+ dbus_error_init(&error);
+
+ pa_assert(u);
+ pa_assert(sink_name);
+ pa_assert(source_name);
+
+ *sink_name =3D *source_name =3D NULL;
+ =
type =3D hal_alsa_device_get_type(u->context, udi, &error);
if (dbus_error_is_set(&error) || type =3D=3D ALSA_TYPE_OTHER)
goto fail;
@@ -161,16 +173,28 @@
goto fail;
=
if (type =3D=3D ALSA_TYPE_SINK) {
+ *sink_name =3D pa_sprintf_malloc("alsa_output.%s", strip_udi(udi));
+ =
module_name =3D "module-alsa-sink";
- pa_snprintf(args, sizeof(args), "device=3Dhw:%u sink_name=3Dalsa_o=
utput.%s", card, strip_udi(udi));
+ pa_snprintf(args, sizeof(args), "device=3Dhw:%u sink_name=3D%s", c=
ard, *sink_name);
} else {
+ *source_name =3D pa_sprintf_malloc("alsa_output.%s", strip_udi(udi=
));
+ =
module_name =3D "module-alsa-source";
- pa_snprintf(args, sizeof(args), "device=3Dhw:%u source_name=3Dalsa=
_input.%s", card, strip_udi(udi));
+ pa_snprintf(args, sizeof(args), "device=3Dhw:%u source_name=3D%s",=
card, *source_name);
}
=
pa_log_debug("Loading %s with arguments '%s'", module_name, args);
=
- return pa_module_load(u->core, module_name, args);
+ m =3D pa_module_load(u->core, module_name, args);
+
+ if (!m) {
+ pa_xfree(*sink_name);
+ pa_xfree(*source_name);
+ *sink_name =3D *source_name =3D NULL;
+ }
+ =
+ return m;
=
fail:
if (dbus_error_is_set(&error)) {
@@ -219,12 +243,19 @@
return r;
}
=
-static pa_module* hal_device_load_oss(struct userdata *u, const char *udi)=
{
+static pa_module* hal_device_load_oss(struct userdata *u, const char *udi,=
char **sink_name, char **source_name) {
char args[256];
char* device;
DBusError error;
- =
- dbus_error_init(&error);
+ pa_module *m;
+ =
+ dbus_error_init(&error);
+
+ pa_assert(u);
+ pa_assert(sink_name);
+ pa_assert(source_name);
+
+ *sink_name =3D *source_name =3D NULL;
=
if (!hal_oss_device_is_pcm(u->context, udi, &error) || dbus_error_is_s=
et(&error))
goto fail;
@@ -233,12 +264,23 @@
if (!device || dbus_error_is_set(&error))
goto fail;
=
- pa_snprintf(args, sizeof(args), "device=3D%s sink_name=3Doss_output.%s=
source_name=3Doss_input.%s", device, strip_udi(udi), strip_udi(udi));
+ *sink_name =3D pa_sprintf_malloc("alsa_output.%s", strip_udi(udi));
+ *source_name =3D pa_sprintf_malloc("alsa_output.%s", strip_udi(udi));
+ =
+ pa_snprintf(args, sizeof(args), "device=3D%s sink_name=3D%s source_nam=
e=3D%s", device, sink_name, source_name);
libhal_free_string(device);
=
pa_log_debug("Loading module-oss with arguments '%s'", args);
=
- return pa_module_load(u->core, "module-oss", args);
+ m =3D pa_module_load(u->core, "module-oss", args);
+
+ if (!m) {
+ pa_xfree(*sink_name);
+ pa_xfree(*source_name);
+ *sink_name =3D *source_name =3D NULL;
+ }
+
+ return m;
=
fail:
if (dbus_error_is_set(&error)) {
@@ -250,31 +292,34 @@
}
#endif
=
-static int hal_device_add(struct userdata *u, const char *udi) {
+static struct device* hal_device_add(struct userdata *u, const char *udi) {
pa_module* m =3D NULL;
struct device *d;
+ char *sink_name =3D NULL, *source_name =3D NULL;
=
pa_assert(u);
pa_assert(u->capability);
=
#ifdef HAVE_ALSA
if (strcmp(u->capability, CAPABILITY_ALSA) =3D=3D 0)
- m =3D hal_device_load_alsa(u, udi);
+ m =3D hal_device_load_alsa(u, udi, &sink_name, &source_name);
#endif
#ifdef HAVE_OSS
if (strcmp(u->capability, CAPABILITY_OSS) =3D=3D 0)
- m =3D hal_device_load_oss(u, udi);
+ m =3D hal_device_load_oss(u, udi, &sink_name, &source_name);
#endif
=
if (!m)
- return -1;
+ return NULL;
=
d =3D pa_xnew(struct device, 1);
d->udi =3D pa_xstrdup(udi);
d->index =3D m->index;
+ d->sink_name =3D sink_name;
+ d->source_name =3D source_name;
pa_hashmap_put(u->devices, d->udi, d);
=
- return 0;
+ return d;
}
=
static int hal_device_add_all(struct userdata *u, const char *capability) {
@@ -300,10 +345,15 @@
u->capability =3D capability;
=
for (i =3D 0; i < n; i++) {
- if (hal_device_add(u, udis[i]) < 0)
+ struct device *d;
+ =
+ if (!(d =3D hal_device_add(u, udis[i])))
pa_log_debug("Not loaded device %s", udis[i]);
- else
+ else {
+ if (d->sink_name)
+ pa_scache_play_item_by_name(u->core, "pulse-coldplug",=
d->sink_name, PA_VOLUME_NORM, 0);
count++;
+ }
}
}
=
@@ -325,6 +375,7 @@
DBusError error;
struct timerdata *td =3D userdata;
int b;
+ struct device *d;
=
dbus_error_init(&error);
=
@@ -333,8 +384,14 @@
if (dbus_error_is_set(&error)) {
pa_log_error("Error adding device: %s: %s", error.name, error.mess=
age);
dbus_error_free(&error);
- } else if (b)
- hal_device_add(td->u, td->udi);
+ } else if (b) {
+ if (!(d =3D hal_device_add(td->u, td->udi))) =
+ pa_log_debug("Not loaded device %s", td->udi);
+ else {
+ if (d->sink_name)
+ pa_scache_play_item_by_name(td->u->core, "pulse-hotplug", =
d->sink_name, PA_VOLUME_NORM, 0);
+ }
+ }
=
pa_xfree(td->udi);
pa_xfree(td);
@@ -446,6 +503,66 @@
device_removed_cb(context, udi);
}
=
+
+static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *messa=
ge, void *userdata) {
+ struct userdata*u =3D userdata;
+ DBusError error;
+
+ pa_assert(bus);
+ pa_assert(message);
+ pa_assert(u);
+ =
+ dbus_error_init(&error);
+
+ pa_log_debug("dbus: interface=3D%s, path=3D%s, member=3D%s\n",
+ dbus_message_get_interface(message),
+ dbus_message_get_path(message),
+ dbus_message_get_member(message));
+
+ if (dbus_message_is_signal(message, "org.freedesktop.Hal.Device.Access=
Control", "ACLAdded") ||
+ dbus_message_is_signal(message, "org.freedesktop.Hal.Device.Access=
Control", "ACLRemoved")) {
+ uint32_t uid;
+ int suspend =3D strcmp(dbus_message_get_member(message), "ACLRemov=
ed") =3D=3D 0;
+ =
+ if (!dbus_message_get_args(message, &error, DBUS_TYPE_UINT32, &uid=
, DBUS_TYPE_INVALID) || dbus_error_is_set(&error)) {
+ pa_log_error("Failed to parse ACL message: %s: %s", error.name=
, error.message);
+ goto finish;
+ }
+
+ if (uid =3D=3D getuid() || uid =3D=3D geteuid()) {
+ struct device *d;
+ const char *udi;
+
+ udi =3D dbus_message_get_path(message);
+ =
+ if ((d =3D pa_hashmap_get(u->devices, udi))) {
+ =
+ if (d->sink_name) {
+ pa_sink *sink;
+ =
+ if ((sink =3D pa_namereg_get(u->core, d->sink_name, PA=
_NAMEREG_SINK, 0)))
+ if (pa_sink_suspend(sink, suspend) >=3D 0)
+ pa_scache_play_item_by_name(u->core, "pulse-ac=
cess", d->sink_name, PA_VOLUME_NORM, 0);
+ }
+
+ if (d->source_name) {
+ pa_source *source;
+
+ if ((source =3D pa_namereg_get(u->core, d->source_name=
, PA_NAMEREG_SOURCE, 0)))
+ pa_source_suspend(source, suspend);
+ }
+ }
+
+ }
+ =
+ }
+
+finish:
+ dbus_error_free(&error);
+ =
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
static void hal_context_free(LibHalContext* hal_context) {
DBusError error;
=
@@ -454,8 +571,7 @@
libhal_ctx_shutdown(hal_context, &error);
libhal_ctx_free(hal_context);
=
- if (dbus_error_is_set(&error))
- dbus_error_free(&error);
+ dbus_error_free(&error);
}
=
static LibHalContext* hal_context_new(pa_core* c, DBusConnection *conn) {
@@ -485,8 +601,7 @@
if (hal_context)
hal_context_free(hal_context);
=
- if (dbus_error_is_set(&error))
- dbus_error_free(&error);
+ dbus_error_free(&error);
=
return NULL;
}
@@ -503,16 +618,17 @@
=
dbus_error_init(&error);
=
- if (!(conn =3D pa_dbus_bus_get(c, DBUS_BUS_SYSTEM, &error))) {
+ if (!(conn =3D pa_dbus_bus_get(c, DBUS_BUS_SYSTEM, &error)) || dbus_er=
ror_is_set(&error)) {
+ if (conn)
+ pa_dbus_connection_unref(conn);
pa_log_error("Unable to contact DBUS system bus: %s: %s", error.na=
me, error.message);
- dbus_error_free(&error);
- return -1;
+ goto fail;
}
=
if (!(hal_context =3D hal_context_new(c, pa_dbus_connection_get(conn))=
)) {
/* pa_hal_context_new() logs appropriate errors */
pa_dbus_connection_unref(conn);
- return -1;
+ goto fail;
}
=
u =3D pa_xnew(struct userdata, 1);
@@ -539,18 +655,30 @@
libhal_ctx_set_device_new_capability(hal_context, new_capability_cb);
libhal_ctx_set_device_lost_capability(hal_context, lost_capability_cb);
=
- dbus_error_init(&error);
- =
if (!libhal_device_property_watch_all(hal_context, &error)) {
pa_log_error("Error monitoring device list: %s: %s", error.name, e=
rror.message);
- dbus_error_free(&error);
- pa__done(c, m);
- return -1;
- }
-
+ goto fail;
+ }
+
+ if (!dbus_connection_add_filter(pa_dbus_connection_get(conn), filter_c=
b, u, NULL)) {
+ pa_log_error("Failed to add filter function");
+ goto fail;
+ }
+
+ dbus_bus_add_match(pa_dbus_connection_get(conn), "type=3D'signal',send=
er=3D'org.freedesktop.Hal', interface=3D'org.freedesktop.Hal.Device.AccessC=
ontrol'", &error);
+ if (dbus_error_is_set(&error)) {
+ pa_log_error("Unable to subscribe to HAL ACL signals: %s: %s", err=
or.name, error.message);
+ goto fail;
+ }
+ =
pa_log_info("Loaded %i modules.", n);
=
return 0;
+
+fail:
+ dbus_error_free(&error);
+ pa__done(c, m);
+ return -1;
}
=
=
More information about the pulseaudio-commits
mailing list