/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/

/*
  The PulseAudio target for SDL 1.3 is based on the 1.3 arts target, with
   the appropriate parts replaced with the 1.2 PulseAudio target code. This
   was the cleanest way to move it to 1.3. The 1.2 target was written by
   Stéphan Kochen: stephan .a.t. kochen.nl
*/
#include "../../SDL_internal.h"
#include "SDL_assert.h"

#if SDL_AUDIO_DRIVER_PULSEAUDIO

/* Allow access to a raw mixing buffer */

#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <pulse/pulseaudio.h>

#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audio_c.h"
#include "SDL_pulseaudio.h"
#include "SDL_loadso.h"
#include "../../thread/SDL_systhread.h"

#if (PA_API_VERSION < 12)
/** Return non-zero if the passed state is one of the connected states */
static SDL_INLINE int PA_CONTEXT_IS_GOOD(pa_context_state_t x) {
    return
        x == PA_CONTEXT_CONNECTING ||
        x == PA_CONTEXT_AUTHORIZING ||
        x == PA_CONTEXT_SETTING_NAME ||
        x == PA_CONTEXT_READY;
}
/** Return non-zero if the passed state is one of the connected states */
static SDL_INLINE int PA_STREAM_IS_GOOD(pa_stream_state_t x) {
    return
        x == PA_STREAM_CREATING ||
        x == PA_STREAM_READY;
}
#endif /* pulseaudio <= 0.9.10 */


static const char *(*PULSEAUDIO_pa_get_library_version) (void);
static pa_channel_map *(*PULSEAUDIO_pa_channel_map_init_auto) (
    pa_channel_map *, unsigned, pa_channel_map_def_t);
static const char * (*PULSEAUDIO_pa_strerror) (int);
static pa_mainloop * (*PULSEAUDIO_pa_mainloop_new) (void);
static pa_mainloop_api * (*PULSEAUDIO_pa_mainloop_get_api) (pa_mainloop *);
static int (*PULSEAUDIO_pa_mainloop_iterate) (pa_mainloop *, int, int *);
static int (*PULSEAUDIO_pa_mainloop_run) (pa_mainloop *, int *);
static void (*PULSEAUDIO_pa_mainloop_quit) (pa_mainloop *, int);
static void (*PULSEAUDIO_pa_mainloop_free) (pa_mainloop *);

static pa_operation_state_t (*PULSEAUDIO_pa_operation_get_state) (
    pa_operation *);
static void (*PULSEAUDIO_pa_operation_cancel) (pa_operation *);
static void (*PULSEAUDIO_pa_operation_unref) (pa_operation *);

static pa_context * (*PULSEAUDIO_pa_context_new) (pa_mainloop_api *,
    const char *);
static int (*PULSEAUDIO_pa_context_connect) (pa_context *, const char *,
    pa_context_flags_t, const pa_spawn_api *);
static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_list) (pa_context *, pa_sink_info_cb_t, void *);
static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_list) (pa_context *, pa_source_info_cb_t, void *);
static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_by_index) (pa_context *, uint32_t, pa_sink_info_cb_t, void *);
static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_by_index) (pa_context *, uint32_t, pa_source_info_cb_t, void *);
static pa_context_state_t (*PULSEAUDIO_pa_context_get_state) (pa_context *);
static pa_operation * (*PULSEAUDIO_pa_context_subscribe) (pa_context *, pa_subscription_mask_t, pa_context_success_cb_t, void *);
static void (*PULSEAUDIO_pa_context_set_subscribe_callback) (pa_context *, pa_context_subscribe_cb_t, void *);
static void (*PULSEAUDIO_pa_context_disconnect) (pa_context *);
static void (*PULSEAUDIO_pa_context_unref) (pa_context *);

static pa_stream * (*PULSEAUDIO_pa_stream_new) (pa_context *, const char *,
    const pa_sample_spec *, const pa_channel_map *);
