winecoreaudio: Initial MIDI In Mach message handling.
This commit is contained in:
parent
4903fbedc9
commit
1a47f36cb9
|
@ -67,7 +67,7 @@ void MIDIIn_ReadProc(const MIDIPacketList *pktlist, void *refCon, void *connRefC
|
||||||
msg.length = packet->length;
|
msg.length = packet->length;
|
||||||
memcpy(msg.data, packet->data, sizeof(packet->data));
|
memcpy(msg.data, packet->data, sizeof(packet->data));
|
||||||
|
|
||||||
/* send message to Wine */
|
MIDIIn_SendMessage(msg);
|
||||||
|
|
||||||
packet = MIDIPacketNext(packet);
|
packet = MIDIPacketNext(packet);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,4 +76,7 @@ extern MIDIClientRef CoreMIDI_CreateClient(CFStringRef name);
|
||||||
extern void CoreMIDI_GetObjectName(MIDIObjectRef obj, char *name, int size);
|
extern void CoreMIDI_GetObjectName(MIDIObjectRef obj, char *name, int size);
|
||||||
extern void MIDIIn_ReadProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon);
|
extern void MIDIIn_ReadProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon);
|
||||||
|
|
||||||
|
/* midi.c */
|
||||||
|
void MIDIIn_SendMessage(MIDIMessage msg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -76,6 +76,10 @@ typedef struct tagMIDISource {
|
||||||
DWORD startTime;
|
DWORD startTime;
|
||||||
} MIDISource;
|
} MIDISource;
|
||||||
|
|
||||||
|
static CRITICAL_SECTION midiInLock; /* Critical section for MIDI In */
|
||||||
|
static CFStringRef MIDIInThreadPortName = NULL;
|
||||||
|
|
||||||
|
static DWORD WINAPI MIDIIn_MessageThread(LPVOID p);
|
||||||
|
|
||||||
#define MAX_MIDI_SYNTHS 1
|
#define MAX_MIDI_SYNTHS 1
|
||||||
|
|
||||||
|
@ -114,6 +118,13 @@ LONG CoreAudio_MIDIInit(void)
|
||||||
destinations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MIDIOut_NumDevs * sizeof(MIDIDestination));
|
destinations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MIDIOut_NumDevs * sizeof(MIDIDestination));
|
||||||
sources = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MIDIIn_NumDevs * sizeof(MIDISource));
|
sources = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MIDIIn_NumDevs * sizeof(MIDISource));
|
||||||
|
|
||||||
|
if (MIDIIn_NumDevs > 0)
|
||||||
|
{
|
||||||
|
InitializeCriticalSection(&midiInLock);
|
||||||
|
MIDIInThreadPortName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("MIDIInThreadPortName.%u"), getpid());
|
||||||
|
CreateThread(NULL, 0, MIDIIn_MessageThread, NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* initialize sources */
|
/* initialize sources */
|
||||||
for (i = 0; i < MIDIIn_NumDevs; i++)
|
for (i = 0; i < MIDIIn_NumDevs; i++)
|
||||||
{
|
{
|
||||||
|
@ -182,6 +193,17 @@ LONG CoreAudio_MIDIInit(void)
|
||||||
LONG CoreAudio_MIDIRelease(void)
|
LONG CoreAudio_MIDIRelease(void)
|
||||||
{
|
{
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
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);
|
||||||
|
|
||||||
|
DeleteCriticalSection(&midiInLock);
|
||||||
|
}
|
||||||
|
|
||||||
if (wineMIDIClient) MIDIClientDispose(wineMIDIClient); /* MIDIClientDispose will close all ports */
|
if (wineMIDIClient) MIDIClientDispose(wineMIDIClient); /* MIDIClientDispose will close all ports */
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, sources);
|
HeapFree(GetProcessHeap(), 0, sources);
|
||||||
|
@ -567,6 +589,75 @@ static DWORD MIDIOut_Reset(WORD wDevID)
|
||||||
return MMSYSERR_NOERROR;
|
return MMSYSERR_NOERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIDI In Mach message handling
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call from CoreMIDI IO threaded callback,
|
||||||
|
* we can't call Wine debug channels, critical section or anything using NtCurrentTeb here.
|
||||||
|
*/
|
||||||
|
void MIDIIn_SendMessage(MIDIMessage msg)
|
||||||
|
{
|
||||||
|
CFDataRef data;
|
||||||
|
|
||||||
|
CFMessagePortRef messagePort;
|
||||||
|
messagePort = CFMessagePortCreateRemote(kCFAllocatorDefault, MIDIInThreadPortName);
|
||||||
|
|
||||||
|
data = CFDataCreate(kCFAllocatorDefault, (UInt8 *) &msg, sizeof(msg));
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
CFMessagePortSendRequest(messagePort, 0, data, 0.0, 0.0, NULL, NULL);
|
||||||
|
CFRelease(data);
|
||||||
|
CFRelease(messagePort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static CFDataRef MIDIIn_MessageHandler(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info)
|
||||||
|
{
|
||||||
|
MIDIMessage *msg = NULL;
|
||||||
|
int i = 0;
|
||||||
|
FIXME("\n");
|
||||||
|
|
||||||
|
switch (msgid)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
msg = (MIDIMessage *) CFDataGetBytePtr(data);
|
||||||
|
TRACE("devID=%d\n", msg->devID);
|
||||||
|
for (i = 0; i < msg->length; ++i) {
|
||||||
|
TRACE("%02X ", msg->data[i]);
|
||||||
|
}
|
||||||
|
TRACE("\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CFRunLoopStop(CFRunLoopGetCurrent());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD WINAPI MIDIIn_MessageThread(LPVOID p)
|
||||||
|
{
|
||||||
|
CFMessagePortRef local;
|
||||||
|
CFRunLoopSourceRef source;
|
||||||
|
Boolean info;
|
||||||
|
|
||||||
|
local = CFMessagePortCreateLocal(kCFAllocatorDefault, MIDIInThreadPortName, &MIDIIn_MessageHandler, NULL, &info);
|
||||||
|
|
||||||
|
source = CFMessagePortCreateRunLoopSource(kCFAllocatorDefault, local, (CFIndex)0);
|
||||||
|
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
|
||||||
|
|
||||||
|
CFRunLoopRun();
|
||||||
|
|
||||||
|
CFRunLoopSourceInvalidate(source);
|
||||||
|
CFRelease(source);
|
||||||
|
CFRelease(local);
|
||||||
|
CFRelease(MIDIInThreadPortName);
|
||||||
|
MIDIInThreadPortName = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* modMessage
|
* modMessage
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue