Index: configure
===================================================================
--- configure	(revision 20397)
+++ configure	(working copy)
@@ -1040,6 +1040,7 @@
 '
 
 MYTHTV_LIST='
+    audio_pulse
     audio_alsa
     audio_arts
     audio_jack
@@ -1311,6 +1312,8 @@
 CONFIG_INCLUDEPATH=""
 PROFILEFLAGS=""
 
+audio_pulse="default"
+audio_pulse_libs="-lpulse"
 audio_alsa="default"
 audio_alsa_libs="-lasound"
 audio_arts="default"
@@ -2839,6 +2842,12 @@
 check_header sys/soundcard.h
 check_header soundcard.h
 
+# PulseAudio probe
+! disabled audio_pulse &&
+    check_lib pulse/version.h pa_get_library_version $audio_pulse_libs &&
+    enable  audio_pulse ||
+    disable audio_pulse
+
 # ALSA probe
 ! disabled audio_alsa &&
     check_lib alsa/asoundlib.h snd_asoundlib_version $audio_alsa_libs &&
@@ -3321,6 +3330,7 @@
 if enabled frontend; then
   echo
   echo "# Sound Output Support"
+  echo "PulseAudio support        ${audio_pulse-no}"
   echo "OSS support               ${audio_oss-no}"
   echo "ALSA support              ${audio_alsa-no}"
   echo "aRts support              ${audio_arts-no}"
@@ -3517,6 +3527,11 @@
   echo "CONFIG_AUDIO_ALSA_LIBS=$audio_alsa_libs" >> $MYTH_CONFIG_MAK
 fi
 
+if enabled audio_pulse; then
+  append CCONFIG "using_pulse"
+  echo "CONFIG_AUDIO_PULSE_LIBS=$audio_pulse_libs" >> $MYTH_CONFIG_MAK
+fi
+
 if enabled audio_arts; then
     append CCONFIG "using_arts"
   echo "CONFIG_AUDIO_ARTS_LIBS=$audio_arts_libs" >> $MYTH_CONFIG_MAK
Index: libs/libmyth/audiopulseutil.h
===================================================================
--- libs/libmyth/audiopulseutil.h	(revision 0)
+++ libs/libmyth/audiopulseutil.h	(revision 0)
@@ -0,0 +1,3 @@
+bool suspend_pulseaudio(void);
+
+int handle_pulseaudio(void);
Index: libs/libmyth/libmyth.pro
===================================================================
--- libs/libmyth/libmyth.pro	(revision 20397)
+++ libs/libmyth/libmyth.pro	(working copy)
@@ -105,6 +105,13 @@
     LIBS += $$OSS_LIBS
 }
 
