If we know if a certain port is available/unavailable, we can print that out, as a help to the user (and as debugging for ourselves). A profile is also available/unavailable if all ports which have that profile is available/unavailable. --- src/mainwindow.cc | 44 ++++++++++++++++++++++++++++++++++++++------ src/pavucontrol.cc | 16 ++++++++++++++++ src/pavucontrol.h | 1 + 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/mainwindow.cc b/src/mainwindow.cc index dc84682..b843d03 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -285,8 +285,22 @@ void MainWindow::updateCard(const pa_card_info &info) { } w->profiles.clear(); - for (std::set<pa_card_profile_info>::iterator i = profile_priorities.begin(); i != profile_priorities.end(); ++i) - w->profiles.push_back(std::pair<Glib::ustring,Glib::ustring>(i->name, i->description)); + for (std::set<pa_card_profile_info>::iterator i = profile_priorities.begin(); i != profile_priorities.end(); ++i) { + gchar* desc = NULL; + int sums[3] = {0, 0, 0}; +#ifdef HAVE_PORT_AVAILABILITY + for (pa_card_port_info** cp = info.ports; *cp; cp++) + for (pa_card_profile_info** pp = (*cp)->profiles; *pp; pp++) + if ((*pp)->name == i->name && (*cp)->available < 3) + sums[(*cp)->available]++; + if (sums[PA_PORT_AVAILABLE_NO] && !sums[PA_PORT_AVAILABLE_YES] && !sums[PA_PORT_AVAILABLE_UNKNOWN]) + desc = g_strdup_printf(_("%s (unplugged)"), i->description); + else if (sums[PA_PORT_AVAILABLE_YES] && !sums[PA_PORT_AVAILABLE_NO] && !sums[PA_PORT_AVAILABLE_UNKNOWN]) + desc = g_strdup_printf(_("%s (plugged in)"), i->description); +#endif + w->profiles.push_back(std::pair<Glib::ustring,Glib::ustring>(i->name, desc ? desc : i->description)); + g_free(desc); + } w->activeProfile = info.active_profile ? info.active_profile->name : ""; @@ -343,8 +357,17 @@ bool MainWindow::updateSink(const pa_sink_info &info) { } w->ports.clear(); - for (std::set<pa_sink_port_info>::iterator i = port_priorities.begin(); i != port_priorities.end(); ++i) - w->ports.push_back(std::pair<Glib::ustring,Glib::ustring>(i->name, i->description)); + for (std::set<pa_sink_port_info>::iterator i = port_priorities.begin(); i != port_priorities.end(); ++i) { + gchar *desc = NULL; +#ifdef HAVE_PORT_AVAILABILITY + if (i->available == PA_PORT_AVAILABLE_NO) + desc = g_strdup_printf(_("%s (unplugged)"), i->description); + else if (i->available == PA_PORT_AVAILABLE_YES) + desc = g_strdup_printf(_("%s (plugged in)"), i->description); +#endif + w->ports.push_back(std::pair<Glib::ustring,Glib::ustring>(i->name, desc ? desc : i->description)); + g_free(desc); + } w->activePort = info.active_port ? info.active_port->name : ""; @@ -492,8 +515,17 @@ void MainWindow::updateSource(const pa_source_info &info) { } w->ports.clear(); - for (std::set<pa_source_port_info>::iterator i = port_priorities.begin(); i != port_priorities.end(); ++i) - w->ports.push_back(std::pair<Glib::ustring,Glib::ustring>(i->name, i->description)); + for (std::set<pa_source_port_info>::iterator i = port_priorities.begin(); i != port_priorities.end(); ++i) { + gchar *desc = NULL; +#ifdef HAVE_PORT_AVAILABILITY + if (i->available == PA_PORT_AVAILABLE_NO) + desc = g_strdup_printf(_("%s (unplugged)"), i->description); + else if (i->available == PA_PORT_AVAILABLE_YES) + desc = g_strdup_printf(_("%s (plugged in)"), i->description); +#endif + w->ports.push_back(std::pair<Glib::ustring,Glib::ustring>(i->name, desc ? desc : i->description)); + g_free(desc); + } w->activePort = info.active_port ? info.active_port->name : ""; diff --git a/src/pavucontrol.cc b/src/pavucontrol.cc index 72ec980..6a5ff8b 100644 --- a/src/pavucontrol.cc +++ b/src/pavucontrol.cc @@ -426,6 +426,22 @@ void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t index, return; } pa_operation_unref(o); + + /* Because the port availability might have changed, and we don't send + update events for that, we must update sources and sinks belonging. + to that card. Do it for all sources and sinks for simplicity. */ + if (!(o = pa_context_get_sink_info_list(c, sink_cb, w))) { + show_error(_("pa_context_get_sink_info_list() failed")); + return; + } + pa_operation_unref(o); + + if (!(o = pa_context_get_source_info_list(c, source_cb, w))) { + show_error(_("pa_context_get_source_info_list() failed")); + return; + } + pa_operation_unref(o); + } break; diff --git a/src/pavucontrol.h b/src/pavucontrol.h index 65cb913..54321bd 100644 --- a/src/pavucontrol.h +++ b/src/pavucontrol.h @@ -41,6 +41,7 @@ #define HAVE_SOURCE_OUTPUT_VOLUMES PA_CHECK_VERSION(0,99,0) #define HAVE_EXT_DEVICE_RESTORE_API PA_CHECK_VERSION(0,99,0) +#define HAVE_PORT_AVAILABILITY PA_CHECK_VERSION(1,99,0) enum SinkInputType { SINK_INPUT_ALL, -- 1.7.9.5