static int (*PULSEAUDIO_pa_stream_connect_playback) (pa_stream *, const char *,
    const pa_buffer_attr *, pa_stream_flags_t, pa_cvolume *, pa_stream *);
static int (*PULSEAUDIO_pa_stream_connect_record) (pa_stream *, const char *,
    const pa_buffer_attr *, pa_stream_flags_t);
static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state) (pa_stream *);
static size_t (*PULSEAUDIO_pa_stream_writable_size) (pa_stream *);
static size_t (*PULSEAUDIO_pa_stream_readable_size) (pa_stream *);
static int (*PULSEAUDIO_pa_stream_write) (pa_stream *, const void *, size_t,
    pa_free_cb_t, int64_t, pa_seek_mode_t);
static pa_operation * (*PULSEAUDIO_pa_stream_drain) (pa_stream *,
    pa_stream_success_cb_t, void *);
static int (*PULSEAUDIO_pa_stream_peek) (pa_stream *, const void **, size_t *);
static int (*PULSEAUDIO_pa_stream_drop) (pa_stream *);
static pa_operation * (*PULSEAUDIO_pa_stream_flush)	(pa_stream *,
    pa_stream_success_cb_t, void *);
static int (*PULSEAUDIO_pa_stream_disconnect) (pa_stream *);
static void (*PULSEAUDIO_pa_stream_unref) (pa_stream *);

static int load_pulseaudio_syms(void);


#ifdef SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC

static const char *pulseaudio_library = SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC;
static void *pulseaudio_handle = NULL;

static int
load_pulseaudio_sym(const char *fn, void **addr)
{
    *addr = SDL_LoadFunction(pulseaudio_handle, fn);
    if (*addr == NULL) {
        /* Don't call SDL_SetError(): SDL_LoadFunction already did. */
        return 0;
    }

    return 1;
}

