summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2007-09-02 23:38:55 +0000
committerLennart Poettering <lennart@poettering.net>2007-09-02 23:38:55 +0000
commite41c9bed6c792c566436c29e2116406acc06b05e (patch)
treec1894855594fcde07240bfc7cb3b069b1353f0c3
parente7ecb632499a5c71350b676e9f1316e4c17d3040 (diff)
add popup menu to sink/source view to choose default device
git-svn-id: file:///home/lennart/svn/public/pavucontrol/trunk@61 c17c95f2-f111-0410-90bf-f30a9569010c
-rw-r--r--src/pavucontrol.cc173
1 files changed, 166 insertions, 7 deletions
diff --git a/src/pavucontrol.cc b/src/pavucontrol.cc
index 25601e2..4a313b3 100644
--- a/src/pavucontrol.cc
+++ b/src/pavucontrol.cc
@@ -117,10 +117,18 @@ public:
SinkType type;
Glib::ustring description;
+ Glib::ustring name;
+ uint32_t index;
+
+ Gtk::Menu menu;
+ Gtk::CheckMenuItem defaultMenuItem;
virtual void onMuteToggleButton();
- uint32_t index;
virtual void executeVolumeUpdate();
+ virtual void onDefaultToggle();
+
+protected:
+ virtual bool on_button_press_event(GdkEventButton* event);
};
class SourceWidget : public StreamWidget {
@@ -129,10 +137,18 @@ public:
static SourceWidget* create();
SourceType type;
+ Glib::ustring name;
+ uint32_t index;
+
+ Gtk::Menu menu;
+ Gtk::CheckMenuItem defaultMenuItem;
virtual void onMuteToggleButton();
- uint32_t index;
virtual void executeVolumeUpdate();
+ virtual void onDefaultToggle();
+
+protected:
+ virtual bool on_button_press_event(GdkEventButton* event);
};
class SinkInputWidget : public StreamWidget {
@@ -185,6 +201,7 @@ public:
void updateSource(const pa_source_info &info);
void updateSinkInput(const pa_sink_input_info &info);
void updateClient(const pa_client_info &info);
+ void updateServer(const pa_server_info &info);
void removeSink(uint32_t index);
void removeSource(uint32_t index);
@@ -211,6 +228,8 @@ public:
void updateDeviceVisibility();
+ Glib::ustring defaultSinkName, defaultSourceName;
+
protected:
virtual void on_realize();
};
@@ -360,7 +379,15 @@ void StreamWidget::executeVolumeUpdate() {
}
SinkWidget::SinkWidget(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& x) :
- StreamWidget(cobject, x) {
+ StreamWidget(cobject, x),
+ defaultMenuItem("Default"){
+
+ add_events(Gdk::BUTTON_PRESS_MASK);
+
+ defaultMenuItem.set_active(false);
+ defaultMenuItem.signal_toggled().connect(sigc::mem_fun(*this, &SinkWidget::onDefaultToggle));
+ menu.append(defaultMenuItem);
+ menu.show_all();
}
SinkWidget* SinkWidget::create() {
@@ -396,8 +423,42 @@ void SinkWidget::onMuteToggleButton() {
pa_operation_unref(o);
}
+bool SinkWidget::on_button_press_event(GdkEventButton* event) {
+ if (StreamWidget::on_button_press_event(event))
+ return TRUE;
+
+ if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
+
+ menu.popup(0, event->time);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void SinkWidget::onDefaultToggle() {
+ pa_operation* o;
+
+ if (updating)
+ return;
+
+ if (!(o = pa_context_set_default_sink(context, name.c_str(), NULL, NULL))) {
+ show_error("pa_context_set_default_sink() failed");
+ return;
+ }
+ pa_operation_unref(o);
+}
+
SourceWidget::SourceWidget(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& x) :
- StreamWidget(cobject, x) {
+ StreamWidget(cobject, x),
+ defaultMenuItem("Default"){
+
+ add_events(Gdk::BUTTON_PRESS_MASK);
+
+ defaultMenuItem.set_active(false);
+ defaultMenuItem.signal_toggled().connect(sigc::mem_fun(*this, &SourceWidget::onDefaultToggle));
+ menu.append(defaultMenuItem);
+ menu.show_all();
}
SourceWidget* SourceWidget::create() {
@@ -433,6 +494,32 @@ void SourceWidget::onMuteToggleButton() {
pa_operation_unref(o);
}
+bool SourceWidget::on_button_press_event(GdkEventButton* event) {
+ if (StreamWidget::on_button_press_event(event))
+ return TRUE;
+
+ if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
+
+ menu.popup(0, event->time);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void SourceWidget::onDefaultToggle() {
+ pa_operation* o;
+
+ if (updating)
+ return;
+
+ if (!(o = pa_context_set_default_source(context, name.c_str(), NULL, NULL))) {
+ show_error("pa_context_set_default_source() failed");
+ return;
+ }
+ pa_operation_unref(o);
+}
+
SinkInputWidget::SinkInputWidget(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& x) :
StreamWidget(cobject, x),
mainWindow(NULL),
@@ -516,6 +603,9 @@ void SinkInputWidget::buildMenu() {
void SinkInputWidget::SinkMenuItem::onToggle() {
+ if (widget->updating)
+ return;
+
if (!menuItem.get_active())
return;
@@ -600,8 +690,9 @@ void MainWindow::updateSink(const pa_sink_info &info) {
w->updating = true;
- w->type = info.flags & PA_SINK_HARDWARE ? SINK_HARDWARE : SINK_VIRTUAL;
+ w->name = info.name;
w->description = info.description;
+ w->type = info.flags & PA_SINK_HARDWARE ? SINK_HARDWARE : SINK_VIRTUAL;
w->boldNameLabel->set_text("");
gchar *txt;
@@ -611,6 +702,8 @@ void MainWindow::updateSink(const pa_sink_info &info) {
w->setVolume(info.volume);
w->muteToggleButton->set_active(info.mute);
+ w->defaultMenuItem.set_active(w->name == defaultSinkName);
+
if (is_new)
updateDeviceVisibility();
@@ -633,6 +726,7 @@ void MainWindow::updateSource(const pa_source_info &info) {
w->updating = true;
+ w->name = info.name;
w->type = info.monitor_of_sink != PA_INVALID_INDEX ? SOURCE_MONITOR : (info.flags & PA_SOURCE_HARDWARE ? SOURCE_HARDWARE : SOURCE_VIRTUAL);
w->boldNameLabel->set_text("");
@@ -643,6 +737,8 @@ void MainWindow::updateSource(const pa_source_info &info) {
w->setVolume(info.volume);
w->muteToggleButton->set_active(info.mute);
+ w->defaultMenuItem.set_active(w->name == defaultSourceName);
+
if (is_new)
updateDeviceVisibility();
@@ -710,6 +806,34 @@ void MainWindow::updateClient(const pa_client_info &info) {
}
}
+void MainWindow::updateServer(const pa_server_info &info) {
+
+ for (std::map<uint32_t, SinkWidget*>::iterator i = sinkWidgets.begin(); i != sinkWidgets.end(); ++i) {
+ SinkWidget *w = i->second;
+
+ if (!w)
+ continue;
+
+ w->updating = true;
+ w->defaultMenuItem.set_active(w->name == info.default_sink_name);
+ w->updating = false;
+ }
+
+ for (std::map<uint32_t, SourceWidget*>::iterator i = sourceWidgets.begin(); i != sourceWidgets.end(); ++i) {
+ SourceWidget *w = i->second;
+
+ if (!w)
+ continue;
+
+ w->updating = true;
+ w->defaultMenuItem.set_active(w->name == info.default_source_name);
+ w->updating = false;
+ }
+
+ defaultSourceName = info.default_source_name;
+ defaultSinkName = info.default_sink_name;
+}
+
void MainWindow::updateDeviceVisibility() {
streamsVBox->hide_all();
@@ -896,6 +1020,18 @@ void client_cb(pa_context *, const pa_client_info *i, int eol, void *userdata) {
w->updateClient(*i);
}
+void server_info_cb(pa_context *, const pa_server_info *i, void *userdata) {
+ MainWindow *w = static_cast<MainWindow*>(userdata);
+
+ if (!i) {
+ show_error("Server info callback failure");
+ return;
+ }
+
+ w->updateServer(*i);
+ dec_outstanding(w);
+}
+
void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t index, void *userdata) {
MainWindow *w = static_cast<MainWindow*>(userdata);
@@ -912,6 +1048,7 @@ void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t index,
pa_operation_unref(o);
}
break;
+
case PA_SUBSCRIPTION_EVENT_SOURCE:
if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE)
w->removeSource(index);
@@ -924,6 +1061,7 @@ void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t index,
pa_operation_unref(o);
}
break;
+
case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE)
w->removeSinkInput(index);
@@ -936,6 +1074,7 @@ void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t index,
pa_operation_unref(o);
}
break;
+
case PA_SUBSCRIPTION_EVENT_CLIENT:
if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE)
w->removeClient(index);
@@ -948,6 +1087,15 @@ void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t index,
pa_operation_unref(o);
}
break;
+
+ case PA_SUBSCRIPTION_EVENT_SERVER: {
+ pa_operation *o;
+ if (!(o = pa_context_get_server_info(c, server_info_cb, w))) {
+ show_error("pa_context_get_server_info() failed");
+ return;
+ }
+ pa_operation_unref(o);
+ }
}
}
@@ -968,12 +1116,23 @@ void context_state_callback(pa_context *c, void *userdata) {
pa_context_set_subscribe_callback(c, subscribe_cb, w);
- if (!(o = pa_context_subscribe(c, (pa_subscription_mask_t) (PA_SUBSCRIPTION_MASK_SINK|PA_SUBSCRIPTION_MASK_SOURCE|PA_SUBSCRIPTION_MASK_SINK_INPUT|PA_SUBSCRIPTION_MASK_CLIENT), NULL, NULL))) {
+ if (!(o = pa_context_subscribe(c, (pa_subscription_mask_t)
+ (PA_SUBSCRIPTION_MASK_SINK|
+ PA_SUBSCRIPTION_MASK_SOURCE|
+ PA_SUBSCRIPTION_MASK_SINK_INPUT|
+ PA_SUBSCRIPTION_MASK_CLIENT|
+ PA_SUBSCRIPTION_MASK_SERVER), NULL, NULL))) {
show_error("pa_context_subscribe() failed");
return;
}
pa_operation_unref(o);
+ if (!(o = pa_context_get_server_info(c, server_info_cb, w))) {
+ show_error("pa_context_get_server_info() failed");
+ return;
+ }
+ pa_operation_unref(o);
+
if (!(o = pa_context_get_client_info_list(c, client_cb, w))) {
show_error("pa_context_client_info_list() failed");
return;
@@ -998,7 +1157,7 @@ void context_state_callback(pa_context *c, void *userdata) {
}
pa_operation_unref(o);
- n_outstanding = 4;
+ n_outstanding = 5;
break;
}