/*
 * Wine Driver for jack Sound Server
 *   http://jackit.sourceforge.net
 *
 * Copyright 1994 Martin Ayotte
 * Copyright 1999 Eric Pouech (async playing in waveOut/waveIn)
 * Copyright 2000 Eric Pouech (loops in waveOut)
 * Copyright 2002 Chris Morgan (jack version of this file)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

/*
 * TODO:
 *  implement audio stream resampling for any arbitrary frequenty
 *    right now we use the winmm layer to do resampling although it would 
 *    be nice to have a full set of algorithms to choose from based on cpu 
 *    time
 *
 * FIXME:
 *  pause in waveOut during loop is not handled correctly
 */

#include "config.h"

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <fcntl.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "wingdi.h"
#include "winerror.h"
#include "mmddk.h"
#include "dsound.h"
#include "dsdriver.h"
#include "jack.h"
#include "wine/unicode.h"
#include "wine/library.h"
#include "wine/debug.h"

#ifdef HAVE_JACK_JACK_H
#include <jack/jack.h>
#endif


WINE_DEFAULT_DEBUG_CHANNEL(wave);

#ifdef SONAME_LIBJACK

#define MAKE_FUNCPTR(f) static typeof(f) * fp_##f = NULL;

/* Function pointers for dynamic loading of libjack */
/* these are prefixed with "fp_", ie. "fp_jack_client_new" */
MAKE_FUNCPTR(jack_activate);
MAKE_FUNCPTR(jack_connect);
MAKE_FUNCPTR(jack_client_new);
MAKE_FUNCPTR(jack_client_close);
MAKE_FUNCPTR(jack_deactivate);
MAKE_FUNCPTR(jack_set_process_callback);
MAKE_FUNCPTR(jack_set_buffer_size_callback);
MAKE_FUNCPTR(jack_set_sample_rate_callback);
MAKE_FUNCPTR(jack_on_shutdown);
MAKE_FUNCPTR(jack_get_sample_rate);
MAKE_FUNCPTR(jack_port_register);
MAKE_FUNCPTR(jack_port_get_buffer);
MAKE_FUNCPTR(jack_get_ports);
MAKE_FUNCPTR(jack_port_name);
MAKE_FUNCPTR(jack_get_buffer_size);
#undef MAKE_FUNCPTR

/* define the below to work around a bug in jack where closing a port */
/* takes a very long time, so to get around this we actually don't */
/* close the port when the device is closed but instead mark the */
/* corresponding device as unused */
#define JACK_CLOSE_HACK    1

typedef jack_default_audio_sample_t sample_t;
typedef jack_nframes_t nframes_t;

/* only allow 10 output devices through this driver, this ought to be adequate */
#define MAX_WAVEOUTDRV  (10)
#define MAX_WAVEINDRV   (10)

/* state diagram for waveOut writing:
 *
 * +---------+-------------+---------------+---------------------------------+
 * |  state  |  function   |     event     |            new state	     |
 * +---------+-------------+---------------+---------------------------------+
 * |	     | open()	   |		   | STOPPED		       	     |
 * | PAUSED  | write()	   | 		   | PAUSED		       	     |
 * | STOPPED | write()	   | <thrd create> | PLAYING		  	     |
 * | PLAYING | write()	   | HEADER        | PLAYING		  	     |
 * | (other) | write()	   | <error>       |		       		     |
 * | (any)   | pause()	   | PAUSING	   | PAUSED		       	     |
 * | PAUSED  | restart()   | RESTARTING    | PLAYING (if no thrd => STOPPED) |
 * | (any)   | reset()	   | RESETTING     | STOPPED		      	     |
 * | (any)   | close()	   | CLOSING	   | CLOSED		      	     |
 * +---------+-------------+---------------+---------------------------------+
 */

/* states of the playing device */
#define	WINE_WS_PLAYING   0
#define	WINE_WS_PAUSED    1
#define	WINE_WS_STOPPED   2
#define WINE_WS_CLOSED    3

typedef struct {
    volatile int      state;      /* one of the WINE_WS_ manifest constants */
    WAVEOPENDESC      waveDesc;
    WORD              wFlags;
    PCMWAVEFORMAT     format;
    WAVEOUTCAPSW      caps;
    WORD              wDevID;
    char              interface_name[32];

    jack_port_t*      out_port_l;   /* ports for left and right channels */
    jack_port_t*      out_port_r;
    jack_client_t*    client;
    long              sample_rate;        /* jack server sample rate */

#if JACK_CLOSE_HACK
    BOOL              in_use; /* TRUE if this device is in use */
#endif

    char*             sound_buffer;
    unsigned long     buffer_size;

    DWORD             volume_left;
    DWORD             volume_right;

    LPWAVEHDR         lpQueuePtr;   /* start of queued WAVEHDRs (waiting to be notified) */
    LPWAVEHDR         lpPlayPtr;    /* start of not yet fully played buffers */
    DWORD             dwPartialOffset;  /* Offset of not yet written bytes in lpPlayPtr */

    LPWAVEHDR         lpLoopPtr;    /* pointer of first buffer in loop, if any */
    DWORD             dwLoops;      /* private copy of loop counter */
    
    DWORD             dwPlayedTotal;    /* number of bytes actually played since opening */
    DWORD             dwWrittenTotal;   /* number of bytes written to jack since opening */

    DWORD	      bytesInJack; /* bytes that we wrote during the previous JACK_Callback() */
    DWORD	      tickCountMS; /* time in MS of last JACK_Callback() */

    /* synchronization stuff */
    CRITICAL_SECTION    access_crst;
} WINE_WAVEOUT;

typedef struct {
    volatile int    state;
    WAVEOPENDESC    waveDesc;
    WORD            wFlags;
    PCMWAVEFORMAT   format;
    LPWAVEHDR       lpQueuePtr;
    DWORD           dwTotalRecorded;
    WAVEINCAPSW     caps;
    BOOL            bTriggerSupport;
    WORD              wDevID;
    char              interface_name[32];

    jack_port_t*      in_port_l;   /* ports for left and right channels */
    jack_port_t*      in_port_r;
    jack_client_t*    client;
    long              sample_rate;        /* jack server sample rate */

#if JACK_CLOSE_HACK
    BOOL              in_use; /* TRUE if this device is in use */
#endif

    char*             sound_buffer;
    unsigned long     buffer_size;

    /* synchronization stuff */
    CRITICAL_SECTION    access_crst;
} WINE_WAVEIN;

static WINE_WAVEOUT WOutDev   [MAX_WAVEOUTDRV];
static WINE_WAVEIN  WInDev    [MAX_WAVEINDRV ];

static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv);
static DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc);

static LPWAVEHDR wodHelper_PlayPtrNext(WINE_WAVEOUT* wwo);
static DWORD wodHelper_NotifyCompletions(WINE_WAVEOUT* wwo, BOOL force);

static int JACK_OpenWaveOutDevice(WINE_WAVEOUT* wwo);
static int JACK_OpenWaveInDevice(WINE_WAVEIN* wwi, WORD nChannels);

#if JACK_CLOSE_HACK
static void	JACK_CloseWaveOutDevice(WINE_WAVEOUT* wwo, BOOL close_client);
#else
static void	JACK_CloseWaveOutDevice(WINE_WAVEOUT* wwo);
#endif

#if JACK_CLOSE_HACK
static void	JACK_CloseWaveInDevice(WINE_WAVEIN* wwi, BOOL close_client);
#else
static void	JACK_CloseWaveInDevice(WINE_WAVEIN* wwi);
#endif

static DWORD bytes_to_mmtime(LPMMTIME lpTime, DWORD position,
                             PCMWAVEFORMAT* format)
{
    TRACE("wType=%04X wBitsPerSample=%u nSamplesPerSec=%u nChannels=%u nAvgBytesPerSec=%u\n",
          lpTime->wType, format->wBitsPerSample, format->wf.nSamplesPerSec,
          format->wf.nChannels, format->wf.nAvgBytesPerSec);
    TRACE("Position in bytes=%u\n", position);

    switch (lpTime->wType) {
    case TIME_SAMPLES:
        lpTime->u.sample = position / (format->wBitsPerSample / 8 * format->wf.nChannels);
        TRACE("TIME_SAMPLES=%u\n", lpTime->u.sample);
        break;
    case TIME_MS:
        lpTime->u.ms = 1000.0 * position / (format->wBitsPerSample / 8 * format->wf.nChannels * format->wf.nSamplesPerSec);
        TRACE("TIME_MS=%u\n", lpTime->u.ms);
        break;
    case TIME_SMPTE:
        lpTime->u.smpte.fps = 30;
        position = position / (format->wBitsPerSample / 8 * format->wf.nChannels);
        position += (format->wf.nSamplesPerSec / lpTime->u.smpte.fps) - 1; /* round up */
        lpTime->u.smpte.sec = position / format->wf.nSamplesPerSec;
        position -= lpTime->u.smpte.sec * format->wf.nSamplesPerSec;
        lpTime->u.smpte.min = lpTime->u.smpte.sec / 60;
        lpTime->u.smpte.sec -= 60 * lpTime->u.smpte.min;
        lpTime->u.smpte.hour = lpTime->u.smpte.min / 60;
        lpTime->u.smpte.min -= 60 * lpTime->u.smpte.hour;
        lpTime->u.smpte.fps = 30;
        lpTime->u.smpte.frame = position * lpTime->u.smpte.fps / format->wf.nSamplesPerSec;
        TRACE("TIME_SMPTE=%02u:%02u:%02u:%02u\n",
              lpTime->u.smpte.hour, lpTime->u.smpte.min,
              lpTime->u.smpte.sec, lpTime->u.smpte.frame);
        break;
    default:
        WARN("Format %d not supported, using TIME_BYTES !\n", lpTime->wType);
        lpTime->wType = TIME_BYTES;
        /* fall through */
    case TIME_BYTES:
        lpTime->u.cb = position;
        TRACE("TIME_BYTES=%u\n", lpTime->u.cb);
        break;
    }
    return MMSYSERR_NOERROR;
}


/*======================================================================*
 *                  Low level WAVE implementation			*
 *======================================================================*/

#define SAMPLE_MAX_16BIT  32767.0f