/* cast funcs to char* first, to please GCC's strict aliasing rules. */
#define SDL_PULSEAUDIO_SYM(x) \
    if (!load_pulseaudio_sym(#x, (void **) (char *) &PULSEAUDIO_##x)) return -1

static void
UnloadPulseAudioLibrary(void)
{
    if (pulseaudio_handle != NULL) {
        SDL_UnloadObject(pulseaudio_handle);
        pulseaudio_handle = NULL;
    }
}

static int
LoadPulseAudioLibrary(void)
{
    int retval = 0;
    if (pulseaudio_handle == NULL) {
        pulseaudio_handle = SDL_LoadObject(pulseaudio_library);
        if (pulseaudio_handle == NULL) {
            retval = -1;
            /* Don't call SDL_SetError(): SDL_LoadObject already did. */
        } else {
            retval = load_pulseaudio_syms();
            if (retval < 0) {
                UnloadPulseAudioLibrary();
            }
        }
    }
    return retval;
}

#else

#define SDL_PULSEAUDIO_SYM(x) PULSEAUDIO_##x = x

static void
UnloadPulseAudioLibrary(void)
{
}

static int
LoadPulseAudioLibrary(void)
{
    load_pulseaudio_syms();
    return 0;
}

#endif /* SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC */


static int
load_pulseaudio_syms(void)
{
    SDL_PULSEAUDIO_SYM(pa_get_library_version);
    SDL_PULSEAUDIO_SYM(pa_mainloop_new);
    SDL_PULSEAUDIO_SYM(pa_mainloop_get_api);
    SDL_PULSEAUDIO_SYM(pa_mainloop_iterate);
    SDL_PULSEAUDIO_SYM(pa_mainloop_run);
    SDL_PULSEAUDIO_SYM(pa_mainloop_quit);
    SDL_PULSEAUDIO_SYM(pa_mainloop_free);
    SDL_PULSEAUDIO_SYM(pa_operation_get_state);
    SDL_PULSEAUDIO_SYM(pa_operation_cancel);
    SDL_PULSEAUDIO_SYM(pa_operation_unref);
    SDL_PULSEAUDIO_SYM(pa_context_new);
    SDL_PULSEAUDIO_SYM(pa_context_connect);
    SDL_PULSEAUDIO_SYM(pa_context_get_sink_info_list);
    SDL_PULSEAUDIO_SYM(pa_context_get_source_info_list);
    SDL_PULSEAUDIO_SYM(pa_context_get_sink_info_by_index);
    SDL_PULSEAUDIO_SYM(pa_context_get_source_info_by_index);
    SDL_PULSEAUDIO_SYM(pa_context_get_state);
    SDL_PULSEAUDIO_SYM(pa_context_subscribe);
    SDL_PULSEAUDIO_SYM(pa_context_set_subscribe_callback);
    SDL_PULSEAUDIO_SYM(pa_context_disconnect);
    SDL_PULSEAUDIO_SYM(pa_context_unref);
    SDL_PULSEAUDIO_SYM(pa_stream_new);
    SDL_PULSEAUDIO_SYM(pa_stream_connect_playback);
    SDL_PULSEAUDIO_SYM(pa_stream_connect_record);
    SDL_PULSEAUDIO_SYM(pa_stream_get_state);
    SDL_PULSEAUDIO_SYM(pa_stream_writable_size);
    SDL_PULSEAUDIO_SYM(pa_stream_readable_size);
    SDL_PULSEAUDIO_SYM(pa_stream_write);
    SDL_PULSEAUDIO_SYM(pa_stream_drain);
    SDL_PULSEAUDIO_SYM(pa_stream_disconnect);
    SDL_PULSEAUDIO_SYM(pa_stream_peek);
    SDL_PULSEAUDIO_SYM(pa_stream_drop);
    SDL_PULSEAUDIO_SYM(pa_stream_flush);
    SDL_PULSEAUDIO_SYM(pa_stream_unref);
    SDL_PULSEAUDIO_SYM(pa_channel_map_init_auto);
    SDL_PULSEAUDIO_SYM(pa_strerror);
    return 0;
}

static SDL_INLINE int
squashVersion(const int major, const int minor, const int patch)
{
    return ((major & 0xFF) << 16) | ((minor & 0xFF) << 8) | (patch & 0xFF);
}

/* Workaround for older pulse: pa_context_new() must have non-NULL appname */
static const char *
getAppName(void)
{
    const char *verstr = PULSEAUDIO_pa_get_library_version();
    if (verstr != NULL) {
        int maj, min, patch;
        if (SDL_sscanf(verstr, "%d.%d.%d", &maj, &min, &patch) == 3) {
            if (squashVersion(maj, min, patch) >= squashVersion(0, 9, 15)) {
                return NULL;  /* 0.9.15+ handles NULL correctly. */
            }
        }
    }
    return "SDL Application";  /* oh well. */
}

static void
stream_operation_complete_no_op(pa_stream *s, int success, void *userdata)
{
    /* no-op for pa_stream_drain(), etc, to use for callback. */
}

static void
WaitForPulseOperation(pa_mainloop *mainloop, pa_operation *o)
{
    /* This checks for NO errors currently. Either fix that, check results elsewhere, or do things you don't care about. */
    if (mainloop && o) {
        SDL_bool okay = SDL_TRUE;
        while (okay && (PULSEAUDIO_pa_operation_get_state(o) == PA_OPERATION_RUNNING)) {
            okay = (PULSEAUDIO_pa_mainloop_iterate(mainloop, 1, NULL) >= 0);
        }
        PULSEAUDIO_pa_operation_unref(o);
    }
}

static void
DisconnectFromPulseServer(pa_mainloop *mainloop, pa_context *context)
{
    if (context) {
        PULSEAUDIO_pa_context_disconnect(context);
        PULSEAUDIO_pa_context_unref(context);
    }
    if (mainloop != NULL) {
        PULSEAUDIO_pa_mainloop_free(mainloop);
    }
}

static int
ConnectToPulseServer_Internal(pa_mainloop **_mainloop, pa_context **_context)
{
    pa_mainloop *mainloop = NULL;
    pa_context *context = NULL;
    pa_mainloop_api *mainloop_api = NULL;
    int state = 0;

    *_mainloop = NULL;
    *_context = NULL;

    /* Set up a new main loop */
    if (!(mainloop = PULSEAUDIO_pa_mainloop_new())) {
        return SDL_SetError("pa_mainloop_new() failed");
    }

    *_mainloop = mainloop;

    mainloop_api = PULSEAUDIO_pa_mainloop_get_api(mainloop);
    SDL_assert(mainloop_api);  /* this never fails, right? */

    context = PULSEAUDIO_pa_context_new(mainloop_api, getAppName());
    if (!context) {
        return SDL_SetError("pa_context_new() failed");
    }
    *_context = context;

    /* Connect to the PulseAudio server */
    if (PULSEAUDIO_pa_context_connect(context, NULL, 0, NULL) < 0) {
        return SDL_SetError("Could not setup connection to PulseAudio");
    }

    do {
        if (PULSEAUDIO_pa_mainloop_iterate(mainloop, 1, NULL) < 0) {
            return SDL_SetError("pa_mainloop_iterate() failed");
        }
        state = PULSEAUDIO_pa_context_get_state(context);
        if (!PA_CONTEXT_IS_GOOD(state)) {
            return SDL_SetError("Could not connect to PulseAudio");
        }
    } while (state != PA_CONTEXT_READY);

    return 0;  /* connected and ready! */
}

static int
ConnectToPulseServer(pa_mainloop **_mainloop, pa_context **_context)
{
    const int retval = ConnectToPulseServer_Internal(_mainloop, _context);
    if (retval < 0) {
        DisconnectFromPulseServer(*_mainloop, *_context);
    }
    return retval;
}


/* This function waits until it is possible to write a full sound buffer */
static void
PULSEAUDIO_WaitDevice(_THIS)
{
    struct SDL_PrivateAudioData *h = this->hidden;

    while (SDL_AtomicGet(&this->enabled)) {
        if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
            PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
            PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
            SDL_OpenedAudioDeviceDisconnected(this);
            return;
        }
        if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= h->mixlen) {
            return;
        }
    }
}