+using_pulse {
+    DEFINES += USING_PULSE
+    SOURCES += audiopulseutil.cpp
+    HEADERS += audiopulseutil.h
+    LIBS += $$PULSE_LIBS
+}
+
 unix:!cygwin {
     SOURCES += mediamonitor-unix.cpp
     HEADERS += mediamonitor-unix.h
Index: libs/libmyth/audiopulseutil.cpp
===================================================================
--- libs/libmyth/audiopulseutil.cpp	(revision 0)
+++ libs/libmyth/audiopulseutil.cpp	(revision 0)
@@ -0,0 +1,331 @@
+/***
+ *   This file was part of PulseAudio, the license has been upgraded to GPL v2
+ *   or later as per the LGPL grant this was originally distributed under.
+ *
+ *   Copyright 2004-2006 Lennart Poettering
+ *
+ *   MythTV 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.
+ *
+ *   This program 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 this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <getopt.h>
+#include <locale.h>
+
+#ifdef __linux__
+#include <sys/prctl.h>
+#endif
+
+#include <pulse/pulseaudio.h>
+
+#include <QThread>
+#include <QMutex>
+#include <QWaitCondition>
+#include "mythverbose.h"
+#include "util.h" // for IsPulseAudioRunning()
+#include "exitcodes.h"
+
+#define BUFSIZE 1024
+
+#define LOC      QString("AudioPulseUtil: ")
+#define LOC_WARN QString("AudioPulseUtil, Warning: ")
+#define LOC_ERR  QString("AudioPulseUtil, Error: ")
+#define pa_assert(X) assert(X)
+#define pa_assert_se(X) do { bool i = (bool) X; assert(i); } while (0)
+#define _(X) X
+
+static pa_context *context = NULL;
+static pa_mainloop_api *mainloop_api = NULL;
+static int dead = 1;
+static QMutex pa_lock;
+static QWaitCondition pa_wait;
+enum pa_values {
+    kPA_undefined                   = -1,
+    kPA_suspended                   = +0,
+    kPA_not_suspended_remote_server = +1,
+    kPA_not_suspended_error         = +2,
+    kPA_not_suspended_success       = +3,
+};
+static int pa_value = -1;
+
+static void set_pa_value(int new_value)
+{
+    QMutexLocker ml(&pa_lock);
+    pa_value = new_value;
+    pa_wait.wakeAll();
+}
+
+static void quit(int ret) {
+    pa_assert(mainloop_api);
+    mainloop_api->quit(mainloop_api, ret);
+}
+
+
+static void context_drain_complete(pa_context *c, void *userdata) {
+    pa_context_disconnect(c);
+}
+
+static void drain(void) {
+    pa_operation *o;
+
+    if (!(o = pa_context_drain(context, context_drain_complete, NULL)))
+        pa_context_disconnect(context);
+    else
+        pa_operation_unref(o);
+}
+
+static void suspend_complete(pa_context *c, int success, void *userdata)
+{
+    if (!success)
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Failure to suspend: %1")
+                .arg(pa_strerror(pa_context_errno(c))));
+
+        set_pa_value(kPA_not_suspended_error);
+
+        return;
+    }
+
+    VERBOSE(VB_GENERAL, LOC + "Suspend Success");
+
+    set_pa_value(kPA_suspended);
+}
+
+static void resume_complete(pa_context *c, int success, void *userdata)
+{
+    static int n = 0;
+
+    n++;
+
+    if (!success)
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Failure to resume: %1")
+                .arg(pa_strerror(pa_context_errno(c))));
+        return;
+    }
+
+    if (n >= 2)
+        drain(); /* drain and quit */
+
+    VERBOSE(VB_GENERAL, LOC + "Resume Success");
+
+    set_pa_value(kPA_not_suspended_success);
+}
+
+static void context_state_callback(pa_context *c, void *userdata)
+{
+    pa_assert(c);
+
+    switch (pa_context_get_state(c))
+    {
+        case PA_CONTEXT_CONNECTING:
+        case PA_CONTEXT_AUTHORIZING:
+        case PA_CONTEXT_SETTING_NAME:
+            break;
+
+        case PA_CONTEXT_READY:
+            if (pa_context_is_local(c))
+            {
+                pa_operation_unref(
+                    pa_context_suspend_sink_by_index(
+                        c, PA_INVALID_INDEX, 1, suspend_complete, NULL));
+                pa_operation_unref(
+                    pa_context_suspend_source_by_index(
+                        c, PA_INVALID_INDEX, 1, suspend_complete, NULL));
+            }
+            else
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR +
+                        "Sound server is not local, can not suspend.");
+
+                set_pa_value(kPA_not_suspended_remote_server);
+            }
+
+            break;
+
+        case PA_CONTEXT_TERMINATED:
+            quit(0);
+            break;
+
+        case PA_CONTEXT_FAILED:
+        default:
+            VERBOSE(VB_IMPORTANT, LOC_WARN +
+                    "Can not connect to sound server, can not suspend." +
+                    QString("\n\t\t\t%1")
+                    .arg(pa_strerror(pa_context_errno(c))));
+
+            set_pa_value(kPA_not_suspended_error);
+
+            pa_context_unref(context);
+            context = NULL;
+
+            //if (child_pid == (pid_t) -1)
+            //    /* not started yet, then we do it now */
+            //    start_child();
+            //else if (dead)
+            //    /* already started, and dead, so let's quit */
+            //    quit(1);
+
+            break;
+    }
+}
+
+static void sigchld_callback(pa_mainloop_api *m, pa_signal_event *e, int sig, void *userdata) {
+
+    return;//**//
+
+    int status = 0;
+    pid_t p;
+
+    p = waitpid(-1, &status, WNOHANG);
+
+    //if (p != child_pid)
+    //    return;
+
+    dead = 1;
+
+    if (WIFEXITED(status))
+    {
+        //child_ret = WEXITSTATUS(status);
+    }
+    else if (WIFSIGNALED(status)) {
+        fprintf(stderr, _("WARNING: Child process terminated by signal %u\n"), WTERMSIG(status));
+        //child_ret = 1;
+    }
+
+    if (context) {
+        if (pa_context_is_local(context)) {
+            /* A context is around, so let's resume */
+            pa_operation_unref(pa_context_suspend_sink_by_index(context, PA_INVALID_INDEX, 0, resume_complete, NULL));
+            pa_operation_unref(pa_context_suspend_source_by_index(context, PA_INVALID_INDEX, 0, resume_complete, NULL));
+        } else
+            drain();
+    } else
+        /* Hmm, no context here, so let's terminate right away */
+        quit(0);
+}
+
+void suspend_pulseaudio_internal(void) {
+    pa_mainloop* m = NULL;
+    int ret = 1;
+    char *server = NULL;
+    const char *bn = "mythtv";
+
+    //setlocale(LC_ALL, "");
+    //bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
+
+    if (!(m = pa_mainloop_new())) {
+        fprintf(stderr, _("pa_mainloop_new() failed.\n"));
+        goto quit;
+    }
+
+    mainloop_api = pa_mainloop_get_api(m);
+    if (!mainloop_api)
+        goto quit;
+
+    if (pa_signal_init(mainloop_api) != 0)
+        goto quit;
+
+    pa_signal_new(SIGCHLD, sigchld_callback, NULL);
+
+    if (!(context = pa_context_new(mainloop_api, bn))) {
+        fprintf(stderr, _("pa_context_new() failed.\n"));
+        goto quit;
+    }
+
+    pa_context_set_state_callback(context, context_state_callback, NULL);
+    pa_context_connect(context, server, PA_CONTEXT_NOAUTOSPAWN, NULL);
+
+    if (pa_mainloop_run(m, &ret) < 0) {
+        fprintf(stderr, _("pa_mainloop_run() failed.\n"));
+        goto quit;
+    }
+
+quit:
+    if (context)
+        pa_context_unref(context);
+
+    if (m) {
+        pa_signal_done();
+        pa_mainloop_free(m);
+    }
+
+    pa_xfree(server);
+}
+
+class PAThread : public QThread
+{
+  public:
+    void run(void)
+    {
+        VERBOSE(VB_IMPORTANT, LOC + "Here - begin");
+        suspend_pulseaudio_internal();
+        VERBOSE(VB_IMPORTANT, LOC + "Here - end");
+    }
+};
+
+/// \returns true if successful
+bool suspend_pulseaudio(void)
+{
+    QThread *t = new PAThread();
+    t->start();
+
+    QMutexLocker ml(&pa_lock);
+    while (pa_value < 0)
+        pa_wait.wait(&pa_lock);
+
+    return kPA_suspended == pa_value;
+}
+
+int handle_pulseaudio(void)
+{
+#ifndef USING_PULSE
+    if (IsPulseAudioRunning())
+    {
+        VERBOSE(VB_IMPORTANT, "ERROR: ***Pulse Audio is running!!!!***");
+        VERBOSE(VB_IMPORTANT, "ERROR: But MythTV has not been compiled "
+                "with Pulse Audio disabling support. EXITING!");
+        return GENERIC_EXIT_NOT_OK;
+    }
+#else
+    if (getenv("EXPERIMENTALLY_ALLOW_PULSE_AUDIO"))
+    {
+        VERBOSE(VB_IMPORTANT, "WARNING: ");
+        VERBOSE(VB_IMPORTANT, "WARNING: ***Pulse Audio is running!!!!***");
+        VERBOSE(VB_IMPORTANT, "WARNING: ");
+        VERBOSE(VB_IMPORTANT, "WARNING: You have told MythTV to ignore it.");
+        VERBOSE(VB_IMPORTANT, "WARNING: ");
+    }
+    else if (IsPulseAudioRunning() && !suspend_pulseaudio())
+    {
+        VERBOSE(VB_IMPORTANT, "ERROR: ***Pulse Audio is running!!!!***");
+        VERBOSE(VB_IMPORTANT,
+                "ERROR: But MythTV was not able to suspend it. EXITING!");
+
+        return GENERIC_EXIT_NOT_OK;
+    }
+#endif
+
+    return GENERIC_EXIT_OK;
+}
Index: programs/mythfrontend/main.cpp
===================================================================
--- programs/mythfrontend/main.cpp	(revision 20397)
+++ programs/mythfrontend/main.cpp	(working copy)
@@ -61,7 +61,7 @@
 #include "mythuihelper.h"
 #include "mythdirs.h"
 #include "mythosdmenueditor.h"
