[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, ¶ms);
> + 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