static void
PULSEAUDIO_PlayDevice(_THIS)
{
    /* Write the audio data */
    struct SDL_PrivateAudioData *h = this->hidden;
    if (SDL_AtomicGet(&this->enabled)) {
        if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
            SDL_OpenedAudioDeviceDisconnected(this);
        }
    }
}

static Uint8 *
PULSEAUDIO_GetDeviceBuf(_THIS)
{
    return (this->hidden->mixbuf);
}


static int
PULSEAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
{
    struct SDL_PrivateAudioData *h = this->hidden;
    const void *data = NULL;
    size_t nbytes = 0;

    while (SDL_AtomicGet(&this->enabled)) {
        if (h->capturebuf != NULL) {
            const int cpy = SDL_min(buflen, h->capturelen);
            SDL_memcpy(buffer, h->capturebuf, cpy);
            /*printf("PULSEAUDIO: fed %d captured bytes\n", cpy);*/
            h->capturebuf += cpy;
            h->capturelen -= cpy;
            if (h->capturelen == 0) {
                h->capturebuf = NULL;
                PULSEAUDIO_pa_stream_drop(h->stream);  /* done with this fragment. */
            }
            return cpy;  /* new data, return it. */
        }

        if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
            PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
            PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
            SDL_OpenedAudioDeviceDisconnected(this);
            return -1;  /* uhoh, pulse failed! */
        }

        if (PULSEAUDIO_pa_stream_readable_size(h->stream) == 0) {
            continue;  /* no data available yet. */
        }

        /* a new fragment is available! */
        PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes);
        SDL_assert(nbytes > 0);
        if (data == NULL) {  /* NULL==buffer had a hole. Ignore that. */
            PULSEAUDIO_pa_stream_drop(h->stream);  /* drop this fragment. */
        } else {
            /* store this fragment's data, start feeding it to SDL. */
            /*printf("PULSEAUDIO: captured %d new bytes\n", (int) nbytes);*/
            h->capturebuf = (const Uint8 *) data;
            h->capturelen = nbytes;
        }
    }

    return -1;  /* not enabled? */
}

