PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
- by the Free Software Foundation; either version 2 of the License,
+ by the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
PulseAudio is distributed in the hope that it will be useful, but
#include <pulsecore/namereg.h>
#include <pulsecore/core-scache.h>
#include <pulsecore/modargs.h>
+#include <pulsecore/dbus-shared.h>
#include <hal/libhal.h>
-#include "dbus-util.h"
#include "module-hal-detect-symdef.h"
PA_MODULE_AUTHOR("Shahms King");
enum alsa_type {
ALSA_TYPE_PLAYBACK,
ALSA_TYPE_CAPTURE,
+ ALSA_TYPE_CONTROL,
ALSA_TYPE_OTHER
};
t = ALSA_TYPE_PLAYBACK;
else if (pa_streq(type, "capture"))
t = ALSA_TYPE_CAPTURE;
+ else if (pa_streq(type, "control"))
+ t = ALSA_TYPE_CONTROL;
libhal_free_string(type);
finish:
if (dbus_error_is_set(&error)) {
- pa_log_error("D-Bus error while parsing HAL ALSA data: %s: %s", error.name, error.message);
+ if (!dbus_error_has_name(&error, "org.freedesktop.Hal.NoSuchProperty"))
+ pa_log_error("D-Bus error while parsing HAL ALSA data: %s: %s", error.name, error.message);
dbus_error_free(&error);
}
static int hal_device_load_alsa(struct userdata *u, const char *udi, struct device *d) {
enum alsa_type type;
- int device, card;
+ int card;
DBusError error;
pa_module *m;
char *args, *originating_udi = NULL, *card_name = NULL;
/* We only care for PCM devices */
type = hal_alsa_device_get_type(u->context, udi);
- if (type == ALSA_TYPE_OTHER)
- goto fail;
- /* We don't care for modems */
- if (hal_alsa_device_is_modem(u->context, udi))
+ /* For each ALSA card that appears the control device will be the
+ * last one to be created, this is considered part of the ALSA
+ * usperspace API. We rely on this and load our modules only when
+ * the control device is available assuming that *all* device
+ * nodes have been properly created and assigned the right ACLs at
+ * that time. Also see:
+ *
+ * http://mailman.alsa-project.org/pipermail/alsa-devel/2009-April/015958.html
+ *
+ * and the associated thread.*/
+
+ if (type != ALSA_TYPE_CONTROL)
goto fail;
- /* We only care for the main device */
- device = libhal_device_get_property_int(u->context, udi, "alsa.device", &error);
- if (dbus_error_is_set(&error) || device != 0)
+ /* We don't care for modems -- this is most likely not set for
+ * control devices, so kind of pointless here. */
+ if (hal_alsa_device_is_modem(u->context, udi))
goto fail;
/* We store only one entry per card, hence we look for the originating device */
d->originating_udi = NULL;
d->module = PA_INVALID_INDEX;
d->sink_name = d->source_name = d->card_name = NULL;
+ r = -1;
#ifdef HAVE_ALSA
if (pa_streq(u->capability, CAPABILITY_ALSA))
for (i = 0; i < n; i++) {
struct device *d;
- if ((d = hal_device_add(u, udis[i])))
+ if ((d = hal_device_add(u, udis[i]))) {
count++;
- else
+ pa_log_debug("Loaded device %s", udis[i]);
+ } else
pa_log_debug("Not loaded device %s", udis[i]);
}
}
if (!hal_device_add(u, udi))
pa_log_debug("Not loaded device %s", udi);
+ else
+ pa_log_debug("Loaded device %s", udi);
finish:
if (dbus_error_is_set(&error)) {
- pa_log_error("D-Bus error while parsing HAL data: %s: %s", error.name, error.message);
+ if (!dbus_error_has_name(&error, "org.freedesktop.Hal.NoSuchProperty"))
+ pa_log_error("D-Bus error while parsing HAL data: %s: %s", error.name, error.message);
dbus_error_free(&error);
}
}
goto fail;
}
- dbus_bus_add_match(pa_dbus_connection_get(u->connection), "type='signal',sender='org.freedesktop.Hal', interface='org.freedesktop.Hal.Device.AccessControl'", &error);
- if (dbus_error_is_set(&error)) {
+ if (pa_dbus_add_matches(
+ pa_dbus_connection_get(u->connection), &error,
+ "type='signal',sender='org.freedesktop.Hal',interface='org.freedesktop.Hal.Device.AccessControl',member='ACLAdded'",
+ "type='signal',sender='org.freedesktop.Hal',interface='org.freedesktop.Hal.Device.AccessControl',member='ACLRemoved'",
+ "type='signal',interface='org.pulseaudio.Server',member='DirtyGiveUpMessage'", NULL) < 0) {
pa_log_error("Unable to subscribe to HAL ACL signals: %s: %s", error.name, error.message);
goto fail;
}
- dbus_bus_add_match(pa_dbus_connection_get(u->connection), "type='signal',interface='org.pulseaudio.Server'", &error);
- if (dbus_error_is_set(&error)) {
- pa_log_error("Unable to subscribe to PulseAudio signals: %s: %s", error.name, error.message);
- goto fail;
- }
-
pa_log_info("Loaded %i modules.", n);
pa_modargs_free(ma);
return -1;
}
-
void pa__done(pa_module *m) {
struct userdata *u;
}
if (u->connection) {
- DBusError error;
- dbus_error_init(&error);
-
- dbus_bus_remove_match(pa_dbus_connection_get(u->connection), "type='signal',sender='org.freedesktop.Hal', interface='org.freedesktop.Hal.Device.AccessControl'", &error);
- dbus_error_free(&error);
-
- dbus_bus_remove_match(pa_dbus_connection_get(u->connection), "type='signal',interface='org.pulseaudio.Server'", &error);
- dbus_error_free(&error);
+ pa_dbus_remove_matches(
+ pa_dbus_connection_get(u->connection),
+ "type='signal',sender='org.freedesktop.Hal',interface='org.freedesktop.Hal.Device.AccessControl',member='ACLAdded'",
+ "type='signal',sender='org.freedesktop.Hal',interface='org.freedesktop.Hal.Device.AccessControl',member='ACLRemoved'",
+ "type='signal',interface='org.pulseaudio.Server',member='DirtyGiveUpMessage'", NULL);
dbus_connection_remove_filter(pa_dbus_connection_get(u->connection), filter_cb, u);
-
pa_dbus_connection_unref(u->connection);
}