Emmanuel Maillard : winecoreaudio: Initial MIDI In Mach message
handling.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Apr 26 10:23:58 CDT 2007
Module: wine
Branch: master
Commit: 1a47f36cb970fbb00237561da45972b8f65fb837
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1a47f36cb970fbb00237561da45972b8f65fb837
Author: Emmanuel Maillard <mahanuu at free.fr>
Date: Thu Apr 26 01:24:53 2007 +0200
winecoreaudio: Initial MIDI In Mach message handling.
---
dlls/winecoreaudio.drv/coremidi.c | 2 +-
dlls/winecoreaudio.drv/coremidi.h | 3 +
dlls/winecoreaudio.drv/midi.c | 91 +++++++++++++++++++++++++++++++++++++
3 files changed, 95 insertions(+), 1 deletions(-)
diff --git a/dlls/winecoreaudio.drv/coremidi.c b/dlls/winecoreaudio.drv/coremidi.c
index ab4cd87..a127aff 100644
--- a/dlls/winecoreaudio.drv/coremidi.c
+++ b/dlls/winecoreaudio.drv/coremidi.c
@@ -67,7 +67,7 @@ void MIDIIn_ReadProc(const MIDIPacketList *pktlist, void *refCon, void *connRefC
msg.length = packet->length;
memcpy(msg.data, packet->data, sizeof(packet->data));
- /* send message to Wine */
+ MIDIIn_SendMessage(msg);
packet = MIDIPacketNext(packet);
}
diff --git a/dlls/winecoreaudio.drv/coremidi.h b/dlls/winecoreaudio.drv/coremidi.h
index 182c190..7cc7f08 100644
--- a/dlls/winecoreaudio.drv/coremidi.h
+++ b/dlls/winecoreaudio.drv/coremidi.h
@@ -76,4 +76,7 @@ extern MIDIClientRef CoreMIDI_CreateClient(CFStringRef name);
extern void CoreMIDI_GetObjectName(MIDIObjectRef obj, char *name, int size);
extern void MIDIIn_ReadProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon);
+/* midi.c */
+void MIDIIn_SendMessage(MIDIMessage msg);
+
#endif
diff --git a/dlls/winecoreaudio.drv/midi.c b/dlls/winecoreaudio.drv/midi.c
index d12532c..ff43a35 100644
--- a/dlls/winecoreaudio.drv/midi.c
+++ b/dlls/winecoreaudio.drv/midi.c
@@ -76,6 +76,10 @@ typedef struct tagMIDISource {
DWORD startTime;
} 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
@@ -114,6 +118,13 @@ LONG CoreAudio_MIDIInit(void)
destinations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MIDIOut_NumDevs * sizeof(MIDIDestination));
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 */
for (i = 0; i < MIDIIn_NumDevs; i++)
{
@@ -182,6 +193,17 @@ LONG CoreAudio_MIDIInit(void)
LONG CoreAudio_MIDIRelease(void)
{
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 */
HeapFree(GetProcessHeap(), 0, sources);
@@ -567,6 +589,75 @@ static DWORD MIDIOut_Reset(WORD wDevID)
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
*/
More information about the wine-cvs
mailing list