/* Alsaplayer function that applies volume changes to a buffer */
/* (C) Andy Lo A Foe */
/* Length is in terms of 32 bit samples */
static void volume_effect32(void *buffer, int length, int left, int right)
{
        short *data = buffer;
        int i, v;
    
        if (right == -1) right = left;
 
        for(i = 0; i < length; i++) {
                v = (int) ((*(data) * left) / 100);
                *(data++) = (v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
                v = (int) ((*(data) * right) / 100);
                *(data++) = (v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
        }
}

/* move 16 bit mono/stereo to 16 bit stereo */
static void sample_move_d16_d16(short *dst, short *src,
                  unsigned long nsamples, int nChannels)
{
  while(nsamples--)
  {
    *dst = *src;
    dst++;

    if(nChannels == 2) src++;

    *dst = *src;
    dst++;

    src++;
  }
}

/* convert from 16 bit to floating point */
/* allow for copying of stereo data with alternating left/right */
/* channels to a buffer that will hold a single channel stream */
/* nsamples is in terms of 16bit samples */
/* src_skip is in terms of 16bit samples */
static void sample_move_d16_s16 (sample_t *dst, short *src,
                        unsigned long nsamples, unsigned long src_skip)
{
  /* ALERT: signed sign-extension portability !!! */
  while (nsamples--)
  {
    *dst = (*src) / SAMPLE_MAX_16BIT;
    dst++;
    src += src_skip;
  }
}       

/* convert from floating point to 16 bit */
/* allow for copying of a buffer that will hold a single channel stream */
/* to stereo data with alternating left/right channels */
/* nsamples is in terms of float samples */
/* dst_skip is in terms of 16bit samples */
static void sample_move_s16_d16 (short *dst, sample_t *src,
                        unsigned long nsamples, unsigned long dst_skip)
{
  /* ALERT: signed sign-extension portability !!! */
  while (nsamples--)
  {
      *dst = (*src) * SAMPLE_MAX_16BIT;
/*      TRACE("src=(%.8f,%p) dst=(%d,%p)\n",*src,src,*dst,dst); */
      dst += dst_skip;
      src++;
  }
}       


/* fill dst buffer with nsamples worth of silence */
static void sample_silence_dS (sample_t *dst, unsigned long nsamples)
{
  /* ALERT: signed sign-extension portability !!! */
  while (nsamples--)
  {
    *dst = 0;
    dst++;
  }
}       

/******************************************************************
 *    JACK_callback_wwo
 */
/* everytime the jack server wants something from us it calls this 
function, so we either deliver it some sound to play or deliver it nothing 
to play */
static int JACK_callback_wwo (nframes_t nframes, void *arg)
{
  sample_t* out_l;
  sample_t* out_r;
  WINE_WAVEOUT* wwo = arg;

  TRACE("wDevID: %u, nframes %u state=%u\n", wwo->wDevID, nframes,wwo->state);

  if(!wwo->client)
    ERR("client is closed, this is weird...\n");

  out_l = fp_jack_port_get_buffer(wwo->out_port_l, nframes);
  out_r = fp_jack_port_get_buffer(wwo->out_port_r, nframes);

  if(wwo->state == WINE_WS_PLAYING)
  {
    DWORD jackFramesAvailable = nframes;
    DWORD outputFramesAvailable;
    DWORD numFramesToWrite;

    long written = 0;
    char* buffer;

#if JACK_CLOSE_HACK
    if(wwo->in_use == FALSE)
    {
      /* output silence if nothing is being outputted */
      sample_silence_dS(out_l, nframes);
      sample_silence_dS(out_r, nframes);

      return 0;
    }
#endif

    TRACE("wwo.state == WINE_WS_PLAYING\n");

    /* see if our sound_buffer is large enough to hold the number of frames jack requested */
    /* Note: sound_buffer is always filled with 16-bit stereo data, even for mono mode */
    if(wwo->buffer_size < (nframes * sizeof(short) * 2))
    {
      ERR("for some reason JACK_BufSize() didn't allocate enough memory\n");
      ERR("allocated %ld bytes, need %d bytes\n", wwo->buffer_size, (nframes * (unsigned)sizeof(short) * 2));
      return 0;
    }

    /* while we have jackFramesAvailable and a wave header to be played */
    while(jackFramesAvailable && wwo->lpPlayPtr)
    {
      /* find the amount of audio to be played at this time */
      outputFramesAvailable = (wwo->lpPlayPtr->dwBufferLength - wwo->dwPartialOffset) / wwo->format.wf.nBlockAlign;

      numFramesToWrite = min(jackFramesAvailable, outputFramesAvailable);
      TRACE("dwBufferLength=(%d) dwPartialOffset=(%d)\n",wwo->lpPlayPtr->dwBufferLength,wwo->dwPartialOffset);
      TRACE("outputFramesAvailable == %d, jackFramesAvailable == %d\n", outputFramesAvailable, jackFramesAvailable);

      buffer = wwo->lpPlayPtr->lpData + wwo->dwPartialOffset;

      /* convert from mono to stereo if necessary */
      /* otherwise just memcpy to the output buffer */

      if(wwo->format.wf.nChannels == 1)
      {
	sample_move_d16_d16((short*)wwo->sound_buffer + ((nframes - jackFramesAvailable) * sizeof(short)),
			    (short*)buffer, numFramesToWrite, wwo->format.wf.nChannels);
      } else /* just copy the memory over */
      {
        memcpy(wwo->sound_buffer + ((nframes - jackFramesAvailable) * wwo->format.wf.nBlockAlign),
	       buffer, numFramesToWrite * wwo->format.wf.nBlockAlign);
      }

      /* advance to the next wave header if possible, or advance pointer */
      /* inside of the current header if we haven't completed it */
      if(numFramesToWrite == outputFramesAvailable)
      {
        wodHelper_PlayPtrNext(wwo);            /* we wrote the whole waveheader, skip to the next one*/
      }
      else
      {
        wwo->dwPartialOffset+=(numFramesToWrite * wwo->format.wf.nBlockAlign); /* else advance by the bytes we took in to write */
      }

      written+=(numFramesToWrite * wwo->format.wf.nBlockAlign); /* add on what we wrote */
      jackFramesAvailable-=numFramesToWrite; /* take away what was written in terms of output bytes */
    }

    wwo->tickCountMS = GetTickCount();    /* record the current time */
    wwo->dwWrittenTotal+=written; /* update states on wave device */
    wwo->dwPlayedTotal+=wwo->bytesInJack; /* we must have finished with the last bytes or we wouldn't be back inside of this callback again... */
    wwo->bytesInJack = written; /* record the bytes inside of jack */

    /* Now that we have finished filling the buffer either until it is full or until */
    /* we have run out of application sound data to process, apply volume and output */
    /* the audio to the jack server */

    /* apply volume to the buffer */
    volume_effect32(wwo->sound_buffer, (nframes - jackFramesAvailable), wwo->volume_left, wwo->volume_right);

    /* convert from stereo 16 bit to single channel 32 bit float */
    /* for each jack server channel */
    /* NOTE: we skip over two sample since we want to only get either the left or right channel */
    sample_move_d16_s16(out_l, (short*)wwo->sound_buffer,     (nframes - jackFramesAvailable), 2);
    sample_move_d16_s16(out_r, (short*)wwo->sound_buffer + 1, (nframes - jackFramesAvailable), 2);

    /* see if we still have jackBytesLeft here, if we do that means that we
    ran out of wave data to play and had a buffer underrun, fill in
    the rest of the space with zero bytes */
    if(jackFramesAvailable)
    {
      ERR("buffer underrun of %d frames\n", jackFramesAvailable);
      sample_silence_dS(out_l + (nframes - jackFramesAvailable), jackFramesAvailable);
      sample_silence_dS(out_r + (nframes - jackFramesAvailable), jackFramesAvailable);
    }
  }
  else if(wwo->state == WINE_WS_PAUSED || 
    wwo->state == WINE_WS_STOPPED ||
    wwo->state == WINE_WS_CLOSED)
  {
      /* output silence if nothing is being outputted */
      sample_silence_dS(out_l, nframes);
      sample_silence_dS(out_r, nframes);
  }

  /* notify the client of completed wave headers */
  EnterCriticalSection(&wwo->access_crst);
  wodHelper_NotifyCompletions(wwo, FALSE);
  LeaveCriticalSection(&wwo->access_crst);

  return 0;
}

/******************************************************************
 *		JACK_bufsize_wwo
 *
 *		Called whenever the jack server changes the max number
 *		of frames passed to JACK_callback
 */
static int JACK_bufsize_wwo (nframes_t nframes, void *arg)
{
  WINE_WAVEOUT* wwo = arg;
  DWORD buffer_required;
  TRACE("wDevID=%d\n",wwo->wDevID);
  TRACE("the maximum buffer size is now %u frames\n", nframes);

  /* make sure the callback routine has adequate memory */
    /* see if our buffer is large enough for the data we are writing */
    /* ie. Buffer_size < (bytes we already wrote + bytes we are going to write in this loop) */
  EnterCriticalSection(&wwo->access_crst);

  /* wwo->sound_buffer is always filled with 16-bit stereo data, even for mono streams */
  buffer_required = nframes * sizeof(short) * 2;
  TRACE("wwo->buffer_size (%ld) buffer_required (%d).\n", wwo->buffer_size,buffer_required);
  if(wwo->buffer_size < buffer_required)
  {
    TRACE("expanding buffer from wwo->buffer_size == %ld, to %d\n",
      wwo->buffer_size, buffer_required);
    TRACE("GetProcessHeap() == %p\n", GetProcessHeap());
    wwo->buffer_size = buffer_required;

    if (wwo->sound_buffer)
      wwo->sound_buffer = HeapReAlloc(GetProcessHeap(), 0, wwo->sound_buffer, wwo->buffer_size);
    else
      wwo->sound_buffer = HeapAlloc(GetProcessHeap(), 0, wwo->buffer_size);

    /* if we don't have a buffer then error out */
    if(!wwo->sound_buffer)
    {
        ERR("error allocating sound_buffer memory\n");
        LeaveCriticalSection(&wwo->access_crst);
        return 0;
    }
  }

  LeaveCriticalSection(&wwo->access_crst);

  TRACE("ending\n");

  return 0;
}
/******************************************************************
 *		JACK_bufsize_wwi
 *
 *		Called whenever the jack server changes the max number
 *		of frames passed to JACK_callback
 */
static int JACK_bufsize_wwi (nframes_t nframes, void *arg)
{
  TRACE("the maximum buffer size is now %u frames\n", nframes);
  return 0;
}

/******************************************************************
 *		JACK_srate
 */
static int JACK_srate (nframes_t nframes, void *arg)
{
  TRACE("the sample rate is now %u/sec\n", nframes);
  return 0;
}


/******************************************************************
 *		JACK_shutdown_wwo
 */
/* if this is called then jack shut down... handle this appropriately */
static void JACK_shutdown_wwo(void* arg)
{
  WINE_WAVEOUT* wwo = arg;

  wwo->client = 0; /* reset client */

  TRACE("trying to reconnect after sleeping for a short while...\n");
  
  /* lets see if we can't reestablish the connection */
  Sleep(750); /* pause for a short period of time */
  if(!JACK_OpenWaveOutDevice(wwo))
  {
    ERR("unable to reconnect with jack...\n");
  }
}

/******************************************************************
 *		JACK_shutdown_wwi
 */
/* if this is called then jack shut down... handle this appropriately */
static void JACK_shutdown_wwi(void* arg)
{
  WINE_WAVEIN* wwi = arg;

  wwi->client = 0; /* reset client */

  TRACE("trying to reconnect after sleeping for a short while...\n");
  
  /* lets see if we can't reestablish the connection */
  Sleep(750); /* pause for a short period of time */
  if(!JACK_OpenWaveInDevice(wwi,wwi->format.wf.nChannels))
  {
    ERR("unable to reconnect with jack...\n");
  }
}


/******************************************************************
 *		JACK_OpenWaveOutDevice
 */
static int JACK_OpenWaveOutDevice(WINE_WAVEOUT* wwo)
{
  const char** ports;
  int i;
  char client_name[64];
  jack_port_t* out_port_l;
  jack_port_t* out_port_r;
  jack_client_t* client;
  int failed = 0;

  TRACE("creating jack client and setting up callbacks\n");

#if JACK_CLOSE_HACK
  /* see if this device is already open */
        if(wwo->client)
        {
          /* if this device is already in use then it is bad for us to be in here */
          if(wwo->in_use)
            return 0;

          TRACE("using existing client\n");
          wwo->in_use = TRUE;
          return 1;
        }
#endif

        /* zero out the buffer pointer and the size of the buffer */
        wwo->sound_buffer = 0;
        wwo->buffer_size = 0;

        /* try to become a client of the JACK server */
        snprintf(client_name, sizeof(client_name), "wine_jack_out_%d", wwo->wDevID);
	TRACE("client name '%s'\n", client_name);
        if ((client = fp_jack_client_new (client_name)) == 0)
        {
                /* jack has problems with shutting down clients, so lets */
                /* wait a short while and try once more before we give up */
                Sleep(250);
                if ((client = fp_jack_client_new (client_name)) == 0)
                {
                  ERR("jack server not running?\n");
                  return 0;
                }
        }
	                
        /* tell the JACK server to call `JACK_callback_wwo()' whenever
           there is work to be done. */
        fp_jack_set_process_callback (client, JACK_callback_wwo, wwo);
        
        /* tell the JACK server to call `JACK_bufsize_wwo()' whenever   
           the maximum number of frames that will be passed
           to `JACK_Callback()' changes */
        fp_jack_set_buffer_size_callback (client, JACK_bufsize_wwo, wwo);

        /* tell the JACK server to call `srate()' whenever
           the sample rate of the system changes. */
        fp_jack_set_sample_rate_callback (client, JACK_srate, wwo);

        /* tell the JACK server to call `jack_shutdown()' if
           it ever shuts down, either entirely, or if it
           just decides to stop calling us. */
        fp_jack_on_shutdown (client, JACK_shutdown_wwo, wwo);
        
        /* display the current sample rate. once the client is activated
           (see below), you should rely on your own sample rate
           callback (see above) for this value. */
        wwo->sample_rate = fp_jack_get_sample_rate(client);
        TRACE("engine sample rate: %lu\n", wwo->sample_rate);
          
        /* create the left and right channel output ports */
        /* jack's ports are all mono so for stereo you need two */
        out_port_l = fp_jack_port_register (client, "out_l",
                         JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

        out_port_r = fp_jack_port_register (client, "out_r",
                         JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

	TRACE("Created ports. (%p) (%p)\n",out_port_l, out_port_r);

        /* save away important values to the WINE_WAVEOUT struct */
        wwo->client = client;
        wwo->out_port_l = out_port_l;
        wwo->out_port_r = out_port_r;

#if JACK_CLOSE_HACK
        wwo->in_use = TRUE; /* mark this device as in use since it now is ;-) */
#endif

	/* set initial buffer size */
	JACK_bufsize_wwo (fp_jack_get_buffer_size(client),wwo);

        /* tell the JACK server that we are ready to roll */
        if (fp_jack_activate (client))
        {
          ERR( "cannot activate client\n");
          return 0;
        }

	TRACE("jack activate.\n");
        /* figure out what the ports that we want to output on are */
        /* NOTE: we do this instead of using stuff like "alsa_pcm:playback_X" because */
        /*   this way works if names are changed */
        ports = fp_jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsInput);

        /* display a trace of the output ports we found */
        for(i = 0; ports[i]; i++)
        {
          TRACE("ports[%d] = '%s'\n", i, ports[i]);
        }

        if(!ports)
        {
          ERR("jack_get_ports() failed to find 'JackPortIsPhysical|JackPortIsInput'\n");
        }

        /* connect the ports. Note: you can't do this before
           the client is activated (this may change in the future).
        */ 
        /* we want to connect to two ports so we have stereo output ;-) */

        if(fp_jack_connect(client, fp_jack_port_name(out_port_l), ports[0]))
        {
          ERR ("cannot connect to output port %d('%s')\n", 0, ports[0]);
          failed = 1;
        }

        if(fp_jack_connect(client, fp_jack_port_name(out_port_r), ports[1]))
        {
          ERR ("cannot connect to output port %d('%s')\n", 1, ports[1]);
          failed = 1;
        }

        free(ports); /* free the returned array of ports */

        /* if something failed we need to shut the client down and return 0 */
        if(failed)
        {
#if JACK_CLOSE_HACK
          JACK_CloseWaveOutDevice(wwo, TRUE);
#else
          JACK_CloseWaveOutDevice(wwo);
#endif
          return 0;
        }

        return 1; /* return success */
}

/******************************************************************
 *		JACK_CloseWaveOutDevice
 *
 *	Close the connection to the server cleanly.
 *  If close_client is TRUE we close the client for this device instead of
 *    just marking the device as in_use(JACK_CLOSE_HACK only)
 */
#if JACK_CLOSE_HACK
static void	JACK_CloseWaveOutDevice(WINE_WAVEOUT* wwo, BOOL close_client)
#else
static void	JACK_CloseWaveOutDevice(WINE_WAVEOUT* wwo)
#endif
{
#if JACK_CLOSE_HACK
  TRACE("wDevID: %d, close_client (wwo): %d\n", wwo->wDevID, close_client);
#else
  TRACE("wDevID: %d\n", wwo->wDevID);
#endif

#if JACK_CLOSE_HACK
  if(close_client)
  {
#endif
    fp_jack_deactivate(wwo->client); /* supposed to help the jack_client_close() to succeed */
    fp_jack_client_close (wwo->client);

    EnterCriticalSection(&wwo->access_crst);
    wwo->client = 0; /* reset client */
    HeapFree(GetProcessHeap(), 0, wwo->sound_buffer); /* free buffer memory */
    wwo->sound_buffer = 0;
    wwo->buffer_size = 0; /* zero out size of the buffer */
    LeaveCriticalSection(&wwo->access_crst);
#if JACK_CLOSE_HACK
  } else
  {
    EnterCriticalSection(&wwo->access_crst);
    TRACE("setting in_use to FALSE\n");
    wwo->in_use = FALSE;
    LeaveCriticalSection(&wwo->access_crst);
  }
#endif
}

/******************************************************************
 *		JACK_CloseWaveInDevice
 *
 *	Close the connection to the server cleanly.
 *  If close_client is TRUE we close the client for this device instead of
 *    just marking the device as in_use(JACK_CLOSE_HACK only)
 */
#if JACK_CLOSE_HACK
static void	JACK_CloseWaveInDevice(WINE_WAVEIN* wwi, BOOL close_client)
#else
static void	JACK_CloseWaveInDevice(WINE_WAVEIN* wwi)
#endif
{
#if JACK_CLOSE_HACK
  TRACE("wDevID: %d, close_client (wwi): %d\n", wwi->wDevID, close_client);
#else
  TRACE("wDevID: %d\n", wwi->wDevID);
#endif

#if JACK_CLOSE_HACK
  if(close_client)
  {
#endif
    fp_jack_deactivate(wwi->client); /* supposed to help the jack_client_close() to succeed */
    fp_jack_client_close (wwi->client);

    EnterCriticalSection(&wwi->access_crst);
    wwi->client = 0; /* reset client */
    HeapFree(GetProcessHeap(), 0, wwi->sound_buffer); /* free buffer memory */
    wwi->sound_buffer = 0;
    wwi->buffer_size = 0; /* zero out size of the buffer */
    LeaveCriticalSection(&wwi->access_crst);
#if JACK_CLOSE_HACK
  } else
  {
    EnterCriticalSection(&wwi->access_crst);
    TRACE("setting in_use to FALSE\n");
    wwi->in_use = FALSE;
    LeaveCriticalSection(&wwi->access_crst);
  }
#endif
}

/******************************************************************
 *		JACK_WaveRelease
 *
 *
 */
LONG	JACK_WaveRelease(void)
{ 
  int iDevice;

  TRACE("closing all open waveout devices\n");

  /* close all open output devices */
  for(iDevice = 0; iDevice < MAX_WAVEOUTDRV; iDevice++)
  {
    TRACE("iDevice == %d\n", iDevice);
    if(WOutDev[iDevice].client)
    {
#if JACK_CLOSE_HACK
      JACK_CloseWaveOutDevice(&WOutDev[iDevice], TRUE); /* close the device, FORCE the client to close */
#else
      JACK_CloseWaveOutDevice(&WOutDev[iDevice]); /* close the device, FORCE the client to close */
#endif
      DeleteCriticalSection(&(WOutDev[iDevice].access_crst)); /* delete the critical section */
    }
  }

  TRACE("closing all open wavein devices\n");

  /* close all open input devices */
  for(iDevice = 0; iDevice < MAX_WAVEINDRV; iDevice++)
  {
    TRACE("iDevice == %d\n", iDevice);
    if(WInDev[iDevice].client)
    {
#if JACK_CLOSE_HACK
      JACK_CloseWaveInDevice(&WInDev[iDevice], TRUE); /* close the device, FORCE the client to close */
#else
      JACK_CloseWaveInDevice(&WInDev[iDevice]); /* close the device, FORCE the client to close */
#endif
      DeleteCriticalSection(&(WInDev[iDevice].access_crst)); /* delete the critical section */
    }
  }

  TRACE("returning 1\n");

  return 1;
}

/******************************************************************
 *		JACK_WaveInit
 *
 * Initialize internal structures from JACK server info
 */
LONG JACK_WaveInit(void)
{
    int i;
    CHAR szPname[MAXPNAMELEN];

    TRACE("called\n");

    /* setup function pointers */
#define LOAD_FUNCPTR(f) if((fp_##f = wine_dlsym(jackhandle, #f, NULL, 0)) == NULL) goto sym_not_found;    
    LOAD_FUNCPTR(jack_activate);
    LOAD_FUNCPTR(jack_connect);
    LOAD_FUNCPTR(jack_client_new);
    LOAD_FUNCPTR(jack_client_close);
    LOAD_FUNCPTR(jack_deactivate);
    LOAD_FUNCPTR(jack_set_process_callback);
    LOAD_FUNCPTR(jack_set_buffer_size_callback);
    LOAD_FUNCPTR(jack_set_sample_rate_callback);
    LOAD_FUNCPTR(jack_on_shutdown);
    LOAD_FUNCPTR(jack_get_sample_rate);
    LOAD_FUNCPTR(jack_port_register);
    LOAD_FUNCPTR(jack_port_get_buffer);
    LOAD_FUNCPTR(jack_get_ports);
    LOAD_FUNCPTR(jack_port_name);
    LOAD_FUNCPTR(jack_get_buffer_size);
#undef LOAD_FUNCPTR

    /* start with output device */

    for (i = 0; i < MAX_WAVEOUTDRV; ++i)
    {
      WOutDev[i].client = 0; /* initialize the client to 0 */

#if JACK_CLOSE_HACK
      WOutDev[i].in_use = FALSE;
      WInDev[i].in_use  = FALSE;
#endif

      memset(&WOutDev[i].caps, 0, sizeof(WOutDev[i].caps));

      WOutDev[i].caps.wMid = 0x00FF; 	/* Manufac ID */
      WOutDev[i].caps.wPid = 0x0001; 	/* Product ID */
      snprintf(szPname, sizeof(szPname), "JACK WaveOut %d", i);
      MultiByteToWideChar(CP_ACP, 0, szPname, -1, WOutDev[i].caps.szPname, sizeof(WOutDev[i].caps.szPname)/sizeof(WCHAR));
      snprintf(WOutDev[i].interface_name, sizeof(WOutDev[i].interface_name), "winejack: %d", i);

      WOutDev[i].caps.vDriverVersion = 0x0100;
      WOutDev[i].caps.dwFormats = 0x00000000;
      WOutDev[i].caps.dwSupport = WAVECAPS_VOLUME;
    
      WOutDev[i].caps.wChannels = 2;
      WOutDev[i].caps.dwSupport |= WAVECAPS_LRVOLUME;

/* NOTE: we don't support any 8 bit modes so note that */
/*      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4M08;
      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4S08; */
      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4S16;
      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4M16;
/*      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2M08;
      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2S08; */
      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2M16;
      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2S16;
/*      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1M08;
      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1S08;*/
      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1M16;
      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1S16;
    }

    /* then do input device */
    for (i = 0; i < MAX_WAVEINDRV; ++i)
    {
        /* TODO: we should initialize read stuff here */
        memset(&WInDev[i].caps, 0, sizeof(WInDev[i].caps));

	WInDev[i].caps.wMid = 0x00FF;
	WInDev[i].caps.wPid = 0x0001;
        snprintf(szPname, sizeof(szPname), "JACK WaveIn %d", i);
        MultiByteToWideChar(CP_ACP, 0, szPname, -1, WInDev[i].caps.szPname, sizeof(WInDev[i].caps.szPname)/sizeof(WCHAR));
        snprintf(WInDev[i].interface_name, sizeof(WInDev[i].interface_name), "winejack: %d", i);

	WInDev[i].caps.vDriverVersion = 0x0100;

	WInDev[i].caps.wChannels = 0x2;
	/* NOTE: we don't support any 8 bit modes so note that */
/*      WInDev[i].caps.dwFormats |= WAVE_FORMAT_4M08;
	WInDev[i].caps.dwFormats |= WAVE_FORMAT_4S08; */
	WInDev[i].caps.dwFormats |= WAVE_FORMAT_4S16;
	WInDev[i].caps.dwFormats |= WAVE_FORMAT_4M16;
/*      WInDev[i].caps.dwFormats |= WAVE_FORMAT_2M08;
	WInDev[i].caps.dwFormats |= WAVE_FORMAT_2S08; */
	WInDev[i].caps.dwFormats |= WAVE_FORMAT_2M16;
	WInDev[i].caps.dwFormats |= WAVE_FORMAT_2S16;
/*      WInDev[i].caps.dwFormats |= WAVE_FORMAT_1M08;
	WInDev[i].caps.dwFormats |= WAVE_FORMAT_1S08;*/
	WInDev[i].caps.dwFormats |= WAVE_FORMAT_1M16;
	WInDev[i].caps.dwFormats |= WAVE_FORMAT_1S16;
	WInDev[i].caps.wReserved1 = 0;
    }
    
    return 1;		/* return success */

/* error path for function pointer loading errors */
sym_not_found:
    WINE_MESSAGE(
      "Wine cannot find certain functions that it needs inside the jack"
      "library.  To enable Wine to use the jack audio server please "
      "install libjack\n");
    wine_dlclose(jackhandle, NULL, 0);
    jackhandle = NULL;
    return FALSE;
}

/*======================================================================*
 *                  Low level WAVE OUT implementation			*
 *======================================================================*/

/**************************************************************************
 * 			wodNotifyClient			[internal]
 */
static DWORD wodNotifyClient(WINE_WAVEOUT* wwo, WORD wMsg, DWORD_PTR dwParam1,
                             DWORD_PTR dwParam2)
{
    TRACE("wMsg = %04X dwParm1 = %08lX dwParam2 = %08lX\n", wMsg, dwParam1, dwParam2);

    switch (wMsg) {
    case WOM_OPEN:
    case WOM_CLOSE:
    case WOM_DONE:
      if (wwo->wFlags != DCB_NULL &&
        !DriverCallback(wwo->waveDesc.dwCallback, wwo->wFlags,
          (HDRVR)wwo->waveDesc.hWave, wMsg, wwo->waveDesc.dwInstance,
          dwParam1, dwParam2))
      {
        WARN("can't notify client !\n");
        return MMSYSERR_ERROR;
      }
    break;
    default:
      FIXME("Unknown callback message %u\n", wMsg);
        return MMSYSERR_INVALPARAM;
    }
    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				wodHelper_BeginWaveHdr          [internal]
 *
 * Makes the specified lpWaveHdr the currently playing wave header.
 * If the specified wave header is a begin loop and we're not already in
 * a loop, setup the loop.
 */
static void wodHelper_BeginWaveHdr(WINE_WAVEOUT* wwo, LPWAVEHDR lpWaveHdr)
{
    EnterCriticalSection(&wwo->access_crst);

    wwo->lpPlayPtr = lpWaveHdr;

    if (!lpWaveHdr)
    {
       LeaveCriticalSection(&wwo->access_crst);
       return;
    }

    if (lpWaveHdr->dwFlags & WHDR_BEGINLOOP)
    {
      if (wwo->lpLoopPtr)
      {
        WARN("Already in a loop. Discarding loop on this header (%p)\n", lpWaveHdr);
        TRACE("Already in a loop. Discarding loop on this header (%p)\n", lpWaveHdr);
      } else
      {
        TRACE("Starting loop (%dx) with %p\n", lpWaveHdr->dwLoops, lpWaveHdr);
        wwo->lpLoopPtr = lpWaveHdr;
        /* Windows does not touch WAVEHDR.dwLoops,
         * so we need to make an internal copy */
        wwo->dwLoops = lpWaveHdr->dwLoops;
      }
    }
    wwo->dwPartialOffset = 0;

    LeaveCriticalSection(&wwo->access_crst);
}


/**************************************************************************
 * 				wodHelper_PlayPtrNext	        [internal]
 *
 * Advance the play pointer to the next waveheader, looping if required.
 */
static LPWAVEHDR wodHelper_PlayPtrNext(WINE_WAVEOUT* wwo)
{
  LPWAVEHDR lpWaveHdr;

  EnterCriticalSection(&wwo->access_crst);

  lpWaveHdr = wwo->lpPlayPtr;

  wwo->dwPartialOffset = 0;
  if ((lpWaveHdr->dwFlags & WHDR_ENDLOOP) && wwo->lpLoopPtr)
  {
    /* We're at the end of a loop, loop if required */
    if (--wwo->dwLoops > 0)
    {
      wwo->lpPlayPtr = wwo->lpLoopPtr;
    } else
    {
      /* Handle overlapping loops correctly */
      if (wwo->lpLoopPtr != lpWaveHdr && (lpWaveHdr->dwFlags & WHDR_BEGINLOOP)) {
        FIXME("Correctly handled case ? (ending loop buffer also starts a new loop)\n");
        /* shall we consider the END flag for the closing loop or for
         * the opening one or for both ???
         * code assumes for closing loop only
         */
      } else
      {
        lpWaveHdr = lpWaveHdr->lpNext;
      }
      wwo->lpLoopPtr = NULL;
      wodHelper_BeginWaveHdr(wwo, lpWaveHdr);
    }
  } else
  {
     /* We're not in a loop.  Advance to the next wave header */
    TRACE("not inside of a loop, advancing to next wave header\n");
    wodHelper_BeginWaveHdr(wwo, lpWaveHdr = lpWaveHdr->lpNext);
  }

  LeaveCriticalSection(&wwo->access_crst);

  return lpWaveHdr;
}

/* if force is TRUE then notify the client that all the headers were completed */
static DWORD wodHelper_NotifyCompletions(WINE_WAVEOUT* wwo, BOOL force)
{
  LPWAVEHDR		lpWaveHdr;
  DWORD retval;

  TRACE("called\n");

  EnterCriticalSection(&wwo->access_crst);

  /* Start from lpQueuePtr and keep notifying until:
   * - we hit an unwritten wavehdr
   * - we hit the beginning of a running loop
   * - we hit a wavehdr which hasn't finished playing
   */
  while ((lpWaveHdr = wwo->lpQueuePtr) &&
           (force || 
            (lpWaveHdr != wwo->lpPlayPtr &&
             lpWaveHdr != wwo->lpLoopPtr)))
  {
    wwo->lpQueuePtr = lpWaveHdr->lpNext;

    lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
    lpWaveHdr->dwFlags |= WHDR_DONE;
    TRACE("notifying client: lpWaveHdr=(%p) lpPlayPtr=(%p) dwFlags=(%d)\n",
	  lpWaveHdr, wwo->lpPlayPtr, lpWaveHdr->dwFlags);

    wodNotifyClient(wwo, WOM_DONE, (DWORD_PTR)lpWaveHdr, 0);
  }
  TRACE("Not notifying client: lpWaveHdr=(%p) lpPlayPtr=(%p) lpLoopPtr=(%p)\n",
	lpWaveHdr, wwo->lpPlayPtr, wwo->lpLoopPtr);
  retval = (lpWaveHdr && lpWaveHdr != wwo->lpPlayPtr && lpWaveHdr != 
              wwo->lpLoopPtr) ? 0 : INFINITE;

  LeaveCriticalSection(&wwo->access_crst);

  return retval;
}

/**************************************************************************
 * 				wodHelper_Reset			[internal]
 *
 * Resets current output stream.
 */
static  void  wodHelper_Reset(WINE_WAVEOUT* wwo, BOOL reset)
{
    EnterCriticalSection(&wwo->access_crst);
 
    /* updates current notify list */
    wodHelper_NotifyCompletions(wwo, FALSE);

    if (reset)
    {
        /* remove all wave headers and notify client that all headers were completed */
        wodHelper_NotifyCompletions(wwo, TRUE);

        wwo->lpPlayPtr = wwo->lpQueuePtr = wwo->lpLoopPtr = NULL;
        wwo->state = WINE_WS_STOPPED;
        wwo->dwPlayedTotal = wwo->dwWrittenTotal = wwo->bytesInJack = 0;

        wwo->dwPartialOffset = 0;        /* Clear partial wavehdr */
    } else
    {
        if (wwo->lpLoopPtr)
        {
            /* complicated case, not handled yet (could imply modifying the loop counter) */
            FIXME("Pausing while in loop isn't correctly handled yet, expect strange results\n");
            wwo->lpPlayPtr = wwo->lpLoopPtr;
            wwo->dwPartialOffset = 0;
            wwo->dwWrittenTotal = wwo->dwPlayedTotal; /* this is wrong !!! */
        } else
        {
            LPWAVEHDR   ptr;
            DWORD       sz = wwo->dwPartialOffset;

            /* reset all the data as if we had written only up to lpPlayedTotal bytes */
            /* compute the max size playable from lpQueuePtr */
            for (ptr = wwo->lpQueuePtr; ptr != wwo->lpPlayPtr; ptr = ptr->lpNext)
            {
                sz += ptr->dwBufferLength;
            }

            /* because the reset lpPlayPtr will be lpQueuePtr */
            if (wwo->dwWrittenTotal > wwo->dwPlayedTotal + sz) ERR("doh\n");
            wwo->dwPartialOffset = sz - (wwo->dwWrittenTotal - wwo->dwPlayedTotal);
            wwo->dwWrittenTotal = wwo->dwPlayedTotal;
            wwo->lpPlayPtr = wwo->lpQueuePtr;
        }

        wwo->state = WINE_WS_PAUSED;
    }
 
    LeaveCriticalSection(&wwo->access_crst);
}

/**************************************************************************
 * 			wodGetDevCaps				[internal]
 */
static DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPSW lpCaps, DWORD dwSize)
{
    TRACE("(%u, %p, %u);\n", wDevID, lpCaps, dwSize);
    
    if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
    
    if (wDevID >= MAX_WAVEOUTDRV)
    {
      TRACE("MAX_WAVOUTDRV reached !\n");
      return MMSYSERR_BADDEVICEID;
    }

    TRACE("dwSupport=(0x%x), dwFormats=(0x%x)\n", WOutDev[wDevID].caps.dwSupport, WOutDev[wDevID].caps.dwFormats);
    memcpy(lpCaps, &WOutDev[wDevID].caps, min(dwSize, sizeof(*lpCaps)));
    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				wodOpen				[internal]
 *
 * NOTE: doesn't it seem like there is a race condition if you try to open 
 * the same device twice?
 */
static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
{
    WINE_WAVEOUT*	wwo;
    DWORD retval;

    TRACE("(%u, %p, %08X);\n", wDevID, lpDesc, dwFlags);
    if (lpDesc == NULL)
    {
      WARN("Invalid Parameter !\n");
      return MMSYSERR_INVALPARAM;
    }
    if (wDevID >= MAX_WAVEOUTDRV) {
      TRACE("MAX_WAVOUTDRV reached !\n");
      return MMSYSERR_BADDEVICEID;
    }

#if JACK_CLOSE_HACK
    if(WOutDev[wDevID].client && WOutDev[wDevID].in_use)
#else
    if(WOutDev[wDevID].client)
#endif
    {
      TRACE("device %d already allocated\n", wDevID);
      return MMSYSERR_ALLOCATED;
    }

    /* Only the PCM format is supported so far...
     * Also we only support 16 bit mode.
     */
    if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM ||
      lpDesc->lpFormat->nChannels == 0 ||
      lpDesc->lpFormat->nSamplesPerSec == 0 ||
      lpDesc->lpFormat->wBitsPerSample != 16)
    {
      WARN("Bad format: tag=%04X nChannels=%d nSamplesPerSec=%d wBitsPerSample=%d !\n",
       lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
       lpDesc->lpFormat->nSamplesPerSec, lpDesc->lpFormat->wBitsPerSample);
      return WAVERR_BADFORMAT;
    }

    if (dwFlags & WAVE_FORMAT_QUERY)
    {
      TRACE("Query format: tag=%04X nChannels=%d nSamplesPerSec=%d !\n",
       lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
       lpDesc->lpFormat->nSamplesPerSec);
      return MMSYSERR_NOERROR;
    }

    wwo = &WOutDev[wDevID];
    wwo->wDevID = wDevID;

    /* Set things up before we call JACK_OpenWaveOutDevice because */
    /* we will start getting callbacks before JACK_OpenWaveOutDevice */
    /* even returns and we want to be initialized before then */
    wwo->state = WINE_WS_STOPPED; /* start in a stopped state */
    wwo->dwPlayedTotal = 0; /* zero out these totals */
    wwo->dwWrittenTotal = 0;
    wwo->bytesInJack = 0;
    wwo->tickCountMS = 0;

    /* Initialize volume to full level */
    wwo->volume_left = 100;
    wwo->volume_right = 100;

    InitializeCriticalSection(&wwo->access_crst); /* initialize the critical section */
    EnterCriticalSection(&wwo->access_crst);

    dwFlags &= ~WAVE_DIRECTSOUND;  /* direct sound not supported, ignore the flag */

    wwo->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);

    wwo->waveDesc = *lpDesc;
    memcpy(&wwo->format,   lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));

    /* open up jack ports for this device */
    if (!JACK_OpenWaveOutDevice(&WOutDev[wDevID]))
    {
      ERR("JACK_OpenWaveOutDevice(%d) failed\n", wDevID);
      LeaveCriticalSection(&wwo->access_crst);
      DeleteCriticalSection(&wwo->access_crst); /* delete the critical section so we can initialize it again from wodOpen() */
      return MMSYSERR_ERROR;		/* return unspecified error */
    }

    LeaveCriticalSection(&wwo->access_crst);

    /* display the current wave format */
    TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%u, nSamplesPerSec=%u, nChannels=%u nBlockAlign=%u!\n",
    wwo->format.wBitsPerSample, wwo->format.wf.nAvgBytesPerSec,
    wwo->format.wf.nSamplesPerSec, wwo->format.wf.nChannels,
    wwo->format.wf.nBlockAlign);

    /* make sure that we have the same sample rate in our audio stream */
    /* as we do in the jack server */
    if(wwo->format.wf.nSamplesPerSec != wwo->sample_rate)
    {
      TRACE("error: jack server sample rate is '%ld', wave sample rate is '%d'\n",
         wwo->sample_rate, wwo->format.wf.nSamplesPerSec);

#if JACK_CLOSE_HACK
      JACK_CloseWaveOutDevice(wwo, FALSE); /* close this device, don't force the client to close */
#else
      JACK_CloseWaveOutDevice(wwo); /* close this device */
#endif
      DeleteCriticalSection(&wwo->access_crst); /* delete the critical section so we can initialize it again from wodOpen() */
      return WAVERR_BADFORMAT;
    }

    /* check for an invalid number of bits per sample */
    if (wwo->format.wBitsPerSample == 0)
    {
      WARN("Resetting zeroed wBitsPerSample\n");
      wwo->format.wBitsPerSample = 8 *
      (wwo->format.wf.nAvgBytesPerSec /
       wwo->format.wf.nSamplesPerSec) /
       wwo->format.wf.nChannels;
    }

    EnterCriticalSection(&wwo->access_crst);
    retval = wodNotifyClient(wwo, WOM_OPEN, 0, 0);
    LeaveCriticalSection(&wwo->access_crst);

    return retval;
}