static void
PULSEAUDIO_FlushCapture(_THIS)
{
    struct SDL_PrivateAudioData *h = this->hidden;

    if (h->capturebuf != NULL) {
        PULSEAUDIO_pa_stream_drop(h->stream);
        h->capturebuf = NULL;
        h->capturelen = 0;
    }

    WaitForPulseOperation(h->mainloop, PULSEAUDIO_pa_stream_flush(h->stream, stream_operation_complete_no_op, NULL));
}

static void
PULSEAUDIO_CloseDevice(_THIS)
{
    if (this->hidden->stream) {
        if (this->hidden->capturebuf != NULL) {
            PULSEAUDIO_pa_stream_drop(this->hidden->stream);
        }
        PULSEAUDIO_pa_stream_disconnect(this->hidden->stream);
        PULSEAUDIO_pa_stream_unref(this->hidden->stream);
    }

    DisconnectFromPulseServer(this->hidden->mainloop, this->hidden->context);
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden->device_name);
    SDL_free(this->hidden);
}

static void
SinkDeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
{
    if (i) {
        char **devname = (char **) data;
        *devname = SDL_strdup(i->name);
    }
}

static void
SourceDeviceNameCallback(pa_context *c, const pa_source_info *i, int is_last, void *data)
{
    if (i) {
        char **devname = (char **) data;
        *devname = SDL_strdup(i->name);
    }
}

static SDL_bool
FindDeviceName(struct SDL_PrivateAudioData *h, const int iscapture, void *handle)
{
    const uint32_t idx = ((uint32_t) ((size_t) handle)) - 1;

    if (handle == NULL) {  /* NULL == default device. */
        return SDL_TRUE;
    }

    if (iscapture) {
        WaitForPulseOperation(h->mainloop,
            PULSEAUDIO_pa_context_get_source_info_by_index(h->context, idx,
                SourceDeviceNameCallback, &h->device_name));
    } else {
        WaitForPulseOperation(h->mainloop,
            PULSEAUDIO_pa_context_get_sink_info_by_index(h->context, idx,
                SinkDeviceNameCallback, &h->device_name));
    }

    return (h->device_name != NULL);
}

static int
PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    struct SDL_PrivateAudioData *h = NULL;
    Uint16 test_format = 0;
    pa_sample_spec paspec;
    pa_buffer_attr paattr;
    pa_channel_map pacmap;
    pa_stream_flags_t flags = 0;
    int state = 0;
    int rc = 0;

    /* Initialize all variables that we clean on shutdown */
    h = this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_zerop(this->hidden);

    paspec.format = PA_SAMPLE_INVALID;

    /* Try for a closest match on audio format */
    for (test_format = SDL_FirstAudioFormat(this->spec.format);
         (paspec.format == PA_SAMPLE_INVALID) && test_format;) {
#ifdef DEBUG_AUDIO
        fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
#endif
        switch (test_format) {
        case AUDIO_U8:
            paspec.format = PA_SAMPLE_U8;
            break;
        case AUDIO_S16LSB:
            paspec.format = PA_SAMPLE_S16LE;
            break;
        case AUDIO_S16MSB:
            paspec.format = PA_SAMPLE_S16BE;
            break;
        case AUDIO_S32LSB:
            paspec.format = PA_SAMPLE_S32LE;
            break;
        case AUDIO_S32MSB:
            paspec.format = PA_SAMPLE_S32BE;
            break;
        case AUDIO_F32LSB:
            paspec.format = PA_SAMPLE_FLOAT32LE;
            break;
        case AUDIO_F32MSB:
            paspec.format = PA_SAMPLE_FLOAT32BE;
            break;
        default:
            paspec.format = PA_SAMPLE_INVALID;
            break;
        }
        if (paspec.format == PA_SAMPLE_INVALID) {
            test_format = SDL_NextAudioFormat();
        }
    }
    if (paspec.format == PA_SAMPLE_INVALID) {
        return SDL_SetError("Couldn't find any hardware audio formats");
    }
    this->spec.format = test_format;

    /* Calculate the final parameters for this audio specification */
