diff options
Diffstat (limited to 'src/modules/module-hal-detect.c')
-rw-r--r-- | src/modules/module-hal-detect.c | 143 |
1 files changed, 71 insertions, 72 deletions
diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index 441ebfed..19430a3d 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -1,5 +1,3 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. @@ -53,15 +51,16 @@ #include "dbus-util.h" #include "module-hal-detect-symdef.h" -PA_MODULE_AUTHOR("Shahms King") -PA_MODULE_DESCRIPTION("Detect available audio hardware and load matching drivers") -PA_MODULE_VERSION(PACKAGE_VERSION) +PA_MODULE_AUTHOR("Shahms King"); +PA_MODULE_DESCRIPTION("Detect available audio hardware and load matching drivers"); +PA_MODULE_VERSION(PACKAGE_VERSION); +PA_MODULE_LOAD_ONCE(TRUE); #if defined(HAVE_ALSA) && defined(HAVE_OSS) -PA_MODULE_USAGE("api=<alsa or oss>") +PA_MODULE_USAGE("api=<alsa or oss>"); #elif defined(HAVE_ALSA) -PA_MODULE_USAGE("api=<alsa>") +PA_MODULE_USAGE("api=<alsa>"); #elif defined(HAVE_OSS) -PA_MODULE_USAGE("api=<oss>") +PA_MODULE_USAGE("api=<oss>"); #endif struct device { @@ -94,7 +93,7 @@ static const char* const valid_modargs[] = { static void hal_device_free(struct device* d) { pa_assert(d); - + pa_xfree(d->udi); pa_xfree(d->sink_name); pa_xfree(d->source_name); @@ -107,7 +106,7 @@ static void hal_device_free_cb(void *d, PA_GCC_UNUSED void *data) { static const char *strip_udi(const char *udi) { const char *slash; - + if ((slash = strrchr(udi, '/'))) return slash+1; @@ -130,11 +129,11 @@ static alsa_type_t hal_alsa_device_get_type(LibHalContext *context, const char * if (!(type = libhal_device_get_property_string(context, udi, "alsa.type", error))) return ALSA_TYPE_OTHER; - if (!strcmp(type, "playback")) + if (!strcmp(type, "playback")) t = ALSA_TYPE_SINK; else if (!strcmp(type, "capture")) t = ALSA_TYPE_SOURCE; - else + else t = ALSA_TYPE_OTHER; libhal_free_string(type); @@ -145,13 +144,13 @@ static alsa_type_t hal_alsa_device_get_type(LibHalContext *context, const char * static int hal_alsa_device_is_modem(LibHalContext *context, const char *udi, DBusError *error) { char *class; int r; - + if (!(class = libhal_device_get_property_string(context, udi, "alsa.pcm_class", error))) return 0; r = strcmp(class, "modem") == 0; pa_xfree(class); - + return r; } @@ -162,7 +161,7 @@ static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi, char const char *module_name; DBusError error; pa_module *m; - + dbus_error_init(&error); pa_assert(u); @@ -170,7 +169,7 @@ static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi, char pa_assert(source_name); *sink_name = *source_name = NULL; - + type = hal_alsa_device_get_type(u->context, udi, &error); if (dbus_error_is_set(&error) || type == ALSA_TYPE_OTHER) goto fail; @@ -188,14 +187,14 @@ static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi, char if (type == ALSA_TYPE_SINK) { *sink_name = pa_sprintf_malloc("alsa_output.%s", strip_udi(udi)); - + module_name = "module-alsa-sink"; - args = pa_sprintf_malloc("device=hw:%u sink_name=%s", card, *sink_name); + args = pa_sprintf_malloc("device_id=%u sink_name=%s", card, *sink_name); } else { *source_name = pa_sprintf_malloc("alsa_input.%s", strip_udi(udi)); - + module_name = "module-alsa-source"; - args = pa_sprintf_malloc("device=hw:%u source_name=%s", card, *source_name); + args = pa_sprintf_malloc("device_id=%u source_name=%s", card, *source_name); } pa_log_debug("Loading %s with arguments '%s'", module_name, args); @@ -209,7 +208,7 @@ static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi, char pa_xfree(*source_name); *sink_name = *source_name = NULL; } - + return m; fail: @@ -255,7 +254,7 @@ finish: libhal_free_string(class); libhal_free_string(dev); - + return r; } @@ -264,7 +263,7 @@ static pa_module* hal_device_load_oss(struct userdata *u, const char *udi, char char* device; DBusError error; pa_module *m; - + dbus_error_init(&error); pa_assert(u); @@ -282,7 +281,7 @@ static pa_module* hal_device_load_oss(struct userdata *u, const char *udi, char *sink_name = pa_sprintf_malloc("oss_output.%s", strip_udi(udi)); *source_name = pa_sprintf_malloc("oss_input.%s", strip_udi(udi)); - + args = pa_sprintf_malloc("device=%s sink_name=%s source_name=%s", device, *sink_name, *source_name); libhal_free_string(device); @@ -316,7 +315,7 @@ static struct device* hal_device_add(struct userdata *u, const char *udi) { pa_assert(u); pa_assert(u->capability); pa_assert(!pa_hashmap_get(u->devices, udi)); - + #ifdef HAVE_ALSA if (strcmp(u->capability, CAPABILITY_ALSA) == 0) m = hal_device_load_alsa(u, udi, &sink_name, &source_name); @@ -346,12 +345,12 @@ static int hal_device_add_all(struct userdata *u, const char *capability) { char** udis; pa_assert(u); - + dbus_error_init(&error); if (u->capability && strcmp(u->capability, capability) != 0) return 0; - + pa_log_info("Trying capability %s", capability); udis = libhal_find_device_by_capability(u->context, capability, &n, &error); @@ -363,15 +362,15 @@ static int hal_device_add_all(struct userdata *u, const char *capability) { if (n > 0) { u->capability = capability; - + for (i = 0; i < n; i++) { struct device *d; - + if (!(d = hal_device_add(u, udis[i]))) pa_log_debug("Not loaded device %s", udis[i]); else { if (d->sink_name) - pa_scache_play_item_by_name(u->core, "pulse-coldplug", d->sink_name, PA_VOLUME_NORM, 0); + pa_scache_play_item_by_name(u->core, "pulse-coldplug", d->sink_name, FALSE, PA_VOLUME_NORM, NULL, NULL); count++; } } @@ -383,7 +382,7 @@ static int hal_device_add_all(struct userdata *u, const char *capability) { static dbus_bool_t device_has_capability(LibHalContext *context, const char *udi, const char* cap, DBusError *error){ dbus_bool_t has_prop; - + has_prop = libhal_device_property_exists(context, udi, "info.capabilities", error); if (!has_prop || dbus_error_is_set(error)) return FALSE; @@ -400,18 +399,18 @@ static void device_added_time_cb(pa_mainloop_api *ea, pa_time_event *ev, const s if (!pa_hashmap_get(td->u->devices, td->udi)) { int b; struct device *d; - + b = libhal_device_exists(td->u->context, td->udi, &error); - + if (dbus_error_is_set(&error)) { pa_log_error("Error adding device: %s: %s", error.name, error.message); dbus_error_free(&error); } else if (b) { - if (!(d = hal_device_add(td->u, td->udi))) + if (!(d = 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_scache_play_item_by_name(td->u->core, "pulse-hotplug", d->sink_name, FALSE, PA_VOLUME_NORM, NULL, NULL); } } } @@ -432,13 +431,13 @@ static void device_added_cb(LibHalContext *context, const char *udi) { if (pa_hashmap_get(u->devices, udi)) return; - + pa_log_debug("HAL Device added: %s", udi); dbus_error_init(&error); if (u->capability) { - + good = device_has_capability(context, udi, u->capability, &error); if (dbus_error_is_set(&error)) { @@ -446,7 +445,7 @@ static void device_added_cb(LibHalContext *context, const char *udi) { dbus_error_free(&error); return; } - + } else { #ifdef HAVE_ALSA @@ -463,10 +462,10 @@ static void device_added_cb(LibHalContext *context, const char *udi) { #endif #if defined(HAVE_OSS) && defined(HAVE_ALSA) if (!good) { -#endif +#endif #ifdef HAS_OSS good = device_has_capability(context, udi, CAPABILITY_OSS, &error); - + if (dbus_error_is_set(&error)) { pa_log_error("Error getting capability: %s: %s", error.name, error.message); dbus_error_free(&error); @@ -481,7 +480,7 @@ static void device_added_cb(LibHalContext *context, const char *udi) { } #endif } - + if (!good) return; @@ -502,7 +501,7 @@ static void device_removed_cb(LibHalContext* context, const char *udi) { pa_assert_se(u = libhal_ctx_get_user_data(context)); pa_log_debug("Device removed: %s", udi); - + if ((d = pa_hashmap_remove(u->devices, udi))) { pa_module_unload_by_index(u->core, d->index); hal_device_free(d); @@ -536,7 +535,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo pa_assert(bus); pa_assert(message); pa_assert(u); - + dbus_error_init(&error); pa_log_debug("dbus: interface=%s, path=%s, member=%s\n", @@ -548,7 +547,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo dbus_message_is_signal(message, "org.freedesktop.Hal.Device.AccessControl", "ACLRemoved")) { uint32_t uid; int suspend = strcmp(dbus_message_get_member(message), "ACLRemoved") == 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; @@ -559,25 +558,25 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo const char *udi; udi = dbus_message_get_path(message); - + if ((d = pa_hashmap_get(u->devices, udi))) { int send_acl_race_fix_message = 0; - d->acl_race_fix = 0; + d->acl_race_fix = 0; if (d->sink_name) { pa_sink *sink; - + if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0))) { int prev_suspended = pa_sink_get_state(sink) == PA_SINK_SUSPENDED; if (prev_suspended && !suspend) { /* resume */ if (pa_sink_suspend(sink, 0) >= 0) - pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, PA_VOLUME_NORM, 0); + pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, FALSE, PA_VOLUME_NORM, NULL, NULL); else d->acl_race_fix = 1; - + } else if (!prev_suspended && suspend) { /* suspend */ if (pa_sink_suspend(sink, 1) >= 0) @@ -611,11 +610,11 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo dbus_connection_send(pa_dbus_connection_get(u->connection), msg, NULL); dbus_message_unref(msg); } - + } else if (!suspend) device_added_cb(u->context, udi); } - + } else if (dbus_message_is_signal(message, "org.pulseaudio.Server", "DirtyGiveUpMessage")) { /* We use this message to avoid a dirty race condition when we get an ACLAdded message before the previously owning PA @@ -626,15 +625,15 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo struct device *d; udi = dbus_message_get_path(message); - + if ((d = pa_hashmap_get(u->devices, udi)) && d->acl_race_fix) { pa_log_debug("Got dirty give up message for '%s', trying resume ...", udi); d->acl_race_fix = 0; - + if (d->sink_name) { pa_sink *sink; - + if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0))) { int prev_suspended = pa_sink_get_state(sink) == PA_SINK_SUSPENDED; @@ -642,14 +641,14 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo if (prev_suspended) { /* resume */ if (pa_sink_suspend(sink, 0) >= 0) - pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, PA_VOLUME_NORM, 0); + pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, FALSE, PA_VOLUME_NORM, NULL, NULL); } } } - + if (d->source_name) { pa_source *source; - + if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE, 0))) { int prev_suspended = pa_source_get_state(source) == PA_SOURCE_SUSPENDED; @@ -658,15 +657,15 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo pa_source_suspend(source, 0); } } - - } else + + } else /* Yes, we don't check the UDI for validity, but hopefully HAL will */ device_added_cb(u->context, udi); } finish: dbus_error_free(&error); - + return DBUS_HANDLER_RESULT_HANDLED; } @@ -674,7 +673,7 @@ static void hal_context_free(LibHalContext* hal_context) { DBusError error; dbus_error_init(&error); - + libhal_ctx_shutdown(hal_context, &error); libhal_ctx_free(hal_context); @@ -686,7 +685,7 @@ static LibHalContext* hal_context_new(pa_core* c, DBusConnection *conn) { LibHalContext *hal_context = NULL; dbus_error_init(&error); - + if (!(hal_context = libhal_ctx_new())) { pa_log_error("libhal_ctx_new() failed"); goto fail; @@ -721,7 +720,7 @@ int pa__init(pa_module*m) { int n = 0; pa_modargs *ma; const char *api; - + pa_assert(m); dbus_error_init(&error); @@ -738,7 +737,7 @@ int pa__init(pa_module*m) { if (strcmp(api, CAPABILITY_ALSA) == 0) { good = 1; api = CAPABILITY_ALSA; - } + } #endif #ifdef HAVE_OSS if (strcmp(api, CAPABILITY_OSS) == 0) { @@ -746,13 +745,13 @@ int pa__init(pa_module*m) { api = CAPABILITY_OSS; } #endif - + if (!good) { pa_log_error("Invalid API specification."); goto fail; } } - + if (!(conn = pa_dbus_bus_get(m->core, DBUS_BUS_SYSTEM, &error)) || dbus_error_is_set(&error)) { if (conn) pa_dbus_connection_unref(conn); @@ -779,7 +778,7 @@ int pa__init(pa_module*m) { #endif #if defined(HAVE_ALSA) && defined(HAVE_OSS) if (n <= 0) -#endif +#endif #ifdef HAVE_OSS n += hal_device_add_all(u, CAPABILITY_OSS); #endif @@ -811,17 +810,17 @@ int pa__init(pa_module*m) { 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 0; fail: if (ma) pa_modargs_free(ma); - + dbus_error_free(&error); pa__done(m); @@ -831,7 +830,7 @@ fail: void pa__done(pa_module *m) { struct userdata *u; - + pa_assert(m); if (!(u = m->userdata)) @@ -845,6 +844,6 @@ void pa__done(pa_module *m) { if (u->connection) pa_dbus_connection_unref(u->connection); - + pa_xfree(u); } |