-#include "util.h" // for IsPulseAudioRunning()
+#include "audiopulseutil.h"
 
 static ExitPrompter   *exitPopup = NULL;
 static MythThemedMenu *menu;
@@ -1038,13 +1038,6 @@
 
 int main(int argc, char **argv)
 {
-    if (IsPulseAudioRunning())
-    {
-        cerr << "***Pulse Audio is running!!!!***" << endl
-             << "Pulse Audio is incompatible with MythTV." << endl;
-        return GENERIC_EXIT_NOT_OK;
-    }
-
     bool bPromptForBackend    = false;
     bool bBypassAutoDiscovery = false;
     bool upgradeAllowed = false;
@@ -1167,6 +1160,10 @@
     }
     QMap<QString,QString> settingsOverride = cmdline.GetSettingsOverride();
 
+    int pa_ret = handle_pulseaudio();
+    if (GENERIC_EXIT_OK != pa_ret)
+        return pa_ret;
+
     if (logfile.size())
     {
         if (log_rotate(1) < 0)
Index: programs/mythfrontend/mythfrontend.pro
===================================================================
--- programs/mythfrontend/mythfrontend.pro	(revision 20397)
+++ programs/mythfrontend/mythfrontend.pro	(working copy)
@@ -63,6 +63,7 @@
 using_opengl_video:DEFINES += USING_OPENGL_VIDEO
 using_vdpau:DEFINES += USING_VDPAU
 
+using_pulse:DEFINES += USING_PULSE
 using_alsa:DEFINES += USING_ALSA
 using_arts:DEFINES += USING_ARTS
 using_jack:DEFINES += USING_JACK
Index: programs/mythtv/main.cpp
===================================================================
--- programs/mythtv/main.cpp	(revision 20397)
+++ programs/mythtv/main.cpp	(working copy)
@@ -20,9 +20,10 @@
 #include "compat.h"
 #include "mythuihelper.h"
 #include "dbcheck.h"
-#include "util.h" // for IsPulseAudioRunning()
 #include "myththemebase.h"
+#include "audiopulseutil.h"
 
+
 static void *run_priv_thread(void *data)
 {
     (void)data;
@@ -77,13 +78,6 @@
 
 int main(int argc, char *argv[])
 {
-    if (IsPulseAudioRunning())
-    {
-        cerr << "***Pulse Audio is running!!!!***" << endl
-             << "Pulse Audio is incompatible with MythTV." << endl;
-        return GENERIC_EXIT_NOT_OK;
-    }
-
     bool cmdline_err;
     MythCommandLineParser cmdline(
         kCLPOverrideSettings     |
@@ -207,6 +201,10 @@
     
     GetMythUI()->LoadQtConfig();
 
+    int pa_ret = handle_pulseaudio();
+    if (GENERIC_EXIT_OK != pa_ret)
+        return pa_ret;
+
 #if defined(Q_OS_MACX)
     // Mac OS X doesn't define the AudioOutputDevice setting
 #else
Index: programs/mythtv/mythtv.pro
===================================================================
--- programs/mythtv/mythtv.pro	(revision 20397)
+++ programs/mythtv/mythtv.pro	(working copy)
@@ -23,3 +23,18 @@
 }
 
 using_x11:DEFINES += USING_X11
+using_xv:DEFINES += USING_XV
+using_ivtv:DEFINES += USING_IVTV
+using_xvmc:DEFINES += USING_XVMC
+using_xvmc_vld:DEFINES += USING_XVMC_VLD
+using_xrandr:DEFINES += USING_XRANDR
+using_opengl_vsync:DEFINES += USING_OPENGL_VSYNC
+using_opengl_video:DEFINES += USING_OPENGL_VIDEO
+using_vdpau:DEFINES += USING_VDPAU
+
+using_pulse:DEFINES += USING_PULSE
+using_alsa:DEFINES += USING_ALSA
+using_arts:DEFINES += USING_ARTS
+using_jack:DEFINES += USING_JACK
+using_oss: DEFINES += USING_OSS
+macx:      DEFINES += USING_COREAUDIO
Index: settings.pro
===================================================================
--- settings.pro	(revision 20397)
+++ settings.pro	(working copy)
@@ -123,6 +123,7 @@
 ALSA_LIBS = $$CONFIG_AUDIO_ALSA_LIBS
 ARTS_LIBS = $$CONFIG_AUDIO_ARTS_LIBS
 JACK_LIBS = $$CONFIG_AUDIO_JACK_LIBS
+PULSE_LIBS = $$CONFIG_AUDIO_PULSE_LIBS
 
 EXTRA_LIBS = $$FREETYPE_LIBS
 EXTRA_LIBS += $$CONFIG_FIREWIRE_LIBS
@@ -135,5 +136,6 @@
 EXTRA_LIBS += $$CONFIG_XVMC_LIBS
 EXTRA_LIBS += $$CONFIG_OPENGL_LIBS
 EXTRA_LIBS += $$FRIBIDI_LIBS
+using_pulse:EXTRA_LIBS += $$PULSE_LIBS
 
 LIRC_LIBS = $$CONFIG_LIRC_LIBS