/**************************************************************************
 * 				wodClose			[internal]
 */
static DWORD wodClose(WORD wDevID)
{
    DWORD		ret = MMSYSERR_NOERROR;
    WINE_WAVEOUT*	wwo;

    TRACE("(%u);\n", wDevID);

    if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
    {
      WARN("bad device ID !\n");
      return MMSYSERR_BADDEVICEID;
    }
    
    wwo = &WOutDev[wDevID];
    if (wwo->lpQueuePtr)
    {
      WARN("buffers still playing !\n");
      ret = WAVERR_STILLPLAYING;
    } else
    {
      /* sanity check: this should not happen since the device must have been reset before */
      if (wwo->lpQueuePtr || wwo->lpPlayPtr) ERR("out of sync\n");

      wwo->state = WINE_WS_CLOSED; /* mark the device as closed */

#if JACK_CLOSE_HACK
      JACK_CloseWaveOutDevice(wwo, FALSE); /* close the jack device, DO NOT force the client to close */
#else
      JACK_CloseWaveOutDevice(wwo); /* close the jack device */
#endif
      DeleteCriticalSection(&wwo->access_crst); /* delete the critical section so we can initialize it again from wodOpen() */

      ret = wodNotifyClient(wwo, WOM_CLOSE, 0, 0);
    }

    return ret;
}