#ifdef PA_STREAM_ADJUST_LATENCY
    this->spec.samples /= 2; /* Mix in smaller chunck to avoid underruns */
#endif
    SDL_CalculateAudioSpec(&this->spec);

    /* Allocate mixing buffer */
    if (!iscapture) {
        h->mixlen = this->spec.size;
        h->mixbuf = (Uint8 *) SDL_malloc(h->mixlen);
        if (h->mixbuf == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(h->mixbuf, this->spec.silence, this->spec.size);
    }

    paspec.channels = this->spec.channels;
    paspec.rate = this->spec.freq;

    /* Reduced prebuffering compared to the defaults. */
#ifdef PA_STREAM_ADJUST_LATENCY
    /* 2x original requested bufsize */
    paattr.tlength = h->mixlen * 4;
    paattr.prebuf = -1;
    paattr.maxlength = -1;
    /* -1 can lead to pa_stream_writable_size() >= mixlen never being true */
    paattr.minreq = h->mixlen;
    flags = PA_STREAM_ADJUST_LATENCY;
#else
    paattr.tlength = h->mixlen*2;
    paattr.prebuf = h->mixlen*2;
    paattr.maxlength = h->mixlen*2;
    paattr.minreq = h->mixlen;
#endif

    if (ConnectToPulseServer(&h->mainloop, &h->context) < 0) {
        return SDL_SetError("Could not connect to PulseAudio server");
    }

    if (!FindDeviceName(h, iscapture, handle)) {
        return SDL_SetError("Requested PulseAudio sink/source missing?");
    }

    /* The SDL ALSA output hints us that we use Windows' channel mapping */
    /* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */
    PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels,
                                        PA_CHANNEL_MAP_WAVEEX);

    h->stream = PULSEAUDIO_pa_stream_new(
        h->context,
        "Simple DirectMedia Layer", /* stream description */
        &paspec,    /* sample format spec */
        &pacmap     /* channel map */
        );

    if (h->stream == NULL) {
        return SDL_SetError("Could not set up PulseAudio stream");
    }

    /* now that we have multi-device support, don't move a stream from
        a device that was unplugged to something else, unless we're default. */
    if (h->device_name != NULL) {
        flags |= PA_STREAM_DONT_MOVE;
    }

    if (iscapture) {
        rc = PULSEAUDIO_pa_stream_connect_record(h->stream, h->device_name, &paattr, flags);
    } else {
        rc = PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags, NULL, NULL);
    }

    if (rc < 0) {
        return SDL_SetError("Could not connect PulseAudio stream");
    }

    do {
        if (PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
            return SDL_SetError("pa_mainloop_iterate() failed");
        }
        state = PULSEAUDIO_pa_stream_get_state(h->stream);
        if (!PA_STREAM_IS_GOOD(state)) {
            return SDL_SetError("Could not connect PulseAudio stream");
        }
    } while (state != PA_STREAM_READY);

    /* We're ready to rock and roll. :-) */
    return 0;
}

static pa_mainloop *hotplug_mainloop = NULL;
static pa_context *hotplug_context = NULL;
static SDL_Thread *hotplug_thread = NULL;

/* device handles are device index + 1, cast to void*, so we never pass a NULL. */

/* This is called when PulseAudio adds an output ("sink") device. */
static void
SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
{
    if (i) {
        SDL_AddAudioDevice(SDL_FALSE, i->description, (void *) ((size_t) i->index+1));
    }
}

/* This is called when PulseAudio adds a capture ("source") device. */
static void
SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_last, void *data)
{
    if (i) {
        /* Skip "monitor" sources. These are just output from other sinks. */
        if (i->monitor_of_sink == PA_INVALID_INDEX) {
            SDL_AddAudioDevice(SDL_TRUE, i->description, (void *) ((size_t) i->index+1));
        }
    }
}

