[PATCH 2/6] winealsa: Move midi_init to unixlib.

Huw Davies huw at codeweavers.com
Tue Mar 15 04:30:41 CDT 2022


Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/winealsa.drv/alsa.c     |   1 +
 dlls/winealsa.drv/alsamidi.c | 256 +++++++++++++++++++++++++++++++++++
 dlls/winealsa.drv/midi.c     | 240 ++------------------------------
 dlls/winealsa.drv/unixlib.h  |  34 +++++
 4 files changed, 305 insertions(+), 226 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..9e7962f46cd 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,248 @@ 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;
+    int external;
+
+    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() );
+
+    /* Add internal ports first, followed by external */
+    for (external = 0; external < 2; external++) {
+        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 (!external == !(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 c90b061da64..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,49 +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;
-    int external;
-
-    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() );
-
-    /* Add internal ports first, followed by external */
-    for (external = 0; external < 2; external++) {
-        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 (!external == !(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