[PATCH v2 1/5] winealsa: Move midi_init to unixlib.

Andrew Eikum aeikum at codeweavers.com
Wed Mar 16 09:02:05 CDT 2022


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>

On Tue, Mar 15, 2022 at 04:18:59PM +0000, Huw Davies wrote:
> Signed-off-by: Huw Davies <huw at codeweavers.com>
> ---
>  dlls/winealsa.drv/alsa.c     |   1 +
>  dlls/winealsa.drv/alsamidi.c | 265 +++++++++++++++++++++++++++++++++++
>  dlls/winealsa.drv/midi.c     | 250 ++-------------------------------
>  dlls/winealsa.drv/unixlib.h  |  34 +++++
>  4 files changed, 314 insertions(+), 236 deletions(-)
> 
> diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c
> index cdc3d81d8cc..76e4b98caaf 100644
> --- a/dlls/winealsa.drv/alsa.c
> +++ b/dlls/winealsa.drv/alsa.c
> @@ -2444,6 +2444,7 @@ unixlib_entry_t __wine_unix_call_funcs[] =
>      set_event_handle,
>      is_started,
>      get_prop_value,
> +    midi_init,
>  
>      midi_seq_lock, /* temporary */
>  };
> diff --git a/dlls/winealsa.drv/alsamidi.c b/dlls/winealsa.drv/alsamidi.c
> index ab4de4f7f9e..86e092bd977 100644
> --- a/dlls/winealsa.drv/alsamidi.c
> +++ b/dlls/winealsa.drv/alsamidi.c
> @@ -31,6 +31,7 @@
>  #include <stdarg.h>
>  #include <stdio.h>
>  #include <pthread.h>
> +#include <alsa/asoundlib.h>
>  
>  #include "ntstatus.h"
>  #define WIN32_NO_STATUS
> @@ -38,13 +39,23 @@
>  #include "winbase.h"
>  #include "winternl.h"
>  #include "mmdeviceapi.h"
> +#include "mmddk.h"
>  
> +#include "wine/debug.h"
>  #include "wine/unixlib.h"
>  
>  #include "unixlib.h"
>  
> +WINE_DEFAULT_DEBUG_CHANNEL(midi);
> +
>  static pthread_mutex_t seq_mutex = PTHREAD_MUTEX_INITIALIZER;
>  
> +static unsigned int num_dests, num_srcs;
> +static struct midi_dest dests[MAX_MIDIOUTDRV];
> +static struct midi_src srcs[MAX_MIDIINDRV];
> +static snd_seq_t *midi_seq;
> +static unsigned int seq_refs;
> +
>  static void seq_lock(void)
>  {
>      pthread_mutex_lock(&seq_mutex);
> @@ -62,3 +73,257 @@ NTSTATUS midi_seq_lock(void *args)
>  
>      return STATUS_SUCCESS;
>  }
> +
> +static int seq_open(void)
> +{
> +    static int midi_warn;
> +
> +    seq_lock();
> +    if (seq_refs == 0)
> +    {
> +        if (snd_seq_open(&midi_seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0)
> +        {
> +            if (!midi_warn)
> +                WARN("Error opening ALSA sequencer.\n");
> +            midi_warn = 1;
> +            seq_unlock();
> +            return -1;
> +        }
> +    }
> +    seq_refs++;
> +    seq_unlock();
> +    return 0;
> +}
> +
> +static void seq_close(void)
> +{
> +    seq_lock();
> +    if (--seq_refs == 0)
> +    {
> +        snd_seq_close(midi_seq);
> +        midi_seq = NULL;
> +    }
> +    seq_unlock();
> +}
> +
> +static int alsa_to_win_device_type(unsigned int type)
> +{
> +    /* MOD_MIDIPORT     output port
> +     * MOD_SYNTH        generic internal synth
> +     * MOD_SQSYNTH      square wave internal synth
> +     * MOD_FMSYNTH      FM internal synth
> +     * MOD_MAPPER       MIDI mapper
> +     * MOD_WAVETABLE    hardware wavetable internal synth
> +     * MOD_SWSYNTH      software internal synth
> +     */
> +
> +    /* FIXME Is this really the correct equivalence from ALSA to
> +       Windows Sound type? */
> +
> +    if (type & SND_SEQ_PORT_TYPE_SYNTH)
> +        return MOD_FMSYNTH;
> +
> +    if (type & (SND_SEQ_PORT_TYPE_DIRECT_SAMPLE|SND_SEQ_PORT_TYPE_SAMPLE))
> +        return MOD_SYNTH;
> +
> +    if (type & (SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION))
> +        return MOD_MIDIPORT;
> +
> +    ERR("Cannot determine the type (alsa type is %x) of this midi device. Assuming FM Synth\n", type);
> +    return MOD_FMSYNTH;
> +}
> +
> +static void port_add(snd_seq_client_info_t* cinfo, snd_seq_port_info_t* pinfo, unsigned int cap, unsigned int type)
> +{
> +    char name[MAXPNAMELEN];
> +    unsigned int len;
> +    struct midi_dest *dest;
> +    struct midi_src *src;
> +
> +    if (cap & SND_SEQ_PORT_CAP_WRITE) {
> +        TRACE("OUT (%d:%s:%s:%d:%s:%x)\n",snd_seq_client_info_get_client(cinfo),
> +              snd_seq_client_info_get_name(cinfo),
> +              snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel",
> +              snd_seq_port_info_get_port(pinfo),
> +              snd_seq_port_info_get_name(pinfo),
> +              type);
> +
> +        if (num_dests >= MAX_MIDIOUTDRV)
> +            return;
> +        if (!type)
> +            return;
> +
> +        dest = dests + num_dests;
> +        dest->addr = *snd_seq_port_info_get_addr(pinfo);
> +
> +        /* Manufac ID. We do not have access to this with soundcard.h
> +         * Does not seem to be a problem, because in mmsystem.h only
> +         * Microsoft's ID is listed.
> +         */
> +        dest->caps.wMid = 0x00FF;
> +        dest->caps.wPid = 0x0001;     /* FIXME Product ID  */
> +        /* Product Version. We simply say "1" */
> +        dest->caps.vDriverVersion = 0x001;
> +        /* The following are mandatory for MOD_MIDIPORT */
> +        dest->caps.wChannelMask = 0xFFFF;
> +        dest->caps.wVoices      = 0;
> +        dest->caps.wNotes       = 0;
> +        dest->caps.dwSupport    = 0;
> +
> +        /* Try to use both client and port names, if this is too long take the port name only.
> +           In the second case the port name should be explicit enough due to its big size.
> +        */
> +        len = strlen(snd_seq_port_info_get_name(pinfo));
> +        if ( (strlen(snd_seq_client_info_get_name(cinfo)) + len + 3) < sizeof(name) ) {
> +            sprintf(name, "%s - %s", snd_seq_client_info_get_name(cinfo), snd_seq_port_info_get_name(pinfo));
> +            len = strlen(name);
> +        } else {
> +            len = min(len, sizeof(name) - 1);
> +            memcpy(name, snd_seq_port_info_get_name(pinfo), len);
> +            name[len] = '\0';
> +        }
> +        ntdll_umbstowcs( name, len + 1, dest->caps.szPname, ARRAY_SIZE(dest->caps.szPname));
> +
> +        dest->caps.wTechnology = alsa_to_win_device_type(type);
> +
> +        if (MOD_MIDIPORT != dest->caps.wTechnology) {
> +            /* FIXME Do we have this information?
> +             * Assuming the soundcards can handle
> +             * MIDICAPS_VOLUME and MIDICAPS_LRVOLUME but
> +             * not MIDICAPS_CACHE.
> +             */
> +            dest->caps.dwSupport = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;
> +            dest->caps.wVoices   = 16;
> +
> +            /* FIXME Is it possible to know the maximum
> +             * number of simultaneous notes of a soundcard ?
> +             * I believe we don't have this information, but
> +             * it's probably equal or more than wVoices
> +             */
> +            dest->caps.wNotes     = 16;
> +        }
> +        dest->bEnabled            = TRUE;
> +        dest->port_out            = -1;
> +
> +        TRACE("MidiOut[%d]\tname='%s' techn=%d voices=%d notes=%d chnMsk=%04x support=%d\n"
> +              "\tALSA info: midi dev-type=%x, capa=0\n",
> +              num_dests, wine_dbgstr_w(dest->caps.szPname),
> +              dest->caps.wTechnology,
> +              dest->caps.wVoices, dest->caps.wNotes,
> +              dest->caps.wChannelMask, dest->caps.dwSupport,
> +              type);
> +
> +        num_dests++;
> +    }
> +    if (cap & SND_SEQ_PORT_CAP_READ) {
> +        TRACE("IN  (%d:%s:%s:%d:%s:%x)\n",snd_seq_client_info_get_client(cinfo),
> +              snd_seq_client_info_get_name(cinfo),
> +              snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel",
> +              snd_seq_port_info_get_port(pinfo),
> +              snd_seq_port_info_get_name(pinfo),
> +              type);
> +
> +        if (num_srcs >= MAX_MIDIINDRV)
> +            return;
> +        if (!type)
> +            return;
> +
> +        src = srcs + num_srcs;
> +        src->addr = *snd_seq_port_info_get_addr(pinfo);
> +
> +        /* Manufac ID. We do not have access to this with soundcard.h
> +         * Does not seem to be a problem, because in mmsystem.h only
> +         * Microsoft's ID is listed.
> +         */
> +        src->caps.wMid = 0x00FF;
> +        src->caps.wPid = 0x0001;      /* FIXME Product ID  */
> +        /* Product Version. We simply say "1" */
> +        src->caps.vDriverVersion = 0x001;
> +        src->caps.dwSupport = 0; /* mandatory with MIDIINCAPS */
> +
> +        /* Try to use both client and port names, if this is too long take the port name only.
> +           In the second case the port name should be explicit enough due to its big size.
> +        */
> +        len = strlen(snd_seq_port_info_get_name(pinfo));
> +        if ( (strlen(snd_seq_client_info_get_name(cinfo)) + len + 3) < sizeof(name) ) {
> +            sprintf(name, "%s - %s", snd_seq_client_info_get_name(cinfo), snd_seq_port_info_get_name(pinfo));
> +            len = strlen(name);
> +        } else {
> +            len = min(len, sizeof(name) - 1);
> +            memcpy(name, snd_seq_port_info_get_name(pinfo), len);
> +            name[len] = '\0';
> +        }
> +        ntdll_umbstowcs( name, len + 1, src->caps.szPname, ARRAY_SIZE(src->caps.szPname));
> +        src->state = 0;
> +
> +        TRACE("MidiIn [%d]\tname='%s' support=%d\n"
> +              "\tALSA info: midi dev-type=%x, capa=0\n",
> +              num_srcs, wine_dbgstr_w(src->caps.szPname), src->caps.dwSupport, type);
> +
> +        num_srcs++;
> +    }
> +}
> +
> +NTSTATUS midi_init(void *args)
> +{
> +    struct midi_init_params *params = args;
> +    static BOOL init_done;
> +    snd_seq_client_info_t *cinfo;
> +    snd_seq_port_info_t *pinfo;
> +
> +    if (init_done) {
> +        *params->err = ERROR_ALREADY_INITIALIZED;
> +        return STATUS_SUCCESS;
> +    }
> +
> +    TRACE("Initializing the MIDI variables.\n");
> +    init_done = TRUE;
> +
> +    /* try to open device */
> +    if (seq_open() == -1) {
> +        *params->err = ERROR_OPEN_FAILED;
> +        return STATUS_SUCCESS;
> +    }
> +
> +    cinfo = calloc( 1, snd_seq_client_info_sizeof() );
> +    pinfo = calloc( 1, snd_seq_port_info_sizeof() );
> +
> +    /* First, search for all internal midi devices */
> +    snd_seq_client_info_set_client(cinfo, -1);
> +    while (snd_seq_query_next_client(midi_seq, cinfo) >= 0) {
> +        snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
> +        snd_seq_port_info_set_port(pinfo, -1);
> +        while (snd_seq_query_next_port(midi_seq, pinfo) >= 0) {
> +            unsigned int cap = snd_seq_port_info_get_capability(pinfo);
> +            unsigned int type = snd_seq_port_info_get_type(pinfo);
> +            if (!(type & SND_SEQ_PORT_TYPE_PORT))
> +                port_add(cinfo, pinfo, cap, type);
> +        }
> +    }
> +
> +    /* Second, search for all external ports */
> +    snd_seq_client_info_set_client(cinfo, -1);
> +    while (snd_seq_query_next_client(midi_seq, cinfo) >= 0) {
> +        snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
> +        snd_seq_port_info_set_port(pinfo, -1);
> +        while (snd_seq_query_next_port(midi_seq, pinfo) >= 0) {
> +            unsigned int cap = snd_seq_port_info_get_capability(pinfo);
> +            unsigned int type = snd_seq_port_info_get_type(pinfo);
> +            if (type & SND_SEQ_PORT_TYPE_PORT)
> +                port_add(cinfo, pinfo, cap, type);
> +        }
> +    }
> +    seq_close();
> +    free( cinfo );
> +    free( pinfo );
> +
> +    *params->err = NOERROR;
> +    params->num_dests = num_dests;
> +    params->num_srcs = num_srcs;
> +    params->dests = dests;
> +    params->srcs = srcs;
> +
> +    TRACE("End\n");
> +
> +    return STATUS_SUCCESS;
> +}
> diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c
> index dff77ce88d8..988429ab934 100644
> --- a/dlls/winealsa.drv/midi.c
> +++ b/dlls/winealsa.drv/midi.c
> @@ -43,33 +43,12 @@
>  #include "wine/debug.h"
>  #include "wine/unixlib.h"
>  
> -#include <alsa/asoundlib.h>
> -
>  #include "unixlib.h"
>  
>  WINE_DEFAULT_DEBUG_CHANNEL(midi);
>  
> -typedef struct {
> -    int			state;                  /* -1 disabled, 0 is no recording started, 1 in recording, bit 2 set if in sys exclusive recording */
> -    MIDIOPENDESC	midiDesc;
> -    WORD		wFlags;
> -    LPMIDIHDR	 	lpQueueHdr;
> -    DWORD		startTime;
> -    MIDIINCAPSW         caps;
> -    snd_seq_addr_t      addr;
> -} WINE_MIDIIN;
> -
> -typedef struct {
> -    BOOL                bEnabled;
> -    MIDIOPENDESC	midiDesc;
> -    WORD		wFlags;
> -    MIDIOUTCAPSW        caps;
> -    snd_seq_addr_t      addr;
> -    int                 port_out;
> -} WINE_MIDIOUT;
> -
> -static WINE_MIDIIN	MidiInDev [MAX_MIDIINDRV ];
> -static WINE_MIDIOUT	MidiOutDev[MAX_MIDIOUTDRV];
> +static WINE_MIDIIN	*MidiInDev;
> +static WINE_MIDIOUT	*MidiOutDev;
>  
>  /* this is the total number of MIDI out devices found (synth and port) */
>  static	int 		MODM_NumDevs = 0;
> @@ -124,39 +103,6 @@ static void error_handler(const char* file, int line, const char* function, int
>  }
>  #endif
>  
> -/**************************************************************************
> - * 			MIDI_unixToWindowsDeviceType  		[internal]
> - *
> - * return the Windows equivalent to a Unix Device Type
> - *
> - */
> -static	int 	MIDI_AlsaToWindowsDeviceType(unsigned int type)
> -{
> -    /* MOD_MIDIPORT     output port
> -     * MOD_SYNTH        generic internal synth
> -     * MOD_SQSYNTH      square wave internal synth
> -     * MOD_FMSYNTH      FM internal synth
> -     * MOD_MAPPER       MIDI mapper
> -     * MOD_WAVETABLE    hardware wavetable internal synth
> -     * MOD_SWSYNTH      software internal synth
> -     */
> -
> -    /* FIXME Is this really the correct equivalence from ALSA to
> -       Windows Sound type? */
> -
> -    if (type & SND_SEQ_PORT_TYPE_SYNTH)
> -        return MOD_FMSYNTH;
> -
> -    if (type & (SND_SEQ_PORT_TYPE_DIRECT_SAMPLE|SND_SEQ_PORT_TYPE_SAMPLE))
> -        return MOD_SYNTH;
> -
> -    if (type & (SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION))
> -        return MOD_MIDIPORT;
> -    
> -    ERR("Cannot determine the type (alsa type is %x) of this midi device. Assuming FM Synth\n", type);
> -    return MOD_FMSYNTH;
> -}
> -
>  /**************************************************************************
>   * 			MIDI_NotifyClient			[internal]
>   */
> @@ -1121,134 +1067,6 @@ static DWORD modReset(WORD wDevID)
>  }
>  
>  
> -/**************************************************************************
> - *                      ALSA_AddMidiPort			[internal]
> - *
> - * Helper for ALSA_MidiInit
> - */
> -static void ALSA_AddMidiPort(snd_seq_client_info_t* cinfo, snd_seq_port_info_t* pinfo, unsigned int cap, unsigned int type)
> -{
> -    char midiPortName[MAXPNAMELEN];
> -
> -    if (cap & SND_SEQ_PORT_CAP_WRITE) {
> -	TRACE("OUT (%d:%s:%s:%d:%s:%x)\n",snd_seq_client_info_get_client(cinfo),
> -					  snd_seq_client_info_get_name(cinfo),
> -					  snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel",
> -					  snd_seq_port_info_get_port(pinfo),
> -					  snd_seq_port_info_get_name(pinfo),
> -					  type);
> -		
> -	if (MODM_NumDevs >= MAX_MIDIOUTDRV)
> -	    return;
> -	if (!type)
> -            return;
> -
> -	MidiOutDev[MODM_NumDevs].addr = *snd_seq_port_info_get_addr(pinfo);
> -
> -	/* Manufac ID. We do not have access to this with soundcard.h
> -	 * Does not seem to be a problem, because in mmsystem.h only
> -	 * Microsoft's ID is listed.
> -	 */
> -	MidiOutDev[MODM_NumDevs].caps.wMid = 0x00FF;
> -	MidiOutDev[MODM_NumDevs].caps.wPid = 0x0001; 	/* FIXME Product ID  */
> -	/* Product Version. We simply say "1" */
> -	MidiOutDev[MODM_NumDevs].caps.vDriverVersion = 0x001;
> -	/* The following are mandatory for MOD_MIDIPORT */
> -	MidiOutDev[MODM_NumDevs].caps.wChannelMask   = 0xFFFF;
> -	MidiOutDev[MODM_NumDevs].caps.wVoices        = 0;
> -	MidiOutDev[MODM_NumDevs].caps.wNotes         = 0;
> -	MidiOutDev[MODM_NumDevs].caps.dwSupport      = 0;
> -
> -	/* Try to use both client and port names, if this is too long take the port name only.
> -           In the second case the port name should be explicit enough due to its big size.
> -	 */
> -	if ( (strlen(snd_seq_client_info_get_name(cinfo)) + strlen(snd_seq_port_info_get_name(pinfo)) + 3) < MAXPNAMELEN ) {
> -	    sprintf(midiPortName, "%s - %s", snd_seq_client_info_get_name(cinfo), snd_seq_port_info_get_name(pinfo));
> -	} else {
> -	    lstrcpynA(midiPortName, snd_seq_port_info_get_name(pinfo), MAXPNAMELEN);
> -	}
> -        MultiByteToWideChar(CP_UNIXCP, 0, midiPortName, -1, MidiOutDev[MODM_NumDevs].caps.szPname,
> -                            ARRAY_SIZE(MidiOutDev[MODM_NumDevs].caps.szPname));
> -
> -	MidiOutDev[MODM_NumDevs].caps.wTechnology = MIDI_AlsaToWindowsDeviceType(type);
> -
> -	if (MOD_MIDIPORT != MidiOutDev[MODM_NumDevs].caps.wTechnology) {
> -	    /* FIXME Do we have this information?
> -	     * Assuming the soundcards can handle
> -	     * MIDICAPS_VOLUME and MIDICAPS_LRVOLUME but
> -	     * not MIDICAPS_CACHE.
> -	     */
> -	    MidiOutDev[MODM_NumDevs].caps.dwSupport = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;
> -	    MidiOutDev[MODM_NumDevs].caps.wVoices   = 16;
> -
> -            /* FIXME Is it possible to know the maximum
> -             * number of simultaneous notes of a soundcard ?
> -             * I believe we don't have this information, but
> -             * it's probably equal or more than wVoices
> -             */
> -	    MidiOutDev[MODM_NumDevs].caps.wNotes    = 16;
> -	}
> -	MidiOutDev[MODM_NumDevs].bEnabled    = TRUE;
> -	MidiOutDev[MODM_NumDevs].port_out    = -1;
> -
> -	TRACE("MidiOut[%d]\tname='%s' techn=%d voices=%d notes=%d chnMsk=%04x support=%d\n"
> -            "\tALSA info: midi dev-type=%x, capa=0\n",
> -              MODM_NumDevs, wine_dbgstr_w(MidiOutDev[MODM_NumDevs].caps.szPname),
> -              MidiOutDev[MODM_NumDevs].caps.wTechnology,
> -              MidiOutDev[MODM_NumDevs].caps.wVoices, MidiOutDev[MODM_NumDevs].caps.wNotes,
> -              MidiOutDev[MODM_NumDevs].caps.wChannelMask, MidiOutDev[MODM_NumDevs].caps.dwSupport,
> -              type);
> -		
> -	MODM_NumDevs++;
> -    }
> -    if (cap & SND_SEQ_PORT_CAP_READ) {
> -        TRACE("IN  (%d:%s:%s:%d:%s:%x)\n",snd_seq_client_info_get_client(cinfo),
> -			                  snd_seq_client_info_get_name(cinfo),
> -					  snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel",
> -					  snd_seq_port_info_get_port(pinfo),
> -					  snd_seq_port_info_get_name(pinfo),
> -					  type);
> -		
> -	if (MIDM_NumDevs >= MAX_MIDIINDRV)
> -	    return;
> -	if (!type)
> -	    return;
> -
> -	MidiInDev[MIDM_NumDevs].addr = *snd_seq_port_info_get_addr(pinfo);
> -
> -	/* Manufac ID. We do not have access to this with soundcard.h
> -	 * Does not seem to be a problem, because in mmsystem.h only
> -	 * Microsoft's ID is listed.
> -	 */
> -	MidiInDev[MIDM_NumDevs].caps.wMid = 0x00FF;
> -	MidiInDev[MIDM_NumDevs].caps.wPid = 0x0001; 	/* FIXME Product ID  */
> -	/* Product Version. We simply say "1" */
> -	MidiInDev[MIDM_NumDevs].caps.vDriverVersion = 0x001;
> -	MidiInDev[MIDM_NumDevs].caps.dwSupport = 0; /* mandatory with MIDIINCAPS */
> -
> -	/* Try to use both client and port names, if this is too long take the port name only.
> -           In the second case the port name should be explicit enough due to its big size.
> -	 */
> -	if ( (strlen(snd_seq_client_info_get_name(cinfo)) + strlen(snd_seq_port_info_get_name(pinfo)) + 3) < MAXPNAMELEN ) {
> -	    sprintf(midiPortName, "%s - %s", snd_seq_client_info_get_name(cinfo), snd_seq_port_info_get_name(pinfo));
> -	} else {
> -	    lstrcpynA(midiPortName, snd_seq_port_info_get_name(pinfo), MAXPNAMELEN);
> -        }
> -        MultiByteToWideChar(CP_UNIXCP, 0, midiPortName, -1, MidiInDev[MIDM_NumDevs].caps.szPname,
> -                            ARRAY_SIZE(MidiInDev[MIDM_NumDevs].caps.szPname));
> -	MidiInDev[MIDM_NumDevs].state = 0;
> -
> -	TRACE("MidiIn [%d]\tname='%s' support=%d\n"
> -              "\tALSA info: midi dev-type=%x, capa=0\n",
> -              MIDM_NumDevs, wine_dbgstr_w(MidiInDev[MIDM_NumDevs].caps.szPname),
> -              MidiInDev[MIDM_NumDevs].caps.dwSupport,
> -              type);
> -
> -	MIDM_NumDevs++;
> -    }
> -}
> -
> -
>  /*======================================================================*
>   *                  	    MIDI entry points 				*
>   *======================================================================*/
> @@ -1260,59 +1078,19 @@ static void ALSA_AddMidiPort(snd_seq_client_info_t* cinfo, snd_seq_port_info_t*
>   */
>  static BOOL ALSA_MidiInit(void)
>  {
> -    static	BOOL	bInitDone = FALSE;
> -    snd_seq_client_info_t *cinfo;
> -    snd_seq_port_info_t *pinfo;
> -
> -    if (bInitDone)
> -	return TRUE;
> -
> -    TRACE("Initializing the MIDI variables.\n");
> -    bInitDone = TRUE;
> -
> -    /* try to open device */
> -    if (midiOpenSeq(FALSE) == -1) {
> -	return TRUE;
> +    struct midi_init_params params;
> +    UINT err;
> +
> +    params.err = &err;
> +    ALSA_CALL(midi_init, &params);
> +
> +    if (!err)
> +    {
> +        MODM_NumDevs = params.num_dests;
> +        MIDM_NumDevs = params.num_srcs;
> +        MidiOutDev = params.dests;
> +        MidiInDev = params.srcs;
>      }
> -
> -#if 0 /* Debug purpose */
> -    snd_lib_error_set_handler(error_handler);
> -#endif
> -    cinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, snd_seq_client_info_sizeof() );
> -    pinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, snd_seq_port_info_sizeof() );
> -
> -    /* First, search for all internal midi devices */
> -    snd_seq_client_info_set_client(cinfo, -1);
> -    while(snd_seq_query_next_client(midiSeq, cinfo) >= 0) {
> -        snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
> -	snd_seq_port_info_set_port(pinfo, -1);
> -	while (snd_seq_query_next_port(midiSeq, pinfo) >= 0) {
> -	    unsigned int cap = snd_seq_port_info_get_capability(pinfo);
> -	    unsigned int type = snd_seq_port_info_get_type(pinfo);
> -	    if (!(type & SND_SEQ_PORT_TYPE_PORT))
> -	        ALSA_AddMidiPort(cinfo, pinfo, cap, type);
> -	}
> -    }
> -
> -    /* Second, search for all external ports */
> -    snd_seq_client_info_set_client(cinfo, -1);
> -    while(snd_seq_query_next_client(midiSeq, cinfo) >= 0) {
> -        snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
> -	snd_seq_port_info_set_port(pinfo, -1);
> -	while (snd_seq_query_next_port(midiSeq, pinfo) >= 0) {
> -	    unsigned int cap = snd_seq_port_info_get_capability(pinfo);
> -	    unsigned int type = snd_seq_port_info_get_type(pinfo);
> -	    if (type & SND_SEQ_PORT_TYPE_PORT)
> -	        ALSA_AddMidiPort(cinfo, pinfo, cap, type);
> -	}
> -    }
> -
> -    /* close file and exit */
> -    midiCloseSeq();
> -    HeapFree( GetProcessHeap(), 0, cinfo );
> -    HeapFree( GetProcessHeap(), 0, pinfo );
> -
> -    TRACE("End\n");
>      return TRUE;
>  }
>  
> diff --git a/dlls/winealsa.drv/unixlib.h b/dlls/winealsa.drv/unixlib.h
> index 89afcb71bec..adac72183ee 100644
> --- a/dlls/winealsa.drv/unixlib.h
> +++ b/dlls/winealsa.drv/unixlib.h
> @@ -207,6 +207,37 @@ struct get_prop_value_params
>      unsigned int *buffer_size;
>  };
>  
> +#include <alsa/asoundlib.h>
> +#include "mmddk.h"
> +
> +typedef struct midi_src
> +{
> +    int                 state;          /* -1 disabled, 0 is no recording started, 1 in recording, bit 2 set if in sys exclusive recording */
> +    MIDIOPENDESC        midiDesc;
> +    WORD                wFlags;
> +    MIDIHDR            *lpQueueHdr;
> +    UINT                startTime;
> +    MIDIINCAPSW         caps;
> +    snd_seq_addr_t      addr;
> +} WINE_MIDIIN;
> +
> +typedef struct midi_dest
> +{
> +    BOOL                bEnabled;
> +    MIDIOPENDESC        midiDesc;
> +    WORD                wFlags;
> +    MIDIOUTCAPSW        caps;
> +    snd_seq_addr_t      addr;
> +    int                 port_out;
> +} WINE_MIDIOUT;
> +
> +struct midi_init_params
> +{
> +    UINT *err;
> +    unsigned int num_dests, num_srcs;
> +    void *dests, *srcs;
> +};
> +
>  enum alsa_funcs
>  {
>      alsa_get_endpoint_ids,
> @@ -232,10 +263,13 @@ enum alsa_funcs
>      alsa_set_event_handle,
>      alsa_is_started,
>      alsa_get_prop_value,
> +    alsa_midi_init,
>  
>      alsa_midi_seq_lock, /* temporary */
>  };
>  
> +NTSTATUS midi_init(void *args) DECLSPEC_HIDDEN;
> +
>  NTSTATUS midi_seq_lock(void *args) DECLSPEC_HIDDEN;
>  
>  extern unixlib_handle_t alsa_handle;
> -- 
> 2.25.1
> 
> 



More information about the wine-devel mailing list