/**************************************************************************
 * 				wodWrite			[internal]
 * 
 */
static DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
{
    LPWAVEHDR*wh;
    WINE_WAVEOUT *wwo;

    TRACE("(%u, %p, %08X);\n", wDevID, lpWaveHdr, dwSize);
    
    /* first, do the sanity checks... */
    if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
    {
      WARN("bad dev ID !\n");
      return MMSYSERR_BADDEVICEID;
    }

    wwo = &WOutDev[wDevID];

    if (lpWaveHdr->lpData == NULL || !(lpWaveHdr->dwFlags & WHDR_PREPARED))
    {
      TRACE("unprepared\n");
      return WAVERR_UNPREPARED;
    }
    
    if (lpWaveHdr->dwFlags & WHDR_INQUEUE) 
    {
      TRACE("still playing\n");
      return WAVERR_STILLPLAYING;
    }

    lpWaveHdr->dwFlags &= ~WHDR_DONE;
    lpWaveHdr->dwFlags |= WHDR_INQUEUE;
    lpWaveHdr->lpNext = 0;

    EnterCriticalSection(&wwo->access_crst);

    /* insert buffer at the end of queue */
    for (wh = &(wwo->lpQueuePtr); *wh; wh = &((*wh)->lpNext));
    *wh = lpWaveHdr;

    if (!wwo->lpPlayPtr)
      wodHelper_BeginWaveHdr(wwo,lpWaveHdr);
    if (wwo->state == WINE_WS_STOPPED)
      wwo->state = WINE_WS_PLAYING;
    LeaveCriticalSection(&wwo->access_crst);

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 			wodPause				[internal]
 */
static DWORD wodPause(WORD wDevID)
{
  TRACE("(%u);!\n", wDevID);
    
  if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
  {
    WARN("bad device ID !\n");
    return MMSYSERR_BADDEVICEID;
  }
    
  TRACE("[3-PAUSING]\n");

  EnterCriticalSection(&(WOutDev[wDevID].access_crst));
  wodHelper_Reset(&WOutDev[wDevID], FALSE);
  LeaveCriticalSection(&(WOutDev[wDevID].access_crst));

  return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 			wodRestart				[internal]
 */
static DWORD wodRestart(WORD wDevID)
{
    TRACE("(%u);\n", wDevID);

    if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
    {
      WARN("bad device ID !\n");
      return MMSYSERR_BADDEVICEID;
    }

    if (WOutDev[wDevID].state == WINE_WS_PAUSED)
    {
      EnterCriticalSection(&(WOutDev[wDevID].access_crst));
      WOutDev[wDevID].state = WINE_WS_PLAYING;
      LeaveCriticalSection(&(WOutDev[wDevID].access_crst));
    }
    
    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 			wodReset				[internal]
 */
static DWORD wodReset(WORD wDevID)
{
    TRACE("(%u);\n", wDevID);
    
    if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
    {
      WARN("bad device ID !\n");
      return MMSYSERR_BADDEVICEID;
    }

    EnterCriticalSection(&(WOutDev[wDevID].access_crst));
    wodHelper_Reset(&WOutDev[wDevID], TRUE);
    LeaveCriticalSection(&(WOutDev[wDevID].access_crst));

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				wodGetPosition			[internal]
 */
static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
{
    DWORD		val;
    WINE_WAVEOUT*	wwo;
    DWORD elapsedMS;

    TRACE("(%u, %p, %u);\n", wDevID, lpTime, uSize);

    if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
    {
      WARN("bad device ID !\n");
      return MMSYSERR_BADDEVICEID;
    }

    /* if null pointer to time structure return error */
    if (lpTime == NULL)	return MMSYSERR_INVALPARAM;

    wwo = &WOutDev[wDevID];

    EnterCriticalSection(&(WOutDev[wDevID].access_crst));
    val = wwo->dwPlayedTotal;
    elapsedMS = GetTickCount() - wwo->tickCountMS;
    LeaveCriticalSection(&(WOutDev[wDevID].access_crst));

    /* account for the bytes played since the last JACK_Callback() */
    val+=((elapsedMS * wwo->format.wf.nAvgBytesPerSec) / 1000);

    return bytes_to_mmtime(lpTime, val, &wwo->format);
}

/**************************************************************************
 * 				wodBreakLoop			[internal]
 */
static DWORD wodBreakLoop(WORD wDevID)
{
  TRACE("(%u);\n", wDevID);

  if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
  {
    WARN("bad device ID !\n");
    return MMSYSERR_BADDEVICEID;
  }

  EnterCriticalSection(&(WOutDev[wDevID].access_crst));

  if (WOutDev[wDevID].state == WINE_WS_PLAYING && WOutDev[wDevID].lpLoopPtr != NULL)
  {
    /* ensure exit at end of current loop */
    WOutDev[wDevID].dwLoops = 1;
  }

  LeaveCriticalSection(&(WOutDev[wDevID].access_crst));

  return MMSYSERR_NOERROR;
}
    
/**************************************************************************
 * 				wodGetVolume			[internal]
 */
static DWORD wodGetVolume(WORD wDevID, LPDWORD lpdwVol)
{
  DWORD left, right;
    
  left = WOutDev[wDevID].volume_left;
  right = WOutDev[wDevID].volume_right;
        
  TRACE("(%u, %p);\n", wDevID, lpdwVol);
 
  *lpdwVol = ((left * 0xFFFFl) / 100) + (((right * 0xFFFFl) / 100) <<
              16);
    
  return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				wodSetVolume			[internal]
 */
static DWORD wodSetVolume(WORD wDevID, DWORD dwParam)
{
  DWORD left, right;
 
  left  = (LOWORD(dwParam) * 100) / 0xFFFFl;
  right = (HIWORD(dwParam) * 100) / 0xFFFFl;
 
  TRACE("(%u, %08X);\n", wDevID, dwParam);

  EnterCriticalSection(&(WOutDev[wDevID].access_crst));

  WOutDev[wDevID].volume_left = left;
  WOutDev[wDevID].volume_right = right;

  LeaveCriticalSection(&(WOutDev[wDevID].access_crst));

  return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				wodGetNumDevs			[internal]
 */
static DWORD wodGetNumDevs(void)
{
  return MAX_WAVEOUTDRV;
}

/**************************************************************************
 *                              wodDevInterfaceSize             [internal]
 */
static DWORD wodDevInterfaceSize(UINT wDevID, LPDWORD dwParam1)
{
    TRACE("(%u, %p)\n", wDevID, dwParam1);
                                                                                                       
    *dwParam1 = MultiByteToWideChar(CP_ACP, 0, WOutDev[wDevID].interface_name, -1,
                                    NULL, 0 ) * sizeof(WCHAR);
    return MMSYSERR_NOERROR;
}

/**************************************************************************
 *                              wodDevInterface                 [internal]
 */
static DWORD wodDevInterface(UINT wDevID, PWCHAR dwParam1, DWORD dwParam2)
{
    if (dwParam2 >= MultiByteToWideChar(CP_ACP, 0, WOutDev[wDevID].interface_name, -1,
                                        NULL, 0 ) * sizeof(WCHAR))
    {
        MultiByteToWideChar(CP_ACP, 0, WOutDev[wDevID].interface_name, -1,
                            dwParam1, dwParam2 / sizeof(WCHAR));
        return MMSYSERR_NOERROR;
    }
    return MMSYSERR_INVALPARAM;
}

/**************************************************************************
 * 				wodMessage (WINEJACK.7)
 */
DWORD WINAPI JACK_wodMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
                             DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
  TRACE("(%u, %04X, %08X, %08lX, %08lX);\n", wDevID, wMsg, dwUser, dwParam1, dwParam2);

  switch (wMsg) {
  case DRVM_INIT:
  case DRVM_EXIT:
  case DRVM_ENABLE:
  case DRVM_DISABLE:
    /* FIXME: Pretend this is supported */
    return 0;
  case WODM_OPEN:             return wodOpen(wDevID, (LPWAVEOPENDESC)dwParam1,	dwParam2);
  case WODM_CLOSE:            return wodClose(wDevID);
  case WODM_WRITE:            return wodWrite(wDevID, (LPWAVEHDR)dwParam1,		dwParam2);
  case WODM_PAUSE:            return wodPause(wDevID);
  case WODM_GETPOS:           return wodGetPosition(wDevID, (LPMMTIME)dwParam1, 		dwParam2);
  case WODM_BREAKLOOP:        return wodBreakLoop(wDevID);
  case WODM_PREPARE:          return MMSYSERR_NOTSUPPORTED;
  case WODM_UNPREPARE:        return MMSYSERR_NOTSUPPORTED;
  case WODM_GETDEVCAPS:       return wodGetDevCaps(wDevID, (LPWAVEOUTCAPSW)dwParam1,	dwParam2);
  case WODM_GETNUMDEVS:       return wodGetNumDevs();
  case WODM_GETPITCH:         return MMSYSERR_NOTSUPPORTED;
  case WODM_SETPITCH:         return MMSYSERR_NOTSUPPORTED;
  case WODM_GETPLAYBACKRATE:	return MMSYSERR_NOTSUPPORTED;
  case WODM_SETPLAYBACKRATE:	return MMSYSERR_NOTSUPPORTED;
  case WODM_GETVOLUME:        return wodGetVolume(wDevID, (LPDWORD)dwParam1);
  case WODM_SETVOLUME:        return wodSetVolume(wDevID, dwParam1);
  case WODM_RESTART:          return wodRestart(wDevID);
  case WODM_RESET:            return wodReset(wDevID);

  case DRV_QUERYDEVICEINTERFACESIZE: return wodDevInterfaceSize       (wDevID, (LPDWORD)dwParam1);
  case DRV_QUERYDEVICEINTERFACE:     return wodDevInterface           (wDevID, (PWCHAR)dwParam1, dwParam2);
  case DRV_QUERYDSOUNDIFACE:	return wodDsCreate(wDevID, (PIDSDRIVER*)dwParam1);
  case DRV_QUERYDSOUNDDESC:	return wodDsDesc(wDevID, (PDSDRIVERDESC)dwParam1);
  default:
    FIXME("unknown message %d!\n", wMsg);
    }
    return MMSYSERR_NOTSUPPORTED;
}

/*======================================================================*
 *                  Low level DSOUND implementation			*
 *======================================================================*/

typedef struct IDsDriverImpl IDsDriverImpl;
typedef struct IDsDriverBufferImpl IDsDriverBufferImpl;

struct IDsDriverImpl
{
    /* IUnknown fields */
    const IDsDriverVtbl *lpVtbl;
    DWORD		ref;
    /* IDsDriverImpl fields */
    UINT		wDevID;
    IDsDriverBufferImpl*primary;
};

struct IDsDriverBufferImpl
{
    /* IUnknown fields */
    const IDsDriverBufferVtbl *lpVtbl;
    DWORD ref;
    /* IDsDriverBufferImpl fields */
    IDsDriverImpl* drv;
    DWORD buflen;
};

static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv)
{
    /* we can't perform memory mapping as we don't have a file stream 
      interface with jack like we do with oss */
    MESSAGE("This sound card's driver does not support direct access\n");
    MESSAGE("The (slower) DirectSound HEL mode will be used instead.\n");
    return MMSYSERR_NOTSUPPORTED;
}

static DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc)
{
    memset(desc, 0, sizeof(*desc));
    strcpy(desc->szDesc, "Wine jack DirectSound Driver");
    strcpy(desc->szDrvname, "winejack.drv");
    return MMSYSERR_NOERROR;
}

/*======================================================================*
 *                  Low level WAVE IN implementation			*
 *======================================================================*/

/**************************************************************************
 * 			widNotifyClient			[internal]
 */
static DWORD widNotifyClient(WINE_WAVEIN* wwi, WORD wMsg, DWORD_PTR dwParam1,
                             DWORD_PTR dwParam2)
{
    TRACE("wMsg = %04X dwParm1 = %08lX dwParam2 = %08lX\n", wMsg, dwParam1, dwParam2);

    switch (wMsg) {
    case WIM_OPEN:
    case WIM_CLOSE:
    case WIM_DATA:
      if (wwi->wFlags != DCB_NULL &&
        !DriverCallback(wwi->waveDesc.dwCallback, wwi->wFlags,
          (HDRVR)wwi->waveDesc.hWave, wMsg, wwi->waveDesc.dwInstance,
          dwParam1, dwParam2))
      {
        WARN("can't notify client !\n");
        return MMSYSERR_ERROR;
      }
    break;
    default:
      FIXME("Unknown callback message %u\n", wMsg);
        return MMSYSERR_INVALPARAM;
    }
    return MMSYSERR_NOERROR;
}

/******************************************************************
 *    JACK_callback_wwi
 */
/* everytime the jack server wants something from us it calls this 
   function */
static int JACK_callback_wwi (nframes_t nframes, void *arg)
{
    sample_t* in_l;
    sample_t* in_r = 0;
    WINE_WAVEIN* wwi = arg;

    TRACE("wDevID: %u, nframes %u\n", wwi->wDevID, nframes);
    
    if(!wwi->client)
	ERR("client is closed, this is weird...\n");

    in_l = fp_jack_port_get_buffer(wwi->in_port_l, nframes);

    if (wwi->in_port_r)
      in_r = fp_jack_port_get_buffer(wwi->in_port_r, nframes);

    EnterCriticalSection(&wwi->access_crst);
    
    if((wwi->lpQueuePtr != NULL) && (wwi->state == WINE_WS_PLAYING))
    {
	LPWAVEHDR lpWaveHdr = wwi->lpQueuePtr;
	nframes_t jackFramesLeft = nframes;

#if JACK_CLOSE_HACK
	if(wwi->in_use == FALSE)
	{
            /* do nothing if nothing is being recorded */
            LeaveCriticalSection(&wwi->access_crst);
	    return 0;
	}
#endif
	
	TRACE("wwi.state == WINE_WS_PLAYING\n");
	
	while (lpWaveHdr && jackFramesLeft)
	{
	    DWORD waveHdrFramesLeft = (lpWaveHdr->dwBufferLength - lpWaveHdr->dwBytesRecorded) / (sizeof(short) * wwi->format.wf.nChannels); 
	    DWORD numFrames = min (jackFramesLeft, waveHdrFramesLeft);
	    
            TRACE ("dwBufferLength=(%u) dwBytesRecorded=(%d)\n",   lpWaveHdr->dwBufferLength, lpWaveHdr->dwBytesRecorded);
            TRACE ("jackFramesLeft=(%u) waveHdrFramesLeft=(%u)\n", jackFramesLeft, waveHdrFramesLeft);

	    if (!in_r) {
	      /* mono */
	      sample_move_s16_d16((short *)((char *)lpWaveHdr->lpData + lpWaveHdr->dwBytesRecorded), in_l+(nframes-jackFramesLeft), numFrames, 1);
	    } else {
	      /* stereo */
	      sample_move_s16_d16((short *)((char *)lpWaveHdr->lpData + lpWaveHdr->dwBytesRecorded), 
				  in_l+(nframes-jackFramesLeft), numFrames, 2);
	      sample_move_s16_d16((short *)((char *)lpWaveHdr->lpData + lpWaveHdr->dwBytesRecorded + sizeof(short)), 
				  in_r+(nframes-jackFramesLeft), numFrames, 2);
	    }
	    
	    lpWaveHdr->dwBytesRecorded += (numFrames * sizeof(short) * wwi->format.wf.nChannels );
	    jackFramesLeft -= numFrames;

	    if (lpWaveHdr->dwBytesRecorded >= lpWaveHdr->dwBufferLength)
	    {
		/* must copy the value of next waveHdr, because we have no idea of what
		 * will be done with the content of lpWaveHdr in callback
		 */
		LPWAVEHDR	lpNext = lpWaveHdr->lpNext;
				
		lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
		lpWaveHdr->dwFlags |=  WHDR_DONE;

		TRACE("WaveHdr full. dwBytesRecorded=(%u) dwFlags=(0x%x)\n",lpWaveHdr->dwBytesRecorded,lpWaveHdr->dwFlags);

		widNotifyClient(wwi, WIM_DATA, (DWORD_PTR)lpWaveHdr, 0);

		lpWaveHdr = wwi->lpQueuePtr = lpNext;
	    }
	}
	TRACE ("jackFramesLeft=(%u) lpWaveHdr=(%p)\n", jackFramesLeft, lpWaveHdr);
	if (jackFramesLeft > 0) { WARN("Record buffer ran out of WaveHdrs\n"); }
    }
    
    LeaveCriticalSection(&wwi->access_crst);

    return 0;
}

/******************************************************************
 *		JACK_OpenWaveInDevice
 */
static int JACK_OpenWaveInDevice(WINE_WAVEIN* wwi, WORD nChannels)
{
  const char** ports;
  int i;
  char client_name[64];
  jack_port_t* in_port_l;
  jack_port_t* in_port_r = 0;
  jack_client_t* client;
  int failed = 0;

  TRACE("creating jack client and setting up callbacks\n");

  if ((nChannels == 0) || (nChannels > 2)) {
    ERR ("nChannels = (%d), but we only support mono or stereo.\n", nChannels);
    return 0;
  }

#if JACK_CLOSE_HACK
  /* see if this device is already open */
        if(wwi->client)
        {
          /* if this device is already in use then it is bad for us to be in here */
          if(wwi->in_use)
            return 0;

          TRACE("using existing client\n");
          wwi->in_use = TRUE;
          return 1;
        }
#endif

        /* zero out the buffer pointer and the size of the buffer */
        wwi->sound_buffer = 0;
        wwi->buffer_size = 0;

        /* try to become a client of the JACK server */
        snprintf(client_name, sizeof(client_name), "wine_jack_in_%d", wwi->wDevID);
        TRACE("client name '%s'\n", client_name);
        if ((client = fp_jack_client_new (client_name)) == 0)
        {
                /* jack has problems with shutting down clients, so lets */
                /* wait a short while and try once more before we give up */
                Sleep(250);
                if ((client = fp_jack_client_new (client_name)) == 0)
                {
                  ERR("jack server not running?\n");
                  return 0;
                }
        }
        wwi->client = client;
                
        /* tell the JACK server to call `JACK_wwi_callback()' whenever
           there is work to be done. */
        fp_jack_set_process_callback (client, JACK_callback_wwi, wwi);
        
        /* tell the JACK server to call `JACK_bufsize_wwi()' whenever   
           the maximum number of frames that will be passed
           to `JACK_Callback()' changes */
        fp_jack_set_buffer_size_callback (client, JACK_bufsize_wwi, wwi);
          
        /* tell the JACK server to call `srate()' whenever
           the sample rate of the system changes. */
        fp_jack_set_sample_rate_callback (client, JACK_srate, wwi);

        /* tell the JACK server to call `jack_shutdown()' if
           it ever shuts down, either entirely, or if it
           just decides to stop calling us. */
        fp_jack_on_shutdown (client, JACK_shutdown_wwi, wwi);
        
        /* display the current sample rate. once the client is activated
           (see below), you should rely on your own sample rate
           callback (see above) for this value. */
        wwi->sample_rate = fp_jack_get_sample_rate(client);
        TRACE("engine sample rate: %lu\n", wwi->sample_rate);
          
        /* create the left and right channel output ports */
        /* jack's ports are all mono so for stereo you need two */
        in_port_l = fp_jack_port_register (client, "in_l",
                         JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
        wwi->in_port_l = in_port_l;
	TRACE("Created port. (%p)\n", in_port_l);

	if (nChannels == 2)
	{
	  in_port_r = fp_jack_port_register (client, "in_r",
			   JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); 
	  TRACE("Created port. (%p)\n", in_port_r);
	} 
	wwi->in_port_r = in_port_r;

#if JACK_CLOSE_HACK
        wwi->in_use = TRUE; /* mark this device as in use since it now is ;-) */
#endif

	TRACE("activating client.\n");
        /* tell the JACK server that we are ready to roll */
        if (fp_jack_activate (client))
        {
          ERR( "cannot activate client\n");
          return 0;
        }
	TRACE("activated client.\n");
        /* figure out what the ports that we want to output on are */
        /* NOTE: we do this instead of using stuff like "alsa_pcm:playback_X" because */
        /*   this way works if names are changed */
        ports = fp_jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput);

        /* display a trace of the output ports we found */
        for(i = 0; ports[i]; i++)
        {
          TRACE("ports[%d] = '%s'\n", i, ports[i]);
        }

        if(!ports)
        {
          ERR("jack_get_ports() failed to find 'JackPortIsPhysical|JackPortIsOutput'\n");
        }

        /* connect the ports. Note: you can't do this before
           the client is activated (this may change in the future).
        */ 
        /* we want to connect to two ports so we have stereo input ;-) */

	if(fp_jack_connect(client, ports[0], fp_jack_port_name(in_port_l)))
	{
	  ERR ("cannot connect to input port %d('%s')\n", 0, ports[0]);
	  failed = 1;
	}
	TRACE("Connected (%s)<->(%s)\n",ports[0],fp_jack_port_name(in_port_l));

	if ((nChannels == 2) && in_port_r) {
	  if(fp_jack_connect(client, ports[1], fp_jack_port_name(in_port_r)))
	  {
	    ERR ("cannot connect to input port %d('%s')\n", 1, ports[1]);
	    failed = 1;
	  }
	  TRACE("Connected (%s)<->(%s)\n",ports[1],fp_jack_port_name(in_port_r));
	}
        free(ports); /* free the returned array of ports */

        /* if something failed we need to shut the client down and return 0 */
        if(failed)
        {
#if JACK_CLOSE_HACK
          JACK_CloseWaveInDevice(wwi, TRUE);
#else
          JACK_CloseWaveInDevice(wwi);
#endif
          return 0;
        }

	TRACE("return success.\n");
        return 1; /* return success */
}

/**************************************************************************
 * 			widGetDevCaps				[internal]
 */
static DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPSW lpCaps, DWORD dwSize)
{
    TRACE("(%u, %p, %u);\n", wDevID, lpCaps, dwSize);

    if (lpCaps == NULL) return MMSYSERR_NOTENABLED;

    if (wDevID >= MAX_WAVEINDRV) {
	TRACE("MAX_WAVEINDRV reached !\n");
	return MMSYSERR_BADDEVICEID;
    }

    memcpy(lpCaps, &WInDev[wDevID].caps, min(dwSize, sizeof(*lpCaps)));
    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				widOpen				[internal]
 */
static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
{
    WINE_WAVEIN*	wwi;
    DWORD retval;

    TRACE("(%u, %p, %08X);\n", wDevID, lpDesc, dwFlags);
    if (lpDesc == NULL)
    {
	WARN("Invalid Parameter !\n");
	return MMSYSERR_INVALPARAM;
    }
    if (wDevID >= MAX_WAVEINDRV) {
	TRACE ("MAX_WAVEINDRV reached !\n");
	return MMSYSERR_BADDEVICEID;
    }

#if JACK_CLOSE_HACK
    if(WInDev[wDevID].client && WOutDev[wDevID].in_use)
#else
    if(WInDev[wDevID].client)
#endif
    {
      TRACE("device %d already allocated\n", wDevID);
      return MMSYSERR_ALLOCATED;
    }

    /* Only the PCM format is supported so far...
     * Also we only support 16 bit mode.
     */
    if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM ||
      lpDesc->lpFormat->nChannels == 0 ||
      lpDesc->lpFormat->nSamplesPerSec == 0 ||
      lpDesc->lpFormat->wBitsPerSample!=16)
    {
      WARN("Bad format: tag=%04X nChannels=%d nSamplesPerSec=%d wBitsPerSample=%d !\n",
       lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
       lpDesc->lpFormat->nSamplesPerSec, lpDesc->lpFormat->wBitsPerSample);
      return WAVERR_BADFORMAT;
    }

    if (dwFlags & WAVE_FORMAT_QUERY)
    {
      TRACE("Query format: tag=%04X nChannels=%d nSamplesPerSec=%d !\n",
       lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
       lpDesc->lpFormat->nSamplesPerSec);
      return MMSYSERR_NOERROR;
    }

    wwi = &WInDev[wDevID];
    wwi->wDevID = wDevID;

    /* Set things up before we call JACK_OpenWaveOutDevice because */
    /* we will start getting callbacks before JACK_OpenWaveOutDevice */
    /* even returns and we want to be initialized before then */
    wwi->state = WINE_WS_STOPPED; /* start in a stopped state */

    InitializeCriticalSection(&wwi->access_crst); /* initialize the critical section */
    EnterCriticalSection(&wwi->access_crst);

    /* open up jack ports for this device */
    if (!JACK_OpenWaveInDevice(&WInDev[wDevID], lpDesc->lpFormat->nChannels))
    {
      ERR("JACK_OpenWaveInDevice(%d) failed\n", wDevID);
      LeaveCriticalSection(&wwi->access_crst);
      DeleteCriticalSection(&wwi->access_crst);
      return MMSYSERR_ERROR;		/* return unspecified error */
    }

    dwFlags &= ~WAVE_DIRECTSOUND;  /* direct sound not supported, ignore the flag */

    wwi->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);

    wwi->waveDesc = *lpDesc;
    memcpy(&wwi->format,   lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));

    LeaveCriticalSection(&wwi->access_crst);

    /* display the current wave format */
    TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%u, nSamplesPerSec=%u, nChannels=%u nBlockAlign=%u!\n",
    wwi->format.wBitsPerSample, wwi->format.wf.nAvgBytesPerSec,
    wwi->format.wf.nSamplesPerSec, wwi->format.wf.nChannels,
    wwi->format.wf.nBlockAlign);

    /* make sure that we have the same sample rate in our audio stream */
    /* as we do in the jack server */
    if(wwi->format.wf.nSamplesPerSec != wwi->sample_rate)
    {
      TRACE("error: jack server sample rate is '%ld', wave sample rate is '%d'\n",
         wwi->sample_rate, wwi->format.wf.nSamplesPerSec);

#if JACK_CLOSE_HACK
      JACK_CloseWaveInDevice(wwi, FALSE); /* close this device, don't force the client to close */
#else
      JACK_CloseWaveInDevice(wwi); /* close this device */
#endif
      DeleteCriticalSection(&wwi->access_crst);
      return WAVERR_BADFORMAT;
    }

    /* check for an invalid number of bits per sample */
    if (wwi->format.wBitsPerSample == 0)
    {
      WARN("Resetting zeroed wBitsPerSample\n");
      wwi->format.wBitsPerSample = 8 *
      (wwi->format.wf.nAvgBytesPerSec /
       wwi->format.wf.nSamplesPerSec) /
       wwi->format.wf.nChannels;
    }

    TRACE("notify client.\n");
    EnterCriticalSection(&wwi->access_crst);
    retval = widNotifyClient(wwi, WIM_OPEN, 0, 0);
    LeaveCriticalSection(&wwi->access_crst);

    return retval;
}
/**************************************************************************
 * 				widClose			[internal]
 */
