[PATCH 3/3] dmusic: Create the list of available system ports at the beginning and use it to enumerate ports.
Christian Costa
titan.costa at gmail.com
Sun Sep 16 13:24:10 CDT 2012
--
In next patches this list will be used to create ports.
There will be 3 differents constructors for midi in, midi out and synth ports.
---
dlls/dmusic/dmusic.c | 175 +++++++++++++++++++++++++-----------------
dlls/dmusic/dmusic_private.h | 10 ++
dlls/dmusic/port.c | 5 +
3 files changed, 115 insertions(+), 75 deletions(-)
diff --git a/dlls/dmusic/dmusic.c b/dlls/dmusic/dmusic.c
index 3bc4901..bb1eb96 100644
--- a/dlls/dmusic/dmusic.c
+++ b/dlls/dmusic/dmusic.c
@@ -74,6 +74,7 @@ static ULONG WINAPI IDirectMusic8Impl_Release(LPDIRECTMUSIC8 iface)
TRACE("(%p)->(): new ref = %u\n", This, ref);
if (!ref) {
+ HeapFree(GetProcessHeap(), 0, This->system_ports);
HeapFree(GetProcessHeap(), 0, This->ppPorts);
HeapFree(GetProcessHeap(), 0, This);
}
@@ -87,85 +88,18 @@ static ULONG WINAPI IDirectMusic8Impl_Release(LPDIRECTMUSIC8 iface)
static HRESULT WINAPI IDirectMusic8Impl_EnumPort(LPDIRECTMUSIC8 iface, DWORD index, LPDMUS_PORTCAPS port_caps)
{
IDirectMusic8Impl *This = impl_from_IDirectMusic8(iface);
- ULONG nb_midi_out;
- ULONG nb_midi_in;
- const WCHAR emulated[] = {' ','[','E','m','u','l','a','t','e','d',']',0};
TRACE("(%p, %d, %p)\n", This, index, port_caps);
if (!port_caps)
return E_POINTER;
- /* NOTE: It seems some native versions get the rest of devices through dmusic32.EnumLegacyDevices...*sigh*...which is undocumented */
-
- /* NOTE: Should we enum wave devices ? Native does not seem to */
-
- /* Fill common port caps for winmm ports */
- port_caps->dwType = DMUS_PORT_WINMM_DRIVER;
- port_caps->dwMemorySize = 0;
- port_caps->dwMaxChannelGroups = 1;
- port_caps->dwMaxVoices = 0;
- port_caps->dwMaxAudioChannels = 0;
- port_caps->dwEffectFlags = DMUS_EFFECT_NONE;
- /* Fake port GUID */
- port_caps->guidPort = IID_IUnknown;
- port_caps->guidPort.Data1 = index + 1;
-
- nb_midi_out = midiOutGetNumDevs();
-
- if (index == 0)
- {
- MIDIOUTCAPSW caps;
- midiOutGetDevCapsW(MIDI_MAPPER, &caps, sizeof(caps));
- strcpyW(port_caps->wszDescription, caps.szPname);
- strcatW(port_caps->wszDescription, emulated);
- port_caps->dwFlags = DMUS_PC_SHAREABLE;
- port_caps->dwClass = DMUS_PC_OUTPUTCLASS;
- TRACE("Enumerating port: %s\n", debugstr_w(port_caps->wszDescription));
- return S_OK;
- }
-
- if (index < (nb_midi_out + 1))
- {
- MIDIOUTCAPSW caps;
- midiOutGetDevCapsW(index - 1, &caps, sizeof(caps));
- strcpyW(port_caps->wszDescription, caps.szPname);
- strcatW(port_caps->wszDescription, emulated);
- port_caps->dwFlags = DMUS_PC_SHAREABLE | DMUS_PC_EXTERNAL;
- port_caps->dwClass = DMUS_PC_OUTPUTCLASS;
- TRACE("Enumerating port: %s\n", debugstr_w(port_caps->wszDescription));
- return S_OK;
- }
-
- nb_midi_in = midiInGetNumDevs();
-
- if (index < (nb_midi_in + nb_midi_out + 1))
- {
- MIDIINCAPSW caps;
- midiInGetDevCapsW(index - nb_midi_out - 1, &caps, sizeof(caps));
- strcpyW(port_caps->wszDescription, caps.szPname);
- strcatW(port_caps->wszDescription, emulated);
- port_caps->dwFlags = DMUS_PC_EXTERNAL;
- port_caps->dwClass = DMUS_PC_INPUTCLASS;
- TRACE("Enumerating port: %s\n", debugstr_w(port_caps->wszDescription));
- return S_OK;
- }
+ if (index >= This->nb_system_ports)
+ return S_FALSE;
- if (index == (nb_midi_in + nb_midi_out + 1))
- {
- IDirectMusicSynth8* synth = NULL;
- HRESULT hr;
- hr = CoCreateInstance(&CLSID_DirectMusicSynth, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicSynth8, (void**)&synth);
- if (SUCCEEDED(hr))
- hr = IDirectMusicSynth8_GetPortCaps(synth, port_caps);
- if (SUCCEEDED(hr))
- TRACE("Enumerating port: %s\n", debugstr_w(port_caps->wszDescription));
- if (synth)
- IDirectMusicSynth8_Release(synth);
- return hr;
- }
+ *port_caps = This->system_ports[index].caps;
- return S_FALSE;
+ return S_OK;
}
static HRESULT WINAPI IDirectMusic8Impl_CreateMusicBuffer(LPDIRECTMUSIC8 iface, LPDMUS_BUFFERDESC buffer_desc, LPDIRECTMUSICBUFFER* buffer, LPUNKNOWN unkouter)
@@ -222,7 +156,7 @@ static HRESULT WINAPI IDirectMusic8Impl_CreatePort(LPDIRECTMUSIC8 iface, REFCLSI
for (i = 0; S_FALSE != IDirectMusic8Impl_EnumPort(iface, i, &PortCaps); i++) {
if (IsEqualCLSID (request_port, &PortCaps.guidPort)) {
- hr = DMUSIC_CreateDirectMusicPortImpl(&IID_IDirectMusicPort, (LPVOID*) &pNewPort, (LPUNKNOWN) This, pPortParams, &PortCaps);
+ hr = DMUSIC_CreateDirectMusicPortImpl(&IID_IDirectMusicPort, (LPVOID*) &pNewPort, (LPUNKNOWN) This, pPortParams, &PortCaps, 0);
if (FAILED(hr)) {
*ppPort = NULL;
return hr;
@@ -370,6 +304,101 @@ static const IDirectMusic8Vtbl DirectMusic8_Vtbl = {
IDirectMusic8Impl_SetExternalMasterClock
};
+static void create_system_ports_list(IDirectMusic8Impl* object)
+{
+ port_info * port;
+ const WCHAR emulated[] = {' ','[','E','m','u','l','a','t','e','d',']',0};
+ ULONG nb_ports;
+ ULONG nb_midi_out;
+ ULONG nb_midi_in;
+ MIDIOUTCAPSW caps_out;
+ MIDIINCAPSW caps_in;
+ IDirectMusicSynth8* synth;
+ HRESULT hr;
+ int i;
+
+ TRACE("(%p)\n", object);
+
+ /* NOTE:
+ - it seems some native versions get the rest of devices through dmusic32.EnumLegacyDevices...*sigh*...which is undocumented
+ - should we enum wave devices ? Native does not seem to
+ */
+
+ nb_midi_out = midiOutGetNumDevs();
+ nb_midi_in = midiInGetNumDevs();
+ nb_ports = 1 /* midi mapper */ + nb_midi_out + nb_midi_in + 1 /* synth port */;
+
+ port = object->system_ports = HeapAlloc(GetProcessHeap(), 0, nb_ports * sizeof(port_info));
+ if (!object->system_ports)
+ return;
+
+ /* Fill common port caps for all winmm ports */
+ for (i = 0; i < (nb_ports - 1 /* synth port*/); i++)
+ {
+ object->system_ports[i].caps.dwSize = sizeof(DMUS_PORTCAPS);
+ object->system_ports[i].caps.dwType = DMUS_PORT_WINMM_DRIVER;
+ object->system_ports[i].caps.dwMemorySize = 0;
+ object->system_ports[i].caps.dwMaxChannelGroups = 1;
+ object->system_ports[i].caps.dwMaxVoices = 0;
+ object->system_ports[i].caps.dwMaxAudioChannels = 0;
+ object->system_ports[i].caps.dwEffectFlags = DMUS_EFFECT_NONE;
+ /* Fake port GUID */
+ object->system_ports[i].caps.guidPort = IID_IUnknown;
+ object->system_ports[i].caps.guidPort.Data1 = i + 1;
+ }
+
+ /* Fill midi mapper port info */
+ port->device = MIDI_MAPPER;
+ port->create = DMUSIC_CreateDirectMusicPortImpl; /* FIXME: The same for all ports for now */
+ midiOutGetDevCapsW(MIDI_MAPPER, &caps_out, sizeof(caps_out));
+ strcpyW(port->caps.wszDescription, caps_out.szPname);
+ strcatW(port->caps.wszDescription, emulated);
+ port->caps.dwFlags = DMUS_PC_SHAREABLE;
+ port->caps.dwClass = DMUS_PC_OUTPUTCLASS;
+ port++;
+
+ /* Fill midi out port info */
+ for (i = 0; i < nb_midi_out; i++)
+ {
+ port->device = i;
+ port->create = DMUSIC_CreateDirectMusicPortImpl; /* FIXME: The same for all ports for now */
+ midiOutGetDevCapsW(i, &caps_out, sizeof(caps_out));
+ strcpyW(port->caps.wszDescription, caps_in.szPname);
+ strcatW(port->caps.wszDescription, emulated);
+ port->caps.dwFlags = DMUS_PC_SHAREABLE | DMUS_PC_EXTERNAL;
+ port->caps.dwClass = DMUS_PC_OUTPUTCLASS;
+ port++;
+ }
+
+ /* Fill midi in port info */
+ for (i = 0; i < nb_midi_in; i++)
+ {
+ port->device = i;
+ port->create = DMUSIC_CreateDirectMusicPortImpl; /* FIXME: The same for all ports for now */
+ midiInGetDevCapsW(i, &caps_in, sizeof(caps_in));
+ strcpyW(port->caps.wszDescription, caps_in.szPname);
+ strcatW(port->caps.wszDescription, emulated);
+ port->caps.dwFlags = DMUS_PC_EXTERNAL;
+ port->caps.dwClass = DMUS_PC_INPUTCLASS;
+ port++;
+ }
+
+ /* Fill synth port info */
+ port->create = DMUSIC_CreateDirectMusicPortImpl; /* FIXME: The same for all ports for now */
+ hr = CoCreateInstance(&CLSID_DirectMusicSynth, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicSynth8, (void**)&synth);
+ if (SUCCEEDED(hr))
+ {
+ hr = IDirectMusicSynth8_GetPortCaps(synth, &port->caps);
+ IDirectMusicSynth8_Release(synth);
+ }
+ else
+ {
+ nb_ports--;
+ }
+
+ object->nb_system_ports = nb_ports;
+}
+
/* For ClassFactory */
HRESULT WINAPI DMUSIC_CreateDirectMusicImpl(LPCGUID riid, LPVOID* ret_iface, LPUNKNOWN unkouter)
{
@@ -402,5 +431,7 @@ HRESULT WINAPI DMUSIC_CreateDirectMusicImpl(LPCGUID riid, LPVOID* ret_iface, LPU
return ret;
}
+ create_system_ports_list(dmusic);
+
return S_OK;
}
diff --git a/dlls/dmusic/dmusic_private.h b/dlls/dmusic/dmusic_private.h
index 0572a82..a1430ef 100644
--- a/dlls/dmusic/dmusic_private.h
+++ b/dlls/dmusic/dmusic_private.h
@@ -72,6 +72,12 @@ typedef struct DMUSIC_PRIVATE_CHANNEL_GROUP_ {
DMUSIC_PRIVATE_MCHANNEL channel[16]; /* 16 channels in a group */
} DMUSIC_PRIVATE_CHANNEL_GROUP, *LPDMUSIC_PRIVATE_CHANNEL_GROUP;
+typedef struct port_info {
+ DMUS_PORTCAPS caps;
+ HRESULT (*create)(LPCGUID guid, LPVOID *object, LPUNKNOWN unkouter, LPDMUS_PORTPARAMS port_params, LPDMUS_PORTCAPS port_caps, DWORD device);
+ ULONG device;
+} port_info;
+
/*****************************************************************************
* ClassFactory
@@ -100,6 +106,8 @@ struct IDirectMusic8Impl {
IReferenceClockImpl* pMasterClock;
IDirectMusicPort** ppPorts;
int nrofports;
+ port_info* system_ports;
+ int nb_system_ports;
};
/*****************************************************************************
@@ -161,7 +169,7 @@ struct IDirectMusicPortImpl {
};
/** Internal factory */
-extern HRESULT DMUSIC_CreateDirectMusicPortImpl (LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter, LPDMUS_PORTPARAMS pPortParams, LPDMUS_PORTCAPS pPortCaps) DECLSPEC_HIDDEN;
+extern HRESULT DMUSIC_CreateDirectMusicPortImpl(LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter, LPDMUS_PORTPARAMS pPortParams, LPDMUS_PORTCAPS pPortCaps, DWORD device) DECLSPEC_HIDDEN;
/*****************************************************************************
* IReferenceClockImpl implementation structure
diff --git a/dlls/dmusic/port.c b/dlls/dmusic/port.c
index 7e1f5e1..2530fb9 100644
--- a/dlls/dmusic/port.c
+++ b/dlls/dmusic/port.c
@@ -473,12 +473,13 @@ static const IDirectMusicThruVtbl DirectMusicThru_Vtbl = {
IDirectMusicThruImpl_ThruChannel
};
-HRESULT DMUSIC_CreateDirectMusicPortImpl (LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter, LPDMUS_PORTPARAMS pPortParams, LPDMUS_PORTCAPS pPortCaps) {
+HRESULT DMUSIC_CreateDirectMusicPortImpl(LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter, LPDMUS_PORTPARAMS pPortParams, LPDMUS_PORTCAPS pPortCaps, DWORD device)
+{
IDirectMusicPortImpl *obj;
HRESULT hr = E_FAIL;
UINT j;
- TRACE("(%p,%p,%p)\n", lpcGUID, ppobj, pUnkOuter);
+ TRACE("(%p,%p,%p,%d)\n", lpcGUID, ppobj, pUnkOuter, device);
obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicPortImpl));
if (NULL == obj) {
More information about the wine-patches
mailing list