[PATCH 03/12] winecoreaudio: Move midi_init and midi_release to the unixlib.

Andrew Eikum aeikum at codeweavers.com
Fri Nov 26 09:01:50 CST 2021


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

On Thu, Nov 25, 2021 at 11:03:38AM +0000, Huw Davies wrote:
> midi_init temporarily returns unix-side info, which will eventually
> be removed.
> 
> Signed-off-by: Huw Davies <huw at codeweavers.com>
> ---
>  dlls/winecoreaudio.drv/coreaudio.c |   2 +
>  dlls/winecoreaudio.drv/coremidi.c  | 233 +++++++++++++++++++++++++----
>  dlls/winecoreaudio.drv/coremidi.h  |  28 +++-
>  dlls/winecoreaudio.drv/midi.c      | 153 ++++---------------
>  dlls/winecoreaudio.drv/unixlib.h   |  13 ++
>  5 files changed, 276 insertions(+), 153 deletions(-)
> 
> diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c
> index fd32a2a99ac..9476b6baf6f 100644
> --- a/dlls/winecoreaudio.drv/coreaudio.c
> +++ b/dlls/winecoreaudio.drv/coreaudio.c
> @@ -1629,4 +1629,6 @@ unixlib_entry_t __wine_unix_call_funcs[] =
>      get_frequency,
>      is_started,
>      set_volumes,
> +    midi_init,
> +    midi_release,
>  };
> diff --git a/dlls/winecoreaudio.drv/coremidi.c b/dlls/winecoreaudio.drv/coremidi.c
> index 92f52c972d3..dedfa0aa9ee 100644
> --- a/dlls/winecoreaudio.drv/coremidi.c
> +++ b/dlls/winecoreaudio.drv/coremidi.c
> @@ -21,46 +21,90 @@
>   * License along with this library; if not, write to the Free Software
>   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
>   */
> -
> +#if 0
> +#pragma makedep unix
> +#endif
>  
>  #include "config.h"
>  
> -#include <CoreMIDI/CoreMIDI.h>
> +#define ULONG __carbon_ULONG
> +#define E_INVALIDARG __carbon_E_INVALIDARG
> +#define E_OUTOFMEMORY __carbon_E_OUTOFMEMORY
> +#define E_HANDLE __carbon_E_HANDLE
> +#define E_ACCESSDENIED __carbon_E_ACCESSDENIED
> +#define E_UNEXPECTED __carbon_E_UNEXPECTED
> +#define E_FAIL __carbon_E_FAIL
> +#define E_ABORT __carbon_E_ABORT
> +#define E_POINTER __carbon_E_POINTER
> +#define E_NOINTERFACE __carbon_E_NOINTERFACE
> +#define E_NOTIMPL __carbon_E_NOTIMPL
> +#define S_FALSE __carbon_S_FALSE
> +#define S_OK __carbon_S_OK
> +#define HRESULT_FACILITY __carbon_HRESULT_FACILITY
> +#define IS_ERROR __carbon_IS_ERROR
> +#define FAILED __carbon_FAILED
> +#define SUCCEEDED __carbon_SUCCEEDED
> +#define MAKE_HRESULT __carbon_MAKE_HRESULT
> +#define HRESULT __carbon_HRESULT
> +#define STDMETHODCALLTYPE __carbon_STDMETHODCALLT
>  #include <mach/mach_time.h>
> +#include <CoreMIDI/CoreMIDI.h>
> +#include <AudioUnit/AudioUnit.h>
> +#include <AudioToolbox/AudioToolbox.h>
> +#undef ULONG
> +#undef E_INVALIDARG
> +#undef E_OUTOFMEMORY
> +#undef E_HANDLE
> +#undef E_ACCESSDENIED
> +#undef E_UNEXPECTED
> +#undef E_FAIL
> +#undef E_ABORT
> +#undef E_POINTER
> +#undef E_NOINTERFACE
> +#undef E_NOTIMPL
> +#undef S_FALSE
> +#undef S_OK
> +#undef HRESULT_FACILITY
> +#undef IS_ERROR
> +#undef FAILED
> +#undef SUCCEEDED
> +#undef MAKE_HRESULT
> +#undef HRESULT
> +#undef STDMETHODCALLTYPE
>  
> -#include "coremidi.h"
> -
> -
> -MIDIClientRef CoreMIDI_CreateClient(CFStringRef name)
> -{
> -    MIDIClientRef client = 0;
> -
> -    if (MIDIClientCreate(name, NULL /* FIXME use notify proc */, NULL, &client) != noErr)
> -        return 0;
> +#include "ntstatus.h"
> +#define WIN32_NO_STATUS
> +#include "windef.h"
> +#include "winbase.h"
> +#include "winnls.h"
> +#include "winreg.h"
> +#include "mmsystem.h"
> +#include "mmddk.h"
> +#include "mmdeviceapi.h"
> +#include "audioclient.h"
> +#include "wine/debug.h"
> +#include "wine/unicode.h"
> +#include "wine/unixlib.h"
>  
> -    return client;
> -}
> +#include "coremidi.h"
> +#include "unixlib.h"
>  
> -void CoreMIDI_GetObjectName(MIDIObjectRef obj, char *name, int size)
> -{
> -    OSStatus err = noErr;
> -    CFStringRef cfname;
> +WINE_DEFAULT_DEBUG_CHANNEL(midi);
>  
> -    err = MIDIObjectGetStringProperty(obj, kMIDIPropertyName, &cfname);
> -    if (err == noErr)
> -    {
> -        CFStringGetCString(cfname, name, size, kCFStringEncodingASCII);
> -        CFRelease(cfname);
> -    }
> -}
> +static MIDIClientRef midi_client;
> +static MIDIPortRef midi_out_port, midi_in_port;
> +static UINT num_dests, num_srcs;
> +static struct midi_dest *dests;
> +static struct midi_src *srcs;
> +static CFStringRef midi_in_thread_port_name;
>  
>  /*
>   *  CoreMIDI IO threaded callback,
>   *  we can't call Wine debug channels, critical section or anything using NtCurrentTeb here.
>   */
> -void MIDIIn_ReadProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon)
> +static void midi_in_read_proc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon)
>  {
> -    CFMessagePortRef msg_port = CFMessagePortCreateRemote(kCFAllocatorDefault, MIDIInThreadPortName);
> +    CFMessagePortRef msg_port = CFMessagePortCreateRemote(kCFAllocatorDefault, midi_in_thread_port_name);
>      MIDIPacket *packet = (MIDIPacket *)pktlist->packet;
>      CFMutableDataRef data;
>      MIDIMessage msg;
> @@ -82,3 +126,140 @@ void MIDIIn_ReadProc(const MIDIPacketList *pktlist, void *refCon, void *connRefC
>      }
>      CFRelease(msg_port);
>  }
> +
> +NTSTATUS midi_init(void *args)
> +{
> +    CFStringRef name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("wineMIDIClient.%d"), getpid());
> +    struct midi_init_params *params = args;
> +    OSStatus sc;
> +    UINT i;
> +
> +    sc = MIDIClientCreate(name, NULL /* FIXME use notify proc */, NULL, &midi_client);
> +    CFRelease(name);
> +    if (sc)
> +    {
> +        ERR("can't create MIDI Client\n");
> +        *params->err = DRV_FAILURE;
> +        return STATUS_SUCCESS;
> +    }
> +
> +    num_dests = MAX_MIDI_SYNTHS + MIDIGetNumberOfDestinations();
> +    num_srcs = MIDIGetNumberOfSources();
> +
> +    TRACE("num_dests %d num_srcs %d\n", num_dests, num_srcs);
> +
> +    dests = calloc(num_dests, sizeof(*dests));
> +    srcs = calloc(num_srcs, sizeof(*srcs));
> +
> +    if (num_srcs > 0)
> +    {
> +        midi_in_thread_port_name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("MIDIInThreadPortName.%u"), getpid());
> +        name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("WineInputPort.%u"), getpid());
> +        MIDIInputPortCreate(midi_client, name, midi_in_read_proc, NULL, &midi_in_port);
> +        CFRelease(name);
> +    }
> +
> +    if (num_dests > MAX_MIDI_SYNTHS)
> +    {
> +        name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("WineOutputPort.%u"), getpid());
> +        MIDIOutputPortCreate(midi_client, name, &midi_out_port);
> +        CFRelease(name);
> +    }
> +
> +    /* initialize sources */
> +    for (i = 0; i < num_srcs; i++)
> +    {
> +        srcs[i].wDevID = i;
> +        srcs[i].source = MIDIGetSource(i);
> +
> +        sc = MIDIObjectGetStringProperty(srcs[i].source, kMIDIPropertyName, &name);
> +        if (!sc)
> +        {
> +            int len = min(CFStringGetLength(name), ARRAY_SIZE(srcs[i].caps.szPname) - 1);
> +            CFStringGetCharacters(name, CFRangeMake(0, len), srcs[i].caps.szPname);
> +            srcs[i].caps.szPname[len] = '\0';
> +        }
> +        MIDIPortConnectSource(midi_in_port, srcs[i].source, &srcs[i].wDevID);
> +
> +        srcs[i].state = 0;
> +        /* FIXME */
> +        srcs[i].caps.wMid = 0x00FF; 	/* Manufac ID */
> +        srcs[i].caps.wPid = 0x0001; 	/* Product ID */
> +        srcs[i].caps.vDriverVersion = 0x0001;
> +        srcs[i].caps.dwSupport = 0;
> +    }
> +
> +    /* initialise MIDI synths */
> +    for (i = 0; i < MAX_MIDI_SYNTHS; i++)
> +    {
> +        static const WCHAR synth_name[] = {'C','o','r','e','A','u','d','i','o',' ','M','I','D','I',' ','S','y','n','t','h',' '};
> +
> +        C_ASSERT(MAX_MIDI_SYNTHS < 10);
> +        memcpy(dests[i].caps.szPname, synth_name, sizeof(synth_name));
> +        dests[i].caps.szPname[ARRAY_SIZE(synth_name)] = '1' + i;
> +        dests[i].caps.szPname[ARRAY_SIZE(synth_name) + 1] = '\0';
> +
> +        dests[i].caps.wTechnology = MOD_SYNTH;
> +        dests[i].caps.wChannelMask = 0xFFFF;
> +
> +        dests[i].caps.wMid = 0x00FF; 	/* Manufac ID */
> +        dests[i].caps.wPid = 0x0001; 	/* Product ID */
> +        dests[i].caps.vDriverVersion = 0x0001;
> +        dests[i].caps.dwSupport = MIDICAPS_VOLUME;
> +        dests[i].caps.wVoices = 16;
> +        dests[i].caps.wNotes = 16;
> +    }
> +    /* initialise available destinations */
> +    for (i = MAX_MIDI_SYNTHS; i < num_dests; i++)
> +    {
> +        dests[i].dest = MIDIGetDestination(i - MAX_MIDI_SYNTHS);
> +
> +        sc = MIDIObjectGetStringProperty(dests[i].dest, kMIDIPropertyName, &name);
> +        if (!sc)
> +        {
> +            int len = min(CFStringGetLength(name), ARRAY_SIZE(dests[i].caps.szPname) - 1);
> +            CFStringGetCharacters(name, CFRangeMake(0, len), dests[i].caps.szPname);
> +            dests[i].caps.szPname[len] = '\0';
> +        }
> +
> +        dests[i].caps.wTechnology = MOD_MIDIPORT;
> +        dests[i].caps.wChannelMask = 0xFFFF;
> +
> +        dests[i].caps.wMid = 0x00FF; 	/* Manufac ID */
> +        dests[i].caps.wPid = 0x0001;
> +        dests[i].caps.vDriverVersion = 0x0001;
> +        dests[i].caps.dwSupport = 0;
> +        dests[i].caps.wVoices = 0;
> +        dests[i].caps.wNotes = 0;
> +    }
> +
> +    params->num_dests = num_dests;
> +    params->num_srcs = num_srcs;
> +    params->dests = dests;
> +    params->srcs = srcs;
> +    params->midi_out_port = (void *)midi_out_port;
> +    params->midi_in_port = (void *)midi_in_port;
> +
> +    *params->err = DRV_SUCCESS;
> +    return STATUS_SUCCESS;
> +}
> +
> +NTSTATUS midi_release(void *args)
> +{
> +    CFMessagePortRef msg_port;
> +
> +    if (num_srcs)
> +    {
> +        /* Stop CFRunLoop in MIDIIn_MessageThread */
> +        msg_port = CFMessagePortCreateRemote(kCFAllocatorDefault, midi_in_thread_port_name);
> +        CFMessagePortSendRequest(msg_port, 1, NULL, 0.0, 0.0, NULL, NULL);
> +        CFRelease(msg_port);
> +    }
> +
> +    if (midi_client) MIDIClientDispose(midi_client); /* MIDIClientDispose will close all ports */
> +
> +    free(srcs);
> +    free(dests);
> +
> +    return STATUS_SUCCESS;
> +}
> diff --git a/dlls/winecoreaudio.drv/coremidi.h b/dlls/winecoreaudio.drv/coremidi.h
> index 47566345b54..ca669db7db1 100644
> --- a/dlls/winecoreaudio.drv/coremidi.h
> +++ b/dlls/winecoreaudio.drv/coremidi.h
> @@ -23,6 +23,8 @@
>  
>  #include <CoreFoundation/CoreFoundation.h>
>  
> +#define MAX_MIDI_SYNTHS 1
> +
>  #ifdef WINE_DEFINITIONS
>  /*
>   * Due to CoreMIDI headers conflict redefine some types for Wine
> @@ -73,7 +75,31 @@ extern void MIDIIn_ReadProc(const MIDIPacketList *pktlist, void *refCon, void *c
>  extern void MIDIOut_Send(MIDIPortRef port, MIDIEndpointRef dest, UInt8 *buffer, unsigned length);
>  
>  /* midi.c */
> -extern CFStringRef MIDIInThreadPortName;
> +typedef struct midi_dest
> +{
> +    /* graph and synth are only used for MIDI Synth */
> +    AUGraph graph;
> +    AudioUnit synth;
> +
> +    MIDIEndpointRef dest;
> +
> +    MIDIOUTCAPSW caps;
> +    MIDIOPENDESC midiDesc;
> +    WORD wFlags;
> +} MIDIDestination;
> +
> +typedef struct midi_src
> +{
> +    MIDIEndpointRef source;
> +
> +    WORD wDevID;
> +    int state; /* 0 is no recording started, 1 in recording, bit 2 set if in sys exclusive recording */
> +    MIDIINCAPSW caps;
> +    MIDIOPENDESC midiDesc;
> +    LPMIDIHDR lpQueueHdr;
> +    WORD wFlags;
> +    DWORD startTime;
> +} MIDISource;
>  
>  typedef struct {
>      UInt16 devID;
> diff --git a/dlls/winecoreaudio.drv/midi.c b/dlls/winecoreaudio.drv/midi.c
> index 2c89f32b430..000c57ad98d 100644
> --- a/dlls/winecoreaudio.drv/midi.c
> +++ b/dlls/winecoreaudio.drv/midi.c
> @@ -35,9 +35,13 @@
>  #include "winuser.h"
>  #include "winnls.h"
>  #include "mmddk.h"
> +#include "mmdeviceapi.h"
> +#include "audioclient.h"
>  #include "wine/unicode.h"
>  #include "wine/debug.h"
> +#include "wine/unixlib.h"
>  #include "coreaudio.h"
> +#include "unixlib.h"
>  
>  WINE_DEFAULT_DEBUG_CHANNEL(midi);
>  
> @@ -46,45 +50,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(midi);
>  #define WINE_DEFINITIONS
>  #include "coremidi.h"
>  
> -static MIDIClientRef wineMIDIClient = NULL;
> -
>  static DWORD MIDIOut_NumDevs = 0;
>  static DWORD MIDIIn_NumDevs = 0;
>  
> -typedef struct tagMIDIDestination {
> -    /* graph and synth are only used for MIDI Synth */
> -    AUGraph graph;
> -    AudioUnit synth;
> -
> -    MIDIEndpointRef dest;
> -
> -    MIDIOUTCAPSW caps;
> -    MIDIOPENDESC midiDesc;
> -    WORD wFlags;
> -} MIDIDestination;
> -
> -typedef struct tagMIDISource {
> -    MIDIEndpointRef source;
> -
> -    WORD wDevID;
> -    int state; /* 0 is no recording started, 1 in recording, bit 2 set if in sys exclusive recording */
> -    MIDIINCAPSW caps;
> -    MIDIOPENDESC midiDesc;
> -    LPMIDIHDR lpQueueHdr;
> -    WORD wFlags;
> -    DWORD startTime;
> -} MIDISource;
> -
>  static CRITICAL_SECTION midiInLock; /* Critical section for MIDI In */
> -CFStringRef MIDIInThreadPortName = NULL;
> +static CFStringRef MIDIInThreadPortName;
>  
>  static DWORD WINAPI MIDIIn_MessageThread(LPVOID p);
>  
>  static MIDIPortRef MIDIInPort = NULL;
>  static MIDIPortRef MIDIOutPort = NULL;
>  
> -#define MAX_MIDI_SYNTHS 1
> -
>  MIDIDestination *destinations;
>  MIDISource *sources;
>  
> @@ -92,127 +68,52 @@ extern int SynthUnit_CreateDefaultSynthUnit(AUGraph *graph, AudioUnit *synth);
>  extern int SynthUnit_Initialize(AudioUnit synth, AUGraph graph);
>  extern int SynthUnit_Close(AUGraph graph);
>  
> -
> -LONG CoreAudio_MIDIInit(void)
> +static LONG CoreAudio_MIDIInit(void)
>  {
> -    int i;
> -    CHAR szPname[MAXPNAMELEN] = {0};
> +    struct midi_init_params params;
> +    DWORD err;
>  
> -    int numDest = MIDIGetNumberOfDestinations();
> -    CFStringRef name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("wineMIDIClient.%d"), getpid());
> +    params.err = &err;
>  
> -    wineMIDIClient = CoreMIDI_CreateClient( name );
> -    if (wineMIDIClient == NULL)
> +    UNIX_CALL(midi_init, &params);
> +    if (err != DRV_SUCCESS)
>      {
> -        CFRelease(name);
> -        ERR("can't create wineMIDIClient\n");
> -        return DRV_FAILURE;
> +        ERR("can't create midi client\n");
> +        return err;
>      }
> -    CFRelease(name);
>  
> -    MIDIOut_NumDevs = MAX_MIDI_SYNTHS;
> -    MIDIOut_NumDevs += numDest;
> -
> -    MIDIIn_NumDevs = MIDIGetNumberOfSources();
> -
> -    TRACE("MIDIOut_NumDevs %d MIDIIn_NumDevs %d\n", MIDIOut_NumDevs, MIDIIn_NumDevs);
> -
> -    destinations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MIDIOut_NumDevs * sizeof(MIDIDestination));
> -    sources = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MIDIIn_NumDevs * sizeof(MIDISource));
> +    MIDIOut_NumDevs = params.num_dests;
> +    MIDIIn_NumDevs = params.num_srcs;
> +    destinations = params.dests;
> +    sources = params.srcs;
> +    MIDIOutPort = params.midi_out_port;
> +    MIDIInPort = params.midi_in_port;
>  
>      if (MIDIIn_NumDevs > 0)
>      {
>          InitializeCriticalSection(&midiInLock);
>          midiInLock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": midiInLock");
> +
>          MIDIInThreadPortName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("MIDIInThreadPortName.%u"), getpid());
>          CloseHandle( CreateThread(NULL, 0, MIDIIn_MessageThread, NULL, 0, NULL));
> -
> -        name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("WineInputPort.%u"), getpid());
> -        MIDIInputPortCreate(wineMIDIClient, name, MIDIIn_ReadProc, NULL, &MIDIInPort);
> -        CFRelease(name);
>      }
> -    if (numDest > 0)
> -    {
> -        name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("WineOutputPort.%u"), getpid());
> -        MIDIOutputPortCreate(wineMIDIClient, name, &MIDIOutPort);
> -        CFRelease(name);
> -    }
> -
> -    /* initialize sources */
> -    for (i = 0; i < MIDIIn_NumDevs; i++)
> -    {
> -        sources[i].wDevID = i;
> -        sources[i].source = MIDIGetSource(i);
> -
> -        CoreMIDI_GetObjectName(sources[i].source, szPname, sizeof(szPname));
> -        MultiByteToWideChar(CP_ACP, 0, szPname, -1, sources[i].caps.szPname, ARRAY_SIZE(sources[i].caps.szPname));
> -
> -        MIDIPortConnectSource(MIDIInPort, sources[i].source, &sources[i].wDevID);
> -
> -        sources[i].state = 0;
> -        /* FIXME */
> -        sources[i].caps.wMid = 0x00FF; 	/* Manufac ID */
> -        sources[i].caps.wPid = 0x0001; 	/* Product ID */
> -        sources[i].caps.vDriverVersion = 0x0001;
> -        sources[i].caps.dwSupport = 0;
> -    }
> -
> -    /* initialise MIDI synths */
> -    for (i = 0; i < MAX_MIDI_SYNTHS; i++)
> -    {
> -        snprintf(szPname, sizeof(szPname), "CoreAudio MIDI Synth %d", i);
> -        MultiByteToWideChar(CP_ACP, 0, szPname, -1, destinations[i].caps.szPname, ARRAY_SIZE(destinations[i].caps.szPname));
> -
> -        destinations[i].caps.wTechnology = MOD_SYNTH;
> -        destinations[i].caps.wChannelMask = 0xFFFF;
> -
> -        destinations[i].caps.wMid = 0x00FF; 	/* Manufac ID */
> -        destinations[i].caps.wPid = 0x0001; 	/* Product ID */
> -        destinations[i].caps.vDriverVersion = 0x0001;
> -        destinations[i].caps.dwSupport = MIDICAPS_VOLUME;
> -        destinations[i].caps.wVoices = 16;
> -        destinations[i].caps.wNotes = 16;
> -    }
> -    /* initialise available destinations */
> -    for (i = MAX_MIDI_SYNTHS; i < numDest + MAX_MIDI_SYNTHS; i++)
> -    {
> -        destinations[i].dest = MIDIGetDestination(i - MAX_MIDI_SYNTHS);
> -
> -        CoreMIDI_GetObjectName(destinations[i].dest, szPname, sizeof(szPname));
> -        MultiByteToWideChar(CP_ACP, 0, szPname, -1, destinations[i].caps.szPname, ARRAY_SIZE(destinations[i].caps.szPname));
> -
> -        destinations[i].caps.wTechnology = MOD_MIDIPORT;
> -        destinations[i].caps.wChannelMask = 0xFFFF;
> -
> -        destinations[i].caps.wMid = 0x00FF; 	/* Manufac ID */
> -        destinations[i].caps.wPid = 0x0001;
> -        destinations[i].caps.vDriverVersion = 0x0001;
> -        destinations[i].caps.dwSupport = 0;
> -        destinations[i].caps.wVoices = 0;
> -        destinations[i].caps.wNotes = 0;
> -    }
> -    return DRV_SUCCESS;
> +    return err;
>  }
>  
> -LONG CoreAudio_MIDIRelease(void)
> +static LONG CoreAudio_MIDIRelease(void)
>  {
>      TRACE("\n");
> +
> +    UNIX_CALL(midi_release, NULL);
> +    sources = NULL;
> +    destinations = NULL;
> +
>      if (MIDIIn_NumDevs > 0)
>      {
> -        CFMessagePortRef messagePort;
> -        /* Stop CFRunLoop in MIDIIn_MessageThread */
> -        messagePort = CFMessagePortCreateRemote(kCFAllocatorDefault, MIDIInThreadPortName);
> -        CFMessagePortSendRequest(messagePort, 1, NULL, 0.0, 0.0, NULL, NULL);
> -        CFRelease(messagePort);
> -
>          midiInLock.DebugInfo->Spare[0] = 0;
>          DeleteCriticalSection(&midiInLock);
>      }
>  
> -    if (wineMIDIClient) MIDIClientDispose(wineMIDIClient); /* MIDIClientDispose will close all ports */
> -
> -    HeapFree(GetProcessHeap(), 0, sources);
> -    HeapFree(GetProcessHeap(), 0, destinations);
>      return DRV_SUCCESS;
>  }
>  
> diff --git a/dlls/winecoreaudio.drv/unixlib.h b/dlls/winecoreaudio.drv/unixlib.h
> index 6f51c7877fa..6dfb68d202f 100644
> --- a/dlls/winecoreaudio.drv/unixlib.h
> +++ b/dlls/winecoreaudio.drv/unixlib.h
> @@ -182,6 +182,14 @@ struct set_volumes_params
>      int channel;
>  };
>  
> +struct midi_init_params
> +{
> +    DWORD *err;
> +    UINT num_dests, num_srcs;
> +    void *dests, *srcs;
> +    void *midi_out_port, *midi_in_port;
> +};
> +
>  enum unix_funcs
>  {
>      unix_get_endpoint_ids,
> @@ -204,8 +212,13 @@ enum unix_funcs
>      unix_get_frequency,
>      unix_is_started,
>      unix_set_volumes,
> +    unix_midi_init,
> +    unix_midi_release,
>  };
>  
> +NTSTATUS midi_init( void * ) DECLSPEC_HIDDEN;
> +NTSTATUS midi_release( void * ) DECLSPEC_HIDDEN;
> +
>  extern unixlib_handle_t coreaudio_handle;
>  
>  #define UNIX_CALL( func, params ) __wine_unix_call( coreaudio_handle, unix_ ## func, params )
> -- 
> 2.23.0
> 
> 



More information about the wine-devel mailing list