summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--gnu-system.am1
-rw-r--r--gnu/packages/patches/pavucontrol-sigsegv.patch203
-rw-r--r--gnu/packages/pulseaudio.scm3
3 files changed, 206 insertions, 1 deletions
diff --git a/gnu-system.am b/gnu-system.am
index c3e8c5b02d..b6a0f3a770 100644
--- a/gnu-system.am
+++ b/gnu-system.am
@@ -475,6 +475,7 @@ dist_patch_DATA =						\
   gnu/packages/patches/patchelf-page-size.patch			\
   gnu/packages/patches/patchelf-rework-for-arm.patch		\
   gnu/packages/patches/patchutils-xfail-gendiff-tests.patch	\
+  gnu/packages/patches/pavucontrol-sigsegv.patch		\
   gnu/packages/patches/perl-no-sys-dirs.patch			\
   gnu/packages/patches/perl-tk-x11-discover.patch		\
   gnu/packages/patches/petsc-fix-threadcomm.patch		\
diff --git a/gnu/packages/patches/pavucontrol-sigsegv.patch b/gnu/packages/patches/pavucontrol-sigsegv.patch
new file mode 100644
index 0000000000..094765b6a0
--- /dev/null
+++ b/gnu/packages/patches/pavucontrol-sigsegv.patch
@@ -0,0 +1,203 @@
+Work around a segmentation fault when starting pavucontrol.
+
+From a98200f2699d453a78c9dfbb85e307bbdb3e3dbf Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Thu, 28 Aug 2014 12:58:05 +0200
+Subject: [PATCH] Reference the widget before returning it from ::create
+ methods
+
+Widgets (unlike Windows and Dialogs) returned by Gtk::Builder::get_widget*
+start owned by the GtkBuilder object, the idea being that they will get
+added to a container before the scope of the GtkBuilder object ends, and it
+thus automatically gets destroyed.
+
+But in the various ::create methods in pavucontrol, a pointer to the widget
+gets returned, so that it can be added to a cointainer by the caller.
+However as soon as the ::create method exits the GtkBuilder object owning
+the widget, and thus also the widget gets destroyed, and we end up returning
+free-ed memory.
+
+This commit fixes this by making all ::create methods take a reference on
+the widget before returning it, and having all the callers unreference the
+widget after adding it to a container.
+
+https://bugs.freedesktop.org/show_bug.cgi?id=83144
+https://bugzilla.redhat.com/show_bug.cgi?id=1133339
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ src/cardwidget.cc         | 1 +
+ src/channelwidget.cc      | 1 +
+ src/devicewidget.cc       | 1 +
+ src/mainwindow.cc         | 6 ++++++
+ src/rolewidget.cc         | 1 +
+ src/sinkinputwidget.cc    | 1 +
+ src/sinkwidget.cc         | 1 +
+ src/sourceoutputwidget.cc | 1 +
+ src/sourcewidget.cc       | 1 +
+ src/streamwidget.cc       | 1 +
+ 10 files changed, 15 insertions(+)
+
+diff --git a/src/cardwidget.cc b/src/cardwidget.cc
+index c79ac6c..28c558d 100644
+--- a/src/cardwidget.cc
++++ b/src/cardwidget.cc
+@@ -45,6 +45,7 @@ CardWidget* CardWidget::create() {
+     CardWidget* w;
+     Glib::RefPtr<Gtk::Builder> x = Gtk::Builder::create_from_file(GLADE_FILE, "cardWidget");
+     x->get_widget_derived("cardWidget", w);
++    w->reference();
+     return w;
+ }
+ 
+diff --git a/src/channelwidget.cc b/src/channelwidget.cc
+index 6f59de2..fe94c11 100644
+--- a/src/channelwidget.cc
++++ b/src/channelwidget.cc
+@@ -53,6 +53,7 @@ ChannelWidget* ChannelWidget::create() {
+     x->add_from_file(GLADE_FILE, "adjustment1");
+     x->add_from_file(GLADE_FILE, "channelWidget");
+     x->get_widget_derived("channelWidget", w);
++    w->reference();
+     return w;
+ }
+ 
+diff --git a/src/devicewidget.cc b/src/devicewidget.cc
+index 1a148ee..813780f 100644
+--- a/src/devicewidget.cc
++++ b/src/devicewidget.cc
+@@ -89,6 +89,7 @@ void DeviceWidget::setChannelMap(const pa_channel_map &m, bool can_decibel) {
+         snprintf(text, sizeof(text), "<b>%s</b>", pa_channel_position_to_pretty_string(m.map[i]));
+         cw->channelLabel->set_markup(text);
+         channelsVBox->pack_start(*cw, false, false, 0);
++        cw->unreference();
+     }
+     channelWidgets[m.channels-1]->last = true;
+ 
+diff --git a/src/mainwindow.cc b/src/mainwindow.cc
+index 5a42318..5d205fb 100644
+--- a/src/mainwindow.cc
++++ b/src/mainwindow.cc
+@@ -300,6 +300,7 @@ void MainWindow::updateCard(const pa_card_info &info) {
+     else {
+         cardWidgets[info.index] = w = CardWidget::create();
+         cardsVBox->pack_start(*w, false, false, 0);
++        w->unreference();
+         w->index = info.index;
+         is_new = true;
+     }
+@@ -416,6 +417,7 @@ bool MainWindow::updateSink(const pa_sink_info &info) {
+         sinkWidgets[info.index] = w = SinkWidget::create(this);
+         w->setChannelMap(info.channel_map, !!(info.flags & PA_SINK_DECIBEL_VOLUME));
+         sinksVBox->pack_start(*w, false, false, 0);
++        w->unreference();
+         w->index = info.index;
+         w->monitor_index = info.monitor_source;
+         is_new = true;
+@@ -570,6 +572,7 @@ void MainWindow::updateSource(const pa_source_info &info) {
+         sourceWidgets[info.index] = w = SourceWidget::create(this);
+         w->setChannelMap(info.channel_map, !!(info.flags & PA_SOURCE_DECIBEL_VOLUME));
+         sourcesVBox->pack_start(*w, false, false, 0);
++        w->unreference();
+         w->index = info.index;
+         is_new = true;
+ 
+@@ -686,6 +689,7 @@ void MainWindow::updateSinkInput(const pa_sink_input_info &info) {
+         sinkInputWidgets[info.index] = w = SinkInputWidget::create(this);
+         w->setChannelMap(info.channel_map, true);
+         streamsVBox->pack_start(*w, false, false, 0);
++        w->unreference();
+         w->index = info.index;
+         w->clientIndex = info.client;
+         is_new = true;
+@@ -743,6 +747,7 @@ void MainWindow::updateSourceOutput(const pa_source_output_info &info) {
+         w->setChannelMap(info.channel_map, true);
+ #endif
+         recsVBox->pack_start(*w, false, false, 0);
++        w->unreference();
+         w->index = info.index;
+         w->clientIndex = info.client;
+         is_new = true;
+@@ -838,6 +843,7 @@ bool MainWindow::createEventRoleWidget() {
+ 
+     eventRoleWidget = RoleWidget::create();
+     streamsVBox->pack_start(*eventRoleWidget, false, false, 0);
++    eventRoleWidget->unreference();
+     eventRoleWidget->role = "sink-input-by-media-role:event";
+     eventRoleWidget->setChannelMap(cm, true);
+ 
+diff --git a/src/rolewidget.cc b/src/rolewidget.cc
+index fd3196c..db07f92 100644
+--- a/src/rolewidget.cc
++++ b/src/rolewidget.cc
+@@ -40,6 +40,7 @@ RoleWidget* RoleWidget::create() {
+     RoleWidget* w;
+     Glib::RefPtr<Gtk::Builder> x = Gtk::Builder::create_from_file(GLADE_FILE, "streamWidget");
+     x->get_widget_derived("streamWidget", w);
++    w->reference();
+     return w;
+ }
+ 
+diff --git a/src/sinkinputwidget.cc b/src/sinkinputwidget.cc
+index b88b718..5a0ba39 100644
+--- a/src/sinkinputwidget.cc
++++ b/src/sinkinputwidget.cc
+@@ -43,6 +43,7 @@ SinkInputWidget* SinkInputWidget::create(MainWindow* mainWindow) {
+     Glib::RefPtr<Gtk::Builder> x = Gtk::Builder::create_from_file(GLADE_FILE, "streamWidget");
+     x->get_widget_derived("streamWidget", w);
+     w->init(mainWindow);
++    w->reference();
+     return w;
+ }
+ 
+diff --git a/src/sinkwidget.cc b/src/sinkwidget.cc
+index 7f4902c..f682cf2 100644
+--- a/src/sinkwidget.cc
++++ b/src/sinkwidget.cc
+@@ -82,6 +82,7 @@ SinkWidget* SinkWidget::create(MainWindow* mainWindow) {
+     Glib::RefPtr<Gtk::Builder> x = Gtk::Builder::create_from_file(GLADE_FILE, "deviceWidget");
+     x->get_widget_derived("deviceWidget", w);
+     w->init(mainWindow, "sink");
++    w->reference();
+     return w;
+ }
+ 
+diff --git a/src/sourceoutputwidget.cc b/src/sourceoutputwidget.cc
+index 827c5a8..4d915b0 100644
+--- a/src/sourceoutputwidget.cc
++++ b/src/sourceoutputwidget.cc
+@@ -49,6 +49,7 @@ SourceOutputWidget* SourceOutputWidget::create(MainWindow* mainWindow) {
+     Glib::RefPtr<Gtk::Builder> x = Gtk::Builder::create_from_file(GLADE_FILE, "streamWidget");
+     x->get_widget_derived("streamWidget", w);
+     w->init(mainWindow);
++    w->reference();
+     return w;
+ }
+ 
+diff --git a/src/sourcewidget.cc b/src/sourcewidget.cc
+index 5e4ecf0..fde5333 100644
+--- a/src/sourcewidget.cc
++++ b/src/sourcewidget.cc
+@@ -35,6 +35,7 @@ SourceWidget* SourceWidget::create(MainWindow* mainWindow) {
+     Glib::RefPtr<Gtk::Builder> x = Gtk::Builder::create_from_file(GLADE_FILE, "deviceWidget");
+     x->get_widget_derived("deviceWidget", w);
+     w->init(mainWindow, "source");
++    w->reference();
+     return w;
+ }
+ 
+diff --git a/src/streamwidget.cc b/src/streamwidget.cc
+index 94363ec..e602cce 100644
+--- a/src/streamwidget.cc
++++ b/src/streamwidget.cc
+@@ -77,6 +77,7 @@ void StreamWidget::setChannelMap(const pa_channel_map &m, bool can_decibel) {
+         snprintf(text, sizeof(text), "<b>%s</b>", pa_channel_position_to_pretty_string(m.map[i]));
+         cw->channelLabel->set_markup(text);
+         channelsVBox->pack_start(*cw, false, false, 0);
++        cw->unreference();
+     }
+     channelWidgets[m.channels-1]->last = true;
+     channelWidgets[m.channels-1]->setBaseVolume(PA_VOLUME_NORM);
+-- 
+2.1.0
+
diff --git a/gnu/packages/pulseaudio.scm b/gnu/packages/pulseaudio.scm
index e915ea0e8c..d76f74b775 100644
--- a/gnu/packages/pulseaudio.scm
+++ b/gnu/packages/pulseaudio.scm
@@ -194,7 +194,8 @@ mixing several sounds into one are easily achieved using a sound server. ")
                    ".tar.xz"))
              (sha256
               (base32
-               "02s775m1531sshwlbvfddk3pz8zjmwkv1sgzggn386ja3gc9vwi2"))))
+               "02s775m1531sshwlbvfddk3pz8zjmwkv1sgzggn386ja3gc9vwi2"))
+             (patches (list (search-patch "pavucontrol-sigsegv.patch")))))
     (build-system gnu-build-system)
     (inputs
      `(("libcanberra" ,libcanberra)