static DWORD widClose(WORD wDevID)
{
    DWORD		ret = MMSYSERR_NOERROR;
    WINE_WAVEIN*	wwi;

    TRACE("(%u);\n", wDevID);

    if (wDevID >= MAX_WAVEINDRV || !WInDev[wDevID].client)
    {
      WARN("bad device ID !\n");
      return MMSYSERR_BADDEVICEID;
    }
    
    wwi = &WInDev[wDevID];
    if (wwi->lpQueuePtr)
    {
      WARN("buffers still playing !\n");
      ret = WAVERR_STILLPLAYING;
    } else
    {
	/* sanity check: this should not happen since the device must have been reset before */
	if (wwi->lpQueuePtr) ERR("out of sync\n");
	
	wwi->state = WINE_WS_CLOSED; /* mark the device as closed */
	
#if JACK_CLOSE_HACK
	JACK_CloseWaveInDevice(wwi, FALSE); /* close the jack device, DO NOT force the client to close */
#else
	JACK_CloseWaveInDevice(wwi); /* close the jack device */
#endif
	DeleteCriticalSection(&wwi->access_crst); /* delete the critical section so we can initialize it again from wodOpen() */

	ret = widNotifyClient(wwi, WIM_CLOSE, 0, 0);
    }

    return ret;
}

