summaryrefslogtreecommitdiffstats
path: root/src/mainwindow.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mainwindow.cc')
-rw-r--r--src/mainwindow.cc1124
1 files changed, 0 insertions, 1124 deletions
diff --git a/src/mainwindow.cc b/src/mainwindow.cc
deleted file mode 100644
index 0b6b310..0000000
--- a/src/mainwindow.cc
+++ /dev/null
@@ -1,1124 +0,0 @@
-/***
- This file is part of pavucontrol.
-
- Copyright 2006-2008 Lennart Poettering
- Copyright 2009 Colin Guthrie
-
- pavucontrol is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 2 of the License, or
- (at your option) any later version.
-
- pavucontrol 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 General Public License
- along with pavucontrol. If not, see <https://www.gnu.org/licenses/>.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <QDebug>
-#include <set>
-
-#include "mainwindow.h"
-#include "cardwidget.h"
-#include "sinkwidget.h"
-#include "sourcewidget.h"
-#include "sinkinputwidget.h"
-#include "sourceoutputwidget.h"
-#include "rolewidget.h"
-#include <QIcon>
-#include <QStyle>
-#include <QSettings>
-
-struct sink_port_prio_compare {
- bool operator() (const pa_sink_port_info& lhs, const pa_sink_port_info& rhs) const {
-
- if (lhs.priority == rhs.priority)
- return strcmp(lhs.name, rhs.name) > 0;
-
- return lhs.priority > rhs.priority;
- }
-};
-
-struct source_port_prio_compare {
- bool operator() (const pa_source_port_info& lhs, const pa_source_port_info& rhs) const {
-
- if (lhs.priority == rhs.priority)
- return strcmp(lhs.name, rhs.name) > 0;
-
- return lhs.priority > rhs.priority;
- }
-};
-
-MainWindow::MainWindow():
- QDialog(),
- showSinkInputType(SINK_INPUT_CLIENT),
- showSinkType(SINK_ALL),
- showSourceOutputType(SOURCE_OUTPUT_CLIENT),
- showSourceType(SOURCE_NO_MONITOR),
- eventRoleWidget(nullptr),
- canRenameDevices(false),
- m_connected(false),
- m_config_filename(nullptr) {
-
- setupUi(this);
-
- sinkInputTypeComboBox->setCurrentIndex((int) showSinkInputType);
- sourceOutputTypeComboBox->setCurrentIndex((int) showSourceOutputType);
- sinkTypeComboBox->setCurrentIndex((int) showSinkType);
- sourceTypeComboBox->setCurrentIndex((int) showSourceType);
-
- connect(sinkInputTypeComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MainWindow::onSinkInputTypeComboBoxChanged);
- connect(sourceOutputTypeComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MainWindow::onSourceOutputTypeComboBoxChanged);
- connect(sinkTypeComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MainWindow::onSinkTypeComboBoxChanged);
- connect(sourceTypeComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MainWindow::onSourceTypeComboBoxChanged);
- connect(showVolumeMetersCheckButton, &QCheckBox::toggled, this, &MainWindow::onShowVolumeMetersCheckButtonToggled);
-
- QAction * quit = new QAction{this};
- connect(quit, &QAction::triggered, this, &QWidget::close);
- quit->setShortcut(QKeySequence::Quit);
- addAction(quit);
-
- const QSettings config;
-
- showVolumeMetersCheckButton->setChecked(config.value(QStringLiteral("window/showVolumeMeters"), true).toBool());
-
- const QSize last_size = config.value(QStringLiteral("window/size")).toSize();
- if (last_size.isValid())
- resize(last_size);
-
- const QVariant sinkInputTypeSelection = config.value(QStringLiteral("window/sinkInputType"));
- if (sinkInputTypeSelection.isValid())
- sinkInputTypeComboBox->setCurrentIndex(sinkInputTypeSelection.toInt());
-
- const QVariant sourceOutputTypeSelection = config.value(QStringLiteral("window/sourceOutputType"));
- if (sourceOutputTypeSelection.isValid())
- sourceOutputTypeComboBox->setCurrentIndex(sourceOutputTypeSelection.toInt());
-
- const QVariant sinkTypeSelection = config.value(QStringLiteral("window/sinkType"));
- if (sinkTypeSelection.isValid())
- sinkTypeComboBox->setCurrentIndex(sinkTypeSelection.toInt());
-
- const QVariant sourceTypeSelection = config.value(QStringLiteral("window/sourceType"));
- if (sourceTypeSelection.isValid())
- sourceTypeComboBox->setCurrentIndex(sourceTypeSelection.toInt());
-
- /* Hide first and show when we're connected */
- notebook->hide();
- connectingLabel->show();
-}
-
-MainWindow::~MainWindow() {
- QSettings config;
- config.setValue(QStringLiteral("window/size"), size());
- config.setValue(QStringLiteral("window/sinkInputType"), sinkInputTypeComboBox->currentIndex());
- config.setValue(QStringLiteral("window/sourceOutputType"), sourceOutputTypeComboBox->currentIndex());
- config.setValue(QStringLiteral("window/sinkType"), sinkTypeComboBox->currentIndex());
- config.setValue(QStringLiteral("window/sourceType"), sourceTypeComboBox->currentIndex());
- config.setValue(QStringLiteral("window/showVolumeMeters"), showVolumeMetersCheckButton->isChecked());
-
- while (!clientNames.empty()) {
- auto i = clientNames.begin();
- g_free(i->second);
- clientNames.erase(i);
- }
-}
-
-class DeviceWidget;
-static void updatePorts(DeviceWidget *w, std::map<QByteArray, PortInfo> &ports) {
- std::map<QByteArray, PortInfo>::iterator it;
- PortInfo p;
-
- for (auto & port : w->ports) {
- QByteArray desc;
- it = ports.find(port.first);
-
- if (it == ports.end())
- continue;
-
- p = it->second;
- desc = p.description;
-
- if (p.available == PA_PORT_AVAILABLE_YES)
- desc += MainWindow::tr(" (plugged in)").toUtf8().constData();
- else if (p.available == PA_PORT_AVAILABLE_NO) {
- if (p.name == "analog-output-speaker" ||
- p.name == "analog-input-microphone-internal")
- desc += MainWindow::tr(" (unavailable)").toUtf8().constData();
- else
- desc += MainWindow::tr(" (unplugged)").toUtf8().constData();
- }
-
- port.second = desc;
- }
-
- it = ports.find(w->activePort);
-
- if (it != ports.end()) {
- p = it->second;
- w->setLatencyOffset(p.latency_offset);
- }
-}
-
-static void setIconByName(QLabel* label, const char* name, const char* fallback_name = nullptr) {
- QIcon icon = QIcon::fromTheme(QString::fromLatin1(name));
- if (icon.isNull() || icon.availableSizes().isEmpty())
- icon = QIcon::fromTheme(QString::fromLatin1(fallback_name));
- int size = label->style()->pixelMetric(QStyle::PM_ToolBarIconSize);
- QPixmap pix = icon.pixmap(size, size);
- label->setPixmap(pix);
-}
-
-void MainWindow::updateCard(const pa_card_info &info) {
- CardWidget *w;
- bool is_new = false;
- const char *description, *icon;
- std::set<pa_card_profile_info2 *, profile_prio_compare> profile_priorities;
-
- if (cardWidgets.count(info.index))
- w = cardWidgets[info.index];
- else {
- cardWidgets[info.index] = w = new CardWidget(this);
- cardsVBox->layout()->addWidget(w);
- w->index = info.index;
- is_new = true;
- }
-
- w->updating = true;
-
- description = pa_proplist_gets(info.proplist, PA_PROP_DEVICE_DESCRIPTION);
- w->name = description ? description : info.name;
- w->nameLabel->setText(QString::fromUtf8(w->name));
-
- icon = pa_proplist_gets(info.proplist, PA_PROP_DEVICE_ICON_NAME);
- setIconByName(w->iconImage, icon, "audio-card");
-
- w->hasSinks = w->hasSources = false;
-
- profile_priorities.clear();
- for (pa_card_profile_info2 ** p_profile = info.profiles2; p_profile && *p_profile != nullptr; ++p_profile) {
- w->hasSinks = w->hasSinks || ((*p_profile)->n_sinks > 0);
- w->hasSources = w->hasSources || ((*p_profile)->n_sources > 0);
- profile_priorities.insert(*p_profile);
- }
-
- populatePorts(info, w->ports);
-
- groupProfiles(profile_priorities, w->ports, w->profiles);
-
- w->activeProfile = info.active_profile ? info.active_profile->name : "";
-
- /* Because the port info for sinks and sources is discontinued we need
- * to update the port info for them here. */
- if (w->hasSinks) {
- std::map<uint32_t, SinkWidget*>::iterator it;
-
- for (it = sinkWidgets.begin() ; it != sinkWidgets.end(); it++) {
- SinkWidget *sw = it->second;
-
- if (sw->card_index == w->index) {
- sw->updating = true;
- updatePorts(sw, w->ports);
- sw->updating = false;
- }
- }
- }
-
- if (w->hasSources) {
- std::map<uint32_t, SourceWidget*>::iterator it;
-
- for (it = sourceWidgets.begin() ; it != sourceWidgets.end(); it++) {
- SourceWidget *sw = it->second;
-
- if (sw->card_index == w->index) {
- sw->updating = true;
- updatePorts(sw, w->ports);
- sw->updating = false;
- }
- }
- }
- w->prepareMenu();
-
- if (is_new)
- updateDeviceVisibility();
-
- w->updating = false;
-}
-
-bool MainWindow::updateSink(const pa_sink_info &info) {
- SinkWidget *w;
- bool is_new = false;
-
- const char *icon;
- std::map<uint32_t, CardWidget*>::iterator cw;
- std::set<pa_sink_port_info,sink_port_prio_compare> port_priorities;
-
- if (sinkWidgets.count(info.index))
- w = sinkWidgets[info.index];
- else {
- sinkWidgets[info.index] = w = new SinkWidget(this);
- w->setChannelMap(info.channel_map, !!(info.flags & PA_SINK_DECIBEL_VOLUME));
- sinksVBox->layout()->addWidget(w);
- w->index = info.index;
- w->monitor_index = info.monitor_source;
- is_new = true;
-
- w->setBaseVolume(info.base_volume);
- w->setVolumeMeterVisible(showVolumeMetersCheckButton->isChecked());
- }
-
- w->updating = true;
-
- w->card_index = info.card;
- w->name = info.name;
- w->description = info.description;
- w->type = info.flags & PA_SINK_HARDWARE ? SINK_HARDWARE : SINK_VIRTUAL;
-
- w->boldNameLabel->setText(QLatin1String(""));
- gchar *txt = g_markup_printf_escaped("%s", info.description);
- w->nameLabel->setText(QString::fromUtf8(static_cast<char*>(txt)));
- w->nameLabel->setToolTip(QString::fromUtf8(info.description));
- g_free(txt);
-
- icon = pa_proplist_gets(info.proplist, PA_PROP_DEVICE_ICON_NAME);
- setIconByName(w->iconImage, icon, "audio-card");
-
- w->setVolume(info.volume);
- w->muteToggleButton->setChecked(info.mute);
-
- w->setDefault(w->name == defaultSinkName);
-
- port_priorities.clear();
- for (uint32_t i=0; i<info.n_ports; ++i) {
- port_priorities.insert(*info.ports[i]);
- }
-
- w->ports.clear();
- for (const auto & port_prioritie : port_priorities)
- w->ports.push_back(std::pair<QByteArray,QByteArray>(port_prioritie.name, port_prioritie.description));
-
- w->activePort = info.active_port ? info.active_port->name : "";
-
- cw = cardWidgets.find(info.card);
-
- if (cw != cardWidgets.end())
- updatePorts(w, cw->second->ports);
-
-#ifdef PA_SINK_SET_FORMATS
- w->setDigital(info.flags & PA_SINK_SET_FORMATS);
-#endif
-
- w->prepareMenu();
-
- w->updating = false;
- if (is_new)
- updateDeviceVisibility();
-
- return is_new;
-}
-
-static void suspended_callback(pa_stream *s, void *userdata) {
- MainWindow *w = static_cast<MainWindow*>(userdata);
-
- if (pa_stream_is_suspended(s))
- w->updateVolumeMeter(pa_stream_get_device_index(s), PA_INVALID_INDEX, -1);
-}
-
-static void read_callback(pa_stream *s, size_t length, void *userdata) {
- MainWindow *w = static_cast<MainWindow*>(userdata);
- const void *data;
- double v;
-
- if (pa_stream_peek(s, &data, &length) < 0) {
- show_error(MainWindow::tr("Failed to read data from stream").toUtf8().constData());
- return;
- }
-
- if (!data) {
- /* nullptr data means either a hole or empty buffer.
- * Only drop the stream when there is a hole (length > 0) */
- if (length)
- pa_stream_drop(s);
- return;
- }
-
- assert(length > 0);
- assert(length % sizeof(float) == 0);
-
- v = ((const float*) data)[length / sizeof(float) -1];
-
- pa_stream_drop(s);
-
- if (v < 0)
- v = 0;
- if (v > 1)
- v = 1;
-
- w->updateVolumeMeter(pa_stream_get_device_index(s), pa_stream_get_monitor_stream(s), v);
-}
-
-pa_stream* MainWindow::createMonitorStreamForSource(uint32_t source_idx, uint32_t stream_idx = -1, bool suspend = false) {
- pa_stream *s;
- char t[16];
- pa_buffer_attr attr;
- pa_sample_spec ss;
- pa_stream_flags_t flags;
-
- ss.channels = 1;
- ss.format = PA_SAMPLE_FLOAT32;
- ss.rate = 25;
-
- memset(&attr, 0, sizeof(attr));
- attr.fragsize = sizeof(float);
- attr.maxlength = (uint32_t) -1;
-
- snprintf(t, sizeof(t), "%u", source_idx);
-
- if (!(s = pa_stream_new(get_context(), tr("Peak detect").toUtf8().constData(), &ss, nullptr))) {
- show_error(tr("Failed to create monitoring stream").toUtf8().constData());
- return nullptr;
- }
-
- if (stream_idx != (uint32_t) -1)
- pa_stream_set_monitor_stream(s, stream_idx);
-
- pa_stream_set_read_callback(s, read_callback, this);
- pa_stream_set_suspended_callback(s, suspended_callback, this);
-
- flags = (pa_stream_flags_t) (PA_STREAM_DONT_MOVE | PA_STREAM_PEAK_DETECT | PA_STREAM_ADJUST_LATENCY |
- (suspend ? PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND : PA_STREAM_NOFLAGS) |
- (!showVolumeMetersCheckButton->isChecked() ? PA_STREAM_START_CORKED : PA_STREAM_NOFLAGS));
-
- if (pa_stream_connect_record(s, t, &attr, flags) < 0) {
- show_error(tr("Failed to connect monitoring stream").toUtf8().constData());
- pa_stream_unref(s);
- return nullptr;
- }
- return s;
-}
-
-void MainWindow::createMonitorStreamForSinkInput(SinkInputWidget* w, uint32_t sink_idx) {
- if (!sinkWidgets.count(sink_idx))
- return;
-
- if (w->peak) {
- pa_stream_disconnect(w->peak);
- w->peak = nullptr;
- }
-
- w->peak = createMonitorStreamForSource(sinkWidgets[sink_idx]->monitor_index, w->index);
-}
-
-void MainWindow::updateSource(const pa_source_info &info) {
- SourceWidget *w;
- bool is_new = false;
- const char *icon;
- std::map<uint32_t, CardWidget*>::iterator cw;
- std::set<pa_source_port_info,source_port_prio_compare> port_priorities;
-
- if (sourceWidgets.count(info.index))
- w = sourceWidgets[info.index];
- else {
- sourceWidgets[info.index] = w = new SourceWidget(this);
- w->setChannelMap(info.channel_map, !!(info.flags & PA_SOURCE_DECIBEL_VOLUME));
- sourcesVBox->layout()->addWidget(w);
-
- w->index = info.index;
- is_new = true;
-
- w->setBaseVolume(info.base_volume);
- w->setVolumeMeterVisible(showVolumeMetersCheckButton->isChecked());
-
- if (pa_context_get_server_protocol_version(get_context()) >= 13)
- w->peak = createMonitorStreamForSource(info.index, -1, !!(info.flags & PA_SOURCE_NETWORK));
- }
-
- w->updating = true;
-
- w->card_index = info.card;
- w->name = info.name;
- w->description = info.description;
- w->type = info.monitor_of_sink != PA_INVALID_INDEX ? SOURCE_MONITOR : (info.flags & PA_SOURCE_HARDWARE ? SOURCE_HARDWARE : SOURCE_VIRTUAL);
-
- w->boldNameLabel->setText(QLatin1String(""));
- gchar *txt = g_markup_printf_escaped("%s", info.description);
- w->nameLabel->setText(QString::fromUtf8(static_cast<char*>(txt)));
- w->nameLabel->setToolTip(QString::fromUtf8(info.description));
- g_free(txt);
-
- icon = pa_proplist_gets(info.proplist, PA_PROP_DEVICE_ICON_NAME);
- setIconByName(w->iconImage, icon, "audio-input-microphone");
-
- w->setVolume(info.volume);
- w->muteToggleButton->setChecked(info.mute);
-
- w->setDefault(w->name == defaultSourceName);
-
- port_priorities.clear();
- for (uint32_t i=0; i<info.n_ports; ++i) {
- port_priorities.insert(*info.ports[i]);
- }
-
-
- w->ports.clear();
- for (const auto & port_prioritie : port_priorities)
- w->ports.push_back(std::pair<QByteArray,QByteArray>(port_prioritie.name, port_prioritie.description));
-
- w->activePort = info.active_port ? info.active_port->name : "";
-
- cw = cardWidgets.find(info.card);
-
- if (cw != cardWidgets.end())
- updatePorts(w, cw->second->ports);
-
- w->prepareMenu();
-
- w->updating = false;
-
- if (is_new)
- updateDeviceVisibility();
-}
-
-
-void MainWindow::setIconFromProplist(QLabel *icon, pa_proplist *l, const char *def) {
- const char *t;
-
- if ((t = pa_proplist_gets(l, PA_PROP_MEDIA_ICON_NAME)))
- goto finish;
-
- if ((t = pa_proplist_gets(l, PA_PROP_WINDOW_ICON_NAME)))
- goto finish;
-
- if ((t = pa_proplist_gets(l, PA_PROP_APPLICATION_ICON_NAME)))
- goto finish;
-
- if ((t = pa_proplist_gets(l, PA_PROP_MEDIA_ROLE))) {
-
- if (strcmp(t, "video") == 0 ||
- strcmp(t, "phone") == 0)
- goto finish;
-
- if (strcmp(t, "music") == 0) {
- t = "audio";
- goto finish;
- }
-
- if (strcmp(t, "game") == 0) {
- t = "applications-games";
- goto finish;
- }
-
- if (strcmp(t, "event") == 0) {
- t = "dialog-information";
- goto finish;
- }
- }
-
- t = def;
-
-finish:
-
- setIconByName(icon, t, def);
-}
-
-
-void MainWindow::updateSinkInput(const pa_sink_input_info &info) {
- const char *t;
- SinkInputWidget *w;
- bool is_new = false;
-
- if ((t = pa_proplist_gets(info.proplist, "module-stream-restore.id"))) {
- if (strcmp(t, "sink-input-by-media-role:event") == 0) {
- g_debug("%s", tr("Ignoring sink-input due to it being designated as an event and thus handled by the Event widget").toUtf8().constData());
- return;
- }
- }
-
- if (sinkInputWidgets.count(info.index)) {
- w = sinkInputWidgets[info.index];
- if (pa_context_get_server_protocol_version(get_context()) >= 13)
- if (w->sinkIndex() != info.sink)
- createMonitorStreamForSinkInput(w, info.sink);
- } else {
- sinkInputWidgets[info.index] = w = new SinkInputWidget(this);
- w->setChannelMap(info.channel_map, true);
- streamsVBox->layout()->addWidget(w);
-
- w->index = info.index;
- w->clientIndex = info.client;
- is_new = true;
- w->setVolumeMeterVisible(showVolumeMetersCheckButton->isChecked());
-
- if (pa_context_get_server_protocol_version(get_context()) >= 13)
- createMonitorStreamForSinkInput(w, info.sink);
- }
-
- w->updating = true;
-
- w->type = info.client != PA_INVALID_INDEX ? SINK_INPUT_CLIENT : SINK_INPUT_VIRTUAL;
-
- w->setSinkIndex(info.sink);
-
- char *txt;
- if (clientNames.count(info.client)) {
- w->boldNameLabel->setText(QString::fromUtf8(txt = g_markup_printf_escaped("<b>%s</b>", clientNames[info.client])));
- g_free(txt);
- w->nameLabel->setText(QString::fromUtf8(txt = g_markup_printf_escaped(": %s", info.name)));
- g_free(txt);
- } else {
- w->boldNameLabel->setText(QLatin1String(""));
- w->nameLabel->setText(QString::fromUtf8(info.name));
- }
-
- w->nameLabel->setToolTip(QString::fromUtf8(info.name));
-
- setIconFromProplist(w->iconImage, info.proplist, "audio-card");
-
- w->setVolume(info.volume);
- w->muteToggleButton->setChecked(info.mute);
-
- w->updating = false;
-
- if (is_new)
- updateDeviceVisibility();
-}
-
-void MainWindow::updateSourceOutput(const pa_source_output_info &info) {
- SourceOutputWidget *w;
- const char *app;
- bool is_new = false;
-
- if ((app = pa_proplist_gets(info.proplist, PA_PROP_APPLICATION_ID)))
- if (strcmp(app, "org.PulseAudio.pavucontrol") == 0
- || strcmp(app, "org.gnome.VolumeControl") == 0
- || strcmp(app, "org.kde.kmixd") == 0)
- return;
-
- if (sourceOutputWidgets.count(info.index))
- w = sourceOutputWidgets[info.index];
- else {
- sourceOutputWidgets[info.index] = w = new SourceOutputWidget(this);
-#if HAVE_SOURCE_OUTPUT_VOLUMES
- w->setChannelMap(info.channel_map, true);
-#endif
- recsVBox->layout()->addWidget(w);
-
- w->index = info.index;
- w->clientIndex = info.client;
- is_new = true;
- w->setVolumeMeterVisible(showVolumeMetersCheckButton->isChecked());
- }
-
- w->updating = true;
-
- w->type = info.client != PA_INVALID_INDEX ? SOURCE_OUTPUT_CLIENT : SOURCE_OUTPUT_VIRTUAL;
-
- w->setSourceIndex(info.source);
-
- char *txt;
- if (clientNames.count(info.client)) {
- w->boldNameLabel->setText(QString::fromUtf8(txt = g_markup_printf_escaped("<b>%s</b>", clientNames[info.client])));
- g_free(txt);
- w->nameLabel->setText(QString::fromUtf8(txt = g_markup_printf_escaped(": %s", info.name)));
- g_free(txt);
- } else {
- w->boldNameLabel->setText(QLatin1String(""));
- w->nameLabel->setText(QString::fromUtf8(info.name));
- }
-
- w->nameLabel->setToolTip(QString::fromUtf8(info.name));
-
- setIconFromProplist(w->iconImage, info.proplist, "audio-input-microphone");
-
-#if HAVE_SOURCE_OUTPUT_VOLUMES
- w->setVolume(info.volume);
- w->muteToggleButton->setChecked(info.mute);
-#endif
-
- w->updating = false;
-
- if (is_new)
- updateDeviceVisibility();
-}
-
-void MainWindow::updateClient(const pa_client_info &info) {
- g_free(clientNames[info.index]);
- clientNames[info.index] = g_strdup(info.name);
-
- for (auto & sinkInputWidget : sinkInputWidgets) {
- SinkInputWidget *w = sinkInputWidget.second;
-
- if (!w)
- continue;
-
- if (w->clientIndex == info.index) {
- gchar *txt;
- w->boldNameLabel->setText(QString::fromUtf8(txt = g_markup_printf_escaped("<b>%s</b>", info.name)));
- g_free(txt);
- }
- }
-}
-
-void MainWindow::updateServer(const pa_server_info &info) {
- defaultSourceName = info.default_source_name ? info.default_source_name : "";
- defaultSinkName = info.default_sink_name ? info.default_sink_name : "";
-
- for (auto & sinkWidget : sinkWidgets) {
- SinkWidget *w = sinkWidget.second;
-
- if (!w)
- continue;
-
- w->updating = true;
- w->setDefault(w->name == defaultSinkName);
-
- w->updating = false;
- }
-
- for (auto & sourceWidget : sourceWidgets) {
- SourceWidget *w = sourceWidget.second;
-
- if (!w)
- continue;
-
- w->updating = true;
- w->setDefault(w->name == defaultSourceName);
- w->updating = false;
- }
-}
-
-bool MainWindow::createEventRoleWidget() {
- if (eventRoleWidget)
- return false;
-
- pa_channel_map cm = {
- 1, { PA_CHANNEL_POSITION_MONO }
- };
-
- eventRoleWidget = new RoleWidget(this);
- streamsVBox->layout()->addWidget(eventRoleWidget);
- eventRoleWidget->role = "sink-input-by-media-role:event";
- eventRoleWidget->setChannelMap(cm, true);
-
- eventRoleWidget->boldNameLabel->setText(QLatin1String(""));
- eventRoleWidget->nameLabel->setText(tr("System Sounds"));
-
- setIconByName(eventRoleWidget->iconImage, "multimedia-volume-control");
-
- eventRoleWidget->device = "";
-
- eventRoleWidget->updating = true;
-
- pa_cvolume volume;
- volume.channels = 1;
- volume.values[0] = PA_VOLUME_NORM;
-
- eventRoleWidget->setVolume(volume);
- eventRoleWidget->muteToggleButton->setChecked(false);
-
- eventRoleWidget->updating = false;
- return TRUE;
-}
-
-void MainWindow::deleteEventRoleWidget() {
- delete eventRoleWidget;
- eventRoleWidget = nullptr;
-}
-
-void MainWindow::updateRole(const pa_ext_stream_restore_info &info) {
- pa_cvolume volume;
- bool is_new = false;
-
- if (strcmp(info.name, "sink-input-by-media-role:event") != 0)
- return;
-
- is_new = createEventRoleWidget();
-
- eventRoleWidget->updating = true;
-
- eventRoleWidget->device = info.device ? info.device : "";
-
- volume.channels = 1;
- volume.values[0] = pa_cvolume_max(&info.volume);
-
- eventRoleWidget->setVolume(volume);
- eventRoleWidget->muteToggleButton->setChecked(info.mute);
-
- eventRoleWidget->updating = false;
-
- if (is_new)
- updateDeviceVisibility();
-}
-
-#if HAVE_EXT_DEVICE_RESTORE_API
-void MainWindow::updateDeviceInfo(const pa_ext_device_restore_info &info) {
- if (sinkWidgets.count(info.index)) {
- SinkWidget *w;
- pa_format_info *format;
-
- w = sinkWidgets[info.index];
-
- w->updating = true;
-
- /* Unselect everything */
- for (int j = 1; j < PAVU_NUM_ENCODINGS; ++j)
- w->encodings[j].widget->setChecked(false);
-
-
- for (uint8_t i = 0; i < info.n_formats; ++i) {
- format = info.formats[i];
- for (int j = 1; j < PAVU_NUM_ENCODINGS; ++j) {
- if (format->encoding == w->encodings[j].encoding) {
- w->encodings[j].widget->setChecked(true);
- break;
- }
- }
- }
-
- w->updating = false;
- }
-}
-#endif
-
-
-void MainWindow::updateVolumeMeter(uint32_t source_index, uint32_t sink_input_idx, double v) {
- if (sink_input_idx != PA_INVALID_INDEX) {
- SinkInputWidget *w;
-
- if (sinkInputWidgets.count(sink_input_idx)) {
- w = sinkInputWidgets[sink_input_idx];
- w->updatePeak(v);
- }
-
- } else {
-
- for (auto & sinkWidget : sinkWidgets) {
- SinkWidget* w = sinkWidget.second;
-
- if (w->monitor_index == source_index)
- w->updatePeak(v);
- }
-
- for (auto & sourceWidget : sourceWidgets) {
- SourceWidget* w = sourceWidget.second;
-
- if (w->index == source_index)
- w->updatePeak(v);
- }
-
- for (auto & sourceOutputWidget : sourceOutputWidgets) {
- SourceOutputWidget* w = sourceOutputWidget.second;
-
- if (w->sourceIndex() == source_index)
- w->updatePeak(v);
- }
- }
-}
-
-static guint idle_source = 0;
-
-gboolean idle_cb(gpointer data) {
- ((MainWindow*) data)->reallyUpdateDeviceVisibility();
- idle_source = 0;
- return FALSE;
-}
-
-void MainWindow::setConnectionState(gboolean connected) {
- if (m_connected != connected) {
- m_connected = connected;
- if (m_connected) {
- connectingLabel->hide();
- notebook->show();
- } else {
- notebook->hide();
- connectingLabel->show();
- }
- }
-}
-
-void MainWindow::updateDeviceVisibility() {
-
- if (idle_source)
- return;
-
- idle_source = g_idle_add(idle_cb, this);
-}
-
-void MainWindow::reallyUpdateDeviceVisibility() {
- bool is_empty = true;
-
- for (auto & sinkInputWidget : sinkInputWidgets) {
- SinkInputWidget* w = sinkInputWidget.second;
-
- if (sinkWidgets.size() > 1) {
- w->directionLabel->show();
- w->deviceButton->show();
- } else {
- w->directionLabel->hide();
- w->deviceButton->hide();
- }
-
- if (showSinkInputType == SINK_INPUT_ALL || w->type == showSinkInputType) {
- w->show();
- is_empty = false;
- } else
- w->hide();
- }
-
- if (eventRoleWidget)
- is_empty = false;
-
- if (is_empty)
- noStreamsLabel->show();
- else
- noStreamsLabel->hide();
-
- is_empty = true;
-
- for (auto & sourceOutputWidget : sourceOutputWidgets) {
- SourceOutputWidget* w = sourceOutputWidget.second;
-
- if (sourceWidgets.size() > 1) {
- w->directionLabel->show();
- w->deviceButton->show();
- } else {
- w->directionLabel->hide();
- w->deviceButton->hide();
- }
-
- if (showSourceOutputType == SOURCE_OUTPUT_ALL || w->type == showSourceOutputType) {
- w->show();
- is_empty = false;
- } else
- w->hide();
- }
-
- if (is_empty)
- noRecsLabel->show();
- else
- noRecsLabel->hide();
-
- is_empty = true;
-
- for (auto & sinkWidget : sinkWidgets) {
- SinkWidget* w = sinkWidget.second;
-
- if (showSinkType == SINK_ALL || w->type == showSinkType) {
- w->show();
- is_empty = false;
- } else
- w->hide();
- }
-
- if (is_empty)
- noSinksLabel->show();
- else
- noSinksLabel->hide();
-
- is_empty = true;
-
- for (auto & cardWidget : cardWidgets) {
- CardWidget* w = cardWidget.second;
-
- w->show();
- is_empty = false;
- }
-
- if (is_empty)
- noCardsLabel->show();
- else
- noCardsLabel->hide();
-
- is_empty = true;
-
- for (auto & sourceWidget : sourceWidgets) {
- SourceWidget* w = sourceWidget.second;
-
- if (showSourceType == SOURCE_ALL ||
- w->type == showSourceType ||
- (showSourceType == SOURCE_NO_MONITOR && w->type != SOURCE_MONITOR)) {
- w->show();
- is_empty = false;
- } else
- w->hide();
- }
-
- if (is_empty)
- noSourcesLabel->show();
- else
- noSourcesLabel->hide();
-
- /* Hmm, if I don't call hide()/show() here some widgets will never
- * get their proper space allocated */
- sinksVBox->hide();
- sinksVBox->show();
- sourcesVBox->hide();
- sourcesVBox->show();
- streamsVBox->hide();
- streamsVBox->show();
- recsVBox->hide();
- recsVBox->show();
- cardsVBox->hide();
- cardsVBox->show();
-}
-
-void MainWindow::removeCard(uint32_t index) {
- if (!cardWidgets.count(index))
- return;
-
- delete cardWidgets[index];
- cardWidgets.erase(index);
- updateDeviceVisibility();
-}
-
-void MainWindow::removeSink(uint32_t index) {
- if (!sinkWidgets.count(index))
- return;
-
- delete sinkWidgets[index];
- sinkWidgets.erase(index);
- updateDeviceVisibility();
-}
-
-void MainWindow::removeSource(uint32_t index) {
- if (!sourceWidgets.count(index))
- return;
-
- delete sourceWidgets[index];
- sourceWidgets.erase(index);
- updateDeviceVisibility();
-}
-
-void MainWindow::removeSinkInput(uint32_t index) {
- if (!sinkInputWidgets.count(index))
- return;
-
- delete sinkInputWidgets[index];
- sinkInputWidgets.erase(index);
- updateDeviceVisibility();
-}
-
-void MainWindow::removeSourceOutput(uint32_t index) {
- if (!sourceOutputWidgets.count(index))
- return;
-
- delete sourceOutputWidgets[index];
- sourceOutputWidgets.erase(index);
- updateDeviceVisibility();
-}
-
-void MainWindow::removeClient(uint32_t index) {
- g_free(clientNames[index]);
- clientNames.erase(index);
-}
-
-void MainWindow::removeAllWidgets() {
- for (auto & sinkInputWidget : sinkInputWidgets)
- removeSinkInput(sinkInputWidget.first);
- for (auto & sourceOutputWidget : sourceOutputWidgets)
- removeSourceOutput(sourceOutputWidget.first);
- for (auto & sinkWidget : sinkWidgets)
- removeSink(sinkWidget.first);
- for (auto & sourceWidget : sourceWidgets)
- removeSource(sourceWidget.first);
- for (auto & cardWidget : cardWidgets)
- removeCard(cardWidget.first);
- for (auto & clientName : clientNames)
- removeClient(clientName.first);
- deleteEventRoleWidget();
-}
-
-void MainWindow::setConnectingMessage(const char *string) {
- QByteArray markup = "<i>";
- if (!string)
- markup += tr("Establishing connection to PulseAudio. Please wait...").toUtf8().constData();
- else
- markup += string;
- markup += "</i>";
- connectingLabel->setText(QString::fromUtf8(markup));
-}
-
-void MainWindow::onSinkTypeComboBoxChanged(int /*index*/) {
- showSinkType = (SinkType) sinkTypeComboBox->currentIndex();
-
- if (showSinkType == (SinkType) -1)
- sinkTypeComboBox->setCurrentIndex((int) SINK_ALL);
-
- updateDeviceVisibility();
-}
-
-void MainWindow::onSourceTypeComboBoxChanged(int /*index*/) {
- showSourceType = (SourceType) sourceTypeComboBox->currentIndex();
-
- if (showSourceType == (SourceType) -1)
- sourceTypeComboBox->setCurrentIndex((int) SOURCE_NO_MONITOR);
-
- updateDeviceVisibility();
-}
-
-void MainWindow::onSinkInputTypeComboBoxChanged(int /*index*/) {
- showSinkInputType = (SinkInputType) sinkInputTypeComboBox->currentIndex();
-
- if (showSinkInputType == (SinkInputType) -1)
- sinkInputTypeComboBox->setCurrentIndex((int) SINK_INPUT_CLIENT);
-
- updateDeviceVisibility();
-}
-
-void MainWindow::onSourceOutputTypeComboBoxChanged(int /*index*/) {
- showSourceOutputType = (SourceOutputType) sourceOutputTypeComboBox->currentIndex();
-
- if (showSourceOutputType == (SourceOutputType) -1)
- sourceOutputTypeComboBox->setCurrentIndex((int) SOURCE_OUTPUT_CLIENT);
-
- updateDeviceVisibility();
-}
-
-
-void MainWindow::onShowVolumeMetersCheckButtonToggled(bool /*toggled*/) {
- bool state = showVolumeMetersCheckButton->isChecked();
- pa_operation *o;
-
- for (auto & sinkWidget : sinkWidgets) {
- SinkWidget *sw = sinkWidget.second;
- if (sw->peak) {
- o = pa_stream_cork(sw->peak, (int)!state, nullptr, nullptr);
- if (o)
- pa_operation_unref(o);
- }
- sw->setVolumeMeterVisible(state);
- }
- for (auto & sourceWidget : sourceWidgets) {
- SourceWidget *sw = sourceWidget.second;
- if (sw->peak) {
- o = pa_stream_cork(sw->peak, (int)!state, nullptr, nullptr);
- if (o)
- pa_operation_unref(o);
- }
- sw->setVolumeMeterVisible(state);
- }
- for (auto & sinkInputWidget : sinkInputWidgets) {
- SinkInputWidget *sw = sinkInputWidget.second;
- if (sw->peak) {
- o = pa_stream_cork(sw->peak, (int)!state, nullptr, nullptr);
- if (o)
- pa_operation_unref(o);
- }
- sw->setVolumeMeterVisible(state);
- }
- for (auto & sourceOutputWidget : sourceOutputWidgets) {
- SourceOutputWidget *sw = sourceOutputWidget.second;
- if (sw->peak) {
- o = pa_stream_cork(sw->peak, (int)!state, nullptr, nullptr);
- if (o)
- pa_operation_unref(o);
- }
- sw->setVolumeMeterVisible(state);
- }
-}