/* This is called when PulseAudio has a device connected/removed/changed. */
static void
HotplugCallback(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *data)
{
    const SDL_bool added = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW);
    const SDL_bool removed = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE);

    if (added || removed) {  /* we only care about add/remove events. */
        const SDL_bool sink = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK);
        const SDL_bool source = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE);

        /* adds need sink details from the PulseAudio server. Another callback... */
        if (added && sink) {
            PULSEAUDIO_pa_context_get_sink_info_by_index(hotplug_context, idx, SinkInfoCallback, NULL);
        } else if (added && source) {
            PULSEAUDIO_pa_context_get_source_info_by_index(hotplug_context, idx, SourceInfoCallback, NULL);
        } else if (removed && (sink || source)) {
            /* removes we can handle just with the device index. */
            SDL_RemoveAudioDevice(source != 0, (void *) ((size_t) idx+1));
        }
    }
}

/* this runs as a thread while the Pulse target is initialized to catch hotplug events. */
static int SDLCALL
HotplugThread(void *data)
{
    pa_operation *o;
    SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW);
    PULSEAUDIO_pa_context_set_subscribe_callback(hotplug_context, HotplugCallback, NULL);
    o = PULSEAUDIO_pa_context_subscribe(hotplug_context, PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE, NULL, NULL);
    PULSEAUDIO_pa_operation_unref(o);  /* don't wait for it, just do our thing. */
    PULSEAUDIO_pa_mainloop_run(hotplug_mainloop, NULL);
    return 0;
}

static void
PULSEAUDIO_DetectDevices()
{
    WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_sink_info_list(hotplug_context, SinkInfoCallback, NULL));
    WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_source_info_list(hotplug_context, SourceInfoCallback, NULL));

    /* ok, we have a sane list, let's set up hotplug notifications now... */
    hotplug_thread = SDL_CreateThreadInternal(HotplugThread, "PulseHotplug", 256 * 1024, NULL);
}

static void
PULSEAUDIO_Deinitialize(void)
{
    if (hotplug_thread) {
        PULSEAUDIO_pa_mainloop_quit(hotplug_mainloop, 0);
        SDL_WaitThread(hotplug_thread, NULL);
        hotplug_thread = NULL;
    }

    DisconnectFromPulseServer(hotplug_mainloop, hotplug_context);
    hotplug_mainloop = NULL;
    hotplug_context = NULL;

    UnloadPulseAudioLibrary();
}

static int
PULSEAUDIO_Init(SDL_AudioDriverImpl * impl)
{
    if (LoadPulseAudioLibrary() < 0) {
        return 0;
    }

    if (ConnectToPulseServer(&hotplug_mainloop, &hotplug_context) < 0) {
        UnloadPulseAudioLibrary();
        return 0;
    }

    /* Set the function pointers */
    impl->DetectDevices = PULSEAUDIO_DetectDevices;
    impl->OpenDevice = PULSEAUDIO_OpenDevice;
    impl->PlayDevice = PULSEAUDIO_PlayDevice;
    impl->WaitDevice = PULSEAUDIO_WaitDevice;
    impl->GetDeviceBuf = PULSEAUDIO_GetDeviceBuf;
    impl->CloseDevice = PULSEAUDIO_CloseDevice;
    impl->Deinitialize = PULSEAUDIO_Deinitialize;
    impl->CaptureFromDevice = PULSEAUDIO_CaptureFromDevice;
    impl->FlushCapture = PULSEAUDIO_FlushCapture;

    impl->HasCaptureSupport = SDL_TRUE;

    return 1;   /* this audio target is available. */
}

AudioBootStrap PULSEAUDIO_bootstrap = {
    "pulseaudio", "PulseAudio", PULSEAUDIO_Init, 0
};

#endif /* SDL_AUDIO_DRIVER_PULSEAUDIO */

/* vi: set ts=4 sw=4 expandtab: */
