diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/modules/alsa/alsa-sink.c | 2 | ||||
-rw-r--r-- | src/modules/alsa/alsa-source.c | 2 | ||||
-rw-r--r-- | src/modules/alsa/alsa-util.c | 42 | ||||
-rw-r--r-- | src/modules/alsa/alsa-util.h | 1 | ||||
-rw-r--r-- | src/modules/alsa/module-alsa-card.c | 1 | ||||
-rw-r--r-- | src/modules/bluetooth/bluetooth-util.c | 4 | ||||
-rw-r--r-- | src/modules/bluetooth/module-bluetooth-device.c | 2 | ||||
-rw-r--r-- | src/modules/hal-util.c | 3 | ||||
-rw-r--r-- | src/modules/udev-util.c | 142 | ||||
-rw-r--r-- | src/modules/udev-util.h | 30 | ||||
-rw-r--r-- | src/pulse/proplist.h | 33 | ||||
-rw-r--r-- | src/pulse/thread-mainloop.h | 10 | ||||
-rw-r--r-- | src/pulsecore/card.c | 3 | ||||
-rw-r--r-- | src/pulsecore/sink.c | 69 | ||||
-rw-r--r-- | src/pulsecore/sink.h | 3 | ||||
-rw-r--r-- | src/pulsecore/source.c | 3 |
17 files changed, 332 insertions, 24 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index f5a1febe..9f2fa02a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1313,6 +1313,12 @@ libalsa_util_la_LIBADD += $(HAL_LIBS) libalsa_util_la_CFLAGS += $(HAL_CFLAGS) endif +if HAVE_UDEV +libalsa_util_la_SOURCES += modules/udev-util.h modules/udev-util.c +libalsa_util_la_LIBADD += $(UDEV_LIBS) +libalsa_util_la_CFLAGS += $(UDEV_CFLAGS) +endif + if HAVE_DBUS libalsa_util_la_SOURCES += modules/reserve.h modules/reserve.c modules/reserve-wrap.c modules/reserve-wrap.h libalsa_util_la_LIBADD += $(DBUS_LIBS) libdbus-util.la diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 708e020c..d4325881 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -1667,6 +1667,8 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile->description); } + pa_alsa_init_description(data.proplist); + u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY); pa_sink_new_data_done(&data); diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index 4321c7ff..7a1b0f8d 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -1509,6 +1509,8 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile->description); } + pa_alsa_init_description(data.proplist); + u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY); pa_source_new_data_done(&data); diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c index 6740c069..7d833ff7 100644 --- a/src/modules/alsa/alsa-util.c +++ b/src/modules/alsa/alsa-util.c @@ -47,6 +47,10 @@ #include "hal-util.h" #endif +#ifdef HAVE_UDEV +#include "udev-util.h" +#endif + struct pa_alsa_fdlist { unsigned num_fds; struct pollfd *fds; @@ -1362,6 +1366,26 @@ void pa_alsa_redirect_errors_dec(void) { snd_lib_error_set_handler(NULL); } +pa_bool_t pa_alsa_init_description(pa_proplist *p) { + const char *s; + pa_assert(p); + + if (pa_device_init_description(p)) + return TRUE; + + if ((s = pa_proplist_gets(p, "alsa.card_name"))) { + pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, s); + return TRUE; + } + + if ((s = pa_proplist_gets(p, "alsa.name"))) { + pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, s); + return TRUE; + } + + return FALSE; +} + void pa_alsa_init_proplist_card(pa_core *c, pa_proplist *p, int card) { char *cn, *lcn, *dn; @@ -1385,6 +1409,10 @@ void pa_alsa_init_proplist_card(pa_core *c, pa_proplist *p, int card) { pa_xfree(dn); } +#ifdef HAVE_UDEV + pa_udev_get_info(c, p, card); +#endif + #ifdef HAVE_HAL pa_hal_get_info(c, p, card); #endif @@ -1411,7 +1439,7 @@ void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t * snd_pcm_class_t class; snd_pcm_subclass_t subclass; - const char *n, *id, *sdn, *cn = NULL; + const char *n, *id, *sdn; int card; pa_assert(p); @@ -1426,6 +1454,7 @@ void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t * if (alsa_class_table[class]) pa_proplist_sets(p, "alsa.class", alsa_class_table[class]); } + subclass = snd_pcm_info_get_subclass(pcm_info); if (subclass <= SND_PCM_SUBCLASS_LAST) if (alsa_subclass_table[subclass]) @@ -1443,17 +1472,8 @@ void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t * pa_proplist_setf(p, "alsa.device", "%u", snd_pcm_info_get_device(pcm_info)); - if ((card = snd_pcm_info_get_card(pcm_info)) >= 0) { + if ((card = snd_pcm_info_get_card(pcm_info)) >= 0) pa_alsa_init_proplist_card(c, p, card); - cn = pa_proplist_gets(p, "alsa.card_name"); - } - - if (cn && n && !strstr(cn, n) && !strstr(n, cn)) - pa_proplist_setf(p, PA_PROP_DEVICE_DESCRIPTION, "%s, %s", cn, n); - else if (cn && (!n || strstr(cn, n))) - pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, cn); - else if (n) - pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, n); } void pa_alsa_init_proplist_pcm(pa_core *c, pa_proplist *p, snd_pcm_t *pcm) { diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h index 899532e2..a8397ae9 100644 --- a/src/modules/alsa/alsa-util.h +++ b/src/modules/alsa/alsa-util.h @@ -123,6 +123,7 @@ void pa_alsa_redirect_errors_dec(void); void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t *pcm_info); void pa_alsa_init_proplist_card(pa_core *c, pa_proplist *p, int card); void pa_alsa_init_proplist_pcm(pa_core *c, pa_proplist *p, snd_pcm_t *pcm); +pa_bool_t pa_alsa_init_description(pa_proplist *p); int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents); diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c index fc6b886b..9e149a48 100644 --- a/src/modules/alsa/module-alsa-card.c +++ b/src/modules/alsa/module-alsa-card.c @@ -318,6 +318,7 @@ int pa__init(pa_module *m) { data.module = m; pa_alsa_init_proplist_card(m->core, data.proplist, alsa_card_index); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device_id); + pa_alsa_init_description(data.proplist); set_card_name(&data, ma, u->device_id); if (reserve) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 7855c2ef..6b522200 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -811,8 +811,8 @@ const char*pa_bluetooth_get_form_factor(uint32_t class) { [1] = "headset", [2] = "hands-free", [4] = "microphone", - [5] = "external-speakers", - [6] = "headphones", + [5] = "speaker", + [6] = "headphone", [7] = "portable", [8] = "car", [10] = "hifi" diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index b2fb1db1..3332df2c 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -1728,7 +1728,7 @@ static int add_card(struct userdata *u, const char * default_profile) { pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device->address); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, "bluez"); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound"); - pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CONNECTOR, "bluetooth"); + pa_proplist_sets(data.proplist, PA_PROP_DEVICE_BUS, "bluetooth"); if ((ff = pa_bluetooth_get_form_factor(u->device->class))) pa_proplist_sets(data.proplist, PA_PROP_DEVICE_FORM_FACTOR, ff); pa_proplist_sets(data.proplist, "bluez.path", u->device->path); diff --git a/src/modules/hal-util.c b/src/modules/hal-util.c index 82bbc57e..6959a706 100644 --- a/src/modules/hal-util.c +++ b/src/modules/hal-util.c @@ -89,6 +89,9 @@ int pa_hal_get_info(pa_core *core, pa_proplist *p, int card) { pa_proplist_sets(p, "hal.udi", udis[i]); + /* The data HAL stores in info.product is not actually a product + * string but simply the ALSA card name. We will hence not write + * it to PA_PROP_DEVICE_PRODUCT_NAME */ t = libhal_device_get_property_string(hal, udis[i], "info.product", &error); if (dbus_error_is_set(&error)) dbus_error_free(&error); diff --git a/src/modules/udev-util.c b/src/modules/udev-util.c new file mode 100644 index 00000000..a72bc8f8 --- /dev/null +++ b/src/modules/udev-util.c @@ -0,0 +1,142 @@ +/*** + This file is part of PulseAudio. + + Copyright 2009 Lennart Poettering + + 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, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <libudev.h> + +#include <pulse/xmalloc.h> +#include <pulse/proplist.h> + +#include <pulsecore/log.h> +#include <pulsecore/core-util.h> + +#include "udev-util.h" + +static int read_id(struct udev_device *d, const char *n) { + const char *v; + unsigned u; + + pa_assert(d); + pa_assert(n); + + if (!(v = udev_device_get_property_value(d, n))) + return -1; + + if (pa_startswith(v, "0x")) + v += 2; + + if (!*v) + return -1; + + if (sscanf(v, "%04x", &u) != 1) + return -1; + + if (u > 0xFFFFU) + return -1; + + return u; +} + +int pa_udev_get_info(pa_core *core, pa_proplist *p, int card_idx) { + int r = -1; + struct udev *udev; + struct udev_device *card; + char *t; + const char *v; + int id; + + pa_assert(core); + pa_assert(p); + pa_assert(card_idx >= 0); + + if (!(udev = udev_new())) { + pa_log_error("Failed to allocate udev context."); + goto finish; + } + + t = pa_sprintf_malloc("%s/class/sound/card%i", udev_get_sys_path(udev), card_idx); + card = udev_device_new_from_syspath(udev, t); + pa_xfree(t); + + if (!card) { + pa_log_error("Failed to get card object."); + goto finish; + } + + if (!pa_proplist_contains(p, PA_PROP_DEVICE_BUS)) + if ((v = udev_device_get_property_value(card, "ID_BUS")) && *v) + pa_proplist_sets(p, PA_PROP_DEVICE_BUS, v); + + if (!pa_proplist_contains(p, PA_PROP_DEVICE_VENDOR_ID)) + if ((id = read_id(card, "ID_VENDOR_ID")) > 0 && *v) + pa_proplist_setf(p, PA_PROP_DEVICE_VENDOR_ID, "%04x", id); + + if (!pa_proplist_contains(p, PA_PROP_DEVICE_VENDOR_NAME)) { + if ((v = udev_device_get_property_value(card, "ID_VENDOR_FROM_DATABASE")) && *v) + pa_proplist_sets(p, PA_PROP_DEVICE_VENDOR_NAME, v); + else if ((v = udev_device_get_property_value(card, "ID_VENDOR")) && *v) + pa_proplist_sets(p, PA_PROP_DEVICE_VENDOR_NAME, v); + } + + if (!pa_proplist_contains(p, PA_PROP_DEVICE_PRODUCT_ID)) + if ((id = read_id(card, "ID_MODEL_ID")) >= 0) + pa_proplist_setf(p, PA_PROP_DEVICE_PRODUCT_ID, "%04x", id); + + if (!pa_proplist_contains(p, PA_PROP_DEVICE_PRODUCT_NAME)) { + if ((v = udev_device_get_property_value(card, "ID_MODEL_FROM_DATABASE")) && *v) + pa_proplist_sets(p, PA_PROP_DEVICE_PRODUCT_NAME, v); + else if ((v = udev_device_get_property_value(card, "ID_MODEL")) && *v) + pa_proplist_sets(p, PA_PROP_DEVICE_PRODUCT_NAME, v); + } + + if (!pa_proplist_contains(p, PA_PROP_DEVICE_SERIAL)) + if ((v = udev_device_get_property_value(card, "ID_SERIAL")) && *v) + pa_proplist_sets(p, PA_PROP_DEVICE_SERIAL, v); + + if (!pa_proplist_contains(p, PA_PROP_DEVICE_FORM_FACTOR)) + if ((v = udev_device_get_property_value(card, "SOUND_FORM_FACTOR")) && *v) + pa_proplist_sets(p, PA_PROP_DEVICE_FORM_FACTOR, v); + + if (!pa_proplist_contains(p, PA_PROP_DEVICE_BUS_PATH)) + if ((v = udev_device_get_devpath(card))) + pa_proplist_sets(p, PA_PROP_DEVICE_BUS_PATH, v); + + /* This is normaly not set by th udev rules but may be useful to + * allow administrators to overwrite the device description.*/ + if (!pa_proplist_contains(p, PA_PROP_DEVICE_DESCRIPTION)) + if ((v = udev_device_get_property_value(card, "SOUND_DESCRIPTION")) && *v) + pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, v); + + r = 0; + +finish: + + if (card) + udev_device_unref(card); + + if (udev) + udev_unref(udev); + + return r; +} diff --git a/src/modules/udev-util.h b/src/modules/udev-util.h new file mode 100644 index 00000000..86fbba7f --- /dev/null +++ b/src/modules/udev-util.h @@ -0,0 +1,30 @@ +#ifndef fooudevutilhfoo +#define fooudevutilhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2009 Lennart Poettering + + 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, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + + +#include <pulsecore/core.h> + +int pa_udev_get_info(pa_core *core, pa_proplist *p, int card); + +#endif diff --git a/src/pulse/proplist.h b/src/pulse/proplist.h index fa44c426..d5f5bc04 100644 --- a/src/pulse/proplist.h +++ b/src/pulse/proplist.h @@ -45,8 +45,10 @@ PA_C_DECL_BEGIN /** For streams: source filename if applicable, in URI format or local path. e.g. "/home/lennart/music/foobar.ogg" */ #define PA_PROP_MEDIA_FILENAME "media.filename" +/** \cond fulldocs */ /** For streams: icon for the media. A binary blob containing PNG image data */ #define PA_PROP_MEDIA_ICON "media.icon" +/** \endcond */ /** For streams: an XDG icon name for the media. e.g. "audio-x-mp3" */ #define PA_PROP_MEDIA_ICON_NAME "media.icon_name" @@ -81,8 +83,10 @@ PA_C_DECL_BEGIN /** For streams that belong to a window on the screen: a textual id for identifying a window logically. e.g. "org.gnome.Totem.MainWindow" */ #define PA_PROP_WINDOW_ID "window.id" +/** \cond fulldocs */ /** For streams that belong to a window on the screen: window icon. A binary blob containing PNG image data */ #define PA_PROP_WINDOW_ICON "window.icon" +/** \endcond */ /** For streams that belong to a window on the screen: an XDG icon name for the window. e.g. "totem" */ #define PA_PROP_WINDOW_ICON_NAME "window.icon_name" @@ -108,8 +112,10 @@ PA_C_DECL_BEGIN /** For clients/streams: a version string e.g. "0.6.88" */ #define PA_PROP_APPLICATION_VERSION "application.version" +/** \cond fulldocs */ /** For clients/streams: application icon. A binary blob containing PNG image data */ #define PA_PROP_APPLICATION_ICON "application.icon" +/** \endcond */ /** For clients/streams: an XDG icon name for the application. e.g. "totem" */ #define PA_PROP_APPLICATION_ICON_NAME "application.icon_name" @@ -150,17 +156,34 @@ PA_C_DECL_BEGIN /** For devices: serial number if applicable. e.g. "4711-0815-1234" */ #define PA_PROP_DEVICE_SERIAL "device.serial" -/** For devices: vendor/product ID if applicable. e.g. 1274:1371 */ -#define PA_PROP_DEVICE_VENDOR_PRODUCT_ID "device.vendor_product_id" +/** For devices: vendor ID if applicable. e.g. 1274 */ +#define PA_PROP_DEVICE_VENDOR_ID "device.vendor.id" + +/** For devices: vendor name if applicable. e.g. "Foocorp Heavy Industries" */ +#define PA_PROP_DEVICE_VENDOR_NAME "device.vendor.name" + +/** For devices: product ID if applicable. e.g. 4565 */ +#define PA_PROP_DEVICE_PRODUCT_ID "device.product.id" + +/** For devices: product name if applicable. e.g. "SuperSpeakers 2000 Pro" */ +#define PA_PROP_DEVICE_PRODUCT_NAME "device.product.name" /** For devices: device class. One of "sound", "modem", "monitor", "filter" */ #define PA_PROP_DEVICE_CLASS "device.class" -/** For devices: form factor if applicable. One of "internal-speakers", "external-speakers", "handset", "tv-capture", "webcam", "microphone", "headset", "headphones", "hands-free", "car", "hifi", "computer", "portable" */ +/** For devices: form factor if applicable. One of "internal", "speaker", "handset", "tv", "webcam", "microphone", "headset", "headphone", "hands-free", "car", "hifi", "computer", "portable" */ #define PA_PROP_DEVICE_FORM_FACTOR "device.form_factor" -/** For devices: connector of the device if applicable. One of "isa", "pci", "usb", "firewire", "bluetooth" */ -#define PA_PROP_DEVICE_CONNECTOR "device.connector" +/** For devices: bus of the device if applicable. One of "isa", "pci", "usb", "firewire", "bluetooth" */ +#define PA_PROP_DEVICE_BUS "device.bus" + +/** \cond fulldocs */ +/** For devices: icon for the device. A binary blob containing PNG image data */ +#define PA_PROP_DEVICE_ICON "device.icon" +/** \endcond */ + +/** For devices: an XDG icon name for the device. e.g. "sound-card-speakers-usb" */ +#define PA_PROP_DEVICE_ICON_NAME "device.icon_name" /** For devices: access mode of the device if applicable. One of "mmap", "mmap_rewrite", "serial" */ #define PA_PROP_DEVICE_ACCESS_MODE "device.access_mode" diff --git a/src/pulse/thread-mainloop.h b/src/pulse/thread-mainloop.h index 4de338a1..f0b1a84b 100644 --- a/src/pulse/thread-mainloop.h +++ b/src/pulse/thread-mainloop.h @@ -108,10 +108,10 @@ PA_C_DECL_BEGIN * Example: * * \code - * static void my_drain_callback(pa_stream*s, int success, void *userdata) { + * static void my_drain_callback(pa_stream *s, int success, void *userdata) { * pa_threaded_mainloop *m; * - * m = (pa_threaded_mainloop*)userdata; + * m = userdata; * assert(m); * * pa_threaded_mainloop_signal(m, 0); @@ -125,7 +125,7 @@ PA_C_DECL_BEGIN * o = pa_stream_drain(s, my_drain_callback, m); * assert(o); * - * while (pa_operation_get_state(o) != OPERATION_DONE) + * while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) * pa_threaded_mainloop_wait(m); * * pa_operation_unref(o); @@ -167,7 +167,7 @@ PA_C_DECL_BEGIN * static void my_drain_callback(pa_stream*s, int success, void *userdata) { * pa_threaded_mainloop *m; * - * m = (pa_threaded_mainloop*)userdata; + * m = userdata; * assert(m); * * drain_result = &success; @@ -183,7 +183,7 @@ PA_C_DECL_BEGIN * o = pa_stream_drain(s, my_drain_callback, m); * assert(o); * - * while (pa_operation_get_state(o) != OPERATION_DONE) + * while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) * pa_threaded_mainloop_wait(m); * * pa_operation_unref(o); diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c index 515d1f90..94064c72 100644 --- a/src/pulsecore/card.c +++ b/src/pulsecore/card.c @@ -160,6 +160,9 @@ pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) { c->userdata = NULL; c->set_profile = NULL; + pa_device_init_description(c->proplist); + pa_device_init_icon(c->proplist, TRUE); + pa_assert_se(pa_idxset_put(core->cards, c, &c->index) >= 0); pa_log_info("Created %u \"%s\"", c->index, c->name); diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 7441e971..fadbb857 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -33,6 +33,7 @@ #include <pulse/xmalloc.h> #include <pulse/timeval.h> #include <pulse/util.h> +#include <pulse/i18n.h> #include <pulsecore/sink-input.h> #include <pulsecore/namereg.h> @@ -172,6 +173,9 @@ pa_sink* pa_sink_new( if (data->card) pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->card->proplist); + pa_device_init_description(data->proplist); + pa_device_init_icon(data->proplist, TRUE); + if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_FIXATE], data) < 0) { pa_xfree(s); pa_namereg_unregister(core, name); @@ -1886,3 +1890,68 @@ size_t pa_sink_get_max_request(pa_sink *s) { return r; } + +/* Called from main context */ +pa_bool_t pa_device_init_icon(pa_proplist *p, pa_bool_t is_sink) { + const char *ff, *t = NULL, *s = "", *profile, *bus; + + pa_assert(p); + + if (pa_proplist_contains(p, PA_PROP_DEVICE_ICON_NAME)) + return TRUE; + + if ((ff = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR))) { + + if (pa_streq(ff, "microphone")) + t = "audio-input-microphone"; + else if (pa_streq(ff, "webcam")) + t = "camera-web"; + else if (pa_streq(ff, "computer")) + t = "computer"; + else if (pa_streq(ff, "handset")) + t = "phone"; + } + + if (!t) { + if (is_sink) + t = "audio-card"; + else + t = "audio-input-microphone"; + } + + if ((profile = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_NAME))) { + if (strstr(profile, "analog")) + s = "-analog"; + else if (strstr(profile, "iec958")) + s = "-iec958"; + else if (strstr(profile, "hdmi")) + s = "-hdmi"; + } + + bus = pa_proplist_gets(p, PA_PROP_DEVICE_BUS); + + pa_proplist_setf(p, PA_PROP_DEVICE_ICON_NAME, "%s%s%s%s", t, pa_strempty(s), bus ? "-" : "", pa_strempty(bus)); + + return TRUE; +} + +pa_bool_t pa_device_init_description(pa_proplist *p) { + const char *s; + pa_assert(p); + + if (pa_proplist_contains(p, PA_PROP_DEVICE_DESCRIPTION)) + return TRUE; + + if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR))) + if (pa_streq(s, "internal")) { + pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, _("Internal Audio")); + return TRUE; + } + + if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_PRODUCT_NAME))) { + pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, s); + return TRUE; + } + + return FALSE; +} diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 124b4e11..2eaae697 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -225,6 +225,9 @@ void pa_sink_attach(pa_sink *s); void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume); +pa_bool_t pa_device_init_description(pa_proplist *p); +pa_bool_t pa_device_init_icon(pa_proplist *p, pa_bool_t is_sink); + /**** May be called by everyone, from main context */ /* The returned value is supposed to be in the time domain of the sound card! */ diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index c0d6d9ea..4ce5cbfe 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -163,6 +163,9 @@ pa_source* pa_source_new( if (data->card) pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->card->proplist); + pa_device_init_description(data->proplist); + pa_device_init_icon(data->proplist, FALSE); + if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], data) < 0) { pa_xfree(s); pa_namereg_unregister(core, name); |