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