/**************************************************************************
 * 				widAddBuffer		[internal]
 */
static DWORD widAddBuffer(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
{
    WINE_WAVEIN* wwi = &WInDev[wDevID];

    TRACE("(%u, %p, %08X);\n", wDevID, lpWaveHdr, dwSize);

    if (wDevID >= MAX_WAVEINDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
				WARN("can't do it !\n");
				return MMSYSERR_INVALHANDLE;
    }
    if (!(lpWaveHdr->dwFlags & WHDR_PREPARED)) {
				TRACE("never been prepared !\n");
				return WAVERR_UNPREPARED;
    }
    if (lpWaveHdr->dwFlags & WHDR_INQUEUE) {
				TRACE("header already in use !\n");
				return WAVERR_STILLPLAYING;
    }

    lpWaveHdr->dwFlags |= WHDR_INQUEUE;
    lpWaveHdr->dwFlags &= ~WHDR_DONE;
    lpWaveHdr->dwBytesRecorded = 0;
    lpWaveHdr->lpNext = NULL;

    EnterCriticalSection(&wwi->access_crst);
    /* insert buffer at end of queue */
    {
	LPWAVEHDR* wh;
	for (wh = &(wwi->lpQueuePtr); *wh; wh = &((*wh)->lpNext));
	*wh=lpWaveHdr;
    }
    LeaveCriticalSection(&wwi->access_crst);

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 			widStart				[internal]
 */
static DWORD widStart(WORD wDevID)
{
    TRACE("(%u);\n", wDevID);
    if (wDevID >= MAX_WAVEINDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
	WARN("can't start recording !\n");
	return MMSYSERR_INVALHANDLE;
    }

    WInDev[wDevID].state = WINE_WS_PLAYING;
    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 			widStop					[internal]
 */
static DWORD widStop(WORD wDevID)
{
    WINE_WAVEIN* wwi = &WInDev[wDevID];

    TRACE("(%u);\n", wDevID);
    if (wDevID >= MAX_WAVEINDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
	WARN("can't stop !\n");
	return MMSYSERR_INVALHANDLE;
    }
    
    if (wwi->state != WINE_WS_STOPPED)
    {
	WAVEHDR*		lpWaveHdr;
	/* do something here to stop recording ??? */
	
	/* return current buffer to app */
	lpWaveHdr = wwi->lpQueuePtr;
	if (lpWaveHdr)
	{
	    LPWAVEHDR	lpNext = lpWaveHdr->lpNext;
	    TRACE("stop %p %p\n", lpWaveHdr, lpWaveHdr->lpNext);
	    lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
	    lpWaveHdr->dwFlags |= WHDR_DONE;
            widNotifyClient(wwi, WIM_DATA, (DWORD_PTR)lpWaveHdr, 0);
	    wwi->lpQueuePtr = lpNext;
	}
    }
    wwi->state = WINE_WS_STOPPED;

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 			widReset				[internal]
 */
static DWORD widReset(WORD wDevID)
{
    WINE_WAVEIN* wwi = &WInDev[wDevID];
    WAVEHDR*		lpWaveHdr;

    TRACE("(%u);\n", wDevID);
    if (wDevID >= MAX_WAVEINDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
	WARN("can't reset !\n");
	return MMSYSERR_INVALHANDLE;
    }

    wwi->state = WINE_WS_STOPPED;

    /* return all buffers to the app */
    for (lpWaveHdr = wwi->lpQueuePtr; lpWaveHdr; lpWaveHdr = lpWaveHdr->lpNext) {
	TRACE("reset %p %p\n", lpWaveHdr, lpWaveHdr->lpNext);
	lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
	lpWaveHdr->dwFlags |= WHDR_DONE;

	widNotifyClient(wwi, WIM_DATA, (DWORD_PTR)lpWaveHdr, 0);
    }
    wwi->lpQueuePtr = NULL;

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				widGetNumDevs			[internal]
 */
static DWORD widGetNumDevs(void)
{
  return MAX_WAVEINDRV;
}

/**************************************************************************
 *                              widDevInterfaceSize             [internal]
 */
static DWORD widDevInterfaceSize(UINT wDevID, LPDWORD dwParam1)
{
    TRACE("(%u, %p)\n", wDevID, dwParam1);
                                                                                                       
                                                                                                       
    *dwParam1 = MultiByteToWideChar(CP_ACP, 0, WInDev[wDevID].interface_name, -1,
                                    NULL, 0 ) * sizeof(WCHAR);
    return MMSYSERR_NOERROR;
}

/**************************************************************************
 *                              widDevInterface                 [internal]
 */
static DWORD widDevInterface(UINT wDevID, PWCHAR dwParam1, DWORD dwParam2)
{
    if (dwParam2 >= MultiByteToWideChar(CP_ACP, 0, WInDev[wDevID].interface_name, -1,
                                        NULL, 0 ) * sizeof(WCHAR))
    {
        MultiByteToWideChar(CP_ACP, 0, WInDev[wDevID].interface_name, -1,
                            dwParam1, dwParam2 / sizeof(WCHAR));
        return MMSYSERR_NOERROR;
    }
    return MMSYSERR_INVALPARAM;
}

/**************************************************************************
 * 				widMessage (WINEJACK.6)
 */
DWORD WINAPI JACK_widMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
                             DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
  TRACE("(%u, %04X, %08X, %08lX, %08lX);\n", wDevID, wMsg, dwUser, dwParam1, dwParam2);

    switch (wMsg) {
    case DRVM_INIT:
    case DRVM_EXIT:
    case DRVM_ENABLE:
    case DRVM_DISABLE:
	/* FIXME: Pretend this is supported */
	return 0;
    case WIDM_OPEN:	 	return widOpen		(wDevID, (LPWAVEOPENDESC)dwParam1,	dwParam2);
    case WIDM_CLOSE:		return widClose		(wDevID);
    case WIDM_ADDBUFFER:	return widAddBuffer	(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
    case WIDM_PREPARE:		return MMSYSERR_NOTSUPPORTED;
    case WIDM_UNPREPARE:	return MMSYSERR_NOTSUPPORTED;
    case WIDM_GETDEVCAPS:	return widGetDevCaps	(wDevID, (LPWAVEINCAPSW)dwParam1,	dwParam2);
    case WIDM_GETNUMDEVS:	return widGetNumDevs();
    case WIDM_RESET:		return widReset		(wDevID);
    case WIDM_START:		return widStart		(wDevID);
    case WIDM_STOP:		return widStop		(wDevID);
    case DRV_QUERYDEVICEINTERFACESIZE: return widDevInterfaceSize       (wDevID, (LPDWORD)dwParam1);
    case DRV_QUERYDEVICEINTERFACE:     return widDevInterface           (wDevID, (PWCHAR)dwParam1, dwParam2);
    default:
	FIXME("unknown message %d!\n", wMsg);
    }

  return MMSYSERR_NOTSUPPORTED;
}

#else /* !SONAME_LIBJACK */

/**************************************************************************
 * 				widMessage (WINEJACK.6)
 */
DWORD WINAPI JACK_widMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
                             DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
  FIXME("(%u, %04X, %08X, %08lX, %08lX):jack support not compiled into wine\n",
        wDevID, wMsg, dwUser, dwParam1, dwParam2);
  return MMSYSERR_NOTENABLED;
}

/**************************************************************************
 * 				wodMessage (WINEJACK.7)
 */
DWORD WINAPI JACK_wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
                             DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
  FIXME("(%u, %04X, %08X, %08lX, %08lX):jack support not compiled into wine\n",
        wDevID, wMsg, dwUser, dwParam1, dwParam2);
  return MMSYSERR_NOTENABLED;
}

#endif /* SONAME_LIBJACK */
